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

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 (409) 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 +1731 -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/enter-worktree.js +250 -0
  351. package/dist/tools/exit-worktree.js +147 -0
  352. package/dist/tools/file-tools.js +161 -44
  353. package/dist/tools/lsp-tools.js +377 -1
  354. package/dist/tools/mcp-tool.js +260 -0
  355. package/dist/tools/multi-edit.js +361 -0
  356. package/dist/tools/powershell.js +268 -0
  357. package/dist/tools/registry.js +86 -4
  358. package/dist/tools/skill-tool.js +96 -0
  359. package/dist/tools/sleep.js +99 -0
  360. package/dist/tools/synthetic-output.js +133 -0
  361. package/dist/tools/tasks.js +208 -0
  362. package/dist/tools/todo-write.js +184 -0
  363. package/dist/tools/verify-plan-execution.js +295 -0
  364. package/dist/tools/web-fetch-injection-scanner.js +207 -0
  365. package/dist/tools/web-fetch.js +195 -10
  366. package/dist/tools/web-search.js +458 -0
  367. package/dist/tui/agent-progress-card.js +111 -0
  368. package/dist/tui/agent-tree.js +11 -1
  369. package/dist/tui/ask-modal.js +14 -14
  370. package/dist/tui/ask-user-question-chips.js +315 -0
  371. package/dist/tui/ask-user-question-prompt.js +203 -0
  372. package/dist/tui/compact-banner.js +81 -0
  373. package/dist/tui/conversation-pane.js +85 -11
  374. package/dist/tui/cost-table.js +111 -0
  375. package/dist/tui/device-flow.js +2 -2
  376. package/dist/tui/doctor-table.js +46 -0
  377. package/dist/tui/feedback-prompt.js +156 -0
  378. package/dist/tui/input-box.js +247 -32
  379. package/dist/tui/login-picker.js +3 -3
  380. package/dist/tui/markdown-render.js +6 -6
  381. package/dist/tui/onboarding-wizard.js +240 -0
  382. package/dist/tui/permissions-picker.js +86 -0
  383. package/dist/tui/render.js +36 -1
  384. package/dist/tui/repl-render.js +176 -25
  385. package/dist/tui/repl-splash-art.js +16 -16
  386. package/dist/tui/repl-splash-mascot.js +48 -24
  387. package/dist/tui/repl-splash.js +22 -22
  388. package/dist/tui/repl.js +125 -45
  389. package/dist/tui/slash-palette.js +6 -6
  390. package/dist/tui/splash.js +2 -2
  391. package/dist/tui/status-bar.js +109 -31
  392. package/dist/tui/status-table.js +7 -0
  393. package/dist/tui/stickers-art.js +136 -0
  394. package/dist/tui/style-table.js +28 -0
  395. package/dist/tui/theme-table.js +29 -0
  396. package/dist/tui/thinking-spinner.js +123 -0
  397. package/dist/tui/tool-stream-pane.js +53 -4
  398. package/dist/tui/update-banner.js +27 -2
  399. package/dist/tui/vim-input.js +267 -0
  400. package/dist/tui/welcome-banner.js +107 -0
  401. package/dist/tui/welcome-data.js +293 -0
  402. package/dist/tui/workspace-context.js +2 -2
  403. package/package.json +31 -16
  404. package/test/scenarios/codegen-create-file.scenario.txt +13 -0
  405. package/test/scenarios/compact-force.scenario.txt +12 -0
  406. package/test/scenarios/identity.scenario.txt +12 -0
  407. package/test/scenarios/persona-handoff.scenario.txt +12 -0
  408. package/test/scenarios/walkback.scenario.txt +12 -0
  409. package/dist/core/engine/compaction-hook.js +0 -154
