@te-river/opencode-team-mode 1.6.0 → 1.6.2

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.
Files changed (150) hide show
  1. package/README.md +80 -15
  2. package/README.zh-CN.md +67 -18
  3. package/dist/host/note.d.ts +7 -0
  4. package/dist/host/note.d.ts.map +1 -0
  5. package/dist/host/note.js +31 -0
  6. package/dist/host/note.js.map +1 -0
  7. package/dist/host/v1.d.ts +14 -0
  8. package/dist/host/v1.d.ts.map +1 -0
  9. package/dist/host/v1.js +340 -0
  10. package/dist/host/v1.js.map +1 -0
  11. package/dist/host/v2-browser-gate.d.ts +45 -0
  12. package/dist/host/v2-browser-gate.d.ts.map +1 -0
  13. package/dist/host/v2-browser-gate.js +319 -0
  14. package/dist/host/v2-browser-gate.js.map +1 -0
  15. package/dist/host/v2-capabilities.d.ts +78 -0
  16. package/dist/host/v2-capabilities.d.ts.map +1 -0
  17. package/dist/host/v2-capabilities.js +173 -0
  18. package/dist/host/v2-capabilities.js.map +1 -0
  19. package/dist/host/v2-client.d.ts +53 -0
  20. package/dist/host/v2-client.d.ts.map +1 -0
  21. package/dist/host/v2-client.js +193 -0
  22. package/dist/host/v2-client.js.map +1 -0
  23. package/dist/host/v2-events.d.ts +56 -0
  24. package/dist/host/v2-events.d.ts.map +1 -0
  25. package/dist/host/v2-events.js +158 -0
  26. package/dist/host/v2-events.js.map +1 -0
  27. package/dist/host/v2-guard.d.ts +101 -0
  28. package/dist/host/v2-guard.d.ts.map +1 -0
  29. package/dist/host/v2-guard.js +199 -0
  30. package/dist/host/v2-guard.js.map +1 -0
  31. package/dist/host/v2-offload.d.ts +148 -0
  32. package/dist/host/v2-offload.d.ts.map +1 -0
  33. package/dist/host/v2-offload.js +288 -0
  34. package/dist/host/v2-offload.js.map +1 -0
  35. package/dist/host/v2-permissions.d.ts +123 -0
  36. package/dist/host/v2-permissions.d.ts.map +1 -0
  37. package/dist/host/v2-permissions.js +190 -0
  38. package/dist/host/v2-permissions.js.map +1 -0
  39. package/dist/host/v2-probe.d.ts +85 -0
  40. package/dist/host/v2-probe.d.ts.map +1 -0
  41. package/dist/host/v2-probe.js +268 -0
  42. package/dist/host/v2-probe.js.map +1 -0
  43. package/dist/host/v2-scope.d.ts +51 -0
  44. package/dist/host/v2-scope.d.ts.map +1 -0
  45. package/dist/host/v2-scope.js +58 -0
  46. package/dist/host/v2-scope.js.map +1 -0
  47. package/dist/host/v2-session-client.d.ts +105 -0
  48. package/dist/host/v2-session-client.d.ts.map +1 -0
  49. package/dist/host/v2-session-client.js +390 -0
  50. package/dist/host/v2-session-client.js.map +1 -0
  51. package/dist/host/v2-session.d.ts +85 -0
  52. package/dist/host/v2-session.d.ts.map +1 -0
  53. package/dist/host/v2-session.js +171 -0
  54. package/dist/host/v2-session.js.map +1 -0
  55. package/dist/host/v2-subagent.d.ts +157 -0
  56. package/dist/host/v2-subagent.d.ts.map +1 -0
  57. package/dist/host/v2-subagent.js +286 -0
  58. package/dist/host/v2-subagent.js.map +1 -0
  59. package/dist/host/v2-tool.d.ts +67 -0
  60. package/dist/host/v2-tool.d.ts.map +1 -0
  61. package/dist/host/v2-tool.js +209 -0
  62. package/dist/host/v2-tool.js.map +1 -0
  63. package/dist/host/v2-transcript.d.ts +73 -0
  64. package/dist/host/v2-transcript.d.ts.map +1 -0
  65. package/dist/host/v2-transcript.js +151 -0
  66. package/dist/host/v2-transcript.js.map +1 -0
  67. package/dist/host/v2-types.d.ts +229 -0
  68. package/dist/host/v2-types.d.ts.map +1 -0
  69. package/dist/host/v2-types.js +17 -0
  70. package/dist/host/v2-types.js.map +1 -0
  71. package/dist/host/v2.d.ts +42 -0
  72. package/dist/host/v2.d.ts.map +1 -0
  73. package/dist/host/v2.js +853 -0
  74. package/dist/host/v2.js.map +1 -0
  75. package/dist/index.d.ts +23 -17
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +29 -366
  78. package/dist/index.js.map +1 -1
  79. package/dist/prompts/lead.d.ts +1 -1
  80. package/dist/prompts/lead.d.ts.map +1 -1
  81. package/dist/prompts/lead.js +456 -426
  82. package/dist/prompts/lead.js.map +1 -1
  83. package/dist/prompts/shared.d.ts +2 -2
  84. package/dist/prompts/shared.d.ts.map +1 -1
  85. package/dist/prompts/shared.js +38 -11
  86. package/dist/prompts/shared.js.map +1 -1
  87. package/dist/prompts/specialists.d.ts +2 -2
  88. package/dist/prompts/specialists.d.ts.map +1 -1
  89. package/dist/prompts/specialists.js +7 -6
  90. package/dist/prompts/specialists.js.map +1 -1
  91. package/dist/task-offload.d.ts +16 -0
  92. package/dist/task-offload.d.ts.map +1 -1
  93. package/dist/task-offload.js +51 -0
  94. package/dist/task-offload.js.map +1 -1
  95. package/dist/tm/browser.d.ts.map +1 -1
  96. package/dist/tm/browser.js +41 -10
  97. package/dist/tm/browser.js.map +1 -1
  98. package/dist/tm/dispatch.d.ts +86 -1
  99. package/dist/tm/dispatch.d.ts.map +1 -1
  100. package/dist/tm/dispatch.js +360 -39
  101. package/dist/tm/dispatch.js.map +1 -1
  102. package/dist/tm/dupe-guard.d.ts +16 -3
  103. package/dist/tm/dupe-guard.d.ts.map +1 -1
  104. package/dist/tm/dupe-guard.js +27 -7
  105. package/dist/tm/dupe-guard.js.map +1 -1
  106. package/dist/tm/index.d.ts +40 -1
  107. package/dist/tm/index.d.ts.map +1 -1
  108. package/dist/tm/index.js +40 -11
  109. package/dist/tm/index.js.map +1 -1
  110. package/dist/tm/ledger.d.ts +114 -0
  111. package/dist/tm/ledger.d.ts.map +1 -0
  112. package/dist/tm/ledger.js +308 -0
  113. package/dist/tm/ledger.js.map +1 -0
  114. package/dist/tm/perm-ask.d.ts +1 -3
  115. package/dist/tm/perm-ask.d.ts.map +1 -1
  116. package/dist/tm/perm-ask.js +10 -1
  117. package/dist/tm/perm-ask.js.map +1 -1
  118. package/dist/tm/preview.d.ts +55 -0
  119. package/dist/tm/preview.d.ts.map +1 -1
  120. package/dist/tm/preview.js +225 -0
  121. package/dist/tm/preview.js.map +1 -1
  122. package/dist/tm/search.d.ts.map +1 -1
  123. package/dist/tm/search.js +40 -10
  124. package/dist/tm/search.js.map +1 -1
  125. package/dist/tm/serp-loop.d.ts +45 -0
  126. package/dist/tm/serp-loop.d.ts.map +1 -0
  127. package/dist/tm/serp-loop.js +80 -0
  128. package/dist/tm/serp-loop.js.map +1 -0
  129. package/dist/tm/stats.d.ts +29 -0
  130. package/dist/tm/stats.d.ts.map +1 -1
  131. package/dist/tm/stats.js +278 -4
  132. package/dist/tm/stats.js.map +1 -1
  133. package/dist/tm/webfetch.d.ts +4 -0
  134. package/dist/tm/webfetch.d.ts.map +1 -1
  135. package/dist/tm/webfetch.js +75 -8
  136. package/dist/tm/webfetch.js.map +1 -1
  137. package/docs/installation-v2.md +445 -0
  138. package/docs/installation.md +12 -0
  139. package/docs/research/agent-data-exchange.md +117 -0
  140. package/docs/research/browser-pane.md +89 -0
  141. package/docs/research/host-http-api.md +132 -0
  142. package/docs/research/host-subagent-injection.md +187 -0
  143. package/docs/research/plugin-loader-contract.md +261 -0
  144. package/docs/research/v2-builtin-tools.md +447 -0
  145. package/docs/v2-port-notes.md +413 -0
  146. package/index.js +7 -0
  147. package/package.json +64 -61
  148. package/scripts/gen-v2-config.mjs +304 -0
  149. package/scripts/lib/config-surgery.cjs +239 -0
  150. package/scripts/lib/fake-ctx.mjs +169 -0
