agent-nuvira 3.3.1 โ†’ 3.3.4

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 (466) hide show
  1. package/README.md +18 -13
  2. package/dist/agent-sdk/src/agent.d.ts +2 -0
  3. package/dist/agent-sdk/src/agent.d.ts.map +1 -1
  4. package/dist/agent-sdk/src/define.d.ts +64 -0
  5. package/dist/agent-sdk/src/define.d.ts.map +1 -0
  6. package/dist/agent-sdk/src/define.js +76 -0
  7. package/dist/agent-sdk/src/define.js.map +1 -0
  8. package/dist/agent-sdk/src/index.d.ts +9 -0
  9. package/dist/agent-sdk/src/index.d.ts.map +1 -1
  10. package/dist/agent-sdk/src/index.js +9 -0
  11. package/dist/agent-sdk/src/index.js.map +1 -1
  12. package/dist/agent-sdk/src/scaffold.d.ts +11 -0
  13. package/dist/agent-sdk/src/scaffold.d.ts.map +1 -1
  14. package/dist/agent-sdk/src/scaffold.js +16 -6
  15. package/dist/agent-sdk/src/scaffold.js.map +1 -1
  16. package/dist/agents/agents/runner.d.ts +9 -0
  17. package/dist/agents/agents/runner.d.ts.map +1 -1
  18. package/dist/agents/agents/runner.js +34 -12
  19. package/dist/agents/agents/runner.js.map +1 -1
  20. package/dist/agents/agents/writer-tool-calling.d.ts.map +1 -1
  21. package/dist/agents/agents/writer-tool-calling.js +7 -2
  22. package/dist/agents/agents/writer-tool-calling.js.map +1 -1
  23. package/dist/agents/agents/writer.d.ts.map +1 -1
  24. package/dist/agents/agents/writer.js +7 -1
  25. package/dist/agents/agents/writer.js.map +1 -1
  26. package/dist/agents/artifact-verification.d.ts +102 -0
  27. package/dist/agents/artifact-verification.d.ts.map +1 -0
  28. package/dist/agents/artifact-verification.js +216 -0
  29. package/dist/agents/artifact-verification.js.map +1 -0
  30. package/dist/agents/checkpoint-store.d.ts +73 -0
  31. package/dist/agents/checkpoint-store.d.ts.map +1 -1
  32. package/dist/agents/checkpoint-store.js +161 -0
  33. package/dist/agents/checkpoint-store.js.map +1 -1
  34. package/dist/agents/credential-store.d.ts +120 -0
  35. package/dist/agents/credential-store.d.ts.map +1 -1
  36. package/dist/agents/credential-store.js +358 -19
  37. package/dist/agents/credential-store.js.map +1 -1
  38. package/dist/agents/long-form-plan.d.ts.map +1 -1
  39. package/dist/agents/long-form-plan.js +2 -1
  40. package/dist/agents/long-form-plan.js.map +1 -1
  41. package/dist/agents/orchestrator.d.ts +10 -1
  42. package/dist/agents/orchestrator.d.ts.map +1 -1
  43. package/dist/agents/orchestrator.js +239 -79
  44. package/dist/agents/orchestrator.js.map +1 -1
  45. package/dist/agents/phase-engine.d.ts +61 -0
  46. package/dist/agents/phase-engine.d.ts.map +1 -1
  47. package/dist/agents/phase-engine.js +68 -2
  48. package/dist/agents/phase-engine.js.map +1 -1
  49. package/dist/agents/prompt-assembly.d.ts +11 -0
  50. package/dist/agents/prompt-assembly.d.ts.map +1 -1
  51. package/dist/agents/prompt-assembly.js +17 -0
  52. package/dist/agents/prompt-assembly.js.map +1 -1
  53. package/dist/agents/release-preflight.d.ts +121 -0
  54. package/dist/agents/release-preflight.d.ts.map +1 -0
  55. package/dist/agents/release-preflight.js +259 -0
  56. package/dist/agents/release-preflight.js.map +1 -0
  57. package/dist/agents/release-runner.d.ts +157 -0
  58. package/dist/agents/release-runner.d.ts.map +1 -0
  59. package/dist/agents/release-runner.js +719 -0
  60. package/dist/agents/release-runner.js.map +1 -0
  61. package/dist/agents/step-handoff.d.ts +190 -0
  62. package/dist/agents/step-handoff.d.ts.map +1 -0
  63. package/dist/agents/step-handoff.js +443 -0
  64. package/dist/agents/step-handoff.js.map +1 -0
  65. package/dist/cli/agent.d.ts +2 -2
  66. package/dist/cli/agent.js +10 -10
  67. package/dist/cli/benchmark.d.ts.map +1 -1
  68. package/dist/cli/benchmark.js +11 -4
  69. package/dist/cli/benchmark.js.map +1 -1
  70. package/dist/cli/chat.d.ts +94 -0
  71. package/dist/cli/chat.d.ts.map +1 -1
  72. package/dist/cli/chat.js +379 -24
  73. package/dist/cli/chat.js.map +1 -1
  74. package/dist/cli/cli-program.d.ts.map +1 -1
  75. package/dist/cli/cli-program.js +8 -0
  76. package/dist/cli/cli-program.js.map +1 -1
  77. package/dist/cli/config.d.ts.map +1 -1
  78. package/dist/cli/config.js +9 -1
  79. package/dist/cli/config.js.map +1 -1
  80. package/dist/cli/credentials.d.ts +28 -0
  81. package/dist/cli/credentials.d.ts.map +1 -0
  82. package/dist/cli/credentials.js +213 -0
  83. package/dist/cli/credentials.js.map +1 -0
  84. package/dist/cli/doctor.d.ts.map +1 -1
  85. package/dist/cli/doctor.js +3 -2
  86. package/dist/cli/doctor.js.map +1 -1
  87. package/dist/cli/edit.js +2 -2
  88. package/dist/cli/eval.d.ts +17 -0
  89. package/dist/cli/eval.d.ts.map +1 -1
  90. package/dist/cli/eval.js +105 -2
  91. package/dist/cli/eval.js.map +1 -1
  92. package/dist/cli/execute.d.ts +16 -1
  93. package/dist/cli/execute.d.ts.map +1 -1
  94. package/dist/cli/execute.js +192 -22
  95. package/dist/cli/execute.js.map +1 -1
  96. package/dist/cli/failover-runner.d.ts.map +1 -1
  97. package/dist/cli/failover-runner.js +9 -3
  98. package/dist/cli/failover-runner.js.map +1 -1
  99. package/dist/cli/loop-executor.d.ts +55 -0
  100. package/dist/cli/loop-executor.d.ts.map +1 -1
  101. package/dist/cli/loop-executor.js +285 -19
  102. package/dist/cli/loop-executor.js.map +1 -1
  103. package/dist/cli/model.d.ts.map +1 -1
  104. package/dist/cli/model.js +9 -8
  105. package/dist/cli/model.js.map +1 -1
  106. package/dist/cli/models.d.ts +1 -1
  107. package/dist/cli/models.js +4 -4
  108. package/dist/cli/nlu.d.ts.map +1 -1
  109. package/dist/cli/nlu.js +8 -2
  110. package/dist/cli/nlu.js.map +1 -1
  111. package/dist/cli/parity.d.ts +85 -0
  112. package/dist/cli/parity.d.ts.map +1 -0
  113. package/dist/cli/parity.js +506 -0
  114. package/dist/cli/parity.js.map +1 -0
  115. package/dist/cli/plan.d.ts.map +1 -1
  116. package/dist/cli/plan.js +2 -1
  117. package/dist/cli/plan.js.map +1 -1
  118. package/dist/cli/publish.d.ts +22 -0
  119. package/dist/cli/publish.d.ts.map +1 -1
  120. package/dist/cli/publish.js +109 -13
  121. package/dist/cli/publish.js.map +1 -1
  122. package/dist/cli/retrieval.d.ts.map +1 -1
  123. package/dist/cli/retrieval.js +5 -4
  124. package/dist/cli/retrieval.js.map +1 -1
  125. package/dist/cli/sdk.js +4 -4
  126. package/dist/cli/sdk.js.map +1 -1
  127. package/dist/cli/trace.d.ts.map +1 -1
  128. package/dist/cli/trace.js +2 -1
  129. package/dist/cli/trace.js.map +1 -1
  130. package/dist/cli/workflow.js +2 -2
  131. package/dist/cli/workflow.js.map +1 -1
  132. package/dist/config/live-credentials.d.ts +57 -0
  133. package/dist/config/live-credentials.d.ts.map +1 -0
  134. package/dist/config/live-credentials.js +126 -0
  135. package/dist/config/live-credentials.js.map +1 -0
  136. package/dist/config/paths.d.ts +18 -0
  137. package/dist/config/paths.d.ts.map +1 -1
  138. package/dist/config/paths.js +25 -0
  139. package/dist/config/paths.js.map +1 -1
  140. package/dist/config/types.d.ts +44 -0
  141. package/dist/config/types.d.ts.map +1 -1
  142. package/dist/federation/a2a-types.js +1 -1
  143. package/dist/federation/a2a-types.js.map +1 -1
  144. package/dist/findings/verdicts.d.ts +241 -0
  145. package/dist/findings/verdicts.d.ts.map +1 -0
  146. package/dist/findings/verdicts.js +284 -0
  147. package/dist/findings/verdicts.js.map +1 -0
  148. package/dist/gateway/adapters.d.ts +65 -0
  149. package/dist/gateway/adapters.d.ts.map +1 -1
  150. package/dist/gateway/adapters.js +216 -10
  151. package/dist/gateway/adapters.js.map +1 -1
  152. package/dist/gateway/channel-directory.d.ts +31 -0
  153. package/dist/gateway/channel-directory.d.ts.map +1 -1
  154. package/dist/gateway/channel-directory.js +40 -0
  155. package/dist/gateway/channel-directory.js.map +1 -1
  156. package/dist/gateway/gateway-log.d.ts +1 -1
  157. package/dist/gateway/gateway-log.d.ts.map +1 -1
  158. package/dist/gateway/gateway-log.js.map +1 -1
  159. package/dist/gateway/hooks.d.ts +87 -19
  160. package/dist/gateway/hooks.d.ts.map +1 -1
  161. package/dist/gateway/hooks.js +62 -23
  162. package/dist/gateway/hooks.js.map +1 -1
  163. package/dist/gateway/inbound-media.d.ts +147 -0
  164. package/dist/gateway/inbound-media.d.ts.map +1 -0
  165. package/dist/gateway/inbound-media.js +317 -0
  166. package/dist/gateway/inbound-media.js.map +1 -0
  167. package/dist/gateway/inbox.d.ts +8 -1
  168. package/dist/gateway/inbox.d.ts.map +1 -1
  169. package/dist/gateway/inbox.js.map +1 -1
  170. package/dist/gateway/platform-config.d.ts +14 -0
  171. package/dist/gateway/platform-config.d.ts.map +1 -1
  172. package/dist/gateway/platform-config.js +26 -8
  173. package/dist/gateway/platform-config.js.map +1 -1
  174. package/dist/gateway/realtime.d.ts +114 -0
  175. package/dist/gateway/realtime.d.ts.map +1 -0
  176. package/dist/gateway/realtime.js +402 -0
  177. package/dist/gateway/realtime.js.map +1 -0
  178. package/dist/gateway/registry.d.ts +31 -0
  179. package/dist/gateway/registry.d.ts.map +1 -1
  180. package/dist/gateway/registry.js +224 -4
  181. package/dist/gateway/registry.js.map +1 -1
  182. package/dist/gateway/whatsapp/baileys-bridge.d.ts +11 -1
  183. package/dist/gateway/whatsapp/baileys-bridge.d.ts.map +1 -1
  184. package/dist/gateway/whatsapp/baileys-bridge.js +123 -4
  185. package/dist/gateway/whatsapp/baileys-bridge.js.map +1 -1
  186. package/dist/gateway/whatsapp/bridge.d.ts +6 -2
  187. package/dist/gateway/whatsapp/bridge.d.ts.map +1 -1
  188. package/dist/gateway/whatsapp/bridge.js.map +1 -1
  189. package/dist/index.js +8 -0
  190. package/dist/index.js.map +1 -1
  191. package/dist/inference/factory.d.ts +14 -0
  192. package/dist/inference/factory.d.ts.map +1 -1
  193. package/dist/inference/factory.js +17 -0
  194. package/dist/inference/factory.js.map +1 -1
  195. package/dist/inference/groq-adapter.d.ts +2 -0
  196. package/dist/inference/groq-adapter.d.ts.map +1 -1
  197. package/dist/inference/groq-adapter.js +16 -6
  198. package/dist/inference/groq-adapter.js.map +1 -1
  199. package/dist/inference/model-validator.d.ts +6 -1
  200. package/dist/inference/model-validator.d.ts.map +1 -1
  201. package/dist/inference/model-validator.js +7 -2
  202. package/dist/inference/model-validator.js.map +1 -1
  203. package/dist/inference/route-resolver.d.ts +116 -0
  204. package/dist/inference/route-resolver.d.ts.map +1 -0
  205. package/dist/inference/route-resolver.js +159 -0
  206. package/dist/inference/route-resolver.js.map +1 -0
  207. package/dist/inference/tools.d.ts.map +1 -1
  208. package/dist/inference/tools.js +29 -0
  209. package/dist/inference/tools.js.map +1 -1
  210. package/dist/learning/autonomy-policy.d.ts +18 -0
  211. package/dist/learning/autonomy-policy.d.ts.map +1 -1
  212. package/dist/learning/autonomy-policy.js +35 -0
  213. package/dist/learning/autonomy-policy.js.map +1 -1
  214. package/dist/learning/benchmark.d.ts.map +1 -1
  215. package/dist/learning/benchmark.js +3 -2
  216. package/dist/learning/benchmark.js.map +1 -1
  217. package/dist/learning/continuation.d.ts.map +1 -1
  218. package/dist/learning/continuation.js +2 -1
  219. package/dist/learning/continuation.js.map +1 -1
  220. package/dist/learning/cost-tracker.d.ts.map +1 -1
  221. package/dist/learning/cost-tracker.js +2 -1
  222. package/dist/learning/cost-tracker.js.map +1 -1
  223. package/dist/learning/deferred-task.d.ts.map +1 -1
  224. package/dist/learning/deferred-task.js +13 -4
  225. package/dist/learning/deferred-task.js.map +1 -1
  226. package/dist/learning/eval-framework.d.ts.map +1 -1
  227. package/dist/learning/eval-framework.js +2 -1
  228. package/dist/learning/eval-framework.js.map +1 -1
  229. package/dist/learning/long-form.d.ts.map +1 -1
  230. package/dist/learning/long-form.js +2 -1
  231. package/dist/learning/long-form.js.map +1 -1
  232. package/dist/learning/model-registry.d.ts.map +1 -1
  233. package/dist/learning/model-registry.js +2 -1
  234. package/dist/learning/model-registry.js.map +1 -1
  235. package/dist/learning/reasoning-cache.d.ts.map +1 -1
  236. package/dist/learning/reasoning-cache.js +2 -1
  237. package/dist/learning/reasoning-cache.js.map +1 -1
  238. package/dist/learning/reasoning-trace.d.ts +38 -2
  239. package/dist/learning/reasoning-trace.d.ts.map +1 -1
  240. package/dist/learning/reasoning-trace.js +91 -1
  241. package/dist/learning/reasoning-trace.js.map +1 -1
  242. package/dist/learning/resilient-call.d.ts.map +1 -1
  243. package/dist/learning/resilient-call.js +31 -18
  244. package/dist/learning/resilient-call.js.map +1 -1
  245. package/dist/learning/retrieval.d.ts.map +1 -1
  246. package/dist/learning/retrieval.js +2 -1
  247. package/dist/learning/retrieval.js.map +1 -1
  248. package/dist/learning/seeded-benchmark.d.ts +160 -0
  249. package/dist/learning/seeded-benchmark.d.ts.map +1 -0
  250. package/dist/learning/seeded-benchmark.js +321 -0
  251. package/dist/learning/seeded-benchmark.js.map +1 -0
  252. package/dist/learning/seeded-bugs.d.ts +142 -0
  253. package/dist/learning/seeded-bugs.d.ts.map +1 -0
  254. package/dist/learning/seeded-bugs.js +535 -0
  255. package/dist/learning/seeded-bugs.js.map +1 -0
  256. package/dist/learning/skill-store.d.ts.map +1 -1
  257. package/dist/learning/skill-store.js +30 -9
  258. package/dist/learning/skill-store.js.map +1 -1
  259. package/dist/learning/step-checkpoint.d.ts +127 -0
  260. package/dist/learning/step-checkpoint.d.ts.map +1 -0
  261. package/dist/learning/step-checkpoint.js +244 -0
  262. package/dist/learning/step-checkpoint.js.map +1 -0
  263. package/dist/mcp/catalog.js +2 -3
  264. package/dist/mcp/catalog.js.map +1 -1
  265. package/dist/mcp/manager.d.ts.map +1 -1
  266. package/dist/mcp/manager.js +5 -3
  267. package/dist/mcp/manager.js.map +1 -1
  268. package/dist/nlu/intent-confirm.d.ts +23 -1
  269. package/dist/nlu/intent-confirm.d.ts.map +1 -1
  270. package/dist/nlu/intent-confirm.js +85 -2
  271. package/dist/nlu/intent-confirm.js.map +1 -1
  272. package/dist/nlu/learnings.d.ts +7 -0
  273. package/dist/nlu/learnings.d.ts.map +1 -1
  274. package/dist/nlu/learnings.js +7 -0
  275. package/dist/nlu/learnings.js.map +1 -1
  276. package/dist/observability/debug-log.d.ts +250 -0
  277. package/dist/observability/debug-log.d.ts.map +1 -0
  278. package/dist/observability/debug-log.js +500 -0
  279. package/dist/observability/debug-log.js.map +1 -0
  280. package/dist/observability/event-bus.d.ts.map +1 -1
  281. package/dist/observability/event-bus.js +4 -1
  282. package/dist/observability/event-bus.js.map +1 -1
  283. package/dist/observability/otel.d.ts +278 -0
  284. package/dist/observability/otel.d.ts.map +1 -0
  285. package/dist/observability/otel.js +590 -0
  286. package/dist/observability/otel.js.map +1 -0
  287. package/dist/parity/drivers.d.ts +99 -0
  288. package/dist/parity/drivers.d.ts.map +1 -0
  289. package/dist/parity/drivers.js +1362 -0
  290. package/dist/parity/drivers.js.map +1 -0
  291. package/dist/parity/graph.d.ts +73 -0
  292. package/dist/parity/graph.d.ts.map +1 -0
  293. package/dist/parity/graph.js +162 -0
  294. package/dist/parity/graph.js.map +1 -0
  295. package/dist/parity/matrix.d.ts +105 -0
  296. package/dist/parity/matrix.d.ts.map +1 -0
  297. package/dist/parity/matrix.js +352 -0
  298. package/dist/parity/matrix.js.map +1 -0
  299. package/dist/parity/observation.d.ts +444 -0
  300. package/dist/parity/observation.d.ts.map +1 -0
  301. package/dist/parity/observation.js +333 -0
  302. package/dist/parity/observation.js.map +1 -0
  303. package/dist/parity/scenarios.d.ts +229 -0
  304. package/dist/parity/scenarios.d.ts.map +1 -0
  305. package/dist/parity/scenarios.js +175 -0
  306. package/dist/parity/scenarios.js.map +1 -0
  307. package/dist/parity/surfaces.d.ts +122 -0
  308. package/dist/parity/surfaces.d.ts.map +1 -0
  309. package/dist/parity/surfaces.js +190 -0
  310. package/dist/parity/surfaces.js.map +1 -0
  311. package/dist/runtime/fault-injection.d.ts +173 -0
  312. package/dist/runtime/fault-injection.d.ts.map +1 -0
  313. package/dist/runtime/fault-injection.js +281 -0
  314. package/dist/runtime/fault-injection.js.map +1 -0
  315. package/dist/skills/secret-capture.d.ts.map +1 -1
  316. package/dist/skills/secret-capture.js +9 -4
  317. package/dist/skills/secret-capture.js.map +1 -1
  318. package/dist/tools/child-agent-entry.d.ts +23 -0
  319. package/dist/tools/child-agent-entry.d.ts.map +1 -0
  320. package/dist/tools/child-agent-entry.js +129 -0
  321. package/dist/tools/child-agent-entry.js.map +1 -0
  322. package/dist/tools/child-agent-runtime.d.ts +124 -0
  323. package/dist/tools/child-agent-runtime.d.ts.map +1 -0
  324. package/dist/tools/child-agent-runtime.js +704 -0
  325. package/dist/tools/child-agent-runtime.js.map +1 -0
  326. package/dist/tools/coding-tools.d.ts.map +1 -1
  327. package/dist/tools/coding-tools.js +82 -10
  328. package/dist/tools/coding-tools.js.map +1 -1
  329. package/dist/tools/credentials-tool.d.ts +24 -0
  330. package/dist/tools/credentials-tool.d.ts.map +1 -0
  331. package/dist/tools/credentials-tool.js +125 -0
  332. package/dist/tools/credentials-tool.js.map +1 -0
  333. package/dist/tools/delegation-system.d.ts +31 -0
  334. package/dist/tools/delegation-system.d.ts.map +1 -1
  335. package/dist/tools/delegation-system.js +70 -9
  336. package/dist/tools/delegation-system.js.map +1 -1
  337. package/dist/tools/extract/docx.d.ts +27 -0
  338. package/dist/tools/extract/docx.d.ts.map +1 -0
  339. package/dist/tools/extract/docx.js +48 -0
  340. package/dist/tools/extract/docx.js.map +1 -0
  341. package/dist/tools/extract/html-text.d.ts +27 -0
  342. package/dist/tools/extract/html-text.d.ts.map +1 -0
  343. package/dist/tools/extract/html-text.js +86 -0
  344. package/dist/tools/extract/html-text.js.map +1 -0
  345. package/dist/tools/extract/pdf-ocr.d.ts +58 -0
  346. package/dist/tools/extract/pdf-ocr.d.ts.map +1 -0
  347. package/dist/tools/extract/pdf-ocr.js +116 -0
  348. package/dist/tools/extract/pdf-ocr.js.map +1 -0
  349. package/dist/tools/extract/pdf.d.ts +65 -0
  350. package/dist/tools/extract/pdf.d.ts.map +1 -0
  351. package/dist/tools/extract/pdf.js +197 -0
  352. package/dist/tools/extract/pdf.js.map +1 -0
  353. package/dist/tools/extract/pptx.d.ts +32 -0
  354. package/dist/tools/extract/pptx.d.ts.map +1 -0
  355. package/dist/tools/extract/pptx.js +77 -0
  356. package/dist/tools/extract/pptx.js.map +1 -0
  357. package/dist/tools/extract/xlsx.d.ts +47 -0
  358. package/dist/tools/extract/xlsx.d.ts.map +1 -0
  359. package/dist/tools/extract/xlsx.js +111 -0
  360. package/dist/tools/extract/xlsx.js.map +1 -0
  361. package/dist/tools/finding-tool.d.ts +76 -0
  362. package/dist/tools/finding-tool.d.ts.map +1 -0
  363. package/dist/tools/finding-tool.js +125 -0
  364. package/dist/tools/finding-tool.js.map +1 -0
  365. package/dist/tools/git-tool.d.ts +25 -7
  366. package/dist/tools/git-tool.d.ts.map +1 -1
  367. package/dist/tools/git-tool.js +155 -15
  368. package/dist/tools/git-tool.js.map +1 -1
  369. package/dist/tools/loop-project-context.d.ts.map +1 -1
  370. package/dist/tools/loop-project-context.js +16 -0
  371. package/dist/tools/loop-project-context.js.map +1 -1
  372. package/dist/tools/loop-route-feed.d.ts +57 -0
  373. package/dist/tools/loop-route-feed.d.ts.map +1 -0
  374. package/dist/tools/loop-route-feed.js +101 -0
  375. package/dist/tools/loop-route-feed.js.map +1 -0
  376. package/dist/tools/messaging-tools.d.ts +41 -11
  377. package/dist/tools/messaging-tools.d.ts.map +1 -1
  378. package/dist/tools/messaging-tools.js +104 -55
  379. package/dist/tools/messaging-tools.js.map +1 -1
  380. package/dist/tools/neutts-synth.d.ts +27 -3
  381. package/dist/tools/neutts-synth.d.ts.map +1 -1
  382. package/dist/tools/neutts-synth.js +57 -13
  383. package/dist/tools/neutts-synth.js.map +1 -1
  384. package/dist/tools/pipeline-tool.d.ts +43 -1
  385. package/dist/tools/pipeline-tool.d.ts.map +1 -1
  386. package/dist/tools/pipeline-tool.js +21 -4
  387. package/dist/tools/pipeline-tool.js.map +1 -1
  388. package/dist/tools/publish-tool.d.ts.map +1 -1
  389. package/dist/tools/publish-tool.js +76 -10
  390. package/dist/tools/publish-tool.js.map +1 -1
  391. package/dist/tools/read-extract.d.ts +116 -45
  392. package/dist/tools/read-extract.d.ts.map +1 -1
  393. package/dist/tools/read-extract.js +494 -158
  394. package/dist/tools/read-extract.js.map +1 -1
  395. package/dist/tools/registry.d.ts +23 -3
  396. package/dist/tools/registry.d.ts.map +1 -1
  397. package/dist/tools/registry.js +196 -29
  398. package/dist/tools/registry.js.map +1 -1
  399. package/dist/tools/run-terminal.d.ts +9 -0
  400. package/dist/tools/run-terminal.d.ts.map +1 -1
  401. package/dist/tools/run-terminal.js +80 -2
  402. package/dist/tools/run-terminal.js.map +1 -1
  403. package/dist/tools/subagent-refusal.d.ts +15 -0
  404. package/dist/tools/subagent-refusal.d.ts.map +1 -0
  405. package/dist/tools/subagent-refusal.js +18 -0
  406. package/dist/tools/subagent-refusal.js.map +1 -0
  407. package/dist/tools/subagent-spawner.d.ts +122 -0
  408. package/dist/tools/subagent-spawner.d.ts.map +1 -1
  409. package/dist/tools/subagent-spawner.js +249 -28
  410. package/dist/tools/subagent-spawner.js.map +1 -1
  411. package/dist/tools/tool-hooks.d.ts +177 -0
  412. package/dist/tools/tool-hooks.d.ts.map +1 -0
  413. package/dist/tools/tool-hooks.js +427 -0
  414. package/dist/tools/tool-hooks.js.map +1 -0
  415. package/dist/tools/tool-loop.d.ts +94 -5
  416. package/dist/tools/tool-loop.d.ts.map +1 -1
  417. package/dist/tools/tool-loop.js +315 -9
  418. package/dist/tools/tool-loop.js.map +1 -1
  419. package/dist/tools/tool-refusal.d.ts +68 -0
  420. package/dist/tools/tool-refusal.d.ts.map +1 -0
  421. package/dist/tools/tool-refusal.js +78 -0
  422. package/dist/tools/tool-refusal.js.map +1 -0
  423. package/dist/tools/toolsets.d.ts +8 -0
  424. package/dist/tools/toolsets.d.ts.map +1 -1
  425. package/dist/tools/toolsets.js +14 -4
  426. package/dist/tools/toolsets.js.map +1 -1
  427. package/dist/tools/vision-tools.d.ts +88 -83
  428. package/dist/tools/vision-tools.d.ts.map +1 -1
  429. package/dist/tools/vision-tools.js +134 -103
  430. package/dist/tools/vision-tools.js.map +1 -1
  431. package/dist/tools/worktree.d.ts +210 -0
  432. package/dist/tools/worktree.d.ts.map +1 -0
  433. package/dist/tools/worktree.js +374 -0
  434. package/dist/tools/worktree.js.map +1 -0
  435. package/dist/utils/format.d.ts +3 -0
  436. package/dist/utils/format.d.ts.map +1 -0
  437. package/dist/utils/format.js +32 -0
  438. package/dist/utils/format.js.map +1 -0
  439. package/dist/web-dashboard/attachment-extract.d.ts +64 -0
  440. package/dist/web-dashboard/attachment-extract.d.ts.map +1 -0
  441. package/dist/web-dashboard/attachment-extract.js +154 -0
  442. package/dist/web-dashboard/attachment-extract.js.map +1 -0
  443. package/dist/web-dashboard/chat-console.d.ts +108 -1
  444. package/dist/web-dashboard/chat-console.d.ts.map +1 -1
  445. package/dist/web-dashboard/chat-console.js +36 -0
  446. package/dist/web-dashboard/chat-console.js.map +1 -1
  447. package/dist/web-dashboard/hub-data.d.ts +37 -0
  448. package/dist/web-dashboard/hub-data.d.ts.map +1 -1
  449. package/dist/web-dashboard/hub-data.js +61 -1
  450. package/dist/web-dashboard/hub-data.js.map +1 -1
  451. package/dist/web-dashboard/server.d.ts +14 -0
  452. package/dist/web-dashboard/server.d.ts.map +1 -1
  453. package/dist/web-dashboard/server.js +247 -13
  454. package/dist/web-dashboard/server.js.map +1 -1
  455. package/dist/web-dashboard/src/types.d.ts +196 -48
  456. package/dist/web-dashboard/src/types.d.ts.map +1 -1
  457. package/dist/workflow/registry.js +1 -1
  458. package/dist/workflow/registry.js.map +1 -1
  459. package/package.json +22 -6
  460. package/src/web-dashboard/public/assets/{index-Cyd6tIew.css โ†’ index-XJjj2cBX.css} +1 -1
  461. package/src/web-dashboard/public/assets/index-YWF9FpwQ.js +207 -0
  462. package/src/web-dashboard/public/assets/index-YWF9FpwQ.js.map +1 -0
  463. package/src/web-dashboard/public/index.html +2 -2
  464. package/dist/tools/child-agent-worker.js +0 -212
  465. package/src/web-dashboard/public/assets/index-CjvoBhlz.js +0 -207
  466. package/src/web-dashboard/public/assets/index-CjvoBhlz.js.map +0 -1
