@pugi/cli 0.1.0-beta.9 → 0.1.0-beta.91

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 (411) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/LICENSE +1 -1
  3. package/assets/pugi-prozr2-mascot.ansi +9 -0
  4. package/bin/run.js +33 -1
  5. package/dist/commands/deploy.js +40 -40
  6. package/dist/commands/flatten.js +191 -0
  7. package/dist/commands/jobs-watch.js +201 -0
  8. package/dist/commands/jobs.js +42 -27
  9. package/dist/commands/smoke.js +133 -0
  10. package/dist/core/agent-progress/cleanup.js +134 -0
  11. package/dist/core/agent-progress/schema.js +144 -0
  12. package/dist/core/agent-progress/writer.js +101 -0
  13. package/dist/core/agents/adaptive-router.js +330 -0
  14. package/dist/core/agents/query-decomposer.js +297 -0
  15. package/dist/core/agents/registry.js +3 -3
  16. package/dist/core/approvals/shortcut-resolver.js +98 -0
  17. package/dist/core/artifact-chain/dispatcher.js +148 -0
  18. package/dist/core/artifact-chain/exporter.js +164 -0
  19. package/dist/core/artifact-chain/state.js +243 -0
  20. package/dist/core/artifact-chain/steps.js +169 -0
  21. package/dist/core/ask-user/question.js +92 -0
  22. package/dist/core/audit/audit-trail.js +275 -0
  23. package/dist/core/auth/ensure-authenticated.js +129 -0
  24. package/dist/core/auth/env-provider.js +238 -0
  25. package/dist/core/auto-open-browser.js +4 -4
  26. package/dist/core/auto-update/channels.js +122 -0
  27. package/dist/core/auto-update/checker.js +241 -0
  28. package/dist/core/auto-update/state.js +235 -0
  29. package/dist/core/bare-mode/index.js +107 -0
  30. package/dist/core/bash/redirect.js +281 -0
  31. package/dist/core/bash-classifier.js +436 -40
  32. package/dist/core/checkpoint/resumer.js +149 -0
  33. package/dist/core/checkpoint/rewinder.js +291 -0
  34. package/dist/core/checkpoints/shadow-git.js +670 -0
  35. package/dist/core/citations/parser.js +109 -0
  36. package/dist/core/classifier/yolo-classifier.js +88 -0
  37. package/dist/core/codegraph/decision-store.js +248 -0
  38. package/dist/core/codegraph/detect-repo.js +459 -0
  39. package/dist/core/codegraph/install.js +134 -0
  40. package/dist/core/codegraph/offer-hook.js +220 -0
  41. package/dist/core/compact/auto-trigger.js +96 -0
  42. package/dist/core/compact/buffer-rewriter.js +115 -0
  43. package/dist/core/compact/summarizer.js +208 -0
  44. package/dist/core/compact/token-counter.js +108 -0
  45. package/dist/core/consensus/anvil-fanout.js +25 -25
  46. package/dist/core/consensus/diff-capture.js +121 -12
  47. package/dist/core/consensus/rubric.js +21 -21
  48. package/dist/core/context/builder.js +6 -6
  49. package/dist/core/context/compaction-events.js +8 -8
  50. package/dist/core/context/compaction.js +31 -31
  51. package/dist/core/context/index.js +15 -8
  52. package/dist/core/context/invariants.js +51 -51
  53. package/dist/core/context/markdown-loader.js +28 -10
  54. package/dist/core/context/markdown-traverse.js +255 -0
  55. package/dist/core/context/pugiignore.js +41 -41
  56. package/dist/core/context/repo-skeleton.js +37 -37
  57. package/dist/core/context/tool-eviction.js +55 -0
  58. package/dist/core/context/watcher.js +32 -32
  59. package/dist/core/context/working-set.js +23 -23
  60. package/dist/core/coordinator/agent-tools.js +77 -0
  61. package/dist/core/coordinator/agent-toolset.js +65 -0
  62. package/dist/core/coordinator/fsm.js +73 -0
  63. package/dist/core/coordinator/mode-fsm.js +70 -0
  64. package/dist/core/cost/rate-card.js +129 -0
  65. package/dist/core/cost/tracker.js +221 -0
  66. package/dist/core/credentials.js +13 -13
  67. package/dist/core/cron/scheduler.js +138 -0
  68. package/dist/core/denial-tracking/index.js +8 -0
  69. package/dist/core/denial-tracking/state.js +264 -0
  70. package/dist/core/diagnostics/probe-runner.js +93 -0
  71. package/dist/core/diagnostics/probes/api.js +46 -0
  72. package/dist/core/diagnostics/probes/auth.js +93 -0
  73. package/dist/core/diagnostics/probes/bare-mode.js +42 -0
  74. package/dist/core/diagnostics/probes/cli-version.js +127 -0
  75. package/dist/core/diagnostics/probes/config.js +72 -0
  76. package/dist/core/diagnostics/probes/denial-tracking.js +57 -0
  77. package/dist/core/diagnostics/probes/disk.js +81 -0
  78. package/dist/core/diagnostics/probes/engine-live.js +46 -0
  79. package/dist/core/diagnostics/probes/git.js +65 -0
  80. package/dist/core/diagnostics/probes/hooks.js +118 -0
  81. package/dist/core/diagnostics/probes/mcp.js +75 -0
  82. package/dist/core/diagnostics/probes/node.js +59 -0
  83. package/dist/core/diagnostics/probes/pnpm.js +36 -0
  84. package/dist/core/diagnostics/probes/pugi-md.js +89 -0
  85. package/dist/core/diagnostics/probes/sandbox.js +40 -0
  86. package/dist/core/diagnostics/probes/session.js +74 -0
  87. package/dist/core/diagnostics/probes/status-snapshot.js +488 -0
  88. package/dist/core/diagnostics/probes/workspace.js +63 -0
  89. package/dist/core/diagnostics/types.js +70 -0
  90. package/dist/core/dispatch/cache-cleanup.js +197 -0
  91. package/dist/core/dispatch/cache-handoff.js +295 -0
  92. package/dist/core/edits/apply-patch-layer-e.js +189 -0
  93. package/dist/core/edits/dispatch.js +333 -7
  94. package/dist/core/edits/format-detector.js +260 -0
  95. package/dist/core/edits/format-matrix.js +26 -0
  96. package/dist/core/edits/fuzzy-ladder.js +650 -0
  97. package/dist/core/edits/index.js +5 -1
  98. package/dist/core/edits/journal.js +199 -0
  99. package/dist/core/edits/layer-a-apply.js +15 -15
  100. package/dist/core/edits/layer-a-fuzzy-apply.js +198 -0
  101. package/dist/core/edits/layer-b-apply.js +9 -9
  102. package/dist/core/edits/layer-c-apply.js +6 -6
  103. package/dist/core/edits/layer-d-ast.js +557 -14
  104. package/dist/core/edits/marker-parser.js +12 -12
  105. package/dist/core/edits/security-gate.js +27 -27
  106. package/dist/core/edits/verify-hook.js +273 -0
  107. package/dist/core/edits/worktree.js +29 -29
  108. package/dist/core/engine/anvil-client.js +214 -26
  109. package/dist/core/engine/auto-compact.js +179 -0
  110. package/dist/core/engine/budgets.js +186 -0
  111. package/dist/core/engine/context-prefix.js +155 -0
  112. package/dist/core/engine/index.js +1 -1
  113. package/dist/core/engine/intensity.js +158 -0
  114. package/dist/core/engine/intent.js +260 -0
  115. package/dist/core/engine/native-pugi.js +1295 -227
  116. package/dist/core/engine/prompts.js +129 -19
  117. package/dist/core/engine/strip-internal-fields.js +124 -0
  118. package/dist/core/engine/tool-bridge.js +1792 -59
  119. package/dist/core/evaluation/golden-dataset.js +293 -0
  120. package/dist/core/feedback/queue.js +177 -0
  121. package/dist/core/feedback/submitter.js +145 -0
  122. package/dist/core/file-cache.js +113 -1
  123. package/dist/core/flatten/flatten-repo.js +439 -0
  124. package/dist/core/format/osc8-link.js +28 -0
  125. package/dist/core/hook-chains.js +392 -0
  126. package/dist/core/hooks/citation-verify-hook.js +138 -0
  127. package/dist/core/hooks/citation-verify.js +112 -0
  128. package/dist/core/hooks/events.js +46 -0
  129. package/dist/core/hooks/index.js +15 -0
  130. package/dist/core/hooks/registry.js +216 -0
  131. package/dist/core/hooks/runner.js +236 -0
  132. package/dist/core/hooks/v2/event-emitter.js +115 -0
  133. package/dist/core/hooks/v2/executor.js +282 -0
  134. package/dist/core/hooks/v2/index.js +25 -0
  135. package/dist/core/hooks/v2/lifecycle.js +104 -0
  136. package/dist/core/hooks/v2/loader.js +216 -0
  137. package/dist/core/hooks/v2/matcher.js +125 -0
  138. package/dist/core/hooks/v2/trust.js +143 -0
  139. package/dist/core/hooks/v2/types.js +86 -0
  140. package/dist/core/hooks/worktree-events.js +158 -0
  141. package/dist/core/image/renderer.js +71 -0
  142. package/dist/core/init/detector.js +582 -0
  143. package/dist/core/init/template-renderer.js +242 -0
  144. package/dist/core/jobs/registry.js +18 -18
  145. package/dist/core/ledger/results-tsv.js +142 -0
  146. package/dist/core/log-discipline/stdout-redirect.js +51 -0
  147. package/dist/core/lsp/cache.js +105 -0
  148. package/dist/core/lsp/client.js +551 -41
  149. package/dist/core/lsp/language-detect.js +66 -0
  150. package/dist/core/lsp/post-edit-diagnostics.js +171 -0
  151. package/dist/core/lsp/server-detect.js +173 -0
  152. package/dist/core/lsp/symbol-cache.js +162 -0
  153. package/dist/core/lsp/symbol-tools.js +664 -0
  154. package/dist/core/mcp/client.js +97 -28
  155. package/dist/core/mcp/http-server.js +553 -0
  156. package/dist/core/mcp/orchestrator-tools.js +662 -0
  157. package/dist/core/mcp/permission.js +190 -0
  158. package/dist/core/mcp/registry.js +39 -17
  159. package/dist/core/mcp/server-tools.js +219 -0
  160. package/dist/core/mcp/server.js +397 -0
  161. package/dist/core/mcp/trust.js +10 -10
  162. package/dist/core/memory/dual-write.js +416 -0
  163. package/dist/core/memory/passive-extract.js +130 -0
  164. package/dist/core/memory/phase1-kinds.js +20 -0
  165. package/dist/core/memory/secret-scanner.js +304 -0
  166. package/dist/core/memory-sync/queue.js +170 -0
  167. package/dist/core/metrics/extract.js +113 -0
  168. package/dist/core/modes/roo-modes.js +68 -0
  169. package/dist/core/onboarding/ensure-initialized.js +133 -0
  170. package/dist/core/onboarding/marker.js +111 -0
  171. package/dist/core/onboarding/telemetry-state.js +108 -0
  172. package/dist/core/output-style/presets.js +176 -0
  173. package/dist/core/output-style/state.js +185 -0
  174. package/dist/core/path-security.js +287 -5
  175. package/dist/core/permission.js +82 -22
  176. package/dist/core/permissions/auto-classifier.js +124 -0
  177. package/dist/core/permissions/bash-parser.js +371 -0
  178. package/dist/core/permissions/circuit-breaker.js +83 -0
  179. package/dist/core/permissions/constrained-edit.js +91 -0
  180. package/dist/core/permissions/gate.js +278 -0
  181. package/dist/core/permissions/index.js +20 -0
  182. package/dist/core/permissions/mode.js +174 -0
  183. package/dist/core/permissions/network-egress.js +137 -0
  184. package/dist/core/permissions/state.js +241 -0
  185. package/dist/core/permissions/tool-class.js +93 -0
  186. package/dist/core/plan-mode/ui-state.js +51 -0
  187. package/dist/core/plans/plan-artifact.js +721 -0
  188. package/dist/core/policy-limits/etag-store.js +122 -0
  189. package/dist/core/prd-check/parser.js +215 -0
  190. package/dist/core/prd-check/reporter.js +127 -0
  191. package/dist/core/prd-check/session-review.js +557 -0
  192. package/dist/core/prd-check/verifiers.js +223 -0
  193. package/dist/core/prompt-cache/client-cache.js +99 -0
  194. package/dist/core/prompts/assembly.js +29 -0
  195. package/dist/core/prompts/registry.js +364 -0
  196. package/dist/core/pugi-md/cc-compat-rules.js +735 -0
  197. package/dist/core/pugi-md/context-injector.js +76 -0
  198. package/dist/core/pugi-md/walk-up.js +207 -0
  199. package/dist/core/python/uv-installer.js +270 -0
  200. package/dist/core/python/uv-resolver.js +83 -0
  201. package/dist/core/rate-limit/narrator.js +146 -0
  202. package/dist/core/recipes/cli-types.js +20 -0
  203. package/dist/core/recipes/loader.js +103 -0
  204. package/dist/core/recipes/runner.js +345 -0
  205. package/dist/core/recipes/schema.js +587 -0
  206. package/dist/core/release-notes/parser.js +241 -0
  207. package/dist/core/release-notes/state.js +116 -0
  208. package/dist/core/repl/ask.js +37 -37
  209. package/dist/core/repl/cancellation.js +26 -26
  210. package/dist/core/repl/cap-warning.js +4 -4
  211. package/dist/core/repl/clipboard-read.js +11 -11
  212. package/dist/core/repl/dispatch-fsm.js +12 -12
  213. package/dist/core/repl/history-search.js +15 -15
  214. package/dist/core/repl/history.js +28 -18
  215. package/dist/core/repl/kill-ring.js +5 -5
  216. package/dist/core/repl/model-pricing.js +135 -0
  217. package/dist/core/repl/privacy-banner.js +22 -22
  218. package/dist/core/repl/session.js +2148 -217
  219. package/dist/core/repl/slash-commands.js +501 -41
  220. package/dist/core/repl/store/index.js +1 -1
  221. package/dist/core/repl/store/jsonl-log.js +22 -22
  222. package/dist/core/repl/store/lockfile.js +10 -10
  223. package/dist/core/repl/store/session-store.js +136 -107
  224. package/dist/core/repl/store/types.js +15 -15
  225. package/dist/core/repl/store/uuid-v7.js +12 -12
  226. package/dist/core/repl/workspace-context.js +43 -21
  227. package/dist/core/repo-map/build.js +125 -0
  228. package/dist/core/repo-map/cache.js +185 -0
  229. package/dist/core/repo-map/extractor.js +254 -0
  230. package/dist/core/repo-map/formatter.js +145 -0
  231. package/dist/core/repo-map/page-rank.js +105 -0
  232. package/dist/core/repo-map/scanner.js +211 -0
  233. package/dist/core/retry-budget/budget.js +284 -0
  234. package/dist/core/retry-budget/index.js +5 -0
  235. package/dist/core/retry-budget/retry-cap.js +74 -0
  236. package/dist/core/routing/lead-worker.js +43 -0
  237. package/dist/core/routing/pre-flight-estimator.js +108 -0
  238. package/dist/core/runs/run-tree.js +103 -0
  239. package/dist/core/security/injection-scanner.js +367 -0
  240. package/dist/core/security/output-filter.js +418 -0
  241. package/dist/core/session/env-file.js +105 -0
  242. package/dist/core/session/section-budgets.js +140 -0
  243. package/dist/core/session.js +92 -0
  244. package/dist/core/settings.js +324 -5
  245. package/dist/core/share/formatter.js +271 -0
  246. package/dist/core/share/redactor.js +221 -0
  247. package/dist/core/share/uploader.js +267 -0
  248. package/dist/core/skills/defaults.js +30 -30
  249. package/dist/core/skills/loader.js +22 -22
  250. package/dist/core/skills/sources.js +27 -27
  251. package/dist/core/smoke/headless-driver.js +174 -0
  252. package/dist/core/smoke/orchestrator.js +194 -0
  253. package/dist/core/smoke/runner.js +238 -0
  254. package/dist/core/smoke/scenario-parser.js +316 -0
  255. package/dist/core/statusline.js +99 -0
  256. package/dist/core/subagents/dispatcher-real.js +600 -0
  257. package/dist/core/subagents/dispatcher.js +132 -43
  258. package/dist/core/subagents/index.js +19 -6
  259. package/dist/core/subagents/isolation-matrix.js +213 -0
  260. package/dist/core/subagents/spawn.js +19 -4
  261. package/dist/core/telemetry/emitter.js +229 -0
  262. package/dist/core/telemetry/queue.js +251 -0
  263. package/dist/core/theme/context.js +91 -0
  264. package/dist/core/theme/presets.js +228 -0
  265. package/dist/core/theme/state.js +181 -0
  266. package/dist/core/todos/invariant.js +10 -0
  267. package/dist/core/todos/state.js +177 -0
  268. package/dist/core/tool-schema/compressor.js +89 -0
  269. package/dist/core/transport/version-interceptor.js +166 -0
  270. package/dist/core/trust.js +2 -2
  271. package/dist/core/tui/thinking-block.js +64 -0
  272. package/dist/core/vim/keymap.js +288 -0
  273. package/dist/core/vim/state.js +92 -0
  274. package/dist/core/watch-markers/marker-watcher.js +133 -0
  275. package/dist/core/worktree/include-parser.js +249 -0
  276. package/dist/core/worktree-manager/cleanup.js +123 -0
  277. package/dist/core/worktree-manager/manager.js +303 -0
  278. package/dist/index.js +36 -0
  279. package/dist/runtime/bootstrap.js +190 -0
  280. package/dist/runtime/cli.js +4185 -549
  281. package/dist/runtime/commands/agents.js +31 -31
  282. package/dist/runtime/commands/budget.js +5 -5
  283. package/dist/runtime/commands/cancel.js +231 -0
  284. package/dist/runtime/commands/chain.js +489 -0
  285. package/dist/runtime/commands/codegraph-status.js +227 -0
  286. package/dist/runtime/commands/compact.js +297 -0
  287. package/dist/runtime/commands/config.js +73 -39
  288. package/dist/runtime/commands/cost.js +199 -0
  289. package/dist/runtime/commands/delegate.js +27 -4
  290. package/dist/runtime/commands/dispatch.js +126 -0
  291. package/dist/runtime/commands/doctor.js +579 -0
  292. package/dist/runtime/commands/feedback.js +184 -0
  293. package/dist/runtime/commands/hooks.js +187 -0
  294. package/dist/runtime/commands/init.js +254 -0
  295. package/dist/runtime/commands/lsp.js +200 -38
  296. package/dist/runtime/commands/mcp.js +879 -0
  297. package/dist/runtime/commands/memory.js +582 -0
  298. package/dist/runtime/commands/model.js +237 -0
  299. package/dist/runtime/commands/onboarding.js +275 -0
  300. package/dist/runtime/commands/patch.js +12 -12
  301. package/dist/runtime/commands/permissions.js +112 -0
  302. package/dist/runtime/commands/plan.js +143 -0
  303. package/dist/runtime/commands/prd-check.js +285 -0
  304. package/dist/runtime/commands/privacy.js +17 -17
  305. package/dist/runtime/commands/recipe.js +325 -0
  306. package/dist/runtime/commands/redo-blob-store.js +92 -0
  307. package/dist/runtime/commands/redo.js +361 -0
  308. package/dist/runtime/commands/release-notes.js +229 -0
  309. package/dist/runtime/commands/repo-map.js +95 -0
  310. package/dist/runtime/commands/report.js +299 -0
  311. package/dist/runtime/commands/resume.js +118 -0
  312. package/dist/runtime/commands/review-consensus.js +68 -53
  313. package/dist/runtime/commands/rewind.js +333 -0
  314. package/dist/runtime/commands/roster.js +14 -14
  315. package/dist/runtime/commands/sessions.js +163 -0
  316. package/dist/runtime/commands/share.js +316 -0
  317. package/dist/runtime/commands/skills.js +31 -31
  318. package/dist/runtime/commands/status.js +186 -0
  319. package/dist/runtime/commands/stickers.js +82 -0
  320. package/dist/runtime/commands/style.js +194 -0
  321. package/dist/runtime/commands/theme.js +196 -0
  322. package/dist/runtime/commands/undo.js +54 -22
  323. package/dist/runtime/commands/update.js +289 -0
  324. package/dist/runtime/commands/vim.js +140 -0
  325. package/dist/runtime/commands/worktree.js +8 -8
  326. package/dist/runtime/commands/worktrees.js +155 -0
  327. package/dist/runtime/headless-repl.js +195 -0
  328. package/dist/runtime/headless.js +543 -0
  329. package/dist/runtime/load-hooks-or-exit.js +71 -0
  330. package/dist/runtime/plan-decompose.js +22 -22
  331. package/dist/runtime/sigint-guard.js +272 -0
  332. package/dist/runtime/update-check.js +28 -28
  333. package/dist/runtime/version.js +65 -0
  334. package/dist/runtime/worktree-bootstrap.js +579 -0
  335. package/dist/skills/bundled/batch.js +617 -0
  336. package/dist/skills/bundled/index.js +45 -0
  337. package/dist/skills/bundled/loop.js +358 -0
  338. package/dist/skills/bundled/remember.js +383 -0
  339. package/dist/skills/bundled/simplify.js +289 -0
  340. package/dist/skills/bundled/skillify.js +373 -0
  341. package/dist/skills/bundled/stuck.js +558 -0
  342. package/dist/skills/bundled/verify.js +439 -0
  343. package/dist/testing/vcr.js +486 -0
  344. package/dist/tools/agent-tool.js +229 -0
  345. package/dist/tools/apply-patch.js +89 -28
  346. package/dist/tools/ask-user-question.js +337 -0
  347. package/dist/tools/ask-user.js +115 -0
  348. package/dist/tools/bash.js +624 -46
  349. package/dist/tools/brief.js +224 -0
  350. package/dist/tools/cron.js +433 -0
  351. package/dist/tools/enter-worktree.js +250 -0
  352. package/dist/tools/exit-worktree.js +147 -0
  353. package/dist/tools/file-tools.js +161 -44
  354. package/dist/tools/lsp-tools.js +377 -1
  355. package/dist/tools/mcp-tool.js +260 -0
  356. package/dist/tools/multi-edit.js +361 -0
  357. package/dist/tools/powershell.js +268 -0
  358. package/dist/tools/registry.js +99 -4
  359. package/dist/tools/skill-tool.js +96 -0
  360. package/dist/tools/sleep.js +99 -0
  361. package/dist/tools/synthetic-output.js +133 -0
  362. package/dist/tools/tasks.js +208 -0
  363. package/dist/tools/todo-write.js +184 -0
  364. package/dist/tools/verify-plan-execution.js +295 -0
  365. package/dist/tools/web-fetch-injection-scanner.js +207 -0
  366. package/dist/tools/web-fetch.js +195 -10
  367. package/dist/tools/web-search.js +458 -0
  368. package/dist/tui/agent-progress-card.js +111 -0
  369. package/dist/tui/agent-tree.js +11 -1
  370. package/dist/tui/ask-modal.js +14 -14
  371. package/dist/tui/ask-user-question-chips.js +315 -0
  372. package/dist/tui/ask-user-question-prompt.js +203 -0
  373. package/dist/tui/compact-banner.js +81 -0
  374. package/dist/tui/conversation-pane.js +85 -11
  375. package/dist/tui/cost-table.js +111 -0
  376. package/dist/tui/device-flow.js +2 -2
  377. package/dist/tui/doctor-table.js +46 -0
  378. package/dist/tui/feedback-prompt.js +156 -0
  379. package/dist/tui/input-box.js +247 -32
  380. package/dist/tui/login-picker.js +3 -3
  381. package/dist/tui/markdown-render.js +6 -6
  382. package/dist/tui/multi-file-diff-approval.js +375 -0
  383. package/dist/tui/onboarding-wizard.js +240 -0
  384. package/dist/tui/permissions-picker.js +86 -0
  385. package/dist/tui/render.js +36 -1
  386. package/dist/tui/repl-render.js +176 -25
  387. package/dist/tui/repl-splash-art.js +16 -16
  388. package/dist/tui/repl-splash-mascot.js +48 -24
  389. package/dist/tui/repl-splash.js +22 -22
  390. package/dist/tui/repl.js +125 -45
  391. package/dist/tui/slash-palette.js +6 -6
  392. package/dist/tui/splash.js +2 -2
  393. package/dist/tui/status-bar.js +109 -31
  394. package/dist/tui/status-table.js +7 -0
  395. package/dist/tui/stickers-art.js +136 -0
  396. package/dist/tui/style-table.js +28 -0
  397. package/dist/tui/theme-table.js +29 -0
  398. package/dist/tui/thinking-spinner.js +123 -0
  399. package/dist/tui/tool-stream-pane.js +53 -4
  400. package/dist/tui/update-banner.js +27 -2
  401. package/dist/tui/vim-input.js +267 -0
  402. package/dist/tui/welcome-banner.js +107 -0
  403. package/dist/tui/welcome-data.js +293 -0
  404. package/dist/tui/workspace-context.js +2 -2
  405. package/package.json +31 -16
  406. package/test/scenarios/codegen-create-file.scenario.txt +13 -0
  407. package/test/scenarios/compact-force.scenario.txt +12 -0
  408. package/test/scenarios/identity.scenario.txt +12 -0
  409. package/test/scenarios/persona-handoff.scenario.txt +12 -0
  410. package/test/scenarios/walkback.scenario.txt +12 -0
  411. package/dist/core/engine/compaction-hook.js +0 -154
