@serveryyswys/node.operit 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/BUILTINS.json CHANGED
@@ -15,60 +15,75 @@
15
15
  "unsupported": "**不提供**。原因有两类,都写在 note 里:其一,平台不成立(例如 vm 需要 Node 运行时本身、dns 的记录级查询需要 Android 没有的 JNDI DNS provider);其二,**刻意不做**(例如 net 的裸 socket —— 那会绕过 Operit 的工具审批模型)。两类都要求 OperitPackageManager 让构建失败。"
16
16
  },
17
17
  "builtins": {
18
- "path": {
19
- "subpath": "path",
20
- "status": "ready",
21
- "note": "与 Node 对拍通过;见 README 的对应说明。"
18
+ "_http_agent": {
19
+ "subpath": "_http_agent",
20
+ "status": "unsupported",
21
+ "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:http / https(走 toolCall)。"
22
22
  },
23
- "path/posix": {
24
- "subpath": "path/posix",
25
- "status": "ready",
26
- "note": "与 Node 对拍通过;见 README 的对应说明。"
23
+ "_http_client": {
24
+ "subpath": "_http_client",
25
+ "status": "unsupported",
26
+ "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:http / https(走 toolCall)。"
27
27
  },
28
- "path/win32": {
29
- "subpath": "path/win32",
30
- "status": "partial",
31
- "note": "与 Node 的 path.win32 在两类边缘有偏差:1) 归一化时含歧义冒号的相对路径(如 '9:')缺少 '.\\' 前缀;2) UNC 根的 dirname/parse 边界。日常 Windows 路径形态经对拍一致,分歧率约 1.5%。"
28
+ "_http_common": {
29
+ "subpath": "_http_common",
30
+ "status": "unsupported",
31
+ "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:http / https(走 toolCall)。"
32
32
  },
33
- "fs": {
34
- "subpath": "fs",
35
- "status": "partial",
36
- "note": "Node 语义层(选项、flag、错误码、返回值形状)已与本机 Node 的 fs 逐项对拍通过,覆盖同步面、fd 系列(openSync/readSync/writeSync/closeSync/fstatSync/ftruncateSync/fsyncSync)、回调形式、流式接口与 fs/promises(open 按 Node 语义返回 FileHandle,其 read/write 返回 {bytesRead/buffer} / {bytesWritten/buffer})。Java 驱动依赖的 bridge 行为尚未真机验证。已知近似:atime/ctime/birthtime 取 mtime;mode 为按类型的默认值;readdir 不区分符号链接;读流是「按需整块读 + 切片」,没有流式的内存特性,'open' 事件参数为 null;fstat 走路径而不是 fd(文件被 unlink 后行为不同)。"
33
+ "_http_incoming": {
34
+ "subpath": "_http_incoming",
35
+ "status": "unsupported",
36
+ "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:http / https(走 toolCall)。"
37
37
  },
38
- "fs/promises": {
39
- "subpath": "fs/promises",
40
- "status": "partial",
41
- "note": "同步面包 Promise;宿主只有 Java bridge 一条同步通道,所以是「接口异步、执行同步」。近似点同 fs。"
38
+ "_http_outgoing": {
39
+ "subpath": "_http_outgoing",
40
+ "status": "unsupported",
41
+ "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:http / https(走 toolCall)。"
42
42
  },
43
- "buffer": {
44
- "subpath": "buffer",
45
- "status": "ready",
46
- "note": "与 Node 的 Buffer 逐项对拍通过,含 Node 特有的 base64 容错规则与 ascii 编解码不对称行为。"
43
+ "_http_server": {
44
+ "subpath": "_http_server",
45
+ "status": "unsupported",
46
+ "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:http / https(走 toolCall)。"
47
47
  },
48
- "os": {
49
- "subpath": "os",
50
- "status": "partial",
51
- "note": "形状与语义对齐 Node,取值来自 Android。近似:totalmem/freemem 是 JVM 堆而非物理内存;cpus() 的 model 取 os.arch、speed/times 为 0;homedir() 为 /sdcard;loadavg() 恒 [0,0,0];getPriority/setPriority 抛 ONJ_UNSUPPORTED(POSIX niceness 在 Android 不成立)。"
48
+ "_stream_duplex": {
49
+ "subpath": "_stream_duplex",
50
+ "status": "unsupported",
51
+ "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:stream(含 stream/promises、stream/consumers)。"
52
52
  },
53
- "process": {
54
- "subpath": "process",
55
- "status": "partial",
56
- "note": "require('process') 返回的进程对象;Operit 没有 process 全局,裸引用需 OperitPackageManager 注入。差异:env 是 Proxy(读走 getEnv,空串与未设置都表现为 undefined,无法枚举);写环境变量依赖未文档化的 NativeInterface.setEnv;exit/abort 显式抛 ONJ_UNSUPPORTED;versions.node 是声明的兼容目标而非真实运行时版本。"
53
+ "_stream_passthrough": {
54
+ "subpath": "_stream_passthrough",
55
+ "status": "unsupported",
56
+ "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:stream(含 stream/promises、stream/consumers)。"
57
57
  },
58
- "util": {
59
- "subpath": "util",
60
- "status": "partial",
61
- "note": "format(占位符、参数不足、多余参数、%%、%c)、promisify、inherits、types、isDeepStrictEqual、TextEncoder/TextDecoder 已实现并对拍;isDeepStrictEqual 已与 Node 在 4225 对语料上零分歧(含 Map/Set/TypedArray/循环引用/符号键/-0/NaN),实现见 lib/deep-equal.ts,assert 也复用它。inspect 只对齐常用形态,支持 compact: false 的多行排版,但 Node 的 breakLength 折行算法未照搬。TextDecoder 只支持 utf-8。"
58
+ "_stream_readable": {
59
+ "subpath": "_stream_readable",
60
+ "status": "unsupported",
61
+ "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:stream(含 stream/promises、stream/consumers)。"
62
62
  },
63
- "events": {
64
- "subpath": "events",
65
- "status": "ready",
66
- "note": "EventEmitter 行为序列与 Node 对拍一致。差异:不能用 EventEmitter.call(this) 做函数式继承;captureRejections 与 events.on()(异步迭代器)未实现。"
63
+ "_stream_transform": {
64
+ "subpath": "_stream_transform",
65
+ "status": "unsupported",
66
+ "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:stream(含 stream/promises、stream/consumers)。"
67
67
  },
68
- "string_decoder": {
69
- "subpath": "string_decoder",
70
- "status": "ready",
71
- "note": "utf8/utf16le/base64 的跨块缓冲语义与 Node 对拍一致(含 end() 只吐一个 U+FFFD)。"
68
+ "_stream_wrap": {
69
+ "subpath": "_stream_wrap",
70
+ "status": "unsupported",
71
+ "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:stream(含 stream/promises、stream/consumers)。"
72
+ },
73
+ "_stream_writable": {
74
+ "subpath": "_stream_writable",
75
+ "status": "unsupported",
76
+ "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:stream(含 stream/promises、stream/consumers)。"
77
+ },
78
+ "_tls_common": {
79
+ "subpath": "_tls_common",
80
+ "status": "unsupported",
81
+ "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:https(走 toolCall)。"
82
+ },
83
+ "_tls_wrap": {
84
+ "subpath": "_tls_wrap",
85
+ "status": "unsupported",
86
+ "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:https(走 toolCall)。"
72
87
  },
73
88
  "assert": {
74
89
  "subpath": "assert",
@@ -80,275 +95,260 @@
80
95
  "status": "partial",
81
96
  "note": "与 require('assert').strict 是同一对象;equal 等同 strictEqual,deepEqual 等同 deepStrictEqual。实现与限制同 assert。"
82
97
  },
83
- "querystring": {
84
- "subpath": "querystring",
98
+ "async_hooks": {
99
+ "subpath": "async_hooks",
100
+ "status": "unsupported",
101
+ "note": "QuickJS 未暴露异步资源跟踪钩子。"
102
+ },
103
+ "buffer": {
104
+ "subpath": "buffer",
85
105
  "status": "ready",
86
- "note": "stringify/parse/escape/unescape 与 Node 对拍一致,含宽松百分号解码与 maxKeys 的空分段计数行为。"
106
+ "note": "与 Node 的 Buffer 逐项对拍通过,含 Node 特有的 base64 容错规则与 ascii 编解码不对称行为。"
87
107
  },
88
- "url": {
89
- "subpath": "url",
108
+ "child_process": {
109
+ "subpath": "child_process",
90
110
  "status": "partial",
91
- "note": "已实现并与 Node 对拍:URLSearchParams、**WHATWG URL**(特殊协议与自定义协议、authority、IPv4/IPv6/域名 punycode、按组件的百分号编码、点段规范化、相对引用、全部 getter 与 setter、searchParams 活视图、URL.canParse / URL.parse)、旧版 parse/format/resolve、pathToFileURL/fileURLToPath、urlToHttpOptions、domainToASCII/domainToUnicode。对拍规模:53 条绝对 URL 逐字段比对 + 12 条相对引用 + 9 个 setter + 活视图与 canParse/parse,零分歧。已知差异:blob: 的 origin 返回 'null'(Node 会解析内部 URL);域名只做 RFC 3492 punycode,不做 UTS-46 映射与归一化;pathToFileURL/fileURLToPath 是 POSIX 规则(面向 Android),Node 在 Windows 上给的是带盘符的形式。几处容易想当然的细节都是实测出来的(空查询 '?' 的 search 是 '' 但 href 保留 '?'、主机结尾的点要保留、file://localhost 归一成空主机、http:///path 的主机是 path),注释都在 src/lib/url-whatwg.ts。punycode 只做 RFC 3492 本体。"
111
+ "note": "已实现:exec/execSync/execFile/execFileSync/spawn/spawnSync、ChildProcess 的 spawn/exit/close/error 事件与 stdout/stderr/stdin、pid、exitCode、kill,以及 Node 的错误形态(非零退出码放 error.status、启动失败放 error.code='ENOENT'、maxBuffer 超出抛 ERR_CHILD_PROCESS_STDIO_MAXBUFFER)。差异:宿主只有同步 bridge,所以 spawn 是「先同步跑完、再异步发事件」——没有真并发与背压,长驻进程会阻塞调用方;输出按 UTF-8 解码(驱动用 java.util.Scanner 读取,因为 InputStream.readAllBytes 是 Java 9,Android 8~12 没有),二进制输出会有损;先读 stdout 再读 stderr,若子进程往 stderr 写超过管道缓冲会死锁。未实现:fork(需要 Node 运行时本身)。"
112
+ },
113
+ "cluster": {
114
+ "subpath": "cluster",
115
+ "status": "unsupported",
116
+ "note": "依赖 worker_threads。"
117
+ },
118
+ "console": {
119
+ "subpath": "console",
120
+ "status": "partial",
121
+ "note": "完整的 Node console API(Console 类 + log/info/warn/error/debug/assert/dir/count/countReset/time/timeEnd/timeLog/trace/table/group/groupEnd/clear/profile/profileEnd/timeStamp)。sandbox 的 prelude 只提供 log/info/warn/error 且用 arguments.join(' '),本模块在其上补齐并改用 util.format(所以 '%s' 行为与 Node 一致)。差异:不指定输出流时写 prelude console(Node 是 process.stdout/stderr);clear/profile/profileEnd/timeStamp 与 Node 在非 TTY 下一样是空操作;table 只覆盖常用形态。"
122
+ },
123
+ "constants": {
124
+ "subpath": "constants",
125
+ "status": "partial",
126
+ "note": "合并 fs / os / zlib / crypto 的常量并把 os.constants 的 signals / errno / priority 摊平到顶层(252 个键),含完整的 Linux errno 表(134 项)。给出的是 **Linux/Android** 的数值:O_CREAT / O_EXCL / O_TRUNC / O_APPEND 与 Node 在 Windows 上的不同,这是平台差异。未提供:大部分 libuv 内部常量(只给了少数 UV_FS_* / UV_DIRENT_* 镜像)、Windows 专有常量(WSA* / SIGBREAK)、Brotli 与 Zstd(BROTLI_* / ZSTD_*)以及 ZLIB_VERNUM。测试里有一份「分歧普查」,把这些缺口分类列出来。"
92
127
  },
93
128
  "crypto": {
94
129
  "subpath": "crypto",
95
130
  "status": "partial",
96
131
  "note": "已实现并与 Node 全量对拍:createHash(md5/sha1/sha224/sha256/sha384/sha512,纯 JS 实现)、createHmac、pbkdf2/pbkdf2Sync、timingSafeEqual、getHashes、randomBytes/randomFillSync/randomUUID/randomInt(随机数走 java.util.UUID.randomUUID,无需往 bridge 传 byte[])。未实现,调用即抛 ONJ_UNSUPPORTED:createCipheriv/createDecipheriv/createSign/createVerify/generateKeyPair(Sync)/createDiffieHellman。"
97
132
  },
98
- "zlib": {
99
- "subpath": "zlib",
100
- "status": "partial",
101
- "note": "已实现并与 Node 双向对拍:inflate/inflateRaw/gunzip/unzip(完整 DEFLATE,含 stored、定长与动态 Huffman)、deflate/deflateRaw/gzip(定长 Huffman + LZ77)、流式接口(createGzip/createGunzip/createDeflate/createInflate/createDeflateRaw/createInflateRaw/createUnzip)、同步与回调两种形式、constants。压缩侧未实现动态 Huffman,压缩率低于 zlib,但输出是任何解压器都能读的合法流。流式接口基于 stream.Transform,但内部仍是一次性处理(攒到 _flush 才压缩/解压),没有真流式的低延迟与低内存。Brotli 未实现。"
133
+ "dgram": {
134
+ "subpath": "dgram",
135
+ "status": "unsupported",
136
+ "note": "刻意不提供,理由与 net 相同:UDP 裸 socket 会让插件绕过 Operit 的工具审批模型(网络访问是工具能力,走用户审批)。需要网络请用 toolCall / 内建 axios。"
102
137
  },
103
- "stream": {
104
- "subpath": "stream",
138
+ "diagnostics_channel": {
139
+ "subpath": "diagnostics_channel",
105
140
  "status": "partial",
106
- "note": "Readable/Writable/Duplex/Transform/PassThrough、pipe/unpipe、pipeline 与 finished(回调形式)、Symbol.asyncIterator、Readable.from 已实现,9 个场景与 Node 对拍一致。用 queueMicrotask 调度,事件时序与 Node 同类但不必逐拍相同(测试比对的是语义结果)。未实现:objectMode 的完整语义差异、cork 的合并优化、compose、addAbortSignal。stream.pipeline 不给回调会按 Node 语义抛 ERR_INVALID_ARG_TYPE,Promise 形式请用 stream/promises。"
141
+ "note": "channel / hasSubscribers / subscribe / unsubscribe / Channel 全部可用(纯发布订阅,不依赖平台)。差异:Channel 的 bindStore / unbindStore / runStores 依赖 AsyncLocalStorage(需要 async_hooks),QuickJS 运行时不提供异步钩子,这三个方法显式抛 ONJ_UNSUPPORTED;tracingChannel 未实现,同样显式拒绝。"
107
142
  },
108
- "stream/promises": {
109
- "subpath": "stream/promises",
143
+ "dns": {
144
+ "subpath": "dns",
110
145
  "status": "partial",
111
- "note": "pipeline / finished 的 Promise 版;与 require('stream').promises 是同一份实现。"
146
+ "note": "实现了 **lookup 一族**(getaddrinfo),也就是绝大多数代码真正用到的那部分:lookup / lookupService / promises.lookup / promises.lookupService / getServers / setServers / getDefaultResultOrder / setDefaultResultOrder / 常量(hints 与错误码字符串,数值对齐 Node 而非 libuv 原始值)。底层是 java.net.InetAddress。**resolve 一族(resolve/resolve4/resolve6/resolveAny/resolveCaa/resolveCname/resolveMx/resolveNaptr/resolveNs/resolvePtr/resolveSoa/resolveSrv/resolveTlsa/resolveTxt)与 reverse 显式抛 ONJ_UNSUPPORTED**:它们需要 DNS 记录级查询,而这要 JNDI 的 DNS provider,com.sun.jndi.dns 不在 Android 里 —— 是平台不成立,不是尚未实现。其它差异:接口异步(queueMicrotask)但底层 getaddrinfo 是同步的;getServers() 返回空数组(Android 的 DNS 由 netd 按网络管理,JVM 侧读不到);setServers() 抛 ONJ_UNSUPPORTED(改不了 JVM 解析器);hints 选项接受但不生效;lookupService 的 service 用内置常见端口表,未命中给端口号字符串(Node 走系统的 services 库)。错误形状与实测 Node 对齐:code='ENOTFOUND'、errno=-3008、syscall='getaddrinfo'、hostname,message 为 'getaddrinfo ENOTFOUND <host>'。**尚未真机验证**。"
112
147
  },
113
- "timers": {
114
- "subpath": "timers",
148
+ "dns/promises": {
149
+ "subpath": "dns/promises",
115
150
  "status": "partial",
116
- "note": "setTimeout / clearTimeout / setInterval / clearInterval 就是宿主提供的全局函数本身(Node 的 timers.setTimeout === 全局 setTimeout 也是如此)。setImmediate / clearImmediate 宿主没有,落在 setTimeout(…, 0) 上 —— 因此在 Operit 里它与定时器是同一个队列(Node 里 setImmediate 在 check 阶段、先于定时器)。promisify(setTimeout) 可用(按需补 promisify.custom,宿主已有就不动)。"
151
+ "note": "dns 的 promises 形态,与 require('dns').promises 是同一个对象。差异与 dns 完全一致:lookup 一族可用,resolve 一族与 reverse 显式抛 ONJ_UNSUPPORTED。"
117
152
  },
118
- "timers/promises": {
119
- "subpath": "timers/promises",
120
- "status": "partial",
121
- "note": "setTimeout / setImmediate / scheduler.wait / scheduler.yield 已实现并与 Node 对拍(含 value 传递、AbortError)。setInterval 用「每次 await 一个 setTimeout」实现,不是原生 interval,因此延迟会随迭代累积漂移(可迭代与取消语义与 Node 一致)。signal 只按结构检查(aborted / addEventListener),因为没有 AbortController。"
153
+ "domain": {
154
+ "subpath": "domain",
155
+ "status": "unsupported",
156
+ "note": "已废弃模块,且它依赖异步上下文追踪(与 async_hooks 同源),运行时不提供。"
122
157
  },
123
- "child_process": {
124
- "subpath": "child_process",
158
+ "events": {
159
+ "subpath": "events",
160
+ "status": "ready",
161
+ "note": "EventEmitter 行为序列与 Node 对拍一致。差异:不能用 EventEmitter.call(this) 做函数式继承;captureRejections 与 events.on()(异步迭代器)未实现。"
162
+ },
163
+ "fs": {
164
+ "subpath": "fs",
125
165
  "status": "partial",
126
- "note": "已实现:exec/execSync/execFile/execFileSync/spawn/spawnSync、ChildProcess 的 spawn/exit/close/error 事件与 stdout/stderr/stdin、pid、exitCode、kill,以及 Node 的错误形态(非零退出码放 error.status、启动失败放 error.code='ENOENT'、maxBuffer 超出抛 ERR_CHILD_PROCESS_STDIO_MAXBUFFER)。差异:宿主只有同步 bridge,所以 spawn 是「先同步跑完、再异步发事件」——没有真并发与背压,长驻进程会阻塞调用方;输出按 UTF-8 解码(驱动用 java.util.Scanner 读取,因为 InputStream.readAllBytes 是 Java 9,Android 8~12 没有),二进制输出会有损;先读 stdout 再读 stderr,若子进程往 stderr 写超过管道缓冲会死锁。未实现:fork(需要 Node 运行时本身)。"
166
+ "note": "Node 语义层(选项、flag、错误码、返回值形状)已与本机 Node 的 fs 逐项对拍通过,覆盖同步面、fd 系列(openSync/readSync/writeSync/closeSync/fstatSync/ftruncateSync/fsyncSync)、回调形式、流式接口与 fs/promises(open 按 Node 语义返回 FileHandle,其 read/write 返回 {bytesRead/buffer} / {bytesWritten/buffer})。Java 驱动依赖的 bridge 行为尚未真机验证。已知近似:atime/ctime/birthtime 取 mtime;mode 为按类型的默认值;readdir 不区分符号链接;读流是「按需整块读 + 切片」,没有流式的内存特性,'open' 事件参数为 null;fstat 走路径而不是 fd(文件被 unlink 后行为不同)。"
127
167
  },
128
- "net": {
129
- "subpath": "net",
130
- "status": "unsupported",
131
- "note": "刻意不提供。net 需要裸 TCP/UDP socket,技术上可以用 java.net.Socket 实现,但那会让插件绕过 Operit 的工具审批模型:网络访问在 Operit 里是**工具能力**(http_request 等,走用户审批),用裸 socket 另起一套等于绕过它。http/https 已经建在 toolCall('http_request') 之上(见 http 条目);如果将来 Operit 提供原始 socket 类工具,net 可以照同样的方式补上。在那之前,需要网络请用 toolCall / 内建 axios。"
168
+ "fs/promises": {
169
+ "subpath": "fs/promises",
170
+ "status": "partial",
171
+ "note": "同步面包 Promise;宿主只有 Java bridge 一条同步通道,所以是「接口异步、执行同步」。近似点同 fs。"
132
172
  },
133
173
  "http": {
134
174
  "subpath": "http",
135
175
  "status": "partial",
136
176
  "note": "只有**客户端**。建在宿主的 toolCall('http_request') 之上,不直接用 Java socket —— http_request 是 Operit 注册的工具(ToolRegistration.kt:1967),走用户审批;用裸 socket 另起一套等于绕过那个模型。覆盖:request / get、ClientRequest(Writable:setHeader/getHeader/getHeaders/getHeaderNames/hasHeader/removeHeader、write/end、setTimeout、abort)、IncomingMessage(Readable:statusCode/statusMessage/headers(键名全小写)/rawHeaders/httpVersion/url)、STATUS_CODES、METHODS、Agent(无连接池)、globalAgent。与 Node 的差异:createServer / Server 构造时显式抛 ONJ_UNSUPPORTED(沙箱没有可监听的 socket);请求体只支持文本(宿主工具的参数是字符串),二进制上行不做;abort() 只发出 'abort' 事件,无法真正取消已在宿主侧执行的请求(工具调用没有取消通道);没有连接池 / keep-alive / HTTP/2;重定向是否跟随由宿主决定。响应体优先用 contentBase64 还原字节,缺失时才按 UTF-8 解释 content。宿主返回形状取自 HttpResponseData(ToolResultDataClasses.kt:600);形状不对时明确报错,不静默兜底。**尚未真机验证**。"
137
177
  },
178
+ "http2": {
179
+ "subpath": "http2",
180
+ "status": "unsupported",
181
+ "note": "建在 net 之上(HTTP/2 需要长连接与帧控制),net 不提供。http/https 客户端走 toolCall('http_request')。"
182
+ },
138
183
  "https": {
139
184
  "subpath": "https",
140
185
  "status": "partial",
141
186
  "note": "只有**客户端**。建在宿主的 toolCall('http_request') 之上,不直接用 Java socket —— http_request 是 Operit 注册的工具(ToolRegistration.kt:1967),走用户审批;用裸 socket 另起一套等于绕过那个模型。覆盖:request / get、ClientRequest(Writable:setHeader/getHeader/getHeaders/getHeaderNames/hasHeader/removeHeader、write/end、setTimeout、abort)、IncomingMessage(Readable:statusCode/statusMessage/headers(键名全小写)/rawHeaders/httpVersion/url)、STATUS_CODES、METHODS、Agent(无连接池)、globalAgent。与 Node 的差异:createServer / Server 构造时显式抛 ONJ_UNSUPPORTED(沙箱没有可监听的 socket);请求体只支持文本(宿主工具的参数是字符串),二进制上行不做;abort() 只发出 'abort' 事件,无法真正取消已在宿主侧执行的请求(工具调用没有取消通道);没有连接池 / keep-alive / HTTP/2;重定向是否跟随由宿主决定。响应体优先用 contentBase64 还原字节,缺失时才按 UTF-8 解释 content。宿主返回形状取自 HttpResponseData(ToolResultDataClasses.kt:600);形状不对时明确报错,不静默兜底。**尚未真机验证**。 与 http 是同一套实现(TLS 由宿主那侧处理,沙箱里既没有 socket 也没有证书链可管),只把缺省协议改成 https:。"
142
187
  },
143
- "dns": {
144
- "subpath": "dns",
145
- "status": "partial",
146
- "note": "实现了 **lookup 一族**(getaddrinfo),也就是绝大多数代码真正用到的那部分:lookup / lookupService / promises.lookup / promises.lookupService / getServers / setServers / getDefaultResultOrder / setDefaultResultOrder / 常量(hints 与错误码字符串,数值对齐 Node 而非 libuv 原始值)。底层是 java.net.InetAddress。**resolve 一族(resolve/resolve4/resolve6/resolveAny/resolveCaa/resolveCname/resolveMx/resolveNaptr/resolveNs/resolvePtr/resolveSoa/resolveSrv/resolveTlsa/resolveTxt)与 reverse 显式抛 ONJ_UNSUPPORTED**:它们需要 DNS 记录级查询,而这要 JNDI 的 DNS provider,com.sun.jndi.dns 不在 Android 里 —— 是平台不成立,不是尚未实现。其它差异:接口异步(queueMicrotask)但底层 getaddrinfo 是同步的;getServers() 返回空数组(Android 的 DNS 由 netd 按网络管理,JVM 侧读不到);setServers() 抛 ONJ_UNSUPPORTED(改不了 JVM 解析器);hints 选项接受但不生效;lookupService 的 service 用内置常见端口表,未命中给端口号字符串(Node 走系统的 services 库)。错误形状与实测 Node 对齐:code='ENOTFOUND'、errno=-3008、syscall='getaddrinfo'、hostname,message 为 'getaddrinfo ENOTFOUND <host>'。**尚未真机验证**。"
147
- },
148
- "perf_hooks": {
149
- "subpath": "perf_hooks",
150
- "status": "partial",
151
- "note": "performance(now / timeOrigin / mark / measure / getEntries* / clearMarks / clearMeasures)与 constants 已实现并与 Node 对拍。注意 measure 的位置参数形式**只认 mark 名字**、数字不当时间戳(实测 Node 就是如此),数字要当时间戳得用 options 形式 measure(name, {start, end})。未实现:PerformanceObserver、PerformanceEntry 等类、monitorEventLoopDelay、createHistogram —— 保持 undefined,不给空壳。"
152
- },
153
- "readline": {
154
- "subpath": "readline",
155
- "status": "planned",
156
- "note": "尚未实现。技术上可行(readline 可以跑在任意流上,不必是真终端),但 Operit 沙箱里没有交互式 stdin,实际价值有限,所以优先级排在最后。OperitPackageManager 应当让构建失败。"
188
+ "inspector": {
189
+ "subpath": "inspector",
190
+ "status": "unsupported",
191
+ "note": "无 V8 inspector 协议。"
157
192
  },
158
- "constants": {
159
- "subpath": "constants",
160
- "status": "partial",
161
- "note": "合并 fs / os / zlib / crypto 的常量并把 os.constants 的 signals / errno / priority 摊平到顶层(252 个键),含完整的 Linux errno 表(134 项)。给出的是 **Linux/Android** 的数值:O_CREAT / O_EXCL / O_TRUNC / O_APPEND 与 Node 在 Windows 上的不同,这是平台差异。未提供:大部分 libuv 内部常量(只给了少数 UV_FS_* / UV_DIRENT_* 镜像)、Windows 专有常量(WSA* / SIGBREAK)、Brotli 与 Zstd(BROTLI_* / ZSTD_*)以及 ZLIB_VERNUM。测试里有一份「分歧普查」,把这些缺口分类列出来。"
193
+ "inspector/promises": {
194
+ "subpath": "inspector/promises",
195
+ "status": "unsupported",
196
+ "note": "inspector 本身就不支持(需要 V8 inspector 协议),其 promises 形态同理。"
162
197
  },
163
198
  "module": {
164
199
  "subpath": "module",
165
200
  "status": "partial",
166
201
  "note": "builtinModules(与 BUILTINS.json 的键逐字一致,测试断言两者同步,改契约表时会失败提醒)与 isBuiltin(认 node: 前缀)。createRequire() 显式抛 ONJ_UNSUPPORTED:它依赖 node_modules 逐级查找与 main/exports 解析,而 Operit 的 require 两样都没有。Module 类与 _resolveFilename 等内部接口不提供。"
167
202
  },
168
- "vm": {
169
- "status": "unsupported",
170
- "note": "QuickJS 运行时未暴露独立上下文创建能力。",
171
- "subpath": "vm"
172
- },
173
- "worker_threads": {
174
- "status": "unsupported",
175
- "note": "QuickJS 运行时为单线程解释器,无 worker 能力。",
176
- "subpath": "worker_threads"
177
- },
178
- "cluster": {
203
+ "net": {
204
+ "subpath": "net",
179
205
  "status": "unsupported",
180
- "note": "依赖 worker_threads。",
181
- "subpath": "cluster"
206
+ "note": "刻意不提供。net 需要裸 TCP/UDP socket,技术上可以用 java.net.Socket 实现,但那会让插件绕过 Operit 的工具审批模型:网络访问在 Operit 里是**工具能力**(http_request 等,走用户审批),用裸 socket 另起一套等于绕过它。http/https 已经建在 toolCall('http_request') 之上(见 http 条目);如果将来 Operit 提供原始 socket 类工具,net 可以照同样的方式补上。在那之前,需要网络请用 toolCall / 内建 axios。"
182
207
  },
183
- "async_hooks": {
184
- "status": "unsupported",
185
- "note": "QuickJS 未暴露异步资源跟踪钩子。",
186
- "subpath": "async_hooks"
208
+ "os": {
209
+ "subpath": "os",
210
+ "status": "partial",
211
+ "note": "形状与语义对齐 Node,取值来自 Android。近似:totalmem/freemem 是 JVM 堆而非物理内存;cpus() 的 model 取 os.arch、speed/times 为 0;homedir() 为 /sdcard;loadavg() 恒 [0,0,0];getPriority/setPriority 抛 ONJ_UNSUPPORTED(POSIX niceness 在 Android 不成立)。"
187
212
  },
188
- "inspector": {
189
- "status": "unsupported",
190
- "note": "无 V8 inspector 协议。",
191
- "subpath": "inspector"
213
+ "path": {
214
+ "subpath": "path",
215
+ "status": "ready",
216
+ "note": "已实现;windows 与 posix 两套语义都提供,含子路径 path/win32 与 path/posix。"
192
217
  },
193
- "repl": {
194
- "status": "unsupported",
195
- "note": "无 stdin/stdout 终端语义。",
196
- "subpath": "repl"
218
+ "path/posix": {
219
+ "subpath": "path/posix",
220
+ "status": "ready",
221
+ "note": "已实现;POSIX 语义(与 Node 的 path.posix 对拍)。"
197
222
  },
198
- "tty": {
199
- "subpath": "tty",
223
+ "path/win32": {
224
+ "subpath": "path/win32",
200
225
  "status": "partial",
201
- "note": "isatty() 恒为 false(沙箱里没有终端,这正是 supports-color / debug 这类包需要知道的答案)。ReadStream / WriteStream 需要真实终端,构造时显式抛 ONJ_UNSUPPORTED,不给「能 new 但不能用」的空壳。"
226
+ "note": "与 Node 的 path.win32 在两类边缘有偏差:1) 归一化时含歧义冒号的相对路径(如 '9:')缺少 '.\\' 前缀;2) UNC 根的 dirname/parse 边界。日常 Windows 路径形态经对拍一致,分歧率约 1.5%。"
202
227
  },
203
- "dns/promises": {
204
- "subpath": "dns/promises",
228
+ "perf_hooks": {
229
+ "subpath": "perf_hooks",
205
230
  "status": "partial",
206
- "note": "dns 的 promises 形态,与 require('dns').promises 是同一个对象。差异与 dns 完全一致:lookup 一族可用,resolve 一族与 reverse 显式抛 ONJ_UNSUPPORTED。"
231
+ "note": "performance(now / timeOrigin / mark / measure / getEntries* / clearMarks / clearMeasures)与 constants 已实现并与 Node 对拍。注意 measure 的位置参数形式**只认 mark 名字**、数字不当时间戳(实测 Node 就是如此),数字要当时间戳得用 options 形式 measure(name, {start, end})。未实现:PerformanceObserver、PerformanceEntry 等类、monitorEventLoopDelay、createHistogram —— 保持 undefined,不给空壳。"
207
232
  },
208
- "console": {
209
- "subpath": "console",
233
+ "process": {
234
+ "subpath": "process",
210
235
  "status": "partial",
211
- "note": "完整的 Node console API(Console 类 + log/info/warn/error/debug/assert/dir/count/countReset/time/timeEnd/timeLog/trace/table/group/groupEnd/clear/profile/profileEnd/timeStamp)。sandbox 的 prelude 只提供 log/info/warn/error 且用 arguments.join(' '),本模块在其上补齐并改用 util.format(所以 '%s' 行为与 Node 一致)。差异:不指定输出流时写 prelude console(Node 是 process.stdout/stderr);clear/profile/profileEnd/timeStamp 与 Node 在非 TTY 下一样是空操作;table 只覆盖常用形态。"
212
- },
213
- "util/types": {
214
- "subpath": "util/types",
215
- "status": "ready",
216
- "note": "与 require('util').types 同一个对象。高频依赖。"
217
- },
218
- "sys": {
219
- "subpath": "sys",
220
- "status": "ready",
221
- "note": "已废弃的别名,Node 里 require('sys') === require('util'),这里保持同一对象。"
236
+ "note": "require('process') 返回的进程对象;Operit 没有 process 全局,裸引用需 OperitPackageManager 注入。差异:env 是 Proxy(读走 getEnv,空串与未设置都表现为 undefined,无法枚举);写环境变量依赖未文档化的 NativeInterface.setEnv;exit/abort 显式抛 ONJ_UNSUPPORTED;versions.node 是声明的兼容目标而非真实运行时版本。"
222
237
  },
223
238
  "punycode": {
224
239
  "subpath": "punycode",
225
240
  "status": "ready",
226
241
  "note": "已废弃但仍被不少包直接 require。实现复用 lib/punycode.ts。version 报 '2.1.1';ucs2.decode 返回的是 UTF-16 码元序列,与 Node 一致。"
227
242
  },
228
- "diagnostics_channel": {
229
- "subpath": "diagnostics_channel",
243
+ "querystring": {
244
+ "subpath": "querystring",
245
+ "status": "ready",
246
+ "note": "stringify/parse/escape/unescape 与 Node 对拍一致,含宽松百分号解码与 maxKeys 的空分段计数行为。"
247
+ },
248
+ "readline": {
249
+ "subpath": "readline",
250
+ "status": "planned",
251
+ "note": "尚未实现。技术上可行(readline 可以跑在任意流上,不必是真终端),但 Operit 沙箱里没有交互式 stdin,实际价值有限,所以优先级排在最后。OperitPackageManager 应当让构建失败。"
252
+ },
253
+ "repl": {
254
+ "subpath": "repl",
255
+ "status": "unsupported",
256
+ "note": "无 stdin/stdout 终端语义。"
257
+ },
258
+ "stream": {
259
+ "subpath": "stream",
230
260
  "status": "partial",
231
- "note": "channel / hasSubscribers / subscribe / unsubscribe / Channel 全部可用(纯发布订阅,不依赖平台)。差异:Channel 的 bindStore / unbindStore / runStores 依赖 AsyncLocalStorage(需要 async_hooks),QuickJS 运行时不提供异步钩子,这三个方法显式抛 ONJ_UNSUPPORTED;tracingChannel 未实现,同样显式拒绝。"
261
+ "note": "Readable/Writable/Duplex/Transform/PassThrough、pipe/unpipe、pipeline 与 finished(回调形式)、Symbol.asyncIterator、Readable.from 已实现,9 个场景与 Node 对拍一致。用 queueMicrotask 调度,事件时序与 Node 同类但不必逐拍相同(测试比对的是语义结果)。未实现:objectMode 的完整语义差异、cork 的合并优化、compose、addAbortSignal。stream.pipeline 不给回调会按 Node 语义抛 ERR_INVALID_ARG_TYPE,Promise 形式请用 stream/promises。"
232
262
  },
233
263
  "stream/consumers": {
234
264
  "subpath": "stream/consumers",
235
265
  "status": "partial",
236
266
  "note": "buffer / text / json / arrayBuffer 可用。差异:blob 显式抛 ONJ_UNSUPPORTED —— 运行时不提供 Blob,与其返回形状相似但类型不对的对象不如明确拒绝;不做 Node 内部的 Readable 品牌校验,只要求对象有 on()。"
237
267
  },
238
- "v8": {
239
- "subpath": "v8",
268
+ "stream/promises": {
269
+ "subpath": "stream/promises",
240
270
  "status": "partial",
241
- "note": "getHeapStatistics / getHeapSpaceStatistics / getHeapCodeStatistics 可用,但取的是 **JVM 堆**而不是 V8 堆(与 os.totalmem / freemem 的近似同类);getHeapSpaceStatistics 返回空数组(QuickJS 不暴露分空间统计)。serialize / deserialize / setFlagsFromString / cachedDataVersionTag / writeHeapSnapshot / takeCoverage / stopCoverage 一律显式抛 ONJ_UNSUPPORTED:它们要么依赖 V8 的二进制格式,要么是 V8 专有能力。"
242
- },
243
- "dgram": {
244
- "subpath": "dgram",
245
- "status": "unsupported",
246
- "note": "刻意不提供,理由与 net 相同:UDP 裸 socket 会让插件绕过 Operit 的工具审批模型(网络访问是工具能力,走用户审批)。需要网络请用 toolCall / 内建 axios。"
247
- },
248
- "tls": {
249
- "subpath": "tls",
250
- "status": "unsupported",
251
- "note": "建在 net 之上,net 不提供所以它也做不了。https 已经走 toolCall('http_request'),TLS 由宿主处理。"
252
- },
253
- "http2": {
254
- "subpath": "http2",
255
- "status": "unsupported",
256
- "note": "建在 net 之上(HTTP/2 需要长连接与帧控制),net 不提供。http/https 客户端走 toolCall('http_request')。"
271
+ "note": "pipeline / finished 的 Promise 版;与 require('stream').promises 是同一份实现。"
257
272
  },
258
273
  "stream/web": {
259
274
  "subpath": "stream/web",
260
275
  "status": "unsupported",
261
276
  "note": "需要 WHATWG Streams(ReadableStream / WritableStream / TransformStream),Android 的 QuickJS 运行时不提供这些内建。本库实现了 Node 的 stream 模块(含 promises 与 consumers),需要流能力请用 stream。"
262
277
  },
263
- "domain": {
264
- "subpath": "domain",
265
- "status": "unsupported",
266
- "note": "已废弃模块,且它依赖异步上下文追踪(与 async_hooks 同源),运行时不提供。"
267
- },
268
- "trace_events": {
269
- "subpath": "trace_events",
270
- "status": "unsupported",
271
- "note": "V8 的 tracing 机制,运行时不是 V8。诊断可观测性请用 diagnostics_channel(已实现)。"
272
- },
273
- "wasi": {
274
- "subpath": "wasi",
275
- "status": "unsupported",
276
- "note": "需要 WASM 运行时与 WASI 宿主实现,Android 的 QuickJS 运行时不提供。"
277
- },
278
- "inspector/promises": {
279
- "subpath": "inspector/promises",
280
- "status": "unsupported",
281
- "note": "inspector 本身就不支持(需要 V8 inspector 协议),其 promises 形态同理。"
278
+ "string_decoder": {
279
+ "subpath": "string_decoder",
280
+ "status": "ready",
281
+ "note": "utf8/utf16le/base64 的跨块缓冲语义与 Node 对拍一致(含 end() 只吐一个 U+FFFD)。"
282
282
  },
283
- "_http_agent": {
284
- "subpath": "_http_agent",
285
- "status": "unsupported",
286
- "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:http / https(走 toolCall)。"
283
+ "sys": {
284
+ "subpath": "sys",
285
+ "status": "ready",
286
+ "note": "已废弃的别名,Node 里 require('sys') === require('util'),这里保持同一对象。"
287
287
  },
288
- "_http_client": {
289
- "subpath": "_http_client",
290
- "status": "unsupported",
291
- "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:http / https(走 toolCall)。"
288
+ "timers": {
289
+ "subpath": "timers",
290
+ "status": "partial",
291
+ "note": "setTimeout / clearTimeout / setInterval / clearInterval 就是宿主提供的全局函数本身(Node 的 timers.setTimeout === 全局 setTimeout 也是如此)。setImmediate / clearImmediate 宿主没有,落在 setTimeout(…, 0) 上 —— 因此在 Operit 里它与定时器是同一个队列(Node 里 setImmediate 在 check 阶段、先于定时器)。promisify(setTimeout) 可用(按需补 promisify.custom,宿主已有就不动)。"
292
292
  },
293
- "_http_common": {
294
- "subpath": "_http_common",
295
- "status": "unsupported",
296
- "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:http / https(走 toolCall)。"
293
+ "timers/promises": {
294
+ "subpath": "timers/promises",
295
+ "status": "partial",
296
+ "note": "setTimeout / setImmediate / scheduler.wait / scheduler.yield 已实现并与 Node 对拍(含 value 传递、AbortError)。setInterval 用「每次 await 一个 setTimeout」实现,不是原生 interval,因此延迟会随迭代累积漂移(可迭代与取消语义与 Node 一致)。signal 只按结构检查(aborted / addEventListener),因为没有 AbortController。"
297
297
  },
298
- "_http_incoming": {
299
- "subpath": "_http_incoming",
298
+ "tls": {
299
+ "subpath": "tls",
300
300
  "status": "unsupported",
301
- "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:http / https(走 toolCall)。"
301
+ "note": "建在 net 之上,net 不提供所以它也做不了。https 已经走 toolCall('http_request'),TLS 由宿主处理。"
302
302
  },
303
- "_http_outgoing": {
304
- "subpath": "_http_outgoing",
303
+ "trace_events": {
304
+ "subpath": "trace_events",
305
305
  "status": "unsupported",
306
- "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:http / https(走 toolCall)。"
306
+ "note": "V8 的 tracing 机制,运行时不是 V8。诊断可观测性请用 diagnostics_channel(已实现)。"
307
307
  },
308
- "_http_server": {
309
- "subpath": "_http_server",
310
- "status": "unsupported",
311
- "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:http / https(走 toolCall)。"
308
+ "tty": {
309
+ "subpath": "tty",
310
+ "status": "partial",
311
+ "note": "isatty() 恒为 false(沙箱里没有终端,这正是 supports-color / debug 这类包需要知道的答案)。ReadStream / WriteStream 需要真实终端,构造时显式抛 ONJ_UNSUPPORTED,不给「能 new 但不能用」的空壳。"
312
312
  },
313
- "_stream_duplex": {
314
- "subpath": "_stream_duplex",
315
- "status": "unsupported",
316
- "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:stream(含 stream/promises、stream/consumers)。"
313
+ "url": {
314
+ "subpath": "url",
315
+ "status": "partial",
316
+ "note": "已实现并与 Node 对拍:URLSearchParams、**WHATWG URL**(特殊协议与自定义协议、authority、IPv4/IPv6/域名 punycode、按组件的百分号编码、点段规范化、相对引用、全部 getter 与 setter、searchParams 活视图、URL.canParse / URL.parse)、旧版 parse/format/resolve、pathToFileURL/fileURLToPath、urlToHttpOptions、domainToASCII/domainToUnicode。对拍规模:53 条绝对 URL 逐字段比对 + 12 条相对引用 + 9 个 setter + 活视图与 canParse/parse,零分歧。已知差异:blob: 的 origin 返回 'null'(Node 会解析内部 URL);域名只做 RFC 3492 punycode,不做 UTS-46 映射与归一化;pathToFileURL/fileURLToPath 是 POSIX 规则(面向 Android),Node 在 Windows 上给的是带盘符的形式。几处容易想当然的细节都是实测出来的(空查询 '?' 的 search 是 '' 但 href 保留 '?'、主机结尾的点要保留、file://localhost 归一成空主机、http:///path 的主机是 path),注释都在 src/lib/url-whatwg.ts。punycode 只做 RFC 3492 本体。"
317
317
  },
318
- "_stream_passthrough": {
319
- "subpath": "_stream_passthrough",
320
- "status": "unsupported",
321
- "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:stream(含 stream/promises、stream/consumers)。"
318
+ "util": {
319
+ "subpath": "util",
320
+ "status": "partial",
321
+ "note": "format(占位符、参数不足、多余参数、%%、%c)、promisify、inherits、types、isDeepStrictEqual、TextEncoder/TextDecoder 已实现并对拍;isDeepStrictEqual 已与 Node 在 4225 对语料上零分歧(含 Map/Set/TypedArray/循环引用/符号键/-0/NaN),实现见 lib/deep-equal.ts,assert 也复用它。inspect 只对齐常用形态,支持 compact: false 的多行排版,但 Node 的 breakLength 折行算法未照搬。TextDecoder 只支持 utf-8。"
322
322
  },
323
- "_stream_readable": {
324
- "subpath": "_stream_readable",
325
- "status": "unsupported",
326
- "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:stream(含 stream/promises、stream/consumers)。"
323
+ "util/types": {
324
+ "subpath": "util/types",
325
+ "status": "ready",
326
+ "note": "与 require('util').types 同一个对象。高频依赖。"
327
327
  },
328
- "_stream_transform": {
329
- "subpath": "_stream_transform",
330
- "status": "unsupported",
331
- "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:stream(含 stream/promises、stream/consumers)。"
328
+ "v8": {
329
+ "subpath": "v8",
330
+ "status": "partial",
331
+ "note": "getHeapStatistics / getHeapSpaceStatistics / getHeapCodeStatistics 可用,但取的是 **JVM 堆**而不是 V8 堆(与 os.totalmem / freemem 的近似同类);getHeapSpaceStatistics 返回空数组(QuickJS 不暴露分空间统计)。serialize / deserialize / setFlagsFromString / cachedDataVersionTag / writeHeapSnapshot / takeCoverage / stopCoverage 一律显式抛 ONJ_UNSUPPORTED:它们要么依赖 V8 的二进制格式,要么是 V8 专有能力。"
332
332
  },
333
- "_stream_wrap": {
334
- "subpath": "_stream_wrap",
333
+ "vm": {
334
+ "subpath": "vm",
335
335
  "status": "unsupported",
336
- "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:stream(含 stream/promises、stream/consumers)。"
336
+ "note": "QuickJS 运行时未暴露独立上下文创建能力。"
337
337
  },
338
- "_stream_writable": {
339
- "subpath": "_stream_writable",
338
+ "wasi": {
339
+ "subpath": "wasi",
340
340
  "status": "unsupported",
341
- "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:stream(含 stream/promises、stream/consumers)。"
341
+ "note": "需要 WASM 运行时与 WASI 宿主实现,Android 的 QuickJS 运行时不提供。"
342
342
  },
343
- "_tls_common": {
344
- "subpath": "_tls_common",
343
+ "worker_threads": {
344
+ "subpath": "worker_threads",
345
345
  "status": "unsupported",
346
- "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:https(走 toolCall)。"
346
+ "note": "QuickJS 运行时为单线程解释器,无 worker 能力。"
347
347
  },
348
- "_tls_wrap": {
349
- "subpath": "_tls_wrap",
350
- "status": "unsupported",
351
- "note": "Node 的**内部**模块(下划线开头)。userland 不应 require 它们;确有包这么做的,说明它依赖 Node 内部实现,本运行时无法提供。已实现的是对应的公开模块:https(走 toolCall)。"
348
+ "zlib": {
349
+ "subpath": "zlib",
350
+ "status": "partial",
351
+ "note": "已实现并与 Node 双向对拍:inflate/inflateRaw/gunzip/unzip(完整 DEFLATE,含 stored、定长与动态 Huffman)、deflate/deflateRaw/gzip(定长 Huffman + LZ77)、流式接口(createGzip/createGunzip/createDeflate/createInflate/createDeflateRaw/createInflateRaw/createUnzip)、同步与回调两种形式、constants。压缩侧未实现动态 Huffman,压缩率低于 zlib,但输出是任何解压器都能读的合法流。流式接口基于 stream.Transform,但内部仍是一次性处理(攒到 _flush 才压缩/解压),没有真流式的低延迟与低内存。Brotli 未实现。"
352
352
  }
353
353
  },
354
354
  "packing": {
@@ -384,7 +384,10 @@
384
384
  "pathNormalization": "normalizePath 丢掉开头的 /,且越界的 .. 直接丢弃,逃不出根(:209)。",
385
385
  "extensionRule": "名字命中 /\\.[a-z0-9]+$/i 就只有一个候选、不补 .js(:254)—— 所以重写目标必须显式带扩展名。",
386
386
  "jsonModules": ".json 走 JSON.parse(:1231,当前源码)。",
387
- "conclusion": "重写目标要相对入口脚本所在目录(嵌套模块则是相对自身;在「入口位于包根」的常规布局下两者一致),并且 node_modules 必须进归档。"
387
+ "conclusion": "重写目标要相对入口脚本所在目录(嵌套模块则是相对自身;在「入口位于包根」的常规布局下两者一致),并且 node_modules 必须进归档。",
388
+ "deviceObservedBareName": "真机实测(debug_run_sandbox_script,Operit 2026-10):require('fs') 返回 object 且 Object.keys 为空、readFileSync 为 undefined —— 即**空对象**,与该文件 bareNameFallback 描述一致。裸名在运行时静默降级,这就是打包期必须重写的原因。",
389
+ "deviceFilesGlobal": "真机实测:typeof Files === 'undefined'(Files 不是全局);宿主文件 API 挂在 Tools.Files 上(Tools.Files.read 是函数)。本库走 NativeInterface,两个都不用。",
390
+ "inlineScriptAndRewrite": "内联脚本(debug_run_sandbox_script)不经过打包器,任何 require('xxx') 都拿不到东西 —— 只有 toolpkg 内被重写过的 require 才能解析。所以调试脚本只能直接用 Tools.* / NativeInterface。"
388
391
  },
389
392
  "packagingTool": "OperitPackageManager (OPM)",
390
393
  "packagingToolNote": "打包期负责裸名重写与归档的一方。本文档里出现的 OperitPackageManager / OPM 都指它;命令行示例用 opm。"