@@ -0,0 +1,143 @@
1
+ /**
2
+ * `pugi plan` / `/plan` — quick mode-switch shortcut.
3
+ *
4
+ * `/plan` is the slick UX shortcut for `/permissions plan`: one keystroke
5
+ * (well, five) puts the gate into plan mode + surfaces a banner so the
6
+ * operator knows write/dispatch tools are refused. The model goes off and
7
+ * thinks / researches without side effects until the operator types
8
+ * `/plan --back` (restore previous mode) or explicitly flips with
9
+ * `/permissions <mode>`.
10
+ *
11
+ * The slash and CLI surfaces both go through `runPlanCommand` — same
12
+ * separation as `runPermissionsCommand`. The runtime is I/O free w.r.t.
13
+ * the engine; the optional one-shot dispatch (`/plan <prompt>`) is
14
+ * handled by the CLI dispatcher AFTER this helper sets the workspace
15
+ * mode so the existing `runEngineTask('plan')` path sees plan mode as
16
+ * the workspace state without needing a parallel code path.
17
+ *
18
+ * Verdicts (the helper returns one so the caller can decide what to do
19
+ * after the mode write — print the banner, dispatch the engine, no-op):
20
+ * - `entered` — first `/plan` from a non-plan mode. Print the
21
+ * banner. Caller may then run a one-shot prompt.
22
+ * - `already-in-plan` — `/plan` while already in plan. No-op + show
23
+ * current. No banner reprint.
24
+ * - `reverted` — `/plan --back` popped the snapshot. Print a
25
+ * one-line confirmation; no banner.
26
+ * - `no-previous` — `/plan --back` without a snapshot. Print a
27
+ * clear "nothing to revert" line.
28
+ * - `persisted` — `/plan --persist` wrote the global default
29
+ * AND set workspace state to plan. Banner +
30
+ * persistence-confirmation line.
31
+ *
32
+ * `previousMode` semantics: stashed BEFORE the workspace write on
33
+ * `entered` / `persisted`. Cleared after a successful `reverted` so a
34
+ * second `--back` reports `no-previous` instead of looping back to plan.
35
+ */
36
+ import { PERMISSION_MODES, PERMISSION_MODE_GLOSS, getCurrentMode, getGlobalDefaultMode, getPreviousMode, setCurrentMode, setGlobalDefaultMode, setPreviousMode, } from '../../core/permissions/index.js';
37
+ /**
38
+ * Run the `/plan` flow. Side effects:
39
+ *
40
+ * command.back = true:
41
+ * - If a previousMode snapshot exists → restore it, clear snapshot,
42
+ * return `reverted`.
43
+ * - Otherwise → no writes, return `no-previous`.
44
+ *
45
+ * command.back = false, current mode is plan:
46
+ * - If `--persist`, write global config (no workspace re-write — it
47
+ * is already plan).
48
+ * - Print "already in plan" + the banner-summary line. Return
49
+ * `already-in-plan`.
50
+ *
51
+ * command.back = false, current mode is NOT plan:
52
+ * - Snapshot current mode → previousPermissionMode.
53
+ * - Write workspace mode = plan.
54
+ * - If `--persist`, also write global config.
55
+ * - Print the banner + (if persisted) the persistence line.
56
+ * - Return `entered` or `persisted`.
57
+ *
58
+ * --back + --persist is a no-op for persistence (revert never writes
59
+ * global config) but the revert itself fires.
60
+ */
61
+ export async function runPlanCommand(command, ctx) {
62
+ const current = effectiveMode(ctx);
63
+ if (command.back) {
64
+ const prev = getPreviousMode(ctx.workspaceRoot);
65
+ if (!prev) {
66
+ ctx.writeOutput(`No previous mode to restore. Current: ${current}. Use \`/permissions <mode>\` to switch explicitly.`);
67
+ return { verdict: 'no-previous', mode: current };
68
+ }
69
+ setCurrentMode(ctx.workspaceRoot, prev);
70
+ setPreviousMode(ctx.workspaceRoot, null);
71
+ ctx.writeOutput(`Switched back to '${prev}' mode. ${PERMISSION_MODE_GLOSS[prev]}`);
72
+ return { verdict: 'reverted', mode: prev };
73
+ }
74
+ if (current === 'plan') {
75
+ // Repeat /plan in plan mode is a no-op for the mode write, but
76
+ // --persist still honours the operator's intent to lock plan as
77
+ // the global default for future sessions.
78
+ if (command.persist) {
79
+ setGlobalDefaultMode('plan', ctx.homeDir);
80
+ ctx.writeOutput('Already in plan mode. Persisted plan as the default for future sessions (~/.pugi/config.json).');
81
+ return { verdict: 'persisted', mode: 'plan' };
82
+ }
83
+ ctx.writeOutput(`Already in plan mode. ${PERMISSION_MODE_GLOSS.plan} Switch back with \`/plan --back\` or \`/permissions <mode>\`.`);
84
+ return { verdict: 'already-in-plan', mode: 'plan' };
85
+ }
86
+ // Entering plan mode from a non-plan baseline. Stash the current mode
87
+ // BEFORE the write so /plan --back can pop it. We intentionally use the
88
+ // observed effective mode (workspace || global || default) rather than
89
+ // strictly the workspace value — if the operator's previous mode was
90
+ // sourced from the global config, `--back` should restore that observed
91
+ // state, not silently degrade to default.
92
+ setPreviousMode(ctx.workspaceRoot, current);
93
+ setCurrentMode(ctx.workspaceRoot, 'plan');
94
+ if (command.persist) {
95
+ setGlobalDefaultMode('plan', ctx.homeDir);
96
+ }
97
+ for (const line of renderPlanBanner()) {
98
+ ctx.writeOutput(line);
99
+ }
100
+ if (command.persist) {
101
+ ctx.writeOutput('Persisted plan as the default for future sessions (~/.pugi/config.json).');
102
+ return { verdict: 'persisted', mode: 'plan' };
103
+ }
104
+ return { verdict: 'entered', mode: 'plan' };
105
+ }
106
+ /**
107
+ * Render the plan-mode banner as a sequence of lines. The slash + CLI
108
+ * surfaces both print these line-by-line through their respective
109
+ * `writeOutput` sinks so the Ink REPL conversation pane and the plain
110
+ * stdout pipeline render identically.
111
+ *
112
+ * The box-drawing uses light-line glyphs (U+2500 family) which render in
113
+ * every modern terminal we target (Linux/macOS/Windows Terminal/iTerm/
114
+ * Ghostty/Alacritty). No emoji per brand-voice gate.
115
+ */
116
+ export function renderPlanBanner() {
117
+ return [
118
+ '┌─ Plan mode active ────────────────────────────────────────┐',
119
+ '│ Read-only tools allowed. Write/dispatch tools blocked. │',
120
+ '│ Pugi will think + research without making changes. │',
121
+ '│ Switch back: /plan --back or /permissions <mode> │',
122
+ '└───────────────────────────────────────────────────────────┘',
123
+ ];
124
+ }
125
+ /**
126
+ * Resolve the effective mode at the moment the helper was invoked,
127
+ * mirroring `resolveMode` but without taking a CLI flag (the `/plan`
128
+ * helper is called AFTER the top-level `--mode` flag has been applied
129
+ * to the workspace, so the file state is the source of truth here).
130
+ */
131
+ function effectiveMode(ctx) {
132
+ const workspace = getCurrentMode(ctx.workspaceRoot);
133
+ if (workspace)
134
+ return workspace;
135
+ const global = getGlobalDefaultMode(ctx.homeDir);
136
+ if (global)
137
+ return global;
138
+ // canonical default — `PERMISSION_MODES[0]` is `default` (the
139
+ // CC-parity ask-every-call ground state). Fall back literally if the
140
+ // array is empty (defensive — should never happen).
141
+ return PERMISSION_MODES[0] ?? 'default';
142
+ }
143
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1,285 @@
1
+ /**
2
+ * `pugi prd-check` — Pugi verified-deliverable gate .
3
+ *
4
+ * Runs a PRD ↔ delivered-artifact verification sweep BEFORE the
5
+ * operator (or an autonomous agent) claims a feature is done.
6
+ * Reads `docs/prd/<feature>.md` (or any explicit path), parses the
7
+ * acceptance-criteria section, and runs file / test / doc / command
8
+ * / route verifiers per criterion. Output mirrors `pugi doctor`:
9
+ * either a plain-text table or a JSON envelope (`--json`).
10
+ *
11
+ * Module contract (mirrors L17 doctor split):
12
+ *
13
+ * - parser + verifiers + reporter are pure with respect to deps;
14
+ * this file is the THIN wiring that resolves cwd, glob-expands
15
+ * `--all`, loads each PRD, and forwards the structured result
16
+ * к the supplied writeOutput sink.
17
+ *
18
+ * - `runPrdCheckCommand` is the single entry point. Both the
19
+ * top-level `pugi prd-check` shell command AND the in-REPL
20
+ * `/prd-check` slash command call it. The function returns the
21
+ * `PrdCheckEnvelope[]` so the REPL can render via Ink without
22
+ * re-running the verification.
23
+ *
24
+ * - Exit codes follow `exitCodeFor` from the reporter:
25
+ * 0 — healthy (every criterion PASS or SKIPPED)
26
+ * 1 — failing (≥1 FAIL across the scanned PRDs)
27
+ * 2 — unparsed (≥1 PRD missing the acceptance section)
28
+ * When `--all` scans multiple PRDs the worst verdict wins (1 > 2 > 0).
29
+ *
30
+ * - The `knownCommands` set is sourced from the CLI registry — we
31
+ * accept it as an injected parameter so the spec can drive
32
+ * command-verification without importing the entire cli.ts
33
+ * module (which would pull the engine graph into the test).
34
+ */
35
+ import { readdirSync, readFileSync, statSync } from 'node:fs';
36
+ import { isAbsolute, join, relative, resolve } from 'node:path';
37
+ import { parsePrd } from '../../core/prd-check/parser.js';
38
+ import { buildEnvelope, exitCodeFor, renderTable, } from '../../core/prd-check/reporter.js';
39
+ import { defaultSessionReviewDeps, renderSessionReview, runSessionReview, } from '../../core/prd-check/session-review.js';
40
+ import { createDefaultDeps, verifyAll, } from '../../core/prd-check/verifiers.js';
41
+ const DEFAULT_PRD_DIR = 'docs/prd';
42
+ /**
43
+ * Run the gate. Resolves which PRDs to inspect, runs the parser +
44
+ * verifiers + reporter chain per PRD, emits the combined output,
45
+ * and sets `process.exitCode` to the worst verdict across the set.
46
+ */
47
+ export async function runPrdCheckCommand(ctx) {
48
+ // final : session-review mode. Orthogonal to
49
+ // the verifier-graph mode — no PRD path resolution, no command
50
+ // registry. The runner walks up for PRD.md, reads the NDJSON
51
+ // events log, and dispatches a cross-review subagent.
52
+ if (ctx.flags.session) {
53
+ const status = (line) => {
54
+ // Emit status lines through the output sink so the slash
55
+ // surface can render them inline. The status payload is
56
+ // intentionally lightweight — only the human-facing text.
57
+ ctx.writeOutput({
58
+ command: 'prd-check',
59
+ overall: 'healthy',
60
+ envelopes: [],
61
+ }, line);
62
+ };
63
+ const sessionDeps = ctx.sessionDeps ??
64
+ defaultSessionReviewDeps({ onStatus: status });
65
+ const review = await runSessionReview(ctx.cwd, sessionDeps);
66
+ const overall = review.status === 'ok'
67
+ ? review.outstanding.length === 0
68
+ ? 'healthy'
69
+ : 'failing'
70
+ : 'unparsed';
71
+ const result = {
72
+ command: 'prd-check',
73
+ overall,
74
+ envelopes: [],
75
+ sessionReview: review,
76
+ };
77
+ ctx.writeOutput(result, renderSessionReview(review));
78
+ process.exitCode = exitCodeFor(overall);
79
+ return result;
80
+ }
81
+ const paths = resolveTargets(ctx);
82
+ if (paths.length === 0) {
83
+ const result = {
84
+ command: 'prd-check',
85
+ overall: 'unparsed',
86
+ envelopes: [],
87
+ };
88
+ ctx.writeOutput(result, 'No PRD files found.');
89
+ process.exitCode = exitCodeFor('unparsed');
90
+ return result;
91
+ }
92
+ const deps = ctx.deps ??
93
+ createDefaultDeps({
94
+ workspaceRoot: ctx.cwd,
95
+ knownCommands: ctx.knownCommands,
96
+ });
97
+ const envelopes = [];
98
+ for (const path of paths) {
99
+ envelopes.push(checkSinglePrd(path, ctx.cwd, deps));
100
+ }
101
+ const overall = combineOverall(envelopes.map((e) => e.overall));
102
+ const result = {
103
+ command: 'prd-check',
104
+ overall,
105
+ envelopes,
106
+ };
107
+ const text = renderRun(result, ctx.cwd);
108
+ ctx.writeOutput(result, text);
109
+ process.exitCode = exitCodeFor(overall);
110
+ return result;
111
+ }
112
+ /**
113
+ * Render the combined plain-text view. Multi-PRD runs print one
114
+ * table per envelope separated by a divider; single-PRD runs print
115
+ * just the table to keep the output narrow.
116
+ */
117
+ function renderRun(result, cwd) {
118
+ if (result.envelopes.length === 0) {
119
+ return 'No PRD files found.';
120
+ }
121
+ if (result.envelopes.length === 1) {
122
+ return renderTable(result.envelopes[0]);
123
+ }
124
+ const parts = [];
125
+ for (const envelope of result.envelopes) {
126
+ const relPath = relative(cwd, envelope.prdPath) || envelope.prdPath;
127
+ parts.push(renderTable({ ...envelope, prdPath: relPath }));
128
+ parts.push('');
129
+ }
130
+ parts.push('-'.repeat(50));
131
+ const summary = `${result.envelopes.length} PRD(s) scanned. Overall: ${result.overall.toUpperCase()}`;
132
+ parts.push(summary);
133
+ return parts.join('\n');
134
+ }
135
+ function checkSinglePrd(prdPath, workspaceRoot, deps) {
136
+ let source;
137
+ try {
138
+ source = readFileSync(prdPath, 'utf8');
139
+ }
140
+ catch (error) {
141
+ const message = error instanceof Error ? error.message : String(error);
142
+ return {
143
+ command: 'prd-check',
144
+ prdPath: relative(workspaceRoot, prdPath) || prdPath,
145
+ title: null,
146
+ overall: 'unparsed',
147
+ counts: { pass: 0, fail: 0, skipped: 0 },
148
+ criteria: [
149
+ {
150
+ index: 0,
151
+ text: `PRD file unreadable: ${message}`,
152
+ status: 'fail',
153
+ results: [],
154
+ },
155
+ ],
156
+ };
157
+ }
158
+ const parsed = parsePrd(source);
159
+ const verified = verifyAll(parsed.criteria, deps);
160
+ return buildEnvelope({
161
+ prdPath: relative(workspaceRoot, prdPath) || prdPath,
162
+ title: parsed.title,
163
+ hasAcceptanceSection: parsed.hasAcceptanceSection,
164
+ verified,
165
+ });
166
+ }
167
+ function resolveTargets(ctx) {
168
+ if (ctx.flags.all) {
169
+ const prdDir = resolve(ctx.cwd, DEFAULT_PRD_DIR);
170
+ return listMarkdownFiles(prdDir);
171
+ }
172
+ if (ctx.prdPath) {
173
+ const absolute = isAbsolute(ctx.prdPath)
174
+ ? ctx.prdPath
175
+ : resolve(ctx.cwd, ctx.prdPath);
176
+ return [absolute];
177
+ }
178
+ return [];
179
+ }
180
+ function listMarkdownFiles(dir) {
181
+ let entries;
182
+ try {
183
+ entries = readdirSync(dir);
184
+ }
185
+ catch {
186
+ return [];
187
+ }
188
+ const out = [];
189
+ for (const entry of entries) {
190
+ const full = join(dir, entry);
191
+ let isDirectory = false;
192
+ try {
193
+ isDirectory = statSync(full).isDirectory();
194
+ }
195
+ catch {
196
+ continue;
197
+ }
198
+ if (isDirectory) {
199
+ out.push(...listMarkdownFiles(full));
200
+ continue;
201
+ }
202
+ if (entry.endsWith('.md')) {
203
+ out.push(full);
204
+ }
205
+ }
206
+ return out.sort();
207
+ }
208
+ /**
209
+ * Combine per-PRD verdicts into the run-wide one. failing > unparsed > healthy.
210
+ * Exported for the spec.
211
+ */
212
+ export function combineOverall(verdicts) {
213
+ if (verdicts.length === 0)
214
+ return 'unparsed';
215
+ if (verdicts.some((v) => v === 'failing'))
216
+ return 'failing';
217
+ if (verdicts.some((v) => v === 'unparsed'))
218
+ return 'unparsed';
219
+ return 'healthy';
220
+ }
221
+ /**
222
+ * Parse the CLI argv tail. Accepts:
223
+ *
224
+ * pugi prd-check -> error (no target)
225
+ * pugi prd-check <path> -> single PRD
226
+ * pugi prd-check --all -> scan docs/prd/**.md
227
+ * pugi prd-check <path> --json -> single PRD, JSON envelope
228
+ *
229
+ * `--json` is also forwarded from the global flag set in cli.ts;
230
+ * the local parse re-honours it so the slash command can use the
231
+ * same parser without the global flag plumbing.
232
+ */
233
+ export function parsePrdCheckArgs(args, options) {
234
+ let json = options.jsonDefault;
235
+ let all = false;
236
+ let session = false;
237
+ let prdPath;
238
+ for (const arg of args) {
239
+ if (arg === '--json') {
240
+ json = true;
241
+ continue;
242
+ }
243
+ if (arg === '--all') {
244
+ all = true;
245
+ continue;
246
+ }
247
+ if (arg === '--session') {
248
+ session = true;
249
+ continue;
250
+ }
251
+ if (arg.startsWith('--')) {
252
+ return { ok: false, error: `unknown flag: ${arg}` };
253
+ }
254
+ if (prdPath !== undefined) {
255
+ return { ok: false, error: `unexpected extra argument: ${arg}` };
256
+ }
257
+ prdPath = arg;
258
+ }
259
+ // final : `--session` is mutually exclusive with
260
+ // the verifier modes — it walks up for a PRD, reads NDJSON turns,
261
+ // and dispatches a subagent. No <path>, no --all, no command-
262
+ // registry inputs. Validating up-front gives operators a clear
263
+ // error instead of a silent fall-through.
264
+ if (session && (all || prdPath !== undefined)) {
265
+ return {
266
+ ok: false,
267
+ error: 'cannot combine --session with --all or <path>',
268
+ };
269
+ }
270
+ if (!session && !all && prdPath === undefined) {
271
+ return {
272
+ ok: false,
273
+ error: 'pugi prd-check <prd-path> | --all | --session (pass a PRD path, --all to scan docs/prd/**.md, or --session to review the live session against PRD.md)',
274
+ };
275
+ }
276
+ if (all && prdPath !== undefined) {
277
+ return { ok: false, error: 'cannot combine <path> with --all' };
278
+ }
279
+ return {
280
+ ok: true,
281
+ flags: { json, all, session },
282
+ ...(prdPath !== undefined ? { prdPath } : {}),
283
+ };
284
+ }
285
+ //# sourceMappingURL=prd-check.js.map
@@ -7,22 +7,22 @@ import { dirname, resolve } from 'node:path';
7
7
  * `pugi privacy` — read or update the operator's privacy mode.