@@ -0,0 +1,250 @@
1
+ /**
2
+ * enter_worktree tool — scratch git worktree primitive (tool gap pack
3
+ *).
4
+ *
5
+ * Spawns `git worktree add <path> [<baseRef>]` at
6
+ * `.pugi/worktrees/<taskId>/` so a long-running agent task can land
7
+ * its edits into an isolated scratch tree. The matching `exit_worktree`
8
+ * tool is the cleanup primitive. The actual fan-out (one worktree per
9
+ * task in a backlog batch) lives behind a separate task — this tool is
10
+ * the primitive both call paths share.
11
+ *
12
+ * Wire shape:
13
+ * args: { taskId: string, baseRef?: string }
14
+ * - taskId: lowercase slug, `[a-z0-9][a-z0-9-]{0,63}`. The
15
+ * pattern bans path-traversal segments (`..`, `/`, `\\`) so
16
+ * the basename cannot escape `.pugi/worktrees/`.
17
+ * - baseRef: optional git ref (branch / tag / SHA). Defaults
18
+ * to `main` so the standard case is "fork from main and go".
19
+ * The CLI validates the ref shape only loosely — git
20
+ * rejects unknown refs upstream and that error message is
21
+ * surfaced verbatim.
22
+ * return: { ok: true, worktreePath, branchName } serialised JSON.
23
+ *
24
+ * Spawn discipline: every git invocation uses `spawnSync` with
25
+ * `shell: false` and a string-array argv so an unsanitised character
26
+ * inside a ref name cannot inject shell metacharacters. The taskId is
27
+ * gated by a strict regex BEFORE the spawn so the path argument is
28
+ * trusted.
29
+ *
30
+ * Path discipline: the worktree path is computed locally
31
+ * (`path.resolve(workspaceRoot, '.pugi/worktrees', taskId)`) and then
32
+ * containment-checked against the workspace root and the
33
+ * `.pugi/worktrees` subtree. Anything else throws — a deformed taskId
34
+ * that survived the regex (it should not) cannot pull the basename
35
+ * outside the expected subtree.
36
+ *
37
+ * Brand voice: English only, no emoji, no banned words.
38
+ */
39
+ import { spawnSync } from 'node:child_process';
40
+ import { existsSync, mkdirSync } from 'node:fs';
41
+ import { join, resolve, sep } from 'node:path';
42
+ /** Strict taskId pattern. Lowercase alphanumeric + hyphen, must start
43
+ * with a lowercase letter or digit, length 1..64. The first-character
44
+ * constraint stops a leading hyphen from being interpreted as a flag
45
+ * by `git worktree add` (defense in depth — argv form already protects
46
+ * us, but a leading hyphen is still a smell). */
47
+ export const TASK_ID_PATTERN = /^[a-z0-9][a-z0-9-]{0,63}$/;
48
+ /** Default base ref when the caller does not supply one. */
49
+ export const DEFAULT_BASE_REF = 'main';
50
+ /** Sentinels. Distinct prefixes so the model / dispatcher can
51
+ * pattern-match without parsing the trailing message. */
52
+ export const ENTER_WORKTREE_INVALID_ARGS = 'ENTER_WORKTREE_INVALID_ARGS';
53
+ export const ENTER_WORKTREE_GIT_FAILED = 'ENTER_WORKTREE_GIT_FAILED';
54
+ export const ENTER_WORKTREE_ALREADY_EXISTS = 'ENTER_WORKTREE_ALREADY_EXISTS';
55
+ export const ENTER_WORKTREE_PATH_ESCAPED = 'ENTER_WORKTREE_PATH_ESCAPED';
56
+ /**
57
+ * Validate the raw arguments. Returns the typed value on success or a
58
+ * `ENTER_WORKTREE_INVALID_ARGS: ...` sentinel string.
59
+ */
60
+ /**
61
+ * Permissive git ref-name validation. We do not aim to fully implement
62
+ * `git check-ref-format` — instead reject anything outside a safe
63
+ * character class plus a leading-dash check. The leading-dash rule is
64
+ * the real defense: it stops an operator-controlled `baseRef` from
65
+ * being reinterpreted as a CLI flag (e.g. `--detach`, `--force`).
66
+ */
67
+ function isValidGitRef(s) {
68
+ if (s.startsWith('-'))
69
+ return false;
70
+ return /^[A-Za-z0-9._/-]+$/.test(s);
71
+ }
72
+ export function parseEnterWorktreeArgs(raw) {
73
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
74
+ return `${ENTER_WORKTREE_INVALID_ARGS}: arguments must be a JSON object`;
75
+ }
76
+ const obj = raw;
77
+ const issues = [];
78
+ const taskId = obj['taskId'];
79
+ if (typeof taskId !== 'string') {
80
+ issues.push('taskId: must be a string');
81
+ }
82
+ else if (!TASK_ID_PATTERN.test(taskId)) {
83
+ issues.push(`taskId: must match ${TASK_ID_PATTERN}`);
84
+ }
85
+ let baseRef;
86
+ if (obj['baseRef'] !== undefined && obj['baseRef'] !== null) {
87
+ if (typeof obj['baseRef'] !== 'string') {
88
+ issues.push('baseRef: must be a string when present');
89
+ }
90
+ else if (obj['baseRef'].length === 0) {
91
+ issues.push('baseRef: must be non-empty when present');
92
+ }
93
+ else if (obj['baseRef'].length > 250) {
94
+ // Git imposes its own limits; we cut off well below them to keep
95
+ // error messages and audit lines bounded.
96
+ issues.push('baseRef: must be <= 250 chars when present');
97
+ }
98
+ else if (!isValidGitRef(obj['baseRef'])) {
99
+ // Permissive ref-chars regex that also rejects leading `-` so
100
+ // an operator-controlled `baseRef` cannot be reinterpreted as
101
+ // a git flag (e.g. `--detach`, `--force`). Combined with the
102
+ // `--` separator in argv this is belt-and-suspenders against
103
+ // arg-injection. Triple-review Claude P2,.
104
+ issues.push('baseRef: must match [A-Za-z0-9._/-] and not start with `-`');
105
+ }
106
+ else {
107
+ baseRef = obj['baseRef'];
108
+ }
109
+ }
110
+ if (issues.length > 0) {
111
+ return `${ENTER_WORKTREE_INVALID_ARGS}: ${issues.join('; ')}`;
112
+ }
113
+ const out = baseRef !== undefined
114
+ ? { taskId: taskId, baseRef }
115
+ : { taskId: taskId };
116
+ return out;
117
+ }
118
+ /**
119
+ * Compute the absolute on-disk path for a task's worktree. Public so
120
+ * `exit_worktree` and any future TUI surface can share the layout.
121
+ */
122
+ export function worktreePathFor(workspaceRoot, taskId) {
123
+ return join(resolve(workspaceRoot), '.pugi', 'worktrees', taskId);
124
+ }
125
+ /**
126
+ * Compute the canonical worktree root (`<workspaceRoot>/.pugi/worktrees`).
127
+ * Used by `exit_worktree` for the containment check.
128
+ */
129
+ export function worktreesRoot(workspaceRoot) {
130
+ return join(resolve(workspaceRoot), '.pugi', 'worktrees');
131
+ }
132
+ /**
133
+ * Dispatch entry point. Validates input, ensures the parent directory
134
+ * exists, then spawns `git worktree add` with the strict argv form.
135
+ * Returns the structured result envelope as JSON, or a sentinel string
136
+ * on a recoverable failure.
137
+ */
138
+ export function dispatchEnterWorktree(ctx, raw) {
139
+ const parsed = parseEnterWorktreeArgs(raw);
140
+ if (typeof parsed === 'string') {
141
+ return parsed;
142
+ }
143
+ const baseRef = parsed.baseRef ?? DEFAULT_BASE_REF;
144
+ const root = resolve(ctx.workspaceRoot);
145
+ const targetPath = worktreePathFor(root, parsed.taskId);
146
+ const subtreeRoot = worktreesRoot(root);
147
+ // Defense in depth: re-check that the resolved target stays inside
148
+ // `<workspaceRoot>/.pugi/worktrees/`. The regex on taskId already
149
+ // bans `..` and `/`, so a successful escape here would indicate a
150
+ // catastrophic node:path regression — we still treat it as a fatal
151
+ // refusal rather than trusting the upstream gate alone.
152
+ if (!isContainedIn(targetPath, subtreeRoot)) {
153
+ return `${ENTER_WORKTREE_PATH_ESCAPED}: ${targetPath} is not under ${subtreeRoot}`;
154
+ }
155
+ if (existsSync(targetPath)) {
156
+ return `${ENTER_WORKTREE_ALREADY_EXISTS}: ${targetPath}`;
157
+ }
158
+ // Ensure `.pugi/worktrees/` exists; git worktree add will not create
159
+ // the parent for us.
160
+ if (!existsSync(subtreeRoot)) {
161
+ mkdirSync(subtreeRoot, { recursive: true });
162
+ }
163
+ // Compose the branch name we hand to git. The convention pairs
164
+ // 1:1 with taskId so `exit_worktree` does not need a separate
165
+ // lookup. `-b <branch>` creates the branch as a side effect of the
166
+ // worktree-add; without it git would refuse a worktree that points
167
+ // to an existing branch already checked out elsewhere.
168
+ const branchName = `pugi/worktree/${parsed.taskId}`;
169
+ // `--` separator forces git to treat everything after it as strict
170
+ // positionals. Belt-and-suspenders against arg-injection via
171
+ // `baseRef` (the regex above already rejects leading `-`).
172
+ const argv = [
173
+ 'worktree',
174
+ 'add',
175
+ '-b',
176
+ branchName,
177
+ '--',
178
+ targetPath,
179
+ baseRef,
180
+ ];
181
+ const runner = ctx.runGit ?? defaultGitRunner;
182
+ const result = runner(argv, root);
183
+ if (result.status !== 0) {
184
+ const detail = (result.stderr || result.stdout || `exit=${result.status}`).trim();
185
+ return `${ENTER_WORKTREE_GIT_FAILED}: ${detail}`;
186
+ }
187
+ const out = {
188
+ ok: true,
189
+ worktreePath: targetPath,
190
+ branchName,
191
+ baseRef,
192
+ };
193
+ return JSON.stringify(out);
194
+ }
195
+ /**
196
+ * Default spawnSync wrapper. `shell: false` is non-negotiable — every
197
+ * argv element is forwarded verbatim к the child without shell
198
+ * interpretation. The stdout/stderr captures are forced to utf-8 so the
199
+ * caller works with strings without manual decoding.
200
+ */
201
+ function defaultGitRunner(argv, cwd) {
202
+ const result = spawnSync('git', [...argv], {
203
+ cwd,
204
+ shell: false,
205
+ encoding: 'utf8',
206
+ timeout: 30_000,
207
+ });
208
+ return {
209
+ status: result.status,
210
+ stdout: typeof result.stdout === 'string' ? result.stdout : '',
211
+ stderr: typeof result.stderr === 'string' ? result.stderr : '',
212
+ };
213
+ }
214
+ /**
215
+ * Containment check. Resolves both paths and asserts the target lives
216
+ * under the root via a separator-aware prefix match. The separator
217
+ * append on the root protects against the `/foo/bar2` vs `/foo/bar`
218
+ * partial-prefix bug.
219
+ */
220
+ function isContainedIn(target, root) {
221
+ const rResolved = resolve(root);
222
+ const tResolved = resolve(target);
223
+ if (tResolved === rResolved)
224
+ return false;
225
+ const rootWithSep = rResolved.endsWith(sep) ? rResolved : `${rResolved}${sep}`;
226
+ return tResolved.startsWith(rootWithSep);
227
+ }
228
+ /**
229
+ * JSON-Schema fragment the schema builder advertises to the model.
230
+ */
231
+ export const enterWorktreeJsonSchema = {
232
+ type: 'object',
233
+ additionalProperties: false,
234
+ required: ['taskId'],
235
+ properties: {
236
+ taskId: {
237
+ type: 'string',
238
+ pattern: '^[a-z0-9][a-z0-9-]{0,63}$',
239
+ description: 'Slug used as the worktree basename. ' +
240
+ 'Lowercase alphanumeric + hyphen, must start with letter/digit, 1..64 chars.',
241
+ },
242
+ baseRef: {
243
+ type: 'string',
244
+ minLength: 1,
245
+ maxLength: 250,
246
+ description: `Optional git base ref (branch / tag / SHA). Defaults to "${DEFAULT_BASE_REF}".`,
247
+ },
248
+ },
249
+ };
250
+ //# sourceMappingURL=enter-worktree.js.map
@@ -0,0 +1,147 @@
1
+ /**
2
+ * exit_worktree tool — opposite of `enter_worktree` (tool gap pack
3
+ *).
4
+ *
5
+ * Tears down a scratch git worktree at the supplied path. The path is
6
+ * STRICTLY validated к live under `<workspaceRoot>/.pugi/worktrees/`
7
+ * — anything outside that subtree refuses with a sentinel and zero
8
+ * filesystem mutation. This is a destructive primitive, so the
9
+ * containment check is the load-bearing safety boundary.
10
+ *
11
+ * Procedure:
12
+ * 1. Validate the argument shape.
13
+ * 2. Resolve the input path and assert it lives under
14
+ * `<workspaceRoot>/.pugi/worktrees/`. Refuse otherwise.
15
+ * 3. Run `git worktree remove --force <path>` so git's bookkeeping
16
+ * drops the worktree. `--force` is required because the model may
17
+ * have left dirty edits inside the scratch tree — that is the
18
+ * normal case for a refactor that the operator is about to merge
19
+ * via a different tool. Best-effort: a non-zero exit from git is
20
+ * logged in the return envelope but does NOT abort the disk
21
+ * cleanup. Git may have already cleaned the entry when the dir
22
+ * itself was removed manually.
23
+ * 4. `rmSync(path, { recursive: true, force: true })` for any
24
+ * leftover files.
25
+ *
26
+ * Wire shape:
27
+ * args: { worktreePath: string }
28
+ * return: { ok: true, removed: boolean, gitStatus: number|null,
29
+ * gitDetail?: string } serialised JSON.
30
+ *
31
+ * Idempotent: calling on a path that no longer exists returns
32
+ * `{ ok: true, removed: false }` with no error. This matches the
33
+ * semantics agent-progress / cleanup operations already follow elsewhere
34
+ * in the CLI.
35
+ *
36
+ * Brand voice: English only, no emoji, no banned words.
37
+ */
38
+ import { spawnSync } from 'node:child_process';
39
+ import { existsSync, rmSync } from 'node:fs';
40
+ import { resolve, sep } from 'node:path';
41
+ import { worktreesRoot } from './enter-worktree.js';
42
+ /** Sentinels. Distinct prefixes so the model / dispatcher can
43
+ * pattern-match. */
44
+ export const EXIT_WORKTREE_INVALID_ARGS = 'EXIT_WORKTREE_INVALID_ARGS';
45
+ export const EXIT_WORKTREE_PATH_ESCAPED = 'EXIT_WORKTREE_PATH_ESCAPED';
46
+ /**
47
+ * Validate the raw arguments. Returns the typed value on success or a
48
+ * `EXIT_WORKTREE_INVALID_ARGS: ...` sentinel string.
49
+ */
50
+ export function parseExitWorktreeArgs(raw) {
51
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
52
+ return `${EXIT_WORKTREE_INVALID_ARGS}: arguments must be a JSON object`;
53
+ }
54
+ const obj = raw;
55
+ const worktreePath = obj['worktreePath'];
56
+ if (typeof worktreePath !== 'string') {
57
+ return `${EXIT_WORKTREE_INVALID_ARGS}: worktreePath: must be a string`;
58
+ }
59
+ if (worktreePath.length === 0) {
60
+ return `${EXIT_WORKTREE_INVALID_ARGS}: worktreePath: must be non-empty`;
61
+ }
62
+ return { worktreePath };
63
+ }
64
+ /**
65
+ * Dispatch entry point. Validates input, asserts the path lives under
66
+ * the allowed root, then runs `git worktree remove --force` followed
67
+ * by a filesystem removal for any leftovers. Returns the structured
68
+ * envelope as JSON.
69
+ *
70
+ * Returns sentinel strings on validation failures or a containment
71
+ * refusal — no throw — so the engine adapter surfaces a recoverable
72
+ * tool result and the model can adapt.
73
+ */
74
+ export function dispatchExitWorktree(ctx, raw) {
75
+ const parsed = parseExitWorktreeArgs(raw);
76
+ if (typeof parsed === 'string') {
77
+ return parsed;
78
+ }
79
+ const root = resolve(ctx.workspaceRoot);
80
+ const subtreeRoot = worktreesRoot(root);
81
+ const target = resolve(parsed.worktreePath);
82
+ if (!isContainedIn(target, subtreeRoot)) {
83
+ return `${EXIT_WORKTREE_PATH_ESCAPED}: ${target} is not under ${subtreeRoot}`;
84
+ }
85
+ // git worktree remove. Best-effort. Non-zero exit is captured in the
86
+ // return envelope but does not block the rmTree step — a half-cleaned
87
+ // worktree (entry gone but dir survived) is a common operator-side
88
+ // mistake we want to recover from.
89
+ const runner = ctx.runGit ?? defaultGitRunner;
90
+ const gitResult = runner(['worktree', 'remove', '--force', target], root);
91
+ const existedBefore = existsSync(target);
92
+ const rmTree = ctx.rmTree ?? defaultRmTree;
93
+ if (existedBefore) {
94
+ rmTree(target);
95
+ }
96
+ const removed = existedBefore && !existsSync(target);
97
+ const envelope = gitResult.status === 0
98
+ ? { ok: true, removed, gitStatus: gitResult.status }
99
+ : {
100
+ ok: true,
101
+ removed,
102
+ gitStatus: gitResult.status,
103
+ gitDetail: (gitResult.stderr || gitResult.stdout || '').trim(),
104
+ };
105
+ return JSON.stringify(envelope);
106
+ }
107
+ function defaultGitRunner(argv, cwd) {
108
+ const result = spawnSync('git', [...argv], {
109
+ cwd,
110
+ shell: false,
111
+ encoding: 'utf8',
112
+ timeout: 30_000,
113
+ });
114
+ return {
115
+ status: result.status,
116
+ stdout: typeof result.stdout === 'string' ? result.stdout : '',
117
+ stderr: typeof result.stderr === 'string' ? result.stderr : '',
118
+ };
119
+ }
120
+ function defaultRmTree(path) {
121
+ rmSync(path, { recursive: true, force: true });
122
+ }
123
+ function isContainedIn(target, root) {
124
+ const rResolved = resolve(root);
125
+ const tResolved = resolve(target);
126
+ if (tResolved === rResolved)
127
+ return false;
128
+ const rootWithSep = rResolved.endsWith(sep) ? rResolved : `${rResolved}${sep}`;
129
+ return tResolved.startsWith(rootWithSep);
130
+ }
131
+ /**
132
+ * JSON-Schema fragment the schema builder advertises to the model.
133
+ */
134
+ export const exitWorktreeJsonSchema = {
135
+ type: 'object',
136
+ additionalProperties: false,
137
+ required: ['worktreePath'],
138
+ properties: {
139
+ worktreePath: {
140
+ type: 'string',
141
+ minLength: 1,
142
+ description: 'Absolute path to the worktree to tear down. Must live under ' +
143
+ '<workspaceRoot>/.pugi/worktrees/ — anything else refuses.',
144
+ },
145
+ },
146
+ };
147
+ //# sourceMappingURL=exit-worktree.js.map