code wiki / (root) / nx_claude_bridge.nx

nx_claude_bridge.nx source

↩ module page · 163 lines · 7935 B

1// nx_claude_bridge.nx -- the CLAUDE <-> NISHI bridge (the "works with you" gap): a sovereign command 2// protocol. Claude writes commands (tool + args) to knowledge/bridge/cmd.txt; this organ reads them, 3// runs the REAL sovereign tool for each (echo / cat / ls -- inline coreutils), and writes the results 4// to knowledge/bridge/result.txt (and stdout). Claude reads the result = the loop where the operator 5// AND Claude drive the Nishi system together. More tools wire in as more dispatch arms. 6// No persistent-hardware writes (Rule 26). expect_exit: 0 license_tier: ORIGINAL 7import "nx_syscalls.nx" 8const K_MAGIC_65536: i64 = 65536 9const K_MAGIC_1000000: i64 = 1000000 10const K_MAGIC_1048576: i64 = 1048576 11const K_MAGIC_1024: i64 = 1024 12 13func cb_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 14func cb_streq(a: *u8, b: *u8) -> i64 { var i: i64=0; while 1==1 { if a[i]!=b[i] { return 0 } if a[i]==(0 as u8) { return 1 } i=i+1 } return 1 } 15func cb_app(out: *u8, off: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){ out[off+i]=s[i]; i=i+1 } return off+i } 16func cb_appn(out: *u8, off: i64, src: *u8, n: i64) -> i64 { var i: i64=0; while i<n { out[off+i]=src[i]; i=i+1 } return off+i } 17 18func cb_cat(path: *u8, out: *u8, o: i64) -> i64 { 19 let lenp: *i64 = sys_mmap(8) as *i64 20 let p: *u8 = sys_read_file(path, lenp) 21 var w: i64 = cb_app(out, o, "[cat " as *u8); w = cb_app(out, w, path); w = cb_app(out, w, "]\n" as *u8) 22 if (p as i64)==0 { return cb_app(out, w, "(not found)\n" as *u8) } 23 w = cb_appn(out, w, p, lenp[0]) 24 return cb_app(out, w, "\n" as *u8) 25} 26func cb_ls(path: *u8, out: *u8, o: i64) -> i64 { 27 let fd: i64 = sys_openat_rd(path) 28 var w: i64 = cb_app(out, o, "[ls " as *u8); w = cb_app(out, w, path); w = cb_app(out, w, "] " as *u8) 29 if fd<0 { return cb_app(out, w, "(no dir)\n" as *u8) } 30 let db: *u8 = sys_mmap(K_MAGIC_65536) 31 let nb: i64 = sys_getdents64(fd, db, K_MAGIC_65536) 32 sys_close(fd) 33 var off: i64=0 34 while off<nb { 35 let reclen: i64 = (db[off+16] as i64)+((db[off+17] as i64)*256) 36 if reclen<=0 { off=nb } else { 37 var j: i64=off+19 38 while db[j]!=(0 as u8){ out[w]=db[j]; w=w+1; j=j+1 } 39 out[w]=0x20 as u8; w=w+1 40 off=off+reclen 41 } 42 } 43 return cb_app(out, w, "\n" as *u8) 44} 45func cb_sleep_ms(ms: i64) -> i64 { 46 let ts: *i64 = sys_mmap(16) as *i64 47 ts[0] = ms / 1000 48 ts[1] = (ms % 1000) * K_MAGIC_1000000 49 return __syscall(SYS_CLOCK_NANOSLEEP, 0, 0, ts, 0, 0, 0) 50} 51// run ANY sovereign organ from a jobfile (line1 = elf path, lines2.. = one arg each VERBATIM -- no shell, 52// no quoting). Forks/execs directly with a 60s watchdog (kill -9), captures stdout+stderr, folds it into the 53// result. This is what lifts the bridge from 3 inline coreutils to the WHOLE organ set = "Claude in a Nishi CLI". 54func cb_run(jobfile: *u8, out: *u8, o: i64) -> i64 { 55 var w: i64 = cb_app(out, o, "[run " as *u8); w = cb_app(out, w, jobfile); w = cb_app(out, w, "]\n" as *u8) 56 let lenp: *i64 = sys_mmap(8) as *i64; lenp[0] = 0 57 let raw: *u8 = sys_read_file(jobfile, lenp) 58 if (raw as i64) == 0 { return cb_app(out, w, "(jobfile not found)\n" as *u8) } 59 let n: i64 = lenp[0] 60 let buf: *u8 = sys_mmap(n + 8) 61 var ci: i64 = 0; while ci < n { buf[ci] = raw[ci]; ci = ci + 1 } buf[n] = 10 as u8 62 let cargv: *i64 = sys_mmap(8 * 128) as *i64 63 var ac: i64 = 0; var i: i64 = 0; var start: i64 = 0 64 while i <= n { 65 if (buf[i] as i64) == 10 { 66 var end: i64 = i 67 if end > start { if (buf[end - 1] as i64) == 13 { end = end - 1 } } 68 if end > start { buf[end] = 0 as u8; if ac < 127 { cargv[ac] = ((buf as i64) + start) as i64; ac = ac + 1 } } 69 start = i + 1 70 } 71 i = i + 1 72 } 73 cargv[ac] = 0 74 if ac == 0 { return cb_app(out, w, "(empty jobfile)\n" as *u8) } 75 let tmp: *u8 = "/tmp/nxbridge_run.out\x00" as *u8 76 let out_fd: i64 = sys_openat_wr(tmp, 0x180) 77 if out_fd < 0 { return cb_app(out, w, "(cannot open capture file)\n" as *u8) } 78 let pid: i64 = sys_fork() 79 if pid == 0 { 80 sys_dup3(out_fd, 1, 0) 81 sys_dup3(out_fd, 2, 0) 82 let envp: *i64 = sys_mmap(16) as *i64 83 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0 84 sys_execve(cargv[0] as *u8, cargv, envp) 85 sys_exit(127) 86 } 87 let st: *i64 = sys_mmap(16) as *i64 88 var ticks: i64 = 0; var rc: i64 = 124; var waiting: i64 = 1 89 while waiting == 1 { 90 let wr: i64 = sys_wait4(pid, st, 1) 91 if wr == pid { 92 waiting = 0 93 if (st[0] % 128) != 0 { rc = 128 + (st[0] % 128) } else { rc = (st[0] >> 8) & 0xff } 94 } else { 95 ticks = ticks + 1 96 if ticks >= 300 { waiting = 0; nx_kill(pid, 9); sys_wait4(pid, st, 0); rc = 124 } 97 else { cb_sleep_ms(200) } 98 } 99 } 100 sys_close(out_fd) 101 let cp: *i64 = sys_mmap(8) as *i64; cp[0] = 0 102 let cap: *u8 = sys_read_file(tmp, cp) 103 if (cap as i64) != 0 { w = cb_appn(out, w, cap, cp[0]) } 104 w = cb_app(out, w, "[exit=" as *u8) 105 let nb: *u8 = sys_mmap(16); var m: i64 = rc; var k: i64 = 0 106 if m == 0 { nb[0] = 48 as u8; k = 1 } 107 while m > 0 { nb[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 108 var z: i64 = 0; while z < k { out[w] = nb[k - 1 - z]; w = w + 1; z = z + 1 } 109 return cb_app(out, w, "]\n" as *u8) 110} 111func cb_dispatch(tool: *u8, arg: *u8, out: *u8, o: i64) -> i64 { 112 if cb_streq(tool, "run\x00" as *u8) == 1 { return cb_run(arg, out, o) } 113 if cb_streq(tool, "echo\x00" as *u8)==1 { var w: i64=cb_app(out,o,"[echo] " as *u8); w=cb_app(out,w,arg); return cb_app(out,w,"\n" as *u8) } 114 if cb_streq(tool, "cat\x00" as *u8)==1 { return cb_cat(arg, out, o) } 115 if cb_streq(tool, "ls\x00" as *u8)==1 { return cb_ls(arg, out, o) } 116 var w: i64 = cb_app(out, o, "[?] unknown tool: " as *u8); w = cb_app(out, w, tool); return cb_app(out, w, "\n" as *u8) 117} 118 119func main() -> i64 { 120 let lenp: *i64 = sys_mmap(8) as *i64 121 let cmd: *u8 = sys_read_file("knowledge/bridge/cmd.txt\x00" as *u8, lenp) 122 if (cmd as i64)==0 { cb_puts("BRIDGE RED: knowledge/bridge/cmd.txt not found\n" as *u8); sys_exit(1); return 1 } 123 let n: i64 = lenp[0] 124 125 let out: *u8 = sys_mmap(K_MAGIC_1048576) 126 var o: i64 = cb_app(out, 0, "=== NISHI <-> CLAUDE BRIDGE :: results ===\n" as *u8) 127 var ncmd: i64 = 0 128 129 var i: i64=0 130 while i<n { 131 let ls: i64=i 132 var le: i64=i 133 var f: i64=1 134 while f==1 { if le>=n { f=0 } else { if cmd[le]==(0x0A as u8) { f=0 } else { le=le+1 } } } 135 var lineend: i64=le 136 if lineend>ls { if cmd[lineend-1]==(0x0D as u8) { lineend=lineend-1 } } 137 if lineend>ls { if cmd[ls]!=(0x23 as u8) { 138 var sp: i64=ls 139 var gs: i64=1 140 while gs==1 { if sp>=lineend { gs=0 } else { if cmd[sp]==(0x20 as u8) { gs=0 } else { sp=sp+1 } } } 141 let tb: *u8 = sys_mmap(64) 142 let ab: *u8 = sys_mmap(K_MAGIC_1024) 143 var ti: i64=0 144 while (ls+ti)<sp { tb[ti]=cmd[ls+ti]; ti=ti+1 } 145 tb[ti]=0 as u8 146 var ai: i64=0 147 if sp<lineend { var k: i64=sp+1; while k<lineend { ab[ai]=cmd[k]; ai=ai+1; k=k+1 } } 148 ab[ai]=0 as u8 149 o = cb_dispatch(tb, ab, out, o) 150 ncmd=ncmd+1 151 } } 152 i=le+1 153 } 154 155 let fd: i64 = sys_openat_wr("knowledge/bridge/result.txt\x00" as *u8, 0x1a4) 156 if fd>0 { sys_write(fd, out, o); sys_close(fd) } 157 sys_write(1, out, o) 158 cb_puts("BRIDGE OK ncmds=" as *u8) 159 let nb: *u8=sys_mmap(16); var m: i64=ncmd; var k: i64=0; if m==0{nb[0]=48 as u8;k=1} while m>0{nb[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var z: i64=0; let rb: *u8=sys_mmap(16); while z<k{rb[z]=nb[k-1-z];z=z+1} sys_write(1,rb,k) 160 cb_puts(" -> knowledge/bridge/result.txt\n" as *u8) 161 sys_exit(0) 162 return 0 163}