@pugi/cli 0.1.0-beta.1 → 0.1.0-beta.100

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 (448) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/LICENSE +1 -1
  3. package/README.md +53 -11
  4. package/THIRD_PARTY_NOTICES.md +40 -0
  5. package/assets/pugi-mascot.ansi +15 -40
  6. package/assets/pugi-prozr2-mascot.ansi +9 -0
  7. package/bin/run.js +33 -1
  8. package/dist/commands/deploy.js +40 -40
  9. package/dist/commands/flatten.js +191 -0
  10. package/dist/commands/jobs-watch.js +201 -0
  11. package/dist/commands/jobs.js +42 -27
  12. package/dist/commands/retro.js +210 -0
  13. package/dist/commands/smoke.js +133 -0
  14. package/dist/core/agent-progress/cleanup.js +134 -0
  15. package/dist/core/agent-progress/schema.js +144 -0
  16. package/dist/core/agent-progress/writer.js +101 -0
  17. package/dist/core/agents/adaptive-router.js +330 -0
  18. package/dist/core/agents/query-decomposer.js +297 -0
  19. package/dist/core/agents/registry.js +3 -3
  20. package/dist/core/approvals/shortcut-resolver.js +98 -0
  21. package/dist/core/artifact-chain/dispatcher.js +148 -0
  22. package/dist/core/artifact-chain/exporter.js +164 -0
  23. package/dist/core/artifact-chain/state.js +243 -0
  24. package/dist/core/artifact-chain/steps.js +169 -0
  25. package/dist/core/ask-user/question.js +92 -0
  26. package/dist/core/audit/audit-trail.js +275 -0
  27. package/dist/core/auth/ensure-authenticated.js +129 -0
  28. package/dist/core/auth/env-provider.js +238 -0
  29. package/dist/core/auto-open-browser.js +4 -4
  30. package/dist/core/auto-update/channels.js +122 -0
  31. package/dist/core/auto-update/checker.js +241 -0
  32. package/dist/core/auto-update/state.js +235 -0
  33. package/dist/core/bare-mode/index.js +107 -0
  34. package/dist/core/bash/redirect.js +281 -0
  35. package/dist/core/bash-classifier.js +436 -40
  36. package/dist/core/checkpoint/resumer.js +149 -0
  37. package/dist/core/checkpoint/rewinder.js +291 -0
  38. package/dist/core/checkpoints/shadow-git.js +670 -0
  39. package/dist/core/citations/parser.js +109 -0
  40. package/dist/core/classifier/yolo-classifier.js +88 -0
  41. package/dist/core/codegraph/db.js +506 -0
  42. package/dist/core/codegraph/decision-store.js +248 -0
  43. package/dist/core/codegraph/detect-repo.js +459 -0
  44. package/dist/core/codegraph/install.js +134 -0
  45. package/dist/core/codegraph/offer-hook.js +220 -0
  46. package/dist/core/codegraph/parser.js +71 -0
  47. package/dist/core/codegraph/types.js +34 -0
  48. package/dist/core/compact/auto-trigger.js +96 -0
  49. package/dist/core/compact/buffer-rewriter.js +115 -0
  50. package/dist/core/compact/summarizer.js +208 -0
  51. package/dist/core/compact/token-counter.js +108 -0
  52. package/dist/core/consensus/anvil-fanout.js +25 -25
  53. package/dist/core/consensus/diff-capture.js +121 -12
  54. package/dist/core/consensus/rubric.js +21 -21
  55. package/dist/core/context/builder.js +6 -6
  56. package/dist/core/context/compaction-events.js +8 -8
  57. package/dist/core/context/compaction.js +31 -31
  58. package/dist/core/context/index.js +15 -8
  59. package/dist/core/context/invariants.js +51 -51
  60. package/dist/core/context/markdown-loader.js +28 -10
  61. package/dist/core/context/markdown-traverse.js +255 -0
  62. package/dist/core/context/pugiignore.js +41 -41
  63. package/dist/core/context/repo-skeleton.js +37 -37
  64. package/dist/core/context/tool-eviction.js +55 -0
  65. package/dist/core/context/watcher.js +32 -32
  66. package/dist/core/context/working-set.js +23 -23
  67. package/dist/core/coordinator/agent-tools.js +77 -0
  68. package/dist/core/coordinator/agent-toolset.js +65 -0
  69. package/dist/core/coordinator/fsm.js +73 -0
  70. package/dist/core/coordinator/mode-fsm.js +70 -0
  71. package/dist/core/cost/rate-card.js +129 -0
  72. package/dist/core/cost/tracker.js +221 -0
  73. package/dist/core/credentials.js +13 -13
  74. package/dist/core/cron/scheduler.js +138 -0
  75. package/dist/core/denial-tracking/index.js +8 -0
  76. package/dist/core/denial-tracking/state.js +264 -0
  77. package/dist/core/diagnostics/probe-runner.js +93 -0
  78. package/dist/core/diagnostics/probes/api.js +46 -0
  79. package/dist/core/diagnostics/probes/auth.js +93 -0
  80. package/dist/core/diagnostics/probes/bare-mode.js +42 -0
  81. package/dist/core/diagnostics/probes/cli-version.js +127 -0
  82. package/dist/core/diagnostics/probes/config.js +72 -0
  83. package/dist/core/diagnostics/probes/denial-tracking.js +57 -0
  84. package/dist/core/diagnostics/probes/disk.js +81 -0
  85. package/dist/core/diagnostics/probes/engine-live.js +46 -0
  86. package/dist/core/diagnostics/probes/git.js +65 -0
  87. package/dist/core/diagnostics/probes/hooks.js +118 -0
  88. package/dist/core/diagnostics/probes/mcp.js +75 -0
  89. package/dist/core/diagnostics/probes/node.js +59 -0
  90. package/dist/core/diagnostics/probes/pnpm.js +36 -0
  91. package/dist/core/diagnostics/probes/pugi-md.js +89 -0
  92. package/dist/core/diagnostics/probes/sandbox.js +72 -0
  93. package/dist/core/diagnostics/probes/session.js +74 -0
  94. package/dist/core/diagnostics/probes/status-snapshot.js +488 -0
  95. package/dist/core/diagnostics/probes/workspace.js +63 -0
  96. package/dist/core/diagnostics/types.js +70 -0
  97. package/dist/core/dispatch/cache-cleanup.js +197 -0
  98. package/dist/core/dispatch/cache-handoff.js +295 -0
  99. package/dist/core/edits/apply-patch-layer-e.js +189 -0
  100. package/dist/core/edits/dispatch.js +333 -7
  101. package/dist/core/edits/format-detector.js +260 -0
  102. package/dist/core/edits/format-matrix.js +26 -0
  103. package/dist/core/edits/fuzzy-ladder.js +650 -0
  104. package/dist/core/edits/index.js +5 -1
  105. package/dist/core/edits/journal.js +199 -0
  106. package/dist/core/edits/layer-a-apply.js +15 -15
  107. package/dist/core/edits/layer-a-fuzzy-apply.js +198 -0
  108. package/dist/core/edits/layer-b-apply.js +9 -9
  109. package/dist/core/edits/layer-c-apply.js +6 -6
  110. package/dist/core/edits/layer-d-ast.js +557 -14
  111. package/dist/core/edits/marker-parser.js +12 -12
  112. package/dist/core/edits/security-gate.js +27 -27
  113. package/dist/core/edits/verify-hook.js +273 -0
  114. package/dist/core/edits/worktree.js +322 -0
  115. package/dist/core/engine/anvil-client.js +214 -26
  116. package/dist/core/engine/auto-compact.js +247 -0
  117. package/dist/core/engine/budgets.js +220 -0
  118. package/dist/core/engine/compact-llm-summarizer.js +124 -0
  119. package/dist/core/engine/context-prefix.js +155 -0
  120. package/dist/core/engine/index.js +1 -1
  121. package/dist/core/engine/intensity.js +163 -0
  122. package/dist/core/engine/intent.js +260 -0
  123. package/dist/core/engine/native-pugi.js +1559 -227
  124. package/dist/core/engine/prompts.js +192 -16
  125. package/dist/core/engine/strip-internal-fields.js +124 -0
  126. package/dist/core/engine/tool-bridge.js +1887 -59
  127. package/dist/core/engine/verification-patterns.js +195 -0
  128. package/dist/core/evaluation/golden-dataset.js +293 -0
  129. package/dist/core/feedback/queue.js +177 -0
  130. package/dist/core/feedback/submitter.js +145 -0
  131. package/dist/core/file-cache.js +113 -1
  132. package/dist/core/flatten/flatten-repo.js +439 -0
  133. package/dist/core/format/osc8-link.js +28 -0
  134. package/dist/core/hook-chains.js +392 -0
  135. package/dist/core/hooks/citation-verify-hook.js +138 -0
  136. package/dist/core/hooks/citation-verify.js +112 -0
  137. package/dist/core/hooks/events.js +46 -0
  138. package/dist/core/hooks/index.js +15 -0
  139. package/dist/core/hooks/registry.js +216 -0
  140. package/dist/core/hooks/runner.js +236 -0
  141. package/dist/core/hooks/v2/event-emitter.js +115 -0
  142. package/dist/core/hooks/v2/executor.js +282 -0
  143. package/dist/core/hooks/v2/index.js +25 -0
  144. package/dist/core/hooks/v2/lifecycle.js +104 -0
  145. package/dist/core/hooks/v2/loader.js +216 -0
  146. package/dist/core/hooks/v2/matcher.js +125 -0
  147. package/dist/core/hooks/v2/trust.js +143 -0
  148. package/dist/core/hooks/v2/types.js +86 -0
  149. package/dist/core/hooks/worktree-events.js +158 -0
  150. package/dist/core/image/renderer.js +71 -0
  151. package/dist/core/init/detector.js +582 -0
  152. package/dist/core/init/template-renderer.js +242 -0
  153. package/dist/core/jobs/registry.js +18 -18
  154. package/dist/core/ledger/results-tsv.js +142 -0
  155. package/dist/core/log-discipline/stdout-redirect.js +51 -0
  156. package/dist/core/lsp/cache.js +105 -0
  157. package/dist/core/lsp/client.js +1229 -0
  158. package/dist/core/lsp/language-detect.js +66 -0
  159. package/dist/core/lsp/post-edit-diagnostics.js +171 -0
  160. package/dist/core/lsp/server-detect.js +173 -0
  161. package/dist/core/lsp/symbol-cache.js +162 -0
  162. package/dist/core/lsp/symbol-tools.js +664 -0
  163. package/dist/core/mcp/client.js +97 -28
  164. package/dist/core/mcp/http-server.js +553 -0
  165. package/dist/core/mcp/orchestrator-config.js +192 -0
  166. package/dist/core/mcp/orchestrator-tools.js +806 -0
  167. package/dist/core/mcp/permission.js +190 -0
  168. package/dist/core/mcp/registry.js +39 -17
  169. package/dist/core/mcp/server-tools.js +219 -0
  170. package/dist/core/mcp/server.js +397 -0
  171. package/dist/core/mcp/trust.js +10 -10
  172. package/dist/core/memory/dual-write.js +416 -0
  173. package/dist/core/memory/passive-extract.js +130 -0
  174. package/dist/core/memory/phase1-kinds.js +20 -0
  175. package/dist/core/memory/secret-scanner.js +304 -0
  176. package/dist/core/memory-sync/queue.js +170 -0
  177. package/dist/core/metrics/extract.js +113 -0
  178. package/dist/core/modes/roo-modes.js +68 -0
  179. package/dist/core/notes/notes-paths.js +113 -0
  180. package/dist/core/notes/notes-recorder.js +140 -0
  181. package/dist/core/notes/notes-writer.js +53 -0
  182. package/dist/core/notes/renderers.js +0 -0
  183. package/dist/core/notes/slug.js +105 -0
  184. package/dist/core/onboarding/ensure-initialized.js +133 -0
  185. package/dist/core/onboarding/marker.js +111 -0
  186. package/dist/core/onboarding/telemetry-state.js +108 -0
  187. package/dist/core/output-style/presets.js +176 -0
  188. package/dist/core/output-style/state.js +185 -0
  189. package/dist/core/path-security.js +287 -5
  190. package/dist/core/permission.js +82 -22
  191. package/dist/core/permissions/auto-classifier.js +124 -0
  192. package/dist/core/permissions/bash-parser.js +371 -0
  193. package/dist/core/permissions/circuit-breaker.js +83 -0
  194. package/dist/core/permissions/constrained-edit.js +91 -0
  195. package/dist/core/permissions/gate.js +278 -0
  196. package/dist/core/permissions/index.js +20 -0
  197. package/dist/core/permissions/mode.js +174 -0
  198. package/dist/core/permissions/network-egress.js +137 -0
  199. package/dist/core/permissions/state.js +241 -0
  200. package/dist/core/permissions/tool-class.js +107 -0
  201. package/dist/core/plan-mode/ui-state.js +51 -0
  202. package/dist/core/plans/plan-artifact.js +721 -0
  203. package/dist/core/policy-limits/etag-store.js +122 -0
  204. package/dist/core/prd-check/parser.js +215 -0
  205. package/dist/core/prd-check/reporter.js +127 -0
  206. package/dist/core/prd-check/session-review.js +557 -0
  207. package/dist/core/prd-check/verifiers.js +223 -0
  208. package/dist/core/prompt-cache/client-cache.js +99 -0
  209. package/dist/core/prompts/assembly.js +29 -0
  210. package/dist/core/prompts/registry.js +364 -0
  211. package/dist/core/pugi-gitignore.js +52 -0
  212. package/dist/core/pugi-md/cc-compat-rules.js +735 -0
  213. package/dist/core/pugi-md/context-injector.js +76 -0
  214. package/dist/core/pugi-md/walk-up.js +207 -0
  215. package/dist/core/python/uv-installer.js +270 -0
  216. package/dist/core/python/uv-resolver.js +83 -0
  217. package/dist/core/rate-limit/narrator.js +146 -0
  218. package/dist/core/recipes/cli-types.js +20 -0
  219. package/dist/core/recipes/loader.js +103 -0
  220. package/dist/core/recipes/runner.js +345 -0
  221. package/dist/core/recipes/schema.js +587 -0
  222. package/dist/core/release-notes/parser.js +241 -0
  223. package/dist/core/release-notes/state.js +116 -0
  224. package/dist/core/repl/ask.js +37 -37
  225. package/dist/core/repl/cancellation.js +26 -26
  226. package/dist/core/repl/cap-warning.js +4 -4
  227. package/dist/core/repl/clipboard-read.js +11 -11
  228. package/dist/core/repl/dispatch-fsm.js +12 -12
  229. package/dist/core/repl/engine-bridge.js +303 -0
  230. package/dist/core/repl/history-search.js +15 -15
  231. package/dist/core/repl/history.js +28 -18
  232. package/dist/core/repl/kill-ring.js +5 -5
  233. package/dist/core/repl/model-pricing.js +135 -0
  234. package/dist/core/repl/privacy-banner.js +22 -22
  235. package/dist/core/repl/session.js +2714 -228
  236. package/dist/core/repl/slash-commands.js +572 -40
  237. package/dist/core/repl/store/index.js +1 -1
  238. package/dist/core/repl/store/jsonl-log.js +22 -22
  239. package/dist/core/repl/store/lockfile.js +10 -10
  240. package/dist/core/repl/store/session-store.js +136 -107
  241. package/dist/core/repl/store/types.js +15 -15
  242. package/dist/core/repl/store/uuid-v7.js +12 -12
  243. package/dist/core/repl/tool-route.js +382 -0
  244. package/dist/core/repl/workspace-context.js +43 -21
  245. package/dist/core/repo-map/build.js +125 -0
  246. package/dist/core/repo-map/cache.js +185 -0
  247. package/dist/core/repo-map/extractor.js +254 -0
  248. package/dist/core/repo-map/formatter.js +145 -0
  249. package/dist/core/repo-map/page-rank.js +105 -0
  250. package/dist/core/repo-map/scanner.js +211 -0
  251. package/dist/core/retro/git-collector.js +251 -0
  252. package/dist/core/retro/health-card.js +25 -0
  253. package/dist/core/retro/metrics.js +342 -0
  254. package/dist/core/retro/narrative.js +249 -0
  255. package/dist/core/retro/plane-collector.js +274 -0
  256. package/dist/core/retro/pr-issue-link.js +65 -0
  257. package/dist/core/retro/types.js +16 -0
  258. package/dist/core/retry-budget/budget.js +284 -0
  259. package/dist/core/retry-budget/index.js +5 -0
  260. package/dist/core/retry-budget/retry-cap.js +74 -0
  261. package/dist/core/routing/lead-worker.js +43 -0
  262. package/dist/core/routing/pre-flight-estimator.js +108 -0
  263. package/dist/core/runs/run-tree.js +103 -0
  264. package/dist/core/sandboxing/adapter.js +29 -0
  265. package/dist/core/sandboxing/index.js +49 -0
  266. package/dist/core/sandboxing/none.js +19 -0
  267. package/dist/core/sandboxing/seatbelt.js +183 -0
  268. package/dist/core/security/injection-scanner.js +367 -0
  269. package/dist/core/security/output-filter.js +418 -0
  270. package/dist/core/session/env-file.js +105 -0
  271. package/dist/core/session/section-budgets.js +140 -0
  272. package/dist/core/session.js +119 -0
  273. package/dist/core/settings.js +378 -5
  274. package/dist/core/share/formatter.js +271 -0
  275. package/dist/core/share/redactor.js +221 -0
  276. package/dist/core/share/uploader.js +267 -0
  277. package/dist/core/skills/defaults.js +457 -0
  278. package/dist/core/skills/loader.js +22 -22
  279. package/dist/core/skills/sources.js +27 -27
  280. package/dist/core/smoke/headless-driver.js +174 -0
  281. package/dist/core/smoke/orchestrator.js +194 -0
  282. package/dist/core/smoke/runner.js +238 -0
  283. package/dist/core/smoke/scenario-parser.js +316 -0
  284. package/dist/core/statusline.js +99 -0
  285. package/dist/core/subagents/dispatcher-real.js +600 -0
  286. package/dist/core/subagents/dispatcher.js +146 -52
  287. package/dist/core/subagents/index.js +19 -6
  288. package/dist/core/subagents/isolation-matrix.js +213 -0
  289. package/dist/core/subagents/spawn.js +19 -4
  290. package/dist/core/telemetry/emitter.js +229 -0
  291. package/dist/core/telemetry/queue.js +251 -0
  292. package/dist/core/theme/context.js +91 -0
  293. package/dist/core/theme/presets.js +228 -0
  294. package/dist/core/theme/state.js +181 -0
  295. package/dist/core/todos/invariant.js +10 -0
  296. package/dist/core/todos/state.js +177 -0
  297. package/dist/core/tool-schema/compressor.js +89 -0
  298. package/dist/core/transport/version-interceptor.js +166 -0
  299. package/dist/core/trust.js +2 -2
  300. package/dist/core/tui/thinking-block.js +64 -0
  301. package/dist/core/vim/keymap.js +288 -0
  302. package/dist/core/vim/state.js +92 -0
  303. package/dist/core/watch-markers/marker-watcher.js +133 -0
  304. package/dist/core/worktree/include-parser.js +249 -0
  305. package/dist/core/worktree-manager/cleanup.js +123 -0
  306. package/dist/core/worktree-manager/manager.js +303 -0
  307. package/dist/index.js +36 -0
  308. package/dist/runtime/bootstrap.js +190 -0
  309. package/dist/runtime/cli.js +4536 -477
  310. package/dist/runtime/commands/agents.js +31 -31
  311. package/dist/runtime/commands/budget.js +5 -5
  312. package/dist/runtime/commands/cancel.js +231 -0
  313. package/dist/runtime/commands/chain.js +489 -0
  314. package/dist/runtime/commands/codegraph-status.js +227 -0
  315. package/dist/runtime/commands/compact.js +297 -0
  316. package/dist/runtime/commands/config.js +74 -40
  317. package/dist/runtime/commands/cost.js +199 -0
  318. package/dist/runtime/commands/delegate.js +312 -0
  319. package/dist/runtime/commands/dispatch.js +126 -0
  320. package/dist/runtime/commands/doctor.js +579 -0
  321. package/dist/runtime/commands/feedback.js +184 -0
  322. package/dist/runtime/commands/hooks.js +187 -0
  323. package/dist/runtime/commands/index-cmd.js +353 -0
  324. package/dist/runtime/commands/init.js +254 -0
  325. package/dist/runtime/commands/lsp.js +368 -0
  326. package/dist/runtime/commands/mcp.js +935 -0
  327. package/dist/runtime/commands/memory.js +582 -0
  328. package/dist/runtime/commands/model.js +237 -0
  329. package/dist/runtime/commands/onboarding.js +275 -0
  330. package/dist/runtime/commands/patch.js +128 -0
  331. package/dist/runtime/commands/permissions.js +112 -0
  332. package/dist/runtime/commands/plan.js +143 -0
  333. package/dist/runtime/commands/prd-check.js +285 -0
  334. package/dist/runtime/commands/privacy.js +17 -17
  335. package/dist/runtime/commands/recipe.js +325 -0
  336. package/dist/runtime/commands/redo-blob-store.js +92 -0
  337. package/dist/runtime/commands/redo.js +361 -0
  338. package/dist/runtime/commands/release-notes.js +229 -0
  339. package/dist/runtime/commands/repo-map.js +95 -0
  340. package/dist/runtime/commands/report.js +299 -0
  341. package/dist/runtime/commands/resume.js +118 -0
  342. package/dist/runtime/commands/review-consensus.js +68 -53
  343. package/dist/runtime/commands/rewind.js +333 -0
  344. package/dist/runtime/commands/roster.js +117 -0
  345. package/dist/runtime/commands/servers.js +236 -0
  346. package/dist/runtime/commands/sessions.js +163 -0
  347. package/dist/runtime/commands/share.js +316 -0
  348. package/dist/runtime/commands/skills.js +31 -31
  349. package/dist/runtime/commands/status.js +186 -0
  350. package/dist/runtime/commands/stickers.js +82 -0
  351. package/dist/runtime/commands/style.js +194 -0
  352. package/dist/runtime/commands/theme.js +196 -0
  353. package/dist/runtime/commands/undo.js +54 -22
  354. package/dist/runtime/commands/update.js +289 -0
  355. package/dist/runtime/commands/vim.js +140 -0
  356. package/dist/runtime/commands/worktree.js +177 -0
  357. package/dist/runtime/commands/worktrees.js +155 -0
  358. package/dist/runtime/deprecation-warning.js +69 -0
  359. package/dist/runtime/engine-exit-code.js +50 -0
  360. package/dist/runtime/headless-repl.js +195 -0
  361. package/dist/runtime/headless.js +548 -0
  362. package/dist/runtime/load-hooks-or-exit.js +71 -0
  363. package/dist/runtime/plan-decompose.js +531 -0
  364. package/dist/runtime/sigint-guard.js +272 -0
  365. package/dist/runtime/stream-renderer.js +195 -0
  366. package/dist/runtime/update-check.js +28 -28
  367. package/dist/runtime/version.js +65 -0
  368. package/dist/runtime/worktree-bootstrap.js +579 -0
  369. package/dist/skills/bundled/batch.js +617 -0
  370. package/dist/skills/bundled/index.js +45 -0
  371. package/dist/skills/bundled/loop.js +358 -0
  372. package/dist/skills/bundled/remember.js +383 -0
  373. package/dist/skills/bundled/simplify.js +289 -0
  374. package/dist/skills/bundled/skillify.js +373 -0
  375. package/dist/skills/bundled/stuck.js +558 -0
  376. package/dist/skills/bundled/verify.js +439 -0
  377. package/dist/testing/vcr.js +486 -0
  378. package/dist/tools/agent-tool.js +229 -0
  379. package/dist/tools/apply-patch.js +556 -0
  380. package/dist/tools/ask-user-question.js +337 -0
  381. package/dist/tools/ask-user.js +115 -0
  382. package/dist/tools/bash.js +624 -46
  383. package/dist/tools/brief.js +224 -0
  384. package/dist/tools/cron.js +433 -0
  385. package/dist/tools/enter-worktree.js +250 -0
  386. package/dist/tools/exit-worktree.js +147 -0
  387. package/dist/tools/file-tools.js +161 -44
  388. package/dist/tools/http-request.js +336 -0
  389. package/dist/tools/lsp-tools.js +565 -0
  390. package/dist/tools/mcp-tool.js +260 -0
  391. package/dist/tools/multi-edit.js +361 -0
  392. package/dist/tools/powershell.js +268 -0
  393. package/dist/tools/registry.js +142 -1
  394. package/dist/tools/server-tools.js +892 -0
  395. package/dist/tools/skill-tool.js +96 -0
  396. package/dist/tools/sleep.js +99 -0
  397. package/dist/tools/synthetic-output.js +133 -0
  398. package/dist/tools/tasks.js +208 -0
  399. package/dist/tools/todo-write.js +184 -0
  400. package/dist/tools/verify-plan-execution.js +295 -0
  401. package/dist/tools/web-fetch-injection-scanner.js +207 -0
  402. package/dist/tools/web-fetch.js +195 -10
  403. package/dist/tools/web-search.js +458 -0
  404. package/dist/tui/agent-progress-card.js +111 -0
  405. package/dist/tui/agent-tree.js +22 -1
  406. package/dist/tui/ask-modal.js +14 -14
  407. package/dist/tui/ask-user-question-chips.js +315 -0
  408. package/dist/tui/ask-user-question-prompt.js +203 -0
  409. package/dist/tui/compact-banner.js +81 -0
  410. package/dist/tui/conversation-pane.js +85 -11
  411. package/dist/tui/cost-table.js +111 -0
  412. package/dist/tui/device-flow.js +2 -2
  413. package/dist/tui/doctor-table.js +46 -0
  414. package/dist/tui/feedback-prompt.js +156 -0
  415. package/dist/tui/input-box.js +247 -32
  416. package/dist/tui/login-picker.js +3 -3
  417. package/dist/tui/markdown-render.js +6 -6
  418. package/dist/tui/multi-file-diff-approval.js +375 -0
  419. package/dist/tui/onboarding-wizard.js +240 -0
  420. package/dist/tui/permissions-picker.js +86 -0
  421. package/dist/tui/render.js +36 -1
  422. package/dist/tui/repl-render.js +405 -32
  423. package/dist/tui/repl-splash-art.js +16 -16
  424. package/dist/tui/repl-splash-mascot.js +48 -24
  425. package/dist/tui/repl-splash.js +22 -22
  426. package/dist/tui/repl.js +136 -43
  427. package/dist/tui/slash-palette.js +6 -6
  428. package/dist/tui/splash.js +2 -2
  429. package/dist/tui/status-bar.js +109 -31
  430. package/dist/tui/status-table.js +7 -0
  431. package/dist/tui/stickers-art.js +136 -0
  432. package/dist/tui/style-table.js +28 -0
  433. package/dist/tui/theme-table.js +29 -0
  434. package/dist/tui/thinking-spinner.js +123 -0
  435. package/dist/tui/tool-stream-pane.js +53 -4
  436. package/dist/tui/update-banner.js +27 -2
  437. package/dist/tui/vim-input.js +267 -0
  438. package/dist/tui/welcome-banner.js +107 -0
  439. package/dist/tui/welcome-data.js +293 -0
  440. package/dist/tui/workspace-context.js +2 -2
  441. package/docs/examples/codegraph.mcp.json +10 -0
  442. package/package.json +25 -7
  443. package/test/scenarios/codegen-create-file.scenario.txt +13 -0
  444. package/test/scenarios/compact-force.scenario.txt +12 -0
  445. package/test/scenarios/identity.scenario.txt +11 -0
  446. package/test/scenarios/persona-handoff.scenario.txt +12 -0
  447. package/test/scenarios/walkback.scenario.txt +12 -0
  448. package/dist/core/engine/compaction-hook.js +0 -154