@@ -0,0 +1,210 @@
1
+ /**
2
+ * WS5 (#27) โ€” a turn's own git worktree, and the diff it leaves behind.
3
+ *
4
+ * WHY A WORKTREE AT ALL. The ask is "try this and show me what changed". Running
5
+ * that in the operator's own tree makes the answer inseparable from the damage: a
6
+ * turn that edits twelve files to test one hypothesis has changed the tree the
7
+ * operator is working in, and the only record of it is whatever they notice. A
8
+ * second checkout of the SAME repository (a `git worktree`) gives the turn a real
9
+ * tree โ€” same code, same test runner, same `node_modules` โ€” that can be thrown
10
+ * away, and turns "what changed" into a diff against the commit it started from.
11
+ *
12
+ * WHY THE BASE IS `HEAD`, AND WHY THE NOTICE SAYS SO. `git worktree add โ€ฆ HEAD`
13
+ * checks out a commit, so UNCOMMITTED work in the operator's tree is not visible
14
+ * inside the copy. That is a real trap โ€” a run that "did not see my edit" โ€” so the
15
+ * number of dirty files in the source tree is MEASURED at creation and reported,
16
+ * rather than left to be discovered. A clean tree reports nothing.
17
+ *
18
+ * WHY IT REFUSES INSTEAD OF DEGRADING. Not every directory can be isolated: not a
19
+ * repository, no commit yet, no `git` at all. The tempting behaviour โ€” run in the
20
+ * real tree and report the turn normally โ€” is the one outcome this feature exists
21
+ * to prevent, because the caller acts on a diff that describes a tree nobody ran
22
+ * in. So isolation either happens or the turn STOPS, and the refusal says why.
23
+ *
24
+ * WHY THE DIFF IS MEASURED BEFORE TEARDOWN. Removing the worktree is what
25
+ * destroys the evidence, so the order is not a detail: measure, then remove. A
26
+ * teardown that fails (a git lock, a file handle) is reported as "not removed"
27
+ * rather than assumed, since the directory is left in the operator's profile with
28
+ * a branch pointing at it.
29
+ *
30
+ * GIT'S OWN STDOUT IS KEPT SEPARATE FROM THE MESSAGE. One helper here returns a
31
+ * never-empty `out` (git printing nothing is a fact worth a sentence), and a
32
+ * second field `raw` holding exactly what git wrote. Counting or parsing `out` is
33
+ * how a PRISTINE repository came to be reported as having one uncommitted change:
34
+ * `git status --porcelain` prints nothing, the fallback sentence has one line, and
35
+ * the count was taken from the sentence (see TOOL_TRUTHFULNESS_TRACKER).
36
+ */
37
+ /** The environment key a deployment asks for isolation through. */
38
+ export declare const WORKTREE_ENABLE_ENV = "NUVIRA_ISOLATE";
39
+ /** The environment keys a forked child reads to learn which worktree it is in. */
40
+ export declare const WORKTREE_DIR_ENV = "NUVIRA_WORKTREE_DIR";
41
+ export declare const WORKTREE_BASE_ENV = "NUVIRA_WORKTREE_BASE";
42
+ /** How long `git worktree add` may take โ€” a big repository is still a checkout. */
43
+ export declare const WORKTREE_CREATE_TIMEOUT_MS = 20000;
44
+ /** Bound on one file's diff body, so a huge change cannot be handed over whole. */
45
+ export declare const WORKTREE_PATCH_CHARS = 120000;
46
+ /** โ”€โ”€โ”€ Requests โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */
47
+ /**
48
+ * What an isolation request resolved to.
49
+ *
50
+ * Exactly two fields, and no more: the parity suite asserts the shape of a
51
+ * default request (`{asked: false, keep: false}`), so a third field added here
52
+ * would be a silent change to a documented value. `asked` and `keep` are kept
53
+ * apart because asking to be isolated and asking to KEEP the result are separate
54
+ * decisions, and a plain `--worktree` must not leave a directory behind.
55
+ */
56
+ export interface IsolationRequest {
57
+ asked: boolean;
58
+ keep: boolean;
59
+ }
60
+ /**
61
+ * Resolve an isolation request from a caller's options, with the environment as
62
+ * the fallback โ€” not the other way round.
63
+ *
64
+ * `undefined` means "nobody said anything", and only then does `NUVIRA_ISOLATE`
65
+ * decide. An explicit `false` is a DECISION (a surface that offers an off switch
66
+ * must be able to turn a deployment's `NUVIRA_ISOLATE=1` off for one turn), and
67
+ * it outranks the environment. This is the distinction a commander-style `false`
68
+ * default destroys: with one, every CLI turn carries an explicit decline and the
69
+ * documented `NUVIRA_ISOLATE=1` is unreachable from the command line.
70
+ */
71
+ export declare function resolveIsolationRequest(input: {
72
+ worktree?: boolean;
73
+ keepWorktree?: boolean;
74
+ }): IsolationRequest;
75
+ /**
76
+ * Why `repoCwd` cannot be isolated, or null when it can.
77
+ *
78
+ * Shared by the refusal path and by the parity harness, which uses it to assert
79
+ * that the checkout it is about to drive CAN be isolated โ€” a harness that
80
+ * silently proved nothing because it ran somewhere unisolatable would be worse
81
+ * than a failure.
82
+ */
83
+ export declare function worktreeRefusal(repoCwd: string): string | null;
84
+ /** The refusal, as the operator reads it. A failure, not a degradation. */
85
+ export declare function isolationRefusalText(why: string): string;
86
+ /** โ”€โ”€โ”€ The worktree โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */
87
+ /** A live worktree: where it is, and the commit everything is measured against. */
88
+ export interface IsolatedWorktree {
89
+ /** The checkout the turn runs in. */
90
+ dir: string;
91
+ /** The commit the diff is against (full sha). */
92
+ base: string;
93
+ /** The branch the worktree is checked out on, created with it. */
94
+ branch: string;
95
+ /** The repository it was created from. */
96
+ repoCwd: string;
97
+ /** Uncommitted paths in the SOURCE tree, which the copy cannot see. */
98
+ sourceDirty: number;
99
+ }
100
+ /**
101
+ * Make a worktree of `repoCwd`, or return null when that is impossible.
102
+ *
103
+ * `node_modules` is LINKED rather than installed: a worktree has no dependencies
104
+ * of its own, and an isolated turn that could not run a test would measure
105
+ * nothing. The link is best-effort โ€” a filesystem that cannot symlink still gets
106
+ * an isolated tree, just one without dependencies.
107
+ */
108
+ export declare function createIsolatedWorktree(input: {
109
+ repoCwd: string;
110
+ label: string;
111
+ timeoutMs?: number;
112
+ }): IsolatedWorktree | null;
113
+ /** โ”€โ”€โ”€ The diff โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */
114
+ /**
115
+ * What an isolated turn changed.
116
+ *
117
+ * NOTE THE TWO HALVES OF `diff`, because they are not the same list and reading
118
+ * the wrong one renders an empty card: `files` is the changed PATHS (one string
119
+ * per file โ€” what a reader scans), and `payload.files[].body` is the unified diff
120
+ * of each. `payload` deliberately has the shape the `git:diff` event already
121
+ * carries, so an isolated change renders with the diff card that is already
122
+ * there instead of a second renderer that could drift from it.
123
+ */
124
+ export interface WorktreeDiff {
125
+ /** Changed paths, sorted as git reports them. */
126
+ files: string[];
127
+ summary: string;
128
+ /** True when the run changed nothing โ€” a fact, not a failure. */
129
+ unchanged: boolean;
130
+ payload: {
131
+ files: Array<{
132
+ path: string;
133
+ body: string;
134
+ }>;
135
+ summary: string;
136
+ };
137
+ }
138
+ /**
139
+ * Measure the diff against the worktree's base commit.
140
+ *
141
+ * UNTRACKED FILES COUNT, and that is why the index is staged first: a run that
142
+ * CREATES a file has changed the tree, and `git diff` alone would report nothing
143
+ * for it. Staging inside a worktree that is about to be thrown away is free, and
144
+ * a worktree that is KEPT has its new files staged โ€” which is what `git diff
145
+ * --cached` reads on the next measurement.
146
+ */
147
+ export declare function worktreeDiff(handle: IsolatedWorktree, opts?: {
148
+ timeoutMs?: number;
149
+ }): WorktreeDiff;
150
+ /**
151
+ * Remove a worktree and the branch that was made with it.
152
+ *
153
+ * Returns whether the directory is GONE, not whether git was happy: a removal
154
+ * that succeeded but left the directory (a file handle, a lock) has still left a
155
+ * directory in the operator's profile, and "removed: true" is the claim the
156
+ * console prints.
157
+ */
158
+ export declare function discardWorktree(handle: IsolatedWorktree, opts?: {
159
+ timeoutMs?: number;
160
+ }): boolean;
161
+ /** โ”€โ”€โ”€ Lifecycle โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */
162
+ /** A started isolation: the worktree, or the refusal that replaced it. */
163
+ export type IsolationStart = {
164
+ ok: true;
165
+ worktree: IsolatedWorktree;
166
+ } | {
167
+ ok: false;
168
+ refusal: string;
169
+ };
170
+ /**
171
+ * Start isolation for a turn, or return null when nobody asked for one.
172
+ *
173
+ * Null and a refusal are different answers and both are load-bearing: null means
174
+ * the turn runs where it always did, and a refusal means the turn DOES NOT RUN.
175
+ */
176
+ export declare function beginIsolation(input: {
177
+ request: IsolationRequest;
178
+ repoCwd: string;
179
+ label: string;
180
+ }): IsolationStart | null;
181
+ /** The environment a forked child reads, so a tool can say where it is running. */
182
+ export declare function worktreeEnv(handle: IsolatedWorktree): Record<string, string>;
183
+ /**
184
+ * Where the turn is running, said when it starts.
185
+ *
186
+ * The base commit is named as a commit AND as a branch, and the dirty count is
187
+ * reported when it is non-zero โ€” the two facts that decide whether the diff at
188
+ * the end describes what the operator expected.
189
+ */
190
+ export declare function worktreeNotice(handle: IsolatedWorktree): string;
191
+ /** What the turn changed, what happened to the directory, and the diff itself. */
192
+ export interface IsolationOutcome {
193
+ dir: string;
194
+ base: string;
195
+ diff: WorktreeDiff;
196
+ /** False when the directory was KEPT (`--keep-worktree`). */
197
+ removed: boolean;
198
+ /** The operator-facing line (see `worktreeNotice` / this module's `notice`). */
199
+ notice: string;
200
+ }
201
+ /**
202
+ * Finish isolation: measure the diff, then tear the worktree down (unless kept).
203
+ *
204
+ * Never throws โ€” the caller attaches this to the turn's own result, and a git
205
+ * error must not replace an answer with a message about a directory.
206
+ */
207
+ export declare function endIsolation(handle: IsolatedWorktree, opts: {
208
+ keep: boolean;
209
+ }): IsolationOutcome;
210
+ //# sourceMappingURL=worktree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../src/tools/worktree.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AASH,mEAAmE;AACnE,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AACpD,kFAAkF;AAClF,eAAO,MAAM,gBAAgB,wBAAwB,CAAC;AACtD,eAAO,MAAM,iBAAiB,yBAAyB,CAAC;AACxD,mFAAmF;AACnF,eAAO,MAAM,0BAA0B,QAAS,CAAC;AACjD,mFAAmF;AACnF,eAAO,MAAM,oBAAoB,SAAU,CAAC;AAE5C,mFAAmF;AAEnF;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,GAAG,gBAAgB,CAMnB;AAoED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS9D;AAED,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED,mFAAmF;AAEnF,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B,qCAAqC;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,WAAW,EAAE,MAAM,CAAC;CACrB;AAoBD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,gBAAgB,GAAG,IAAI,CA0C1B;AAED,mFAAmF;AAEnF;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B,iDAAiD;IACjD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE;QACP,KAAK,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC7C,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AA2BD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,gBAAgB,EACxB,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAChC,YAAY,CA0Bd;AASD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CA0BpG;AAED,mFAAmF;AAEnF,0EAA0E;AAC1E,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,gBAAgB,CAAA;CAAE,GACxC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnC;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,cAAc,GAAG,IAAI,CAUxB;AAED,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAK5E;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAW/D;AAED,kFAAkF;AAClF,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,CAAC;IACnB,6DAA6D;IAC7D,OAAO,EAAE,OAAO,CAAC;IACjB,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG,gBAAgB,CAqBhG"}
@@ -0,0 +1,374 @@
1
+ /**
2
+ * WS5 (#27) โ€” a turn's own git worktree, and the diff it leaves behind.
3
+ *
4
+ * WHY A WORKTREE AT ALL. The ask is "try this and show me what changed". Running
5
+ * that in the operator's own tree makes the answer inseparable from the damage: a
6
+ * turn that edits twelve files to test one hypothesis has changed the tree the
7
+ * operator is working in, and the only record of it is whatever they notice. A
8
+ * second checkout of the SAME repository (a `git worktree`) gives the turn a real
9
+ * tree โ€” same code, same test runner, same `node_modules` โ€” that can be thrown
10
+ * away, and turns "what changed" into a diff against the commit it started from.
11
+ *
12
+ * WHY THE BASE IS `HEAD`, AND WHY THE NOTICE SAYS SO. `git worktree add โ€ฆ HEAD`
13
+ * checks out a commit, so UNCOMMITTED work in the operator's tree is not visible
14
+ * inside the copy. That is a real trap โ€” a run that "did not see my edit" โ€” so the
15
+ * number of dirty files in the source tree is MEASURED at creation and reported,
16
+ * rather than left to be discovered. A clean tree reports nothing.
17
+ *
18
+ * WHY IT REFUSES INSTEAD OF DEGRADING. Not every directory can be isolated: not a
19
+ * repository, no commit yet, no `git` at all. The tempting behaviour โ€” run in the
20
+ * real tree and report the turn normally โ€” is the one outcome this feature exists
21
+ * to prevent, because the caller acts on a diff that describes a tree nobody ran
22
+ * in. So isolation either happens or the turn STOPS, and the refusal says why.
23
+ *
24
+ * WHY THE DIFF IS MEASURED BEFORE TEARDOWN. Removing the worktree is what
25
+ * destroys the evidence, so the order is not a detail: measure, then remove. A
26
+ * teardown that fails (a git lock, a file handle) is reported as "not removed"
27
+ * rather than assumed, since the directory is left in the operator's profile with
28
+ * a branch pointing at it.
29
+ *
30
+ * GIT'S OWN STDOUT IS KEPT SEPARATE FROM THE MESSAGE. One helper here returns a
31
+ * never-empty `out` (git printing nothing is a fact worth a sentence), and a
32
+ * second field `raw` holding exactly what git wrote. Counting or parsing `out` is
33
+ * how a PRISTINE repository came to be reported as having one uncommitted change:
34
+ * `git status --porcelain` prints nothing, the fallback sentence has one line, and
35
+ * the count was taken from the sentence (see TOOL_TRUTHFULNESS_TRACKER).
36
+ */
37
+ import { spawnSync } from 'node:child_process';
38
+ import { randomBytes } from 'node:crypto';
39
+ import { existsSync, mkdirSync, rmSync, symlinkSync } from 'node:fs';
40
+ import { join } from 'node:path';
41
+ import { envBuff, resolveNuviraHome } from '../config/paths.js';
42
+ /** The environment key a deployment asks for isolation through. */
43
+ export const WORKTREE_ENABLE_ENV = 'NUVIRA_ISOLATE';
44
+ /** The environment keys a forked child reads to learn which worktree it is in. */
45
+ export const WORKTREE_DIR_ENV = 'NUVIRA_WORKTREE_DIR';
46
+ export const WORKTREE_BASE_ENV = 'NUVIRA_WORKTREE_BASE';
47
+ /** How long `git worktree add` may take โ€” a big repository is still a checkout. */
48
+ export const WORKTREE_CREATE_TIMEOUT_MS = 20_000;
49
+ /** Bound on one file's diff body, so a huge change cannot be handed over whole. */
50
+ export const WORKTREE_PATCH_CHARS = 120_000;
51
+ /**
52
+ * Resolve an isolation request from a caller's options, with the environment as
53
+ * the fallback โ€” not the other way round.
54
+ *
55
+ * `undefined` means "nobody said anything", and only then does `NUVIRA_ISOLATE`
56
+ * decide. An explicit `false` is a DECISION (a surface that offers an off switch
57
+ * must be able to turn a deployment's `NUVIRA_ISOLATE=1` off for one turn), and
58
+ * it outranks the environment. This is the distinction a commander-style `false`
59
+ * default destroys: with one, every CLI turn carries an explicit decline and the
60
+ * documented `NUVIRA_ISOLATE=1` is unreachable from the command line.
61
+ */
62
+ export function resolveIsolationRequest(input) {
63
+ const asked = input.worktree === undefined ? envAsks(WORKTREE_ENABLE_ENV) : input.worktree === true;
64
+ // `keep` is only meaningful when isolation was asked for; a lever with nothing
65
+ // to keep would otherwise read as a request in its own right.
66
+ const keep = asked && input.keepWorktree === true;
67
+ return { asked, keep };
68
+ }
69
+ /** True when an environment key asks for something (`1`/`true`/`yes`). */
70
+ function envAsks(name) {
71
+ const raw = envBuff(name.replace(/^NUVIRA_/, ''));
72
+ if (raw === undefined)
73
+ return false;
74
+ const value = raw.trim().toLowerCase();
75
+ return value === '1' || value === 'true' || value === 'yes';
76
+ }
77
+ function gitRun(dir, args, timeoutMs = WORKTREE_CREATE_TIMEOUT_MS) {
78
+ try {
79
+ const r = spawnSync('git', args, {
80
+ cwd: dir,
81
+ encoding: 'utf-8',
82
+ timeout: timeoutMs,
83
+ maxBuffer: 64 * 1024 * 1024,
84
+ });
85
+ const raw = (r.stdout ?? '').trim();
86
+ return {
87
+ ok: r.status === 0,
88
+ raw,
89
+ out: raw || 'git reported no output',
90
+ err: (r.stderr ?? '').trim(),
91
+ };
92
+ }
93
+ catch (err) {
94
+ const message = err instanceof Error ? err.message : String(err);
95
+ return { ok: false, raw: '', out: 'git reported no output', err: message };
96
+ }
97
+ }
98
+ /**
99
+ * Files with uncommitted work in `dir`, counted from git's OWN output.
100
+ *
101
+ * Counts LINES of `raw`: `git status --porcelain` prints one line per changed or
102
+ * untracked path, and prints NOTHING for a clean tree โ€” which must count as zero,
103
+ * not as the one line of a fallback sentence.
104
+ */
105
+ function dirtyCount(dir) {
106
+ const status = gitRun(dir, ['status', '--porcelain'], 5_000);
107
+ if (!status.ok)
108
+ return 0;
109
+ return status.raw.split('\n').filter((line) => line.trim() !== '').length;
110
+ }
111
+ /** The commit a turn would start from, or null when there is none. */
112
+ function headOf(dir) {
113
+ const head = gitRun(dir, ['rev-parse', 'HEAD'], 5_000);
114
+ const sha = head.raw.trim();
115
+ return head.ok && /^[0-9a-f]{40}$/i.test(sha) ? sha : null;
116
+ }
117
+ /**
118
+ * Why `repoCwd` cannot be isolated, or null when it can.
119
+ *
120
+ * Shared by the refusal path and by the parity harness, which uses it to assert
121
+ * that the checkout it is about to drive CAN be isolated โ€” a harness that
122
+ * silently proved nothing because it ran somewhere unisolatable would be worse
123
+ * than a failure.
124
+ */
125
+ export function worktreeRefusal(repoCwd) {
126
+ const inside = gitRun(repoCwd, ['rev-parse', '--is-inside-work-tree'], 5_000);
127
+ if (!inside.ok || inside.raw.trim() !== 'true') {
128
+ return `'${repoCwd}' is not inside a git work tree (git is unavailable, or this is not a repository)`;
129
+ }
130
+ if (!headOf(repoCwd)) {
131
+ return `'${repoCwd}' has no commit to start from โ€” an isolated copy is a checkout of HEAD`;
132
+ }
133
+ return null;
134
+ }
135
+ /** The refusal, as the operator reads it. A failure, not a degradation. */
136
+ export function isolationRefusalText(why) {
137
+ return (`Isolation was requested, but this turn cannot be isolated: ${why}.\n` +
138
+ 'Nothing ran โ€” no model was called and no file was touched.');
139
+ }
140
+ /** Where worktrees live (`~/.nuvira/worktrees`, overridable for tests/CI). */
141
+ function worktreesRoot() {
142
+ return envBuff('WORKTREES_DIR') || join(resolveNuviraHome(), 'worktrees');
143
+ }
144
+ /** A filesystem- and branch-safe name for this turn, from its label. */
145
+ function worktreeName(label) {
146
+ const slug = label
147
+ .toLowerCase()
148
+ .replace(/[^a-z0-9]+/g, '-')
149
+ .replace(/^-+|-+$/g, '')
150
+ .slice(0, 32)
151
+ .replace(/-+$/g, '');
152
+ const stamp = randomBytes(4).toString('hex').slice(0, 6);
153
+ const salt = randomBytes(2).toString('hex').slice(0, 4);
154
+ return `${slug || 'turn'}-${stamp}-${salt}`;
155
+ }
156
+ /**
157
+ * Make a worktree of `repoCwd`, or return null when that is impossible.
158
+ *
159
+ * `node_modules` is LINKED rather than installed: a worktree has no dependencies
160
+ * of its own, and an isolated turn that could not run a test would measure
161
+ * nothing. The link is best-effort โ€” a filesystem that cannot symlink still gets
162
+ * an isolated tree, just one without dependencies.
163
+ */
164
+ export function createIsolatedWorktree(input) {
165
+ if (worktreeRefusal(input.repoCwd) !== null)
166
+ return null;
167
+ const base = headOf(input.repoCwd);
168
+ if (!base)
169
+ return null;
170
+ const name = worktreeName(input.label);
171
+ const dir = join(worktreesRoot(), name);
172
+ const branch = `nuvira/${name}`;
173
+ try {
174
+ mkdirSync(worktreesRoot(), { recursive: true });
175
+ }
176
+ catch {
177
+ return null;
178
+ }
179
+ const added = gitRun(input.repoCwd, ['worktree', 'add', '-b', branch, dir, 'HEAD'], input.timeoutMs ?? WORKTREE_CREATE_TIMEOUT_MS);
180
+ if (!added.ok) {
181
+ // Leave nothing behind: a half-made worktree registers with the parent repo
182
+ // even when the checkout failed.
183
+ try {
184
+ rmSync(dir, { recursive: true, force: true });
185
+ gitRun(input.repoCwd, ['worktree', 'prune'], 5_000);
186
+ }
187
+ catch {
188
+ /* best-effort */
189
+ }
190
+ return null;
191
+ }
192
+ const sourceModules = join(input.repoCwd, 'node_modules');
193
+ const linkedModules = join(dir, 'node_modules');
194
+ if (existsSync(sourceModules) && !existsSync(linkedModules)) {
195
+ try {
196
+ symlinkSync(sourceModules, linkedModules, 'dir');
197
+ }
198
+ catch {
199
+ /* a filesystem that cannot link still gets an isolated tree */
200
+ }
201
+ }
202
+ return { dir, base, branch, repoCwd: input.repoCwd, sourceDirty: dirtyCount(input.repoCwd) };
203
+ }
204
+ /** Split git's own unified diff into one body per file, keyed by path. */
205
+ function payloadOf(patch, files) {
206
+ const sections = patch.split(/^diff --git /m).filter((section) => section.trim() !== '');
207
+ const byPath = new Map();
208
+ for (const section of sections) {
209
+ // `a/<path> b/<path>` โ€” the path with a space in it is why this reads the
210
+ // `b/` side rather than splitting the line on whitespace.
211
+ const match = section.match(/^a\/(.+?) b\//);
212
+ if (!match)
213
+ continue;
214
+ byPath.set(match[1], `diff --git ${section}`.slice(0, WORKTREE_PATCH_CHARS));
215
+ }
216
+ return files.map((path) => ({ path, body: byPath.get(path) ?? '' }));
217
+ }
218
+ /**
219
+ * The pathspec that keeps the linked `node_modules` out of a measurement.
220
+ *
221
+ * The repository's own ignore rule is `node_modules/`, which matches a DIRECTORY โ€”
222
+ * and what a worktree gets is a SYMLINK, which that rule does not match at all. So
223
+ * a run that changed one file reported two, the second being the dependency link
224
+ * this module created itself. Excluded by pathspec rather than by writing an
225
+ * ignore file into the worktree, because the ignore file is the repository's.
226
+ */
227
+ const MEASURE_SCOPE = ['.', ':(exclude)node_modules'];
228
+ /**
229
+ * Measure the diff against the worktree's base commit.
230
+ *
231
+ * UNTRACKED FILES COUNT, and that is why the index is staged first: a run that
232
+ * CREATES a file has changed the tree, and `git diff` alone would report nothing
233
+ * for it. Staging inside a worktree that is about to be thrown away is free, and
234
+ * a worktree that is KEPT has its new files staged โ€” which is what `git diff
235
+ * --cached` reads on the next measurement.
236
+ */
237
+ export function worktreeDiff(handle, opts = {}) {
238
+ const timeout = opts.timeoutMs ?? WORKTREE_CREATE_TIMEOUT_MS;
239
+ gitRun(handle.dir, ['add', '-A', '--', ...MEASURE_SCOPE], timeout);
240
+ const names = gitRun(handle.dir, ['diff', '--cached', '--name-only', handle.base, '--', ...MEASURE_SCOPE], timeout);
241
+ const files = names.ok
242
+ ? names.raw.split('\n').map((line) => line.trim()).filter((line) => line !== '')
243
+ : [];
244
+ const short = handle.base.slice(0, 7);
245
+ const summary = files.length === 0
246
+ ? `nothing changed against ${short}`
247
+ : `${files.length} file${files.length === 1 ? '' : 's'} changed against ${short}`;
248
+ const patch = gitRun(handle.dir, ['diff', '--cached', handle.base, '--', ...MEASURE_SCOPE], timeout);
249
+ return {
250
+ files,
251
+ summary,
252
+ unchanged: files.length === 0,
253
+ payload: { files: payloadOf(patch.ok ? patch.raw : '', files), summary },
254
+ };
255
+ }
256
+ /** The honest "nothing is known yet" diff, for a measurement that failed. */
257
+ function unmeasuredDiff(base) {
258
+ const short = base.slice(0, 7);
259
+ const summary = `the diff against ${short} could not be measured`;
260
+ return { files: [], summary, unchanged: false, payload: { files: [], summary } };
261
+ }
262
+ /**
263
+ * Remove a worktree and the branch that was made with it.
264
+ *
265
+ * Returns whether the directory is GONE, not whether git was happy: a removal
266
+ * that succeeded but left the directory (a file handle, a lock) has still left a
267
+ * directory in the operator's profile, and "removed: true" is the claim the
268
+ * console prints.
269
+ */
270
+ export function discardWorktree(handle, opts = {}) {
271
+ const timeout = opts.timeoutMs ?? WORKTREE_CREATE_TIMEOUT_MS;
272
+ let gitSaid = false;
273
+ try {
274
+ gitSaid = gitRun(handle.repoCwd, ['worktree', 'remove', '--force', handle.dir], timeout).ok;
275
+ }
276
+ catch {
277
+ gitSaid = false;
278
+ }
279
+ if (existsSync(handle.dir)) {
280
+ try {
281
+ rmSync(handle.dir, { recursive: true, force: true });
282
+ }
283
+ catch {
284
+ /* fall through โ€” the directory decides */
285
+ }
286
+ }
287
+ try {
288
+ if (!existsSync(handle.dir))
289
+ gitRun(handle.repoCwd, ['branch', '-D', handle.branch], 5_000);
290
+ gitRun(handle.repoCwd, ['worktree', 'prune'], 5_000);
291
+ }
292
+ catch {
293
+ /* best-effort */
294
+ }
295
+ return gitSaid || !existsSync(handle.dir);
296
+ }
297
+ /**
298
+ * Start isolation for a turn, or return null when nobody asked for one.
299
+ *
300
+ * Null and a refusal are different answers and both are load-bearing: null means
301
+ * the turn runs where it always did, and a refusal means the turn DOES NOT RUN.
302
+ */
303
+ export function beginIsolation(input) {
304
+ if (!input.request.asked)
305
+ return null;
306
+ const why = worktreeRefusal(input.repoCwd);
307
+ if (why)
308
+ return { ok: false, refusal: isolationRefusalText(why) };
309
+ const worktree = createIsolatedWorktree({ repoCwd: input.repoCwd, label: input.label });
310
+ if (!worktree) {
311
+ const reason = worktreeRefusal(input.repoCwd) ?? 'the worktree could not be created';
312
+ return { ok: false, refusal: isolationRefusalText(reason) };
313
+ }
314
+ return { ok: true, worktree };
315
+ }
316
+ /** The environment a forked child reads, so a tool can say where it is running. */
317
+ export function worktreeEnv(handle) {
318
+ return {
319
+ [WORKTREE_DIR_ENV]: handle.dir,
320
+ [WORKTREE_BASE_ENV]: handle.base,
321
+ };
322
+ }
323
+ /**
324
+ * Where the turn is running, said when it starts.
325
+ *
326
+ * The base commit is named as a commit AND as a branch, and the dirty count is
327
+ * reported when it is non-zero โ€” the two facts that decide whether the diff at
328
+ * the end describes what the operator expected.
329
+ */
330
+ export function worktreeNotice(handle) {
331
+ const lines = [
332
+ `๐ŸŒฟ isolated in a git worktree: ${handle.dir}`,
333
+ ` base: ${handle.base.slice(0, 7)} (branch ${handle.branch})`,
334
+ ];
335
+ if (handle.sourceDirty > 0) {
336
+ lines.push(` note: ${handle.sourceDirty} uncommitted change(s) in the source tree are NOT in this worktree`);
337
+ }
338
+ return lines.join('\n');
339
+ }
340
+ /**
341
+ * Finish isolation: measure the diff, then tear the worktree down (unless kept).
342
+ *
343
+ * Never throws โ€” the caller attaches this to the turn's own result, and a git
344
+ * error must not replace an answer with a message about a directory.
345
+ */
346
+ export function endIsolation(handle, opts) {
347
+ let diff;
348
+ try {
349
+ diff = worktreeDiff(handle);
350
+ }
351
+ catch {
352
+ diff = unmeasuredDiff(handle.base);
353
+ }
354
+ let removed = false;
355
+ if (!opts.keep) {
356
+ try {
357
+ removed = discardWorktree(handle);
358
+ }
359
+ catch {
360
+ removed = false;
361
+ }
362
+ }
363
+ const lines = [` ${diff.summary}`];
364
+ for (const file of diff.files)
365
+ lines.push(` ยท ${file}`);
366
+ if (opts.keep)
367
+ lines.push(` (kept: ${handle.dir} โ€” nothing was removed)`);
368
+ else if (removed)
369
+ lines.push(' (the worktree was removed โ€” the diff above is what is left of it)');
370
+ else
371
+ lines.push(` (the worktree could NOT be removed: ${handle.dir})`);
372
+ return { dir: handle.dir, base: handle.base, diff, removed, notice: lines.join('\n') };
373
+ }
374
+ //# sourceMappingURL=worktree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree.js","sourceRoot":"","sources":["../../src/tools/worktree.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Format a count for display: `1048576` โ†’ `1,048,576`, on every machine. */
2
+ export declare function formatCount(n: number): string;
3
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"AA4BA,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7C"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Number formatting with a PINNED locale.
3
+ *
4
+ * WHY THIS EXISTS. `n.toLocaleString()` follows the machine's default locale, so
5
+ * one build printed `1,048,576` on an en-US box, `10,48,576` on en-IN and
6
+ * `1.048.576` on de-DE. That is wrong twice over:
7
+ *
8
+ * 1. A count in a report, a log line, or a bug report is a FACT, and it must
9
+ * read the same on every machine.
10
+ * 2. A locale-dependent value cannot be asserted deterministically. The
11
+ * dashboard chip suite and the long-form progress suite passed in CI and
12
+ * failed on a developer machine for exactly this reason, and de-DE renders a
13
+ * word count as `35.000`, which reads as a decimal rather than as 35,000.
14
+ *
15
+ * THE CONVENTION. Every user-visible number goes through {@link formatCount}.
16
+ * This is the same choice the codebase already made in the places it pinned a
17
+ * locale by hand (`toLocaleString('en-US')`, `toLocaleDateString('en-US', โ€ฆ)`) โ€”
18
+ * it is now made once, here, instead of at each call site.
19
+ *
20
+ * SCOPE. Numbers only. Dates still vary by machine in the sites that do not pass
21
+ * a locale; that is a separate decision and is deliberately not covered here.
22
+ *
23
+ * The locale is `en-US` because the grouping is unambiguous: it separates every
24
+ * three digits and never uses a character (a dot, a space, a narrow no-break
25
+ * space) that another locale would read as a decimal point.
26
+ */
27
+ const EN_US = new Intl.NumberFormat('en-US');
28
+ /** Format a count for display: `1048576` โ†’ `1,048,576`, on every machine. */
29
+ export function formatCount(n) {
30
+ return EN_US.format(n);
31
+ }
32
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;AAE7C,6EAA6E;AAC7E,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACzB,CAAC"}