diff --git a/npl/nipbox/nipbox.nim b/npl/nipbox/nipbox.nim index 1190e6b..274aa7b 100644 --- a/npl/nipbox/nipbox.nim +++ b/npl/nipbox/nipbox.nim @@ -7,6 +7,15 @@ import libc as lb import editor import term # Phase 26: Visual Cortex +# Phase 30: Pledge Constants +const + PLEDGE_STDIO* = 0x0001'u64 + PLEDGE_RPATH* = 0x0002'u64 + PLEDGE_WPATH* = 0x0004'u64 + PLEDGE_INET* = 0x0008'u64 + PLEDGE_EXEC* = 0x0010'u64 + PLEDGE_ALL* = 0xFFFFFFFFFFFFFFFF'u64 + type PipelineData = seq[Node] @@ -78,6 +87,57 @@ proc render_output(data: PipelineData) = print(repeat("-", 40) & "\n") print("Total: " & $data.len & " objects.\n\n") +# --- PHASE 30: WORKER SYSTEM --- + +type + WorkerPacket = ref object + command_fn: proc(args: seq[string], input: PipelineData): PipelineData + args: seq[string] + input: PipelineData + output: PipelineData + exit_code: int + pledge_mask: uint64 + +# Worker trampoline (C-compatible) +proc dispatch_worker(arg: uint64) {.cdecl.} = + let packet = cast[ptr WorkerPacket](arg) + if packet == nil: return + + # Apply pledge + if packet.pledge_mask != PLEDGE_ALL: + discard lb.pledge(packet.pledge_mask) + + # Execute command + try: + packet.output = packet.command_fn(packet.args, packet.input) + packet.exit_code = 0 + except: + packet.output = @[] + packet.exit_code = 1 + +# Helper to spawn command as worker +proc spawn_command(cmd_fn: proc(args: seq[string], input: PipelineData): PipelineData, + args: seq[string], input: PipelineData, + pledge: uint64): PipelineData = + var packet = WorkerPacket( + command_fn: cmd_fn, + args: args, + input: input, + output: @[], + exit_code: 0, + pledge_mask: pledge + ) + + let packet_ptr = cast[uint64](cast[pointer](packet)) + let fid = lb.spawn(dispatch_worker, packet_ptr) + + if fid < 0: + # Spawn failed, run inline + return cmd_fn(args, input) + + discard lb.join(fid) + return packet.output + # --- COMMANDS --- proc cmd_ls*(args: seq[string], input: PipelineData): PipelineData = @@ -345,7 +405,9 @@ proc dispatch_command(name: string, args: seq[string], of "edit": return cmd_edit(args, input) of "echo": return cmd_echo(args, input) of "where": return cmd_where(args, input) - of "http.get": return cmd_http_get(args, input) + of "http.get": + # Phase 30: Spawn in worker with INET pledge only (no file access) + return spawn_command(cmd_http_get, args, input, PLEDGE_INET or PLEDGE_STDIO) of "from_json": return cmd_from_json(args, input) of "mount": return cmd_mount(args, input) of "matrix": return cmd_matrix(args, input)