@@ -0,0 +1,163 @@
1
+ /**
2
+ * `pugi sessions` extensions — .
3
+ *
4
+ * The legacy `pugi sessions` handler lives inline in `runtime/cli.ts`
5
+ * (it predates the per-command runner pattern). This module exposes the
6
+ * new sub-commands the L9 sprint adds:
7
+ *
8
+ * - `pugi sessions undo-rewind [<session-id>]`
9
+ * Append an inverse marker that nullifies the latest 'rewind'
10
+ * marker on the target session. Operator escape hatch: nothing
11
+ * is destroyed, the masked range simply becomes visible again.
12
+ *
13
+ * Wire pattern matches `runCompactCommand` / `runRewindCommand`: one
14
+ * structured payload + one human line per invocation, returned to the
15
+ * caller for the JSON path.
16
+ */
17
+ import { homedir } from 'node:os';
18
+ import { slugForCwd } from '../../core/repl/history.js';
19
+ import { appendRewindMarker, findLatestActiveRewind, } from '../../core/checkpoint/rewinder.js';
20
+ import { loadFromStore } from '../../core/checkpoint/resumer.js';
21
+ import { SqliteSessionStore, resolveProjectStoreDir, } from '../../core/repl/store/session-store.js';
22
+ /**
23
+ * Sub-command router. The caller passes the full positional args; we
24
+ * peel `args[0]` as the sub-command name and forward the tail. Unknown
25
+ * sub-commands surface a usage hint at exit code 2.
26
+ */
27
+ export async function runSessionsCommand(args, ctx) {
28
+ const sub = args[0];
29
+ if (sub === 'undo-rewind') {
30
+ return runUndoRewind(args.slice(1), ctx);
31
+ }
32
+ // Other sub-commands (the legacy `pugi sessions` list path) are
33
+ // owned by runtime/cli.ts — return null so the caller knows to fall
34
+ // through to that handler.
35
+ return null;
36
+ }
37
+ async function runUndoRewind(args, ctx) {
38
+ const explicitId = args[0] && !args[0].startsWith('--') ? args[0] : undefined;
39
+ const slug = slugForCwd(ctx.workspaceRoot);
40
+ let store = ctx.store ?? null;
41
+ let sessionId = ctx.sessionId ?? explicitId ?? null;
42
+ let storeOpenedHere = false;
43
+ if (store === null) {
44
+ sessionId = sessionId ?? (await pickMostRecentSessionIdReadOnly(slug));
45
+ if (!sessionId) {
46
+ return emit(ctx, {
47
+ command: 'sessions',
48
+ sub: 'undo-rewind',
49
+ status: 'failed_no_session',
50
+ reason: 'No session to undo-rewind. Start a REPL with `pugi`.',
51
+ });
52
+ }
53
+ const opened = await openLiveStore(slug, sessionId);
54
+ if (!opened) {
55
+ return emit(ctx, {
56
+ command: 'sessions',
57
+ sub: 'undo-rewind',
58
+ status: 'failed_store',
59
+ sessionId,
60
+ reason: 'Could not open local session store (lock held by another REPL?).',
61
+ });
62
+ }
63
+ store = opened;
64
+ storeOpenedHere = true;
65
+ }
66
+ else if (sessionId === null) {
67
+ const rows = await store.listSessions({ project: slug, limit: 1, status: 'active' });
68
+ if (rows.length === 0) {
69
+ return emit(ctx, {
70
+ command: 'sessions',
71
+ sub: 'undo-rewind',
72
+ status: 'failed_no_session',
73
+ reason: 'No active session to undo-rewind.',
74
+ });
75
+ }
76
+ sessionId = rows[0].id;
77
+ }
78
+ try {
79
+ const loaded = await loadFromStore(store, sessionId);
80
+ if (!loaded) {
81
+ return emit(ctx, {
82
+ command: 'sessions',
83
+ sub: 'undo-rewind',
84
+ status: 'failed_no_session',
85
+ sessionId,
86
+ reason: `Session '${sessionId}' not found.`,
87
+ });
88
+ }
89
+ const latest = findLatestActiveRewind(loaded.rawEvents);
90
+ if (latest === null) {
91
+ return emit(ctx, {
92
+ command: 'sessions',
93
+ sub: 'undo-rewind',
94
+ status: 'noop_no_rewind',
95
+ sessionId,
96
+ reason: 'No active rewind to undo on this session.',
97
+ }, 'No active rewind to undo.');
98
+ }
99
+ const fromEventIndex = loaded.rawEvents.length;
100
+ await appendRewindMarker({
101
+ store,
102
+ mode: 'undo-rewind',
103
+ toEventIndex: latest.payload.toEventIndex,
104
+ fromEventIndex,
105
+ turnsRewound: latest.payload.turnsRewound,
106
+ reason: 'undo',
107
+ ...(ctx.now !== undefined ? { now: ctx.now } : {}),
108
+ });
109
+ return emit(ctx, {
110
+ command: 'sessions',
111
+ sub: 'undo-rewind',
112
+ status: 'undone',
113
+ sessionId,
114
+ undoneTurns: latest.payload.turnsRewound,
115
+ }, `Undid the latest rewind (${latest.payload.turnsRewound} turn${latest.payload.turnsRewound === 1 ? '' : 's'} restored).`);
116
+ }
117
+ finally {
118
+ if (storeOpenedHere && store) {
119
+ try {
120
+ await store.close();
121
+ }
122
+ catch {
123
+ /* idempotent */
124
+ }
125
+ }
126
+ }
127
+ }
128
+ function emit(ctx, payload, text) {
129
+ const human = text ?? payload.reason ?? `sessions ${payload.sub}: ${payload.status}`;
130
+ ctx.writeOutput(payload, human);
131
+ return payload;
132
+ }
133
+ async function openLiveStore(projectSlug, sessionId) {
134
+ try {
135
+ const store = new SqliteSessionStore({ projectSlug, home: homedir() });
136
+ await store.open({
137
+ id: sessionId,
138
+ workspaceRoot: process.cwd(),
139
+ projectSlug,
140
+ });
141
+ return store;
142
+ }
143
+ catch {
144
+ return null;
145
+ }
146
+ }
147
+ async function pickMostRecentSessionIdReadOnly(projectSlug) {
148
+ try {
149
+ const dir = resolveProjectStoreDir(projectSlug, homedir());
150
+ const view = await SqliteSessionStore.openReadOnly(dir);
151
+ try {
152
+ const rows = await view.list({ project: projectSlug, limit: 1, status: 'active' });
153
+ return rows.length > 0 ? rows[0].id : null;
154
+ }
155
+ finally {
156
+ await view.close();
157
+ }
158
+ }
159
+ catch {
160
+ return null;
161
+ }
162
+ }
163
+ //# sourceMappingURL=sessions.js.map
@@ -0,0 +1,316 @@
1
+ /**
2
+ * `pugi share` / `/share` command handler — .
3
+ *
4
+ * Exports the current session transcript as Markdown to either a GitHub
5
+ * Gist (default when `gh` is available + auth'd) or a pugi.io public URL
6
+ * (`--pugi`). Mirrors the standard tool's `/share` ergonomics — operator can
7
+ * pin a session for portfolio / debugging / team sharing without copy-
8
+ * pasting the REPL pane by hand.
9
+ *
10
+ * Subcommands / flags (see L20 spec):
11
+ *
12
+ * pugi share Default upload — picks gist when available,
13
+ * falls back to pugi.io.
14
+ * pugi share --gist Force gist target; refuses if `gh` is not
15
+ * installed / authenticated.
16
+ * pugi share --pugi Force pugi.io target.
17
+ * pugi share --redact Run PII scrubber first; shows finding
18
+ * counts in the privacy gate banner.
19
+ * pugi share --preview Print transcript to stdout WITHOUT
20
+ * upload. Always implies a redact step IF
21
+ * `--redact` is also set so the operator
22
+ * inspects the scrubbed shape, not the raw.
23
+ * pugi share --yes Skip the y/n confirmation prompt
24
+ * (CI / scripted callers). Default is
25
+ * ALWAYS to ask before uploading. Refuses
26
+ * if the heuristic detects an active
27
+ * `Bearer ` credential regardless of `--yes`.
28
+ * pugi share --json Emit the result envelope as JSON.
29
+ *
30
+ * Privacy gates (mandatory):
31
+ *
32
+ * 1. Active credential heuristic — refuses upload entirely when the
33
+ * transcript contains a live `Bearer <token>` span. Operators who
34
+ * want to share a debug session that captured an auth header MUST
35
+ * run `--redact` first; the redactor masks the credential before
36
+ * the upload path sees it.
37
+ * 2. Confirmation prompt — y/n question shown to the operator before
38
+ * every upload. Bypassed with `--yes`. Refuses upload on `n` /
39
+ * empty / Ctrl-C.
40
+ * 3. Redact preview — when `--redact` is set, the gate banner shows
41
+ * the per-category finding counts BEFORE the upload prompt so the
42
+ * operator sees what would leave the machine.
43
+ *
44
+ * Same handler powers both `pugi share` (top-level) and `/share`
45
+ * (in-REPL slash). The slash side wires `writeOutput` to the REPL's
46
+ * `appendSystemLine` and never hits stdout directly.
47
+ */
48
+ import { existsSync, readFileSync } from 'node:fs';
49
+ import { resolve } from 'node:path';
50
+ import { createInterface } from 'node:readline/promises';
51
+ import { formatTranscript } from '../../core/share/formatter.js';
52
+ import { containsActiveCredential, redactPii, summariseFindings, } from '../../core/share/redactor.js';
53
+ import { uploadShare, } from '../../core/share/uploader.js';
54
+ export function parseShareFlags(args) {
55
+ const flags = {
56
+ target: 'auto',
57
+ redact: false,
58
+ preview: false,
59
+ yes: false,
60
+ json: false,
61
+ };
62
+ for (const arg of args) {
63
+ if (arg === '--gist')
64
+ flags.target = 'gist';
65
+ else if (arg === '--pugi')
66
+ flags.target = 'pugi';
67
+ else if (arg === '--redact')
68
+ flags.redact = true;
69
+ else if (arg === '--preview')
70
+ flags.preview = true;
71
+ else if (arg === '--yes' || arg === '-y')
72
+ flags.yes = true;
73
+ else if (arg === '--json')
74
+ flags.json = true;
75
+ }
76
+ return flags;
77
+ }
78
+ export async function runShareCommand(args, ctx) {
79
+ const flags = parseShareFlags(args);
80
+ const eventsPath = resolve(ctx.workspaceRoot, '.pugi/events.jsonl');
81
+ if (!existsSync(eventsPath)) {
82
+ ctx.writeOutput({
83
+ command: 'share',
84
+ status: 'no_session',
85
+ message: '.pugi/events.jsonl not found',
86
+ }, 'pugi share: no session log found. Run any pugi command first to create .pugi/events.jsonl.');
87
+ process.exitCode = 2;
88
+ return;
89
+ }
90
+ // Read + format. The formatter walks the events stream once; size cap
91
+ // is implicit (we do not chunk multi-GB files because session logs are
92
+ // capped at a few MB by the cost-tracker / compaction subsystems).
93
+ const eventsJsonl = readFileSync(eventsPath, 'utf8');
94
+ const sessionId = ctx.sessionId ?? deriveSessionIdFromEvents(eventsJsonl) ?? 'no-session';
95
+ const formatted = formatTranscript({
96
+ sessionId,
97
+ workspaceRoot: ctx.workspaceRoot,
98
+ cliVersion: ctx.cliVersion,
99
+ eventsJsonl,
100
+ now: ctx.now,
101
+ });
102
+ // Active-credential gate. Refuses even with `--yes`; redact-first IS
103
+ // the only path to share a transcript with a Bearer token. We check
104
+ // BEFORE redact so the operator's intent is clear in the gate banner.
105
+ const hasLiveCredential = containsActiveCredential(formatted.markdown);
106
+ if (hasLiveCredential && !flags.redact) {
107
+ ctx.writeOutput({
108
+ command: 'share',
109
+ status: 'refused_active_credential',
110
+ message: 'Transcript contains an active Bearer credential. Re-run with --redact to scrub it before sharing.',
111
+ }, 'pugi share: refused — transcript contains an active `Bearer ` credential. ' +
112
+ 'Re-run with --redact to scrub it before sharing, or open .pugi/events.jsonl to inspect manually.');
113
+ process.exitCode = 4;
114
+ return;
115
+ }
116
+ // Optional redact pass. We run BEFORE the preview/upload decisions so
117
+ // the operator sees what would actually leave their machine.
118
+ let body = formatted.markdown;
119
+ let redactionSummary = null;
120
+ let redactionFindings = [];
121
+ if (flags.redact) {
122
+ const result = redactPii(body);
123
+ body = result.output;
124
+ redactionSummary = summariseFindings(result);
125
+ redactionFindings = result.findings;
126
+ }
127
+ // Preview path. Always non-destructive: prints the (possibly redacted)
128
+ // transcript + the redact summary, no upload, no prompt. Operators
129
+ // chain `--preview --redact` to see what would be shared before they
130
+ // commit, which is the L20 spec's "inspect first" affordance.
131
+ if (flags.preview) {
132
+ const payload = {
133
+ command: 'share',
134
+ status: 'preview',
135
+ sessionId,
136
+ turnCount: formatted.turnCount,
137
+ eventCount: formatted.eventCount,
138
+ redact: flags.redact,
139
+ redactionSummary,
140
+ redactionFindings,
141
+ markdown: body,
142
+ };
143
+ const text = [
144
+ redactionSummary ? `${redactionSummary}` : null,
145
+ '--- transcript preview (not uploaded) ---',
146
+ body,
147
+ ]
148
+ .filter((line) => line !== null)
149
+ .join('\n');
150
+ ctx.writeOutput(payload, text);
151
+ return;
152
+ }
153
+ // Resolve the target. `auto` picks gist if `gh` is available, else
154
+ // falls back to pugi.io. The probe is best-effort — a missing `gh`
155
+ // surfaces as `ghAvailable -> false` and we route to pugi without an
156
+ // error.
157
+ const resolvedTarget = await pickTarget(flags.target, ctx);
158
+ // Confirmation gate. Refused by default unless `--yes`.
159
+ if (!flags.yes) {
160
+ const promptText = redactionSummary
161
+ ? `${redactionSummary} Share session transcript to ${resolvedTarget}? [y/N] `
162
+ : `Share session transcript to ${resolvedTarget}? [y/N] `;
163
+ const answer = (await ((ctx.promptYesNo ?? defaultPromptYesNo)(promptText))).trim().toLowerCase();
164
+ if (answer !== 'y' && answer !== 'yes') {
165
+ ctx.writeOutput({
166
+ command: 'share',
167
+ status: 'cancelled',
168
+ target: resolvedTarget,
169
+ message: 'Operator declined the upload.',
170
+ }, 'pugi share: cancelled.');
171
+ return;
172
+ }
173
+ }
174
+ // Resolve pugi.io credentials lazily — gist target does not need them.
175
+ let credential = null;
176
+ if (resolvedTarget === 'pugi') {
177
+ credential = ctx.resolveCredential ? await safeResolveCredential(ctx.resolveCredential) : null;
178
+ }
179
+ const uploadReq = {
180
+ target: resolvedTarget,
181
+ sessionId,
182
+ markdown: body,
183
+ description: `Pugi session ${sessionId}`,
184
+ ...(credential?.apiUrl !== undefined ? { apiUrl: credential.apiUrl } : {}),
185
+ ...(credential?.apiToken !== undefined ? { apiToken: credential.apiToken } : {}),
186
+ ...(ctx.execaLike !== undefined ? { execaLike: ctx.execaLike } : {}),
187
+ ...(ctx.fetchLike !== undefined ? { fetchLike: ctx.fetchLike } : {}),
188
+ };
189
+ const result = await uploadShare(uploadReq);
190
+ emitUploadResult(ctx, sessionId, resolvedTarget, redactionSummary, redactionFindings, result);
191
+ }
192
+ /**
193
+ * Default-target selection. `--gist` / `--pugi` are honoured verbatim;
194
+ * `auto` consults the `gh` probe and picks gist when available. We
195
+ * deliberately do not cache the probe — it costs one syscall and the
196
+ * operator might `gh auth login` between two `pugi share` runs.
197
+ */
198
+ async function pickTarget(requested, ctx) {
199
+ if (requested === 'gist')
200
+ return 'gist';
201
+ if (requested === 'pugi')
202
+ return 'pugi';
203
+ // auto
204
+ const probe = ctx.ghAvailable ?? defaultGhAvailable(ctx.execaLike);
205
+ return (await probe()) ? 'gist' : 'pugi';
206
+ }
207
+ function defaultGhAvailable(execaLike) {
208
+ return async () => {
209
+ if (!execaLike) {
210
+ // Production: try to spawn `gh --version`. The default execa shim
211
+ // in uploader.ts is the right one but importing it here would
212
+ // create a small cycle; instead we replicate the minimal probe.
213
+ try {
214
+ const { defaultExecaLike } = await import('../../core/share/uploader.js');
215
+ const result = await defaultExecaLike('gh', ['--version']);
216
+ return result.exitCode === 0;
217
+ }
218
+ catch {
219
+ return false;
220
+ }
221
+ }
222
+ try {
223
+ const result = await execaLike('gh', ['--version']);
224
+ return result.exitCode === 0;
225
+ }
226
+ catch {
227
+ return false;
228
+ }
229
+ };
230
+ }
231
+ async function defaultPromptYesNo(question) {
232
+ if (!process.stdin.isTTY) {
233
+ // Non-interactive caller without --yes: refuse rather than block on
234
+ // an empty stdin. Mirrors the install-trust pattern in skills.ts.
235
+ process.stdout.write(`${question}\n(non-interactive stdin; declining)\n`);
236
+ return 'n';
237
+ }
238
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
239
+ try {
240
+ return await rl.question(question);
241
+ }
242
+ finally {
243
+ rl.close();
244
+ }
245
+ }
246
+ async function safeResolveCredential(resolver) {
247
+ try {
248
+ return await resolver();
249
+ }
250
+ catch {
251
+ return null;
252
+ }
253
+ }
254
+ /**
255
+ * Walk the JSONL log from the tail and pick the newest `session.created`
256
+ * id. Mirrors the helper in cost.ts so the two surfaces agree on what
257
+ * "current session" means.
258
+ */
259
+ function deriveSessionIdFromEvents(raw) {
260
+ const lines = raw.split('\n').filter((line) => line.trim().length > 0);
261
+ for (let i = lines.length - 1; i >= 0; i -= 1) {
262
+ try {
263
+ const parsed = JSON.parse(lines[i]);
264
+ if (parsed.type === 'session' && parsed.name === 'created' && typeof parsed.sessionId === 'string') {
265
+ return parsed.sessionId;
266
+ }
267
+ }
268
+ catch {
269
+ // skip
270
+ }
271
+ }
272
+ return null;
273
+ }
274
+ function emitUploadResult(ctx, sessionId, target, redactionSummary, redactionFindings, result) {
275
+ if (result.ok) {
276
+ const payload = {
277
+ command: 'share',
278
+ status: 'ok',
279
+ sessionId,
280
+ target,
281
+ url: result.url,
282
+ remoteId: result.remoteId ?? null,
283
+ redact: redactionSummary !== null,
284
+ redactionSummary,
285
+ redactionFindings,
286
+ };
287
+ const text = [
288
+ redactionSummary,
289
+ `pugi share: uploaded to ${target}.`,
290
+ `URL: ${result.url}`,
291
+ ]
292
+ .filter((line) => line !== null)
293
+ .join('\n');
294
+ ctx.writeOutput(payload, text);
295
+ return;
296
+ }
297
+ const payload = {
298
+ command: 'share',
299
+ status: 'upload_failed',
300
+ sessionId,
301
+ target,
302
+ reason: result.reason,
303
+ message: result.message,
304
+ redact: redactionSummary !== null,
305
+ redactionSummary,
306
+ };
307
+ const text = [
308
+ redactionSummary,
309
+ `pugi share: ${result.reason} — ${result.message}`,
310
+ ]
311
+ .filter((line) => line !== null)
312
+ .join('\n');
313
+ ctx.writeOutput(payload, text);
314
+ process.exitCode = 3;
315
+ }
316
+ //# sourceMappingURL=share.js.map
@@ -7,20 +7,20 @@ import { readdirSync, readFileSync } from 'node:fs';
7
7
  import { join } from 'node:path';
