code wiki / (root) / nx_grab_ext_emit.nx

nx_grab_ext_emit.nx

buildroot/runtime/nx_grab_ext_emit.nx

26600 B514 linesdepth 2pulls 2 transitivereach 1 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_grab_ext_emit.nx -- /compare/mediaingest R10 (contract symbol ge_emit): EMIT the browser extension from data, for BOTH engine families, so Nishi OS and the Nishi browser and every third-party browser get the same capture surface without a native companion. OPERATOR STANDING ORDER 2026-08-30: "i dont want js powering any of this -- emit from the first byte up via nishi lang." A WebExtension is JavaScript by the browser's own definition and no organ can change that. What this organ changes is WHO WROTE IT: every byte the browser runs is emitted here from knowledge/grab_ext.conf, so adding a media type or moving the edge host is a DATA edit that reproduces both twins, not a hand-edit of two hand-written trees that then drift. That is the same reason nx_gen_ui_emit exists for the /gen page. WHY BOTH TWINS COME FROM ONE FILE. MV2 (Firefox/Waterfox) and MV3 (Chrome/Edge) differ in STRUCTURE: background.scripts vs background.service_worker browser_action vs action permissions carries <all_urls> vs host_permissions carries it They must NOT differ in POLICY. Emitting both from the same rows makes divergence impossible by construction instead of by review discipline -- the estate's standing rule when two artifacts must agree. WHY NO NATIVE COMPANION (this is R11 ge_edge_push, and it is a DELIBERATE non-dependency). The incumbent (Video DownloadHelper) shipped a native CoApp for years and its own README now says "VDH CoApp is not being developed anymore -- VDH v10 doesn't require a companion." The field moved off native messaging; we do not re-adopt it. The extension holds no binary and does no muxing: it SNIFFS in the tab and POSTs one URL to the estate over the authenticated edge, and the NAS does the capture. That is why it works on Windows with no WSL and no installed binary. ⛔ DECLARED IMPRECISION, NAMED BECAUSE AN UNDECLARED ONE IS A SILENT DEFECT: the emitted background body holds its per-tab media list in a plain in-memory object. On MV2 that is correct -- the background page is PERSISTENT. On MV3 the service worker is EPHEMERAL and is torn down when idle, so the list and the badge count are lost on wake, and a user who leaves a tab open then clicks the toolbar button can see an empty list on Chrome/Edge where Firefox/Waterfox shows the real one. The capture PUSH is unaffected (it carries the url in the message), so this degrades discovery, never correctness of what is captured. THE FIX IS chrome.storage.session MIRRORED ON EVERY ADD PLUS REHYDRATION ON WAKE, and it is deliberately NOT done in this increment: it is a behaviour change to the shared body that both twins run, so it wants its own teeth (wake-with-empty-memory rehydrates; MV2 unaffected) rather than being smuggled in beside the structural split this increment exists to prove. Tracked as the next increment of R10. ⚠ nx_cc LEXER: a string literal may contain neither '#' nor '!'. The emitted JavaScript is therefore written WITHOUT the '!' operator anywhere -- "=== false" and explicit comparisons instead of "!x" and "!==". This is a real constraint on the emitted text, not a style choice, and a future edit that reaches for '!' will fail to compile rather than fail silently.

dependencies 1 imports · 1 importers

nx_syscalls.nx nx_grab_ext_emit.nx nx_grab_ext_emit_gate.nx

imports: nx_syscalls.nx

imported by: nx_grab_ext_emit_gate.nx

structs

none

consts

47const GX_CONF_PATH: *u8 = "knowledge/grab_ext.conf"
48const GX_CONF_CAP: i64 = 65536
49const GX_OUT_CAP: i64 = 262144
50const GX_VAL_CAP: i64 = 4096
51const GX_PATH_CAP: i64 = 1024
52const GX_DIR_MODE: i64 = 0x1FD // 0o775
53const GX_FILE_MODE: i64 = 0x1A4 // 0o644
55const GX_CH_NL: i64 = 10
56const GX_CH_CR: i64 = 13
57const GX_CH_PIPE: i64 = 124
58const GX_CH_HASH: i64 = 35
59const GX_CH_SP: i64 = 32
60const GX_CH_D0: i64 = 48
62const GX_EXIT_OK: i64 = 0
63const GX_EXIT_NOCONF: i64 = 2
64const GX_EXIT_MISSKEY: i64 = 3
65const GX_EXIT_BADEDGE: i64 = 4
66const GX_EXIT_WRITE: i64 = 5
67const GX_EXIT_OVERFLOW: i64 = 6

functions

69func gx_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
70func gx_w(s: *u8) -> i64 { sys_write(1, s, gx_slen(s)); return 0 }
71func gx_wb(b: *u8, n: i64) -> i64 { sys_write(1, b, n); return 0 }
called by 1: gx_emit_content calls 1: sys_write
72func gx_wn(v: i64) -> i64
called by 1: gx_emit_content calls 2: sys_mmapsys_write
84func gx_app(dst: *u8, k0: i64, src: *u8) -> i64
92func gx_appn(dst: *u8, k0: i64, src: *u8, n: i64) -> i64
108func gx_nth(buf: *u8, n: i64, key: *u8, idx: i64, off_out: *i64) -> i64
146func gx_count(buf: *u8, n: i64, key: *u8) -> i64
158func gx_need(buf: *u8, n: i64, key: *u8, off_out: *i64) -> i64
169func gx_starts(buf: *u8, off: i64, len: i64, lit: *u8) -> i64
calls 1: gx_slen
181func gx_media_alt(conf: *u8, cn: i64, out: *u8, cap: i64) -> i64
201func gx_manifest_common_tail(out: *u8, k0: i64) -> i64
called by 2: gx_emit_mv2gx_emit_mv3 calls 1: gx_app
214func gx_emit_mv2(conf: *u8, cn: i64, out: *u8, cap: i64) -> i64
267func gx_emit_mv3(conf: *u8, cn: i64, out: *u8, cap: i64) -> i64
316func gx_emit_bg(conf: *u8, cn: i64, out: *u8, cap: i64) -> i64
379func gx_emit_content(conf: *u8, cn: i64, out: *u8, cap: i64) -> i64
403func gx_write_file(path: *u8, buf: *u8, n: i64) -> i64
416func gx_join(dir: *u8, leaf: *u8, out: *u8) -> i64
424func gx_emit_one(dir: *u8, leaf: *u8, body: *u8, n: i64) -> i64
442func ge_emit(root: *u8) -> i64
510func main(argc: i64, argv: *i64) -> i64