diff --git a/.gitignore b/.gitignore
index af614f13b..71396f911 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
**/*.DS_Store
**/*.zig-cache
+# Ignore build directories
+*/build/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 000000000..14458c274
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,10 @@
+# Contributing
+
+Please write clear commit messages that briefly describe the changes.
+For example:
+
+```
+Add Cell framework example using C++23 modules
+```
+
+Commit messages like "Applying previous commit" should be avoided.
diff --git a/README.md b/README.md
index 9fc04abd2..c33b2a3ac 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
### Quick Start
-A simple command-line client is provided in `agent_client.zig`. Set the `OPENAI_API_KEY` environment variable and run:
+A simple command-line client is provided in `agent_client.zig`. Make sure Zig 0.14.1 is installed (see ). Set the `OPENAI_API_KEY` environment variable and run:
```bash
zig run agent_client.zig -- --persona Abbey
@@ -30,3 +30,6 @@ To predict a probability with the trained model:
zig run local_ml.zig -- predict model.txt 1.2 3.4
```
+
+### Cell Framework Example
+This repository now includes a demonstration of the Cell framework using modern C++23 modules. See `cell_framework/README.md` for build instructions.
diff --git a/agent_client.zig b/agent_client.zig
new file mode 100644
index 000000000..51770f506
--- /dev/null
+++ b/agent_client.zig
@@ -0,0 +1,5 @@
+const Agent = @import("./src/agent.zig");
+
+pub fn main() !void {
+ try Agent.main();
+}
diff --git a/build.zig b/build.zig
index b6884115e..fc46c70d5 100644
--- a/build.zig
+++ b/build.zig
@@ -5,7 +5,7 @@ pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
- // ─── Feature flags for conditional compilation ───────────────────────────
+ // Feature flags for conditional compilation
const options = b.addOptions();
options.addOption(bool, "enable_gpu", b.option(bool, "gpu", "Enable GPU acceleration") orelse detectGPUSupport());
options.addOption(bool, "enable_simd", b.option(bool, "simd", "Enable SIMD optimizations") orelse detectSIMDSupport());
@@ -20,26 +20,26 @@ pub fn build(b: *std.Build) void {
const exe = b.addExecutable(.{
.name = "abi",
- .root_source_file = b.path("src/main.zig"),
+ .root_source_file = .{ .src_path = .{ .owner = b, .sub_path = "src/main.zig" } },
.target = target,
.optimize = platform_optimize,
});
- // ─── Optimization flags ──────────────────────────────────────────────────
+ // Optimization flags
exe.link_function_sections = true;
exe.link_gc_sections = true;
if (platform_optimize == .ReleaseSmall or platform_optimize == .ReleaseFast) {
exe.root_module.strip = true;
}
- // No external dependencies currently required.
+ // Dependencies
exe.root_module.addOptions("build_options", options);
- // ─── Platform-specific dependencies ──────────────────────────────────────
+ // Platform-specific dependencies
switch (target.result.os.tag) {
.linux => {
exe.linkSystemLibrary("c");
- if (b.option(bool, "enable_io_uring", "Enable io_uring support") orelse true) {
+ if (b.option(bool, "enable_io_uring", "Enable io_uring support") orelse false) {
exe.linkSystemLibrary("uring");
}
},
@@ -68,7 +68,7 @@ pub fn build(b: *std.Build) void {
const unit_tests = b.addTest(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
- .optimize = optimize,
+ .optimize = platform_optimize,
});
unit_tests.root_module.addOptions("build_options", options);
test_step.dependOn(&b.addRunArtifact(unit_tests).step);
diff --git a/cell_framework/CMakeLists.txt b/cell_framework/CMakeLists.txt
new file mode 100644
index 000000000..7253c3852
--- /dev/null
+++ b/cell_framework/CMakeLists.txt
@@ -0,0 +1,35 @@
+cmake_minimum_required(VERSION 3.26)
+project(CellFramework LANGUAGES CXX)
+
+set(CMAKE_CXX_STANDARD 23)
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API 1)
+
+# Directory for generated headers
+set(GENERATED_INCLUDE_DIR ${CMAKE_BINARY_DIR}/include)
+file(MAKE_DIRECTORY ${GENERATED_INCLUDE_DIR})
+
+add_custom_target(generate_headers
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/generate_headers.cmake
+ BYPRODUCTS ${GENERATED_INCLUDE_DIR}/Cell/Core.hpp
+ VERBATIM
+)
+
+add_library(CellCore)
+
+target_sources(CellCore
+ PUBLIC
+ FILE_SET cxx_modules TYPE CXX_MODULES FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/Cell/Core.ixx
+ FILE_SET cxx_modules TYPE CXX_MODULES FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/Cell/Core.cpp
+)
+
+target_include_directories(CellCore PUBLIC ${GENERATED_INCLUDE_DIR})
+
+add_dependencies(CellCore generate_headers)
+
+add_executable(cell_app main.cpp)
+
+target_link_libraries(cell_app PRIVATE CellCore)
+
+add_dependencies(cell_app generate_headers)
diff --git a/cell_framework/Cell/Core.cpp b/cell_framework/Cell/Core.cpp
new file mode 100644
index 000000000..a0ed2f418
--- /dev/null
+++ b/cell_framework/Cell/Core.cpp
@@ -0,0 +1,11 @@
+module;
+#include
+
+module Cell.Core;
+
+namespace Cell {
+ void Engine::run() {
+ std::cout << "Cell Engine running!" << std::endl;
+ std::cout << "2 + 2 = " << add(2, 2) << std::endl;
+ }
+}
diff --git a/cell_framework/Cell/Core.ixx b/cell_framework/Cell/Core.ixx
new file mode 100644
index 000000000..609ae65a7
--- /dev/null
+++ b/cell_framework/Cell/Core.ixx
@@ -0,0 +1,14 @@
+export module Cell.Core;
+
+export import ;
+
+export namespace Cell {
+ inline int add(int a, int b) {
+ return a + b;
+ }
+
+ class Engine {
+ public:
+ void run();
+ };
+}
diff --git a/cell_framework/README.md b/cell_framework/README.md
new file mode 100644
index 000000000..f4518f423
--- /dev/null
+++ b/cell_framework/README.md
@@ -0,0 +1,27 @@
+# Cell Framework Example with C++23 Modules
+
+This example demonstrates the Cell framework using a modules-first design.
+The build system uses CMake 3.26+ with the experimental C++ module API and
+automatically generates traditional headers from module interface files.
+
+## Prerequisites
+
+- CMake 3.26 or newer
+- A C++23 compiler with module support (Clang 18+ or equivalent)
+
+## Building
+
+```bash
+mkdir build && cd build
+cmake ..
+cmake --build .
+./cell_app
+```
+
+CMake should be invoked from a separate `build` directory to keep
+generated files isolated from the source tree.
+
+During configuration, module interfaces located in the `Cell/` directory are
+converted into headers under `build/include/Cell`. These generated headers
+allow interoperability with code that still relies on the traditional `#include`
+mechanism.
diff --git a/cell_framework/main.cpp b/cell_framework/main.cpp
new file mode 100644
index 000000000..239dbf731
--- /dev/null
+++ b/cell_framework/main.cpp
@@ -0,0 +1,7 @@
+import Cell.Core;
+
+int main() {
+ Cell::Engine engine;
+ engine.run();
+ return 0;
+}
diff --git a/scripts/generate_headers.cmake b/scripts/generate_headers.cmake
new file mode 100644
index 000000000..5c8ae44a2
--- /dev/null
+++ b/scripts/generate_headers.cmake
@@ -0,0 +1,10 @@
+# Simple header generation from module interface files
+file(GLOB MODULE_FILES "${CMAKE_CURRENT_LIST_DIR}/../cell_framework/Cell/*.ixx")
+foreach(MFILE ${MODULE_FILES})
+ get_filename_component(MNAME ${MFILE} NAME_WE)
+ set(HEADER "${GENERATED_INCLUDE_DIR}/Cell/${MNAME}.hpp")
+ file(MAKE_DIRECTORY "${GENERATED_INCLUDE_DIR}/Cell")
+ file(READ ${MFILE} CONTENTS)
+ string(REGEX REPLACE "export module ([A-Za-z0-9_.]+);" "#pragma once\n// Generated from module \1" CONTENTS "${CONTENTS}")
+ file(WRITE ${HEADER} "${CONTENTS}")
+endforeach()
diff --git a/scripts/install_zig.sh b/scripts/install_zig.sh
new file mode 100755
index 000000000..6e7eb8ecc
--- /dev/null
+++ b/scripts/install_zig.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+set -euo pipefail
+VERSION=0.14.1
+URL="https://ziglang.org/download/${VERSION}/zig-$(uname -m)-linux-${VERSION}.tar.xz"
+TMP_DIR=$(mktemp -d)
+trap 'rm -rf "$TMP_DIR"' EXIT
+curl -L "$URL" -o "$TMP_DIR/zig.tar.xz"
+mkdir -p "$TMP_DIR/extract"
+tar -xf "$TMP_DIR/zig.tar.xz" -C "$TMP_DIR/extract"
+sudo rm -rf /usr/local/zig
+sudo mkdir -p /usr/local/zig
+sudo cp -r "$TMP_DIR/extract"/*/ /usr/local/zig/
+sudo ln -sf /usr/local/zig/zig /usr/local/bin/zig
diff --git a/src/agent.zig b/src/agent.zig
index 4c90c1bf5..ff1031a0d 100644
--- a/src/agent.zig
+++ b/src/agent.zig
@@ -137,6 +137,7 @@ pub const personas = [_]Persona{
fn findPersona(name: []const u8) ?Persona {
for (personas) |p| {
+ if (std.mem.eqlIgnoreCase(u8, p.name, name)) return p;
if (std.mem.eql(u8, p.name, name)) return p;
}
return null;
diff --git a/src/discord/gateway.zig b/src/discord/gateway.zig
index c714b7a19..171808e2b 100644
--- a/src/discord/gateway.zig
+++ b/src/discord/gateway.zig
@@ -39,11 +39,12 @@ fn handleTextFrame(self: *DiscordBot, payload: []const u8) !void {
const root = &parsed.value;
const opv = root.object.get("op") orelse return;
- const op = @intCast(types.OpCode, opv.integer);
+ const op: types.OpCode = @enumFromInt(opv.integer);
switch (op) {
.hello => if (root.object.get("d")) |data| {
- const interval = data.object.get("heartbeat_interval")?.integer orelse return;
+ const iv = data.object.get("heartbeat_interval") orelse return;
+ const interval = iv.integer;
try heartbeatLoop(self, @as(u32, @intCast(interval)));
try identify(self);
} else {},
@@ -55,7 +56,7 @@ fn heartbeatLoop(self: *DiscordBot, interval: u32) !void {
var ws = self.ws.?;
const buf = try self.allocator.alloc(u8, 32);
defer self.allocator.free(buf);
- var timer = std.time.Timer.start() catch return;
+ _ = std.time.Timer.start() catch return;
while (true) {
try std.json.stringify(.{ .op = @as(u8, @intCast(types.OpCode.heartbeat)), .d = null }, .{}, std.io.fixedBufferStream(buf).writer());
try ws.writeFrame(.{ .fin = true, .opcode = .text, .data = buf });
@@ -65,10 +66,10 @@ fn heartbeatLoop(self: *DiscordBot, interval: u32) !void {
fn identify(self: *DiscordBot) !void {
var ws = self.ws.?;
- const identify = types.Identify{ .token = self.token, .intents = 1 << 15 };
+ const id_payload = types.Identify{ .token = self.token, .intents = 1 << 15 };
var buf = std.ArrayList(u8).init(self.allocator);
defer buf.deinit();
- try std.json.stringify(.{ .op = @as(u8, @intCast(types.OpCode.identify)), .d = identify }, .{}, buf.writer());
+ try std.json.stringify(.{ .op = @as(u8, @intCast(types.OpCode.identify)), .d = id_payload }, .{}, buf.writer());
try ws.writeFrame(.{ .fin = true, .opcode = .text, .data = buf.items });
}
@@ -79,7 +80,7 @@ fn fetchGatewayUrl(allocator: std.mem.Allocator, token: []const u8) ![]const u8
const auth_value = try std.fmt.allocPrint(allocator, "Bot {s}", .{token});
defer allocator.free(auth_value);
- const headers = [_]std.http.Header{ .{ .name = "Authorization", .value = auth_value } };
+ const headers = [_]std.http.Header{.{ .name = "Authorization", .value = auth_value }};
var buf = std.ArrayList(u8).init(allocator);
defer buf.deinit();
const result = try client.fetch(.{ .location = .{ .url = "https://discord.com/api/v10/gateway" }, .extra_headers = &headers, .response_storage = .dynamic(&buf) });
diff --git a/src/discord/types.zig b/src/discord/types.zig
index 97038c77c..b1fcecb02 100644
--- a/src/discord/types.zig
+++ b/src/discord/types.zig
@@ -6,7 +6,7 @@ pub const OpCode = enum(u8) {
identify = 2,
presence_update = 3,
voice_state_update = 4,
- resume = 6,
+ resume_session = 6,
reconnect = 7,
request_guild_members = 8,
invalid_session = 9,
diff --git a/src/engine/graphics.zig b/src/engine/graphics.zig
new file mode 100644
index 000000000..9e3f6961c
--- /dev/null
+++ b/src/engine/graphics.zig
@@ -0,0 +1,27 @@
+const std = @import("std");
+
+pub const GraphicsBackend = enum {
+ vulkan,
+ metal,
+ direct3d12,
+ opengl,
+ webgpu,
+};
+
+pub const GraphicsDriver = struct {
+ backend: GraphicsBackend,
+
+ pub fn init(backend: GraphicsBackend) GraphicsDriver {
+ return GraphicsDriver{ .backend = backend };
+ }
+
+ pub fn renderFrame(self: *GraphicsDriver) void {
+ // cross-platform rendering placeholder
+ _ = self;
+ }
+};
+
+test "GraphicsDriver init" {
+ const driver = GraphicsDriver.init(.vulkan);
+ try std.testing.expect(driver.backend == .vulkan);
+}
diff --git a/src/engine/mod.zig b/src/engine/mod.zig
new file mode 100644
index 000000000..6d61d1c7d
--- /dev/null
+++ b/src/engine/mod.zig
@@ -0,0 +1 @@
+pub const graphics = @import("graphics.zig");
diff --git a/src/localml.zig b/src/localml.zig
index 91b5af7d2..daab2b7d5 100644
--- a/src/localml.zig
+++ b/src/localml.zig
@@ -211,9 +211,9 @@ pub fn main() !void {
const data_contents = try std.fs.cwd().readFileAlloc(alloc, data_path, 1024 * 1024);
defer alloc.free(data_contents);
- var lines = std.mem.tokenize(u8, data_contents, "\n");
+ var lines = std.mem.tokenizeScalar(u8, data_contents, '\n');
while (lines.next()) |line| {
- var cols = std.mem.tokenize(u8, line, ",");
+ var cols = std.mem.tokenizeScalar(u8, line, ',');
const x1 = try std.fmt.parseFloat(f64, cols.next() orelse continue);
const x2 = try std.fmt.parseFloat(f64, cols.next() orelse continue);
const label = try std.fmt.parseFloat(f64, cols.next() orelse continue);
diff --git a/src/main.zig b/src/main.zig
index 15f996888..dca48300d 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -10,6 +10,7 @@ const gpu = @import("../zvim/gpu_renderer.zig");
const simd = @import("../zvim/simd_text.zig");
const lockfree = @import("lockfree.zig");
const platform = @import("platform.zig");
+const engine = @import("engine/mod.zig");
pub const Error = error{
EmptyText,
@@ -91,37 +92,15 @@ pub const Abi = struct {
pub fn main() !void {
var args = std.process.args();
_ = args.next(); // exe name
+ var driver = engine.graphics.GraphicsDriver.init(.opengl);
+ driver.renderFrame();
if (args.next()) |arg| {
if (std.mem.eql(u8, arg, "tui")) {
const tui = @import("tui.zig");
try tui.run();
return;
} else if (std.mem.eql(u8, arg, "discord")) {
- const api = @import("discord/api.zig");
- const gw = @import("discord/gateway.zig");
- const bot = @import("discord_bot.zig");
- var gpa = std.heap.GeneralPurposeAllocator(.{}){};
- defer _ = gpa.deinit();
- const allocator = gpa.allocator();
-
- const token = std.process.getEnvVarOwned(allocator, "DISCORD_TOKEN") catch {
- std.log.err("DISCORD_TOKEN environment variable not set", .{});
- return;
- };
- defer allocator.free(token);
-
- const channel = args.next() orelse {
- std.log.err("channel id required", .{});
- return;
- };
-
- var bot = gw.DiscordBot.init(allocator, token);
- defer bot.deinit();
- // Non-blocking send using REST API
- try api.postMessage(allocator, token, channel, "Hello from Zig!");
- // Connect to gateway in blocking mode (example only)
- // try bot.connect();
- try bot.postMessage(allocator, token, channel, "Hello from Zig!");
+ std.log.err("discord feature not available", .{});
return;
}
}
@@ -130,7 +109,7 @@ pub fn main() !void {
.text = "example input",
.values = &[_]usize{ 1, 2, 3, 4 },
};
- const res = Abi.process(req);
+ const res = try Abi.process(req);
const stdout = std.io.getStdOut().writer();
try stdout.print("{s}: {d}\n", .{ res.message, res.result });
}
diff --git a/src/mlai/mlai.zig b/src/mlai/mlai.zig
new file mode 100644
index 000000000..6b997ade7
--- /dev/null
+++ b/src/mlai/mlai.zig
@@ -0,0 +1,44 @@
+const std = @import("std");
+const agent = @import("../agent.zig");
+const wdbx = @import("mlai/wdbx/db.zig");
+
+pub const MLAISystem = struct {
+ allocator: std.mem.Allocator,
+ db: wdbx.Database,
+
+ pub fn init(alloc: std.mem.Allocator, cfg: wdbx.Config) !MLAISystem {
+ return MLAISystem{
+ .allocator = alloc,
+ .db = try wdbx.Database.init(alloc, cfg),
+ };
+ }
+
+ pub fn deinit(self: *MLAISystem) void {
+ self.db.deinit();
+ }
+
+ pub fn processRequest(self: *MLAISystem, query: []const u8) ![]u8 {
+ const persona = router(query);
+ var response = try agent.respond(persona, query, self.allocator);
+ errdefer self.allocator.free(response);
+ try self.db.storeInteraction(query, response, persona);
+ return response;
+ }
+};
+
+pub fn router(query: []const u8) agent.PersonaType {
+ if (std.mem.indexOf(u8, query, "help") != null) return .EmpatheticAnalyst;
+ if (std.mem.indexOf(u8, query, "explain") != null) return .DirectExpert;
+ return .AdaptiveModerator;
+}
+
+pub test "process request stores data" {
+ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
+ defer _ = gpa.deinit();
+ var system = try MLAISystem.init(gpa.allocator(), .{ .shard_count = 2 });
+ defer system.deinit();
+ const reply = try system.processRequest("help me");
+ defer gpa.allocator().free(reply);
+ const e = system.db.retrieve("help me") orelse return error.NotFound;
+ try std.testing.expectEqualStrings(e.value, reply);
+}
diff --git a/src/mlai/wdbx/db.zig b/src/mlai/wdbx/db.zig
new file mode 100644
index 000000000..5dc96cb6e
--- /dev/null
+++ b/src/mlai/wdbx/db.zig
@@ -0,0 +1,111 @@
+const std = @import("std");
+const agent = @import("../../agent.zig");
+
+pub const Config = struct {
+ shard_count: u32 = 3,
+};
+
+const prime_numbers = [_]u64{31, 37, 43, 47, 53, 59, 61, 67, 71, 73};
+
+pub fn primeHash(data: []const u8, seed: u64) u64 {
+ var hash: u64 = seed | 1;
+ for (data) |b| {
+ hash ^= @intCast(u64, b);
+ hash *= 0x9e3779b97f4a7c15;
+ hash = (hash << 7) | (hash >> 57);
+ }
+ return hash;
+}
+
+pub fn calculateShard(key: []const u8, prime: u64) usize {
+ return @intCast(usize, primeHash(key, 0) % prime);
+}
+
+pub const Entry = struct {
+ key: []u8,
+ value: []u8,
+ persona: agent.PersonaType,
+ version: u64,
+};
+
+pub const Shard = struct {
+ id: u64,
+ entries: std.ArrayList(Entry),
+
+ pub fn init(alloc: std.mem.Allocator, id: u64) !Shard {
+ return Shard{ .id = id, .entries = std.ArrayList(Entry).init(alloc) };
+ }
+
+ pub fn store(self: *Shard, key: []const u8, value: []const u8, p: agent.PersonaType) !void {
+ try self.entries.append(.{
+ .key = try self.entries.allocator.dupe(u8, key),
+ .value = try self.entries.allocator.dupe(u8, value),
+ .persona = p,
+ .version = @as(u64, @intCast(std.time.nanoTimestamp())),
+ });
+ }
+
+ pub fn retrieve(self: *Shard, key: []const u8) ?Entry {
+ var i: usize = self.entries.items.len;
+ while (i > 0) {
+ i -= 1;
+ if (std.mem.eql(u8, self.entries.items[i].key, key)) {
+ return self.entries.items[i];
+ }
+ }
+ return null;
+ }
+};
+
+pub const Database = struct {
+ allocator: std.mem.Allocator,
+ shards: []Shard,
+ prime: u64,
+
+ pub fn init(alloc: std.mem.Allocator, cfg: Config) !Database {
+ const count = cfg.shard_count;
+ if (count == 0 or count > prime_numbers.len) return error.InvalidShardCount;
+ var shards = try alloc.alloc(Shard, count);
+ for (shards, 0..) |*s, i| {
+ s.* = try Shard.init(alloc, prime_numbers[i]);
+ }
+ return Database{ .allocator = alloc, .shards = shards, .prime = prime_numbers[count - 1] };
+ }
+
+ pub fn deinit(self: *Database) void {
+ for (self.shards) |*s| {
+ for (s.entries.items) |e| {
+ self.allocator.free(e.key);
+ self.allocator.free(e.value);
+ }
+ s.entries.deinit();
+ }
+ self.allocator.free(self.shards);
+ }
+
+ fn shardIndex(self: *Database, key: []const u8) usize {
+ return calculateShard(key, self.prime) % self.shards.len;
+ }
+
+ pub fn storeInteraction(self: *Database, req: []const u8, resp: []const u8, p: agent.PersonaType) !void {
+ const idx = self.shardIndex(req);
+ try self.shards[idx].store(req, resp, p);
+ }
+
+ pub fn retrieve(self: *Database, key: []const u8) ?Entry {
+ const idx = self.shardIndex(key);
+ return self.shards[idx].retrieve(key);
+ }
+};
+
+pub const WDBXError = error{InvalidShardCount};
+
+pub test "basic store and retrieve" {
+ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
+ defer _ = gpa.deinit();
+ var db = try Database.init(gpa.allocator(), .{ .shard_count = 2 });
+ defer db.deinit();
+ try db.storeInteraction("hello", "world", .EmpatheticAnalyst);
+ const e = db.retrieve("hello") orelse return error.NotFound;
+ try std.testing.expectEqualStrings(e.value, "world");
+}
diff --git a/src/platform.zig b/src/platform.zig
index 8b28b37db..7f6075c76 100644
--- a/src/platform.zig
+++ b/src/platform.zig
@@ -1,11 +1,14 @@
//! Platform-specific optimizations and abstractions
+const std = @import("std");
+const builtin = @import("builtin");
+
pub const PlatformLayer = struct {
/// iOS-specific optimizations for a-Shell
pub const iOS = struct {
const max_memory = 256 * 1024 * 1024; // 256MB limit
const max_file_handles = 256;
-
+
pub fn init() !void {
// Set up iOS-specific memory limits
if (builtin.os.tag == .ios) {
@@ -13,24 +16,15 @@ pub const PlatformLayer = struct {
const dispatch = @cImport({
@cInclude("dispatch/dispatch.h");
});
-
- dispatch.dispatch_source_set_event_handler(
- dispatch.dispatch_source_create(
- dispatch.DISPATCH_SOURCE_TYPE_MEMORYPRESSURE,
- 0,
- dispatch.DISPATCH_MEMORYPRESSURE_WARN,
- dispatch.dispatch_get_main_queue()
- ),
- struct {
- fn handler() callconv(.C) void {
- // Aggressive memory cleanup
- _ = gpa.collectGarbage();
- }
- }.handler
- );
+
+ dispatch.dispatch_source_set_event_handler(dispatch.dispatch_source_create(dispatch.DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, dispatch.DISPATCH_MEMORYPRESSURE_WARN, dispatch.dispatch_get_main_queue()), struct {
+ fn handler() callconv(.C) void {
+ // Aggressive memory cleanup placeholder
+ }
+ }.handler);
}
}
-
+
pub fn openFile(path: []const u8) !std.fs.File {
// iOS sandbox restrictions
const allowed_prefixes = [_][]const u8{
@@ -38,72 +32,71 @@ pub const PlatformLayer = struct {
"~/tmp/",
"/private/var/mobile/",
};
-
+
for (allowed_prefixes) |prefix| {
if (std.mem.startsWith(u8, path, prefix)) {
return std.fs.cwd().openFile(path, .{});
}
}
-
+
return error.SandboxViolation;
}
};
-
+
/// Windows-specific console optimizations
pub const Windows = struct {
+ pub const ConPTY = struct {
+ handle: *anyopaque,
+ input: *anyopaque,
+ output: *anyopaque,
+ };
pub fn enableAnsiColors() !void {
const kernel32 = @cImport({
@cInclude("windows.h");
});
-
+
const stdout_handle = kernel32.GetStdHandle(kernel32.STD_OUTPUT_HANDLE);
var mode: kernel32.DWORD = 0;
-
+
if (kernel32.GetConsoleMode(stdout_handle, &mode) == 0) {
return error.GetConsoleModeFailed;
}
-
+
mode |= kernel32.ENABLE_VIRTUAL_TERMINAL_PROCESSING;
mode |= kernel32.ENABLE_PROCESSED_OUTPUT;
-
+
if (kernel32.SetConsoleMode(stdout_handle, mode) == 0) {
return error.SetConsoleModeFailed;
}
}
-
+
pub fn createConPTY(cols: u16, rows: u16) !ConPTY {
const kernel32 = @cImport({
@cInclude("windows.h");
@cInclude("consoleapi.h");
});
-
- var size = kernel32.COORD{ .X = cols, .Y = rows };
+
+ const size = kernel32.COORD{ .X = cols, .Y = rows };
var input_pipe: kernel32.HANDLE = undefined;
var output_pipe: kernel32.HANDLE = undefined;
var pty: kernel32.HPCON = undefined;
-
+
// Create pipes
if (kernel32.CreatePipe(&input_pipe, null, null, 0) == 0) {
return error.CreatePipeFailed;
}
-
+
if (kernel32.CreatePipe(null, &output_pipe, null, 0) == 0) {
return error.CreatePipeFailed;
}
-
+
// Create pseudo console
- const hr = kernel32.CreatePseudoConsole(
- size,
- input_pipe,
- output_pipe,
- 0,
- &pty
- );
-
+ const hr = kernel32.CreatePseudoConsole(size, input_pipe, output_pipe, 0, &pty);
+
if (hr != kernel32.S_OK) {
return error.CreatePseudoConsoleFailed;
}
-
+
return ConPTY{
.handle = pty,
.input = input_pipe,
@@ -111,52 +104,52 @@ pub const PlatformLayer = struct {
};
}
};
-
+
/// Linux io_uring for maximum async I/O performance
pub const Linux = struct {
pub const AsyncIO = struct {
ring: std.os.linux.io_uring,
submission_queue: []std.os.linux.io_uring_sqe,
completion_queue: []std.os.linux.io_uring_cqe,
-
+
pub fn init(queue_depth: u13) !AsyncIO {
var ring: std.os.linux.io_uring = undefined;
const params = std.os.linux.io_uring_params{};
-
+
try std.os.linux.io_uring_setup(queue_depth, ¶ms, &ring);
-
+
return AsyncIO{
.ring = ring,
.submission_queue = undefined, // Mapped separately
.completion_queue = undefined,
};
}
-
+
pub fn readFile(self: *AsyncIO, path: []const u8, buffer: []u8) !usize {
const fd = try std.os.open(path, .{ .ACCMODE = .RDONLY }, 0);
defer std.os.close(fd);
-
+
// Get submission queue entry
const sqe = try self.getSQE();
std.os.linux.io_uring_prep_read(sqe, fd, buffer.ptr, buffer.len, 0);
sqe.user_data = 1;
-
+
// Submit and wait
_ = try std.os.linux.io_uring_submit(&self.ring);
-
+
var cqe: *std.os.linux.io_uring_cqe = undefined;
_ = try std.os.linux.io_uring_wait_cqe(&self.ring, &cqe);
defer std.os.linux.io_uring_cqe_seen(&self.ring, cqe);
-
+
if (cqe.res < 0) {
return error.ReadFailed;
}
-
+
return @intCast(cqe.res);
}
};
};
-
+
/// macOS unified memory optimizations
pub const macOS = struct {
pub fn createUnifiedBuffer(size: usize) ![]u8 {
@@ -164,28 +157,18 @@ pub const PlatformLayer = struct {
@cInclude("mach/mach.h");
@cInclude("mach/vm_map.h");
});
-
+
var address: mach.vm_address_t = 0;
- const kr = mach.vm_allocate(
- mach.mach_task_self(),
- &address,
- size,
- mach.VM_FLAGS_ANYWHERE
- );
-
+ const kr = mach.vm_allocate(mach.mach_task_self(), &address, size, mach.VM_FLAGS_ANYWHERE);
+
if (kr != mach.KERN_SUCCESS) {
return error.VmAllocateFailed;
}
-
+
// Mark as purgeable for memory pressure handling
var state: mach.vm_purgable_t = mach.VM_PURGABLE_NONVOLATILE;
- _ = mach.vm_purgable_control(
- mach.mach_task_self(),
- address,
- mach.VM_PURGABLE_SET_STATE,
- &state
- );
-
+ _ = mach.vm_purgable_control(mach.mach_task_self(), address, mach.VM_PURGABLE_SET_STATE, &state);
+
return @as([*]u8, @ptrFromInt(address))[0..size];
}
};
diff --git a/src/tui.zig b/src/tui.zig
index 789724809..47386e749 100644
--- a/src/tui.zig
+++ b/src/tui.zig
@@ -28,7 +28,6 @@ pub const Command = union(enum) {
};
pub const Term = struct {
- orig_term: ?std.os.termios = null,
buf: [1024]u8 = undefined,
stdin: std.fs.File,
stdout: std.fs.File,
@@ -37,17 +36,10 @@ pub const Term = struct {
var t = Term{
.stdin = std.io.getStdIn(),
.stdout = std.io.getStdOut(),
- .orig_term = null,
};
if (std.posix.isatty(0)) {
- const tio = std.os.tcgetattr(0) catch return TuiError.TerminalError;
- t.orig_term = tio;
- var raw = tio;
- raw.lflag &= ~(std.os.termiosFlags.ECHO | std.os.termiosFlags.ICANON);
- raw.c_cc[std.os.VMIN] = 1;
- raw.c_cc[std.os.VTIME] = 0;
- std.os.tcsetattr(0, std.os.TCSANOW, &raw) catch return TuiError.TerminalError;
+ // Terminal configuration skipped in this minimal build
}
try t.clearScreen();
@@ -55,9 +47,6 @@ pub const Term = struct {
}
pub fn deinit(self: *Term) void {
- if (self.orig_term) |orig| {
- _ = std.os.tcsetattr(0, std.os.TCSANOW, &orig) catch {};
- }
self.clearScreen() catch {};
}
@@ -77,7 +66,7 @@ pub const Term = struct {
pub fn parseCommand(self: Term, line: []const u8) TuiError!Command {
_ = self;
- var it = std.mem.tokenize(u8, line, " ");
+ var it = std.mem.tokenizeScalar(u8, line, ' ');
const cmd = it.next() orelse return TuiError.InvalidCommand;
if (std.mem.eql(u8, cmd, "help")) {