@@ -0,0 +1,319 @@
1
+ import { checkWebUrl } from "../tm/webfetch.js";
2
+ import { isEnvFilePath } from "../envprotect.js";
3
+ /**
4
+ * The native browser catalog, put behind OUR gate.
5
+ *
6
+ * The host ships 45 `browser_*` tools and renders them in its own side panel, which
7
+ * is why they are the attractive option (docs/research/browser-pane.md). The cost is
8
+ * that they are the one part of the surface we did not police: `permission.evaluate`
9
+ * was observed NOT firing for them in a live 2.0.16 session, so the domain list, the
10
+ * address red line and the R6 env-file rule all had a working bypass the length of a
11
+ * tool name. This module closes it at the only seam that is left — `tool.hook
12
+ * ("execute.before")`, whose `input` is mutable and which sees the exact URL the
13
+ * model is about to navigate to.
14
+ *
15
+ * TWO enforcement layers, because the before-hook's power to abort is a host promise
16
+ * nobody has made to us:
17
+ *
18
+ * 1. refuse at the door: throw with the governance sentence, which is how v1's
19
+ * governed tools already answer an out-of-policy target.
20
+ * 2. if the call happens anyway, take the ANSWER away: an `execute.after` for the
21
+ * same tool and session right after our refusal means the throw did not stop it,
22
+ * so the page content is replaced by the same refusal. The request may still have
23
+ * left the machine (we cannot un-spawn the host's browser from here), but the
24
+ * private page never reaches the context window, the run store or the trajectory.
25
+ *
26
+ * Layer 2 is also the measurement: `leaked` is the count of refusals the host walked
27
+ * past. Zero after a session of browser work is the evidence the gate has teeth; a
28
+ * non-zero number says so in `tm_stats` instead of letting us claim a block we did not
29
+ * perform — which is the product rule, not a logging nicety.
30
+ *
31
+ * Scope discipline (#22) applies first: a non-Team session's browser calls are the
32
+ * user's own configuration's business, and an unattributable one is treated as NOT
33
+ * ours. Only Team roles get this rule injected, and only they get the stricter one.
34
+ */
35
+ /** How long after a refusal we still credit the call to it. Generous on purpose: a
36
+ * host that queues the tool and then answers is the case we are measuring. */
37
+ const LEAK_WINDOW_MS = 30_000;
38
+ /** The four host-vs-tm_browser differences that cost rounds in the user's real task log,
39
+ * said once per session at the result where each one bites. */
40
+ export const NATIVE_BROWSER_NOTE = "(宿主原生浏览器的读法,本会话只说一次:① snapshot/find 的结果是 {tab, content, truncated}," +
41
+ "可寻址记号写成 `@e8 [link]`,不是 tm_browser 的 `[ref=e12]`;② evaluate 的参数名是 `script`(不是 fn)," +
42
+ "而且它求值的是表达式:传 `() => …` 这种函数源文本不会被调用,结果同样是 {} —— 要么写成表达式," +
43
+ "要么自己写成 `(()=>{…})()`,返回对象也要自己 JSON.stringify 成标量;③ screenshot 需要一个真正可见且聚焦的" +
44
+ "桌面标签页,宿主在后台窗口下必定失败,别为它反复 focus;④ wait 的 state 取值不是 playwright 那一套" +
45
+ "(实测 `load` 和 `text` 在 2.0.18 上直接 error,宿主不给原因),别拿它当渲染完成的判据;" +
46
+ "⑤ SPA 首帧常是空 content:先重拍再猜,或者直接用站方自己的搜索接口/搜索框,而不是猜 URL 路径。)";
47
+ function locatableText(result) {
48
+ const content = result?.content;
49
+ if (!Array.isArray(content))
50
+ return null;
51
+ const index = content.findIndex((p) => p && typeof p === "object" && p.type === "text" && typeof p.text === "string");
52
+ if (index < 0)
53
+ return null;
54
+ const part = content[index];
55
+ return { parts: content, index, text: String(part.text ?? "") };
56
+ }
57
+ /** The host spells its browser tools `browser_snapshot` on the direct surface and
58
+ * `browser.snapshot` as a Code Mode catalog path — the user's own desktop log shows both,
59
+ * and a matcher that knows only one of them silently governs nothing. */
60
+ function isNativeBrowserTool(name) {
61
+ return name.startsWith("browser_") || name.startsWith("browser.");
62
+ }
63
+ /** Did this `execute` program actually drive the browser? Read from the host's own
64
+ * `result.metadata.toolCalls[]` (the exported desktop session carries it), because the
65
+ * program TEXT only tells us what was written, not what ran. */
66
+ function droveBrowser(result) {
67
+ const calls = result?.metadata?.toolCalls;
68
+ if (!Array.isArray(calls))
69
+ return false;
70
+ return calls.some((c) => isNativeBrowserTool(String(c?.tool ?? "")));
71
+ }
72
+ /** The three verbs whose result shape a model gets wrong without being told (the snapshot's
73
+ * `content` vs `text`, `find`'s empty answer, `evaluate`'s non-scalar return). Matched on the
74
+ * suffix so BOTH host spellings count — `browser_snapshot` on the direct surface and
75
+ * `browser.snapshot` as a catalog path — because a note that fires for the spelling nobody
76
+ * uses is the same dead code as a gate that returns before its own branch. */
77
+ const NOTE_VERBS = ["snapshot", "find", "evaluate"];
78
+ function wantsReadingNote(tool) {
79
+ return NOTE_VERBS.includes(tool.replace(/^browser[._]/, ""));
80
+ }
81
+ /** The addresses a browser call can carry. `url` on navigate / tabs.open, `path` on
82
+ * preview and the file verbs, and nothing on the pure-input verbs (click, fill),
83
+ * which are governed by whatever page is already open. */
84
+ function targetOf(input) {
85
+ const rec = input;
86
+ if (!rec || typeof rec !== "object")
87
+ return null;
88
+ for (const key of ["url", "targetUrl"]) {
89
+ const v = rec[key];
90
+ if (typeof v === "string" && v.trim())
91
+ return { kind: "url", value: v.trim() };
92
+ }
93
+ if (typeof rec.path === "string" && rec.path.trim())
94
+ return { kind: "path", value: rec.path.trim() };
95
+ return null;
96
+ }
97
+ /** Every http(s) host named in a Code Mode program that is refused WITHOUT consent by
98
+ * the address red line. Only the hostname is read out and reported — never the program
99
+ * text, which is the user's code and may carry a token in its query string. */
100
+ function hardUrlHosts(program) {
101
+ const hits = [];
102
+ for (const m of program.matchAll(/https?:\/\/([^\s"'`)<>,\\]+)/gi)) {
103
+ const raw = m[1] ?? "";
104
+ let host = "";
105
+ try {
106
+ host = new URL("http://" + raw.replace(/^[^@]*@/, "")).hostname;
107
+ }
108
+ catch {
109
+ continue;
110
+ }
111
+ if (!host)
112
+ continue;
113
+ const v = checkWebUrl("http://" + host + "/", []);
114
+ if (!v.ok && !v.askable)
115
+ hits.push(host);
116
+ }
117
+ return hits;
118
+ }
119
+ export function applyV2BrowserGate(ctx, opts) {
120
+ const report = { seen: 0, classified: 0, refused: 0, codeModeRefused: 0, leaked: 0, held: 0, annotated: 0, foreignSkipped: 0, byTool: {} };
121
+ const registrations = [];
122
+ /** key = `${tool}\n${sessionID}` → the refusal we owe that call's answer */
123
+ const annotated = new Set();
124
+ const pending = new Map();
125
+ const off = /^(0|false|no|off)$/i.test(String(opts.env?.TM_V2_BROWSER_GATE ?? "").trim());
126
+ const keyOf = (tool, sessionID) => `${tool}\n${String(sessionID ?? "")}`;
127
+ const decide = (target) => {
128
+ if (target.kind === "path") {
129
+ // R6, applied to the one native verb that reads from the server's own disk.
130
+ return isEnvFilePath(target.value)
131
+ ? `原生浏览器要预览的路径 ${target.value} 是环境文件家族(R6 红线),不放行:这类读取没有任何"看起来对不对"可判断,也不存在可批准的窗口。`
132
+ : null;
133
+ }
134
+ const verdict = checkWebUrl(target.value, opts.allowlist);
135
+ return verdict.ok ? null : verdict.message;
136
+ };
137
+ const fireBefore = (raw) => {
138
+ const event = raw;
139
+ const tool = String(event?.tool ?? event?.name ?? "");
140
+ // `execute` is checked in the same breath as the direct verbs, NOT after a
141
+ // `browser_*` early return: the code-mode leg used to sit BELOW that return, so the
142
+ // whole branch was unreachable and a navigate inside a program was gated by nothing
143
+ // but the model's own memory. Proven by reading the compiled hook, not by reasoning.
144
+ const isExecute = tool === "execute";
145
+ if (!isExecute && !isNativeBrowserTool(tool))
146
+ return;
147
+ if (opts.scope && opts.scope.count(opts.scope.decide(event)) !== "ours") {
148
+ report.foreignSkipped++;
149
+ return;
150
+ }
151
+ report.seen++;
152
+ if (off)
153
+ return;
154
+ // Code Mode reaches the SAME browser through `tools.browser.tabs.open(...)`, and an
155
+ // inner call may never surface as its own execute.before event — so a gate that only
156
+ // reads `input.url` can be walked around by putting the navigate inside a program.
157
+ // The address red line is the part worth defending there: a program is source text,
158
+ // and the hosts it names are judgement-free metadata ranges.
159
+ if (isExecute) {
160
+ const program = event?.input?.program;
161
+ if (typeof program === "string" && /browser[._]|browser_/.test(program)) {
162
+ for (const host of hardUrlHosts(program)) {
163
+ report.classified++;
164
+ report.refused++;
165
+ report.codeModeRefused++;
166
+ const message = `你放进 execute 程序里的浏览器调用指向 ${host},那是不容路由 / 元数据地址段——R6 同级红线,任何配置都不能批准,` +
167
+ `所以我没有让这个程序跑起来。要本机服务请用有头浏览器自己开,要公网内容请给公开主机名。`;
168
+ pending.set(keyOf(tool, event?.sessionID), { message, at: Date.now() });
169
+ throw new Error(message);
170
+ }
171
+ }
172
+ return;
173
+ }
174
+ const target = targetOf(event?.input);
175
+ if (!target)
176
+ return;
177
+ report.classified++;
178
+ report.byTool[tool] ??= { seen: 0, refused: 0, leaked: 0 };
179
+ report.byTool[tool].seen++;
180
+ const message = decide(target);
181
+ if (!message)
182
+ return;
183
+ report.refused++;
184
+ report.byTool[tool].refused++;
185
+ pending.set(keyOf(tool, event?.sessionID), { message, at: Date.now() });
186
+ // Layer 1. Thrown rather than returned: the input is mutable, but silently
187
+ // rewriting a URL the model chose is the guesswork this product refuses — the
188
+ // model has to see the refusal, and the host has to be the one that surfaces it.
189
+ throw new Error(message);
190
+ };
191
+ const fireAfter = (raw) => {
192
+ const event = raw;
193
+ const tool = String(event?.tool ?? event?.name ?? "");
194
+ const isExecute = tool === "execute";
195
+ if (!isExecute && !isNativeBrowserTool(tool))
196
+ return;
197
+ if (off)
198
+ return;
199
+ // No scope re-check here: the owner question was answered at the door, and a
200
+ // foreign session never has a pending refusal for this lookup to match.
201
+ const key = keyOf(tool, event?.sessionID);
202
+ const owed = pending.get(key);
203
+ let stripped = false;
204
+ if (owed) {
205
+ pending.delete(key);
206
+ const now = Date.now();
207
+ if (now - owed.at > LEAK_WINDOW_MS) {
208
+ report.held++;
209
+ }
210
+ else {
211
+ // Layer 2: the host produced an answer to a call we refused. Take the content out
212
+ // and put the refusal in its place — the model must never read a page our policy
213
+ // says it may not, and a silent pass would be the exact claim we cannot make.
214
+ report.leaked++;
215
+ if (report.byTool[tool])
216
+ report.byTool[tool].leaked++;
217
+ const found = locatableText(event?.result);
218
+ stripped = !!found;
219
+ if (found) {
220
+ found.parts[found.index] = {
221
+ type: "text",
222
+ text: `${owed.message}
223
+
224
+ (这道门禁本来是在请求前生效的:${tool} 的调用被宿主放过去了,所以我把它的返回换成了这段拒绝语。这个页面的内容没有进入上下文、run store 或轨迹;请求本身已经发生,这一条我没有能力撤回。)`,
225
+ };
226
+ for (let i = found.index + 1; i < found.parts.length; i++) {
227
+ const p = found.parts[i];
228
+ if (p && typeof p === "object" && p.type === "text" && typeof p.text === "string")
229
+ found.parts[i] = { type: "text", text: "" };
230
+ }
231
+ }
232
+ }
233
+ }
234
+ // Once per session, at the result where the confusion actually happened: the host's
235
+ // browser surface differs from tm_browser's in ways that each cost a round in the
236
+ // user's real-task log (a guessed `snap.text`, an `fn` argument that is really
237
+ // `script`, a function source that reads as `{}`, a screenshot retried after `focus`,
238
+ // a `wait` state the host rejects, a MediaWiki URL guessed instead of the site's own
239
+ // search). This is the cheapest place to say it — the tool description is the host's,
240
+ // and the prompt would charge every role for text only the browsing ones use. The
241
+ // Code Mode shape is why `execute` is included: the model drives the browser through
242
+ // `tools.browser.*` there and never sees a `browser_*` tool call at all.
243
+ if (stripped)
244
+ return;
245
+ const sid = String(event?.sessionID ?? "");
246
+ const wantsNote = isExecute
247
+ ? droveBrowser(event?.result)
248
+ : wantsReadingNote(tool);
249
+ if (!sid || annotated.has(sid) || !wantsNote)
250
+ return;
251
+ const found = locatableText(event?.result);
252
+ if (!found)
253
+ return;
254
+ annotated.add(sid);
255
+ report.annotated++;
256
+ found.parts[found.index] = { type: "text", text: `${found.text}\n\n${NATIVE_BROWSER_NOTE}` };
257
+ };
258
+ const toolDomain = ctx?.tool;
259
+ if (typeof toolDomain?.hook === "function") {
260
+ const hook = toolDomain.hook;
261
+ for (const [name, cb] of [
262
+ ["execute.before", fireBefore],
263
+ ["execute.after", fireAfter],
264
+ ]) {
265
+ try {
266
+ const reg = hook(name, cb);
267
+ // The host's transform/hook registrars are async; hold the promise so teardown
268
+ // can await it rather than disposing a registration that never landed.
269
+ registrations.push({
270
+ dispose: async () => {
271
+ try {
272
+ await reg.then?.((r) => r?.dispose?.());
273
+ }
274
+ catch {
275
+ /* a host that already tore down its registry has nothing left to free */
276
+ }
277
+ },
278
+ });
279
+ }
280
+ catch {
281
+ /* a host that refuses the hook is reported by the capability probe, not here */
282
+ }
283
+ }
284
+ }
285
+ // Sweep refusals that never saw an answer: the door held (the call was aborted and
286
+ // nothing came back), which is the good case and still has to be counted.
287
+ const sweeper = setInterval(() => {
288
+ const now = Date.now();
289
+ for (const [k, v] of pending) {
290
+ if (now - v.at > LEAK_WINDOW_MS) {
291
+ pending.delete(k);
292
+ report.held++;
293
+ }
294
+ }
295
+ }, LEAK_WINDOW_MS);
296
+ if (typeof sweeper === "object" && sweeper && "unref" in sweeper)
297
+ sweeper.unref?.();
298
+ // The host reloads plugins IN THIS PROCESS, so an interval that outlives teardown is
299
+ // not a harmless one: every boot would add another sweeper counting the same
300
+ // refusals. Clearing it is part of releasing the registration, not a nicety.
301
+ registrations.push({
302
+ dispose: async () => {
303
+ clearInterval(sweeper);
304
+ },
305
+ });
306
+ return {
307
+ registrations,
308
+ report,
309
+ fireBefore,
310
+ fireAfter,
311
+ };
312
+ }
313
+ export function browserGateSummary(r) {
314
+ if (!r.seen)
315
+ return "原生 browser_* 没被调用过(门禁在场,没数据)";
316
+ const teeth = r.refused === 0 ? "没有拒绝发生过" : r.leaked === 0 ? `${r.refused} 次拒绝全部拦停在门口` : `${r.refused} 次拒绝中 ${r.leaked} 次被宿主放过去(已在返回处换成拒绝语)`;
317
+ return `原生 browser_*/Code Mode:看过 ${r.seen} 次调用(其中 Code Mode 程序拒绝 ${r.codeModeRefused} 次) · 可判定目标 ${r.classified} 次 · 拒绝 ${r.refused} 次(${teeth})· 拦下后无返回 ${r.held} 次 · 非 Team 跳过 ${r.foreignSkipped} 次 · 原生读法提示发了 ${r.annotated} 个会话`;
318
+ }
319
+ //# sourceMappingURL=v2-browser-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v2-browser-gate.js","sourceRoot":"","sources":["../../src/host/v2-browser-gate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ import type { CapabilityRow } from "../capabilities.js";
2
+ /**
3
+ * The host-capability matrix, built from what THIS v2 session observed.
4
+ *
5
+ * v1's probe can classify a seam as `ok` by watching a hook fire or an event
6
+ * arrive. v2 needs the same table even more — a 2.x host is moving under us, and
7
+ * every promise on this line (per-role tool trim, JIT over native tools, the
8
+ * address red line, the forced background) lives or dies on a hook the host may or
9
+ * may not call. What it must NOT do is reuse v1's row list: those seam names are
10
+ * v1's SDK, and a row that says "declared" because a type file mentions a name is
11
+ * worth nothing when the host never calls it (that is precisely how the invented
12
+ * `session.hook("prompt")` nearly got built on).
13
+ *
14
+ * So every row here is derived from an observation the runtime already made — the
15
+ * probe's attached/missing sets, the guard's and offloader's counters — and a row
16
+ * that we merely know from types says `declared` and names the missing proof.
17
+ */
18
+ interface Inputs {
19
+ ctx: unknown;
20
+ probe: {
21
+ report: {
22
+ ctxDomains: string[];
23
+ hooksMissing: string[];
24
+ executed: string[];
25
+ executedAfter: string[];
26
+ actions: string[];
27
+ evaluations: number;
28
+ agentsSeen: string[];
29
+ };
30
+ };
31
+ guardsInstalled: boolean;
32
+ backgroundForced: boolean;
33
+ offload: {
34
+ active: boolean;
35
+ registrations: unknown[];
36
+ report: {
37
+ seen: number;
38
+ offloaded: number;
39
+ };
40
+ };
41
+ sessionHooks: number;
42
+ temperature: number | false | null;
43
+ hasTodoSeam: boolean;
44
+ hasAsk: boolean;
45
+ /** what the boot round-trip self-check found: absent | round-trip | read-back-mismatch | threw */
46
+ storageState: string;
47
+ /** Team-scope isolation (#22): how many hook events resolved to one of our six
48
+ * roles, how many were somebody else's, and how many the host never told us. */
49
+ scope?: {
50
+ report: {
51
+ ours: number;
52
+ foreign: number;
53
+ unknown: number;
54
+ };
55
+ };
56
+ /** The `ctx.event.subscribe()` feed (#8). `received` is the observation that
57
+ * makes this row `ok` rather than `declared`: an event that actually arrived. */
58
+ eventFeed?: {
59
+ active: boolean;
60
+ received: number;
61
+ forwarded: number;
62
+ unknown: Record<string, number>;
63
+ stopped?: string;
64
+ };
65
+ /** #33 — what `tm_join { cancel: true }` actually got from `ctx.session.interrupt`.
66
+ * Absent means the bridge never wrapped the seam, which is itself the row's story:
67
+ * for a whole release v2 had no stop path at all, and nothing printed that fact. */
68
+ stop?: {
69
+ tried: number;
70
+ confirmed: number;
71
+ refused: number;
72
+ unknown: number;
73
+ error?: string;
74
+ };
75
+ }
76
+ export declare function v2CapabilityRows(i: Inputs): CapabilityRow[];
77
+ export {};
78
+ //# sourceMappingURL=v2-capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v2-capabilities.d.ts","sourceRoot":"","sources":["../../src/host/v2-capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEvD;;;;;;;;;;;;;;;GAeG;AAEH,UAAU,MAAM;IACd,GAAG,EAAE,OAAO,CAAA;IACZ,KAAK,EAAE;QACL,MAAM,EAAE;YACN,UAAU,EAAE,MAAM,EAAE,CAAA;YACpB,YAAY,EAAE,MAAM,EAAE,CAAA;YACtB,QAAQ,EAAE,MAAM,EAAE,CAAA;YAClB,aAAa,EAAE,MAAM,EAAE,CAAA;YACvB,OAAO,EAAE,MAAM,EAAE,CAAA;YACjB,WAAW,EAAE,MAAM,CAAA;YACnB,UAAU,EAAE,MAAM,EAAE,CAAA;SACrB,CAAA;KACF,CAAA;IACD,eAAe,EAAE,OAAO,CAAA;IACxB,gBAAgB,EAAE,OAAO,CAAA;IACzB,OAAO,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,aAAa,EAAE,OAAO,EAAE,CAAC;QAAC,MAAM,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;IACnG,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAAA;IAClC,WAAW,EAAE,OAAO,CAAA;IACpB,MAAM,EAAE,OAAO,CAAA;IACf,kGAAkG;IAClG,YAAY,EAAE,MAAM,CAAA;IACpB;qFACiF;IACjF,KAAK,CAAC,EAAE;QAAE,MAAM,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;IACtE;sFACkF;IAClF,SAAS,CAAC,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACvH;;yFAEqF;IACrF,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAC9F;AAID,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE,CA6K3D"}
@@ -0,0 +1,173 @@
1
+ const has = (list, want) => list.some(want);
2
+ export function v2CapabilityRows(i) {
3
+ const domains = i.probe.report.ctxDomains;
4
+ const missing = i.probe.report.hooksMissing;
5
+ const saw = (point) => !missing.some((m) => m.includes(point));
6
+ const rows = [
7
+ {
8
+ seam: 'session.hook("context")',
9
+ feature: "每个角色不再被 DENY 的工具从请求里删掉 · 温度 0.2 · 黑板根目录送给 lead",
10
+ state: i.probe.report.agentsSeen.length ? "ok" : i.sessionHooks ? "declared" : "missing",
11
+ evidence: "hook",
12
+ note: i.probe.report.agentsSeen.length
13
+ ? `已在这些角色的请求上跑过:${i.probe.report.agentsSeen.join(" ")}`
14
+ : "挂上了,但本进程还没等到一次请求——升级后先看这一行有没有变成 ok",
15
+ },
16
+ {
17
+ seam: 'session.hook("compaction")',
18
+ feature: "压缩后仍然活着的清单(回复骨架 / 卸载句柄 / 未结算子代理 id / 黑板路径)",
19
+ state: saw("compaction") ? "declared" : "missing",
20
+ evidence: "static",
21
+ note: "v2 只在真正压缩前调用它,插件无法自己制造一次,所以这里最多是 declared,不是 ok",
22
+ },
23
+ {
24
+ seam: 'tool.hook("execute.before")',
25
+ feature: "每次 subagent 派发强制 background(前台会把 lead 整轮钉住)",
26
+ state: i.probe.report.executed.length ? "ok" : i.backgroundForced ? "declared" : "missing",
27
+ evidence: "hook",
28
+ note: i.probe.report.executed.length ? `见过的工具:${i.probe.report.executed.join(" ")}` : undefined,
29
+ },
30
+ {
31
+ seam: 'tool.hook("execute.after")',
32
+ feature: "JIT 上下文治理覆盖宿主自己的工具(原生 read/shell/webfetch 与 Code Mode 的大输出不再直接进上下文)",
33
+ state: i.offload.registrations.length === 0 ? "missing" : i.offload.report.offloaded > 0 ? "ok" : i.offload.report.seen > 0 ? "ok" : "declared",
34
+ evidence: "runtime",
35
+ note: i.offload.report.seen
36
+ ? `本进程已看 ${i.offload.report.seen} 次原生结果,其中 ${i.offload.report.offloaded} 次被卸载`
37
+ : "缝挂上了,还没遇到一次够大的原生输出(这不是坏消息,但要等真遇到才算 ok)",
38
+ },
39
+ {
40
+ seam: 'permission.hook("evaluate")',
41
+ feature: "egress 红线(元数据/链路本地/私网)套到宿主原生 webfetch · 按命令行判定的 R6",
42
+ state: i.guardsInstalled ? (i.probe.report.evaluations > 0 ? "ok" : "declared") : "missing",
43
+ evidence: "hook",
44
+ note: i.probe.report.evaluations > 0 ? `看到 ${i.probe.report.evaluations} 次评估,动作:${i.probe.report.actions.join(" ") || "无"}` : i.guardsInstalled ? "挂上了但还没被调用过" : undefined,
45
+ },
46
+ {
47
+ seam: "工具 ctx.ask(宿主官方确认框)",
48
+ feature: "白名单外的目标逐次征求你的同意 · v2 上退化为直接拒绝",
49
+ state: i.hasAsk ? "declared" : "missing",
50
+ evidence: "runtime",
51
+ note: i.hasAsk ? undefined : "2.0.16 的 ToolContext 不带 ask(实测:我们自己在工具 options 里声明 permission 也没触发评估)。受治理的调用因此一律 fail closed,这是这个平台的事实,不是我们的选择",
52
+ },
53
+ {
54
+ seam: "宿主 session 树(children / todo / messages)",
55
+ feature: "tm_join 收子代理结果 · 目标探针读宿主清单",
56
+ state: i.probe.report.ctxDomains.includes("session") ? "not-seen" : "missing",
57
+ evidence: "runtime",
58
+ note: i.probe.report.ctxDomains.includes("session")
59
+ ? "ctx 有 session 域,但我们尚未从中读到子会话/清单(v1 客户端那套 API 形状在 v2 未验;tm_join 现在会明说这一格没查成)"
60
+ : undefined,
61
+ },
62
+ {
63
+ seam: "ctx.event.subscribe() → 事件流",
64
+ feature: "看见别的会话发生了什么(结算、注入、跨会话信号)",
65
+ state: !i.eventFeed
66
+ ? domains.includes("event")
67
+ ? "declared"
68
+ : "missing"
69
+ : i.eventFeed.received > 0
70
+ ? "ok"
71
+ : i.eventFeed.active
72
+ ? "not-seen"
73
+ : "missing",
74
+ // Counted, not asserted: `active` only means subscribe() returned
75
+ // something iterable. `received > 0` is the observation that a 2.x host
76
+ // really does push session events at a plugin, which is what tm_join's
77
+ // settle detection needed and never had (#8).
78
+ evidence: i.eventFeed && i.eventFeed.received > 0 ? "event" : "static",
79
+ // This row used to say the opposite — that the public shape needed an Effect
80
+ // runtime and therefore could not be used with our empty `dependencies`. A
81
+ // live 2.0.16 probe disproved it, so the correction is the whole point: the
82
+ // seam is reachable with zero dependencies, and the catch is not the
83
+ // dependency but the scope (server-wide, every session's events).
84
+ note: "实测(docs/research/agent-data-exchange.md):subscribe() 零依赖可用,但流是**全服务器**的 —— 用它必须先按 sessionID 过滤,否则会把别人会话的事件读进我们的上下文与轨迹",
85
+ },
86
+ {
87
+ seam: "ctx.storage",
88
+ feature: "LEDGER 的落点(v2 没有 todowrite)",
89
+ // Four facts, and only one of them is "fine": the round-trip proved it, an
90
+ // absent domain is not there to build on, a probe that threw or came back
91
+ // different is a failure (NOT `not-seen`, which would read as "haven't got
92
+ // round to it yet"), and `declared` is reserved for the one case where the
93
+ // domain exists and nothing has been tried — which is exactly what it means.
94
+ state: i.storageState === "round-trip"
95
+ ? "ok"
96
+ : i.storageState === "absent" || i.storageState === "threw" || i.storageState === "read-back-mismatch"
97
+ ? "missing"
98
+ : domains.includes("storage")
99
+ ? "declared"
100
+ : "missing",
101
+ evidence: "runtime",
102
+ note: i.storageState === "round-trip"
103
+ ? "启动自检写入标记并读回成功 —— 清单可以落在这里"
104
+ : i.storageState === "absent"
105
+ ? "这个宿主没给 storage 域"
106
+ : i.storageState === "threw" || i.storageState === "read-back-mismatch"
107
+ ? `自检没通过(${i.storageState}):域在,但我们写的东西没有原样回来`
108
+ : "域在,本次启动还没往里写过东西",
109
+ },
110
+ {
111
+ seam: "Team 作用域隔离",
112
+ feature: "每个钩子动手之前先问「这是我们六个角色吗」——不是就完全别碰(build / plan / 用户自己的 agent 保持刚装好 OpenCode 的样子)",
113
+ // ok only means what it says: a resolved call was actually skipped or served.
114
+ // `unknown` is not a pass — it is the host not telling us who owns the call,
115
+ // and every one of those is a call our governance deliberately did NOT touch.
116
+ state: !i.scope ? "declared" : i.scope.report.unknown ? "unverified" : "ok",
117
+ evidence: "runtime",
118
+ note: !i.scope
119
+ ? "本进程的钩子还没被调用过,没东西可判"
120
+ : ` ours=${i.scope.report.ours} foreign=${i.scope.report.foreign} unknown=${i.scope.report.unknown}` +
121
+ (i.scope.report.unknown
122
+ ? " —— 这些次宿主没在事件里带 agent:按「不是我们的」处理,宁可少治理,也不多改别人的会话"
123
+ : ""),
124
+ },
125
+ ];
126
+ // #33 — can the lead STOP a background child at all? Before this the answer was "no",
127
+ // and no row said so: tm_join's cancel:true fell through to 宿主无 abort 接口 in a tool
128
+ // reply only the model sees, so a user asking "kill it" got silence from the panel and
129
+ // the plugin's own capability table claimed nothing about it.
130
+ rows.push({
131
+ seam: "ctx.session.interrupt",
132
+ feature: "tm_join { cancel: true } 停掉跑飞的后台子代理",
133
+ // `ok` requires the host to have confirmed a stop with interrupted=true. attempted-but-
134
+ // never-confirmed is `declared`: the seam is wired, nobody has exercised it. An absent
135
+ // interrupt domain is `missing`, which is the honest row for "this host gave no stop
136
+ // path" and the only way a future upgrade that drops it becomes a line rather than a
137
+ // rumour.
138
+ state: !i.stop
139
+ ? "declared"
140
+ : i.stop.confirmed > 0
141
+ ? "ok"
142
+ : i.stop.tried > 0
143
+ ? "declared"
144
+ : domains.includes("session")
145
+ ? "declared"
146
+ : "missing",
147
+ evidence: i.stop && i.stop.confirmed > 0 ? "runtime" : "static",
148
+ note: i.stop && i.stop.tried
149
+ ? `已试 ${i.stop.tried} 次:宿主确认中断 ${i.stop.confirmed} · idle no-op ${i.stop.refused} · 未回布尔 ${i.stop.unknown}` +
150
+ (i.stop.error ? `(最后一次宿主错误:${i.stop.error})` : "")
151
+ : "缝已接上(POST /api/session/{id}/interrupt 的契约是 interrupted=true / false=idle no-op),本进程还没被 cancel:true 用过",
152
+ });
153
+ if (typeof i.temperature === "number") {
154
+ rows.push({
155
+ seam: "options.temperature",
156
+ feature: "所有角色 0.2(v2 上 agent 配置里的 temperature 是 legacy 字段、runner 不发,所以只能走请求层)",
157
+ state: i.probe.report.agentsSeen.length ? "ok" : "declared",
158
+ evidence: "runtime",
159
+ note: `本进程请求里带的温度:${i.temperature}`,
160
+ });
161
+ }
162
+ if (!i.hasTodoSeam) {
163
+ rows.push({
164
+ seam: "GET /session/{id}/todo",
165
+ feature: "目标探针(清单还有未完成项时不许把该轮当收尾)",
166
+ state: "missing",
167
+ evidence: "runtime",
168
+ note: "v2 的 client 垫片没有这个端点;tm_join 现在会明说'这一轮目标核对没做成',而不是沉默",
169
+ });
170
+ }
171
+ return rows;
172
+ }
173
+ //# sourceMappingURL=v2-capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v2-capabilities.js","sourceRoot":"","sources":["../../src/host/v2-capabilities.ts"],"names":[],"mappings":"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"}