agent-nuvira 3.3.0 → 3.3.3

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 (231) hide show
  1. package/.agents/skills/code-assessment/SKILL.md +10 -1
  2. package/.agents/skills/index.json +1 -1
  3. package/README.md +47 -9
  4. package/dist/agents/agents/runner.d.ts +9 -0
  5. package/dist/agents/agents/runner.d.ts.map +1 -1
  6. package/dist/agents/agents/runner.js +34 -12
  7. package/dist/agents/agents/runner.js.map +1 -1
  8. package/dist/agents/agents/writer-tool-calling.d.ts.map +1 -1
  9. package/dist/agents/agents/writer-tool-calling.js +7 -2
  10. package/dist/agents/agents/writer-tool-calling.js.map +1 -1
  11. package/dist/agents/agents/writer.d.ts.map +1 -1
  12. package/dist/agents/agents/writer.js +7 -1
  13. package/dist/agents/agents/writer.js.map +1 -1
  14. package/dist/agents/artifact-verification.d.ts +102 -0
  15. package/dist/agents/artifact-verification.d.ts.map +1 -0
  16. package/dist/agents/artifact-verification.js +216 -0
  17. package/dist/agents/artifact-verification.js.map +1 -0
  18. package/dist/agents/checkpoint-store.d.ts +73 -0
  19. package/dist/agents/checkpoint-store.d.ts.map +1 -1
  20. package/dist/agents/checkpoint-store.js +161 -0
  21. package/dist/agents/checkpoint-store.js.map +1 -1
  22. package/dist/agents/credential-store.d.ts +120 -0
  23. package/dist/agents/credential-store.d.ts.map +1 -1
  24. package/dist/agents/credential-store.js +358 -19
  25. package/dist/agents/credential-store.js.map +1 -1
  26. package/dist/agents/orchestrator.d.ts +10 -1
  27. package/dist/agents/orchestrator.d.ts.map +1 -1
  28. package/dist/agents/orchestrator.js +234 -75
  29. package/dist/agents/orchestrator.js.map +1 -1
  30. package/dist/agents/phase-engine.d.ts +61 -0
  31. package/dist/agents/phase-engine.d.ts.map +1 -1
  32. package/dist/agents/phase-engine.js +68 -2
  33. package/dist/agents/phase-engine.js.map +1 -1
  34. package/dist/agents/prompt-assembly.d.ts +11 -0
  35. package/dist/agents/prompt-assembly.d.ts.map +1 -1
  36. package/dist/agents/prompt-assembly.js +17 -0
  37. package/dist/agents/prompt-assembly.js.map +1 -1
  38. package/dist/agents/release-preflight.d.ts +121 -0
  39. package/dist/agents/release-preflight.d.ts.map +1 -0
  40. package/dist/agents/release-preflight.js +259 -0
  41. package/dist/agents/release-preflight.js.map +1 -0
  42. package/dist/agents/release-runner.d.ts +157 -0
  43. package/dist/agents/release-runner.d.ts.map +1 -0
  44. package/dist/agents/release-runner.js +719 -0
  45. package/dist/agents/release-runner.js.map +1 -0
  46. package/dist/agents/step-handoff.d.ts +190 -0
  47. package/dist/agents/step-handoff.d.ts.map +1 -0
  48. package/dist/agents/step-handoff.js +443 -0
  49. package/dist/agents/step-handoff.js.map +1 -0
  50. package/dist/cli/benchmark.d.ts.map +1 -1
  51. package/dist/cli/benchmark.js +11 -4
  52. package/dist/cli/benchmark.js.map +1 -1
  53. package/dist/cli/chat.d.ts.map +1 -1
  54. package/dist/cli/chat.js +25 -4
  55. package/dist/cli/chat.js.map +1 -1
  56. package/dist/cli/cli-program.d.ts.map +1 -1
  57. package/dist/cli/cli-program.js +9 -2
  58. package/dist/cli/cli-program.js.map +1 -1
  59. package/dist/cli/commands.d.ts +2 -1
  60. package/dist/cli/commands.d.ts.map +1 -1
  61. package/dist/cli/commands.js +3 -2
  62. package/dist/cli/commands.js.map +1 -1
  63. package/dist/cli/config.js +2 -2
  64. package/dist/cli/config.js.map +1 -1
  65. package/dist/cli/credentials.d.ts +28 -0
  66. package/dist/cli/credentials.d.ts.map +1 -0
  67. package/dist/cli/credentials.js +213 -0
  68. package/dist/cli/credentials.js.map +1 -0
  69. package/dist/cli/dashboard.d.ts +26 -0
  70. package/dist/cli/dashboard.d.ts.map +1 -1
  71. package/dist/cli/dashboard.js +123 -3
  72. package/dist/cli/dashboard.js.map +1 -1
  73. package/dist/cli/failover-runner.d.ts.map +1 -1
  74. package/dist/cli/failover-runner.js +9 -3
  75. package/dist/cli/failover-runner.js.map +1 -1
  76. package/dist/cli/intent.d.ts +1 -1
  77. package/dist/cli/intent.js +2 -2
  78. package/dist/cli/intent.js.map +1 -1
  79. package/dist/cli/loop-executor.d.ts +7 -0
  80. package/dist/cli/loop-executor.d.ts.map +1 -1
  81. package/dist/cli/loop-executor.js +75 -7
  82. package/dist/cli/loop-executor.js.map +1 -1
  83. package/dist/cli/nlu.d.ts.map +1 -1
  84. package/dist/cli/nlu.js +8 -2
  85. package/dist/cli/nlu.js.map +1 -1
  86. package/dist/cli/process-control.d.ts +15 -0
  87. package/dist/cli/process-control.d.ts.map +1 -1
  88. package/dist/cli/process-control.js +38 -14
  89. package/dist/cli/process-control.js.map +1 -1
  90. package/dist/cli/publish.d.ts +22 -0
  91. package/dist/cli/publish.d.ts.map +1 -1
  92. package/dist/cli/publish.js +109 -13
  93. package/dist/cli/publish.js.map +1 -1
  94. package/dist/config/live-credentials.d.ts +57 -0
  95. package/dist/config/live-credentials.d.ts.map +1 -0
  96. package/dist/config/live-credentials.js +126 -0
  97. package/dist/config/live-credentials.js.map +1 -0
  98. package/dist/config/paths.d.ts +18 -0
  99. package/dist/config/paths.d.ts.map +1 -1
  100. package/dist/config/paths.js +25 -0
  101. package/dist/config/paths.js.map +1 -1
  102. package/dist/federation/a2a-types.js +1 -1
  103. package/dist/federation/a2a-types.js.map +1 -1
  104. package/dist/forwarded.d.ts +2 -0
  105. package/dist/forwarded.d.ts.map +1 -0
  106. package/dist/forwarded.js +2 -0
  107. package/dist/forwarded.js.map +1 -0
  108. package/dist/inference/model-validator.d.ts +6 -1
  109. package/dist/inference/model-validator.d.ts.map +1 -1
  110. package/dist/inference/model-validator.js +7 -2
  111. package/dist/inference/model-validator.js.map +1 -1
  112. package/dist/inference/route-resolver.d.ts +116 -0
  113. package/dist/inference/route-resolver.d.ts.map +1 -0
  114. package/dist/inference/route-resolver.js +159 -0
  115. package/dist/inference/route-resolver.js.map +1 -0
  116. package/dist/inference/tool-call-utils.d.ts +44 -0
  117. package/dist/inference/tool-call-utils.d.ts.map +1 -1
  118. package/dist/inference/tool-call-utils.js +126 -4
  119. package/dist/inference/tool-call-utils.js.map +1 -1
  120. package/dist/learning/autonomy-policy.d.ts +24 -0
  121. package/dist/learning/autonomy-policy.d.ts.map +1 -1
  122. package/dist/learning/autonomy-policy.js +110 -23
  123. package/dist/learning/autonomy-policy.js.map +1 -1
  124. package/dist/learning/eval-framework.d.ts +24 -0
  125. package/dist/learning/eval-framework.d.ts.map +1 -1
  126. package/dist/learning/eval-framework.js +291 -0
  127. package/dist/learning/eval-framework.js.map +1 -1
  128. package/dist/learning/intent-envelope.d.ts +162 -0
  129. package/dist/learning/intent-envelope.d.ts.map +1 -0
  130. package/dist/learning/intent-envelope.js +235 -0
  131. package/dist/learning/intent-envelope.js.map +1 -0
  132. package/dist/learning/reasoning-trace.d.ts +2 -2
  133. package/dist/learning/reasoning-trace.d.ts.map +1 -1
  134. package/dist/learning/reasoning-trace.js +25 -1
  135. package/dist/learning/reasoning-trace.js.map +1 -1
  136. package/dist/learning/resilient-call.d.ts.map +1 -1
  137. package/dist/learning/resilient-call.js +29 -17
  138. package/dist/learning/resilient-call.js.map +1 -1
  139. package/dist/learning/run-trace.d.ts +164 -0
  140. package/dist/learning/run-trace.d.ts.map +1 -0
  141. package/dist/learning/run-trace.js +342 -0
  142. package/dist/learning/run-trace.js.map +1 -0
  143. package/dist/learning/skill-store.d.ts.map +1 -1
  144. package/dist/learning/skill-store.js +35 -10
  145. package/dist/learning/skill-store.js.map +1 -1
  146. package/dist/learning/skill-types.d.ts +14 -0
  147. package/dist/learning/skill-types.d.ts.map +1 -1
  148. package/dist/learning/skill-types.js +19 -0
  149. package/dist/learning/skill-types.js.map +1 -1
  150. package/dist/mcp/catalog.js +2 -3
  151. package/dist/mcp/catalog.js.map +1 -1
  152. package/dist/mcp/manager.d.ts.map +1 -1
  153. package/dist/mcp/manager.js +5 -3
  154. package/dist/mcp/manager.js.map +1 -1
  155. package/dist/resources/command-manifest.json +10 -10
  156. package/dist/skills/bundled-skills.d.ts.map +1 -1
  157. package/dist/skills/bundled-skills.js +13 -2
  158. package/dist/skills/bundled-skills.js.map +1 -1
  159. package/dist/skills/secret-capture.d.ts.map +1 -1
  160. package/dist/skills/secret-capture.js +9 -4
  161. package/dist/skills/secret-capture.js.map +1 -1
  162. package/dist/tools/coding-tools.d.ts.map +1 -1
  163. package/dist/tools/coding-tools.js +33 -8
  164. package/dist/tools/coding-tools.js.map +1 -1
  165. package/dist/tools/credentials-tool.d.ts +24 -0
  166. package/dist/tools/credentials-tool.d.ts.map +1 -0
  167. package/dist/tools/credentials-tool.js +125 -0
  168. package/dist/tools/credentials-tool.js.map +1 -0
  169. package/dist/tools/edit-verification.d.ts +78 -0
  170. package/dist/tools/edit-verification.d.ts.map +1 -1
  171. package/dist/tools/edit-verification.js +213 -16
  172. package/dist/tools/edit-verification.js.map +1 -1
  173. package/dist/tools/git-tool.d.ts +25 -7
  174. package/dist/tools/git-tool.d.ts.map +1 -1
  175. package/dist/tools/git-tool.js +155 -15
  176. package/dist/tools/git-tool.js.map +1 -1
  177. package/dist/tools/loop-project-context.d.ts.map +1 -1
  178. package/dist/tools/loop-project-context.js +16 -0
  179. package/dist/tools/loop-project-context.js.map +1 -1
  180. package/dist/tools/loop-route-feed.d.ts +57 -0
  181. package/dist/tools/loop-route-feed.d.ts.map +1 -0
  182. package/dist/tools/loop-route-feed.js +101 -0
  183. package/dist/tools/loop-route-feed.js.map +1 -0
  184. package/dist/tools/pipeline-tool.d.ts.map +1 -1
  185. package/dist/tools/pipeline-tool.js +8 -2
  186. package/dist/tools/pipeline-tool.js.map +1 -1
  187. package/dist/tools/publish-tool.d.ts.map +1 -1
  188. package/dist/tools/publish-tool.js +76 -10
  189. package/dist/tools/publish-tool.js.map +1 -1
  190. package/dist/tools/registry.d.ts +52 -3
  191. package/dist/tools/registry.d.ts.map +1 -1
  192. package/dist/tools/registry.js +88 -11
  193. package/dist/tools/registry.js.map +1 -1
  194. package/dist/tools/run-cli.d.ts.map +1 -1
  195. package/dist/tools/run-cli.js +15 -2
  196. package/dist/tools/run-cli.js.map +1 -1
  197. package/dist/tools/run-terminal.d.ts +9 -0
  198. package/dist/tools/run-terminal.d.ts.map +1 -1
  199. package/dist/tools/run-terminal.js +103 -6
  200. package/dist/tools/run-terminal.js.map +1 -1
  201. package/dist/tools/skill-tool.d.ts.map +1 -1
  202. package/dist/tools/skill-tool.js +5 -0
  203. package/dist/tools/skill-tool.js.map +1 -1
  204. package/dist/tools/tool-loop.d.ts +40 -6
  205. package/dist/tools/tool-loop.d.ts.map +1 -1
  206. package/dist/tools/tool-loop.js +409 -14
  207. package/dist/tools/tool-loop.js.map +1 -1
  208. package/dist/tools/toolsets.js +2 -2
  209. package/dist/tools/toolsets.js.map +1 -1
  210. package/dist/web-dashboard/chat-console.d.ts +5 -0
  211. package/dist/web-dashboard/chat-console.d.ts.map +1 -1
  212. package/dist/web-dashboard/chat-console.js +32 -3
  213. package/dist/web-dashboard/chat-console.js.map +1 -1
  214. package/dist/web-dashboard/server.d.ts +46 -0
  215. package/dist/web-dashboard/server.d.ts.map +1 -1
  216. package/dist/web-dashboard/server.js +115 -1
  217. package/dist/web-dashboard/server.js.map +1 -1
  218. package/dist/web-dashboard/src/admin-auth.d.ts +49 -2
  219. package/dist/web-dashboard/src/admin-auth.d.ts.map +1 -1
  220. package/dist/web-dashboard/src/admin-auth.js +64 -3
  221. package/dist/web-dashboard/src/admin-auth.js.map +1 -1
  222. package/dist/web-dashboard/src/types.d.ts +41 -0
  223. package/dist/web-dashboard/src/types.d.ts.map +1 -1
  224. package/dist/workflow/registry.js +1 -1
  225. package/dist/workflow/registry.js.map +1 -1
  226. package/package.json +9 -5
  227. package/src/web-dashboard/public/assets/index-CxDj7p6i.js +207 -0
  228. package/src/web-dashboard/public/assets/index-CxDj7p6i.js.map +1 -0
  229. package/src/web-dashboard/public/index.html +1 -1
  230. package/src/web-dashboard/public/assets/index-kCUkORm7.js +0 -207
  231. package/src/web-dashboard/public/assets/index-kCUkORm7.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"loop-project-context.d.ts","sourceRoot":"","sources":["../../src/tools/loop-project-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAuBH,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAgBrD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAwCrD;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiD1E"}
