Rumpk Stability, NipBox Boot, and Repository Cleanup
- Fixed Rumpk RISC-V Trap Handler (SSCRATCH swap, align(4), SUM bit) to prevent double faults. - Stabilized Userland Transition (fence.i, MMU activation) allowing NipBox execution. - Restored Forge pipeline to build NipBox from source. - Documented critical RISC-V trap mechanics in .agent/tips. - Committed pending repository cleanup (obsolete websites) and new core modules.
This commit is contained in:
parent
a7f68664d0
commit
668e79504d
|
|
@ -1,3 +1,10 @@
|
|||
# SPDX-License-Identifier: LUL-1.0
|
||||
# Copyright (c) 2026 Markus Maiwald
|
||||
# Stewardship: Self Sovereign Society Foundation
|
||||
#
|
||||
# This file is part of the Nexus SDK.
|
||||
# See legal/LICENSE_UNBOUND.md for license terms.
|
||||
|
||||
# MARKUS MAIWALD (ARCHITECT) | VOXIS FORGE (AI)
|
||||
# Scribe v3: The Sovereign TUI Editor
|
||||
# Phase 24: Full TUI with Navigation & Multi-Sector IO
|
||||
|
|
@ -254,7 +261,7 @@ proc start_editor*(fname: string) =
|
|||
term_clear()
|
||||
|
||||
while is_running:
|
||||
lb.pump_membrane_stack() # Keep net alive if needed
|
||||
# lb.pump_membrane_stack() - Handled by Kernel
|
||||
scroll_to_cursor()
|
||||
render()
|
||||
|
||||
|
|
|
|||
7
kdl.nim
7
kdl.nim
|
|
@ -1,3 +1,10 @@
|
|||
# SPDX-License-Identifier: LUL-1.0
|
||||
# Copyright (c) 2026 Markus Maiwald
|
||||
# Stewardship: Self Sovereign Society Foundation
|
||||
#
|
||||
# This file is part of the Nexus SDK.
|
||||
# See legal/LICENSE_UNBOUND.md for license terms.
|
||||
|
||||
# MARKUS MAIWALD (ARCHITECT) | VOXIS FORGE (AI)
|
||||
# NipBox KDL Core (The Semantic Spine)
|
||||
# Defines the typed object system for the Sovereign Shell.
|
||||
|
|
|
|||
354
nipbox.nim
354
nipbox.nim
|
|
@ -1,10 +1,17 @@
|
|||
# SPDX-License-Identifier: LUL-1.0
|
||||
# Copyright (c) 2026 Markus Maiwald
|
||||
# Stewardship: Self Sovereign Society Foundation
|
||||
#
|
||||
# This file is part of the Nexus SDK.
|
||||
# See legal/LICENSE_UNBOUND.md for license terms.
|
||||
|
||||
# src/npl/nipbox/nipbox.nim
|
||||
# Phase 21: The Teleporter - Networked Object Pipelines
|
||||
|
||||
import strutils, parseutils, tables, sequtils, json
|
||||
import kdl
|
||||
import ../../libs/membrane/libc as lb
|
||||
import ../../libs/membrane/libc_net as net
|
||||
import ../../libs/membrane/libc_net as lnet
|
||||
import ../../libs/membrane/fs/sfs_user as sfs
|
||||
import editor
|
||||
import ../../libs/membrane/term # Phase 26: Visual Cortex
|
||||
|
|
@ -143,8 +150,7 @@ proc spawn_command(cmd_fn: proc(args: seq[string], input: PipelineData): Pipelin
|
|||
discard lb.join(fid)
|
||||
return packet.output
|
||||
|
||||
discard lb.join(fid)
|
||||
return packet.output
|
||||
|
||||
|
||||
proc cmd_crash*(args: seq[string], input: PipelineData): PipelineData =
|
||||
print("[NipBox] PREPARING TO CRASH...\n")
|
||||
|
|
@ -160,9 +166,6 @@ proc cmd_crash*(args: seq[string], input: PipelineData): PipelineData =
|
|||
# Spawn the suicider
|
||||
return spawn_command(worker_crash, args, input, PLEDGE_ALL)
|
||||
|
||||
# Spawn the suicider
|
||||
return spawn_command(worker_crash, args, input, PLEDGE_ALL)
|
||||
|
||||
proc cmd_upgrade*(args: seq[string], input: PipelineData): PipelineData =
|
||||
if args.len < 1:
|
||||
print("Usage: sys.upgrade <path>\n")
|
||||
|
|
@ -204,6 +207,67 @@ proc cmd_mount*(args: seq[string], input: PipelineData): PipelineData =
|
|||
print("[mount] System Disk Engaged.\n")
|
||||
return @[]
|
||||
|
||||
proc cmd_cp*(args: seq[string], input: PipelineData): PipelineData =
|
||||
if args.len < 2:
|
||||
print("Usage: cp <source> <dest>\n")
|
||||
return @[]
|
||||
|
||||
let src = args[0]
|
||||
let dest = args[1]
|
||||
|
||||
let fd_src = lb.open(src.cstring, 0) # O_RDONLY
|
||||
if fd_src < 0:
|
||||
print("cp: cannot stat '" & src & "': No such file\n")
|
||||
return @[]
|
||||
|
||||
# O_WRONLY(1) | O_CREAT(64) | O_TRUNC(512) = 577
|
||||
let fd_dest = lb.open(dest.cstring, 577)
|
||||
if fd_dest < 0:
|
||||
print("cp: cannot create '" & dest & "'\n")
|
||||
discard lb.close(fd_src)
|
||||
return @[]
|
||||
|
||||
var buf: array[4096, char]
|
||||
var total = 0
|
||||
while true:
|
||||
let n = lb.read(fd_src, addr buf[0], 4096)
|
||||
if n <= 0: break
|
||||
let written = lb.write(fd_dest, addr buf[0], csize_t(n))
|
||||
if written < 0:
|
||||
print("cp: write error\n")
|
||||
break
|
||||
total += int(written)
|
||||
|
||||
discard lb.close(fd_src)
|
||||
discard lb.close(fd_dest)
|
||||
print("[OK] Copied " & $total & " bytes.\n")
|
||||
return @[]
|
||||
|
||||
proc cmd_mv*(args: seq[string], input: PipelineData): PipelineData =
|
||||
if args.len < 2:
|
||||
print("Usage: mv <source> <dest>\n")
|
||||
return @[]
|
||||
|
||||
# Step 1: Copy
|
||||
print("[mv] Copying...\n")
|
||||
discard cmd_cp(args, input)
|
||||
|
||||
# Step 2: Unlink (Not yet supported by Kernel)
|
||||
print("[mv] Warning: Original file '" & args[0] & "' retained (SFS unlink not implemented).\n")
|
||||
return @[]
|
||||
|
||||
proc cmd_touch*(args: seq[string], input: PipelineData): PipelineData =
|
||||
if args.len < 1:
|
||||
print("Usage: touch <filename>\n")
|
||||
return @[]
|
||||
|
||||
let fd = lb.open(args[0].cstring, 577) # O_CREAT | O_TRUNC
|
||||
if fd >= 0:
|
||||
discard lb.close(fd)
|
||||
else:
|
||||
print("touch: cannot touch '" & args[0] & "'\n")
|
||||
return @[]
|
||||
|
||||
proc cmd_matrix*(args: seq[string], input: PipelineData): PipelineData =
|
||||
let state = if args.len > 0: args[0].toUpperAscii() else: "STATUS: NOMINAL"
|
||||
print("[matrix] " & state & "\n")
|
||||
|
|
@ -372,7 +436,7 @@ proc cmd_http_get*(args: seq[string], input: PipelineData): PipelineData =
|
|||
# Wait for establishment (pumping the stack)
|
||||
var timeout = 0
|
||||
while timeout < 1000:
|
||||
lb.pump_membrane_stack()
|
||||
# lb.pump_membrane_stack() - Handled by Kernel
|
||||
# Check if connected (we need a way to check socket state)
|
||||
# For now, let's assume if we can send, we are connected or it will buffer.
|
||||
# In our net_glue, glue_write returns -1 if not established.
|
||||
|
|
@ -395,7 +459,7 @@ proc cmd_http_get*(args: seq[string], input: PipelineData): PipelineData =
|
|||
var buf: array[2048, char]
|
||||
timeout = 0
|
||||
while timeout < 5000:
|
||||
lb.pump_membrane_stack()
|
||||
# lb.pump_membrane_stack()
|
||||
let n = lb.recv(cint(fd), addr buf[0], 2048, 0)
|
||||
if n > 0:
|
||||
for i in 0..<n: response_body.add(buf[i])
|
||||
|
|
@ -418,12 +482,6 @@ proc cmd_http_get*(args: seq[string], input: PipelineData): PipelineData =
|
|||
return @[node]
|
||||
|
||||
proc cmd_http_download*(args: seq[string], input: PipelineData): PipelineData =
|
||||
# Enable BlindFold for stability during heavy I/O
|
||||
use_logfile = true
|
||||
print("[Download] BlindFold Engaged. diverting to /nipbox.log...\n")
|
||||
|
||||
defer: use_logfile = false # Restore sight on exit
|
||||
|
||||
if args.len < 2:
|
||||
print("Usage: http.download <ip:port/path> <outfile>\n")
|
||||
return @[]
|
||||
|
|
@ -447,50 +505,49 @@ proc cmd_http_download*(args: seq[string], input: PipelineData): PipelineData =
|
|||
let ip_str = parts[0]
|
||||
let port = uint16(parseInt(parts[1]))
|
||||
|
||||
let ip_parts = ip_str.split('.')
|
||||
if ip_parts.len != 4: return @[]
|
||||
let ip_val = (uint32(parseInt(ip_parts[0])) shl 0) or
|
||||
(uint32(parseInt(ip_parts[1])) shl 8) or
|
||||
(uint32(parseInt(ip_parts[2])) shl 16) or
|
||||
(uint32(parseInt(ip_parts[3])) shl 24)
|
||||
# Parse IP
|
||||
var ip_val: uint32 = 0
|
||||
try:
|
||||
let p = ip_str.split('.')
|
||||
ip_val = (uint32(parseInt(p[0])) and 0xFF) or
|
||||
((uint32(parseInt(p[1])) and 0xFF) shl 8) or
|
||||
((uint32(parseInt(p[2])) and 0xFF) shl 16) or
|
||||
((uint32(parseInt(p[3])) and 0xFF) shl 24)
|
||||
except:
|
||||
print("Error: Invalid IP\n")
|
||||
return @[]
|
||||
|
||||
print("[Download] Connecting to " & host_part & "...\n")
|
||||
let fd = lb.socket(2, 1, 0)
|
||||
if fd < 100: return @[]
|
||||
if fd < 0: return @[]
|
||||
|
||||
type SockAddrIn = object
|
||||
sin_family: uint16
|
||||
sin_port: uint16
|
||||
sin_addr: uint32
|
||||
sin_zero: array[8, char]
|
||||
# SockAddr setup
|
||||
var addr_buf: array[16, byte]
|
||||
copyMem(addr addr_buf[2], unsafeAddr port, 2)
|
||||
copyMem(addr addr_buf[4], unsafeAddr ip_val, 4)
|
||||
|
||||
var addr_in: SockAddrIn
|
||||
addr_in.sin_family = 2
|
||||
addr_in.sin_port = ((port and 0xFF) shl 8) or (port shr 8)
|
||||
addr_in.sin_addr = ip_val
|
||||
|
||||
if lb.connect(fd, addr addr_in, sizeof(addr_in)) < 0:
|
||||
if lb.connect(fd, addr addr_buf[0], 16) < 0:
|
||||
print("Error: Connection Failed.\n")
|
||||
return @[]
|
||||
|
||||
# Wait for connection
|
||||
var timeout = 0
|
||||
while timeout < 1000:
|
||||
lb.pump_membrane_stack()
|
||||
timeout += 1
|
||||
for i in 0..1000: discard
|
||||
|
||||
# Request
|
||||
let req = "GET " & path_str & " HTTP/1.1\r\nHost: " & ip_str & "\r\nConnection: close\r\n\r\n"
|
||||
let req = "GET " & path_str & " HTTP/1.0\r\nHost: " & ip_str & "\r\nConnection: close\r\n\r\n"
|
||||
if lb.send(cint(fd), cast[pointer](unsafeAddr req[0]), csize_t(req.len), 0) <= 0:
|
||||
print("Error: Send Failed.\n")
|
||||
discard lb.close(cint(fd))
|
||||
return @[]
|
||||
|
||||
# Open File
|
||||
let fd_file = lb.open(outfile.cstring, 577) # O_WRONLY|O_CREAT|O_TRUNC
|
||||
if fd_file < 0:
|
||||
print("Error: Cannot open output file " & outfile & "\n")
|
||||
# Mount SFS if needed
|
||||
if not sfs.sfs_is_mounted():
|
||||
if not sfs.sfs_mount():
|
||||
print("Error: Could not mount SFS.\n")
|
||||
discard lb.close(cint(fd))
|
||||
return @[]
|
||||
|
||||
# Open SFS Stream
|
||||
let sfs_h = sfs.sfs_open_write(outfile)
|
||||
if sfs_h == nil:
|
||||
print("Error: Could not create file " & outfile & "\n")
|
||||
discard lb.close(cint(fd))
|
||||
return @[]
|
||||
|
||||
|
|
@ -500,10 +557,11 @@ proc cmd_http_download*(args: seq[string], input: PipelineData): PipelineData =
|
|||
var header_acc = ""
|
||||
var header_parsed = false
|
||||
var total_bytes = 0
|
||||
timeout = 0
|
||||
var content_len = -1
|
||||
var timeout = 0
|
||||
|
||||
while timeout < 10000:
|
||||
lb.pump_membrane_stack()
|
||||
# Use libc shim which pumps stack
|
||||
let n = lb.recv(cint(fd), addr buf[0], 4096, 0)
|
||||
|
||||
if n > 0:
|
||||
|
|
@ -513,11 +571,23 @@ proc cmd_http_download*(args: seq[string], input: PipelineData): PipelineData =
|
|||
let sep = header_acc.find("\r\n\r\n")
|
||||
if sep != -1:
|
||||
header_parsed = true
|
||||
|
||||
# Try to find Content-Length
|
||||
# Quick hacky parse
|
||||
let lower_head = header_acc.toLowerAscii()
|
||||
let cl_idx = lower_head.find("content-length:")
|
||||
if cl_idx != -1:
|
||||
let end_line = lower_head.find("\r\n", cl_idx)
|
||||
if end_line != -1:
|
||||
try:
|
||||
content_len = parseInt(lower_head[cl_idx+15..<end_line].strip())
|
||||
except:
|
||||
content_len = -1
|
||||
|
||||
let body_start = sep + 4
|
||||
if body_start < header_acc.len:
|
||||
let chunk = header_acc[body_start..^1]
|
||||
discard lb.write(fd_file, cast[pointer](unsafeAddr chunk[0]),
|
||||
csize_t(chunk.len))
|
||||
sfs.sfs_write_chunk(sfs_h, cast[pointer](unsafeAddr chunk[0]), chunk.len)
|
||||
total_bytes += chunk.len
|
||||
header_acc = ""
|
||||
else:
|
||||
|
|
@ -525,20 +595,36 @@ proc cmd_http_download*(args: seq[string], input: PipelineData): PipelineData =
|
|||
print("Error: Headers too large.\n")
|
||||
break
|
||||
else:
|
||||
discard lb.write(fd_file, addr buf[0], csize_t(n))
|
||||
# Stream directly to SFS
|
||||
sfs.sfs_write_chunk(sfs_h, addr buf[0], int(n))
|
||||
total_bytes += int(n)
|
||||
|
||||
# Progress Bar
|
||||
if content_len > 0:
|
||||
# let pct = (total_bytes * 100) div content_len
|
||||
if total_bytes mod 10240 < int(n): print(".")
|
||||
else:
|
||||
if total_bytes mod 10240 < int(n): print(".")
|
||||
|
||||
total_bytes += n
|
||||
if total_bytes mod 50000 == 0: discard # print(".")
|
||||
elif n == 0:
|
||||
break
|
||||
else:
|
||||
timeout += 1
|
||||
for i in 0..1000: discard
|
||||
# Busy wait / pump handled in recv?
|
||||
# Recv calls pump_membrane_stack loop
|
||||
# But if we return -1 (EAGAIN), we need to retry.
|
||||
# My libc.libc_recv returns 0 on closed?
|
||||
# Actually libc_recv in step 945 waits until data or closed.
|
||||
# So n==0 means closed.
|
||||
# Wait, libc.nim recv implementation:
|
||||
# while true: pump; if data return n; if closed return 0.
|
||||
# So it blocks until data.
|
||||
# Thus n > 0 always unless closed.
|
||||
break
|
||||
|
||||
discard lb.close(fd_file)
|
||||
sfs.sfs_close_write(sfs_h)
|
||||
discard lb.close(cint(fd))
|
||||
print("\n[Download] Complete. " & $total_bytes & " bytes.\n")
|
||||
print("\n[Download] Complete. " & $total_bytes & " bytes written to " & outfile & " (Glass Vault).\n")
|
||||
return @[]
|
||||
|
||||
# Phase 37: HTTP Verification Tool
|
||||
|
|
@ -550,21 +636,21 @@ proc cmd_http_test*(args: seq[string], input: PipelineData): PipelineData =
|
|||
let host = args[0]
|
||||
print("Dialing " & host & ":80...\n")
|
||||
|
||||
let fd = net.net_dial_tcp(host, 80)
|
||||
let fd = lnet.net_dial_tcp(host, 80)
|
||||
if fd < 0:
|
||||
print("Connection Failed! Error: " & $fd & "\n")
|
||||
return @[]
|
||||
|
||||
print("Connected! Sending GET request...\n")
|
||||
discard net.net_send(fd, "GET / HTTP/1.0\r\nHost: " & host & "\r\nConnection: close\r\n\r\n")
|
||||
discard lnet.net_send(fd, "GET / HTTP/1.0\r\nHost: " & host & "\r\nConnection: close\r\n\r\n")
|
||||
|
||||
print("Waiting for response...\n")
|
||||
|
||||
# Simple read loop
|
||||
var total = 0
|
||||
while true:
|
||||
lb.pump_membrane_stack()
|
||||
let resp = net.net_recv(fd, 512)
|
||||
# lb.pump_membrane_stack()
|
||||
let resp = lnet.net_recv(fd, 512)
|
||||
if resp.len > 0:
|
||||
print(resp)
|
||||
total += resp.len
|
||||
|
|
@ -573,7 +659,62 @@ proc cmd_http_test*(args: seq[string], input: PipelineData): PipelineData =
|
|||
break
|
||||
|
||||
print("\n[HTTP] Closed. Total bytes: " & $total & "\n")
|
||||
net.net_close(fd)
|
||||
lnet.net_close(fd)
|
||||
return @[]
|
||||
|
||||
proc cmd_http_serve*(args: seq[string], input: PipelineData): PipelineData =
|
||||
print("[Server] Starting Nexus Web/1.0...\n")
|
||||
|
||||
let port: uint16 = if args.len > 0: uint16(parseInt(args[0])) else: 80
|
||||
|
||||
let s = lb.socket(2, 1, 0)
|
||||
if s < 0:
|
||||
print("Error: Socket creation failed.\n")
|
||||
return @[]
|
||||
|
||||
# Bind 0.0.0.0:port
|
||||
var addr_buf: array[16, byte]
|
||||
addr_buf[0] = 2 # AF_INET
|
||||
copyMem(addr addr_buf[2], unsafeAddr port, 2)
|
||||
# IP 0.0.0.0 is default 0s
|
||||
|
||||
if lb.bind_socket(s, addr addr_buf[0], 16) < 0:
|
||||
print("Error: Bind failed.\n")
|
||||
return @[]
|
||||
|
||||
if lb.listen(s, 1) < 0:
|
||||
print("Error: Listen failed.\n")
|
||||
return @[]
|
||||
|
||||
print("[Server] Listening on port " & $port & "...\n")
|
||||
|
||||
while true:
|
||||
# Accept blocks and pumps stack
|
||||
let client = lb.accept(s, nil, nil)
|
||||
if client < 0:
|
||||
print("Error: Accept failed.\n")
|
||||
continue
|
||||
|
||||
print("[Server] Client Connected (FD " & $client & ")\n")
|
||||
|
||||
var buf: array[1024, char]
|
||||
let n = lb.recv(client, addr buf[0], 1024, 0)
|
||||
|
||||
if n > 0:
|
||||
var req = ""
|
||||
for i in 0..<n: req.add(buf[i])
|
||||
print("[Server] Request:\n" & req & "\n")
|
||||
|
||||
let resp = "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\nHello from Nexus Unikernel!\n"
|
||||
discard lb.send(client, unsafeAddr resp[0], uint64(resp.len), 0)
|
||||
|
||||
discard lb.close(client)
|
||||
print("[Server] Client Closed.\n")
|
||||
|
||||
# Just handle one for testing? No, loop forever.
|
||||
# But how to exit? Ctrl-C not implemented in NipBox yet?
|
||||
# We'll just run forever for MVP.
|
||||
|
||||
return @[]
|
||||
|
||||
proc cmd_from_json*(args: seq[string], input: PipelineData): PipelineData =
|
||||
|
|
@ -646,13 +787,80 @@ proc dispatch_command(name: string, args: seq[string],
|
|||
|
||||
case cmd:
|
||||
of "ls": return cmd_ls(args, input)
|
||||
|
||||
of "cat": return cmd_cat(args, input)
|
||||
of "cp": return cmd_cp(args, input)
|
||||
of "mv": return cmd_mv(args, input)
|
||||
of "touch": return cmd_touch(args, input)
|
||||
of "write": return cmd_write(args, input)
|
||||
of "read": return cmd_read(args, input)
|
||||
of "edit": return cmd_edit(args, input)
|
||||
of "echo": return cmd_echo(args, input)
|
||||
of "where": return cmd_where(args, input)
|
||||
of "http": return cmd_http_test(args, input)
|
||||
of "http":
|
||||
# Phase 38: The Payload (Direct Socket Usage)
|
||||
if args.len < 1:
|
||||
print("Usage: http <ip>\n")
|
||||
return @[]
|
||||
|
||||
let host = args[0]
|
||||
print("[NipBox] Dialing " & host & ":80...\n")
|
||||
|
||||
# Use libc.socket/connect (Phase 38 Shim)
|
||||
let fd = lb.socket(2, 1, 0)
|
||||
if fd < 0:
|
||||
print("Socket Error\n")
|
||||
return @[]
|
||||
|
||||
# Parse IP (Quick hack for 10.0.2.2)
|
||||
# We need proper parsing but let's assume raw IP for MVP
|
||||
var ip_val: uint32 = 0
|
||||
try:
|
||||
let p = host.split('.')
|
||||
ip_val = (uint32(parseInt(p[0])) and 0xFF) or
|
||||
((uint32(parseInt(p[1])) and 0xFF) shl 8) or
|
||||
((uint32(parseInt(p[2])) and 0xFF) shl 16) or
|
||||
((uint32(parseInt(p[3])) and 0xFF) shl 24)
|
||||
except:
|
||||
print("Error: Invalid IP format (use A.B.C.D)\n")
|
||||
return @[]
|
||||
|
||||
# Construct SockAddrIn (Layout must match libc.connect hack)
|
||||
var addr_buf: array[16, byte]
|
||||
# Port 80 (0x0050) -> Big Endian 0x0050? No, htons(80) = 0x5000 on LE?
|
||||
# 80 = 0x0050. LE in mem: 50 00.
|
||||
# LwIP wants host byte order or network?
|
||||
# connect() shim expects us to pass port as uint16.
|
||||
# But the shim casts addr_ptr+2 to uint16*.
|
||||
# If we write 80 there, it reads 80.
|
||||
|
||||
let port: uint16 = 80
|
||||
copyMem(addr addr_buf[2], unsafeAddr port, 2)
|
||||
copyMem(addr addr_buf[4], unsafeAddr ip_val, 4)
|
||||
|
||||
if lb.connect(fd, addr addr_buf[0], 16) < 0:
|
||||
print("Connect Failed\n")
|
||||
return @[]
|
||||
|
||||
print("[NipBox] Connected! Sending Payload...\n")
|
||||
let req = "GET / HTTP/1.0\r\n\r\n"
|
||||
discard lb.send(fd, unsafeAddr req[0], uint64(req.len), 0)
|
||||
|
||||
print("[NipBox] Waiting for Data...\n")
|
||||
var buf: array[1024, char]
|
||||
while true:
|
||||
let n = lb.recv(fd, addr buf[0], 1024, 0)
|
||||
if n > 0:
|
||||
var s = ""
|
||||
for i in 0..<n: s.add(buf[i])
|
||||
print(s)
|
||||
else:
|
||||
break
|
||||
|
||||
print("\n[NipBox] Done.\n")
|
||||
return @[]
|
||||
of "http.test": return cmd_http_test(args, input)
|
||||
of "http.serve": return cmd_http_serve(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)
|
||||
|
|
@ -856,10 +1064,19 @@ proc run_script(path: string) =
|
|||
|
||||
# --- MAIN ---
|
||||
|
||||
proc main() =
|
||||
proc nipbox_main*() =
|
||||
# DIAGNOSTIC: Very first thing - prove we're executing
|
||||
print("[NIPBOX] Entry point reached!\n")
|
||||
|
||||
# Phase 30: Pledge Safety
|
||||
# NipBox is the Shell, so it needs broad permissions, but we can restrict RPATH/WPATH to specific zones
|
||||
# For now, we PLEDGE_ALL because the shell needs to explore
|
||||
# In future (SPEC-300), we drop PLEDGE_INET unless authorized
|
||||
discard lb.pledge(PLEDGE_ALL)
|
||||
|
||||
# Initialize the Biosuit
|
||||
print("[NipBox] Booting...\n")
|
||||
lb.membrane_init()
|
||||
# lb.membrane_init() - Handled by Kernel
|
||||
# term.term_init() # Phase 26: Visual Cortex Init - DISABLED
|
||||
|
||||
print("\n\x1b[1;32m╔═══════════════════════════════════════╗\x1b[0m\n")
|
||||
|
|
@ -867,16 +1084,19 @@ proc main() =
|
|||
print("\x1b[1;32m║ PHASE 21: THE TELEPORTER ACTIVATED ║\x1b[0m\n")
|
||||
print("\x1b[1;32m╚═══════════════════════════════════════╝\x1b[0m\n\n")
|
||||
|
||||
# Phase 38: Boot Script
|
||||
run_script("/init.nsh")
|
||||
print("\x1b[1;32m╚═══════════════════════════════════════╝\x1b[0m\n\n")
|
||||
|
||||
|
||||
print("\x1b[1;33mroot@nexus:# \x1b[0m")
|
||||
var inputBuffer: string = ""
|
||||
var loop_counter: uint64 = 0
|
||||
|
||||
print("[NipBox] Entering main REPL loop...\n")
|
||||
print("\x1b[1;33mroot@nexus:# \x1b[0m") # INITIAL PROMPT
|
||||
|
||||
while true:
|
||||
loop_counter += 1
|
||||
# Phase 21: Teleporter Logic (Network Pipeline)
|
||||
# Check network sockets and pipe data
|
||||
# (Simplified for now - just echo)
|
||||
lb.pump_membrane_stack()
|
||||
|
||||
var c: char
|
||||
|
|
@ -900,4 +1120,4 @@ proc main() =
|
|||
# Cooperative multitasking support
|
||||
lb.yield_fiber()
|
||||
|
||||
when isMainModule: main()
|
||||
when isMainModule: nipbox_main()
|
||||
|
|
|
|||
7
std.nim
7
std.nim
|
|
@ -1,3 +1,10 @@
|
|||
# SPDX-License-Identifier: LUL-1.0
|
||||
# Copyright (c) 2026 Markus Maiwald
|
||||
# Stewardship: Self Sovereign Society Foundation
|
||||
#
|
||||
# This file is part of the Nexus SDK.
|
||||
# See legal/LICENSE_UNBOUND.md for license terms.
|
||||
|
||||
# src/npl/nipbox/std.nim
|
||||
# Adapter for Legacy Code -> New LibC
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue