@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,107 @@
1
+ /**
2
+ * — `--bare` mode predicate.
3
+ *
4
+ * Mirror of the upstream tool's `--bare` flag: when active the CLI behaves
5
+ * like a plain LLM frontend with NO project auto-discovery. Useful for:
6
+ *
7
+ * - headless scripting where the operator wants deterministic, repo-
8
+ * independent behavior (`pugi --bare --print "..."`),
9
+ * - dropping into a workspace without auto-creating `.pugi/`,
10
+ * - REPL sessions that should NOT inject ambient `PUGI.md` / `CLAUDE.md`
11
+ * into the model prompt,
12
+ * - support / triage flows where the engineer needs the CLI to act
13
+ * like a fresh install regardless of where it's invoked.
14
+ *
15
+ * Discovery surfaces gated by `isBareMode()`:
16
+ *
17
+ * 1. `PUGI.md` / `AGENTS.md` / `CLAUDE.md` / `GEMINI.md` parent-dir
18
+ * walk-up (`loadTraversedMarkdown` in `core/context/markdown-traverse.ts`).
19
+ * 2. Workspace-root markdown context (`loadMarkdownContext` consumers).
20
+ * 3. Auto-init `.pugi/` scaffold on REPL boot in untouched dirs.
21
+ * 4. Persona / skill auto-load from `.pugi/skills/`.
22
+ * 5. Workspace summary (`readPugiSummary`) read on REPL session start.
23
+ *
24
+ * Activation precedence — the bare bit is "sticky" once set so any
25
+ * subprocess the CLI spawns inherits it without re-passing the flag:
26
+ *
27
+ * 1. Top-level `--bare` arg parsed by `parseArgs` in `runtime/cli.ts`.
28
+ * The parser sets `process.env.PUGI_BARE='1'` BEFORE the dispatch
29
+ * flows so callsites checking the env see the activated state.
30
+ * 2. `PUGI_BARE=1` env var (any value matching `/^(1|true|yes|on)$/i`).
31
+ * 3. Default: bare mode OFF — full auto-discovery as before.
32
+ *
33
+ * This mirrors the existing `PUGI_SKIP_SPLASH` / `PUGI_NO_AUTO_INIT`
34
+ * env-flag pattern so the bare module fits the rest of the runtime
35
+ * configuration grammar without inventing a new wire.
36
+ *
37
+ * Test surface: `apps/pugi-cli/test/bare-mode.spec.ts` exercises the
38
+ * env precedence, value parsing, and the explicit-set / clear helpers.
39
+ */
40
+ /**
41
+ * Env var consulted by `isBareMode()`. Kept as an export so the spec
42
+ * + the runtime CLI can use the same constant — no string-typing of
43
+ * the wire name across modules.
44
+ */
45
+ export const PUGI_BARE_ENV = 'PUGI_BARE';
46
+ /**
47
+ * Truthy values recognised on the `PUGI_BARE` env. Anything else
48
+ * (empty string, `0`, `false`, `no`, `off`, `disabled`, undefined) is
49
+ * treated as bare-mode OFF. The list is intentionally short — the
50
+ * value is set by the CLI parser and is not customer-typed prose, so
51
+ * we do not need a permissive boolean coercion.
52
+ */
53
+ const TRUTHY = new Set(['1', 'true', 'yes', 'on']);
54
+ /**
55
+ * Return true when bare mode is active for the current process. Reads
56
+ * `process.env[PUGI_BARE_ENV]` and applies the truthy-value match.
57
+ *
58
+ * Safe to call from any module (no FS, no side-effects). The runtime
59
+ * cost is a single env-var lookup + lower-case + set membership, so
60
+ * gating hot-path callsites with `if (isBareMode()) return ...` adds
61
+ * effectively zero overhead in the default (non-bare) case.
62
+ */
63
+ export function isBareMode(env = process.env) {
64
+ const raw = env[PUGI_BARE_ENV];
65
+ if (typeof raw !== 'string' || raw.length === 0)
66
+ return false;
67
+ return TRUTHY.has(raw.toLowerCase());
68
+ }
69
+ /**
70
+ * Explicitly activate bare mode for the current process. Called by
71
+ * `parseArgs` in `runtime/cli.ts` when `--bare` is seen on the command
72
+ * line so downstream modules (engine, REPL bootstrap, doctor probe)
73
+ * see a consistent activated state via `isBareMode()` regardless of
74
+ * whether the operator set the env var manually or used the flag.
75
+ *
76
+ * Subprocess inheritance is the reason we mutate `process.env` rather
77
+ * than threading a `bare: boolean` field through every call signature
78
+ * — every Node child_process spawn inherits `process.env` by default,
79
+ * so the bare bit propagates to MCP servers / hook scripts / git
80
+ * subprocesses without ceremony.
81
+ */
82
+ export function setBareMode(env = process.env) {
83
+ env[PUGI_BARE_ENV] = '1';
84
+ }
85
+ /**
86
+ * Clear bare mode for the current process. Provided primarily for the
87
+ * spec so adjacent tests do not leak state between cases. Production
88
+ * code does NOT call this — bare mode is a one-shot per process.
89
+ */
90
+ export function clearBareMode(env = process.env) {
91
+ delete env[PUGI_BARE_ENV];
92
+ }
93
+ /**
94
+ * Human-readable one-line banner printed by the dispatcher when bare
95
+ * mode is active and the invocation is NOT JSON-only. Kept as a single
96
+ * constant so the spec can assert the exact wording and downstream
97
+ * tools (status bars, doctor row, REPL header) stay in lockstep.
98
+ */
99
+ export const BARE_MODE_BANNER = 'Pugi --bare mode: project auto-discovery disabled.';
100
+ /**
101
+ * Short label rendered inside the `pugi doctor` table when bare mode
102
+ * is active. The doctor probe surfaces `BARE MODE` as a separate row
103
+ * so operators triaging "why is Pugi ignoring my PUGI.md" see the
104
+ * cause without grep'ing the env.
105
+ */
106
+ export const BARE_MODE_DOCTOR_LABEL = 'BARE MODE';
107
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,281 @@
1
+ /**
2
+ * bash/redirect — stdout-redirect helper (Pugi backlog P2,
3
+ * Karpathy "log discipline" pattern).
4
+ *
5
+ * Long-running scripts (training loops, monorepo builds, agentic
6
+ * stdout dumps) routinely emit hundreds of MB of text. Feeding that
7
+ * back into the LLM's context window burns tokens for noise — the
8
+ * model only needs the path + the trailing N lines to know whether
9
+ * the run succeeded and, if it failed, where to start looking.
10
+ *
11
+ * The redirect pipeline:
12
+ * 1. Caller flips `redirect` on `BashToolInput` to opt in.
13
+ * 2. `resolveRedirectTarget` decides the on-disk path:
14
+ * - default: .pugi/runs/<sessionId>/bash-<commandHash>.log
15
+ * - override: workspace-relative path supplied by the caller
16
+ * Concurrent calls with the same hash dedupe through the
17
+ * filename's `tool-call-id` suffix so two parallel dispatches
18
+ * never share a target file.
19
+ * 3. The bash tool spawns the child with stdio piped to a write
20
+ * stream pointed at the resolved path (no in-memory buffering of
21
+ * stdout/stderr beyond Node's internal pipe).
22
+ * 4. After the child exits, `readTail` reads the last N lines from
23
+ * the log file and `buildRedirectEnvelope` constructs the
24
+ * model-facing payload: empty stdout/stderr, populated logPath,
25
+ * populated tail, `truncated: false`.
26
+ *
27
+ * Token-savings example (real-world ceiling):
28
+ * 100k-line `pnpm build` log = ~6.4 MB raw stdout.
29
+ * - Without redirect: truncated to 32 KB head = ~8k tokens, and the
30
+ * trailing error (where the bug actually lives) is invisible.
31
+ * - With redirect: empty stdout + 20-line tail = ~400 tokens, plus
32
+ * logPath the operator/agent can tail on demand.
33
+ *
34
+ * This module is intentionally framework-free — it only owns path
35
+ * resolution, file tail reading, and the envelope shape. The bash
36
+ * tool wires it into the spawn lifecycle.
37
+ */
38
+ import { createHash } from 'node:crypto';
39
+ import { closeSync, existsSync, mkdirSync, openSync, readSync, renameSync, statSync, unlinkSync, writeFileSync, } from 'node:fs';
40
+ import { isAbsolute, join, relative, resolve } from 'node:path';
41
+ /**
42
+ * Default tail size when the caller does not pin one. Mirrors the
43
+ * Karpathy training-loop convention (`tail -n 20` for the last
44
+ * checkpoint window).
45
+ */
46
+ export const REDIRECT_DEFAULT_TAIL_LINES = 20;
47
+ /**
48
+ * Hard upper bound on tail size. The cap defends the context budget
49
+ * from a caller that flips redirect on but then asks for 100k tail
50
+ * lines — which would defeat the entire point of the redirect.
51
+ */
52
+ export const REDIRECT_MAX_TAIL_LINES = 200;
53
+ /**
54
+ * Deterministically hash a command string into a short hex prefix so
55
+ * the default log filename is predictable. Collisions are not a
56
+ * security concern (the file is workspace-scoped and the tool-call-id
57
+ * suffix disambiguates concurrent calls) so SHA-256 → 10 hex chars is
58
+ * the same compromise the agent-progress writer uses.
59
+ */
60
+ export function hashCommand(command) {
61
+ return createHash('sha256').update(command).digest('hex').slice(0, 10);
62
+ }
63
+ /**
64
+ * Validate and clamp the caller-supplied tail size. Negative / zero /
65
+ * NaN / >max values fall back to the default rather than throwing —
66
+ * the bash tool is the wrong layer to refuse a dispatch over a tail
67
+ * sizing bug.
68
+ */
69
+ export function normalizeTailLines(value) {
70
+ if (typeof value !== 'number' ||
71
+ !Number.isFinite(value) ||
72
+ value <= 0) {
73
+ return REDIRECT_DEFAULT_TAIL_LINES;
74
+ }
75
+ return Math.min(Math.floor(value), REDIRECT_MAX_TAIL_LINES);
76
+ }
77
+ /**
78
+ * Resolve the workspace-relative target the caller asked for (or the
79
+ * tool default) into an absolute path. Throws on traversal escapes
80
+ * (`..` out of workspace) and absolute-path overrides — those are the
81
+ * same anti-patterns the existing `resolveWorkspacePath` rejects, but
82
+ * reimplemented locally so this helper has no cross-module coupling.
83
+ */
84
+ export function resolveRedirectTarget(opts) {
85
+ const { workspaceRoot, sessionId, toolCallId, command, override } = opts;
86
+ const hash = hashCommand(command);
87
+ // Concurrent calls with the same command hash get distinct files by
88
+ // suffixing the (unique) tool-call-id. The bash tool already
89
+ // allocates a fresh id per dispatch, so this is sufficient even
90
+ // when two REPL panes fire the identical command at the same
91
+ // millisecond.
92
+ const defaultRelative = join('.pugi', 'runs', sessionId, `bash-${hash}-${toolCallId}.log`);
93
+ const requested = override ?? defaultRelative;
94
+ if (isAbsolute(requested)) {
95
+ throw new Error(`redirect.path must be workspace-relative; got absolute path: ${requested}`);
96
+ }
97
+ const absolutePath = resolve(workspaceRoot, requested);
98
+ const rel = relative(workspaceRoot, absolutePath);
99
+ if (rel === '' || rel.startsWith('..') || isAbsolute(rel)) {
100
+ throw new Error(`redirect.path escapes workspace root: ${requested}`);
101
+ }
102
+ // Derive the directory the bash tool needs to mkdir before opening
103
+ // the write stream. We split on the trailing separator rather than
104
+ // calling `dirname` so the helper has zero `path` API drift across
105
+ // platforms.
106
+ const slashIndex = Math.max(absolutePath.lastIndexOf('/'), absolutePath.lastIndexOf('\\'));
107
+ const directory = slashIndex > 0
108
+ ? absolutePath.slice(0, slashIndex)
109
+ : workspaceRoot;
110
+ return {
111
+ absolutePath,
112
+ workspacePath: rel,
113
+ directory,
114
+ };
115
+ }
116
+ /**
117
+ * Ensure the redirect file is opened for write through a
118
+ * `tmp + rename` dance so a partial write (operator Ctrl+C, child
119
+ * crash mid-flush) never leaves a torn file at the target path.
120
+ *
121
+ * Returns the open file descriptor along with the temp path so the
122
+ * caller can rename-on-success and unlink-on-cancel.
123
+ *
124
+ * The temp path mirrors the existing `editTool`/`writeTool` pattern:
125
+ * append `.pugi-tmp-<ts>` to the final name. We use `openSync` (vs
126
+ * `createWriteStream`) so the bash tool can hand the fd directly to
127
+ * `spawn`'s `stdio` array.
128
+ */
129
+ export function openRedirectFile(target) {
130
+ mkdirSync(target.directory, { recursive: true });
131
+ const tempPath = `${target.absolutePath}.pugi-tmp-${Date.now()}-${process.pid}`;
132
+ // mode 0o600 = rw for owner only — log files may contain secrets
133
+ // the child process leaked to stdout, so we lock them down by
134
+ // default. The bash tool can later promote them to 0o644 on a
135
+ // per-call basis when the operator opts in.
136
+ const fd = openSync(tempPath, 'w', 0o600);
137
+ return { fd, tempPath };
138
+ }
139
+ /**
140
+ * Finalise the temp file by renaming it onto `absolutePath` so the
141
+ * model-facing logPath always points at a complete file. Idempotent —
142
+ * the bash tool calls this on success AND on timeout/cancel so the
143
+ * partial log is preserved as a debugging artifact (the agent can
144
+ * still read the tail to see how far the run got).
145
+ */
146
+ export function finaliseRedirectFile(target, tempPath) {
147
+ if (!existsSync(tempPath))
148
+ return;
149
+ renameSync(tempPath, target.absolutePath);
150
+ }
151
+ /**
152
+ * Best-effort cleanup of the temp file when the redirect path was
153
+ * never fully written (e.g. spawn never started). Swallows ENOENT so
154
+ * the cleanup is idempotent.
155
+ */
156
+ export function cleanupRedirectTemp(tempPath) {
157
+ try {
158
+ if (existsSync(tempPath))
159
+ unlinkSync(tempPath);
160
+ }
161
+ catch {
162
+ // best-effort
163
+ }
164
+ }
165
+ /**
166
+ * Read the last N lines of a file, without slurping the whole file
167
+ * into memory. We use a backwards-chunked read so even multi-GB logs
168
+ * stay bounded by the tail size.
169
+ *
170
+ * The implementation is intentionally simple — we read at most
171
+ * `maxBytes` (~64 KB by default) from the file tail because 200 lines
172
+ * of compiler output rarely exceed that. Long-line cases (one massive
173
+ * JSON blob on a single line) fall back to "whatever fits in maxBytes
174
+ * counts as the tail".
175
+ */
176
+ export function readTail(path, lines, options = {}) {
177
+ if (!existsSync(path))
178
+ return '';
179
+ const maxBytes = options.maxBytes ?? 64 * 1024;
180
+ const stat = statSync(path);
181
+ if (stat.size === 0)
182
+ return '';
183
+ const readSize = Math.min(stat.size, maxBytes);
184
+ // `readFileSync` with an explicit byte slice is the simplest API
185
+ // available in node:fs without dropping to `read(fd, buf, ...)`.
186
+ // We read the trailing window of the file by opening it and
187
+ // seeking to `stat.size - readSize`.
188
+ const fd = openSync(path, 'r');
189
+ try {
190
+ const buf = Buffer.alloc(readSize);
191
+ const bytesRead = readFileSyncSlice(fd, buf, stat.size - readSize);
192
+ const trailing = buf.subarray(0, bytesRead).toString('utf8');
193
+ // The first line in the buffer may be a partial line if we did
194
+ // not seek to a line boundary. Drop it unless the buffer covers
195
+ // the whole file.
196
+ const startedFromHead = stat.size <= readSize;
197
+ const split = trailing.split('\n');
198
+ // Re-emit the tail; if we DID start mid-line, discard the
199
+ // partial-leading fragment.
200
+ const usable = startedFromHead ? split : split.slice(1);
201
+ // Trailing newline produces an empty string at the end of split;
202
+ // drop it so the line count matches operator expectation.
203
+ if (usable.length > 0 && usable[usable.length - 1] === '') {
204
+ usable.pop();
205
+ }
206
+ return usable.slice(-lines).join('\n');
207
+ }
208
+ finally {
209
+ closeSync(fd);
210
+ }
211
+ }
212
+ /**
213
+ * Helper: read `buf.length` bytes from `fd` starting at `position`.
214
+ * Returns the actual number of bytes read.
215
+ *
216
+ * Loops over `readSync` so a short read on a large file (interruptible
217
+ * syscall, EAGAIN) still produces the full requested window. Bounded
218
+ * by `buf.length` so the helper cannot over-read past the caller's
219
+ * buffer regardless of how the kernel chunked the response.
220
+ */
221
+ function readFileSyncSlice(fd, buf, position) {
222
+ let totalRead = 0;
223
+ while (totalRead < buf.length) {
224
+ const got = readSync(fd, buf, totalRead, buf.length - totalRead, position + totalRead);
225
+ if (got === 0)
226
+ break;
227
+ totalRead += got;
228
+ }
229
+ return totalRead;
230
+ }
231
+ /**
232
+ * Compose the model-facing envelope. The bash tool calls this once
233
+ * the child has exited and the log file has been renamed into place.
234
+ *
235
+ * `truncated` is hardwired to `false` because the redirect contract
236
+ * is "the full output is in the log, we hand you the path and a
237
+ * tail". The legacy stdout/stderr truncation marker (`(...truncated
238
+ * at N bytes)`) only fires in the buffered path that this redirect
239
+ * pipeline replaces — surfacing `truncated: true` for a redirect
240
+ * would mislead the model into thinking it lost data.
241
+ */
242
+ export function buildRedirectEnvelope(opts) {
243
+ return {
244
+ stdout: '',
245
+ stderr: '',
246
+ exitCode: opts.exitCode,
247
+ logPath: opts.logPath,
248
+ tail: opts.tail,
249
+ truncated: false,
250
+ };
251
+ }
252
+ /**
253
+ * Convenience wrapper for the bash tool: given a completed spawn
254
+ * (exit code + finalised log path) and a caller-supplied
255
+ * `BashRedirectOptions`, build the envelope in one call. The bash
256
+ * tool keeps the spawn lifecycle (open fd, stream child's
257
+ * stdout/stderr to it, wait for close, rename) but delegates the
258
+ * tail-read + envelope assembly here so the test suite can exercise
259
+ * the helper without spinning up a child process.
260
+ */
261
+ export function applyRedirect(opts) {
262
+ const tail = readTail(opts.target.absolutePath, opts.tailLines);
263
+ return buildRedirectEnvelope({
264
+ exitCode: opts.exitCode,
265
+ logPath: opts.target.workspacePath,
266
+ tail,
267
+ });
268
+ }
269
+ /**
270
+ * Internal helper used by the spec when it needs to seed a log file
271
+ * for the tail-reader. Exported so tests do not depend on the
272
+ * file-tools/write surface (which has its own permission gate).
273
+ */
274
+ export function writeLogForTest(absolutePath, body) {
275
+ const slashIndex = Math.max(absolutePath.lastIndexOf('/'), absolutePath.lastIndexOf('\\'));
276
+ if (slashIndex > 0) {
277
+ mkdirSync(absolutePath.slice(0, slashIndex), { recursive: true });
278
+ }
279
+ writeFileSync(absolutePath, body, { encoding: 'utf8', mode: 0o600 });
280
+ }
281
+ //# sourceMappingURL=redirect.js.map