8
8
  const USAGE = [
9
9
  'Usage:',
10
- ' pugi skills list [--global|--workspace] Show installed skills.',
11
- ' pugi skills install <source> [--global|--workspace] [--yes] [--as <name>]',
12
- ' Fetch + trust-prompt + activate a skill.',
13
- ' pugi skills info <name> Show metadata + body preview.',
14
- ' pugi skills remove <name> [--global|--workspace] Delete an installed skill.',
15
- ' pugi skills trust <name> [--global|--workspace] Re-trust the on-disk payload.',
10
+ ' pugi skills list [--global|--workspace] Show installed skills.',
11
+ ' pugi skills install <source> [--global|--workspace] [--yes] [--as <name>]',
12
+ ' Fetch + trust-prompt + activate a skill.',
13
+ ' pugi skills info <name> Show metadata + body preview.',
14
+ ' pugi skills remove <name> [--global|--workspace] Delete an installed skill.',
15
+ ' pugi skills trust <name> [--global|--workspace] Re-trust the on-disk payload.',
16
16
  '',
17
17
  'Source forms accepted by `install`:',
18
- ' gh:owner/repo[/subdir][@ref] GitHub tree fetch (default ref: main).',
19
- ' https://github.com/... GitHub tree/blob URL.',
20
- ' anthropic:<slug> Shortcut for gh:anthropics/skills/<slug>@main.',
21
- ' npm:<package>[@version] npm registry tarball.',
22
- ' ./path | /abs/path Local filesystem.',
23
- ' <slug> Catalog lookup (catalog.pugi.dev).',
18
+ ' gh:owner/repo[/subdir][@ref] GitHub tree fetch (default ref: main).',
19
+ ' https://github.com/... GitHub tree/blob URL.',
20
+ ' anthropic:<slug> Shortcut for gh:anthropics/skills/<slug>@main.',
21
+ ' npm:<package>[@version] npm registry tarball.',
22
+ ' ./path | /abs/path Local filesystem.',
23
+ ' <slug> Catalog lookup (catalog.pugi.dev).',
24
24
  ].join('\n');
25
25
  export async function runSkillsCommand(args, ctx) {
26
26
  const sub = args[0];
@@ -103,8 +103,8 @@ async function runSkillsList(args, ctx) {
103
103
  for (const { skill, trust } of trustStatuses) {
104
104
  const version = skill.frontmatter.metadata.version ? ` v${String(skill.frontmatter.metadata.version)}` : '';
105
105
  const trustMark = trust.status === 'trusted' ? '[trusted]' : trust.status === 'unsigned' ? '[unsigned]' : '[mismatch]';
106
- lines.push(` ${skill.name.padEnd(28)} ${skill.scope.padEnd(10)} ${trustMark.padEnd(11)}${version}`);
107
- lines.push(` ${truncate(skill.frontmatter.description, 80)}`);
106
+ lines.push(` ${skill.name.padEnd(28)} ${skill.scope.padEnd(10)} ${trustMark.padEnd(11)}${version}`);
107
+ lines.push(` ${truncate(skill.frontmatter.description, 80)}`);
108
108
  }
109
109
  ctx.writeOutput({ command: 'skills.list', skills: trustStatuses }, lines.join('\n'));
110
110
  }
@@ -206,9 +206,9 @@ async function runSkillsInstall(args, ctx) {
206
206
  source: fetched.sourceUrl,
207
207
  }, [
208
208
  `Installed skill "${skillName}" (${scope}).`,
209
- ` Path: ${installedDir}`,
210
- ` Source: ${fetched.sourceUrl}`,
211
- ` sha256: ${sha256}`,
209
+ ` Path: ${installedDir}`,
210
+ ` Source: ${fetched.sourceUrl}`,
211
+ ` sha256: ${sha256}`,
212
212
  ].join('\n'));