1
+ {"version":3,"file":"loop-project-context.d.ts","sourceRoot":"","sources":["../../src/tools/loop-project-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAwBH,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAgBrD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAwCrD;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA+D1E"}
@@ -29,6 +29,7 @@ import { existsSync, readdirSync, statSync } from 'node:fs';
29
29
  import { join } from 'node:path';
30
30
  import { buildGitStateDigest } from './git-digest.js';
31
31
  import { assessProject } from '../agents/prompt-assembly.js';
32
+ import { handoffBlockFor } from '../agents/step-handoff.js';
32
33
  /** Hard budget: the tree block is truncated to this many lines (~1.5K tokens). */
33
34
  const MAX_TREE_LINES = 60;
34
35
  /** Max tree depth (BFS) — deep node_modules-style nesting is noise at this budget. */
@@ -143,6 +144,21 @@ export async function buildLoopProjectContext(dir) {
143
144
  catch {
144
145
  lines.push('## Project', `- path: ${dir}`);
145
146
  }
147
+ // ── Unfinished work from earlier attempts in this project ──
148
+ // The loop engine re-reads the tree and re-plans on every turn, so without
149
+ // this a repeated or reworded ask restarts from zero even when a previous
150
+ // attempt already put half the deliverable on disk (see step-handoff.ts).
151
+ // Read and reconciled on EVERY context build, not only on an explicit
152
+ // resume. Self-labelled and self-bounded, so it is pushed as-is; a clean
153
+ // project adds nothing.
154
+ try {
155
+ const handoff = handoffBlockFor(dir);
156
+ if (handoff)
157
+ lines.push('## Unfinished work (hand-off)', handoff);
158
+ }
159
+ catch {
160
+ // Hand-off read is best-effort — omit on failure.
161
+ }
146
162
  // ── Bounded file tree ──
147
163
  try {
148
164
  const treeLines = walkBoundedTree(dir);
@@ -1 +1 @@
1
- {"version":3,"file":"loop-project-context.js","sourceRoot":"","sources":["../../src/tools/loop-project-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loop-project-context.js","sourceRoot":"","sources":["../../src/tools/loop-project-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * The route feed — what the model is TOLD about the model that is serving it.
3
+ *
4
+ * WHY THIS EXISTS. The loop's system prompt describes the tool surface, the
5
+ * project, and the contract, and it says nothing about the route. So when a user
6
+ * asks "which model are you?" — or when the model narrates its own run — the only
7
+ * available answers are a guess, the user's config (`nuviraconfig.json`, which is
8
+ * what the ROUTER reads, not what answered), or a model name from its own
9
+ * training data. All three are fabrications. On this machine the config pins
10
+ * `providers.groq.model = openai/gpt-oss-120b` while a run can be served by a
11
+ * Gemini model, a repaired replacement, or a local model after a failover; a
12
+ * model that answers from config is simply wrong, and confidently so.
13
+ *
14
+ * The fix is the one this repo already applies to every other claim: state the
15
+ * fact that was measured, at the moment it was measured. The loop re-reads this
16
+ * feed BEFORE EVERY MODEL CALL, so a mid-turn failover cannot leave the model
17
+ * believing it is still something it stopped being three steps ago.
18
+ *
19
+ * The rules that make it honest rather than decorative:
20
+ * - It is generated from the resolver's own result, never from config.
21
+ * - Unknown stays unknown: an unresolved route says so and forbids inventing one.
22
+ * - A substitution is NAMED, in both directions, because "the router quietly ran
23
+ * you on something else" is the defect (see the route resolver).
24
+ * - It tells the model what to do with the fact (answer from this line; if a user
25
+ * asks, quote it), because a fact with no instruction is a fact the model
26
+ * paraphrases into something else.
27
+ */
28
+ import type { ServedRoute } from '../inference/route-resolver.js';
29
+ /** Marker that identifies the feed inside the thread (used to replace it). */
30
+ export declare const ROUTE_FEED_MARKER = "ROUTE \u2014 what is actually serving this turn";
31
+ export declare function isUnresolvedModel(model: string | undefined): boolean;
32
+ /**
33
+ * The thread frame.
34
+ *
35
+ * `requested`/`substituted` and `previous` are all optional because they are all
36
+ * facts that may not exist yet; the frame degrades to fewer true lines rather
37
+ * than filling gaps.
38
+ */
39
+ export declare function routeFeedText(route: ServedRoute): string;
40
+ /**
41
+ * Record a NEW serving route, carrying the ones it replaced (bounded).
42
+ *
43
+ * The history is what turns "you are on local/gemma4:e4b" into the honest
44
+ * "steps 1-3 were answered by groq/openai/gpt-oss-120b, then it failed over" — a
45
+ * model told only the current pair will happily describe the whole turn as
46
+ * having been run by it.
47
+ */
48
+ export declare function noteServedRoute(previous: ServedRoute | null, next: ServedRoute): ServedRoute;
49
+ /** Cap on remembered serving pairs — enough for a turn's failovers, not a log. */
50
+ export declare const MAX_ROUTE_HISTORY = 4;
51
+ /**
52
+ * Identity of a feed, for change detection. Two feeds with the same fingerprint
53
+ * render the same text, so the loop can skip a rewrite instead of churning the
54
+ * thread on every step.
55
+ */
56
+ export declare function routeFeedFingerprint(route: ServedRoute | null | undefined): string;
57
+ //# sourceMappingURL=loop-route-feed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loop-route-feed.d.ts","sourceRoot":"","sources":["../../src/tools/loop-route-feed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAElE,8EAA8E;AAC9E,eAAO,MAAM,iBAAiB,oDAA+C,CAAC;AAK9E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEpE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CA0BxD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI,EAAE,IAAI,EAAE,WAAW,GAAG,WAAW,CAS5F;AAED,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAUlF"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * The route feed — what the model is TOLD about the model that is serving it.
3
+ *
4
+ * WHY THIS EXISTS. The loop's system prompt describes the tool surface, the
5
+ * project, and the contract, and it says nothing about the route. So when a user
6
+ * asks "which model are you?" — or when the model narrates its own run — the only
7
+ * available answers are a guess, the user's config (`nuviraconfig.json`, which is
8
+ * what the ROUTER reads, not what answered), or a model name from its own
9
+ * training data. All three are fabrications. On this machine the config pins
10
+ * `providers.groq.model = openai/gpt-oss-120b` while a run can be served by a
11
+ * Gemini model, a repaired replacement, or a local model after a failover; a
12
+ * model that answers from config is simply wrong, and confidently so.
13
+ *
14
+ * The fix is the one this repo already applies to every other claim: state the
15
+ * fact that was measured, at the moment it was measured. The loop re-reads this
16
+ * feed BEFORE EVERY MODEL CALL, so a mid-turn failover cannot leave the model
17
+ * believing it is still something it stopped being three steps ago.
18
+ *
19
+ * The rules that make it honest rather than decorative:
20
+ * - It is generated from the resolver's own result, never from config.
21
+ * - Unknown stays unknown: an unresolved route says so and forbids inventing one.
22
+ * - A substitution is NAMED, in both directions, because "the router quietly ran
23
+ * you on something else" is the defect (see the route resolver).
24
+ * - It tells the model what to do with the fact (answer from this line; if a user
25
+ * asks, quote it), because a fact with no instruction is a fact the model
26
+ * paraphrases into something else.
27
+ */
28
+ /** Marker that identifies the feed inside the thread (used to replace it). */
29
+ export const ROUTE_FEED_MARKER = 'ROUTE — what is actually serving this turn';
30
+ /** Sentinel model values that mean "nothing was resolved". */
31
+ const UNRESOLVED = new Set(['', 'default', 'auto', 'unknown', 'undefined']);
32
+ export function isUnresolvedModel(model) {
33
+ return !model || UNRESOLVED.has(model);
34
+ }
35
+ /**
36
+ * The thread frame.
37
+ *
38
+ * `requested`/`substituted` and `previous` are all optional because they are all
39
+ * facts that may not exist yet; the frame degrades to fewer true lines rather
40
+ * than filling gaps.
41
+ */
42
+ export function routeFeedText(route) {
43
+ const lines = [ROUTE_FEED_MARKER + ' (measured by the resolver, not a guess):'];
44
+ lines.push(`- provider: ${route.providerType || 'unknown'}${route.providerName && route.providerName !== route.providerType ? ` (${route.providerName})` : ''}`);
45
+ if (isUnresolvedModel(route.model)) {
46
+ lines.push('- model: UNRESOLVED — the provider chooses at call time. You do NOT know which model is answering.');
47
+ }
48
+ else {
49
+ lines.push(`- model: ${route.model}`);
50
+ }
51
+ if (route.requested && route.substituted) {
52
+ lines.push(`- requested: ${route.requested} → NOT available on ${route.providerType}; the router substituted ${route.model}. Say it that way if it comes up.`);
53
+ }
54
+ else if (route.requested && !route.substituted) {
55
+ lines.push(`- requested: ${route.requested} (served as asked)`);
56
+ }
57
+ if (route.previous && route.previous.length > 0) {
58
+ lines.push(`- earlier in this turn: ${route.previous.join(', ')} (a failover moved the work; the newest line above is the truth)`);
59
+ }
60
+ lines.push('- If the user asks which model/provider you are, answer from THIS line. If it says UNRESOLVED, say the route is unresolved — do not name a model from memory, from the user\'s config, or from an earlier step, and do not claim a model you have not been told about.');
61
+ return lines.join('\n');
62
+ }
63
+ /**
64
+ * Record a NEW serving route, carrying the ones it replaced (bounded).
65
+ *
66
+ * The history is what turns "you are on local/gemma4:e4b" into the honest
67
+ * "steps 1-3 were answered by groq/openai/gpt-oss-120b, then it failed over" — a
68
+ * model told only the current pair will happily describe the whole turn as
69
+ * having been run by it.
70
+ */
71
+ export function noteServedRoute(previous, next) {
72
+ const history = [...(previous?.previous ?? [])];
73
+ if (previous && !isUnresolvedModel(previous.model)) {
74
+ const pair = `${previous.providerType}/${previous.model}`;
75
+ const current = `${next.providerType}/${next.model}`;
76
+ if (pair !== current && !history.includes(pair))
77
+ history.push(pair);
78
+ }
79
+ const bounded = history.slice(-MAX_ROUTE_HISTORY);
80
+ return bounded.length > 0 ? { ...next, previous: bounded } : next;
81
+ }
82
+ /** Cap on remembered serving pairs — enough for a turn's failovers, not a log. */
83
+ export const MAX_ROUTE_HISTORY = 4;
84
+ /**
85
+ * Identity of a feed, for change detection. Two feeds with the same fingerprint
86
+ * render the same text, so the loop can skip a rewrite instead of churning the
87
+ * thread on every step.
88
+ */
89
+ export function routeFeedFingerprint(route) {
90
+ if (!route)
91
+ return '';
92
+ return [
93
+ route.providerType || '',
94
+ route.providerName || '',
95
+ route.model || '',
96
+ route.requested || '',
97
+ route.substituted ? '1' : '0',
98
+ (route.previous || []).join('>'),
99
+ ].join('|');
100
+ }
101
+ //# sourceMappingURL=loop-route-feed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loop-route-feed.js","sourceRoot":"","sources":["../../src/tools/loop-route-feed.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline-tool.d.ts","sourceRoot":"","sources":["../../src/tools/pipeline-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,EAAgB,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAOnF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,uCAAuC;AACvC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,+BAA+B;IAC/B,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,yCAAyC;AACzC,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,gEAAgE;IAChE,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,GAAG,EAClB,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,kBAAkB,CAAC,CAyH7B;AAED,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAYxE;AA0BD;;;;GAIG;AACH,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,MAAM,CAAC,CAoBjB"}
1
+ {"version":3,"file":"pipeline-tool.d.ts","sourceRoot":"","sources":["../../src/tools/pipeline-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,EAAgB,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAOnF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,uCAAuC;AACvC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,+BAA+B;IAC/B,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,yCAAyC;AACzC,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,gEAAgE;IAChE,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,GAAG,EAClB,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,kBAAkB,CAAC,CA+H7B;AAED,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAYxE;AA0BD;;;;GAIG;AACH,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,MAAM,CAAC,CAoBjB"}
@@ -16,7 +16,7 @@
16
16
  * board, and D1 recall wiring for `continue` (mode 'recall').
17
17
  */
18
18
  import { resolveProvider } from '../cli/router.js';
19
- import { resolveWorkingModel } from '../inference/model-validator.js';
19
+ import { resolveRoute } from '../inference/route-resolver.js';
20
20
  import { getAutoRouter, isAutoProvider, isAutoModel } from '../learning/auto-router.js';
21
21
  import { Orchestrator } from '../agents/orchestrator.js';
22
22
  import { getEventBus, EventNames } from '../observability/event-bus.js';
@@ -46,7 +46,13 @@ export async function runPipelineTool(goal, configManager, opts) {
46
46
  const decision = getAutoRouter().resolve('chat', goal, { verbose: true, useRuntimeStats: true }, configManager);
47
47
  const resolved = resolveProvider(configManager, decision.provider);
48
48
  provider = resolved.type;
49
- model = await resolveWorkingModel(resolved.provider, decision.provider, decision.model);
49
+ model = (await resolveRoute({
50
+ providerType: decision.provider,
51
+ provider: resolved.provider,
52
+ model: decision.model,
53
+ source: 'cli',
54
+ task: goal,
55
+ })).model;
50
56
  }
51
57
  catch (err) {
52
58
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline-tool.js","sourceRoot":"","sources":["../../src/tools/pipeline-tool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pipeline-tool.js","sourceRoot":"","sources":["../../src/tools/pipeline-tool.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"publish-tool.d.ts","sourceRoot":"","sources":["../../src/tools/publish-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAajD;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAgGrF"}
1
+ {"version":3,"file":"publish-tool.d.ts","sourceRoot":"","sources":["../../src/tools/publish-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAUH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAkCjD;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA2IrF"}
@@ -15,15 +15,38 @@
15
15
  * - `dry_run: true` previews the phases without touching anything.
16
16
  * - Returns a summary text fed back to the model (never throws).
17
17
  */
18
+ import { readFileSync } from 'node:fs';
19
+ import { join } from 'node:path';
18
20
  import { CredentialStore } from '../agents/credential-store.js';
19
21
  import { Orchestrator } from '../agents/orchestrator.js';
20
22
  import { buildPublishPhases } from '../cli/publish.js';
23
+ import { maskSecret } from '../enterprise/secrets.js';
21
24
  import { logger } from '../utils/logger.js';
25
+ /**
26
+ * One masked line naming the credentials the release will ACTUALLY use.
27
+ *
28
+ * The failure this exists to prevent: a release ran its whole pipeline and
29
+ * reported "complete" while holding no credentials at all, so every push and
30
+ * publish silently no-opped. Saying which token is in play (masked — never the
31
+ * value) makes that state visible in the tool result the model reads back.
32
+ */
33
+ function describeReleaseCredentials(store) {
34
+ const gitToken = store.git?.token;
35
+ const sshKey = store.git?.sshKeyPath;
36
+ const npmToken = store.npm?.token;
37
+ const parts = [
38
+ gitToken ? `git ✓ (${maskSecret(gitToken)})` : sshKey ? 'git ✓ (ssh key)' : 'git ✗',
39
+ npmToken ? `npm ✓ (${maskSecret(npmToken)})` : 'npm ✗',
40
+ ];
41
+ return `🔑 Credentials: ${parts.join(' ')}`;
42
+ }
22
43
  /** P5a — post-publish release-sync (website/docs kept at release level). */
23
44
  function currentPackageVersion() {
24
45
  try {
25
- const { readFileSync } = require('node:fs');
26
- const raw = readFileSync(require('node:path').join(process.cwd(), 'package.json'), 'utf-8');
46
+ // Static ESM imports — the previous inline `require('node:fs')` threw
47
+ // `require is not defined` in the published build, and because this sits in
48
+ // a try/catch the version silently read as '' rather than failing loudly.
49
+ const raw = readFileSync(join(process.cwd(), 'package.json'), 'utf-8');
27
50
  return JSON.parse(raw).version ?? '';
28
51
  }
29
52
  catch {
@@ -51,20 +74,53 @@ export async function runPublishTool(args, ctx) {
51
74
  ].join('\n');
52
75
  }
53
76
  if (!dry_run) {
54
- // Set up the detected credentials for the session (best-effort — the CLI
55
- // does the same before running phases).
77
+ // NON-INTERACTIVE init FIRST. `setupGitCredentials()` / `setupNpmAuth()`
78
+ // both refuse to run until the store is collected, and this tool never
79
+ // prompts — so before `initialize()` existed these two calls threw on
80
+ // every tool-driven release AND a single shared try/catch hid the pair.
81
+ // The pipeline then ran with no credentials while reporting success.
82
+ credStore.initialize();
83
+ // Separate catches: a failure to set up git auth must not swallow the npm
84
+ // one (and vice versa) — that is exactly how the pair went missing before.
56
85
  try {
57
86
  credStore.setupGitCredentials();
87
+ }
88
+ catch (err) {
89
+ logger.warn(` ⚠️ Git credential setup issue: ${err}`);
90
+ }
91
+ try {
58
92
  credStore.setupNpmAuth();
59
93
  }
60
94
  catch (err) {
61
- logger.warn(` ⚠️ Credential setup issue: ${err}`);
95
+ logger.warn(` ⚠️ npm credential setup issue: ${err}`);
62
96
  }
63
97
  }
64
98
  const phases = buildPublishPhases(bump, skip_tests, {
65
99
  git: credStore.git,
66
100
  npm: credStore.npm,
67
101
  });
102
+ // ── PREFLIGHT before anything irreversible ───────────────────────────────
103
+ // The same checks the CLI runs, for the same reason: a tool-driven release is
104
+ // MORE likely to be unattended, so starting one that cannot finish is worse
105
+ // here than at a terminal. Non-interactive by construction — a definitive
106
+ // blocker is reported back to the model, which can fix it or ask the user;
107
+ // "unanswerable" (offline) warns and proceeds.
108
+ if (!dry_run) {
109
+ const { runReleasePreflight, formatPreflight } = await import('../agents/release-preflight.js');
110
+ const { bumpVersionString, readVersion } = await import('../agents/release-runner.js');
111
+ const current = readVersion();
112
+ const targetVersion = current ? bumpVersionString(current, bump) : '';
113
+ const needsModel = phases.some((p) => !p.runner);
114
+ const preflight = await runReleasePreflight({ targetVersion, needsModel });
115
+ if (preflight.blocked) {
116
+ return [
117
+ formatPreflight(preflight),
118
+ '',
119
+ '❌ The release was NOT started: the checks above are definitive, so nothing was committed, tagged or published.',
120
+ ' Fix the blocker (or bump to a free version) and call this tool again.',
121
+ ].join('\n');
122
+ }
123
+ }
68
124
  if (dry_run) {
69
125
  return [
70
126
  `📋 Publish DRY RUN — "${publishGoal}" (${bump} bump)`,
@@ -73,7 +129,12 @@ export async function runPublishTool(args, ctx) {
73
129
  ].join('\n');
74
130
  }
75
131
  const orchestrator = new Orchestrator(ctx.configManager);
76
- const lines = [];
132
+ const lines = [
133
+ // State the credentials up front, so the model (and the user reading the
134
+ // transcript) can see a release that is about to no-op for want of a token
135
+ // BEFORE it reports itself complete.
136
+ describeReleaseCredentials(credStore),
137
+ ];
77
138
  let hasFailure = false;
78
139
  // P5a — capture the PRE-publish version so a post-publish sync check can
79
140
  // diff the release markers against what was actually bumped.
@@ -82,10 +143,15 @@ export async function runPublishTool(args, ctx) {
82
143
  const phase = phases[i];
83
144
  lines.push(`📦 ${i + 1}/${phases.length}: ${phase.description}`);
84
145
  try {
85
- const result = await orchestrator.execute(phase.goal, {
86
- verbose: false,
87
- skipTests: skip_tests,
88
- });
146
+ // A phase with a runner is a mechanical step with a known-correct
147
+ // outcome (bump, tag, push, publish) and runs deterministically; only a
148
+ // phase without one needs the orchestrator to plan it.
149
+ const result = phase.runner
150
+ ? await phase.runner()
151
+ : await orchestrator.execute(phase.goal, {
152
+ verbose: false,
153
+ skipTests: skip_tests,
154
+ });
89
155
  if (result.success) {
90
156
  lines.push(` ✅ ${result.summary ? result.summary.slice(0, 120) : 'completed'}`);
91
157
  }
@@ -1 +1 @@
1
- {"version":3,"file":"publish-tool.js","sourceRoot":"","sources":["../../src/tools/publish-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAG5C,4EAA4E;AAC5E,SAAS,qBAAqB;IAC5B,IAAI,CAAC;QACH,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,SAAS,CAA6B,CAAC;QACxE,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC;QAC5F,OAAQ,IAAI,CAAC,KAAK,CAAC,GAAG,CAA0B,CAAC,OAAO,IAAI,EAAE,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAa,EAAE,GAAgB;IAClE,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;IAC5D,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1E,MAAM,WAAW,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,WAAW,IAAI,UAAU,CAAC;IAE9D,kEAAkE;IAClE,8DAA8D;IAC9D,MAAM,SAAS,GAAG,IAAI,eAAe,EAAE,CAAC;IAExC,IAAI,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;QAC5D,OAAO;YACL,6EAA6E;YAC7E,kEAAkE;YAClE,0FAA0F;YAC1F,+CAA+C;SAChD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,yEAAyE;QACzE,wCAAwC;QACxC,IAAI,CAAC;YACH,SAAS,CAAC,mBAAmB,EAAE,CAAC;YAChC,SAAS,CAAC,YAAY,EAAE,CAAC;QAC3B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,CAAC,iCAAiC,GAAG,EAAE,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,EAAE,UAAU,EAAE;QAClD,GAAG,EAAE,SAAS,CAAC,GAAG;QAClB,GAAG,EAAE,SAAS,CAAC,GAAG;KACnB,CAAC,CAAC;IAEH,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO;YACL,yBAAyB,WAAW,MAAM,IAAI,QAAQ;YACtD,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;YACrE,2BAA2B;SAC5B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACzD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,yEAAyE;IACzE,6DAA6D;IAC7D,MAAM,oBAAoB,GAAG,qBAAqB,EAAE,CAAC;IAErD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QACjE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE;gBACpD,OAAO,EAAE,KAAK;gBACd,SAAS,EAAE,UAAU;aACtB,CAAC,CAAC;YACH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,KAAK,CAAC,IAAI,CAAC,QAAQ,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;YACpF,CAAC;iBAAM,CAAC;gBACN,UAAU,GAAG,IAAI,CAAC;gBAClB,KAAK,CAAC,IAAI,CAAC,QAAQ,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC7E,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,UAAU,GAAG,IAAI,CAAC;YAClB,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,KAAK,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YACxC,MAAM;QACR,CAAC;IACH,CAAC;IAED,SAAS,CAAC,OAAO,EAAE,CAAC;IAEpB,6EAA6E;IAC7E,4EAA4E;IAC5E,0EAA0E;IAC1E,yDAAyD;IACzD,IAAI,QAAQ,GAAkB,IAAI,CAAC;IACnC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;YAC7D,MAAM,SAAS,GAAG,qBAAqB,EAAE,IAAI,oBAAoB,CAAC;YAClE,QAAQ,GAAG,cAAc,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YAC1C,IAAI,oBAAoB;gBAAE,KAAK,CAAC,IAAI,CAAC,+BAA+B,oBAAoB,EAAE,CAAC,CAAC;QAC9F,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,GAAG,IAAI,CAAC,CAAC,gDAAgD;QACnE,CAAC;IACH,CAAC;IAED,OAAO;QACL,UAAU;YACR,CAAC,CAAC,gBAAgB,WAAW,4BAA4B,MAAM,CAAC,MAAM,UAAU;YAChF,CAAC,CAAC,eAAe,WAAW,eAAe,MAAM,CAAC,MAAM,UAAU;QACpE,GAAG,KAAK;QACR,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAChC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"publish-tool.js","sourceRoot":"","sources":["../../src/tools/publish-tool.ts"],"names":[],"mappings":"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"}
@@ -108,6 +108,35 @@ export interface ToolContext {
108
108
  * its original confirm-or-refuse behaviour exactly.
109
109
  */
110
110
  authorizationRequest?: string;
111
+ /**
112
+ * The approved INTENT ENVELOPE for this conversation — the durable, scoped
113
+ * grant that replaced per-action permission (see
114
+ * `learning/intent-envelope.ts`).
115
+ *
116
+ * `writesAuthorized` answers "does the last message ask for files?" and is
117
+ * recomputed every turn, so it forgets an approval the moment the next
118
+ * message arrives. The envelope does not: it is granted once (a directive
119
+ * request, or — the high-trust path — the user approving a plan) and lives
120
+ * for the conversation, so inside it reversible work executes with no
121
+ * prompt while `external` and `destructive` actions still ask.
122
+ *
123
+ * Absent/`null` (no loop, a direct tool call, a test) keeps every gate's
124
+ * original confirm-or-refuse behaviour exactly.
125
+ */
126
+ envelope?: import('../learning/intent-envelope.js').IntentEnvelope | null;
127
+ /**
128
+ * The run's OWN behaviour — every question asked, every refusal, every
129
+ * mutation — so a gate can refuse to RE-ASK a question the user already
130
+ * answered (see `learning/run-trace.ts`).
131
+ *
132
+ * The envelope answers "what may I do"; the trace answers "what have I been
133
+ * doing". Without it the loop could not notice its own repetition (nothing
134
+ * counted it), could not stop it, and could not answer the user asking why it
135
+ * was repeating — the three failures of the live audit, which are one failure.
136
+ *
137
+ * Absent (a direct tool call, a test) keeps every gate's original behaviour.
138
+ */
139
+ runTrace?: import('../learning/run-trace.js').RunTrace;
111
140
  /** Emit an event on the observability bus (for pipeline runs). */
112
141
  emit?: (event: string, data: unknown, source?: string) => void;
113
142
  /** LLM call fn for C2 verify (resolved provider already chosen). */
@@ -223,6 +252,22 @@ export declare const publishToolSchema: z.ZodObject<{
223
252
  dry_run: z.ZodDefault<z.ZodBoolean>;
224
253
  skip_tests: z.ZodDefault<z.ZodBoolean>;
225
254
  }, z.core.$strip>;
255
+ /**
256
+ * Release credentials (store/status/forget/verify) — the E3c publish tool can
257
+ * only release with a GitHub and an npm token, and this is how the agent keeps
258
+ * them. Storing is NOT an irreversible external action, so it is not gated —
259
+ * but the VALUE must come from the user: `ask_user` for it, never invent one.
260
+ */
261
+ export declare const credentialsToolSchema: z.ZodObject<{
262
+ action: z.ZodDefault<z.ZodEnum<{
263
+ store: "store";
264
+ status: "status";
265
+ verify: "verify";
266
+ forget: "forget";
267
+ }>>;
268
+ key: z.ZodOptional<z.ZodString>;
269
+ value: z.ZodOptional<z.ZodString>;
270
+ }, z.core.$strip>;
226
271
  /** E3g — gateway message delivery: target + text + optional media (model-decides vocabulary). */
227
272
  export declare const gatewaySendSchema: z.ZodObject<{
228
273
  target: z.ZodString;
@@ -235,9 +280,10 @@ export declare const runCliSchema: z.ZodObject<{
235
280
  ask: z.ZodString;
236
281
  confirm: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
237
282
  }, z.core.$strip>;
238
- /** P3b — gated git args: structured status/log/diff/commit. */
283
+ /** P3b — gated git args: structured status/log/diff/commit, plus the gated push. */
239
284
  export declare const gitToolSchema: z.ZodObject<{
240
285
  action: z.ZodEnum<{
286
+ push: "push";
241
287
  status: "status";
242
288
  log: "log";
243
289
  diff: "diff";
@@ -247,6 +293,9 @@ export declare const gitToolSchema: z.ZodObject<{
247
293
  files: z.ZodOptional<z.ZodArray<z.ZodString>>;
248
294
  confirm: z.ZodDefault<z.ZodBoolean>;
249
295
  limit: z.ZodOptional<z.ZodNumber>;
296
+ remote: z.ZodOptional<z.ZodString>;
297
+ branch: z.ZodOptional<z.ZodString>;
298
+ tags: z.ZodDefault<z.ZodBoolean>;
250
299
  }, z.core.$strip>;
251
300
  /** P3a — clone_repo args: a git URL to assess (depth-1 shallow only). */
252
301
  export declare const cloneRepoSchema: z.ZodObject<{
@@ -324,9 +373,9 @@ export declare function toolJsonSchemas(toolNames?: string[]): ToolJsonSchema[];
324
373
  * calling suggest_followups with exactly 3 followups, and clarifies ambiguous
325
374
  * requests via ask_user instead of guessing.
326
375
  */
327
- export declare const TOOL_CONTRACT = "You have tools available. Call them when appropriate.\n\n- If a request is ambiguous or incomplete, call `ask_user` with a question and 2\u20134 choices \u2014 never guess, never ask in plain text.\n- If a request needs code written, debugged, or prior work resumed, call `build`, `repair`, or `resume` with the goal.\n- If a request needs documentation, a website, analysis of a project, or running tests, call `document`, `website`, `analyze`, or `test` with the goal.\n- If a request asks to publish a release (npm/GitHub), call `publish`. It leaves this machine and is irreversible \u2014 confirm the bump type and target with the user via `ask_user` first unless they already specified them.\n- If a request's completeness is uncertain, call `verify_requirement` first.\n- If a request asks to deliver a message or result to a DIFFERENT contact/channel than the one you are currently chatting on (WhatsApp, Telegram, Slack, email, \u2026), call `gateway_send` with the target (e.g. `whatsapp:Alex`) and the text. Do NOT call gateway_send to reply to the CURRENT conversation \u2014 your text response is automatically delivered back. If the target contact is not configured, tell the user what to set up.\n- If a request asks to manage the system/agent itself in plain English \u2014 start/stop the dashboard or gateway, check status, add/remove a verified sender, configure a platform (telegram/whatsapp), run evals, show stats \u2014 call `run_cli` with the plain-English ask. It resolves the exact `buff` command and runs it. If the user's own request already resolves to that command (\"stop the dashboard\"), it just runs \u2014 do not ask for permission to do what was just asked. If it reports AMBIGUOUS, call `ask_user` with the two choices; if the intent is one YOU chose rather than the user (or is irreversible: history.clear, memory.prune, stats.cost.clear, publish), call `ask_user` first and retry with confirm:true.\n- If a subtask can be delegated to a specialized sub-agent (gather context, review, security scan, run tests), call `delegate` with the agent type, a focused prompt, and optional file paths.\n- To find code matching a pattern (context gathering, locating definitions/usages), call `code_search` with the pattern and optional globs.\n- To READ the project: call `read_file` to open a file (with line numbers), `list_dir` to see a directory's contents, or `glob` to find files by pattern. Always prefer reading the actual file over assuming its contents \u2014 a large file reports a line range, continue with offset/limit.\n- To CHANGE code (after reading it): call `edit_file` for a surgical exact-text replacement, or `write_file` to create/replace a file. CREATING a file the request asked for is applied directly \u2014 no confirmation needed, so just call it. An `edit_file` that is surgical (small relative to the file) also applies directly, as does one on a file the request names \u2014 the verify loop must not need a human between iterations. A whole-file write over existing content, or an edit that rewrites most of a file, refuses without confirm \u2014 call `ask_user` with a one-line summary, then retry with confirm:true.\n- NEVER ask for permission to do work the user already asked for \u2014 not via `ask_user` and never in plain text. Decide it yourself, state the decision in your answer, and continue. Reserve `ask_user` for a decision that is genuinely the user's: it cannot proceed without an answer, it is high-impact AND irreversible, and there is no sensible default (overwriting existing work, deleting data, spending money, publishing).\n- To VERIFY code by actual invocation: call `run_terminal` with the real command (`npx vitest run tests/x.test.ts`, `npx tsc --noEmit`, `npm run build`, `git diff`). Read-only verify commands run directly, and so do recoverable workspace commands (`npm/pnpm/yarn/bun install`, `pip install`, `mkdir`, `touch`, `cp`, `mv`, `git add`, `npm init`) when the request authorized the work \u2014 the build you were asked for is your job to set up. Everything else state-changing (network fetches, arbitrary code, global installs, anything leaving the machine) needs confirm:true after the user approves via ask_user. Never guess that a test passes \u2014 run it and read the output. Use run_cli (not run_terminal) for buff/agent-nuvira control commands, and the `git` tool (not run_terminal) to commit.\n- END EVERY RESPONSE by calling `suggest_followups` with exactly 3 followups the user is likely to want next \u2014 natural next questions, deeper dives, or related directions that build on what you just said; specific to this conversation, not generic.\n- If you have nothing to add, answer directly and still end with suggest_followups.\n- ORDERING (non-negotiable): deliver the user's answer FIRST, then suggest_followups. The followup call must come only AFTER the complete answer is written \u2014 never before it, never instead of it. A bare lead-in (\"Sure, I can help!\") is NOT an answer; write the full answer in the same step as the followup call.";
376
+ export declare const TOOL_CONTRACT = "You have tools available. Call them when appropriate.\n\n- If a request is ambiguous or incomplete, call `ask_user` with a question and 2\u20134 choices \u2014 never guess, never ask in plain text.\n- If a request needs code written, debugged, or prior work resumed, call `build`, `repair`, or `resume` with the goal.\n- If a request needs documentation, a website, analysis of a project, or running tests, call `document`, `website`, `analyze`, or `test` with the goal.\n- If a request asks to publish a release (npm/GitHub), call `publish`. It leaves this machine and is irreversible \u2014 confirm the bump type and target with the user via `ask_user` first unless they already specified them.\n- If a request's completeness is uncertain, call `verify_requirement` first.\n- If a request asks to deliver a message or result to a DIFFERENT contact/channel than the one you are currently chatting on (WhatsApp, Telegram, Slack, email, \u2026), call `gateway_send` with the target (e.g. `whatsapp:Alex`) and the text. Do NOT call gateway_send to reply to the CURRENT conversation \u2014 your text response is automatically delivered back. If the target contact is not configured, tell the user what to set up.\n- If a request asks to manage the system/agent itself in plain English \u2014 start/stop the dashboard or gateway, check status, add/remove a verified sender, configure a platform (telegram/whatsapp), run evals, show stats \u2014 call `run_cli` with the plain-English ask. It resolves the exact `nuvira` command and runs it. If the user's own request already resolves to that command (\"stop the dashboard\"), it just runs \u2014 do not ask for permission to do what was just asked. If it reports AMBIGUOUS, call `ask_user` with the two choices; if the intent is one YOU chose rather than the user (or is irreversible: history.clear, memory.prune, stats.cost.clear, publish), call `ask_user` first and retry with confirm:true.\n- If a subtask can be delegated to a specialized sub-agent (gather context, review, security scan, run tests), call `delegate` with the agent type, a focused prompt, and optional file paths.\n- To find code matching a pattern (context gathering, locating definitions/usages), call `code_search` with the pattern and optional globs.\n- To READ the project: call `read_file` to open a file (with line numbers), `list_dir` to see a directory's contents, or `glob` to find files by pattern. Always prefer reading the actual file over assuming its contents \u2014 a large file reports a line range, continue with offset/limit.\n- To CHANGE code (after reading it): call `edit_file` for a surgical exact-text replacement, or `write_file` to create/replace a file. CREATING a file the request asked for is applied directly \u2014 no confirmation needed, so just call it. An `edit_file` that is surgical (small relative to the file) also applies directly, as does one on a file the request names \u2014 the verify loop must not need a human between iterations. A whole-file write over existing content, or an edit that rewrites most of a file, refuses without confirm \u2014 call `ask_user` with a one-line summary, then retry with confirm:true.\n- NEVER ask for permission to do work the user already asked for \u2014 not via `ask_user` and never in plain text. Decide it yourself, state the decision in your answer, and continue. Reserve `ask_user` for a decision that is genuinely the user's: it cannot proceed without an answer, it is high-impact AND irreversible, and there is no sensible default (overwriting existing work, deleting data, spending money, publishing).\n- To VERIFY code by actual invocation: call `run_terminal` with the real command (`npx vitest run tests/x.test.ts`, `npx tsc --noEmit`, `npm run build`, `git diff`). Read-only verify commands run directly, and so do recoverable workspace commands (`npm/pnpm/yarn/bun install`, `pip install`, `mkdir`, `touch`, `cp`, `mv`, `git add`, `npm init`) when the request authorized the work \u2014 the build you were asked for is your job to set up. Everything else state-changing (network fetches, arbitrary code, global installs, anything leaving the machine) needs confirm:true after the user approves via ask_user. Never guess that a test passes \u2014 run it and read the output. Use run_cli (not run_terminal) for buff/agent-nuvira control commands, and the `git` tool (not run_terminal) to commit.\n- END EVERY RESPONSE by calling `suggest_followups` with exactly 3 followups the user is likely to want next \u2014 natural next questions, deeper dives, or related directions that build on what you just said; specific to this conversation, not generic.\n- If you have nothing to add, answer directly and still end with suggest_followups.\n- ORDERING (non-negotiable): deliver the user's answer FIRST, then suggest_followups. The followup call must come only AFTER the complete answer is written \u2014 never before it, never instead of it. A bare lead-in (\"Sure, I can help!\") is NOT an answer; write the full answer in the same step as the followup call.";
328
377
  /** The JSON-fallback tool contract — for providers WITHOUT native tool-calling. */
329
- export declare const TOOL_CONTRACT_JSON = "You have tools available. Call them when appropriate.\n\n- If a request is ambiguous or incomplete, call `ask_user` with a question and 2\u20134 choices \u2014 never guess, never ask in plain text.\n- If a request needs code written, debugged, or prior work resumed, call `build`, `repair`, or `resume` with the goal.\n- If a request needs documentation, a website, analysis of a project, or running tests, call `document`, `website`, `analyze`, or `test` with the goal.\n- If a request asks to publish a release (npm/GitHub), call `publish`. It leaves this machine and is irreversible \u2014 confirm the bump type and target with the user via `ask_user` first unless they already specified them.\n- If a request's completeness is uncertain, call `verify_requirement` first.\n- If a request asks to deliver a message or result to a DIFFERENT contact/channel than the one you are currently chatting on (WhatsApp, Telegram, Slack, email, \u2026), call `gateway_send` with the target (e.g. `whatsapp:Alex`) and the text. Do NOT call gateway_send to reply to the CURRENT conversation \u2014 your text response is automatically delivered back. If the target contact is not configured, tell the user what to set up.\n- If a request asks to manage the system/agent itself in plain English \u2014 start/stop the dashboard or gateway, check status, add/remove a verified sender, configure a platform (telegram/whatsapp), run evals, show stats \u2014 call `run_cli` with the plain-English ask. It resolves the exact `buff` command and runs it. If the user's own request already resolves to that command (\"stop the dashboard\"), it just runs \u2014 do not ask for permission to do what was just asked. If it reports AMBIGUOUS, call `ask_user` with the two choices; if the intent is one YOU chose rather than the user (or is irreversible: history.clear, memory.prune, stats.cost.clear, publish), call `ask_user` first and retry with confirm:true.\n- If a subtask can be delegated to a specialized sub-agent (gather context, review, security scan, run tests), call `delegate` with the agent type, a focused prompt, and optional file paths.\n- To find code matching a pattern (context gathering, locating definitions/usages), call `code_search` with the pattern and optional globs.\n- To READ the project: call `read_file` to open a file (with line numbers), `list_dir` to see a directory's contents, or `glob` to find files by pattern. Always prefer reading the actual file over assuming its contents \u2014 a large file reports a line range, continue with offset/limit.\n- To CHANGE code (after reading it): call `edit_file` for a surgical exact-text replacement, or `write_file` to create/replace a file. CREATING a file the request asked for is applied directly \u2014 no confirmation needed, so just call it. An `edit_file` that is surgical (small relative to the file) also applies directly, as does one on a file the request names \u2014 the verify loop must not need a human between iterations. A whole-file write over existing content, or an edit that rewrites most of a file, refuses without confirm \u2014 call `ask_user` with a one-line summary, then retry with confirm:true.\n- NEVER ask for permission to do work the user already asked for \u2014 not via `ask_user` and never in plain text. Decide it yourself, state the decision in your answer, and continue. Reserve `ask_user` for a decision that is genuinely the user's: it cannot proceed without an answer, it is high-impact AND irreversible, and there is no sensible default (overwriting existing work, deleting data, spending money, publishing).\n- To VERIFY code by actual invocation: call `run_terminal` with the real command (`npx vitest run tests/x.test.ts`, `npx tsc --noEmit`, `npm run build`, `git diff`). Read-only verify commands run directly, and so do recoverable workspace commands (`npm/pnpm/yarn/bun install`, `pip install`, `mkdir`, `touch`, `cp`, `mv`, `git add`, `npm init`) when the request authorized the work \u2014 the build you were asked for is your job to set up. Everything else state-changing (network fetches, arbitrary code, global installs, anything leaving the machine) needs confirm:true after the user approves via ask_user. Never guess that a test passes \u2014 run it and read the output. Use run_cli (not run_terminal) for buff/agent-nuvira control commands, and the `git` tool (not run_terminal) to commit.\n- END EVERY RESPONSE by calling `suggest_followups` with exactly 3 followups the user is likely to want next \u2014 natural next questions, deeper dives, or related directions that build on what you just said; specific to this conversation, not generic.\n- If you have nothing to add, answer directly and still end with suggest_followups.\n- ORDERING (non-negotiable): deliver the user's answer FIRST, then suggest_followups. The followup call must come only AFTER the complete answer is written \u2014 never before it, never instead of it. A bare lead-in (\"Sure, I can help!\") is NOT an answer; write the full answer in the same step as the followup call.\n\nTOOL CALL FORMAT (JSON fallback transport):\nWhen calling a tool, emit its JSON AFTER your response text, in this exact shape:\n{\"tool\":\"<name>\",\"arguments\":{...}}\nOne tool call per block. The final block may be a suggest_followups call.";
378
+ export declare const TOOL_CONTRACT_JSON = "You have tools available. Call them when appropriate.\n\n- If a request is ambiguous or incomplete, call `ask_user` with a question and 2\u20134 choices \u2014 never guess, never ask in plain text.\n- If a request needs code written, debugged, or prior work resumed, call `build`, `repair`, or `resume` with the goal.\n- If a request needs documentation, a website, analysis of a project, or running tests, call `document`, `website`, `analyze`, or `test` with the goal.\n- If a request asks to publish a release (npm/GitHub), call `publish`. It leaves this machine and is irreversible \u2014 confirm the bump type and target with the user via `ask_user` first unless they already specified them.\n- If a request's completeness is uncertain, call `verify_requirement` first.\n- If a request asks to deliver a message or result to a DIFFERENT contact/channel than the one you are currently chatting on (WhatsApp, Telegram, Slack, email, \u2026), call `gateway_send` with the target (e.g. `whatsapp:Alex`) and the text. Do NOT call gateway_send to reply to the CURRENT conversation \u2014 your text response is automatically delivered back. If the target contact is not configured, tell the user what to set up.\n- If a request asks to manage the system/agent itself in plain English \u2014 start/stop the dashboard or gateway, check status, add/remove a verified sender, configure a platform (telegram/whatsapp), run evals, show stats \u2014 call `run_cli` with the plain-English ask. It resolves the exact `nuvira` command and runs it. If the user's own request already resolves to that command (\"stop the dashboard\"), it just runs \u2014 do not ask for permission to do what was just asked. If it reports AMBIGUOUS, call `ask_user` with the two choices; if the intent is one YOU chose rather than the user (or is irreversible: history.clear, memory.prune, stats.cost.clear, publish), call `ask_user` first and retry with confirm:true.\n- If a subtask can be delegated to a specialized sub-agent (gather context, review, security scan, run tests), call `delegate` with the agent type, a focused prompt, and optional file paths.\n- To find code matching a pattern (context gathering, locating definitions/usages), call `code_search` with the pattern and optional globs.\n- To READ the project: call `read_file` to open a file (with line numbers), `list_dir` to see a directory's contents, or `glob` to find files by pattern. Always prefer reading the actual file over assuming its contents \u2014 a large file reports a line range, continue with offset/limit.\n- To CHANGE code (after reading it): call `edit_file` for a surgical exact-text replacement, or `write_file` to create/replace a file. CREATING a file the request asked for is applied directly \u2014 no confirmation needed, so just call it. An `edit_file` that is surgical (small relative to the file) also applies directly, as does one on a file the request names \u2014 the verify loop must not need a human between iterations. A whole-file write over existing content, or an edit that rewrites most of a file, refuses without confirm \u2014 call `ask_user` with a one-line summary, then retry with confirm:true.\n- NEVER ask for permission to do work the user already asked for \u2014 not via `ask_user` and never in plain text. Decide it yourself, state the decision in your answer, and continue. Reserve `ask_user` for a decision that is genuinely the user's: it cannot proceed without an answer, it is high-impact AND irreversible, and there is no sensible default (overwriting existing work, deleting data, spending money, publishing).\n- To VERIFY code by actual invocation: call `run_terminal` with the real command (`npx vitest run tests/x.test.ts`, `npx tsc --noEmit`, `npm run build`, `git diff`). Read-only verify commands run directly, and so do recoverable workspace commands (`npm/pnpm/yarn/bun install`, `pip install`, `mkdir`, `touch`, `cp`, `mv`, `git add`, `npm init`) when the request authorized the work \u2014 the build you were asked for is your job to set up. Everything else state-changing (network fetches, arbitrary code, global installs, anything leaving the machine) needs confirm:true after the user approves via ask_user. Never guess that a test passes \u2014 run it and read the output. Use run_cli (not run_terminal) for buff/agent-nuvira control commands, and the `git` tool (not run_terminal) to commit.\n- END EVERY RESPONSE by calling `suggest_followups` with exactly 3 followups the user is likely to want next \u2014 natural next questions, deeper dives, or related directions that build on what you just said; specific to this conversation, not generic.\n- If you have nothing to add, answer directly and still end with suggest_followups.\n- ORDERING (non-negotiable): deliver the user's answer FIRST, then suggest_followups. The followup call must come only AFTER the complete answer is written \u2014 never before it, never instead of it. A bare lead-in (\"Sure, I can help!\") is NOT an answer; write the full answer in the same step as the followup call.\n\nTOOL CALL FORMAT (JSON fallback transport):\nWhen calling a tool, emit its JSON AFTER your response text, in this exact shape:\n{\"tool\":\"<name>\",\"arguments\":{...}}\nOne tool call per block. The final block may be a suggest_followups call.";
330
379
  /**
331
380
  * Parse + validate a model's followups output against the shared
332
381
  * suggest_followups schema. Accepts both the tool shape `[{prompt,label?}]`