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

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 +28 -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 +68 -0
  16. package/dist/host/v2-capabilities.d.ts.map +1 -0
  17. package/dist/host/v2-capabilities.js +146 -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 +74 -0
  48. package/dist/host/v2-session-client.d.ts.map +1 -0
  49. package/dist/host/v2-session-client.js +171 -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 +706 -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 +452 -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 +30 -10
  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 +47 -0
  99. package/dist/tm/dispatch.d.ts.map +1 -1
  100. package/dist/tm/dispatch.js +230 -31
  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 +10 -0
  130. package/dist/tm/stats.d.ts.map +1 -1
  131. package/dist/tm/stats.js +160 -0
  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 +436 -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 +315 -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 +146 -0
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Reading a CHILD session's own messages — in process, with no credential.
3
+ *
4
+ * This is the answer to the HTTP-API decision (task #32). The host's own API
5
+ * (`docs/research/host-http-api.md`) does expose `GET /api/session/{id}/message`, and using
6
+ * it would have meant reading the Basic-auth password out of
7
+ * `<global-config>/service.json` — a secret that would then live in this plugin's memory,
8
+ * in every error string the fetch layer can produce, and in any log line that quotes a
9
+ * request. The user's condition for going there was "prove it cannot leak".
10
+ *
11
+ * Measured instead, on a live 2.0.18 with a plugin that only inspects its own ctx (zero
12
+ * model tokens, `--model nope/nope`): the plugin ctx carries a full `session` domain —
13
+ *
14
+ * hook create get switchAgent switchModel prompt generate command synthetic interrupt
15
+ * update move wait context
16
+ *
17
+ * and `ctx.session.context({ sessionID })` returns the session's message array. On the child
18
+ * session of a real background dispatch that array had 5 items shaped
19
+ * `{id, time:{created}, text, type}`. `ctx.session.get({sessionID})` returns
20
+ * `{id, parentID, projectID, agent, model, outcome, tokens, title, location}`.
21
+ *
22
+ * So the capability was in front of us the whole time and the password was never needed:
23
+ * nothing here opens a socket, reads a credential file, or can be redirected to a port that
24
+ * is not our own host process. That is a stronger guarantee than "we will keep the secret
25
+ * safe" — there is no secret.
26
+ *
27
+ * The one thing this MUST still earn is scope. `session.context` will answer for ANY session
28
+ * id handed to it, including the user's unrelated `build`/`plan` sessions, which makes it a
29
+ * private-content oracle if used carelessly. Therefore: parentage is verified with
30
+ * `session.get` FIRST, and a session that is not the caller's own child is refused without
31
+ * being read. The refusal is counted (`refused`) so "we did not look" stays distinguishable
32
+ * from "we looked and were denied". Text bodies are never written to the trajectory — ids,
33
+ * item counts and the chosen message's TYPE only, per R6.
34
+ */
35
+ export interface V2TranscriptReport {
36
+ /** read() calls made */
37
+ attempted: number;
38
+ /** calls that returned a non-empty body */
39
+ resolved: number;
40
+ /** calls refused because session.get said the child is not the caller's */
41
+ refused: number;
42
+ /** calls where the parentage check itself could not answer (no seam, host error) */
43
+ unverifiable: number;
44
+ lastError?: string;
45
+ }
46
+ export interface V2TranscriptResult {
47
+ text: string;
48
+ /** how many messages the host handed back */
49
+ items: number;
50
+ /** the `type` of the message the body was taken from, when it had one */
51
+ pickedType?: string;
52
+ /** why there is no body — names the seam that failed, never a guess */
53
+ error?: string;
54
+ }
55
+ export interface V2TranscriptReader {
56
+ read: (sessionID: string, callerSessionID: string) => Promise<V2TranscriptResult>;
57
+ report: V2TranscriptReport;
58
+ /** Whether this host gives the seam at all — the caller says so out loud when not. */
59
+ active: boolean;
60
+ }
61
+ /** The child's ANSWER is the last non-user message that carries text. Taking the last,
62
+ * rather than concatenating the transcript, is the whole point: the lead asked for the
63
+ * report, and the earlier turns are the work it does not want to pay tokens for. The type
64
+ * of the chosen item is returned so the reply can say where the text came from instead of
65
+ * implying it read the whole session. */
66
+ export declare function pickChildReply(items: unknown[]): {
67
+ text: string;
68
+ type?: string;
69
+ };
70
+ export declare function createV2TranscriptReader(ctx: unknown): V2TranscriptReader;
71
+ /** One line for tm_stats: what the reader was asked for and what it could say. */
72
+ export declare function transcriptSummary(r: V2TranscriptReport): string;
73
+ //# sourceMappingURL=v2-transcript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v2-transcript.d.ts","sourceRoot":"","sources":["../../src/host/v2-transcript.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,MAAM,WAAW,kBAAkB;IACjC,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAA;IAChB,2EAA2E;IAC3E,OAAO,EAAE,MAAM,CAAA;IACf,oFAAoF;IACpF,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACjF,MAAM,EAAE,kBAAkB,CAAA;IAC1B,sFAAsF;IACtF,MAAM,EAAE,OAAO,CAAA;CAChB;AAkCD;;;;0CAI0C;AAC1C,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAQhF;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,GAAG,kBAAkB,CA2DzE;AAED,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAO/D"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Reading a CHILD session's own messages — in process, with no credential.
3
+ *
4
+ * This is the answer to the HTTP-API decision (task #32). The host's own API
5
+ * (`docs/research/host-http-api.md`) does expose `GET /api/session/{id}/message`, and using
6
+ * it would have meant reading the Basic-auth password out of
7
+ * `<global-config>/service.json` — a secret that would then live in this plugin's memory,
8
+ * in every error string the fetch layer can produce, and in any log line that quotes a
9
+ * request. The user's condition for going there was "prove it cannot leak".
10
+ *
11
+ * Measured instead, on a live 2.0.18 with a plugin that only inspects its own ctx (zero
12
+ * model tokens, `--model nope/nope`): the plugin ctx carries a full `session` domain —
13
+ *
14
+ * hook create get switchAgent switchModel prompt generate command synthetic interrupt
15
+ * update move wait context
16
+ *
17
+ * and `ctx.session.context({ sessionID })` returns the session's message array. On the child
18
+ * session of a real background dispatch that array had 5 items shaped
19
+ * `{id, time:{created}, text, type}`. `ctx.session.get({sessionID})` returns
20
+ * `{id, parentID, projectID, agent, model, outcome, tokens, title, location}`.
21
+ *
22
+ * So the capability was in front of us the whole time and the password was never needed:
23
+ * nothing here opens a socket, reads a credential file, or can be redirected to a port that
24
+ * is not our own host process. That is a stronger guarantee than "we will keep the secret
25
+ * safe" — there is no secret.
26
+ *
27
+ * The one thing this MUST still earn is scope. `session.context` will answer for ANY session
28
+ * id handed to it, including the user's unrelated `build`/`plan` sessions, which makes it a
29
+ * private-content oracle if used carelessly. Therefore: parentage is verified with
30
+ * `session.get` FIRST, and a session that is not the caller's own child is refused without
31
+ * being read. The refusal is counted (`refused`) so "we did not look" stays distinguishable
32
+ * from "we looked and were denied". Text bodies are never written to the trajectory — ids,
33
+ * item counts and the chosen message's TYPE only, per R6.
34
+ */
35
+ /** Unwrap whatever envelope the host puts on a result object. */
36
+ function unwrap(raw) {
37
+ if (!raw || typeof raw !== "object")
38
+ return null;
39
+ const rec = raw;
40
+ for (const cand of [rec, rec.data, rec.result, rec.session]) {
41
+ if (cand && typeof cand === "object")
42
+ return cand;
43
+ }
44
+ return rec;
45
+ }
46
+ /** The text one message item carries, across the shapes the host has been seen to use:
47
+ * a bare `text` (measured on 2.0.18), `parts[]` (the persisted message shape), and
48
+ * `content[]` (the tool-result shape). Never descends into a tool payload. */
49
+ function itemText(raw) {
50
+ if (!raw || typeof raw !== "object")
51
+ return null;
52
+ const it = raw;
53
+ const type = String(it.type ?? it.role ?? "");
54
+ const direct = it.text;
55
+ if (typeof direct === "string" && direct.trim())
56
+ return { text: direct, type };
57
+ for (const key of ["parts", "content"]) {
58
+ const arr = it[key];
59
+ if (!Array.isArray(arr))
60
+ continue;
61
+ const texts = arr
62
+ .map((p) => (p && typeof p === "object" ? p.text : undefined))
63
+ .filter((t) => typeof t === "string" && t.trim().length > 0);
64
+ if (texts.length)
65
+ return { text: texts.join(String.fromCharCode(10)), type };
66
+ }
67
+ return null;
68
+ }
69
+ /** The child's ANSWER is the last non-user message that carries text. Taking the last,
70
+ * rather than concatenating the transcript, is the whole point: the lead asked for the
71
+ * report, and the earlier turns are the work it does not want to pay tokens for. The type
72
+ * of the chosen item is returned so the reply can say where the text came from instead of
73
+ * implying it read the whole session. */
74
+ export function pickChildReply(items) {
75
+ for (let i = items.length - 1; i >= 0; i--) {
76
+ const t = itemText(items[i]);
77
+ if (!t)
78
+ continue;
79
+ if (/^user$/i.test(t.type))
80
+ continue;
81
+ return { text: t.text, type: t.type || undefined };
82
+ }
83
+ return { text: "" };
84
+ }
85
+ export function createV2TranscriptReader(ctx) {
86
+ const report = { attempted: 0, resolved: 0, refused: 0, unverifiable: 0 };
87
+ const session = ctx?.session;
88
+ const getContext = session?.context;
89
+ const get = session?.get;
90
+ const active = typeof getContext === "function";
91
+ const call = async (fn, arg) => await fn.call(session, arg);
92
+ const read = async (sessionID, callerSessionID) => {
93
+ report.attempted++;
94
+ if (!active || typeof getContext !== "function") {
95
+ return { text: "", items: 0, error: "这个宿主没给 ctx.session.context" };
96
+ }
97
+ if (!sessionID || !callerSessionID)
98
+ return { text: "", items: 0, error: "缺少会话 id,无法核验归属" };
99
+ // Scope FIRST. A reader that takes whatever id it is handed is a private-content oracle,
100
+ // and "the user approved the API" does not extend to their unrelated sessions.
101
+ if (typeof get !== "function") {
102
+ report.unverifiable++;
103
+ return { text: "", items: 0, error: "宿主没给 ctx.session.get,无法核验子会话归属,因此没有读取正文" };
104
+ }
105
+ let parentID;
106
+ try {
107
+ const rec = unwrap(await call(get, { sessionID }));
108
+ const p = rec?.parentID ?? rec?.parent_id;
109
+ parentID = typeof p === "string" && p ? p : undefined;
110
+ }
111
+ catch (err) {
112
+ report.unverifiable++;
113
+ report.lastError = String(err?.message ?? err).slice(0, 160);
114
+ return { text: "", items: 0, error: `归属核验失败:${report.lastError ?? "宿主未回应"}` };
115
+ }
116
+ if (!parentID) {
117
+ report.unverifiable++;
118
+ return { text: "", items: 0, error: "宿主回答里没有 parentID,无法确认这个会话是你的子会话,因此没有读取正文" };
119
+ }
120
+ if (parentID !== callerSessionID) {
121
+ report.refused++;
122
+ return { text: "", items: 0, error: "这个会话不是你的子会话(宿主给的 parentID 不匹配),我没有读它" };
123
+ }
124
+ try {
125
+ const raw = await call(getContext, { sessionID });
126
+ const arr = Array.isArray(raw) ? raw : Array.isArray(raw?.data) ? raw.data : null;
127
+ if (!arr) {
128
+ report.lastError = "context 返回值不是数组";
129
+ return { text: "", items: 0, error: report.lastError };
130
+ }
131
+ const picked = pickChildReply(arr);
132
+ if (picked.text)
133
+ report.resolved++;
134
+ return { text: picked.text, items: arr.length, pickedType: picked.type };
135
+ }
136
+ catch (err) {
137
+ report.lastError = String(err?.message ?? err).slice(0, 160);
138
+ return { text: "", items: 0, error: `ctx.session.context 失败:${report.lastError}` };
139
+ }
140
+ };
141
+ return { read, report, active };
142
+ }
143
+ /** One line for tm_stats: what the reader was asked for and what it could say. */
144
+ export function transcriptSummary(r) {
145
+ if (!r.attempted)
146
+ return "子会话正文读取:没被调用过(缝在场,没数据)";
147
+ return (`子会话正文读取:尝试 ${r.attempted} · 拿到正文 ${r.resolved} · ` +
148
+ `归属不符拒绝 ${r.refused} · 无法核验 ${r.unverifiable}` +
149
+ (r.lastError ? ` · 最后错误:${r.lastError}` : ""));
150
+ }
151
+ //# sourceMappingURL=v2-transcript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v2-transcript.js","sourceRoot":"","sources":["../../src/host/v2-transcript.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Hand-written structural types for the OpenCode v2 plugin surface.
3
+ *
4
+ * We deliberately do NOT import `@opencode/plugin`: it is a separate package
5
+ * from the v1 SDK, and a v2 SDK that becomes a runtime dependency would break
6
+ * the dual-personality export for every v1 user who cannot resolve it. The
7
+ * shapes below cover only the members this plugin actually touches, and they
8
+ * are transcribed from `@opencode/plugin@2.0.16/dist/promise/*.d.ts` plus two
9
+ * live-host probes (2026-09-25) — the probe is what proves `hook()` returns a
10
+ * disposable registration and that `execute.before` can really deny.
11
+ *
12
+ * Kept intentionally loose (`unknown` where we only pass values through): a
13
+ * type that is wider than the host's never fails a build, and every field we
14
+ * READ is read defensively because the host makes no stability promise.
15
+ */
16
+ export interface V2Registration {
17
+ readonly dispose: () => Promise<void>;
18
+ }
19
+ /** `Hooks<Spec>` in the SDK: register by name, get a disposable back. */
20
+ export type V2Hooks<Spec> = <Name extends keyof Spec>(name: Name, callback: (input: Spec[Name]) => Promise<void> | void) => Promise<V2Registration>;
21
+ /** `Transform<Input>` in the SDK: mutate an in-memory editor. */
22
+ export type V2Transform<Input> = (callback: (input: Input) => void) => Promise<V2Registration>;
23
+ export interface V2TextContent {
24
+ type: "text";
25
+ text: string;
26
+ }
27
+ export interface V2FileContent {
28
+ type: "file";
29
+ uri: string;
30
+ mime: string;
31
+ name?: string;
32
+ }
33
+ export type V2Content = V2TextContent | V2FileContent;
34
+ /**
35
+ * `Tool.Result`. A live probe measured the host's own rejection of the v1
36
+ * shape: returning `{output: "<text>"}` with no declared `output` schema came
37
+ * back as "Tool result declared output without an output schema" for all three
38
+ * probe tools — so this plugin's v2 adapters return `content` instead.
39
+ */
40
+ export interface V2ToolResult {
41
+ content?: string | ReadonlyArray<V2Content>;
42
+ metadata?: Record<string, unknown>;
43
+ }
44
+ export interface V2ToolContext {
45
+ readonly sessionID: string;
46
+ readonly agent: string;
47
+ readonly messageID?: string;
48
+ readonly id?: string;
49
+ readonly signal?: AbortSignal;
50
+ readonly progress?: (update: unknown) => Promise<void>;
51
+ }
52
+ export interface V2ToolInfo {
53
+ readonly name: string;
54
+ readonly description: string;
55
+ /** A JSON Schema object; the host also accepts zod/StandardSchema. */
56
+ readonly input: unknown;
57
+ readonly execute: (args: Record<string, unknown>, context: V2ToolContext) => Promise<V2ToolResult>;
58
+ readonly options?: {
59
+ readonly namespace?: string;
60
+ readonly permission?: string;
61
+ /**
62
+ * Read from the 2.0.16 binary, NOT from the SDK types (which have no such
63
+ * word): host-built tools carry `options:{codemode:false}` and a tool whose
64
+ * codemode is not false is offered only through the Code Mode catalog, where
65
+ * its description is cut to the first line. This is why a live Team session
66
+ * showed six tools and zero `tm_*` even though registration succeeded.
67
+ */
68
+ readonly codemode?: boolean;
69
+ };
70
+ }
71
+ export interface V2ToolEditor {
72
+ list(): ReadonlyArray<V2ToolInfo & {
73
+ id?: string;
74
+ }>;
75
+ get(id: string): (V2ToolInfo & {
76
+ id?: string;
77
+ }) | undefined;
78
+ add(tool: V2ToolInfo): void;
79
+ update?(id: string, update: (tool: V2ToolInfo) => void): void;
80
+ remove?(id: string): void;
81
+ namespace?(namespace: unknown): void;
82
+ }
83
+ export interface V2ToolExecuteBefore {
84
+ readonly tool: string;
85
+ readonly sessionID: string;
86
+ readonly agent?: string;
87
+ input: unknown;
88
+ }
89
+ export interface V2ToolExecuteAfter {
90
+ readonly tool: string;
91
+ readonly sessionID: string;
92
+ readonly agent?: string;
93
+ readonly status: "completed" | "error";
94
+ readonly result?: unknown;
95
+ readonly error?: unknown;
96
+ }
97
+ export interface V2ToolHooks {
98
+ readonly "execute.before": V2ToolExecuteBefore;
99
+ readonly "execute.after": V2ToolExecuteAfter;
100
+ }
101
+ export interface V2ToolDomain {
102
+ readonly transform: V2Transform<V2ToolEditor>;
103
+ readonly list: () => Promise<ReadonlyArray<V2ToolInfo & {
104
+ id?: string;
105
+ }>>;
106
+ readonly hook: V2Hooks<V2ToolHooks>;
107
+ readonly reload?: () => Promise<void>;
108
+ }
109
+ export interface V2PermissionRule {
110
+ readonly action: string;
111
+ readonly resource: string;
112
+ readonly effect: "allow" | "deny" | "ask";
113
+ }
114
+ export interface V2AgentInfo {
115
+ id?: string;
116
+ name?: string;
117
+ description?: string;
118
+ /** v2's spelling of v1's `prompt`. */
119
+ system?: string;
120
+ mode?: "subagent" | "primary" | "all";
121
+ hidden?: boolean;
122
+ color?: string;
123
+ permissions?: V2PermissionRule[];
124
+ [key: string]: unknown;
125
+ }
126
+ export interface V2AgentEditor {
127
+ list(): ReadonlyArray<V2AgentInfo>;
128
+ get(id: string): V2AgentInfo | undefined;
129
+ default(id: string | undefined): void;
130
+ update(id: string, update: (agent: V2AgentInfo) => void): void;
131
+ remove(id: string): void;
132
+ }
133
+ export interface V2AgentDomain {
134
+ readonly transform: V2Transform<V2AgentEditor>;
135
+ readonly list?: () => Promise<ReadonlyArray<V2AgentInfo>>;
136
+ }
137
+ /**
138
+ * `PermissionEvaluation` — `effect` is the mutable decision. A live probe saw
139
+ * the host itself produce `effect:"ask"` (for an out-of-workspace
140
+ * `external_directory` read) and publish `permission.asked` afterwards, so an
141
+ * `ask` written here is honored by a real dialog. Observed `action` values:
142
+ * `shell` / `read` / `edit` / `external_directory`, with `resources` carrying
143
+ * the concrete command line or path.
144
+ */
145
+ export interface V2PermissionEvaluation {
146
+ readonly sessionID: string;
147
+ readonly agent?: string;
148
+ readonly action: string;
149
+ readonly resources: ReadonlyArray<string>;
150
+ readonly metadata?: Record<string, unknown>;
151
+ effect: "allow" | "deny" | "ask";
152
+ message?: string;
153
+ }
154
+ export interface V2PermissionDomain {
155
+ readonly hook: V2Hooks<{
156
+ evaluate: V2PermissionEvaluation;
157
+ }>;
158
+ readonly list?: (input?: unknown) => Promise<unknown>;
159
+ readonly get?: (input?: unknown) => Promise<unknown>;
160
+ readonly reply?: (input?: unknown) => Promise<unknown>;
161
+ }
162
+ export interface V2SessionContext {
163
+ readonly agent?: string;
164
+ readonly system: unknown[];
165
+ readonly messages: unknown[];
166
+ readonly tools: Record<string, {
167
+ description: string;
168
+ input: unknown;
169
+ }>;
170
+ options: Record<string, unknown>;
171
+ }
172
+ export interface V2SessionHooks {
173
+ readonly context: V2SessionContext;
174
+ readonly compaction: V2SessionContext & {
175
+ result?: unknown;
176
+ };
177
+ }
178
+ export interface V2SessionDomain {
179
+ readonly hook: V2Hooks<V2SessionHooks>;
180
+ readonly [key: string]: unknown;
181
+ }
182
+ export interface V2ShellCreateBefore {
183
+ command: string;
184
+ cwd: string;
185
+ timeout: number;
186
+ shell: string;
187
+ env: Record<string, string | undefined>;
188
+ }
189
+ export interface V2ShellDomain {
190
+ readonly hook: V2Hooks<{
191
+ "create.before": V2ShellCreateBefore;
192
+ }>;
193
+ }
194
+ export interface V2StorageDomain {
195
+ readonly get: (key: string) => Promise<unknown>;
196
+ readonly set: (key: string, value: unknown) => Promise<void>;
197
+ readonly remove: (key: string) => Promise<void>;
198
+ readonly scan: (options: unknown) => Promise<unknown>;
199
+ }
200
+ export interface V2Event {
201
+ readonly type?: string;
202
+ readonly data?: unknown;
203
+ }
204
+ export interface V2Context {
205
+ readonly location?: {
206
+ readonly directory?: string;
207
+ readonly project?: {
208
+ readonly directory?: string;
209
+ readonly id?: string;
210
+ };
211
+ };
212
+ readonly options?: Record<string, unknown>;
213
+ readonly tool: V2ToolDomain;
214
+ readonly agent?: V2AgentDomain;
215
+ readonly permission?: V2PermissionDomain;
216
+ readonly session?: V2SessionDomain;
217
+ readonly shell?: V2ShellDomain;
218
+ readonly storage?: V2StorageDomain;
219
+ readonly event?: {
220
+ readonly subscribe: () => AsyncIterable<V2Event>;
221
+ };
222
+ readonly [key: string]: unknown;
223
+ }
224
+ export type V2Cleanup = () => Promise<void> | void;
225
+ export interface V2Plugin {
226
+ readonly id: string;
227
+ readonly setup: (ctx: V2Context) => Promise<V2Cleanup | void> | V2Cleanup | void;
228
+ }
229
+ //# sourceMappingURL=v2-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v2-types.d.ts","sourceRoot":"","sources":["../../src/host/v2-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Hand-written structural types for the OpenCode v2 plugin surface.
3
+ *
4
+ * We deliberately do NOT import `@opencode/plugin`: it is a separate package
5
+ * from the v1 SDK, and a v2 SDK that becomes a runtime dependency would break
6
+ * the dual-personality export for every v1 user who cannot resolve it. The
7
+ * shapes below cover only the members this plugin actually touches, and they
8
+ * are transcribed from `@opencode/plugin@2.0.16/dist/promise/*.d.ts` plus two
9
+ * live-host probes (2026-09-25) — the probe is what proves `hook()` returns a
10
+ * disposable registration and that `execute.before` can really deny.
11
+ *
12
+ * Kept intentionally loose (`unknown` where we only pass values through): a
13
+ * type that is wider than the host's never fails a build, and every field we
14
+ * READ is read defensively because the host makes no stability promise.
15
+ */
16
+ export {};
17
+ //# sourceMappingURL=v2-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v2-types.js","sourceRoot":"","sources":["../../src/host/v2-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * The v2 personality: `Plugin.define({id, setup(ctx)})`.
3
+ *
4
+ * `Plugin.define` in @opencode/plugin@2.0.16 is literally `plugin => plugin`,
5
+ * so this module exports the plain object and the v2 SDK never becomes a
6
+ * runtime dependency — which is what keeps the dual-personality package
7
+ * installable by a v1 user who cannot resolve that package at all.
8
+ *
9
+ * Scope of this file (milestone M2): build the governed runtime on a
10
+ * filesystem-backed client shim, register the tm_* tools through
11
+ * `ctx.tool.transform`, and normalize the permission matrix onto the agents the
12
+ * CONFIG declares. It deliberately does NOT touch: the approval gate (#94), the
13
+ * session hooks / compaction / description appends (#93), or the browser
14
+ * (#95). Those need this seam proven live first.
15
+ *
16
+ * Two v1 behaviors do not carry over, and both absences are stated rather than
17
+ * discovered later:
18
+ * - creating agents: `AgentEditor` has no `add`, so the six roles must come
19
+ * from the user's config (the installer writes `agents/*.md`).
20
+ * - the conservative default-agent promotion: v1 read `cfg.default_agent` and
21
+ * only filled it when empty or "build". v2 exposes `default(id)` with NO
22
+ * getter, so "only if the user did not choose" is not expressible — the
23
+ * choice is between never promoting and promoting every boot. The user's
24
+ * standing instruction (2026-09-25) is that Team is ALWAYS the default, so
25
+ * this promotes unconditionally; `defaultAgent: false` in the plugin options
26
+ * opts out, exactly as on v1.
27
+ *
28
+ * The official confirmation dialog is absent as well, and for a different
29
+ * reason: probed on the live host, a plugin has no way to raise one.
30
+ * `askFnOf` therefore finds no bridge and every governed call fails closed with
31
+ * the v2-worded refusal set below.
32
+ */
33
+ import type { V2Plugin } from "./v2-types.js";
34
+ /** The refusal has to name the real reason: on v2 the absence is the new
35
+ * protocol, and "旧版协议" would send the model looking for an upgrade the
36
+ * user already installed. It must ALSO not point at a domain gate this
37
+ * personality no longer runs (the default is `"*"`), so the knob it names is
38
+ * the host's own permission config, and the address red line is excluded from
39
+ * "ask the user" because that one has no consent path at all. */
40
+ export declare const V2_NO_DIALOG_NOTE: string;
41
+ export declare const v2Personality: V2Plugin;
42
+ //# sourceMappingURL=v2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v2.d.ts","sourceRoot":"","sources":["../../src/host/v2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAwBH,OAAO,KAAK,EAA0B,QAAQ,EAA8B,MAAM,eAAe,CAAA;AAEjG;;;;;kEAKkE;AAClE,eAAO,MAAM,iBAAiB,QAGmB,CAAA;AASjD,eAAO,MAAM,aAAa,EAAE,QA8oB3B,CAAA"}