@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.
- package/README.md +80 -15
- package/README.zh-CN.md +67 -18
- package/dist/host/note.d.ts +7 -0
- package/dist/host/note.d.ts.map +1 -0
- package/dist/host/note.js +31 -0
- package/dist/host/note.js.map +1 -0
- package/dist/host/v1.d.ts +14 -0
- package/dist/host/v1.d.ts.map +1 -0
- package/dist/host/v1.js +340 -0
- package/dist/host/v1.js.map +1 -0
- package/dist/host/v2-browser-gate.d.ts +45 -0
- package/dist/host/v2-browser-gate.d.ts.map +1 -0
- package/dist/host/v2-browser-gate.js +319 -0
- package/dist/host/v2-browser-gate.js.map +1 -0
- package/dist/host/v2-capabilities.d.ts +78 -0
- package/dist/host/v2-capabilities.d.ts.map +1 -0
- package/dist/host/v2-capabilities.js +173 -0
- package/dist/host/v2-capabilities.js.map +1 -0
- package/dist/host/v2-client.d.ts +53 -0
- package/dist/host/v2-client.d.ts.map +1 -0
- package/dist/host/v2-client.js +193 -0
- package/dist/host/v2-client.js.map +1 -0
- package/dist/host/v2-events.d.ts +56 -0
- package/dist/host/v2-events.d.ts.map +1 -0
- package/dist/host/v2-events.js +158 -0
- package/dist/host/v2-events.js.map +1 -0
- package/dist/host/v2-guard.d.ts +101 -0
- package/dist/host/v2-guard.d.ts.map +1 -0
- package/dist/host/v2-guard.js +199 -0
- package/dist/host/v2-guard.js.map +1 -0
- package/dist/host/v2-offload.d.ts +148 -0
- package/dist/host/v2-offload.d.ts.map +1 -0
- package/dist/host/v2-offload.js +288 -0
- package/dist/host/v2-offload.js.map +1 -0
- package/dist/host/v2-permissions.d.ts +123 -0
- package/dist/host/v2-permissions.d.ts.map +1 -0
- package/dist/host/v2-permissions.js +190 -0
- package/dist/host/v2-permissions.js.map +1 -0
- package/dist/host/v2-probe.d.ts +85 -0
- package/dist/host/v2-probe.d.ts.map +1 -0
- package/dist/host/v2-probe.js +268 -0
- package/dist/host/v2-probe.js.map +1 -0
- package/dist/host/v2-scope.d.ts +51 -0
- package/dist/host/v2-scope.d.ts.map +1 -0
- package/dist/host/v2-scope.js +58 -0
- package/dist/host/v2-scope.js.map +1 -0
- package/dist/host/v2-session-client.d.ts +105 -0
- package/dist/host/v2-session-client.d.ts.map +1 -0
- package/dist/host/v2-session-client.js +390 -0
- package/dist/host/v2-session-client.js.map +1 -0
- package/dist/host/v2-session.d.ts +85 -0
- package/dist/host/v2-session.d.ts.map +1 -0
- package/dist/host/v2-session.js +171 -0
- package/dist/host/v2-session.js.map +1 -0
- package/dist/host/v2-subagent.d.ts +157 -0
- package/dist/host/v2-subagent.d.ts.map +1 -0
- package/dist/host/v2-subagent.js +286 -0
- package/dist/host/v2-subagent.js.map +1 -0
- package/dist/host/v2-tool.d.ts +67 -0
- package/dist/host/v2-tool.d.ts.map +1 -0
- package/dist/host/v2-tool.js +209 -0
- package/dist/host/v2-tool.js.map +1 -0
- package/dist/host/v2-transcript.d.ts +73 -0
- package/dist/host/v2-transcript.d.ts.map +1 -0
- package/dist/host/v2-transcript.js +151 -0
- package/dist/host/v2-transcript.js.map +1 -0
- package/dist/host/v2-types.d.ts +229 -0
- package/dist/host/v2-types.d.ts.map +1 -0
- package/dist/host/v2-types.js +17 -0
- package/dist/host/v2-types.js.map +1 -0
- package/dist/host/v2.d.ts +42 -0
- package/dist/host/v2.d.ts.map +1 -0
- package/dist/host/v2.js +853 -0
- package/dist/host/v2.js.map +1 -0
- package/dist/index.d.ts +23 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -366
- package/dist/index.js.map +1 -1
- package/dist/prompts/lead.d.ts +1 -1
- package/dist/prompts/lead.d.ts.map +1 -1
- package/dist/prompts/lead.js +456 -426
- package/dist/prompts/lead.js.map +1 -1
- package/dist/prompts/shared.d.ts +2 -2
- package/dist/prompts/shared.d.ts.map +1 -1
- package/dist/prompts/shared.js +38 -11
- package/dist/prompts/shared.js.map +1 -1
- package/dist/prompts/specialists.d.ts +2 -2
- package/dist/prompts/specialists.d.ts.map +1 -1
- package/dist/prompts/specialists.js +7 -6
- package/dist/prompts/specialists.js.map +1 -1
- package/dist/task-offload.d.ts +16 -0
- package/dist/task-offload.d.ts.map +1 -1
- package/dist/task-offload.js +51 -0
- package/dist/task-offload.js.map +1 -1
- package/dist/tm/browser.d.ts.map +1 -1
- package/dist/tm/browser.js +41 -10
- package/dist/tm/browser.js.map +1 -1
- package/dist/tm/dispatch.d.ts +86 -1
- package/dist/tm/dispatch.d.ts.map +1 -1
- package/dist/tm/dispatch.js +360 -39
- package/dist/tm/dispatch.js.map +1 -1
- package/dist/tm/dupe-guard.d.ts +16 -3
- package/dist/tm/dupe-guard.d.ts.map +1 -1
- package/dist/tm/dupe-guard.js +27 -7
- package/dist/tm/dupe-guard.js.map +1 -1
- package/dist/tm/index.d.ts +40 -1
- package/dist/tm/index.d.ts.map +1 -1
- package/dist/tm/index.js +40 -11
- package/dist/tm/index.js.map +1 -1
- package/dist/tm/ledger.d.ts +114 -0
- package/dist/tm/ledger.d.ts.map +1 -0
- package/dist/tm/ledger.js +308 -0
- package/dist/tm/ledger.js.map +1 -0
- package/dist/tm/perm-ask.d.ts +1 -3
- package/dist/tm/perm-ask.d.ts.map +1 -1
- package/dist/tm/perm-ask.js +10 -1
- package/dist/tm/perm-ask.js.map +1 -1
- package/dist/tm/preview.d.ts +55 -0
- package/dist/tm/preview.d.ts.map +1 -1
- package/dist/tm/preview.js +225 -0
- package/dist/tm/preview.js.map +1 -1
- package/dist/tm/search.d.ts.map +1 -1
- package/dist/tm/search.js +40 -10
- package/dist/tm/search.js.map +1 -1
- package/dist/tm/serp-loop.d.ts +45 -0
- package/dist/tm/serp-loop.d.ts.map +1 -0
- package/dist/tm/serp-loop.js +80 -0
- package/dist/tm/serp-loop.js.map +1 -0
- package/dist/tm/stats.d.ts +29 -0
- package/dist/tm/stats.d.ts.map +1 -1
- package/dist/tm/stats.js +278 -4
- package/dist/tm/stats.js.map +1 -1
- package/dist/tm/webfetch.d.ts +4 -0
- package/dist/tm/webfetch.d.ts.map +1 -1
- package/dist/tm/webfetch.js +75 -8
- package/dist/tm/webfetch.js.map +1 -1
- package/docs/installation-v2.md +445 -0
- package/docs/installation.md +12 -0
- package/docs/research/agent-data-exchange.md +117 -0
- package/docs/research/browser-pane.md +89 -0
- package/docs/research/host-http-api.md +132 -0
- package/docs/research/host-subagent-injection.md +187 -0
- package/docs/research/plugin-loader-contract.md +261 -0
- package/docs/research/v2-builtin-tools.md +447 -0
- package/docs/v2-port-notes.md +413 -0
- package/index.js +7 -0
- package/package.json +64 -61
- package/scripts/gen-v2-config.mjs +304 -0
- package/scripts/lib/config-surgery.cjs +239 -0
- package/scripts/lib/fake-ctx.mjs +169 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { parseHostEnvelope } from "../task-offload.js";
|
|
4
|
+
const URLish = (s) => {
|
|
5
|
+
if (typeof s !== "string")
|
|
6
|
+
return false;
|
|
7
|
+
return /^https?:\/\//i.test(s.trim()) || /^\[[0-9a-f:.]+\]$/i.test(s.trim());
|
|
8
|
+
};
|
|
9
|
+
const keysOf = (v) => {
|
|
10
|
+
if (!v || typeof v !== "object" || Array.isArray(v))
|
|
11
|
+
return [];
|
|
12
|
+
return Object.keys(v).sort();
|
|
13
|
+
};
|
|
14
|
+
/** Any ctx domain whose `hook` is absent is reported rather than crashing boot. */
|
|
15
|
+
function hookFn(ctx, domain) {
|
|
16
|
+
const d = ctx?.[domain];
|
|
17
|
+
const h = d?.hook;
|
|
18
|
+
return typeof h === "function" ? h : null;
|
|
19
|
+
}
|
|
20
|
+
export async function applyV2Probe(ctx, opts = {}) {
|
|
21
|
+
const env = opts.env ?? process.env;
|
|
22
|
+
const file = typeof env.TM_V2_PROBE === "string" && env.TM_V2_PROBE.trim() ? env.TM_V2_PROBE.trim() : null;
|
|
23
|
+
const maxLines = Number.isFinite(Number(opts.maxLines)) && Number(opts.maxLines) > 0 ? Number(opts.maxLines) : 400;
|
|
24
|
+
const flushMs = Number.isFinite(Number(opts.flushMs)) && Number(opts.flushMs) >= 0 ? Number(opts.flushMs) : 20_000;
|
|
25
|
+
const report = {
|
|
26
|
+
agentsSeen: [],
|
|
27
|
+
toolNames: [],
|
|
28
|
+
executed: [],
|
|
29
|
+
executedAfter: [],
|
|
30
|
+
actions: [],
|
|
31
|
+
urlResources: 0,
|
|
32
|
+
evaluations: 0,
|
|
33
|
+
messages: 0,
|
|
34
|
+
taskEnvelopes: 0,
|
|
35
|
+
maxEnvelopeChars: 0,
|
|
36
|
+
messageShapes: [],
|
|
37
|
+
envelopeForms: new Set(),
|
|
38
|
+
hooksMissing: [],
|
|
39
|
+
ctxDomains: [],
|
|
40
|
+
probeTarget: file ? path.basename(file) : "",
|
|
41
|
+
lines: 0,
|
|
42
|
+
};
|
|
43
|
+
report.ctxDomains = Object.keys((ctx ?? {})).sort();
|
|
44
|
+
const seenToolNames = new Set();
|
|
45
|
+
const seenExecuted = new Set();
|
|
46
|
+
const seenExecutedAfter = new Set();
|
|
47
|
+
const seenActions = new Set();
|
|
48
|
+
const seenAgents = new Set();
|
|
49
|
+
const seenBeforeShapes = new Set();
|
|
50
|
+
const messageShapes = [];
|
|
51
|
+
const envelopeForms = report.envelopeForms;
|
|
52
|
+
const write = (rec) => {
|
|
53
|
+
if (!file || report.lines >= maxLines)
|
|
54
|
+
return;
|
|
55
|
+
report.lines += 1;
|
|
56
|
+
try {
|
|
57
|
+
fs.appendFileSync(file, `${JSON.stringify({ at: new Date().toISOString(), ...rec })}\n`);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
/* a probe that cannot write stays silent; it must never break a tool call */
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
let lastFlush = 0;
|
|
64
|
+
let lastSummary = "";
|
|
65
|
+
// Declared BEFORE any hook is registered: the host can fire a context hook while
|
|
66
|
+
// this function is still awaiting its own registrations, and a callback landing
|
|
67
|
+
// in the temporal dead zone would throw inside somebody's model request.
|
|
68
|
+
const flush = (force = false) => {
|
|
69
|
+
if (!opts.onSummary)
|
|
70
|
+
return;
|
|
71
|
+
const now = Date.now();
|
|
72
|
+
if (!force && now - lastFlush < flushMs)
|
|
73
|
+
return;
|
|
74
|
+
const summary = probeSummary(report);
|
|
75
|
+
const flat = JSON.stringify(summary);
|
|
76
|
+
// An idle session re-runs the context hook on every request; writing an
|
|
77
|
+
// identical line each time would be noise that buries the ones that differ.
|
|
78
|
+
if (!force && flat === lastSummary)
|
|
79
|
+
return;
|
|
80
|
+
lastFlush = now;
|
|
81
|
+
lastSummary = flat;
|
|
82
|
+
try {
|
|
83
|
+
opts.onSummary(summary);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
/* observability is an extra, never a reason to fail a request */
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const pending = [];
|
|
90
|
+
const registrations = [];
|
|
91
|
+
const arm = (domain, point, cb) => {
|
|
92
|
+
const hook = hookFn(ctx, domain);
|
|
93
|
+
if (!hook) {
|
|
94
|
+
report.hooksMissing.push(`${domain}.${point}`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
// The host's convention is `ctx.session.hook("context", …)` — the POINT name,
|
|
98
|
+
// not "session.context". Passing the dotted form would register a hook under a
|
|
99
|
+
// name nothing fires, and the probe would report an empty surface as if the host
|
|
100
|
+
// had none. The label keeps the domain so a missing seam reads unambiguously.
|
|
101
|
+
// The body is wrapped so a defect HERE can never surface as a failed tool call
|
|
102
|
+
// or a broken model request: an observer that can break the thing it observes is
|
|
103
|
+
// not an observer. (This was not theoretical — a callback referencing a `const`
|
|
104
|
+
// declared further down the module hit its temporal dead zone while the host was
|
|
105
|
+
// mid-hook, which is exactly how the shape recorder reported nothing.)
|
|
106
|
+
const guarded = (event) => {
|
|
107
|
+
try {
|
|
108
|
+
cb(event);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
const tag = `${domain}.${point}`;
|
|
112
|
+
if (!report.hooksMissing.includes(`${tag}:callback-threw`))
|
|
113
|
+
report.hooksMissing.push(`${tag}:callback-threw`);
|
|
114
|
+
void err;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
try {
|
|
118
|
+
pending.push(Promise.resolve(hook(point, guarded)));
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
report.hooksMissing.push(`${domain}.${point}:${String(err?.message ?? err).slice(0, 60)}`);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
arm("session", "context", (raw) => {
|
|
125
|
+
const event = raw;
|
|
126
|
+
const names = Object.keys(event?.tools ?? {});
|
|
127
|
+
const msgs = Array.isArray(event.messages) ? event.messages : [];
|
|
128
|
+
report.messages = Math.max(report.messages, msgs.length);
|
|
129
|
+
// The KEY NAMES of what a message actually is — recorded because guessing the
|
|
130
|
+
// shape is what made the v1 envelope matcher quietly dead: the probe reported
|
|
131
|
+
// "0 envelopes" and the honest reading was "I do not know where this lands",
|
|
132
|
+
// not "nothing lands". Names only, never content.
|
|
133
|
+
if (msgs.length && !messageShapes.length) {
|
|
134
|
+
for (const m of msgs.slice(0, 3)) {
|
|
135
|
+
const keys = keysOf(m);
|
|
136
|
+
const nested = {};
|
|
137
|
+
for (const k of keys) {
|
|
138
|
+
const v = m[k];
|
|
139
|
+
if (v && typeof v === "object")
|
|
140
|
+
nested[k] = Array.isArray(v) ? [`array(${v.length})`] : keysOf(v).slice(0, 8);
|
|
141
|
+
}
|
|
142
|
+
messageShapes.push({ keys, nested });
|
|
143
|
+
}
|
|
144
|
+
report.messageShapes = messageShapes;
|
|
145
|
+
write({ where: "message-shape", shapes: messageShapes });
|
|
146
|
+
}
|
|
147
|
+
// Shape only: a boolean "this looks like the host's envelope" and a character
|
|
148
|
+
// count. Nothing of the body is kept, hashed or written.
|
|
149
|
+
for (const m of msgs) {
|
|
150
|
+
// Read the TEXT of each part. JSON.stringify was wrong twice over: escaping
|
|
151
|
+
// the quotes means an envelope inside a part never matches its own parser (so
|
|
152
|
+
// this counter reported 0 on a host that was emitting them), and it would have
|
|
153
|
+
// serialized fields nobody should have in a probe file.
|
|
154
|
+
const texts = [];
|
|
155
|
+
if (typeof m === "string")
|
|
156
|
+
texts.push(m);
|
|
157
|
+
else {
|
|
158
|
+
const parts = m?.parts;
|
|
159
|
+
if (Array.isArray(parts)) {
|
|
160
|
+
for (const pt of parts) {
|
|
161
|
+
if (typeof pt?.text === "string")
|
|
162
|
+
texts.push(pt.text);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else if (typeof m?.text === "string")
|
|
166
|
+
texts.push(m.text);
|
|
167
|
+
}
|
|
168
|
+
// Asked of the same parser the offload uses — a probe that greps for the v1
|
|
169
|
+
// string while the host emits another reports "0 envelopes" forever, and a
|
|
170
|
+
// zero like that is indistinguishable from "nothing was big enough".
|
|
171
|
+
for (const text of texts) {
|
|
172
|
+
const env = parseHostEnvelope(text);
|
|
173
|
+
if (!env)
|
|
174
|
+
continue;
|
|
175
|
+
report.taskEnvelopes += 1;
|
|
176
|
+
report.maxEnvelopeChars = Math.max(report.maxEnvelopeChars, text.length);
|
|
177
|
+
report.envelopeForms.add(env.form);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
for (const n of names)
|
|
181
|
+
seenToolNames.add(n);
|
|
182
|
+
const agent = String(event?.agent ?? "?");
|
|
183
|
+
if (!seenAgents.has(agent)) {
|
|
184
|
+
seenAgents.add(agent);
|
|
185
|
+
report.agentsSeen = [...seenAgents].sort();
|
|
186
|
+
write({ where: "context", agent, toolCount: names.length, tools: names.slice().sort() });
|
|
187
|
+
}
|
|
188
|
+
report.toolNames = [...seenToolNames].sort();
|
|
189
|
+
flush(false);
|
|
190
|
+
});
|
|
191
|
+
arm("tool", "execute.before", (raw) => {
|
|
192
|
+
const event = raw;
|
|
193
|
+
const id = String(event?.tool ?? "?");
|
|
194
|
+
if (!seenExecuted.has(id)) {
|
|
195
|
+
seenExecuted.add(id);
|
|
196
|
+
report.executed = [...seenExecuted].sort();
|
|
197
|
+
write({ where: "execute.before", tool: id, inputKeys: keysOf(event?.input) });
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
// A tool already on record still tells us something new when its argument
|
|
201
|
+
// table differs — the native browser namespace is the open question here, and
|
|
202
|
+
// one line per distinct argument shape is what answers it.
|
|
203
|
+
const shape = keysOf(event?.input).join(",");
|
|
204
|
+
if (id.includes("browser") && !seenBeforeShapes.has(`${id}(${shape})`)) {
|
|
205
|
+
seenBeforeShapes.add(`${id}(${shape})`);
|
|
206
|
+
write({ where: "execute.before.input", tool: id, inputKeys: keysOf(event?.input) });
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
arm("tool", "execute.after", (raw) => {
|
|
210
|
+
const event = raw;
|
|
211
|
+
const id = String(event?.tool ?? "?");
|
|
212
|
+
if (!seenExecutedAfter.has(id)) {
|
|
213
|
+
seenExecutedAfter.add(id);
|
|
214
|
+
report.executedAfter = [...seenExecutedAfter].sort();
|
|
215
|
+
write({ where: "execute.after", tool: id, resultKeys: keysOf(event?.result) });
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
arm("permission", "evaluate", (raw) => {
|
|
219
|
+
const event = raw;
|
|
220
|
+
report.evaluations += 1;
|
|
221
|
+
const action = String(event?.action ?? "?");
|
|
222
|
+
const resources = Array.isArray(event?.resources) ? event.resources : [];
|
|
223
|
+
const hasUrl = resources.some(URLish);
|
|
224
|
+
if (hasUrl)
|
|
225
|
+
report.urlResources += 1;
|
|
226
|
+
if (seenActions.has(action))
|
|
227
|
+
return;
|
|
228
|
+
seenActions.add(action);
|
|
229
|
+
report.actions = [...seenActions].sort();
|
|
230
|
+
write({ where: "permission.evaluate", action, resourceCount: resources.length, hasUrl });
|
|
231
|
+
});
|
|
232
|
+
// A registration that rejects is a host fact worth recording — silently dropping
|
|
233
|
+
// it would leave the probe reporting "no browser tools" when the real reason is
|
|
234
|
+
// that the hook never attached.
|
|
235
|
+
const settled = await Promise.allSettled(pending);
|
|
236
|
+
settled.forEach((r, i) => {
|
|
237
|
+
if (r.status === "fulfilled" && r.value && typeof r.value.dispose === "function")
|
|
238
|
+
registrations.push(r.value);
|
|
239
|
+
else if (r.status === "rejected")
|
|
240
|
+
report.hooksMissing.push(`#${i}:${String(r.reason?.message ?? r.reason).slice(0, 60)}`);
|
|
241
|
+
});
|
|
242
|
+
flush(true);
|
|
243
|
+
return { enabled: Boolean(file), report, registrations, flush };
|
|
244
|
+
}
|
|
245
|
+
/** Compact form for the trajectory — names are safe, values never are. */
|
|
246
|
+
export function probeSummary(report) {
|
|
247
|
+
const browserTools = report.toolNames.filter((n) => n.toLowerCase().includes("browser"));
|
|
248
|
+
return {
|
|
249
|
+
probe_agents: report.agentsSeen.join(" "),
|
|
250
|
+
probe_tool_count: report.toolNames.length,
|
|
251
|
+
probe_browser_tools: browserTools.join(" "),
|
|
252
|
+
probe_executed: report.executed.join(" "),
|
|
253
|
+
probe_executed_after: report.executedAfter.join(" "),
|
|
254
|
+
probe_actions: report.actions.join(" "),
|
|
255
|
+
probe_evaluations: report.evaluations,
|
|
256
|
+
probe_messages: report.messages,
|
|
257
|
+
probe_task_envelopes: report.taskEnvelopes,
|
|
258
|
+
probe_max_envelope_chars: report.maxEnvelopeChars,
|
|
259
|
+
probe_message_shapes: JSON.stringify(report.messageShapes).slice(0, 500),
|
|
260
|
+
probe_envelope_forms: [...report.envelopeForms].join(" "),
|
|
261
|
+
probe_url_resources: report.urlResources,
|
|
262
|
+
probe_hooks_missing: report.hooksMissing.join(" "),
|
|
263
|
+
probe_ctx_domains: report.ctxDomains.join(" "),
|
|
264
|
+
probe_lines: report.lines,
|
|
265
|
+
probe_target: report.probeTarget,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=v2-probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2-probe.js","sourceRoot":"","sources":["../../src/host/v2-probe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team-scope isolation for the v2 personality (#22, user requirement 2026-09-25).
|
|
3
|
+
*
|
|
4
|
+
* "Everything the plugin changes must stay inside Team mode; the other modes
|
|
5
|
+
* (build, plan, anything the user installed) must look exactly like a freshly
|
|
6
|
+
* installed OpenCode." Every v2 hook we register is GLOBAL — `execute.after`,
|
|
7
|
+
* `permission.evaluate`, `session.context` fire for every session on the host, not
|
|
8
|
+
* only for ours. Without one shared answer to "is this ours?", the plugin would
|
|
9
|
+
* · delete tools from a build agent's request,
|
|
10
|
+
* · set `temperature` on somebody else's model call,
|
|
11
|
+
* · offload a stranger's tool result into OUR run store,
|
|
12
|
+
* · force `background: true` on a dispatch the user made on purpose,
|
|
13
|
+
* · and tighten a permission the user's own config already decided.
|
|
14
|
+
*
|
|
15
|
+
* The answer is deliberately three-valued, and the third value is the one that
|
|
16
|
+
* needs explaining. `unknown` means the host did not tell us which agent this is
|
|
17
|
+
* (the field is optional in the shape we were handed). We then treat the call as
|
|
18
|
+
* NOT ours — requirement first, coverage second — but we COUNT it, because
|
|
19
|
+
* "governance is live" and "governance silently stopped applying because a field
|
|
20
|
+
* went missing in a host upgrade" are two different facts, and the second one has
|
|
21
|
+
* to be readable from `tm_stats` rather than inferred from a bad feeling.
|
|
22
|
+
*
|
|
23
|
+
* A session can also become known from the inside: every call to one of OUR tools
|
|
24
|
+
* carries a session id and an agent in its own context, so `learn()` records that
|
|
25
|
+
* pair and a later `execute.after` for the same session resolves even if the host
|
|
26
|
+
* left `agent` off that event.
|
|
27
|
+
*/
|
|
28
|
+
export type ScopeVerdict = "ours" | "foreign" | "unknown";
|
|
29
|
+
export interface V2ScopeReport {
|
|
30
|
+
/** calls that belong to a Team role — the ones we are allowed to touch */
|
|
31
|
+
ours: number;
|
|
32
|
+
/** calls we identified as somebody else's and left completely alone */
|
|
33
|
+
foreign: number;
|
|
34
|
+
/** calls where the host gave us no agent at all — skipped, and the number that
|
|
35
|
+
* tells whether the governance layers are actually live */
|
|
36
|
+
unknown: number;
|
|
37
|
+
}
|
|
38
|
+
export interface TeamScope {
|
|
39
|
+
readonly names: ReadonlySet<string>;
|
|
40
|
+
isOurs(agent: unknown): boolean;
|
|
41
|
+
decide(event: {
|
|
42
|
+
agent?: unknown;
|
|
43
|
+
sessionID?: unknown;
|
|
44
|
+
} | null | undefined): ScopeVerdict;
|
|
45
|
+
learn(agent: unknown, sessionID: unknown): void;
|
|
46
|
+
readonly report: V2ScopeReport;
|
|
47
|
+
/** counted at each call site, so a layer that never fires cannot look healthy */
|
|
48
|
+
count(verdict: ScopeVerdict): ScopeVerdict;
|
|
49
|
+
}
|
|
50
|
+
export declare function createTeamScope(names: Iterable<string>): TeamScope;
|
|
51
|
+
//# sourceMappingURL=v2-scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2-scope.d.ts","sourceRoot":"","sources":["../../src/host/v2-scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAA;AAEzD,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAA;IACZ,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAA;IACf;gEAC4D;IAC5D,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACnC,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAA;IAC/B,MAAM,CAAC,KAAK,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,GAAG,SAAS,GAAG,YAAY,CAAA;IACxF,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,IAAI,CAAA;IAC/C,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;IAC9B,iFAAiF;IACjF,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY,CAAA;CAC3C;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,SAAS,CAyBlE"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team-scope isolation for the v2 personality (#22, user requirement 2026-09-25).
|
|
3
|
+
*
|
|
4
|
+
* "Everything the plugin changes must stay inside Team mode; the other modes
|
|
5
|
+
* (build, plan, anything the user installed) must look exactly like a freshly
|
|
6
|
+
* installed OpenCode." Every v2 hook we register is GLOBAL — `execute.after`,
|
|
7
|
+
* `permission.evaluate`, `session.context` fire for every session on the host, not
|
|
8
|
+
* only for ours. Without one shared answer to "is this ours?", the plugin would
|
|
9
|
+
* · delete tools from a build agent's request,
|
|
10
|
+
* · set `temperature` on somebody else's model call,
|
|
11
|
+
* · offload a stranger's tool result into OUR run store,
|
|
12
|
+
* · force `background: true` on a dispatch the user made on purpose,
|
|
13
|
+
* · and tighten a permission the user's own config already decided.
|
|
14
|
+
*
|
|
15
|
+
* The answer is deliberately three-valued, and the third value is the one that
|
|
16
|
+
* needs explaining. `unknown` means the host did not tell us which agent this is
|
|
17
|
+
* (the field is optional in the shape we were handed). We then treat the call as
|
|
18
|
+
* NOT ours — requirement first, coverage second — but we COUNT it, because
|
|
19
|
+
* "governance is live" and "governance silently stopped applying because a field
|
|
20
|
+
* went missing in a host upgrade" are two different facts, and the second one has
|
|
21
|
+
* to be readable from `tm_stats` rather than inferred from a bad feeling.
|
|
22
|
+
*
|
|
23
|
+
* A session can also become known from the inside: every call to one of OUR tools
|
|
24
|
+
* carries a session id and an agent in its own context, so `learn()` records that
|
|
25
|
+
* pair and a later `execute.after` for the same session resolves even if the host
|
|
26
|
+
* left `agent` off that event.
|
|
27
|
+
*/
|
|
28
|
+
export function createTeamScope(names) {
|
|
29
|
+
const set = new Set([...names].map(String));
|
|
30
|
+
const bySession = new Map();
|
|
31
|
+
const report = { ours: 0, foreign: 0, unknown: 0 };
|
|
32
|
+
const scope = {
|
|
33
|
+
names: set,
|
|
34
|
+
isOurs: (agent) => typeof agent === "string" && set.has(agent),
|
|
35
|
+
learn(agent, sessionID) {
|
|
36
|
+
if (typeof sessionID !== "string" || !sessionID)
|
|
37
|
+
return;
|
|
38
|
+
if (typeof agent === "string" && set.has(agent))
|
|
39
|
+
bySession.set(sessionID, agent);
|
|
40
|
+
},
|
|
41
|
+
decide(event) {
|
|
42
|
+
const agent = event?.agent;
|
|
43
|
+
if (typeof agent === "string" && agent)
|
|
44
|
+
return set.has(agent) ? "ours" : "foreign";
|
|
45
|
+
const sid = event?.sessionID;
|
|
46
|
+
if (typeof sid === "string" && bySession.has(sid))
|
|
47
|
+
return "ours";
|
|
48
|
+
return "unknown";
|
|
49
|
+
},
|
|
50
|
+
count(verdict) {
|
|
51
|
+
report[verdict]++;
|
|
52
|
+
return verdict;
|
|
53
|
+
},
|
|
54
|
+
report,
|
|
55
|
+
};
|
|
56
|
+
return scope;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=v2-scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2-scope.js","sourceRoot":"","sources":["../../src/host/v2-scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAwBH,MAAM,UAAU,eAAe,CAAC,KAAuB;IACrD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;IAC3C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAA;IAC3C,MAAM,MAAM,GAAkB,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;IACjE,MAAM,KAAK,GAAc;QACvB,KAAK,EAAE,GAAG;QACV,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC;QAC9D,KAAK,CAAC,KAAK,EAAE,SAAS;YACpB,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,SAAS;gBAAE,OAAM;YACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;QAClF,CAAC;QACD,MAAM,CAAC,KAAK;YACV,MAAM,KAAK,GAAG,KAAK,EAAE,KAAK,CAAA;YAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK;gBAAE,OAAO,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;YAClF,MAAM,GAAG,GAAG,KAAK,EAAE,SAAS,CAAA;YAC5B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,OAAO,MAAM,CAAA;YAChE,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,KAAK,CAAC,OAAO;YACX,MAAM,CAAC,OAAO,CAAC,EAAE,CAAA;YACjB,OAAO,OAAO,CAAA;QAChB,CAAC;QACD,MAAM;KACP,CAAA;IACD,OAAO,KAAK,CAAA;AACd,CAAC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The v2 session read seam, shaped like the v1 client the collect path expects (#8).
|
|
3
|
+
*
|
|
4
|
+
* `tm_join` collects a child in two ways: it looks the child up in its own registry
|
|
5
|
+
* (children THIS plugin process created — and since `babfcb8` also the host's `subagent`
|
|
6
|
+
* children), and otherwise it asks the host. That ask was written against v1's SDK client
|
|
7
|
+
* (`client.session.get({path:{id}})`), and on a live host it never once resolved.
|
|
8
|
+
*
|
|
9
|
+
* Why it failed, read out of 2.0.18 rather than guessed (both quotes are from the embedded
|
|
10
|
+
* JS): the plugin-facing wrapper is a schema decode plus a single-object call —
|
|
11
|
+
*
|
|
12
|
+
* te = (schema, fn) => (input) => decode(schema, input ?? {}) → fn(decoded)
|
|
13
|
+
* get: te(N["session.get"], a.session.get)
|
|
14
|
+
*
|
|
15
|
+
* and the host's own call sites are flat:
|
|
16
|
+
*
|
|
17
|
+
* await e.session.get({ sessionID: n })
|
|
18
|
+
* await e.message.list({ sessionID: n, limit: 200, cursor: r })
|
|
19
|
+
*
|
|
20
|
+
* So our adapter had TWO bugs: the key (`path.id` / `id` instead of `sessionID`) and the
|
|
21
|
+
* arity (every shape was passed as a one-element ARRAY, which no `te`-wrapped method
|
|
22
|
+
* accepts). A decode failure looks exactly like "the host has no such method", which is
|
|
23
|
+
* how this stayed wrong for a whole release cycle.
|
|
24
|
+
*
|
|
25
|
+
* What this surface does NOT give, stated rather than discovered later:
|
|
26
|
+
* · no `children` method, so adoption from the host's session tree is still impossible on
|
|
27
|
+
* v2 — only an explicitly named id can be claimed, which is what the lead's prompt says.
|
|
28
|
+
* · no `message`/`messages` domain on the plugin ctx (the host's internal `message.list`
|
|
29
|
+
* is the SDK client, not this surface). `context` is the only candidate that could
|
|
30
|
+
* carry a child's reply, so it is tried, and its outcome — including the NAMES of the
|
|
31
|
+
* keys it returned — is recorded. Key names are safe; a message body is not written to
|
|
32
|
+
* the trajectory by this file.
|
|
33
|
+
* · the HTTP API does expose `GET /api/session/{id}/message` (136 distinct routes were
|
|
34
|
+
* enumerated from a scanned window of the binary, and none of them is a todo list —
|
|
35
|
+
* which settles the `tm_ledger` question: there is no host todo resource to read), but
|
|
36
|
+
* reaching it needs the basic-auth password from
|
|
37
|
+
* `~/.config/opencode/service.json`. A plugin reading the user's credential file to
|
|
38
|
+
* call back into the host is a new trust boundary, so it is NOT done here; it is
|
|
39
|
+
* recorded as the option with its cost attached. See
|
|
40
|
+
* `docs/research/host-http-api.md`.
|
|
41
|
+
*/
|
|
42
|
+
export interface V2SessionReaderReport {
|
|
43
|
+
/** calls made through this adapter */
|
|
44
|
+
attempted: number;
|
|
45
|
+
/** calls that produced an object with a parent id */
|
|
46
|
+
resolved: number;
|
|
47
|
+
/** which argument shape the host answered — `sessionID` is the measured one */
|
|
48
|
+
usedShape?: string;
|
|
49
|
+
/** last error text, unwrapped from the host's own error envelope */
|
|
50
|
+
lastError?: string;
|
|
51
|
+
/** shapes tried and failed on the last call */
|
|
52
|
+
failedShapes: string[];
|
|
53
|
+
/** `ctx.session.context` was reached at all */
|
|
54
|
+
contextTried: number;
|
|
55
|
+
contextOk: number;
|
|
56
|
+
contextError?: string;
|
|
57
|
+
/** the KEY NAMES the context call returned (names only, never values) */
|
|
58
|
+
contextKeys: string[];
|
|
59
|
+
/** `ctx.session.interrupt` calls made by `tm_join { cancel: true }` (#33) */
|
|
60
|
+
interruptTried: number;
|
|
61
|
+
/** the host confirmed an active execution was interrupted (`interrupted: true`) */
|
|
62
|
+
interruptConfirmed: number;
|
|
63
|
+
/** the host answered `interrupted: false` — the documented idle no-op, i.e. NOT a stop */
|
|
64
|
+
interruptRefused: number;
|
|
65
|
+
/** the call succeeded and carried no `interrupted` boolean at all */
|
|
66
|
+
interruptUnknown: number;
|
|
67
|
+
interruptError?: string;
|
|
68
|
+
/** the KEY NAMES the interrupt call returned (names only, never values) */
|
|
69
|
+
interruptKeys: string[];
|
|
70
|
+
/** the SHAPE of the last list the seam answered with — names and counts only, and the
|
|
71
|
+
* reason a `child_body_missing` row can be checked later (`contextShapeEvidence`). */
|
|
72
|
+
contextShape?: string;
|
|
73
|
+
}
|
|
74
|
+
export interface V2SessionReader {
|
|
75
|
+
/** a `{session:{get,messages}}` object safe to hand to code written for the v1 client */
|
|
76
|
+
client: unknown;
|
|
77
|
+
report: V2SessionReaderReport;
|
|
78
|
+
}
|
|
79
|
+
/** Turn the host's context items into the `{info,parts}` shape the collect path already
|
|
80
|
+
* understands — HERE, at the seam that knows the shape, so nothing downstream has to guess.
|
|
81
|
+
* Three shapes are in the wild and all three are measurements, not version numbers:
|
|
82
|
+
* · 2.0.18 `[L]`: a FLAT item per message, `{id, time:{created}, text, type}`.
|
|
83
|
+
* · 2.0.20 `[L][D]`: a MESSAGE whose body is `content: (Text|Reasoning|Tool)[]` and whose
|
|
84
|
+
* kind is on `role` — the name-level probe recorded `{keys:["content","id","metadata",
|
|
85
|
+
* "role"]}`. The previous version of this function passed that item through untouched
|
|
86
|
+
* ("already message-shaped"), `lastAssistantMessage` found no `parts` and no `text` on
|
|
87
|
+
* it, and the seam answered while the body was dropped AGAIN — which is why 正文来源=
|
|
88
|
+
* never printed on 2.0.20 (A1).
|
|
89
|
+
* · v1's `[{info,parts[]}]`: passed through untouched, so a host that changes back needs
|
|
90
|
+
* no change here.
|
|
91
|
+
* Only the bag is renamed and the envelope added: the elements are already v1 part shapes
|
|
92
|
+
* (`{type:"text", text}`), and reasoning/tool parts stay exactly as the host wrote them.
|
|
93
|
+
* An empty `content` normalises to empty parts — this function MOVES text, it never
|
|
94
|
+
* manufactures any. */
|
|
95
|
+
export declare function normaliseContextMessages(list: unknown): unknown;
|
|
96
|
+
/** WHY a body came back empty, in names and counts only — never a value, a path, or a
|
|
97
|
+
* snippet of text (the R6 口径 binds a diagnostic). tm_join writes this onto the
|
|
98
|
+
* `child_body_missing` trajectory line so the three conclusions stay distinguishable:
|
|
99
|
+
* a real body (`child_body`), a seam that answered with nothing readable in it
|
|
100
|
+
* (`items=2 keys=[content+id+metadata+role] content=1 kinds=[tool] text=0`), and a seam
|
|
101
|
+
* that did not answer at all (`no-context-method`). Without it, "we read it" and "we could
|
|
102
|
+
* not read it" print the same row — goal #6's failure shape. */
|
|
103
|
+
export declare function contextShapeEvidence(list: unknown): string;
|
|
104
|
+
export declare function createV2SessionReader(ctx: unknown): V2SessionReader;
|
|
105
|
+
//# sourceMappingURL=v2-session-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2-session-client.d.ts","sourceRoot":"","sources":["../../src/host/v2-session-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAA;IACjB,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAA;IAChB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,+CAA+C;IAC/C,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,+CAA+C;IAC/C,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,yEAAyE;IACzE,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,6EAA6E;IAC7E,cAAc,EAAE,MAAM,CAAA;IACtB,mFAAmF;IACnF,kBAAkB,EAAE,MAAM,CAAA;IAC1B,0FAA0F;IAC1F,gBAAgB,EAAE,MAAM,CAAA;IACxB,qEAAqE;IACrE,gBAAgB,EAAE,MAAM,CAAA;IACxB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,2EAA2E;IAC3E,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB;2FACuF;IACvF,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,yFAAyF;IACzF,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,qBAAqB,CAAA;CAC9B;AAuGD;;;;;;;;;;;;;;;wBAewB;AACxB,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CA2B/D;AAED;;;;;;iEAMiE;AACjE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAyB1D;AAMD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,eAAe,CA4JnE"}
|