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
@@ -17,7 +17,16 @@
17
17
  *
18
18
  * Both are pure + deterministic (no LLM, no I/O), so they can be unit-tested
19
19
  * exhaustively and behave identically across the CLI, dashboard, and gateway.
20
+ *
21
+ * A third question is answered here too, and it is the one exception to that
22
+ * rule: WHICH check this project can actually run (`verificationNudgeFor` /
23
+ * `detectAvailableChecks`). It reads workspace markers (package.json scripts,
24
+ * tsconfig/vitest/jest/cargo/go) — filesystem only, never the network and never
25
+ * a model — because "the strongest check" is a property of THIS project, and a
26
+ * nudge that names it is actionable where a generic preference order is not.
20
27
  */
28
+ import { existsSync, readFileSync } from 'node:fs';
29
+ import { join } from 'node:path';
21
30
  /**
22
31
  * Tools that CHANGE the workspace. A turn that ran one of these has produced
23
32
  * a claim about reality that only a verification run can support.
@@ -75,8 +84,52 @@ export function classifyEditActivity(toolsRun) {
75
84
  * Commands that exercise the WHOLE project, so any change in it is covered.
76
85
  * `npm test`, a typecheck, a build, a linter — these observe the artifact even
77
86
  * when they never name the changed file.
87
+ *
88
+ * `node --check` USED to be in this list, which is what let the calculator
89
+ * session report "verified" after running `node -c script.js`. See
90
+ * `PARSE_ONLY_RE` below for why that cannot count.
91
+ */
92
+ const GENERIC_VERIFY_RE = /\b(?:npm|pnpm|yarn|bun)\s+(?:run\s+)?(?:test|build|lint|typecheck|check|ci)\b|\b(?:tsc|vitest|jest|pytest|mocha|cargo\s+test|go\s+test|gradle|mvn|make)\b/i;
93
+ /**
94
+ * Commands that only PARSE the files they are handed. They prove the source is
95
+ * syntactically valid and nothing else.
96
+ *
97
+ * WHY THIS EXISTS. The 2026-09-23 calculator re-test reproduced the audit's
98
+ * finding through a new door: asked to review a project, the agent ran
99
+ * `node -c script.js` and the gate accepted it as verification. It then
100
+ * reported the code "in good shape" while a live correctness bug sat on line
101
+ * 102 — a bug a parser cannot see, because a parser has no notion of what
102
+ * `display.value` holds at runtime. A modification to BEHAVIOUR cannot be
103
+ * observed by a syntax check, so these never satisfy the gate.
104
+ *
105
+ * The same reasoning as the `echo hi` hole this module already closed: a run
106
+ * counts only when it can observe the thing that changed.
78
107
  */
79
- const GENERIC_VERIFY_RE = /\b(?:npm|pnpm|yarn|bun)\s+(?:run\s+)?(?:test|build|lint|typecheck|check|ci)\b|\b(?:tsc|vitest|jest|pytest|mocha|cargo\s+test|go\s+test|gradle|mvn|make|node\s+--check)\b/i;
108
+ const PARSE_ONLY_RE = /\bnode\s+(?:--check|-c)\b|\bpython[23]?\s+-m\s+(?:py_compile|compileall)\b|\bpy_compile\b|\b(?:ruby|perl)\s+-c\b|\bphp\s+-l\b|\bbash\s+-n\b|\bgcc\s+-fsyntax-only\b/i;
109
+ /** The text an evidence entry exposes to the relevance + parse-only checks. */
110
+ function evidenceText(e) {
111
+ let text = e.result ?? '';
112
+ if (e.args) {
113
+ try {
114
+ text += ` ${JSON.stringify(e.args)}`;
115
+ }
116
+ catch {
117
+ // Unserializable args — the result text alone is still usable.
118
+ }
119
+ }
120
+ return text;
121
+ }
122
+ /**
123
+ * Is this evidence a parse/syntax check rather than an observation of
124
+ * behaviour?
125
+ *
126
+ * A run that ALSO performs a real check (`node -c a.js && npm test`) is judged
127
+ * on the real check — it is not demoted for the parse step it contains.
128
+ */
129
+ export function isParseOnlyCheck(evidence) {
130
+ const text = evidenceText(evidence);
131
+ return PARSE_ONLY_RE.test(text) && !GENERIC_VERIFY_RE.test(text);
132
+ }
80
133
  /**
81
134
  * Did this turn's verification actually EXERCISE the artifact it changed?
82
135
  *
@@ -93,7 +146,10 @@ const GENERIC_VERIFY_RE = /\b(?:npm|pnpm|yarn|bun)\s+(?:run\s+)?(?:test|build|li
93
146
  * mutation is never falsely flagged.
94
147
  */
