@te-river/opencode-team-mode 1.6.2 → 1.7.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 (198) hide show
  1. package/README.md +114 -118
  2. package/README.zh-CN.md +95 -100
  3. package/dist/agents.d.ts.map +1 -1
  4. package/dist/agents.js +89 -79
  5. package/dist/agents.js.map +1 -1
  6. package/dist/approval-gate.d.ts +8 -9
  7. package/dist/approval-gate.d.ts.map +1 -1
  8. package/dist/approval-gate.js +13 -14
  9. package/dist/approval-gate.js.map +1 -1
  10. package/dist/capabilities.d.ts +11 -37
  11. package/dist/capabilities.d.ts.map +1 -1
  12. package/dist/capabilities.js +11 -141
  13. package/dist/capabilities.js.map +1 -1
  14. package/dist/commands.js +1 -1
  15. package/dist/envprotect/hook.d.ts +12 -31
  16. package/dist/envprotect/hook.d.ts.map +1 -1
  17. package/dist/envprotect/hook.js +13 -91
  18. package/dist/envprotect/hook.js.map +1 -1
  19. package/dist/envprotect/patterns.d.ts +6 -4
  20. package/dist/envprotect/patterns.d.ts.map +1 -1
  21. package/dist/envprotect/patterns.js +6 -4
  22. package/dist/envprotect/patterns.js.map +1 -1
  23. package/dist/envprotect.d.ts +1 -1
  24. package/dist/envprotect.d.ts.map +1 -1
  25. package/dist/envprotect.js +1 -1
  26. package/dist/envprotect.js.map +1 -1
  27. package/dist/host/v2-browser-gate.d.ts +19 -1
  28. package/dist/host/v2-browser-gate.d.ts.map +1 -1
  29. package/dist/host/v2-browser-gate.js +47 -6
  30. package/dist/host/v2-browser-gate.js.map +1 -1
  31. package/dist/host/v2-capabilities.d.ts +16 -0
  32. package/dist/host/v2-capabilities.d.ts.map +1 -1
  33. package/dist/host/v2-capabilities.js +22 -1
  34. package/dist/host/v2-capabilities.js.map +1 -1
  35. package/dist/host/v2-default-agent.d.ts +37 -0
  36. package/dist/host/v2-default-agent.d.ts.map +1 -0
  37. package/dist/host/v2-default-agent.js +128 -0
  38. package/dist/host/v2-default-agent.js.map +1 -0
  39. package/dist/host/v2-events.d.ts +1 -0
  40. package/dist/host/v2-events.d.ts.map +1 -1
  41. package/dist/host/v2-events.js +14 -0
  42. package/dist/host/v2-events.js.map +1 -1
  43. package/dist/host/v2-guard.d.ts +178 -0
  44. package/dist/host/v2-guard.d.ts.map +1 -1
  45. package/dist/host/v2-guard.js +324 -8
  46. package/dist/host/v2-guard.js.map +1 -1
  47. package/dist/host/v2-offload.d.ts +1 -1
  48. package/dist/host/v2-offload.js +2 -2
  49. package/dist/host/v2-permissions.d.ts +45 -44
  50. package/dist/host/v2-permissions.d.ts.map +1 -1
  51. package/dist/host/v2-permissions.js +48 -49
  52. package/dist/host/v2-permissions.js.map +1 -1
  53. package/dist/host/v2-probe-chain.d.ts +93 -0
  54. package/dist/host/v2-probe-chain.d.ts.map +1 -0
  55. package/dist/host/v2-probe-chain.js +146 -0
  56. package/dist/host/v2-probe-chain.js.map +1 -0
  57. package/dist/host/v2-prune.d.ts +157 -0
  58. package/dist/host/v2-prune.d.ts.map +1 -0
  59. package/dist/host/v2-prune.js +507 -0
  60. package/dist/host/v2-prune.js.map +1 -0
  61. package/dist/host/v2-retry.d.ts +143 -0
  62. package/dist/host/v2-retry.d.ts.map +1 -0
  63. package/dist/host/v2-retry.js +315 -0
  64. package/dist/host/v2-retry.js.map +1 -0
  65. package/dist/host/v2-scope.d.ts.map +1 -1
  66. package/dist/host/v2-scope.js +14 -7
  67. package/dist/host/v2-scope.js.map +1 -1
  68. package/dist/host/v2-session-client.d.ts +24 -0
  69. package/dist/host/v2-session-client.d.ts.map +1 -1
  70. package/dist/host/v2-session-client.js +243 -3
  71. package/dist/host/v2-session-client.js.map +1 -1
  72. package/dist/host/v2-session.d.ts +72 -1
  73. package/dist/host/v2-session.d.ts.map +1 -1
  74. package/dist/host/v2-session.js +154 -10
  75. package/dist/host/v2-session.js.map +1 -1
  76. package/dist/host/v2-tool.d.ts +2 -3
  77. package/dist/host/v2-tool.d.ts.map +1 -1
  78. package/dist/host/v2-tool.js +2 -3
  79. package/dist/host/v2-tool.js.map +1 -1
  80. package/dist/host/v2-types.d.ts +30 -0
  81. package/dist/host/v2-types.d.ts.map +1 -1
  82. package/dist/host/v2-usage.d.ts +50 -0
  83. package/dist/host/v2-usage.d.ts.map +1 -0
  84. package/dist/host/v2-usage.js +82 -0
  85. package/dist/host/v2-usage.js.map +1 -0
  86. package/dist/host/v2.d.ts +14 -12
  87. package/dist/host/v2.d.ts.map +1 -1
  88. package/dist/host/v2.js +430 -73
  89. package/dist/host/v2.js.map +1 -1
  90. package/dist/identity.d.ts +27 -0
  91. package/dist/identity.d.ts.map +1 -0
  92. package/dist/identity.js +34 -0
  93. package/dist/identity.js.map +1 -0
  94. package/dist/index.d.ts +9 -24
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +17 -27
  97. package/dist/index.js.map +1 -1
  98. package/dist/prompts/lead.d.ts +1 -1
  99. package/dist/prompts/lead.d.ts.map +1 -1
  100. package/dist/prompts/lead.js +38 -25
  101. package/dist/prompts/lead.js.map +1 -1
  102. package/dist/prompts/shared.d.ts +2 -2
  103. package/dist/prompts/shared.d.ts.map +1 -1
  104. package/dist/prompts/shared.js +66 -56
  105. package/dist/prompts/shared.js.map +1 -1
  106. package/dist/prompts/specialists.d.ts +2 -2
  107. package/dist/prompts/specialists.d.ts.map +1 -1
  108. package/dist/prompts/specialists.js +53 -83
  109. package/dist/prompts/specialists.js.map +1 -1
  110. package/dist/tm/args-schema.d.ts +7 -32
  111. package/dist/tm/args-schema.d.ts.map +1 -1
  112. package/dist/tm/args-schema.js +12 -153
  113. package/dist/tm/args-schema.js.map +1 -1
  114. package/dist/tm/board.d.ts +10 -9
  115. package/dist/tm/board.d.ts.map +1 -1
  116. package/dist/tm/board.js +11 -10
  117. package/dist/tm/board.js.map +1 -1
  118. package/dist/tm/config-files.d.ts +81 -0
  119. package/dist/tm/config-files.d.ts.map +1 -0
  120. package/dist/tm/config-files.js +209 -0
  121. package/dist/tm/config-files.js.map +1 -0
  122. package/dist/tm/config-layers.d.ts +117 -0
  123. package/dist/tm/config-layers.d.ts.map +1 -0
  124. package/dist/tm/config-layers.js +317 -0
  125. package/dist/tm/config-layers.js.map +1 -0
  126. package/dist/tm/config.d.ts +10 -101
  127. package/dist/tm/config.d.ts.map +1 -1
  128. package/dist/tm/config.js +17 -71
  129. package/dist/tm/config.js.map +1 -1
  130. package/dist/tm/dispatch.d.ts +115 -21
  131. package/dist/tm/dispatch.d.ts.map +1 -1
  132. package/dist/tm/dispatch.js +424 -67
  133. package/dist/tm/dispatch.js.map +1 -1
  134. package/dist/tm/egress.d.ts +19 -7
  135. package/dist/tm/egress.d.ts.map +1 -1
  136. package/dist/tm/egress.js +21 -9
  137. package/dist/tm/egress.js.map +1 -1
  138. package/dist/tm/index.d.ts +23 -20
  139. package/dist/tm/index.d.ts.map +1 -1
  140. package/dist/tm/index.js +117 -116
  141. package/dist/tm/index.js.map +1 -1
  142. package/dist/tm/ledger.d.ts +9 -2
  143. package/dist/tm/ledger.d.ts.map +1 -1
  144. package/dist/tm/ledger.js +4 -1
  145. package/dist/tm/ledger.js.map +1 -1
  146. package/dist/tm/perm-ask.d.ts +3 -3
  147. package/dist/tm/perm-ask.d.ts.map +1 -1
  148. package/dist/tm/perm-ask.js +3 -3
  149. package/dist/tm/perm-ask.js.map +1 -1
  150. package/dist/tm/pipelines.d.ts +12 -11
  151. package/dist/tm/pipelines.d.ts.map +1 -1
  152. package/dist/tm/pipelines.js +40 -207
  153. package/dist/tm/pipelines.js.map +1 -1
  154. package/dist/tm/preview.d.ts +1 -1
  155. package/dist/tm/preview.js +3 -3
  156. package/dist/tm/preview.js.map +1 -1
  157. package/dist/tm/refs.d.ts +31 -4
  158. package/dist/tm/refs.d.ts.map +1 -1
  159. package/dist/tm/refs.js +48 -4
  160. package/dist/tm/refs.js.map +1 -1
  161. package/dist/tm/result.d.ts +1 -1
  162. package/dist/tm/result.d.ts.map +1 -1
  163. package/dist/tm/result.js +4 -3
  164. package/dist/tm/result.js.map +1 -1
  165. package/dist/tm/search.d.ts +2 -2
  166. package/dist/tm/search.js +7 -7
  167. package/dist/tm/search.js.map +1 -1
  168. package/dist/tm/serp-loop.d.ts +19 -7
  169. package/dist/tm/serp-loop.d.ts.map +1 -1
  170. package/dist/tm/serp-loop.js +24 -9
  171. package/dist/tm/serp-loop.js.map +1 -1
  172. package/dist/tm/stats.d.ts +12 -27
  173. package/dist/tm/stats.d.ts.map +1 -1
  174. package/dist/tm/stats.js +43 -45
  175. package/dist/tm/stats.js.map +1 -1
  176. package/dist/tm/store.d.ts +18 -5
  177. package/dist/tm/store.d.ts.map +1 -1
  178. package/dist/tm/store.js +39 -9
  179. package/dist/tm/store.js.map +1 -1
  180. package/dist/tm/tools.d.ts +7 -5
  181. package/dist/tm/tools.d.ts.map +1 -1
  182. package/dist/tm/tools.js +10 -41
  183. package/dist/tm/tools.js.map +1 -1
  184. package/dist/tm/webfetch.d.ts +1 -1
  185. package/dist/tm/webfetch.d.ts.map +1 -1
  186. package/dist/tm/webfetch.js +38 -23
  187. package/dist/tm/webfetch.js.map +1 -1
  188. package/dist/types.d.ts +40 -123
  189. package/dist/types.d.ts.map +1 -1
  190. package/dist/types.js +7 -21
  191. package/dist/types.js.map +1 -1
  192. package/docs/installation-v2.md +133 -33
  193. package/docs/installation.md +9 -0
  194. package/docs/research/browser-pane.md +5 -0
  195. package/docs/v2-port-notes.md +133 -0
  196. package/package.json +1 -1
  197. package/scripts/gen-v2-config.mjs +246 -94
  198. package/scripts/lib/fake-ctx.mjs +67 -0