8
8
  *
9
9
  * Subcommands:
10
- * - `pugi privacy show` — print current mode + source
11
- * - `pugi privacy set <mode>` — write `local-only | metadata | full`
10
+ * - `pugi privacy show` — print current mode + source
11
+ * - `pugi privacy set <mode>` — write `local-only | metadata | full`
12
12
  *
13
13
  * Persistence:
14
- * - Stored in `~/.pugi/privacy.json` (PUGI_HOME-aware).
15
- * - The `privacy` key in `~/.pugi/config.json` is also consulted at
16
- * read time (config takes precedence when both exist) so a user who
17
- * already set `pugi config set privacy ...` sees the same value
18
- * here.
14
+ * - Stored in `~/.pugi/privacy.json` (PUGI_HOME-aware).
15
+ * - The `privacy` key in `~/.pugi/config.json` is also consulted at
16
+ * read time (config takes precedence when both exist) so a user who
17
+ * already set `pugi config set privacy ...` sees the same value
18
+ * here.
19
19
  *
20
20
  * Modes:
21
- * - `local-only` — nothing leaves the workstation. Engine commands
22
- * refuse to ship transcripts; sync is a no-op.
23
- * - `metadata` — only artifact metadata + session timeline ships
24
- * (no raw file contents).
25
- * - `full` — full sync allowed (operator-acknowledged).
21
+ * - `local-only` — nothing leaves the workstation. Engine commands
22
+ * refuse to ship transcripts; sync is a no-op.
23
+ * - `metadata` — only artifact metadata + session timeline ships
24
+ * (no raw file contents).
25
+ * - `full` — full sync allowed (operator-acknowledged).
26
26
  */