213
213
  }
214
214
  async function runSkillsInfo(args, ctx) {
@@ -234,13 +234,13 @@ async function runSkillsInfo(args, ctx) {
234
234
  const preview = skill.body.slice(0, 800);
235
235
  const lines = [
236
236
  `Skill: ${skill.name}`,
237
- ` Scope: ${skill.scope}`,
238
- ` Path: ${skill.dir}`,
239
- ` Description: ${skill.frontmatter.description}`,
240
- ` Version: ${String(skill.frontmatter.metadata.version ?? '(unset)')}`,
241
- ` Tools: ${(skill.frontmatter.metadata.tools ?? []).join(', ') || '(none)'}`,
242
- ` Trust: ${trust.status}`,
243
- ` sha256: ${actualSha}`,
237
+ ` Scope: ${skill.scope}`,
238
+ ` Path: ${skill.dir}`,
239
+ ` Description: ${skill.frontmatter.description}`,
240
+ ` Version: ${String(skill.frontmatter.metadata.version ?? '(unset)')}`,
241
+ ` Tools: ${(skill.frontmatter.metadata.tools ?? []).join(', ') || '(none)'}`,
242
+ ` Trust: ${trust.status}`,
243
+ ` sha256: ${actualSha}`,
244
244
  '',
245
245
  'Body preview:',
246
246
  preview,
@@ -362,13 +362,13 @@ async function promptTrust(kind, summary, body) {
362
362
  const banner = [
363
363
  '',
364
364
  `About to install ${kind} "${summary.name}"`,
365
- ` Description: ${summary.description}`,
366
- ` Version: ${summary.version ?? '(unset)'}`,
367
- ` Tools: ${summary.tools.join(', ') || '(none)'}`,
368
- ` Files: ${summary.files}`,
369
- ` Source: ${summary.source}`,
370
- ` Target: ${summary.targetDir}`,
371
- ` sha256: ${summary.sha256}`,
365
+ ` Description: ${summary.description}`,
366
+ ` Version: ${summary.version ?? '(unset)'}`,
367
+ ` Tools: ${summary.tools.join(', ') || '(none)'}`,
368
+ ` Files: ${summary.files}`,
369
+ ` Source: ${summary.source}`,
370
+ ` Target: ${summary.targetDir}`,
371
+ ` sha256: ${summary.sha256}`,
372
372
  '',
373
373
  'This payload becomes part of the system prompt and may influence agent decisions.',
374
374
  'Trust this install? [y/N/info] ',