95
148
  export function verificationExercisedArtifact(evidence, changedFiles) {
96
- if (evidence.length === 0)
149
+ // A parse check observes syntax, never behaviour — drop it before judging,
150
+ // so it can satisfy neither the relevance match nor the file-name match.
151
+ const observed = evidence.filter((e) => !isParseOnlyCheck(e));
152
+ if (observed.length === 0)
97
153
  return false;
98
154
  // Unknown changed paths → cannot judge relevance; don't cry wolf.
99
155
  if (changedFiles.length === 0)
@@ -107,18 +163,10 @@ export function verificationExercisedArtifact(evidence, changedFiles) {
107
163
  if (base)
108
164
  names.add(base);
109
165
  }
110
- for (const e of evidence) {
166
+ for (const e of observed) {
111
167
  if (e.tool === 'test' || e.tool === 'browser')
112
168
  return true;
113
- let text = e.result ?? '';
114
- if (e.args) {
115
- try {
116
- text += ` ${JSON.stringify(e.args)}`;
117
- }
118
- catch {
119
- // Unserializable args — the result text alone is still usable.
120
- }
121
- }
169
+ const text = evidenceText(e);
122
170
  if (GENERIC_VERIFY_RE.test(text))
123
171
  return true;
124
172
  for (const n of names) {
@@ -198,16 +246,143 @@ export function detectUnverifiedEditClaim(content, mutationsRun, verificationsRu
198
246
  }
199
247
  return false;
200
248
  }
249
+ /** Read a JSON file, returning null on any failure (never throws at the gate). */
250
+ function readJsonSafe(path) {
251
+ try {
252
+ return JSON.parse(readFileSync(path, 'utf-8'));
253
+ }
254
+ catch {
255
+ return null;
256
+ }
257
+ }
258
+ /** Does this path exist as a file? (Never throws.) */
259
+ function fileExists(path) {
260
+ try {
261
+ return existsSync(path);
262
+ }
263
+ catch {
264
+ return false;
265
+ }
266
+ }
267
+ /**
268
+ * Which verification checks does THIS project actually have?
269
+ *
270
+ * The nudge used to name a generic preference order ("the project's own test
271
+ * command, a typecheck or build, a real run"). That is the right ORDER but it is
272
+ * not actionable on its own: a model holding it still has to guess what the
273
+ * project has, and the guess it reached for in a live turn was `node -c` — the
274
+ * cheapest thing available, and the one that is not allowed to count. Asking for
275
+ * the strongest check only works if the loop NAMES it, so this detects the real
276
+ * command instead of describing one.
277
+ *
278
+ * Deterministic, filesystem-only, never throws — a project with no checks at all
279
+ * is a normal answer (and produces the honest "say so explicitly" nudge).
280
+ */
281
+ export function detectAvailableChecks(cwd) {
282
+ const checks = [];
283
+ const add = (command, label, strength) => {
284
+ if (!checks.some((c) => c.command === command))
285
+ checks.push({ command, label, strength });
286
+ };
287
+ const pkg = fileExists(join(cwd, 'package.json')) ? readJsonSafe(join(cwd, 'package.json')) : null;
288
+ const scripts = (pkg?.scripts ?? {}) || {};
289
+ const hasScript = (k) => typeof scripts[k] === 'string' && String(scripts[k]).trim().length > 0;
290
+ // The project's OWN test command is the strongest observation there is.
291
+ if (hasScript('test'))
292
+ add('npm test', 'the "test" script in package.json', 100);
293
+ if (hasScript('tests'))
294
+ add('npm test', 'the "tests" script in package.json', 100);
295
+ if (hasScript('typecheck'))
296
+ add('npm run typecheck', 'the "typecheck" script in package.json', 80);
297
+ if (hasScript('type-check'))
298
+ add('npm run type-check', 'the "type-check" script in package.json', 80);
299
+ if (hasScript('build'))
300
+ add('npm run build', 'the "build" script in package.json', 60);
301
+ if (hasScript('lint'))
302
+ add('npm run lint', 'the "lint" script in package.json', 40);
303
+ if (hasScript('check'))
304
+ add('npm run check', 'the "check" script in package.json', 40);
305
+ // A runner configured without a package script is still a real test command.
306
+ if (!checks.some((c) => c.strength >= 90)) {
307
+ for (const name of ['vitest.config.ts', 'vitest.config.mts', 'vitest.config.js']) {
308
+ if (fileExists(join(cwd, name))) {
309
+ add('npx vitest run', `a ${name}`, 95);
310
+ break;
311
+ }
312
+ }
313
+ for (const name of ['jest.config.js', 'jest.config.ts', 'jest.config.cjs', 'jest.config.mjs']) {
314
+ if (fileExists(join(cwd, name))) {
315
+ add('npx jest', `a ${name}`, 95);
316
+ break;
317
+ }
318
+ }
319
+ if (fileExists(join(cwd, 'pytest.ini')) || fileExists(join(cwd, 'pyproject.toml'))) {
320
+ add('pytest', 'a Python test setup', 95);
321
+ }
322
+ if (fileExists(join(cwd, 'Cargo.toml')))
323
+ add('cargo test', 'a Cargo project', 95);
324
+ if (fileExists(join(cwd, 'go.mod')))
325
+ add('go test ./...', 'a Go module', 95);
326
+ }
327
+ // A typechecker with no script is still the strongest static observation.
328
+ if (fileExists(join(cwd, 'tsconfig.json')))
329
+ add('npx tsc --noEmit', 'a tsconfig.json', 70);
330
+ return checks.sort((a, b) => b.strength - a.strength);
331
+ }
201
332
  /**
202
333
  * The nudge sent when a turn mutated the workspace and verified nothing.
334
+ *
203
335
  * Deliberately concrete (names the tools) so a weak model can act on it
204
336
  * without inventing a syntax — the same principle as `TOOL_FALLBACK_HINTS`.
337
+ * Static text, exported for callers that have no workspace (and for back-compat);
338
+ * the loop uses {@link verificationNudgeFor}, which names THIS project's checks.
205
339
  */
206
340
  export const VERIFICATION_NUDGE = 'You changed files this turn but nothing VERIFIED the change — an edit is not ' +
207
- 'evidence that it works. Before finishing, run the check that actually observes ' +
208
- 'the artifact (e.g. run_terminal for a typecheck/test/build, the test pipeline, ' +
209
- 'or a browser run), then report what that check showed. If no such check is ' +
210
- 'possible here, say so explicitly and do NOT claim the change works.';
341
+ 'evidence that it works, and neither is a syntax/parse check (`node --check` / ' +
342
+ '`node -c`, `python -m py_compile`): those prove the file PARSES, not that it ' +
343
+ 'behaves correctly, so they do not count. Run the strongest check this project ' +
344
+ 'actually has, in this order of preference: (1) the project\u2019s own test command ' +
345
+ '(package.json "test", or `nuvira test`), (2) a typecheck or build, (3) the ' +
346
+ 'browser tool or a real run that exercises the changed code with actual input. ' +
347
+ 'Then report what that check showed. If genuinely no such check exists here, ' +
348
+ 'say so explicitly and do NOT claim the change works.';
349
+ /**
350
+ * The verification nudge for a specific workspace — the strongest check it
351
+ * actually HAS, named.
352
+ *
353
+ * The difference from {@link VERIFICATION_NUDGE} is the difference between
354
+ * "run the strongest check you have" and "run `npm test`". A model handed the
355
+ * first re-derives the answer and reaches for the cheapest thing that looks like
356
+ * a check; a model handed the second has nothing to guess. When the project has
357
+ * no runnable check at all the instruction is a REAL RUN, and failing that an
358
+ * explicit admission — never a claim.
359
+ */
360
+ export function verificationNudgeFor(cwd, changedFiles = []) {
361
+ const checks = detectAvailableChecks(cwd);
362
+ const changed = changedFiles.filter(Boolean).slice(0, 5);
363
+ const head = 'You changed files this turn' +
364
+ (changed.length > 0 ? ` (${changed.join(', ')})` : '') +
365
+ ' but nothing VERIFIED the change — an edit is not evidence that it works, and neither ' +
366
+ 'is a syntax/parse check (`node --check` / `node -c`, `python -m py_compile`): those prove ' +
367
+ 'the file PARSES, not that it behaves correctly, so they do not count.';
368
+ if (checks.length === 0) {
369
+ return (`${head}\n` +
370
+ 'No test, typecheck or build command was found in this project, so the strongest check ' +
371
+ 'AVAILABLE to you is a REAL RUN that exercises the changed code — the `browser` tool, or ' +
372
+ '`run_terminal` with a command that executes the changed behaviour with real input. Then ' +
373
+ 'report what it showed. If even that is impossible, say so explicitly and do NOT claim ' +
374
+ 'the change works.');
375
+ }
376
+ const list = checks
377
+ .slice(0, 3)
378
+ .map((c, i) => ` ${i + 1}. \`${c.command}\` — ${c.label}`)
379
+ .join('\n');
380
+ return (`${head}\n` +
381
+ `This project's strongest available checks, best first:\n${list}\n` +
382
+ 'Run the strongest one and report what it showed. If it does not apply to this change, say ' +
383
+ 'which you tried and why. If none of them runs, say so explicitly and do NOT claim the ' +
384
+ 'change works.');
385
+ }
211
386
  /**
212
387
  * The nudge sent when a turn ended asking PERMISSION for work the user's own
213
388
  * request already authorized (G13 — the manual-cadence complaint).
@@ -219,6 +394,28 @@ export const VERIFICATION_NUDGE = 'You changed files this turn but nothing VERIF
219
394
  * proceed unless the decision is blocking, high-impact, irreversible and has
220
395
  * no sensible default.
221
396
  */
397
+ /**
398
+ * The escalation sent when the model produces REASONING ONLY, repeatedly, with
399
+ * no tool call and no answer.
400
+ *
401
+ * WHY THIS EXISTS (a live eval run, 2026-09-23). A think-only response makes the
402
+ * loop `continue` so a model that emits a reasoning block then its answer in the
403
+ * next step is not cut off — sensible, but UNBOUNDED: nothing counted the
404
+ * continuations and nothing ever changed the instruction. Both groq and gemini
405
+ * therefore produced 31 consecutive reasoning-only steps, one `list_dir` call,
406
+ * and a 0% score on a task they were perfectly capable of doing — with the exact
407
+ * "model reasoning… (continuing)" spam a user had already reported in a real
408
+ * dashboard turn. A spin is not a stall the user can act on; it burns the whole
409
+ * budget and looks like the agent thinking hard while nothing happens.
410
+ *
411
+ * Deliberately an ESCALATION rather than a hard stop on the first repeat: a
412
+ * legitimate `<think>`-then-answer model needs a step or two, so the loop allows
413
+ * a small budget, then says this, then ends the turn honestly if it still spins.
414
+ */
415
+ export const THINK_ONLY_ESCALATION = 'You have produced only reasoning for several steps — no tool call and no answer to the ' +
416
+ 'user. Stop reasoning and ACT: call the tool you need now, or write your final answer. ' +
417
+ 'If you are unsure, make the decision you can defend and proceed — the user is waiting on ' +
418
+ 'a result, not on deliberation.';
222
419
  export const AUTHORIZED_WORK_NUDGE = 'The user\u2019s own request already asked for this work, so asking whether to ' +
223
420
  'proceed is a round trip that delivers nothing. Do NOT end the turn on a request ' +
224
421
  'for permission: carry the work out with the tools available, decide anything that ' +
@@ -1 +1 @@
1
- {"version":3,"file":"edit-verification.js","sourceRoot":"","sources":["../../src/tools/edit-verification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;AAExF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAwB,IAAI,GAAG,CAAC;IAC7D,cAAc;IACd,MAAM;IACN,SAAS;IACT,SAAS;CACV,CAAC,CAAC;AAEH,iDAAiD;AACjD,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,OAAO,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAA2B;IAK9D,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,cAAc,CAAC,IAAI,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aAC1C,IAAI,kBAAkB,CAAC,IAAI,CAAC;YAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO;QACL,SAAS;QACT,aAAa;QACb,oEAAoE;QACpE,iBAAiB,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;KACtE,CAAC;AACJ,CAAC;AAUD;;;;GAIG;AACH,MAAM,iBAAiB,GACrB,2KAA2K,CAAC;AAE9K;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,6BAA6B,CAC3C,QAAqC,EACrC,YAA+B;IAE/B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,kEAAkE;IAClE,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE3C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;QAC7B,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACb,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC;QACpC,IAAI,IAAI;YAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QAC3D,IAAI,IAAI,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YACX,IAAI,CAAC;gBACH,IAAI,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,CAAC;YAAC,MAAM,CAAC;gBACP,+DAA+D;YACjE,CAAC;QACH,CAAC;QACD,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC9C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;QACzC,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAA2B,EAC3B,WAAwC,EAAE,EAC1C,eAAkC,EAAE;IAMpC,MAAM,IAAI,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC5C,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,GAAG,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC;IAC9E,OAAO,EAAE,GAAG,IAAI,EAAE,iBAAiB,EAAE,CAAC,6BAA6B,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,CAAC;AAChG,CAAC;AAED,gFAAgF;AAChF,MAAM,oBAAoB,GACxB,4MAA4M,CAAC;AAE/M;;;;;;;GAOG;AACH,MAAM,cAAc,GAAsB;IACxC,yEAAyE;IACzE,uTAAuT;IACvT,wCAAwC;IACxC,6JAA6J;IAC7J,kFAAkF;IAClF,wTAAwT;IACxT,gEAAgE;IAChE,8OAA8O;IAC9O,mEAAmE;IACnE,yOAAyO;IACzO,yCAAyC;IACzC,mIAAmI;IACnI,uCAAuC;IACvC,+GAA+G;CAChH,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,yBAAyB,CACvC,OAAe,EACf,YAA+B,EAC/B,gBAAmC;IAEnC,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACpC,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,kEAAkE;IAClE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC;QAAE,OAAO,KAAK,CAAC;IACrD,2DAA2D;IAC3D,IAAI,gBAAgB,CAAC,IAAI,CAAC,kBAAkB,CAAC;QAAE,OAAO,KAAK,CAAC;IAE5D,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACpE,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,SAAS;QACjD,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;IAC3D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAC7B,+EAA+E;IAC/E,iFAAiF;IACjF,iFAAiF;IACjF,6EAA6E;IAC7E,qEAAqE,CAAC;AAExE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAChC,gFAAgF;IAChF,kFAAkF;IAClF,oFAAoF;IACpF,sFAAsF;IACtF,+EAA+E;IAC/E,kFAAkF;IAClF,uDAAuD,CAAC;AAE1D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,gBAAgB,CAAC,aAAsB;IACrD,MAAM,WAAW,GAAG,aAAa;QAC/B,CAAC,CAAC,uEAAuE,aAAa,EAAE;QACxF,CAAC,CAAC,sFAAsF,CAAC;IAC3F,OAAO,CACL,gGAAgG;QAChG,oGAAoG;QACpG,uBAAuB,GAAG,WAAW,GAAG,4DAA4D;QACpG,qFAAqF,CACtF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAC/B,8EAA8E;IAC9E,gFAAgF;IAChF,gBAAgB,CAAC"}
1
+ {"version":3,"file":"edit-verification.js","sourceRoot":"","sources":["../../src/tools/edit-verification.ts"],"names":[],"mappings":"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"}
@@ -19,14 +19,26 @@
19
19
  * those are staged+committed ("accept/reject applies only accepted
20
20
  * hunks" — the model shows the diff card, the user picks files, the
21
21
  * commit touches nothing else).
22
+ * - `push` — GATED, and the strictest gate here: a push is the one git action
23
+ * whose effect is visible OUTSIDE this machine (a remote other people and CI
24
+ * read). It proceeds when the user's OWN REQUEST named it ("commit and push
25
+ * this to GitHub" — the evidence is in `requestRequestsPush`, so the ask is
26
+ * not a round trip), and it ASKS otherwise. A request that only asked to
27
+ * record work locally ("commit these changes") does not unlock it: the agent
28
+ * must not decide on its own to publish someone's work.
22
29
  *
23
30
  * Security (deny-first, shared with run_terminal):
24
- * - `git push`, `git reset --hard`, `git clean`, `git checkout -- .` are
25
- * STRUCTURALLY unexpressible (the action enum has no such action) AND a
26
- * deny guard refuses any future action name that maps to them (parity
27
- * test: a command denied in run_terminal is denied here).
28
- * - argv-array exec (execFileSync, NO shell) — the message/files are
29
- * passed as arguments, injection is structurally impossible.
31
+ * - `git push` is reachable HERE (gated, argv-array, auditable) and DELIBERATELY
32
+ * still denied as a raw `run_terminal` shell string. The structured tool is
33
+ * the sanctioned path: it validates the remote/branch as literals, passes
34
+ * them as argv (injection impossible), reports what it pushed, and asks
35
+ * first. The unstructured shell string gets none of that, so it stays denied.
36
+ * - `git reset --hard`, `git clean`, `git checkout -- .` are STRUCTURALLY
37
+ * unexpressible (the action enum has no such action) AND deny-guarded —
38
+ * there is no gated variant of them because no user request makes an
39
+ * irreversible working-tree wipe the right thing to do in a tool call.
40
+ * - argv-array exec (execFileSync, NO shell) — the message/files/remote/branch
41
+ * are passed as arguments, injection is structurally impossible.
30
42
  * - The commit message may be empty (git opens the editor — blocked):
31
43
  * an empty message is refused with guidance instead.
32
44
  *
@@ -36,7 +48,7 @@ import type { ToolContext } from './registry.js';
36
48
  /** The tool's args (zod-validated in the registry). */
37
49
  export interface GitToolArgs {
38
50
  /** What to do. */
39
- action: 'status' | 'log' | 'diff' | 'commit';
51
+ action: 'status' | 'log' | 'diff' | 'commit' | 'push';
40
52
  /** Commit message (action=commit, required). */
41
53
  message?: string;
42
54
  /**
@@ -48,6 +60,12 @@ export interface GitToolArgs {
48
60
  confirm?: boolean;
49
61
  /** Limit for `log` (default 20). */
50
62
  limit?: number;
63
+ /** Push destination (action=push, default: the repo's first remote). */
64
+ remote?: string;
65
+ /** Push source branch (action=push, default: the current branch). */
66
+ branch?: string;
67
+ /** action=push — also push tags (`git push --tags`). */
68
+ tags?: boolean;
51
69
  }
52
70
  /** The structured diff payload the GUI renders as a card. */
53
71
  export interface GitDiffPayload {
@@ -1 +1 @@
1
- {"version":3,"file":"git-tool.d.ts","sourceRoot":"","sources":["../../src/tools/git-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGjD,uDAAuD;AACvD,MAAM,WAAW,WAAW;IAC1B,kBAAkB;IAClB,MAAM,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC7C,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,oEAAoE;IACpE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,6DAA6D;AAC7D,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB;AAkCD,8EAA8E;AAC9E,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAgBzF;AAED,qFAAqF;AACrF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE7D;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA0GrF"}
1
+ {"version":3,"file":"git-tool.d.ts","sourceRoot":"","sources":["../../src/tools/git-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAOjD,uDAAuD;AACvD,MAAM,WAAW,WAAW;IAC1B,kBAAkB;IAClB,MAAM,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;IACtD,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,oEAAoE;IACpE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,6DAA6D;AAC7D,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB;AA4ED,8EAA8E;AAC9E,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAgBzF;AAED,qFAAqF;AACrF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE7D;AAsGD,wBAAsB,UAAU,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA+GrF"}
@@ -19,24 +19,42 @@
19
19
  * those are staged+committed ("accept/reject applies only accepted
20
20
  * hunks" — the model shows the diff card, the user picks files, the
21
21
  * commit touches nothing else).
22
+ * - `push` — GATED, and the strictest gate here: a push is the one git action
23
+ * whose effect is visible OUTSIDE this machine (a remote other people and CI
24
+ * read). It proceeds when the user's OWN REQUEST named it ("commit and push
25
+ * this to GitHub" — the evidence is in `requestRequestsPush`, so the ask is
26
+ * not a round trip), and it ASKS otherwise. A request that only asked to
27
+ * record work locally ("commit these changes") does not unlock it: the agent
28
+ * must not decide on its own to publish someone's work.
22
29
  *
23
30
  * Security (deny-first, shared with run_terminal):
24
- * - `git push`, `git reset --hard`, `git clean`, `git checkout -- .` are
25
- * STRUCTURALLY unexpressible (the action enum has no such action) AND a
26
- * deny guard refuses any future action name that maps to them (parity
27
- * test: a command denied in run_terminal is denied here).
28
- * - argv-array exec (execFileSync, NO shell) — the message/files are
29
- * passed as arguments, injection is structurally impossible.
31
+ * - `git push` is reachable HERE (gated, argv-array, auditable) and DELIBERATELY
32
+ * still denied as a raw `run_terminal` shell string. The structured tool is
33
+ * the sanctioned path: it validates the remote/branch as literals, passes
34
+ * them as argv (injection impossible), reports what it pushed, and asks
35
+ * first. The unstructured shell string gets none of that, so it stays denied.
36
+ * - `git reset --hard`, `git clean`, `git checkout -- .` are STRUCTURALLY
37
+ * unexpressible (the action enum has no such action) AND deny-guarded —
38
+ * there is no gated variant of them because no user request makes an
39
+ * irreversible working-tree wipe the right thing to do in a tool call.
40
+ * - argv-array exec (execFileSync, NO shell) — the message/files/remote/branch
41
+ * are passed as arguments, injection is structurally impossible.
30
42
  * - The commit message may be empty (git opens the editor — blocked):
31
43
  * an empty message is refused with guidance instead.
32
44
  *
33
45
  * Never throws: every failure returns a helpful string.
34
46
  */
35
- import { execFileSync } from 'node:child_process';
36
- import { decideStateChange, requestRequestsCommit } from '../learning/autonomy-policy.js';
37
- /** Action names that map to denied git commands (parity with run_terminal). */
47
+ import { execFileSync, spawnSync } from 'node:child_process';
48
+ import { decideStateChange, requestRequestsCommit, requestRequestsPush, } from '../learning/autonomy-policy.js';
49
+ /**
50
+ * Action names that map to denied git commands — parity with run_terminal.
51
+ *
52
+ * `push` is deliberately ABSENT: it is a real, gated action on this tool (see
53
+ * the module docstring), while the raw `git push` shell string stays denied in
54
+ * run_terminal. Everything here destroys working-tree state that no request
55
+ * makes safe to do from a tool call.
56
+ */
38
57
  const DENIED_ACTIONS = {
39
- push: 'git push is denied — pushing is a human decision, never an autonomous loop.',
40
58
  'reset --hard': 'git reset --hard is denied — it destroys the working tree irreversibly.',
41
59
  clean: 'git clean is denied — it removes untracked files irreversibly.',
42
60
  'checkout -- .': 'git checkout -- . is denied — it discards working-tree changes irreversibly.',
@@ -47,14 +65,23 @@ const DENIED_ACTIONS = {
47
65
  // NOTE: \s is deliberately NOT here — commit messages and file names contain
48
66
  // spaces legitimately and argv exec passes them safely.
49
67
  const SHELL_METACHARS = /[;&|`$()<>"'\\]/;
68
+ /**
69
+ * A remote name or ref that is safe as an argv literal.
70
+ *
71
+ * The push path is the one place a caller-supplied string reaches a network
72
+ * command, so it is allow-listed rather than deny-listed: letters/digits first
73
+ * (never a leading `-`, which is how an argv entry turns into an option), then
74
+ * the punctuation real branch names use (`feature/x`, `v3.3.2`, `release_1`).
75
+ */
76
+ const SAFE_REF_RE = /^[A-Za-z0-9][A-Za-z0-9._/-]*$/;
50
77
  /** Run git with an argv array (no shell). Returns stdout or a masked error. */
51
- function git(argv, ctx) {
78
+ function git(argv, ctx, timeoutMs = 60_000) {
52
79
  try {
53
80
  const out = execFileSync('git', argv, {
54
81
  cwd: ctx.cwd || process.cwd(),
55
82
  encoding: 'utf-8',
56
83
  stdio: ['ignore', 'pipe', 'pipe'],
57
- timeout: 60_000,
84
+ timeout: timeoutMs,
58
85
  });
59
86
  return { ok: true, out: out.trim() };
60
87
  }
@@ -64,6 +91,27 @@ function git(argv, ctx) {
64
91
  return { ok: false, out: detail || 'git failed', code: e.status };
65
92
  }
66
93
  }
94
+ /**
95
+ * Run a git subcommand that reports its progress on STDERR and capture BOTH
96
+ * streams.
97
+ *
98
+ * `execFileSync` returns stdout only, and a successful `git push` writes
99
+ * everything it has to say ("To <url> … main -> main", "Everything up-to-date")
100
+ * to stderr — so a push reported through the stdout-only helper would look like
101
+ * it said nothing at all. Returns a never-empty string so a result line can
102
+ * always show what git actually printed.
103
+ */
104
+ function gitCombined(argv, ctx, timeoutMs) {
105
+ const r = spawnSync('git', argv, {
106
+ cwd: ctx.cwd || process.cwd(),
107
+ encoding: 'utf-8',
108
+ stdio: ['ignore', 'pipe', 'pipe'],
109
+ timeout: timeoutMs,
110
+ });
111
+ const text = `${r.stdout ?? ''}${r.stderr ?? ''}`.trim();
112
+ const failed = r.error ? String(r.error.message) : '';
113
+ return { ok: r.status === 0, out: text || failed || 'git reported no output' };
114
+ }
67
115
  /** Split a unified diff into per-file sections (diff --git … hunk blocks). */
68
116
  export function parseDiffIntoSections(diff) {
69
117
  if (!diff.trim())
@@ -90,17 +138,105 @@ export function parseDiffIntoSections(diff) {
90
138
  export function deniedGitAction(action) {
91
139
  return DENIED_ACTIONS[action] ?? null;
92
140
  }
141
+ /**
142
+ * The push action — the only git operation here whose effect LEAVES this machine.
143
+ *
144
+ * Gate: the user's OWN REQUEST must have named the push, or the model must have
145
+ * confirmed with the user first. A local-only commit request does NOT authorize
146
+ * it. That asymmetry with {@link runGitTool}'s commit path is the point: a commit
147
+ * is undone by a reset, while a push is read by everyone with access to the
148
+ * remote and acted on by CI, so the agent must not infer it from work the user
149
+ * only asked to record.
150
+ *
151
+ * Every caller-supplied ref is allow-listed ({@link SAFE_REF_RE}) and passed as
152
+ * an argv literal, so neither an option-injection (`--force`) nor a shell
153
+ * metacharacter can travel through it.
154
+ */
155
+ async function pushAction(args, ctx) {
156
+ const remoteArg = String(args.remote ?? '').trim();
157
+ const branchArg = String(args.branch ?? '').trim();
158
+ for (const [label, value] of [['remote', remoteArg], ['branch', branchArg]]) {
159
+ if (!value)
160
+ continue;
161
+ if (!SAFE_REF_RE.test(value) || value.includes('..')) {
162
+ return `Error: git push ${label} '${value}' is not a plain remote/branch name — denied.`;
163
+ }
164
+ }
165
+ // Resolve the defaults from the repository, so BOTH the confirmation and the
166
+ // result can name exactly what moves.
167
+ let remote = remoteArg;
168
+ if (!remote) {
169
+ const remotes = git(['remote'], ctx);
170
+ remote = remotes.ok ? (remotes.out.split('\n')[0] ?? '').trim() : '';
171
+ }
172
+ if (!remote) {
173
+ return ('Error: git push has no remote to push to. Add one first ' +
174
+ '(git remote add origin <url>), or pass remote explicitly.');
175
+ }
176
+ let branch = branchArg;
177
+ if (!branch) {
178
+ const head = git(['rev-parse', '--abbrev-ref', 'HEAD'], ctx);
179
+ branch = head.ok ? head.out.trim() : '';
180
+ }
181
+ if (!branch || branch === 'HEAD') {
182
+ return 'Error: git push needs a branch to push, and HEAD is detached. Check out a branch, or pass branch explicitly.';
183
+ }
184
+ // ── The gate ────────────────────────────────────────────────────────────
185
+ const namedByRequest = requestRequestsPush(ctx.authorizationRequest ?? '');
186
+ if (!args.confirm && !namedByRequest) {
187
+ // `external` is what makes the ask unconditional here — even a request that
188
+ // authorized writes cannot authorize this, because it was not the user who
189
+ // decided the work should leave this machine.
190
+ const verdict = decideStateChange({
191
+ tool: 'git push',
192
+ action: `pushing ${branch} to '${remote}'`,
193
+ changeClass: 'external',
194
+ namedByRequest: false,
195
+ authorizedByRequest: ctx.writesAuthorized?.authorized === true,
196
+ });
197
+ return (`git push: pushing ${branch} to '${remote}' sends this work to a remote that other ` +
198
+ `people and CI can see, so it is the user's call (${verdict.reason}). ` +
199
+ 'Call ask_user (show the branch, the remote, and the commits that would move), then ' +
200
+ 're-call git push with confirm:true only if the user agreed.');
201
+ }
202
+ // Longer than the read-only timeout: a push carries the whole working history
203
+ // over the network, and timing out mid-push is worse than waiting.
204
+ const pushed = gitCombined(['push', '-u', remote, branch], ctx, 180_000);
205
+ if (!pushed.ok)
206
+ return `git push failed: ${pushed.out}`;
207
+ let tagsNote = '';
208
+ if (args.tags) {
209
+ const tags = gitCombined(['push', remote, '--tags'], ctx, 120_000);
210
+ tagsNote = tags.ok ? '; pushed tags' : `; but pushing tags failed: ${tags.out}`;
211
+ }
212
+ const reported = !args.confirm;
213
+ if (reported) {
214
+ // Reported, never silent — same contract as the commit path's autonomous
215
+ // write: the user must be able to see where their work just went.
216
+ ctx.emit?.('autonomy:write-applied', {
217
+ tool: 'git push',
218
+ remote,
219
+ branch,
220
+ reason: 'the request itself names the push',
221
+ }, 'tool-loop');
222
+ }
223
+ const result = `✅ Pushed ${branch} → ${remote}${tagsNote}:\n${pushed.out.slice(0, 800)}`;
224
+ if (!reported)
225
+ return result;
226
+ return (`${result}\n💡 Pushed without asking: the request itself named the push. ` +
227
+ 'State the push in your answer so the user can see where the work went.');
228
+ }
93
229
  export async function runGitTool(args, ctx) {
94
230
  const action = String(args?.action ?? '').trim();
95
231
  if (!action)
96
- return 'Error: git tool needs an action (status | log | diff | commit).';
232
+ return 'Error: git tool needs an action (status | log | diff | commit | push).';
97
233
  // Deny guard — an action that maps to a run_terminal-denied command is
98
234
  // refused before anything runs (parity with the shared deny list).
99
235
  const denied = deniedGitAction(action);
100
236
  if (denied)
101
237
  return `Error: ${denied}`;
102
- if (!['status', 'log', 'diff', 'commit'].includes(action)) {
103
- return `Error: unknown git action '${action}' — use status | log | diff | commit.`;
238
+ if (!['status', 'log', 'diff', 'commit', 'push'].includes(action)) {
239
+ return `Error: unknown git action '${action}' — use status | log | diff | commit | push.`;
104
240
  }
105
241
  if (action === 'status') {
106
242
  const r = git(['status', '--short'], ctx);
@@ -132,6 +268,10 @@ export async function runGitTool(args, ctx) {
132
268
  const files = sections.map((s) => s.path).join(', ');
133
269
  return `git diff — ${payload.summary}: ${files}\n${r.out.slice(0, 6000)}`;
134
270
  }
271
+ // ── action === 'push' — the OUTBOUND path (external effect, own gate) ───
272
+ if (action === 'push') {
273
+ return pushAction(args, ctx);
274
+ }
135
275
  // ── action === 'commit' — the GATED path ────────────────────────────────
136
276
  const message = String(args.message ?? '').trim();
137
277
  if (!message) {
@@ -1 +1 @@
1
- {"version":3,"file":"git-tool.js","sourceRoot":"","sources":["../../src/tools/git-tool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"git-tool.js","sourceRoot":"","sources":["../../src/tools/git-tool.ts"],"names":[],"mappings":"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"}