@@ -108,7 +108,7 @@ interface OffloadDeps {
108
108
  * take a `ref` out of the snapshot, so a preview that drops the ref tokens does not
109
109
  * save the model a round-trip — it makes it click the wrong element, or spend a call
110
110
  * re-snapshotting. For these two the text stays in context, capped, with the handle
111
- * kept for the tail. 1 200 tokens is the budget tm_browser's own snapshot already
111
+ * kept for the tail. 1 200 tokens is the budget a native snapshot already
112
112
  * runs at, so the governed door and the native one cost the same window space.
113
113
  */
114
114
  export declare const ADDRESSING_NATIVE_TOOLS: ReadonlySet<string>;
@@ -70,7 +70,7 @@ export const NATIVE_GOVERNED_TOOLS = new Set([
70
70
  * `session.hook("context")` carrying a single message and no
71
71
  * `<task id=… state="completed">` envelope at all -- so v1's chat.message offload
72
72
  * has no anchor on v2, and rewriting the message list against a guessed shape is
73
- * how evidence gets deleted silently (the same reason host-hooks.ts declines
73
+ * how evidence gets deleted silently (the same reason we decline
74
74
  * `experimental.chat.messages.transform`). Consequence stated plainly: a
75
75
  * BACKGROUND child's reply, which the host injects later, is NOT governed here --
76
76
  * closing that needs the ctx.event/ctx.session rebuild, which is an open decision.
@@ -115,7 +115,7 @@ function locatableText(result) {
115
115
  * take a `ref` out of the snapshot, so a preview that drops the ref tokens does not
116
116
  * save the model a round-trip — it makes it click the wrong element, or spend a call
117
117
  * re-snapshotting. For these two the text stays in context, capped, with the handle
118
- * kept for the tail. 1 200 tokens is the budget tm_browser's own snapshot already
118
+ * kept for the tail. 1 200 tokens is the budget a native snapshot already
119
119
  * runs at, so the governed door and the native one cost the same window space.
120
120
  */
121
121
  export const ADDRESSING_NATIVE_TOOLS = new Set(["browser_snapshot", "browser_find"]);
@@ -1,11 +1,11 @@
1
1
  /**
2
- * v1's flat permission map -> v2's ordered `{action, resource, effect}` rules.
2
+ * The agent permission matrix -> v2's ordered `{action, resource, effect}` rules.
3
3
  *
4
- * v1 expressed an agent's whitelist as an object keyed by tool name, with two
4
+ * The matrix expresses a whitelist as an object keyed by tool name, with two
5
5
  * tricks the v2 schema cannot hold: a value may be an OBJECT of
6
6
  * pattern->effect (the bash escalation that made the host's official dialog
7
- * fire for the R6/R2 faces), and `"tm_*"` was a literal wildcard KEY that
8
- * matched our whole tool family. v2 takes only flat triples, so:
7
+ * fire for the R6/R2 faces), and `"tm_*"` is a literal wildcard KEY that
8
+ * matches our whole tool family. v2 takes only flat triples, so:
9
9
  *
10
10
  * - a plain `tool: "allow"|"deny"|"ask"` becomes `{action: tool, resource:"*", effect}`;
11
11
  * - an escalation object becomes ONE `ask` triple for that action — the object
@@ -25,9 +25,10 @@ export interface PermissionTriple {
25
25
  effect: PermissionEffect;
26
26
  }
27
27
  /**
28
- * v1 named its built-in tools differently. Measured against the live v2
29
- * surface (probed `session.context.tools`: edit glob grep question read shell
30
- * skill subagent webfetch websearch write, plus patch/browser_*):
28
+ * The matrix names three built-in tools differently from the host's v2 tool
29
+ * ids. Measured against the live v2 surface (probed `session.context.tools`:
30
+ * edit glob grep question read shell skill subagent webfetch websearch write,
31
+ * plus patch/browser_*):
31
32
  *
32
33
  * bash → shell · task → subagent · apply_patch → patch
33
34
  *
@@ -38,41 +39,41 @@ export interface PermissionTriple {
38
39
  */
39
40
  export declare const V2_ACTION_NAMES: Readonly<Record<string, string>>;
40
41
  /**
41
- * Tools the v1 personality registers and the v2 one does NOT — the host's own
42
- * `execute` (Code Mode) already covers `tm_ptc_run` on v2 (proved against a live
43
- * session: parallel governed calls, results still offloaded through handles).
42
+ * RETIRED TOOLS — names the v1 personality used to register and this package
43
+ * no longer ships. v1 support was removed in 1.7.0, so these are historical
44
+ * names; the set survives because it still has three live jobs:
44
45
  *
45
- * This is the single source for that fact: `v2.ts` skips them when registering,
46
- * and `scripts/gen-v2-config.mjs` drops their permission triples, because an
47
- * `allow` for an action the host has never heard of claims a capability that
48
- * does not exist.
49
- */
50
- /**
51
- * Tools v1 keeps and v2 does not register.
46
+ * - `v2.ts` skips them when registering, so a stale build or a future re-add
47
+ * cannot slip one back onto the tool surface;
48
+ * - `triplesFromAgentPermission` drops any permission rule naming one, and
49
+ * `mergeTriples` reclaims such a rule from an upgraded config — an `allow`
50
+ * for an action the host has never heard of claims a capability that does
51
+ * not exist;
52
+ * - `scripts/gen-v2-config.mjs` drops their triples from the generated
53
+ * markdown for the same reason.
52
54
  *
53
- * `tm_ptc_run` left because the host's own Code Mode does the job. The other
54
- * three left for the opposite reason: on v2 the NATIVE read/grep/shell are the
55
- * better tools (paged reads, image/PDF attachment, background shell, and — since
56
- * 1.7.0's offload layer — they are now governed too, measured at 12,902 tokens
57
- * arriving as a 78-token preview). Retiring them is only safe in that order,
58
- * which is why the governance moved to `execute.after` FIRST and this list is the
59
- * step that follows it, not the one that precedes it.
60
- *
61
- * v1 keeps all three: its `tool.execute.before` can rewrite arguments but not
62
- * results, so deleting them there would delete offload itself.
55
+ * Why each left: `tm_ptc_run` because the host's own Code Mode does the job
56
+ * (one program, N governed calls, zero round-trips, proved against a live
57
+ * session: parallel governed calls, results still offloaded through handles).
58
+ * `tm_read`/`tm_grep`/`tm_bash` because the NATIVE read/grep/shell are the
59
+ * better tools (paged reads, image/PDF attachment, background shell, and —
60
+ * since the offload layer — they are governed too, measured at 12,902 tokens
61
+ * arriving as a 78-token preview). Retiring them was only safe in that order,
62
+ * which is why the governance moved to `execute.after` FIRST and this list is
63
+ * the step that follows it, not the one that precedes it.
63
64
  */
64
65
  export declare const V1_ONLY_TOOLS: ReadonlySet<string>;
65
66
  /**
66
- * The v2 file/shell ladder runs through the host's own tools, so the triples that
67
+ * The file/shell ladder runs through the host's own tools, so the triples that
67
68
  * DENY them must not be projected: v2-session.ts deletes every literal-`deny`
68
69
  * action from the request, and denying `read` while `tm_read` is unregistered
69
70
  * would leave a role with no way to open a file at all. This is a translation
70
- * decision, not an edit to src/agents.ts — v1's matrix keeps its denies and the
71
- * two personalities' ladders genuinely differ now.
71
+ * decision, not an edit to src/agents.ts — the matrix keeps its denies and the
72
+ * ladder is applied at translation time.
72
73
  *
73
74
  * Both halves have to agree, so the SAME set is consulted by `toolsToRemove()` in
74
75
  * v2-session.ts; this constant is the one source. Letting the native file tools
75
- * back in does not lower a red line: v1's P2 scope ("stay inside the project +
76
+ * back in does not lower a red line: the P2 scope ("stay inside the project +
76
77
  * the store dirs") is the host's own `external_directory` permission action on v2,
77
78
  * observed live answering `effect:"ask"` with a `permission.asked` behind it — a
78
79
  * real dialog where our code used to hard-throw. The two red lines the host does
@@ -83,25 +84,25 @@ export declare const V1_ONLY_TOOLS: ReadonlySet<string>;
83
84
  export declare const V2_LADDER_ACTIONS: ReadonlySet<string>;
84
85
  export interface TranslateOptions {
85
86
  /**
86
- * With R6 on, v1 escalated `bash` to a pattern object so the host's OFFICIAL
87
- * dialog fired. A plugin cannot raise a dialog on v2 (probed) — but the host
88
- * does honor an `ask` EFFECT it evaluates itself, so escalating the mapped
89
- * `shell` action to `ask` is the closest honest equivalent: the human is
90
- * asked, just per command rather than per pattern. #94 refines the
87
+ * With R6 on, the matrix escalates `bash` to a pattern object so the host's
88
+ * OFFICIAL dialog fires. A plugin cannot raise a dialog on v2 (probed) — but
89
+ * the host does honor an `ask` EFFECT it evaluates itself, so escalating the
90
+ * mapped `shell` action to `ask` is the closest honest equivalent: the human
91
+ * is asked, just per command rather than per pattern. #94 refines the
91
92
  * per-pattern half through `permission.hook("evaluate")`.
92
93
  */
93
94
  escalateShellAsk?: boolean;
94
95
  /**
95
- * Which role these triples are for. Needed for the ONE tool that exists only on this
96
- * personality: `tm_ledger` is not in the v1 permission map (v1 has the host's
97
- * `todowrite`), so nothing would ever name it, and an unruled action is the host's
98
- * default rather than our stated rule. The lead's list is the lead's: `allow` for it,
99
- * `deny` for the five specialists, which also makes the runtime gate
100
- * (`onlyAgent: "team"`) visible in the config the user can read.
96
+ * Which role these triples are for. Needed for the ONE tool the matrix does
97
+ * not name: `tm_ledger` is not in the permission map, so nothing would ever
98
+ * name it, and an unruled action is the host's default rather than our stated
99
+ * rule. The lead's list is the lead's: `allow` for it, `deny` for the five
100
+ * specialists, which also makes the runtime gate (`onlyAgent: "Team"`)
101
+ * visible in the config the user can read.
101
102
  */
102
103
  agentName?: string;
103
104
  }
104
- /** The v1 `permission` block, as loosely as the host hands it to us. */
105
+ /** The agent `permission` block, as loosely as the config hands it to us. */
105
106
  export declare function triplesFromAgentPermission(permission: Record<string, unknown> | undefined | null, options?: TranslateOptions): {
106
107
  triples: PermissionTriple[];
107
108
  unmapped: string[];
@@ -113,7 +114,7 @@ export declare function triplesFromAgentPermission(permission: Record<string, un
113
114
  * it). Idempotent: running it twice changes nothing.
114
115
  *
115
116
  * `drop` is the reclaim path for an upgrade: a rule naming an action this
116
- * personality never registers (a v1-only tool) can only have come from us, and
117
+ * package never registers (a retired tool) can only have come from us, and
117
118
  * leaving it behind would keep claiming a capability the host does not have.
118
119
  */
119
120
  export declare function mergeTriples(existing: ReadonlyArray<PermissionTriple> | undefined | null, ours: ReadonlyArray<PermissionTriple>, drop?: ReadonlySet<string>): {
@@ -1 +1 @@
1
- {"version":3,"file":"v2-permissions.d.ts","sourceRoot":"","sources":["../../src/host/v2-permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAA;AAEvD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,gBAAgB,CAAA;CACzB;AAID;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAI5D,CAAA;AAED;;;;;;;;;GASG;AACH;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CAe5C,CAAA;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAqC,CAAA;AAQvF,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wEAAwE;AACxE,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,EACtD,OAAO,GAAE,gBAAqB,GAC7B;IAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CA0DrD;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,SAAS,GAAG,IAAI,EAC5D,IAAI,EAAE,aAAa,CAAC,gBAAgB,CAAC,EACrC,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GACzB;IAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAcnD"}
1
+ {"version":3,"file":"v2-permissions.d.ts","sourceRoot":"","sources":["../../src/host/v2-permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAA;AAEvD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,gBAAgB,CAAA;CACzB;AAID;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAI5D,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CAe5C,CAAA;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAqC,CAAA;AAQvF,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,6EAA6E;AAC7E,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,EACtD,OAAO,GAAE,gBAAqB,GAC7B;IAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAuDrD;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,SAAS,GAAG,IAAI,EAC5D,IAAI,EAAE,aAAa,CAAC,gBAAgB,CAAC,EACrC,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GACzB;IAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAcnD"}
@@ -1,11 +1,11 @@
1
1
  /**
2
- * v1's flat permission map -> v2's ordered `{action, resource, effect}` rules.
2
+ * The agent permission matrix -> v2's ordered `{action, resource, effect}` rules.
3
3
  *
4
- * v1 expressed an agent's whitelist as an object keyed by tool name, with two
4
+ * The matrix expresses a whitelist as an object keyed by tool name, with two
5
5
  * tricks the v2 schema cannot hold: a value may be an OBJECT of
6
6
  * pattern->effect (the bash escalation that made the host's official dialog
7
- * fire for the R6/R2 faces), and `"tm_*"` was a literal wildcard KEY that
8
- * matched our whole tool family. v2 takes only flat triples, so:
7
+ * fire for the R6/R2 faces), and `"tm_*"` is a literal wildcard KEY that
8
+ * matches our whole tool family. v2 takes only flat triples, so:
9
9
  *
10
10
  * - a plain `tool: "allow"|"deny"|"ask"` becomes `{action: tool, resource:"*", effect}`;
11
11
  * - an escalation object becomes ONE `ask` triple for that action — the object
@@ -18,11 +18,13 @@
18
18
  * rather than guessed at: a rule the host cannot parse is worse than no rule,
19
19
  * because it may fail closed on the whole agent.
20
20
  */
21
+ import { isLeadAgent } from "../identity.js";
21
22
  const EFFECTS = new Set(["allow", "deny", "ask"]);
22
23
  /**
23
- * v1 named its built-in tools differently. Measured against the live v2
24
- * surface (probed `session.context.tools`: edit glob grep question read shell
25
- * skill subagent webfetch websearch write, plus patch/browser_*):
24
+ * The matrix names three built-in tools differently from the host's v2 tool
25
+ * ids. Measured against the live v2 surface (probed `session.context.tools`:
26
+ * edit glob grep question read shell skill subagent webfetch websearch write,
27
+ * plus patch/browser_*):
26
28
  *
27
29
  * bash → shell · task → subagent · apply_patch → patch
28
30
  *
@@ -37,28 +39,28 @@ export const V2_ACTION_NAMES = {
37
39
  apply_patch: "patch",
38
40
  };
39
41
  /**
40
- * Tools the v1 personality registers and the v2 one does NOT — the host's own
41
- * `execute` (Code Mode) already covers `tm_ptc_run` on v2 (proved against a live
42
- * session: parallel governed calls, results still offloaded through handles).
42
+ * RETIRED TOOLS — names the v1 personality used to register and this package
43
+ * no longer ships. v1 support was removed in 1.7.0, so these are historical
44
+ * names; the set survives because it still has three live jobs:
43
45
  *
44
- * This is the single source for that fact: `v2.ts` skips them when registering,
45
- * and `scripts/gen-v2-config.mjs` drops their permission triples, because an
46
- * `allow` for an action the host has never heard of claims a capability that
47
- * does not exist.
48
- */
49
- /**
50
- * Tools v1 keeps and v2 does not register.
46
+ * - `v2.ts` skips them when registering, so a stale build or a future re-add
47
+ * cannot slip one back onto the tool surface;
48
+ * - `triplesFromAgentPermission` drops any permission rule naming one, and
49
+ * `mergeTriples` reclaims such a rule from an upgraded config — an `allow`
50
+ * for an action the host has never heard of claims a capability that does
51
+ * not exist;
52
+ * - `scripts/gen-v2-config.mjs` drops their triples from the generated
53
+ * markdown for the same reason.
51
54
  *
52
- * `tm_ptc_run` left because the host's own Code Mode does the job. The other
53
- * three left for the opposite reason: on v2 the NATIVE read/grep/shell are the
54
- * better tools (paged reads, image/PDF attachment, background shell, and — since
55
- * 1.7.0's offload layer — they are now governed too, measured at 12,902 tokens
56
- * arriving as a 78-token preview). Retiring them is only safe in that order,
57
- * which is why the governance moved to `execute.after` FIRST and this list is the
58
- * step that follows it, not the one that precedes it.
59
- *
60
- * v1 keeps all three: its `tool.execute.before` can rewrite arguments but not
61
- * results, so deleting them there would delete offload itself.
55
+ * Why each left: `tm_ptc_run` because the host's own Code Mode does the job
56
+ * (one program, N governed calls, zero round-trips, proved against a live
57
+ * session: parallel governed calls, results still offloaded through handles).
58
+ * `tm_read`/`tm_grep`/`tm_bash` because the NATIVE read/grep/shell are the
59
+ * better tools (paged reads, image/PDF attachment, background shell, and —
60
+ * since the offload layer — they are governed too, measured at 12,902 tokens
61
+ * arriving as a 78-token preview). Retiring them was only safe in that order,
62
+ * which is why the governance moved to `execute.after` FIRST and this list is
63
+ * the step that follows it, not the one that precedes it.
62
64
  */
63
65
  export const V1_ONLY_TOOLS = new Set([
64
66
  "tm_ptc_run",
@@ -69,7 +71,7 @@ export const V1_ONLY_TOOLS = new Set([
69
71
  * `tm_pty` executes on the host's OWN terminal sessions through `client.pty.*`,
70
72
  * and the v2 plugin context has no pty domain at all — so registering it meant
71
73
  * shipping a tool whose every start answers "宿主 pty 接口不可用". A tool that
72
- * cannot work is the overstated claim, not the fallback. v1 keeps it.
74
+ * cannot work is the overstated claim, not the fallback.
73
75
  * Revisit only when #28 measures the native `shell` background round-trip
74
76
  (what returns, how output is retrieved, how it is cancelled); if the host's own
75
77
  * background shell covers it, this stays retired and the prompt says `shell`.
@@ -77,16 +79,16 @@ export const V1_ONLY_TOOLS = new Set([
77
79
  "tm_pty",
78
80
  ]);
79
81
  /**
80
- * The v2 file/shell ladder runs through the host's own tools, so the triples that
82
+ * The file/shell ladder runs through the host's own tools, so the triples that
81
83
  * DENY them must not be projected: v2-session.ts deletes every literal-`deny`
82
84
  * action from the request, and denying `read` while `tm_read` is unregistered
83
85
  * would leave a role with no way to open a file at all. This is a translation
84
- * decision, not an edit to src/agents.ts — v1's matrix keeps its denies and the
85
- * two personalities' ladders genuinely differ now.
86
+ * decision, not an edit to src/agents.ts — the matrix keeps its denies and the
87
+ * ladder is applied at translation time.
86
88
  *
87
89
  * Both halves have to agree, so the SAME set is consulted by `toolsToRemove()` in
88
90
  * v2-session.ts; this constant is the one source. Letting the native file tools
89
- * back in does not lower a red line: v1's P2 scope ("stay inside the project +
91
+ * back in does not lower a red line: the P2 scope ("stay inside the project +
90
92
  * the store dirs") is the host's own `external_directory` permission action on v2,
91
93
  * observed live answering `effect:"ask"` with a `permission.asked` behind it — a
92
94
  * real dialog where our code used to hard-throw. The two red lines the host does
@@ -99,20 +101,20 @@ const V2_ONLY_ACTIONS = new Set(["list", "todowrite", "lsp"]);
99
101
  function normalizeEffect(value) {
100
102
  return typeof value === "string" && EFFECTS.has(value) ? value : null;
101
103
  }
102
- /** The v1 `permission` block, as loosely as the host hands it to us. */
104
+ /** The agent `permission` block, as loosely as the config hands it to us. */
103
105
  export function triplesFromAgentPermission(permission, options = {}) {
104
106
  const triples = [];
105
107
  const unmapped = [];
106
108
  if (!permission || typeof permission !== "object")
107
109
  return { triples, unmapped };
108
- for (const [v1Action, value] of Object.entries(permission)) {
109
- if (!v1Action)
110
+ for (const [matrixAction, value] of Object.entries(permission)) {
111
+ if (!matrixAction)
110
112
  continue;
111
- if (V2_ONLY_ACTIONS.has(v1Action)) {
112
- unmapped.push(v1Action);
113
+ if (V2_ONLY_ACTIONS.has(matrixAction)) {
114
+ unmapped.push(matrixAction);
113
115
  continue;
114
116
  }
115
- const action = V2_ACTION_NAMES[v1Action] ?? v1Action;
117
+ const action = V2_ACTION_NAMES[matrixAction] ?? matrixAction;
116
118
  // A rule for an action v2 never registers claims a capability that does not
117
119
  // exist, and `permission.evaluate` cannot even see it to enforce it. One
118
120
  // source for the decision: this is the same set v2.ts skips when registering
@@ -128,16 +130,13 @@ export function triplesFromAgentPermission(permission, options = {}) {
128
130
  if (V2_LADDER_ACTIONS.has(action) && direct === "deny")
129
131
  continue;
130
132
  const effect = options.escalateShellAsk && action === "shell" && direct === "allow" ? "ask" : direct;
133
+ // The host's 45 `browser_*` tools share ONE permission action named
134
+ // `browser` (read from the binary), and they are NOT in the direct tool
135
+ // surface — so deleting `browser_*` from `event.tools` at the request layer
136
+ // removes a catalog the assembled request never contained. The matrix now
137
+ // names that action directly (`browser`), so the deny reaches the host's
138
+ // own evaluator, which is the only lever that speaks their language.
131
139
  triples.push({ action, resource: "*", effect });
132
- // The host's 45 `browser_*` tools share ONE permission action named `browser`
133
- // (read from the binary), and they are NOT in the direct tool surface — so
134
- // deleting `browser_*` from `event.tools` at the request layer removes a
135
- // catalog the assembled request never contained, while a role that is denied
136
- // `tm_browser` can still reach every one of them from inside `execute`.
137
- // Projecting the deny is the only lever that speaks their language.
138
- if (action === "tm_browser" && direct === "deny") {
139
- triples.push({ action: "browser", resource: "*", effect: "deny" });
140
- }
141
140
  continue;
142
141
  }
143
142
  if (value && typeof value === "object" && !Array.isArray(value)) {
@@ -155,7 +154,7 @@ export function triplesFromAgentPermission(permission, options = {}) {
155
154
  }
156
155
  }
157
156
  if (options.agentName) {
158
- const ledgerEffect = options.agentName === "team" ? "allow" : "deny";
157
+ const ledgerEffect = isLeadAgent(options.agentName) ? "allow" : "deny";
159
158
  if (!triples.some((x) => x.action === "tm_ledger")) {
160
159
  triples.push({ action: "tm_ledger", resource: "*", effect: ledgerEffect });
161
160
  }
@@ -169,7 +168,7 @@ export function triplesFromAgentPermission(permission, options = {}) {
169
168
  * it). Idempotent: running it twice changes nothing.
170
169
  *
171
170
  * `drop` is the reclaim path for an upgrade: a rule naming an action this
172
- * personality never registers (a v1-only tool) can only have come from us, and
171
+ * package never registers (a retired tool) can only have come from us, and
173
172
  * leaving it behind would keep claiming a capability the host does not have.
174
173
  */
175
174
  export function mergeTriples(existing, ours, drop) {
@@ -1 +1 @@
1
- {"version":3,"file":"v2-permissions.js","sourceRoot":"","sources":["../../src/host/v2-permissions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"v2-permissions.js","sourceRoot":"","sources":["../../src/host/v2-permissions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Code Mode adoption guard (#35, 2026-10-06).
3
+ *
4
+ * The v2 retirement moved the file/command ladder onto the HOST's native
5
+ * `read` / `grep` / `glob` / `shell`, and the host's `execute` (Code Mode) is the
6
+ * one program that folds N governed calls into a single round-trip. A model that
7
+ * keeps reaching for the native tools one at a time pays N rounds for what one
8
+ * `execute` program answers — the exact inefficiency the retirement was supposed
9
+ * to remove, wearing the opposite face.
10
+ *
11
+ * This is an ADOPTION HINT, not a gate: after a run of consecutive native
12
+ * file/command calls it APPENDS one line to the next result naming `execute`.
13
+ * It never rewrites the body, never touches args, never refuses a call — the
14
+ * same shape as `src/tm/dupe-guard.ts` (append a directive + count + trajectory
15
+ * event), minus the escalation, because a hint that blocks would cost the user
16
+ * the very round it is trying to save.
17
+ *
18
+ * Discipline, copied from the layers beside it:
19
+ * - Team-scoped through the shared `scope.decide` gate — a foreign session's
20
+ * result is nobody's to annotate;
21
+ * - it may NEVER throw into somebody's tool call: a failure is swallowed and
22
+ * COUNTED (`threw`), and the host's verbatim result passes through;
23
+ * - the append is IDEMPOTENT (a marker check), because the host reloads plugins
24
+ * in-process and a replayed hook must not stack two lines.
25
+ */
26
+ import type { V2Registration } from "./v2-types.js";
27
+ import type { TeamScope } from "./v2-scope.js";
28
+ /** The native tools whose repeated use is what `execute` folds into one program.
29
+ * A closed list on purpose: `question`, `edit`, `subagent` … are not "one more
30
+ * read", and counting them would make the streak mean nothing. */
31
+ export declare const NATIVE_CHAIN_TOOLS: ReadonlySet<string>;
32
+ /** The tool that RESETS the streak: it is the alternative the hint points at, so
33
+ * using it is the behaviour the guard exists to encourage. */
34
+ export declare const CHAIN_RESET_TOOL = "execute";
35
+ /** Stable marker so a replayed hook cannot append the line twice. */
36
+ export declare const PROBE_CHAIN_MARKER = "\uFF08Code Mode \u91C7\u7528\u7387\u63D0\u793A\uFF09";
37
+ export declare const DEFAULT_PROBE_CHAIN_AFTER = 3;
38
+ export interface ProbeChainReport {
39
+ /** chain-tool calls observed in a Team session */
40
+ seen: number;
41
+ /** results that actually got the appended line */
42
+ advised: number;
43
+ /** `execute` calls that reset the streak */
44
+ reset: number;
45
+ /** non-Team sessions left completely alone */
46
+ foreignSkipped: number;
47
+ /** a throw inside the hook, swallowed and counted (never a reason to fail a call) */
48
+ threw: number;
49
+ }
50
+ export interface ProbeChainVerdict {
51
+ /** the current run of consecutive native file/command calls */
52
+ count: number;
53
+ /** should the line be appended to THIS result? */
54
+ advise: boolean;
55
+ }
56
+ /**
57
+ * The pure ledger. `threshold` is the number of consecutive native calls after
58
+ * which the NEXT result carries the hint: with the default 3, calls 1-3 are
59
+ * silent and the 4th (and every one after it, until a reset) is advised. A
60
+ * non-chain tool is transparent — it neither counts nor resets — and `execute`
61
+ * resets, because it is the alternative.
62
+ */
63
+ export declare function createProbeChain(threshold: number): {
64
+ observe: (tool: string) => ProbeChainVerdict;
65
+ streak: () => number;
66
+ };
67
+ /** The appended line, in the tool-output language the tm_* strings use. */
68
+ export declare function renderProbeChainNote(count: number): string;
69
+ /**
70
+ * Append the line to the result's first text part, byte-exact otherwise. Returns
71
+ * true only when a line was actually added — an unknown result shape, a missing
72
+ * text part, or an already-marked body all return false (the caller counts the
73
+ * difference). The body is never rewritten: the original text is preserved
74
+ * verbatim and the line is appended after it.
75
+ */
76
+ export declare function appendProbeChainNote(result: unknown, line: string): boolean;
77
+ export interface ProbeChainDeps {
78
+ /** Team-scope isolation: a foreign or unattributable session is left alone. */
79
+ scope?: TeamScope;
80
+ env?: Record<string, string | undefined>;
81
+ /** the trajectory sink — wired in v2.ts, same shape as the browser gate's `onSerp` */
82
+ onAdvise?: (info: {
83
+ tool: string;
84
+ count: number;
85
+ sessionID?: unknown;
86
+ }) => void;
87
+ }
88
+ export declare function applyV2ProbeChain(ctx: unknown, deps: ProbeChainDeps): {
89
+ registrations: Promise<V2Registration>[];
90
+ report: ProbeChainReport;
91
+ active: boolean;
92
+ };
93
+ //# sourceMappingURL=v2-probe-chain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v2-probe-chain.d.ts","sourceRoot":"","sources":["../../src/host/v2-probe-chain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAE9C;;mEAEmE;AACnE,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAA8C,CAAA;AAEjG;+DAC+D;AAC/D,eAAO,MAAM,gBAAgB,YAAY,CAAA;AAEzC,qEAAqE;AACrE,eAAO,MAAM,kBAAkB,yDAAsB,CAAA;AAErD,eAAO,MAAM,yBAAyB,IAAI,CAAA;AAE1C,MAAM,WAAW,gBAAgB;IAC/B,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAA;IACZ,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAA;IACf,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAA;IACb,8CAA8C;IAC9C,cAAc,EAAE,MAAM,CAAA;IACtB,qFAAqF;IACrF,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,MAAM,EAAE,OAAO,CAAA;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG;IACnD,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,iBAAiB,CAAA;IAC5C,MAAM,EAAE,MAAM,MAAM,CAAA;CACrB,CAcA;AAED,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAY3E;AAED,MAAM,WAAW,cAAc;IAC7B,+EAA+E;IAC/E,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;IACxC,sFAAsF;IACtF,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAA;CAChF;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,cAAc,GACnB;IAAE,aAAa,EAAE,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAkDzF"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Code Mode adoption guard (#35, 2026-10-06).
3
+ *
4
+ * The v2 retirement moved the file/command ladder onto the HOST's native
5
+ * `read` / `grep` / `glob` / `shell`, and the host's `execute` (Code Mode) is the
6
+ * one program that folds N governed calls into a single round-trip. A model that
7
+ * keeps reaching for the native tools one at a time pays N rounds for what one
8
+ * `execute` program answers — the exact inefficiency the retirement was supposed
9
+ * to remove, wearing the opposite face.
10
+ *
11
+ * This is an ADOPTION HINT, not a gate: after a run of consecutive native
12
+ * file/command calls it APPENDS one line to the next result naming `execute`.
13
+ * It never rewrites the body, never touches args, never refuses a call — the
14
+ * same shape as `src/tm/dupe-guard.ts` (append a directive + count + trajectory
15
+ * event), minus the escalation, because a hint that blocks would cost the user
16
+ * the very round it is trying to save.
17
+ *
18
+ * Discipline, copied from the layers beside it:
19
+ * - Team-scoped through the shared `scope.decide` gate — a foreign session's
20
+ * result is nobody's to annotate;
21
+ * - it may NEVER throw into somebody's tool call: a failure is swallowed and
22
+ * COUNTED (`threw`), and the host's verbatim result passes through;
23
+ * - the append is IDEMPOTENT (a marker check), because the host reloads plugins
24
+ * in-process and a replayed hook must not stack two lines.
25
+ */
26
+ /** The native tools whose repeated use is what `execute` folds into one program.
27
+ * A closed list on purpose: `question`, `edit`, `subagent` … are not "one more
28
+ * read", and counting them would make the streak mean nothing. */
29
+ export const NATIVE_CHAIN_TOOLS = new Set(["read", "grep", "glob", "shell"]);
30
+ /** The tool that RESETS the streak: it is the alternative the hint points at, so
31
+ * using it is the behaviour the guard exists to encourage. */
32
+ export const CHAIN_RESET_TOOL = "execute";
33
+ /** Stable marker so a replayed hook cannot append the line twice. */
34
+ export const PROBE_CHAIN_MARKER = "(Code Mode 采用率提示)";
35
+ export const DEFAULT_PROBE_CHAIN_AFTER = 3;
36
+ /**
37
+ * The pure ledger. `threshold` is the number of consecutive native calls after
38
+ * which the NEXT result carries the hint: with the default 3, calls 1-3 are
39
+ * silent and the 4th (and every one after it, until a reset) is advised. A
40
+ * non-chain tool is transparent — it neither counts nor resets — and `execute`
41
+ * resets, because it is the alternative.
42
+ */
43
+ export function createProbeChain(threshold) {
44
+ let count = 0;
45
+ return {
46
+ observe(tool) {
47
+ if (tool === CHAIN_RESET_TOOL) {
48
+ count = 0;
49
+ return { count, advise: false };
50
+ }
51
+ if (!NATIVE_CHAIN_TOOLS.has(tool))
52
+ return { count, advise: false };
53
+ count++;
54
+ return { count, advise: count > threshold };
55
+ },
56
+ streak: () => count,
57
+ };
58
+ }
59
+ /** The appended line, in the tool-output language the tm_* strings use. */
60
+ export function renderProbeChainNote(count) {
61
+ return (`${PROBE_CHAIN_MARKER} 你已经连续 ${count} 次用原生 read/grep/glob/shell 逐个取数——` +
62
+ `这些调用可以折叠成一个 \`execute\`(Code Mode)程序:一次跑完多个受治理调用,只回一份汇总,省下 ${count - 1} 轮。` +
63
+ `下一步:把接下来的多次读取/搜索写进一个 execute 程序。`);
64
+ }
65
+ /**
66
+ * Append the line to the result's first text part, byte-exact otherwise. Returns
67
+ * true only when a line was actually added — an unknown result shape, a missing
68
+ * text part, or an already-marked body all return false (the caller counts the
69
+ * difference). The body is never rewritten: the original text is preserved
70
+ * verbatim and the line is appended after it.
71
+ */
72
+ export function appendProbeChainNote(result, line) {
73
+ const r = result;
74
+ if (!r || !Array.isArray(r.content))
75
+ return false;
76
+ for (const p of r.content) {
77
+ if (!p || typeof p !== "object")
78
+ continue;
79
+ const part = p;
80
+ if (part.type !== "text" || typeof part.text !== "string")
81
+ continue;
82
+ if (part.text.includes(PROBE_CHAIN_MARKER))
83
+ return false;
84
+ part.text = `${part.text}\n\n${line}`;
85
+ return true;
86
+ }
87
+ return false;
88
+ }
89
+ export function applyV2ProbeChain(ctx, deps) {
90
+ const env = deps.env ?? process.env;
91
+ const report = { seen: 0, advised: 0, reset: 0, foreignSkipped: 0, threw: 0 };
92
+ const off = /^(0|false|no|off)$/i.test(String(env.TM_PROBE_CHAIN ?? "").trim());
93
+ const raw = String(env.TM_PROBE_CHAIN_AFTER ?? "").trim();
94
+ const parsed = raw === "" ? DEFAULT_PROBE_CHAIN_AFTER : Number(raw);
95
+ const threshold = Number.isFinite(parsed) ? Math.max(0, Math.floor(parsed)) : DEFAULT_PROBE_CHAIN_AFTER;
96
+ const disabled = off || threshold <= 0;
97
+ const hook = ctx?.tool?.hook;
98
+ if (typeof hook !== "function") {
99
+ // No seam at all: report it rather than pretending the hint is live.
100
+ return { registrations: [], report, active: false };
101
+ }
102
+ const chain = createProbeChain(threshold);
103
+ const reg = hook("execute.after", (rawEvent) => {
104
+ try {
105
+ const event = rawEvent;
106
+ const tool = String(event?.tool ?? "");
107
+ // The owner question comes FIRST: a foreign or unattributable session is
108
+ // left alone no matter which tool it called.
109
+ if (deps.scope) {
110
+ if (deps.scope.count(deps.scope.decide(event)) !== "ours") {
111
+ report.foreignSkipped++;
112
+ return;
113
+ }
114
+ deps.scope.learn(event.agent, event.sessionID);
115
+ }
116
+ if (disabled)
117
+ return;
118
+ if (tool === CHAIN_RESET_TOOL) {
119
+ report.reset++;
120
+ chain.observe(tool);
121
+ return;
122
+ }
123
+ if (!NATIVE_CHAIN_TOOLS.has(tool))
124
+ return;
125
+ report.seen++;
126
+ const verdict = chain.observe(tool);
127
+ if (!verdict.advise)
128
+ return;
129
+ if (!appendProbeChainNote(event.result, renderProbeChainNote(verdict.count)))
130
+ return;
131
+ report.advised++;
132
+ try {
133
+ deps.onAdvise?.({ tool, count: verdict.count, sessionID: event.sessionID });
134
+ }
135
+ catch {
136
+ /* the trajectory is an extra, never a reason to fail the call */
137
+ }
138
+ }
139
+ catch {
140
+ // A governance failure must never break somebody's tool call.
141
+ report.threw++;
142
+ }
143
+ });
144
+ return { registrations: [reg], report, active: !disabled };
145
+ }
146
+ //# sourceMappingURL=v2-probe-chain.js.map