@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,373 @@
1
+ /**
2
+ * `pugi skillify` — codify a freeform operator description into a
3
+ * reusable skill scaffold.
4
+ *
5
+ * Bundled skill, batch 2 (backlog). The operator types a short
6
+ * description ("Write a Pugi skill that scans for `// TODO ASAP` and
7
+ * fails CI"); this skill asks the engine to produce a canonical
8
+ * skill scaffold (name + description + mode + allowedTools + prompt
9
+ * template + example invocation), validates the engine output, and
10
+ * writes the result к `.pugi/skills/<kebab-name>.md` in the same
11
+ * frontmatter format the existing bundled skills use.
12
+ *
13
+ * # Output shape
14
+ *
15
+ * The on-disk file mirrors the stuck / simplify / remember frontmatter
16
+ * shape — `---name / description / mode---` block followed by markdown
17
+ * body. The body holds:
18
+ *
19
+ * - Operator-facing usage block.
20
+ * - Prompt template that the slash dispatcher injects when the skill
21
+ * fires.
22
+ * - Example invocation.
23
+ *
24
+ * # Safety
25
+ *
26
+ * The engine's JSON envelope is validated field-by-field before any
27
+ * file is touched. A malformed envelope produces an explicit error
28
+ * with the failing field — we never write a half-baked skill to disk.
29
+ *
30
+ * # Provenance
31
+ *
32
+ * Inspired by the external bundled-skills pattern (intel from
33
+ * leak-research memos, independent implementation TS). No upstream code reused.
34
+ */
35
+ import { existsSync, mkdirSync, renameSync, rmSync, writeFileSync, } from 'node:fs';
36
+ import { dirname, join } from 'node:path';
37
+ function parseFlags(args) {
38
+ const flags = {
39
+ json: false,
40
+ description: null,
41
+ outputDir: null,
42
+ force: false,
43
+ dryRun: false,
44
+ };
45
+ const positional = [];
46
+ for (let i = 0; i < args.length; i += 1) {
47
+ const arg = args[i];
48
+ if (arg === undefined)
49
+ continue;
50
+ if (arg === '--json') {
51
+ flags.json = true;
52
+ continue;
53
+ }
54
+ if (arg === '--force') {
55
+ flags.force = true;
56
+ continue;
57
+ }
58
+ if (arg === '--dry-run') {
59
+ flags.dryRun = true;
60
+ continue;
61
+ }
62
+ if (arg === '--output-dir') {
63
+ const next = args[i + 1];
64
+ if (next === undefined) {
65
+ return { flags, error: '--output-dir requires a value' };
66
+ }
67
+ flags.outputDir = next;
68
+ i += 1;
69
+ continue;
70
+ }
71
+ if (arg === '--help' || arg === '-h') {
72
+ return { flags, error: 'help' };
73
+ }
74
+ if (arg.startsWith('--')) {
75
+ return { flags, error: `unknown flag: ${arg}` };
76
+ }
77
+ positional.push(arg);
78
+ }
79
+ if (positional.length > 0) {
80
+ flags.description = positional.join(' ').trim();
81
+ if (flags.description === '')
82
+ flags.description = null;
83
+ }
84
+ return { flags, error: null };
85
+ }
86
+ const ALLOWED_TOOL_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
87
+ const NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
88
+ /**
89
+ * Validate + normalise the engine's JSON envelope. Public for direct
90
+ * test coverage of the boundary contract.
91
+ */
92
+ export function parseScaffoldEnvelope(raw) {
93
+ const json = extractJsonBlock(raw);
94
+ if (json === null) {
95
+ return { ok: false, error: 'engine output did not contain a JSON object' };
96
+ }
97
+ let value;
98
+ try {
99
+ value = JSON.parse(json);
100
+ }
101
+ catch (err) {
102
+ const message = err instanceof Error ? err.message : String(err);
103
+ return { ok: false, error: `engine JSON parse failed: ${message}` };
104
+ }
105
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
106
+ return { ok: false, error: 'engine envelope must be a JSON object' };
107
+ }
108
+ const obj = value;
109
+ const name = obj.name;
110
+ if (typeof name !== 'string' || !NAME_PATTERN.test(name)) {
111
+ return {
112
+ ok: false,
113
+ error: 'envelope.name must be kebab-case [a-z][a-z0-9-]*',
114
+ };
115
+ }
116
+ const description = obj.description;
117
+ if (typeof description !== 'string' ||
118
+ description.length < 8 ||
119
+ description.length > 500) {
120
+ return {
121
+ ok: false,
122
+ error: 'envelope.description must be a string 8..500 chars',
123
+ };
124
+ }
125
+ const modeRaw = obj.mode;
126
+ if (modeRaw !== 'read-only' &&
127
+ modeRaw !== 'read-write' &&
128
+ modeRaw !== 'agent') {
129
+ return {
130
+ ok: false,
131
+ error: 'envelope.mode must be read-only | read-write | agent',
132
+ };
133
+ }
134
+ const allowedToolsRaw = obj.allowedTools;
135
+ if (!Array.isArray(allowedToolsRaw)) {
136
+ return { ok: false, error: 'envelope.allowedTools must be an array' };
137
+ }
138
+ const allowedTools = [];
139
+ for (let i = 0; i < allowedToolsRaw.length; i += 1) {
140
+ const item = allowedToolsRaw[i];
141
+ if (typeof item !== 'string' || !ALLOWED_TOOL_PATTERN.test(item)) {
142
+ return {
143
+ ok: false,
144
+ error: `envelope.allowedTools[${i}] must match ${String(ALLOWED_TOOL_PATTERN)}`,
145
+ };
146
+ }
147
+ allowedTools.push(item);
148
+ }
149
+ const promptTemplate = obj.promptTemplate;
150
+ if (typeof promptTemplate !== 'string' ||
151
+ promptTemplate.length < 16 ||
152
+ promptTemplate.length > 8000) {
153
+ return {
154
+ ok: false,
155
+ error: 'envelope.promptTemplate must be a string 16..8000 chars',
156
+ };
157
+ }
158
+ const exampleInvocation = obj.exampleInvocation;
159
+ if (typeof exampleInvocation !== 'string' ||
160
+ exampleInvocation.length < 4 ||
161
+ exampleInvocation.length > 500) {
162
+ return {
163
+ ok: false,
164
+ error: 'envelope.exampleInvocation must be a string 4..500 chars',
165
+ };
166
+ }
167
+ return {
168
+ ok: true,
169
+ scaffold: {
170
+ name,
171
+ description,
172
+ mode: modeRaw,
173
+ allowedTools,
174
+ promptTemplate,
175
+ exampleInvocation,
176
+ },
177
+ };
178
+ }
179
+ /**
180
+ * Extract a top-level JSON object from a freeform engine response. We
181
+ * walk the string and balance braces, ignoring brace characters inside
182
+ * strings. Returns the first balanced `{...}` span or null if none.
183
+ * Public for direct test coverage; engines sometimes prepend prose to
184
+ * the envelope and we have to be resilient.
185
+ */
186
+ export function extractJsonBlock(raw) {
187
+ const start = raw.indexOf('{');
188
+ if (start === -1)
189
+ return null;
190
+ let depth = 0;
191
+ let inString = null;
192
+ let escape = false;
193
+ for (let i = start; i < raw.length; i += 1) {
194
+ const ch = raw.charAt(i);
195
+ if (inString !== null) {
196
+ if (escape) {
197
+ escape = false;
198
+ continue;
199
+ }
200
+ if (ch === '\\') {
201
+ escape = true;
202
+ continue;
203
+ }
204
+ if (ch === inString) {
205
+ inString = null;
206
+ }
207
+ continue;
208
+ }
209
+ if (ch === '"' || ch === "'") {
210
+ inString = ch;
211
+ continue;
212
+ }
213
+ if (ch === '{')
214
+ depth += 1;
215
+ if (ch === '}') {
216
+ depth -= 1;
217
+ if (depth === 0) {
218
+ return raw.slice(start, i + 1);
219
+ }
220
+ }
221
+ }
222
+ return null;
223
+ }
224
+ function atomicWriteFile(targetPath, body) {
225
+ const parent = dirname(targetPath);
226
+ if (!existsSync(parent)) {
227
+ mkdirSync(parent, { recursive: true });
228
+ }
229
+ const tmpPath = `${targetPath}.tmp-${process.pid}-${Date.now()}-${Math.floor(Math.random() * 1_000_000)}`;
230
+ try {
231
+ writeFileSync(tmpPath, body, 'utf8');
232
+ renameSync(tmpPath, targetPath);
233
+ }
234
+ catch (err) {
235
+ try {
236
+ rmSync(tmpPath, { force: true });
237
+ }
238
+ catch {
239
+ // ignore cleanup
240
+ }
241
+ throw err;
242
+ }
243
+ }
244
+ /**
245
+ * Render the on-disk skill markdown using the canonical frontmatter
246
+ * format the existing batch-1 bundled skills follow. Public so the
247
+ * test suite can assert the rendered text directly.
248
+ */
249
+ export function renderSkillMarkdown(scaffold) {
250
+ // The frontmatter description is quoted to keep multi-line summaries
251
+ // legal YAML without dragging in a real YAML emitter.
252
+ const allowedToolsLine = scaffold.allowedTools.length === 0
253
+ ? '[]'
254
+ : `[${scaffold.allowedTools.map((t) => `"${t}"`).join(', ')}]`;
255
+ const lines = [];
256
+ lines.push('---');
257
+ lines.push(`name: ${scaffold.name}`);
258
+ lines.push(`description: ${JSON.stringify(scaffold.description)}`);
259
+ lines.push(`mode: ${scaffold.mode}`);
260
+ lines.push(`allowedTools: ${allowedToolsLine}`);
261
+ lines.push('---');
262
+ lines.push('');
263
+ lines.push(`# /${scaffold.name}`);
264
+ lines.push('');
265
+ lines.push(scaffold.description);
266
+ lines.push('');
267
+ lines.push('## Prompt template');
268
+ lines.push('');
269
+ lines.push(scaffold.promptTemplate.trim());
270
+ lines.push('');
271
+ lines.push('## Example');
272
+ lines.push('');
273
+ lines.push('```');
274
+ lines.push(scaffold.exampleInvocation.trim());
275
+ lines.push('```');
276
+ lines.push('');
277
+ return `${lines.join('\n')}\n`;
278
+ }
279
+ const SCHEMA_HINT = JSON.stringify({
280
+ name: '<kebab-case>',
281
+ description: '<8..500 chars>',
282
+ mode: 'read-only | read-write | agent',
283
+ allowedTools: ['<tool-name>', '...'],
284
+ promptTemplate: '<16..8000 chars>',
285
+ exampleInvocation: '<short usage example>',
286
+ });
287
+ export async function runSkillifyCommand(args, ctx) {
288
+ const { flags, error } = parseFlags(args);
289
+ if (error === 'help') {
290
+ ctx.writeOutput({ ok: true, command: 'skillify', usage: SKILLIFY_USAGE }, SKILLIFY_USAGE);
291
+ return { scaffold: null, writtenPath: null, exitCode: 0 };
292
+ }
293
+ if (error !== null) {
294
+ ctx.writeOutput({ ok: false, command: 'skillify', error }, `pugi skillify: ${error}`);
295
+ return { scaffold: null, writtenPath: null, exitCode: 2 };
296
+ }
297
+ if (flags.description === null) {
298
+ const msg = 'description is required';
299
+ ctx.writeOutput({ ok: false, command: 'skillify', error: msg }, `pugi skillify: ${msg}\n\n${SKILLIFY_USAGE}`);
300
+ return { scaffold: null, writtenPath: null, exitCode: 2 };
301
+ }
302
+ let engineRaw;
303
+ try {
304
+ engineRaw = await ctx.engineInvoker({
305
+ description: flags.description,
306
+ schemaHint: SCHEMA_HINT,
307
+ });
308
+ }
309
+ catch (err) {
310
+ const message = err instanceof Error ? err.message : String(err);
311
+ ctx.writeOutput({ ok: false, command: 'skillify', error: `engine failed: ${message}` }, `pugi skillify: engine failed — ${message}`);
312
+ return { scaffold: null, writtenPath: null, exitCode: 1 };
313
+ }
314
+ const parsed = parseScaffoldEnvelope(engineRaw);
315
+ if (!parsed.ok) {
316
+ ctx.writeOutput({ ok: false, command: 'skillify', error: parsed.error, raw: engineRaw }, `pugi skillify: engine envelope invalid — ${parsed.error}`);
317
+ return { scaffold: null, writtenPath: null, exitCode: 1 };
318
+ }
319
+ const scaffold = parsed.scaffold;
320
+ const outputDir = flags.outputDir ?? join(ctx.cwd, '.pugi', 'skills');
321
+ const writtenPath = join(outputDir, `${scaffold.name}.md`);
322
+ if (flags.dryRun) {
323
+ ctx.writeOutput({
324
+ ok: true,
325
+ command: 'skillify',
326
+ scaffold,
327
+ wouldWrite: writtenPath,
328
+ body: renderSkillMarkdown(scaffold),
329
+ dryRun: true,
330
+ }, `pugi skillify: dry-run — would write ${writtenPath}`);
331
+ return { scaffold, writtenPath: null, exitCode: 0 };
332
+ }
333
+ if (existsSync(writtenPath) && !flags.force) {
334
+ const msg = `target exists: ${writtenPath} (pass --force to overwrite)`;
335
+ ctx.writeOutput({ ok: false, command: 'skillify', error: msg, scaffold }, `pugi skillify: ${msg}`);
336
+ return { scaffold, writtenPath: null, exitCode: 1 };
337
+ }
338
+ const body = renderSkillMarkdown(scaffold);
339
+ try {
340
+ atomicWriteFile(writtenPath, body);
341
+ }
342
+ catch (err) {
343
+ const message = err instanceof Error ? err.message : String(err);
344
+ ctx.writeOutput({
345
+ ok: false,
346
+ command: 'skillify',
347
+ error: `write failed: ${message}`,
348
+ scaffold,
349
+ }, `pugi skillify: write failed — ${message}`);
350
+ return { scaffold, writtenPath: null, exitCode: 1 };
351
+ }
352
+ ctx.writeOutput({ ok: true, command: 'skillify', scaffold, writtenPath }, `Wrote ${writtenPath} — invoke via \`/skill-${scaffold.name}\`.`);
353
+ return { scaffold, writtenPath, exitCode: 0 };
354
+ }
355
+ const SKILLIFY_USAGE = [
356
+ 'pugi skillify — generate a reusable skill scaffold from a freeform description.',
357
+ '',
358
+ 'Usage:',
359
+ ' pugi skillify "<description>" [--output-dir <dir>] [--force] [--dry-run] [--json]',
360
+ '',
361
+ 'Flags:',
362
+ ' --output-dir <dir> Destination directory (default: .pugi/skills/).',
363
+ ' --force Overwrite an existing file with the same name.',
364
+ ' --dry-run Print the rendered markdown without writing it.',
365
+ ' --json Emit a JSON envelope instead of human text.',
366
+ '',
367
+ 'Engine envelope schema:',
368
+ ' { "name": "kebab", "description": "...", "mode": "read-only|read-write|agent",',
369
+ ' "allowedTools": ["..."], "promptTemplate": "...", "exampleInvocation": "..." }',
370
+ '',
371
+ 'Output lands at .pugi/skills/<name>.md in the canonical frontmatter format.',
372
+ ].join('\n');
373
+ //# sourceMappingURL=skillify.js.map