27
27
  export const privacyModeSchema = z.enum(['local-only', 'metadata', 'full']);
28
28
  const privacyFileSchema = z.object({
@@ -53,9 +53,9 @@ function writePrivacyFile(mode) {
53
53
  }
54
54
  /**
55
55
  * Effective privacy mode resolution order:
56
- * 1. `~/.pugi/config.json` privacy key (when set via `pugi config set`)
57
- * 2. `~/.pugi/privacy.json` (when set via `pugi privacy set`)
58
- * 3. `metadata` (default — matches the M1 default-ship posture)
56
+ * 1. `~/.pugi/config.json` privacy key (when set via `pugi config set`)
57
+ * 2. `~/.pugi/privacy.json` (when set via `pugi privacy set`)
58
+ * 3. `metadata` (default — matches the M1 default-ship posture)
59
59
  */
60
60
  export function resolvePrivacyMode() {
61
61
  const config = readConfig();
@@ -75,8 +75,8 @@ export async function runPrivacyCommand(args, ctx) {
75
75
  modes: ['local-only', 'metadata', 'full'],
76
76
  }, [
77
77
  'Usage:',
78
- ' pugi privacy show Show current privacy mode.',
79
- ' pugi privacy set <mode> Set mode to local-only, metadata, or full.',
78
+ ' pugi privacy show Show current privacy mode.',
79
+ ' pugi privacy set <mode> Set mode to local-only, metadata, or full.',
80
80
  ].join('\n'));
81
81
  return;
82
82
  }