@pugi/cli 0.1.0-beta.99 → 1.0.0-alpha.2

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/LICENSE +1 -1
  2. package/README.md +11 -191
  3. package/bin/pugi +8 -0
  4. package/package.json +15 -71
  5. package/postinstall.mjs +31 -0
  6. package/CHANGELOG.md +0 -132
  7. package/THIRD_PARTY_NOTICES.md +0 -40
  8. package/assets/pugi-mascot.ansi +0 -16
  9. package/assets/pugi-prozr2-mascot.ansi +0 -9
  10. package/bin/run.js +0 -34
  11. package/dist/commands/deploy.js +0 -439
  12. package/dist/commands/flatten.js +0 -191
  13. package/dist/commands/jobs-watch.js +0 -201
  14. package/dist/commands/jobs.js +0 -260
  15. package/dist/commands/retro.js +0 -210
  16. package/dist/commands/smoke.js +0 -133
  17. package/dist/core/agent-progress/cleanup.js +0 -134
  18. package/dist/core/agent-progress/schema.js +0 -144
  19. package/dist/core/agent-progress/writer.js +0 -101
  20. package/dist/core/agents/adaptive-router.js +0 -330
  21. package/dist/core/agents/loader.js +0 -104
  22. package/dist/core/agents/query-decomposer.js +0 -297
  23. package/dist/core/agents/registry.js +0 -69
  24. package/dist/core/approvals/shortcut-resolver.js +0 -98
  25. package/dist/core/artifact-chain/dispatcher.js +0 -148
  26. package/dist/core/artifact-chain/exporter.js +0 -164
  27. package/dist/core/artifact-chain/state.js +0 -243
  28. package/dist/core/artifact-chain/steps.js +0 -169
  29. package/dist/core/ask-user/question.js +0 -92
  30. package/dist/core/audit/audit-trail.js +0 -275
  31. package/dist/core/auth/ensure-authenticated.js +0 -129
  32. package/dist/core/auth/env-provider.js +0 -238
  33. package/dist/core/auto-open-browser.js +0 -128
  34. package/dist/core/auto-update/channels.js +0 -122
  35. package/dist/core/auto-update/checker.js +0 -241
  36. package/dist/core/auto-update/state.js +0 -235
  37. package/dist/core/bare-mode/index.js +0 -107
  38. package/dist/core/bash/redirect.js +0 -281
  39. package/dist/core/bash-classifier.js +0 -1397
  40. package/dist/core/checkpoint/resumer.js +0 -149
  41. package/dist/core/checkpoint/rewinder.js +0 -291
  42. package/dist/core/checkpoints/shadow-git.js +0 -670
  43. package/dist/core/citations/parser.js +0 -109
  44. package/dist/core/classifier/yolo-classifier.js +0 -88
  45. package/dist/core/clipboard.js +0 -70
  46. package/dist/core/codegraph/decision-store.js +0 -248
  47. package/dist/core/codegraph/detect-repo.js +0 -459
  48. package/dist/core/codegraph/install.js +0 -134
  49. package/dist/core/codegraph/offer-hook.js +0 -220
  50. package/dist/core/compact/auto-trigger.js +0 -96
  51. package/dist/core/compact/buffer-rewriter.js +0 -115
  52. package/dist/core/compact/summarizer.js +0 -208
  53. package/dist/core/compact/token-counter.js +0 -108
  54. package/dist/core/consensus/anvil-fanout.js +0 -276
  55. package/dist/core/consensus/diff-capture.js +0 -491
  56. package/dist/core/consensus/rubric.js +0 -233
  57. package/dist/core/context/builder.js +0 -114
  58. package/dist/core/context/compaction-events.js +0 -99
  59. package/dist/core/context/compaction.js +0 -602
  60. package/dist/core/context/index.js +0 -28
  61. package/dist/core/context/invariants.js +0 -250
  62. package/dist/core/context/markdown-loader.js +0 -288
  63. package/dist/core/context/markdown-traverse.js +0 -255
  64. package/dist/core/context/pugiignore.js +0 -316
  65. package/dist/core/context/repo-skeleton.js +0 -533
  66. package/dist/core/context/tool-eviction.js +0 -55
  67. package/dist/core/context/watcher.js +0 -342
  68. package/dist/core/context/working-set.js +0 -165
  69. package/dist/core/coordinator/agent-tools.js +0 -77
  70. package/dist/core/coordinator/agent-toolset.js +0 -65
  71. package/dist/core/coordinator/fsm.js +0 -73
  72. package/dist/core/coordinator/mode-fsm.js +0 -70
  73. package/dist/core/cost/rate-card.js +0 -129
  74. package/dist/core/cost/tracker.js +0 -221
  75. package/dist/core/credentials.js +0 -355
  76. package/dist/core/cron/scheduler.js +0 -138
  77. package/dist/core/denial-tracking/index.js +0 -8
  78. package/dist/core/denial-tracking/state.js +0 -264
  79. package/dist/core/diagnostics/probe-runner.js +0 -93
  80. package/dist/core/diagnostics/probes/api.js +0 -46
  81. package/dist/core/diagnostics/probes/auth.js +0 -93
  82. package/dist/core/diagnostics/probes/bare-mode.js +0 -42
  83. package/dist/core/diagnostics/probes/cli-version.js +0 -127
  84. package/dist/core/diagnostics/probes/config.js +0 -72
  85. package/dist/core/diagnostics/probes/denial-tracking.js +0 -57
  86. package/dist/core/diagnostics/probes/disk.js +0 -81
  87. package/dist/core/diagnostics/probes/engine-live.js +0 -46
  88. package/dist/core/diagnostics/probes/git.js +0 -65
  89. package/dist/core/diagnostics/probes/hooks.js +0 -118
  90. package/dist/core/diagnostics/probes/mcp.js +0 -75
  91. package/dist/core/diagnostics/probes/node.js +0 -59
  92. package/dist/core/diagnostics/probes/pnpm.js +0 -36
  93. package/dist/core/diagnostics/probes/pugi-md.js +0 -89
  94. package/dist/core/diagnostics/probes/sandbox.js +0 -72
  95. package/dist/core/diagnostics/probes/session.js +0 -74
  96. package/dist/core/diagnostics/probes/status-snapshot.js +0 -488
  97. package/dist/core/diagnostics/probes/workspace.js +0 -63
  98. package/dist/core/diagnostics/types.js +0 -70
  99. package/dist/core/dispatch/cache-cleanup.js +0 -197
  100. package/dist/core/dispatch/cache-handoff.js +0 -295
  101. package/dist/core/edits/apply-patch-layer-e.js +0 -189
  102. package/dist/core/edits/dispatch.js +0 -511
  103. package/dist/core/edits/format-detector.js +0 -260
  104. package/dist/core/edits/format-matrix.js +0 -26
  105. package/dist/core/edits/fuzzy-ladder.js +0 -650
  106. package/dist/core/edits/index.js +0 -19
  107. package/dist/core/edits/journal.js +0 -199
  108. package/dist/core/edits/layer-a-apply.js +0 -217
  109. package/dist/core/edits/layer-a-fuzzy-apply.js +0 -198
  110. package/dist/core/edits/layer-b-apply.js +0 -211
  111. package/dist/core/edits/layer-c-apply.js +0 -160
  112. package/dist/core/edits/layer-d-ast.js +0 -572
  113. package/dist/core/edits/marker-parser.js +0 -401
  114. package/dist/core/edits/security-gate.js +0 -223
  115. package/dist/core/edits/verify-hook.js +0 -273
  116. package/dist/core/edits/worktree.js +0 -322
  117. package/dist/core/engine/adapter-runner.js +0 -8
  118. package/dist/core/engine/anvil-client.js +0 -344
  119. package/dist/core/engine/auto-compact.js +0 -179
  120. package/dist/core/engine/budgets.js +0 -195
  121. package/dist/core/engine/context-prefix.js +0 -155
  122. package/dist/core/engine/index.js +0 -12
  123. package/dist/core/engine/intensity.js +0 -163
  124. package/dist/core/engine/intent.js +0 -260
  125. package/dist/core/engine/native-pugi.js +0 -1616
  126. package/dist/core/engine/noop.js +0 -27
  127. package/dist/core/engine/prompts.js +0 -236
  128. package/dist/core/engine/strip-internal-fields.js +0 -124
  129. package/dist/core/engine/tool-bridge.js +0 -2173
  130. package/dist/core/engine/verification-patterns.js +0 -195
  131. package/dist/core/evaluation/golden-dataset.js +0 -293
  132. package/dist/core/feedback/queue.js +0 -177
  133. package/dist/core/feedback/submitter.js +0 -145
  134. package/dist/core/file-cache.js +0 -141
  135. package/dist/core/flatten/flatten-repo.js +0 -439
  136. package/dist/core/format/osc8-link.js +0 -28
  137. package/dist/core/hook-chains.js +0 -392
  138. package/dist/core/hooks/citation-verify-hook.js +0 -138
  139. package/dist/core/hooks/citation-verify.js +0 -112
  140. package/dist/core/hooks/events.js +0 -46
  141. package/dist/core/hooks/index.js +0 -15
  142. package/dist/core/hooks/registry.js +0 -216
  143. package/dist/core/hooks/runner.js +0 -236
  144. package/dist/core/hooks/v2/event-emitter.js +0 -115
  145. package/dist/core/hooks/v2/executor.js +0 -282
  146. package/dist/core/hooks/v2/index.js +0 -25
  147. package/dist/core/hooks/v2/lifecycle.js +0 -104
  148. package/dist/core/hooks/v2/loader.js +0 -216
  149. package/dist/core/hooks/v2/matcher.js +0 -125
  150. package/dist/core/hooks/v2/trust.js +0 -143
  151. package/dist/core/hooks/v2/types.js +0 -86
  152. package/dist/core/hooks/worktree-events.js +0 -158
  153. package/dist/core/hooks.js +0 -415
  154. package/dist/core/image/renderer.js +0 -71
  155. package/dist/core/index-store.js +0 -260
  156. package/dist/core/init/detector.js +0 -582
  157. package/dist/core/init/template-renderer.js +0 -242
  158. package/dist/core/jobs/registry.js +0 -462
  159. package/dist/core/ledger/results-tsv.js +0 -142
  160. package/dist/core/log-discipline/stdout-redirect.js +0 -51
  161. package/dist/core/lsp/cache.js +0 -105
  162. package/dist/core/lsp/client.js +0 -1229
  163. package/dist/core/lsp/language-detect.js +0 -66
  164. package/dist/core/lsp/post-edit-diagnostics.js +0 -171
  165. package/dist/core/lsp/server-detect.js +0 -173
  166. package/dist/core/lsp/symbol-cache.js +0 -162
  167. package/dist/core/lsp/symbol-tools.js +0 -664
  168. package/dist/core/mcp/client.js +0 -385
  169. package/dist/core/mcp/http-server.js +0 -553
  170. package/dist/core/mcp/orchestrator-config.js +0 -192
  171. package/dist/core/mcp/orchestrator-tools.js +0 -806
  172. package/dist/core/mcp/permission.js +0 -190
  173. package/dist/core/mcp/registry.js +0 -193
  174. package/dist/core/mcp/server-tools.js +0 -219
  175. package/dist/core/mcp/server.js +0 -397
  176. package/dist/core/mcp/trust.js +0 -91
  177. package/dist/core/memory/dual-write.js +0 -416
  178. package/dist/core/memory/passive-extract.js +0 -130
  179. package/dist/core/memory/phase1-kinds.js +0 -20
  180. package/dist/core/memory/secret-scanner.js +0 -304
  181. package/dist/core/memory-sync/queue.js +0 -170
  182. package/dist/core/metrics/extract.js +0 -113
  183. package/dist/core/modes/roo-modes.js +0 -68
  184. package/dist/core/onboarding/ensure-initialized.js +0 -133
  185. package/dist/core/onboarding/marker.js +0 -111
  186. package/dist/core/onboarding/telemetry-state.js +0 -108
  187. package/dist/core/output-style/presets.js +0 -176
  188. package/dist/core/output-style/state.js +0 -185
  189. package/dist/core/path-security.js +0 -345
  190. package/dist/core/permission.js +0 -369
  191. package/dist/core/permissions/auto-classifier.js +0 -124
  192. package/dist/core/permissions/bash-parser.js +0 -371
  193. package/dist/core/permissions/circuit-breaker.js +0 -83
  194. package/dist/core/permissions/constrained-edit.js +0 -91
  195. package/dist/core/permissions/gate.js +0 -278
  196. package/dist/core/permissions/index.js +0 -20
  197. package/dist/core/permissions/mode.js +0 -174
  198. package/dist/core/permissions/network-egress.js +0 -137
  199. package/dist/core/permissions/state.js +0 -241
  200. package/dist/core/permissions/tool-class.js +0 -107
  201. package/dist/core/plan-mode/ui-state.js +0 -51
  202. package/dist/core/plans/plan-artifact.js +0 -721
  203. package/dist/core/policy-limits/etag-store.js +0 -122
  204. package/dist/core/prd-check/parser.js +0 -215
  205. package/dist/core/prd-check/reporter.js +0 -127
  206. package/dist/core/prd-check/session-review.js +0 -557
  207. package/dist/core/prd-check/verifiers.js +0 -223
  208. package/dist/core/prompt-cache/client-cache.js +0 -99
  209. package/dist/core/prompts/assembly.js +0 -29
  210. package/dist/core/prompts/registry.js +0 -364
  211. package/dist/core/pugi-gitignore.js +0 -52
  212. package/dist/core/pugi-md/cc-compat-rules.js +0 -735
  213. package/dist/core/pugi-md/context-injector.js +0 -76
  214. package/dist/core/pugi-md/walk-up.js +0 -207
  215. package/dist/core/python/uv-installer.js +0 -270
  216. package/dist/core/python/uv-resolver.js +0 -83
  217. package/dist/core/rate-limit/narrator.js +0 -146
  218. package/dist/core/recipes/cli-types.js +0 -20
  219. package/dist/core/recipes/loader.js +0 -103
  220. package/dist/core/recipes/runner.js +0 -345
  221. package/dist/core/recipes/schema.js +0 -587
  222. package/dist/core/release-notes/parser.js +0 -241
  223. package/dist/core/release-notes/state.js +0 -116
  224. package/dist/core/repl/ask.js +0 -512
  225. package/dist/core/repl/cancellation.js +0 -98
  226. package/dist/core/repl/cap-warning.js +0 -91
  227. package/dist/core/repl/clipboard-read.js +0 -174
  228. package/dist/core/repl/dispatch-fsm.js +0 -220
  229. package/dist/core/repl/engine-bridge.js +0 -303
  230. package/dist/core/repl/history-search.js +0 -175
  231. package/dist/core/repl/history.js +0 -182
  232. package/dist/core/repl/kill-ring.js +0 -138
  233. package/dist/core/repl/model-pricing.js +0 -135
  234. package/dist/core/repl/privacy-banner.js +0 -71
  235. package/dist/core/repl/session.js +0 -4962
  236. package/dist/core/repl/slash-commands.js +0 -747
  237. package/dist/core/repl/store/index.js +0 -12
  238. package/dist/core/repl/store/jsonl-log.js +0 -321
  239. package/dist/core/repl/store/lockfile.js +0 -155
  240. package/dist/core/repl/store/session-store.js +0 -821
  241. package/dist/core/repl/store/types.js +0 -44
  242. package/dist/core/repl/store/uuid-v7.js +0 -68
  243. package/dist/core/repl/tool-route.js +0 -382
  244. package/dist/core/repl/workspace-context.js +0 -206
  245. package/dist/core/repo-map/build.js +0 -125
  246. package/dist/core/repo-map/cache.js +0 -185
  247. package/dist/core/repo-map/extractor.js +0 -254
  248. package/dist/core/repo-map/formatter.js +0 -145
  249. package/dist/core/repo-map/page-rank.js +0 -105
  250. package/dist/core/repo-map/scanner.js +0 -211
  251. package/dist/core/retro/git-collector.js +0 -251
  252. package/dist/core/retro/health-card.js +0 -25
  253. package/dist/core/retro/metrics.js +0 -342
  254. package/dist/core/retro/narrative.js +0 -249
  255. package/dist/core/retro/plane-collector.js +0 -274
  256. package/dist/core/retro/pr-issue-link.js +0 -65
  257. package/dist/core/retro/types.js +0 -16
  258. package/dist/core/retry-budget/budget.js +0 -284
  259. package/dist/core/retry-budget/index.js +0 -5
  260. package/dist/core/retry-budget/retry-cap.js +0 -74
  261. package/dist/core/routing/lead-worker.js +0 -43
  262. package/dist/core/routing/pre-flight-estimator.js +0 -108
  263. package/dist/core/runs/run-tree.js +0 -103
  264. package/dist/core/sandboxing/adapter.js +0 -29
  265. package/dist/core/sandboxing/index.js +0 -49
  266. package/dist/core/sandboxing/none.js +0 -19
  267. package/dist/core/sandboxing/seatbelt.js +0 -183
  268. package/dist/core/security/injection-scanner.js +0 -367
  269. package/dist/core/security/output-filter.js +0 -418
  270. package/dist/core/session/env-file.js +0 -105
  271. package/dist/core/session/section-budgets.js +0 -140
  272. package/dist/core/session.js +0 -377
  273. package/dist/core/settings.js +0 -400
  274. package/dist/core/share/formatter.js +0 -271
  275. package/dist/core/share/redactor.js +0 -221
  276. package/dist/core/share/uploader.js +0 -267
  277. package/dist/core/skills/defaults.js +0 -457
  278. package/dist/core/skills/loader.js +0 -454
  279. package/dist/core/skills/sources.js +0 -480
  280. package/dist/core/skills/trust.js +0 -172
  281. package/dist/core/smoke/headless-driver.js +0 -174
  282. package/dist/core/smoke/orchestrator.js +0 -194
  283. package/dist/core/smoke/runner.js +0 -238
  284. package/dist/core/smoke/scenario-parser.js +0 -316
  285. package/dist/core/statusline.js +0 -99
  286. package/dist/core/subagents/dispatcher-real.js +0 -600
  287. package/dist/core/subagents/dispatcher.js +0 -352
  288. package/dist/core/subagents/index.js +0 -39
  289. package/dist/core/subagents/isolation-matrix.js +0 -213
  290. package/dist/core/subagents/spawn.js +0 -101
  291. package/dist/core/telemetry/emitter.js +0 -229
  292. package/dist/core/telemetry/queue.js +0 -251
  293. package/dist/core/theme/context.js +0 -91
  294. package/dist/core/theme/presets.js +0 -228
  295. package/dist/core/theme/state.js +0 -181
  296. package/dist/core/todos/invariant.js +0 -10
  297. package/dist/core/todos/state.js +0 -177
  298. package/dist/core/tool-schema/compressor.js +0 -89
  299. package/dist/core/transport/version-interceptor.js +0 -166
  300. package/dist/core/trust.js +0 -109
  301. package/dist/core/tui/thinking-block.js +0 -64
  302. package/dist/core/vim/keymap.js +0 -288
  303. package/dist/core/vim/state.js +0 -92
  304. package/dist/core/watch-markers/marker-watcher.js +0 -133
  305. package/dist/core/worktree/include-parser.js +0 -249
  306. package/dist/core/worktree-manager/cleanup.js +0 -123
  307. package/dist/core/worktree-manager/manager.js +0 -303
  308. package/dist/index.js +0 -44
  309. package/dist/runtime/bootstrap.js +0 -190
  310. package/dist/runtime/cli.js +0 -8121
  311. package/dist/runtime/commands/agents.js +0 -385
  312. package/dist/runtime/commands/budget.js +0 -192
  313. package/dist/runtime/commands/cancel.js +0 -231
  314. package/dist/runtime/commands/chain.js +0 -489
  315. package/dist/runtime/commands/codegraph-status.js +0 -227
  316. package/dist/runtime/commands/compact.js +0 -297
  317. package/dist/runtime/commands/config.js +0 -595
  318. package/dist/runtime/commands/cost.js +0 -199
  319. package/dist/runtime/commands/delegate.js +0 -312
  320. package/dist/runtime/commands/dispatch.js +0 -126
  321. package/dist/runtime/commands/doctor.js +0 -579
  322. package/dist/runtime/commands/feedback.js +0 -184
  323. package/dist/runtime/commands/hooks.js +0 -187
  324. package/dist/runtime/commands/init.js +0 -254
  325. package/dist/runtime/commands/lsp.js +0 -368
  326. package/dist/runtime/commands/mcp.js +0 -935
  327. package/dist/runtime/commands/memory.js +0 -582
  328. package/dist/runtime/commands/model.js +0 -237
  329. package/dist/runtime/commands/onboarding.js +0 -275
  330. package/dist/runtime/commands/patch.js +0 -128
  331. package/dist/runtime/commands/permissions.js +0 -112
  332. package/dist/runtime/commands/plan.js +0 -143
  333. package/dist/runtime/commands/prd-check.js +0 -285
  334. package/dist/runtime/commands/privacy.js +0 -107
  335. package/dist/runtime/commands/recipe.js +0 -325
  336. package/dist/runtime/commands/redo-blob-store.js +0 -92
  337. package/dist/runtime/commands/redo.js +0 -361
  338. package/dist/runtime/commands/release-notes.js +0 -229
  339. package/dist/runtime/commands/repo-map.js +0 -95
  340. package/dist/runtime/commands/report.js +0 -299
  341. package/dist/runtime/commands/resume.js +0 -118
  342. package/dist/runtime/commands/review-consensus.js +0 -414
  343. package/dist/runtime/commands/rewind.js +0 -333
  344. package/dist/runtime/commands/roster.js +0 -117
  345. package/dist/runtime/commands/sessions.js +0 -163
  346. package/dist/runtime/commands/share.js +0 -316
  347. package/dist/runtime/commands/skills.js +0 -401
  348. package/dist/runtime/commands/status.js +0 -186
  349. package/dist/runtime/commands/stickers.js +0 -82
  350. package/dist/runtime/commands/style.js +0 -194
  351. package/dist/runtime/commands/theme.js +0 -196
  352. package/dist/runtime/commands/undo.js +0 -361
  353. package/dist/runtime/commands/update.js +0 -289
  354. package/dist/runtime/commands/vim.js +0 -140
  355. package/dist/runtime/commands/worktree.js +0 -177
  356. package/dist/runtime/commands/worktrees.js +0 -155
  357. package/dist/runtime/deprecation-warning.js +0 -69
  358. package/dist/runtime/engine-exit-code.js +0 -50
  359. package/dist/runtime/headless-repl.js +0 -195
  360. package/dist/runtime/headless.js +0 -548
  361. package/dist/runtime/load-hooks-or-exit.js +0 -71
  362. package/dist/runtime/plan-decompose.js +0 -531
  363. package/dist/runtime/sigint-guard.js +0 -272
  364. package/dist/runtime/stream-renderer.js +0 -195
  365. package/dist/runtime/update-check.js +0 -294
  366. package/dist/runtime/version.js +0 -65
  367. package/dist/runtime/worktree-bootstrap.js +0 -579
  368. package/dist/skills/bundled/batch.js +0 -617
  369. package/dist/skills/bundled/index.js +0 -45
  370. package/dist/skills/bundled/loop.js +0 -358
  371. package/dist/skills/bundled/remember.js +0 -383
  372. package/dist/skills/bundled/simplify.js +0 -289
  373. package/dist/skills/bundled/skillify.js +0 -373
  374. package/dist/skills/bundled/stuck.js +0 -558
  375. package/dist/skills/bundled/verify.js +0 -439
  376. package/dist/testing/vcr.js +0 -486
  377. package/dist/tools/agent-tool.js +0 -229
  378. package/dist/tools/apply-patch.js +0 -556
  379. package/dist/tools/ask-user-question.js +0 -337
  380. package/dist/tools/ask-user.js +0 -115
  381. package/dist/tools/bash.js +0 -1238
  382. package/dist/tools/brief.js +0 -224
  383. package/dist/tools/cron.js +0 -433
  384. package/dist/tools/enter-worktree.js +0 -250
  385. package/dist/tools/exit-worktree.js +0 -147
  386. package/dist/tools/file-tools.js +0 -553
  387. package/dist/tools/http-request.js +0 -336
  388. package/dist/tools/lsp-tools.js +0 -565
  389. package/dist/tools/mcp-tool.js +0 -260
  390. package/dist/tools/multi-edit.js +0 -361
  391. package/dist/tools/powershell.js +0 -268
  392. package/dist/tools/registry.js +0 -166
  393. package/dist/tools/server-tools.js +0 -892
  394. package/dist/tools/skill-tool.js +0 -96
  395. package/dist/tools/sleep.js +0 -99
  396. package/dist/tools/synthetic-output.js +0 -133
  397. package/dist/tools/tasks.js +0 -208
  398. package/dist/tools/todo-write.js +0 -184
  399. package/dist/tools/verify-plan-execution.js +0 -295
  400. package/dist/tools/web-fetch-injection-scanner.js +0 -207
  401. package/dist/tools/web-fetch.js +0 -720
  402. package/dist/tools/web-search.js +0 -458
  403. package/dist/tui/agent-progress-card.js +0 -111
  404. package/dist/tui/agent-tree-pane.js +0 -9
  405. package/dist/tui/agent-tree.js +0 -87
  406. package/dist/tui/ask-cli.js +0 -52
  407. package/dist/tui/ask-modal.js +0 -211
  408. package/dist/tui/ask-user-question-chips.js +0 -315
  409. package/dist/tui/ask-user-question-prompt.js +0 -203
  410. package/dist/tui/compact-banner.js +0 -81
  411. package/dist/tui/conversation-pane.js +0 -164
  412. package/dist/tui/cost-table.js +0 -111
  413. package/dist/tui/device-flow.js +0 -142
  414. package/dist/tui/doctor-table.js +0 -46
  415. package/dist/tui/feedback-prompt.js +0 -156
  416. package/dist/tui/input-box.js +0 -732
  417. package/dist/tui/login-picker.js +0 -69
  418. package/dist/tui/markdown-render.js +0 -266
  419. package/dist/tui/multi-file-diff-approval.js +0 -375
  420. package/dist/tui/onboarding-wizard.js +0 -240
  421. package/dist/tui/permissions-picker.js +0 -86
  422. package/dist/tui/render.js +0 -160
  423. package/dist/tui/repl-render.js +0 -770
  424. package/dist/tui/repl-splash-art.js +0 -64
  425. package/dist/tui/repl-splash-mascot.js +0 -154
  426. package/dist/tui/repl-splash.js +0 -117
  427. package/dist/tui/repl.js +0 -378
  428. package/dist/tui/slash-palette.js +0 -106
  429. package/dist/tui/splash-data.js +0 -61
  430. package/dist/tui/splash.js +0 -31
  431. package/dist/tui/status-bar.js +0 -209
  432. package/dist/tui/status-table.js +0 -7
  433. package/dist/tui/stickers-art.js +0 -136
  434. package/dist/tui/style-table.js +0 -28
  435. package/dist/tui/theme-table.js +0 -29
  436. package/dist/tui/thinking-spinner.js +0 -123
  437. package/dist/tui/tool-stream-pane.js +0 -140
  438. package/dist/tui/update-banner.js +0 -33
  439. package/dist/tui/vim-input.js +0 -267
  440. package/dist/tui/welcome-banner.js +0 -107
  441. package/dist/tui/welcome-data.js +0 -293
  442. package/dist/tui/workspace-context.js +0 -105
  443. package/docs/examples/codegraph.mcp.json +0 -10
  444. package/test/scenarios/codegen-create-file.scenario.txt +0 -13
  445. package/test/scenarios/compact-force.scenario.txt +0 -12
  446. package/test/scenarios/identity.scenario.txt +0 -11
  447. package/test/scenarios/persona-handoff.scenario.txt +0 -12
  448. package/test/scenarios/walkback.scenario.txt +0 -12
package/dist/tui/repl.js DELETED
@@ -1,378 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- /**
3
- * REPL root component - Sprint .
4
- *
5
- * Three-zone layout:
6
- *
7
- * header - `Pugi.io · workspace: <name> · v<X> on watch`
8
- * main - conversation pane (top half) + agent tree (bottom half)
9
- * footer - input box + status bar + key hints
10
- *
11
- * The component subscribes to a ReplSession instance for state. It does
12
- * NOT own the SSE client or the transport - the session module does.
13
- * This keeps the component a pure render over a typed state plus three
14
- * callbacks (submit, exit, overlay request).
15
- *
16
- * Overlays (`/help`, `/agents`) are rendered as full-pane modals that
17
- * eclipse the main area so they read top-to-bottom even on small
18
- * terminals. Pressing any key dismisses an overlay.
19
- */
20
- import { useCallback, useEffect, useMemo, useState } from 'react';
21
- import { Box, Text, useApp, useInput } from 'ink';
22
- import { PUGI_TAGLINE, THE_TEN } from '@pugi/personas';
23
- import { AgentTreePane } from './agent-tree-pane.js';
24
- import { AskModal, PlanReviewModal } from './ask-modal.js';
25
- import { ConversationPane } from './conversation-pane.js';
26
- import { InputBox } from './input-box.js';
27
- import { ReplSplash } from './repl-splash.js';
28
- import { StatusBar } from './status-bar.js';
29
- import { ThinkingSpinner } from './thinking-spinner.js';
30
- import { ToolStreamPane } from './tool-stream-pane.js';
31
- import { UpdateBanner } from './update-banner.js';
32
- import { WelcomeBanner } from './welcome-banner.js';
33
- import { collectWorkspaceContext } from './workspace-context.js';
34
- import { useTheme } from '../core/theme/context.js';
35
- import { slugForCwd } from '../core/repl/history.js';
36
- import { SLASH_COMMAND_HELP, SLASH_COMMAND_GROUPS } from '../core/repl/slash-commands.js';
37
- const TICK_INTERVAL_MS = 200;
38
- const PULSE_INTERVAL_MS = 700;
39
- // : maximum transcript rows the conversation pane renders at once.
40
- // Older rows scroll off the top; full history stays in session state.
41
- const CONVERSATION_WINDOW = 12;
42
- export function Repl(props) {
43
- const [state, setState] = useState(props.session.getState());
44
- const [overlay, setOverlay] = useState('none');
45
- const [pulsePhase, setPulsePhase] = useState(0);
46
- const [tickNow, setTickNow] = useState((props.now ?? Date.now)());
47
- // : operator-driven collapse for the tool stream pane. The CLI
48
- // host can hide the pane entirely via `--no-tool-stream`; this state
49
- // is the runtime toggle (Ctrl+T) for operators who want the pane on
50
- // screen but folded to a single row while they read a long reply.
51
- const [toolStreamCollapsed, setToolStreamCollapsed] = useState(false);
52
- // wave 3: boot splash visible until first input, first
53
- // `agent.spawned` event, or 10s idle. The host gates the initial
54
- // visibility on `--no-splash` / PUGI_SKIP_SPLASH via `skipSplash`.
55
- // CEO dogfood: default splash to HIDDEN at boot
56
- // (parity with the upstream tool's minimal one-line banner). Operator can
57
- // opt back in via `/splash` slash. The chafa pug pre-print + header
58
- // line already give the brand cue without the multi-row Plan/Model/
59
- // Tenant block crowding the top.
60
- const [splashVisible, setSplashVisible] = useState(false);
61
- const dismissSplash = useCallback(() => setSplashVisible(false), []);
62
- // CEO P0 #2 : welcome banner. Visible from boot
63
- // until the operator submits the first brief OR the session emits
64
- // its first agent event. The host owns dismissal lifecycle (kept
65
- // symmetric with the splash) so the welcome card never lingers
66
- // behind а live transcript.
67
- const [welcomeVisible, setWelcomeVisible] = useState(Boolean(props.welcomeData));
68
- // wave 3: workspace context snapshot for the status bar. We
69
- // read once at mount and freeze; a brand-new PUGI.md or skill is
70
- // surfaced on the next REPL boot rather than via a watcher.
71
- const workspaceContext = useMemo(() => props.workspaceContext ?? collectWorkspaceContext(process.cwd()), [props.workspaceContext]);
72
- // Subscribe to session state updates. The session module fires the
73
- // callback synchronously inside `patch` so we mirror without a
74
- // batching layer.
75
- useEffect(() => {
76
- const unsubscribe = props.session.subscribe(setState);
77
- return unsubscribe;
78
- }, [props.session]);
79
- // 200ms tick for the status-bar wall-clock + token counter rerender.
80
- // Cheaper than re-mounting the session subscription and lets the
81
- // status bar lag the dispatcher events by at most one frame.
82
- useEffect(() => {
83
- const interval = setInterval(() => {
84
- setTickNow((props.now ?? Date.now)());
85
- }, TICK_INTERVAL_MS);
86
- return () => clearInterval(interval);
87
- }, [props.now]);
88
- // Pulse the on-watch dot every 700ms. Three glyphs cycle, so the
89
- // operator sees a gentle three-step animation rather than a binary
90
- // blink. Subtle by design - brand voice forbids flashing.
91
- useEffect(() => {
92
- const interval = setInterval(() => {
93
- setPulsePhase((prev) => (prev + 1) % 3);
94
- }, PULSE_INTERVAL_MS);
95
- return () => clearInterval(interval);
96
- }, []);
97
- useEffect(() => {
98
- props.onOverlayChange?.(overlay);
99
- }, [overlay, props]);
100
- // wave 3: dismiss the boot splash once the first agent spawns
101
- // (the operator has clearly engaged the system) or the transcript
102
- // gains a row. Mirrors the natural attention shift the upstream tool /
103
- // Codex / Gemini CLI all do on their boot screens.
104
- useEffect(() => {
105
- if (!splashVisible)
106
- return;
107
- if (state.agents.length > 0 || state.transcript.length > 0) {
108
- setSplashVisible(false);
109
- }
110
- }, [splashVisible, state.agents.length, state.transcript.length]);
111
- // CEO P0 #2 v2: welcome banner stays until the operator
112
- // actively engages the loop — first agent spawn. Boot-time auto-init
113
- // emits system rows into `state.transcript` (skip-trust hints, dirty
114
- // tree warnings) which used к dismiss the banner within ~2s, hiding
115
- // the brand mascot before the operator could read it. Drop the
116
- // `transcript.length` trigger; agent spawn (= real dispatch) remains
117
- // the sole signal that the operator stopped reading the banner.
118
- useEffect(() => {
119
- if (!welcomeVisible)
120
- return;
121
- if (state.agents.length > 0) {
122
- setWelcomeVisible(false);
123
- }
124
- }, [welcomeVisible, state.agents.length]);
125
- const personaNames = useMemo(() => buildPersonaNameMap(), []);
126
- const { exit } = useApp();
127
- const handleSubmit = useCallback((line) => {
128
- // Dismiss the boot splash on first operator input. Idempotent —
129
- // `setSplashVisible(false)` is a no-op once the state already
130
- // settled to false (timer fired or `agent.spawned` arrived).
131
- setSplashVisible(false);
132
- // CEO P0 #2 : same dismissal for the welcome banner
133
- // — the operator engaging the input box is the cleanest signal
134
- // they have finished reading the boot card.
135
- setWelcomeVisible(false);
136
- // Run async without awaiting - the session module owns the
137
- // network call, errors land in the transcript automatically.
138
- void props.session.handleInput(line).then((verdict) => {
139
- applyVerdictSideEffects(verdict, {
140
- showHelp: () => setOverlay('help'),
141
- showRoster: () => setOverlay('roster'),
142
- farewell: () => {
143
- setOverlay('farewell');
144
- setTimeout(() => {
145
- props.session.close();
146
- exit();
147
- }, 800);
148
- },
149
- });
150
- });
151
- }, [props.session, exit]);
152
- const handleExit = useCallback(() => {
153
- setOverlay('farewell');
154
- setTimeout(() => {
155
- props.session.close();
156
- exit();
157
- }, 400);
158
- }, [props.session, exit]);
159
- // Any keystroke dismisses an overlay; mounting useInput at the root
160
- // gives us the dismiss without colliding with the input box (which
161
- // unmounts while an overlay is active).
162
- useInput((_input, _key) => {
163
- if (overlay !== 'none' && overlay !== 'farewell') {
164
- setOverlay('none');
165
- }
166
- }, { isActive: overlay === 'help' || overlay === 'roster' });
167
- // : Ctrl+T toggles the tool stream pane between expanded and
168
- // collapsed states. Active only while no overlay is open, so the
169
- // toggle never fights the help/roster dismiss handler. The input box
170
- // owns its own raw-input mode, so this listener only fires on the
171
- // global Ctrl+T binding rather than every printable keystroke.
172
- useInput((input, key) => {
173
- if (key.ctrl && input === 't') {
174
- setToolStreamCollapsed((prev) => !prev);
175
- }
176
- }, { isActive: overlay === 'none' && props.hideToolStream !== true });
177
- // office-hours: a pending ask or plan-review modal pauses input
178
- // until the operator resolves it. The modal owns its own useInput
179
- // hook, so the InputBox unmounts while a modal is open to avoid two
180
- // raw-input listeners competing for the same keystroke. Resolution
181
- // forwards through ReplSession.resolveAsk / resolvePlanReview.
182
- const askPending = state.pendingAsk !== null;
183
- const planPending = state.pendingPlanReview !== null;
184
- const modalActive = askPending || planPending;
185
- const handleAskResolve = useCallback((verdict) => {
186
- void props.session.resolveAsk(verdict);
187
- }, [props.session]);
188
- const handlePlanReviewResolve = useCallback((result) => {
189
- void props.session.resolvePlanReview(result);
190
- }, [props.session]);
191
- // : Ctrl+C abort handler. Forwards to ReplSession.cancel() which
192
- // aborts the in-flight dispatch, closes the SSE stream, and surfaces
193
- // "Aborted." in the transcript.
194
- //
195
- // Return contract (consumed by InputBox):
196
- // - true - dispatch was cancelled (keep the buffer + DO arm
197
- // the press-again-to-exit timer; second Ctrl+C in
198
- // the window exits).
199
- // - false - idle / nothing to cancel (legacy: clear buffer +
200
- // arm the exit timer so the operator sees the hint
201
- // and can confirm exit on the next press).
202
- // - undefined - bypassed entirely (e.g. a modal owns the input).
203
- // InputBox MUST NOT arm the exit timer and MUST
204
- // NOT clear the buffer. P2 fix: previously this
205
- // returned `false` and the buffer-clear path wiped
206
- // the operator's mid-typed modal text on the first
207
- // Ctrl+C, costing a press of work.
208
- const handleCancel = useCallback(() => {
209
- if (modalActive)
210
- return undefined;
211
- return props.session.cancel();
212
- }, [props.session, modalActive]);
213
- // BT 8 (the upstream tool parity): Esc-Esc walkback. Forwards to
214
- // ReplSession.walkbackLastTurn which trims the trailing operator
215
- // turn + its persona response from the in-memory transcript. Returns
216
- // `'walked-back'` so the input box knows the host did the work;
217
- // `'nothing'` covers both the empty-transcript and dispatch-in-flight
218
- // refusals (the session module owns the refusal copy in both cases).
219
- const handleWalkback = useCallback(() => {
220
- if (modalActive)
221
- return 'nothing';
222
- const verdict = props.session.walkbackLastTurn();
223
- return verdict === 'walked-back' ? 'walked-back' : 'nothing';
224
- }, [props.session, modalActive]);
225
- // — Shift+Tab cycles the 6 canonical permission modes (CC
226
- // parity). Refuses while a modal is active so the operator does not
227
- // accidentally flip mode mid-prompt; otherwise resolves the current
228
- // mode through the workspace > global > default merge, advances via
229
- // `nextPermissionMode`, и persists к .pugi/session.json. Returns the
230
- // new mode string so the InputBox can flash a one-line toast.
231
- const handleCyclePermissionMode = useCallback(() => {
232
- if (modalActive)
233
- return null;
234
- try {
235
- // Lazy-require так this code path doesn't drag the permissions
236
- // module into the splash + boot stages where it isn't needed.
237
- // The require is sync but the inner work is pure JSON IO.
238
- // eslint-disable-next-line @typescript-eslint/no-require-imports
239
- const perm = require('../core/permissions/index.js');
240
- const workspaceRoot = process.cwd();
241
- const current = perm.resolveMode({ workspaceRoot });
242
- const next = perm.nextPermissionMode(current);
243
- perm.setCurrentMode(workspaceRoot, next);
244
- return next;
245
- }
246
- catch {
247
- // Persistence is best-effort — if .pugi/session.json is read-only
248
- // или ENOENT-on-parent the toast is suppressed so we don't lie
249
- // about the flip к the operator.
250
- return null;
251
- }
252
- }, [modalActive]);
253
- // CEO dogfood (parity with the upstream tool): input
254
- // box pinned to alt-screen BOTTOM, conversation grows above it.
255
- // Beta.3's height={rows} fix broke keystroke focus - raw echo at
256
- // viewport bottom. The right pattern is minHeight on the root +
257
- // flexGrow=1 on the MainArea Box: empty alt-screen lives ABOVE the
258
- // input, and the input stays the sole focusable surface adjacent
259
- // to the cursor row, so all keystrokes route through it.
260
- const altScreenRows = process.stdout.rows ?? 24;
261
- return (_jsxs(Box, { flexDirection: "column", paddingX: 1, minHeight: altScreenRows, children: [welcomeVisible && props.welcomeData ? (_jsx(WelcomeBanner, { data: props.welcomeData, mascotPrePrinted: props.mascotPrePrinted === true, autoInitStatus: props.autoInitStatus ?? null })) : null, splashVisible ? (_jsx(ReplSplash, { cliVersion: state.cliVersion, workspaceLabel: state.workspaceLabel, plan: props.splashPlan, model: props.splashModel, tenant: props.splashTenant, onDismiss: dismissSplash, mascotPrePrinted: props.mascotPrePrinted === true })) : null, _jsx(Header, { state: state }), _jsx(Box, { flexDirection: "column", marginTop: 1, flexGrow: 1, justifyContent: "flex-end", children: overlay === 'help' ? (_jsx(HelpOverlay, {})) : overlay === 'roster' ? (_jsx(RosterOverlay, {})) : overlay === 'farewell' ? (_jsx(FarewellOverlay, {})) : (_jsx(MainArea, { state: state, personaNames: personaNames, nowEpochMs: tickNow, hideToolStream: props.hideToolStream === true, toolStreamCollapsed: toolStreamCollapsed })) }), state.pendingAsk ? (_jsx(Box, { marginTop: 1, children: _jsx(AskModal, { tag: state.pendingAsk, onResolve: handleAskResolve }) })) : null, state.pendingPlanReview ? (_jsx(Box, { marginTop: 1, children: _jsx(PlanReviewModal, { tag: state.pendingPlanReview, onResolve: handlePlanReviewResolve }) })) : null, _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [overlay === 'farewell' || modalActive ? null : (_jsx(InputBox, { onSubmit: handleSubmit, onExit: handleExit, onCancel: handleCancel, onWalkback: handleWalkback, onCyclePermissionMode: handleCyclePermissionMode, now: props.now,
262
- // Slug from process.cwd() (full path) so two workspaces with
263
- // the same basename do not share history. state.workspaceLabel
264
- // is the basename only. Codex review P2.
265
- workspaceSlug: slugForCwd(process.cwd()) })), _jsx(ThinkingSpinner, { dispatchState: state.dispatchState, dispatchToolLabel: state.dispatchToolLabel }), _jsx(StatusBar, { connection: state.connection, activeAgentCount: countActive(state), tokensDownstreamTotal: state.tokensDownstreamTotal, briefStartedAtEpochMs: state.briefStartedAtEpochMs, nowEpochMs: tickNow, pulsePhase: pulsePhase, pugiMdCount: workspaceContext.pugiMdCount, mcpServerCount: workspaceContext.mcpServerCount, skillCount: workspaceContext.skillCount, quotaPct: props.quotaPct, dispatchState: state.dispatchState, dispatchToolLabel: state.dispatchToolLabel, lastCompletedOutcome: state.lastCompletedOutcome,
266
- // cost-meter sprint — surface accumulated session totals
267
- // + per-turn delta flash on the status bar's top row. The
268
- // session module owns accumulation; the bar is a pure render.
269
- sessionTokensIn: state.sessionTokensIn, sessionTokensOut: state.sessionTokensOut, sessionCostUsd: state.sessionCostUsd, sessionStartedAtEpochMs: state.sessionStartedAtEpochMs, lastTurnDelta: state.lastTurnDelta }), props.updateBanner ? _jsx(UpdateBanner, { result: props.updateBanner }) : null] })] }));
270
- }
271
- function Header({ state }) {
272
- // the header `.io` brand accent + connection
273
- // pill route through `useTheme()` so the operator's `/theme` flip
274
- // (default / dark / light / colorblind) re-tints the chrome on
275
- // re-mount. The `useTheme` hook returns the `default` preset's
276
- // colors when no provider is mounted, preserving the previous
277
- // `#3da9fc` constants for tests that import `<Repl />` standalone.
278
- const theme = useTheme();
279
- return (_jsxs(Box, { children: [_jsx(Text, { bold: true, children: "Pugi" }), _jsx(Text, { bold: true, color: theme.accent, children: ".io" }), _jsx(Text, { dimColor: true, children: ` · workspace: ${state.workspaceLabel} · v${state.cliVersion} · ` }), _jsx(Text, { color: theme.accent, children: state.connection === 'on_watch' ? 'on watch' : state.connection.replace('_', ' ') })] }));
280
- }
281
- function MainArea({ state, personaNames, nowEpochMs, hideToolStream, toolStreamCollapsed, }) {
282
- // : three vertical panes stacked above the input box.
283
- //
284
- // 1. Conversation pane (top) - transcript with Markdown render.
285
- // 2. Tool stream pane (mid) - live Read/Edit/Bash/Grep lines.
286
- // Hidden when `--no-tool-stream` is
287
- // set; collapsed via Ctrl+T while
288
- // the pane is visible.
289
- // 3. Agent tree pane (bottom) - Cyber-Zoo roster with persona /
290
- // status / duration / token counts.
291
- //
292
- // The window over the transcript is small (last 12 rows) so the
293
- // bottom of the frame stays anchored to the input box. New agents
294
- // push the operator line up the screen, mirroring the upstream tool /
295
- // peer CLI / Gemini CLI rendering.
296
- const conversationSlice = state.transcript.slice(-CONVERSATION_WINDOW);
297
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(ConversationPane, { rows: conversationSlice, personaNames: personaNames }), hideToolStream ? null : (_jsx(Box, { marginTop: 1, children: _jsx(ToolStreamPane, { calls: state.toolCalls, collapsed: toolStreamCollapsed }) })), _jsx(Box, { marginTop: 1, children: _jsx(AgentTreePane, { agents: state.agents, nowEpochMs: nowEpochMs }) })] }));
298
- }
299
- function HelpOverlay() {
300
- // Group commands by their `group` field so the operator scans the
301
- // palette by intent (dispatch → session → tools → settings → meta).
302
- // The wave-2 expansion grew the surface from 6 to 20 commands;
303
- // a flat list would force the operator to read 20 rows top-to-bottom
304
- // every time. Grouping cuts perceived complexity dramatically.
305
- const grouped = new Map();
306
- for (const row of SLASH_COMMAND_HELP) {
307
- const list = grouped.get(row.group);
308
- if (list) {
309
- grouped.set(row.group, [...list, row]);
310
- }
311
- else {
312
- grouped.set(row.group, [row]);
313
- }
314
- }
315
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Pugi REPL help" }), SLASH_COMMAND_GROUPS.map((group) => {
316
- const rows = grouped.get(group);
317
- if (!rows || rows.length === 0)
318
- return null;
319
- return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { dimColor: true, children: ` -- ${group} --` }), rows.map((row) => (_jsxs(Box, { children: [_jsx(Text, { bold: true, color: "#3da9fc", children: ` /${row.name} ${row.args}`.padEnd(22, ' ') }), _jsx(Text, { dimColor: true, children: row.gloss })] }, row.name)))] }, group));
320
- }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: `${PUGI_TAGLINE}` }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: 'Press any key to dismiss.' }) })] }));
321
- }
322
- function RosterOverlay() {
323
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "On-watch roster" }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: THE_TEN.map((persona) => (_jsxs(Box, { children: [_jsx(Text, { bold: true, children: ` ${persona.name.padEnd(10, ' ')}` }), _jsx(Text, { dimColor: true, children: `${persona.role.padEnd(20, ' ')}` }), _jsx(Text, { children: persona.oneLiner })] }, persona.slug))) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: 'Press any key to dismiss.' }) })] }));
324
- }
325
- function FarewellOverlay() {
326
- return (_jsx(Box, { flexDirection: "column", alignItems: "center", paddingY: 2, children: _jsx(Text, { bold: true, color: "#3da9fc", children: PUGI_TAGLINE }) }));
327
- }
328
- function applyVerdictSideEffects(verdict, handlers) {
329
- switch (verdict.kind) {
330
- case 'help':
331
- handlers.showHelp();
332
- return;
333
- case 'roster':
334
- handlers.showRoster();
335
- return;
336
- case 'quit':
337
- handlers.farewell();
338
- return;
339
- case 'dispatch':
340
- case 'stop':
341
- case 'web':
342
- case 'error':
343
- case 'noop':
344
- case 'clear':
345
- case 'version':
346
- case 'jobs':
347
- case 'ask':
348
- case 'consensus':
349
- case 'diff':
350
- case 'cost':
351
- case 'quota':
352
- case 'status':
353
- case 'resume':
354
- case 'mcp':
355
- case 'stub':
356
- // All non-overlay verdicts: the session module already appended
357
- // any operator-visible system lines (and, for `ask`, set
358
- // pendingAsk so the modal renders on the next frame). No further
359
- // UI side effect needed here.
360
- return;
361
- }
362
- }
363
- function countActive(state) {
364
- let count = 0;
365
- for (const agent of state.agents) {
366
- if (agent.status === 'queued' || agent.status === 'thinking')
367
- count += 1;
368
- }
369
- return count;
370
- }
371
- function buildPersonaNameMap() {
372
- const map = new Map();
373
- for (const persona of THE_TEN) {
374
- map.set(persona.slug, persona.name);
375
- }
376
- return map;
377
- }
378
- //# sourceMappingURL=repl.js.map
@@ -1,106 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Text } from 'ink';
3
- import { SLASH_COMMAND_HELP } from '../core/repl/slash-commands.js';
4
- export const PALETTE_ROW_LIMIT = 8;
5
- /**
6
- * Compute the FULL filtered candidate list for a given input buffer.
7
- * Centralises the "starts-with-slash → filter SLASH_COMMAND_HELP"
8
- * logic so the input box and the unit test agree on the shape.
9
- *
10
- * fix: returns the FULL filtered set, not just the
11
- * first PALETTE_ROW_LIMIT rows. The palette renderer now windows the
12
- * visible slice internally based on `focusedIndex`, so the operator
13
- * can scroll past row 7 via ↑/↓ on a long list (e.g. 20 commands when
14
- * the buffer is `/`). `totalBeforeLimit` is preserved on the return
15
- * shape for backward compatibility but always equals `rows.length`.
16
- *
17
- * Behaviour:
18
- * - Empty / non-slash buffer → empty result; palette stays hidden.
19
- * - `/` alone → all registry rows (the operator wants to browse).
20
- * - `/he` → rows whose name starts with `he` (case-insensitive).
21
- */
22
- export function filterPalette(buffer) {
23
- if (!buffer.startsWith('/')) {
24
- return { rows: [], totalBeforeLimit: 0 };
25
- }
26
- // Treat anything past the first whitespace as args - palette only
27
- // filters on the command name itself.
28
- const headEnd = buffer.indexOf(' ');
29
- const head = headEnd === -1 ? buffer.slice(1) : buffer.slice(1, headEnd);
30
- const prefix = head.toLowerCase();
31
- // Lowercase row.name too so a registry entry like `Help` still matches
32
- // an operator typing `/he`. Today every entry is lowercase, but the
33
- // type contract on SlashCommandHelp.name does not enforce that, and
34
- // a future addition would silently disappear from the palette
35
- // without this guard. Codex P2.
36
- const all = prefix.length === 0
37
- ? SLASH_COMMAND_HELP
38
- : SLASH_COMMAND_HELP.filter((row) => row.name.toLowerCase().startsWith(prefix));
39
- // Defensive copy via spread so callers cannot mutate the registry
40
- // through the returned readonly array (TS-only enforcement, but
41
- // future refactors might assume the contract).
42
- const rows = [...all];
43
- return {
44
- rows,
45
- totalBeforeLimit: rows.length,
46
- };
47
- }
48
- export function computePaletteWindow(rows, focusedIndex) {
49
- const total = rows.length;
50
- if (total <= PALETTE_ROW_LIMIT) {
51
- return { visible: rows, startIndex: 0, total };
52
- }
53
- // Sliding window: anchor the start so the focused row stays inside the
54
- // PALETTE_ROW_LIMIT span. Clamp at both ends so we never render fewer
55
- // than PALETTE_ROW_LIMIT rows when the list is long enough to fill them.
56
- let start = focusedIndex - Math.floor(PALETTE_ROW_LIMIT / 2);
57
- if (start < 0)
58
- start = 0;
59
- const maxStart = total - PALETTE_ROW_LIMIT;
60
- if (start > maxStart)
61
- start = maxStart;
62
- return {
63
- visible: rows.slice(start, start + PALETTE_ROW_LIMIT),
64
- startIndex: start,
65
- total,
66
- };
67
- }
68
- /**
69
- * Compute the auto-complete result for the Tab key. Picks the focused
70
- * row when there is one, falls back to the longest common prefix
71
- * otherwise (bash-like behaviour). Returns the new buffer the input
72
- * box should adopt, or `null` when there is nothing to complete.
73
- */
74
- export function completePalette(buffer, rows, focusedIndex) {
75
- if (rows.length === 0)
76
- return null;
77
- const target = rows[focusedIndex] ?? rows[0];
78
- if (!target)
79
- return null;
80
- // Preserve any args the operator has already started typing after a
81
- // space; only swap the head.
82
- const headEnd = buffer.indexOf(' ');
83
- const tail = headEnd === -1 ? '' : buffer.slice(headEnd);
84
- return `/${target.name}${tail}`;
85
- }
86
- export function SlashPalette(props) {
87
- if (props.rows.length === 0)
88
- return null;
89
- // fix: compute the visible window so the operator
90
- // can scroll past row 7 on long lists. Focus indexes the full rows
91
- // array; the window slides to keep the focused row visible.
92
- const window = computePaletteWindow(props.rows, props.focusedIndex);
93
- const overflow = window.total > PALETTE_ROW_LIMIT;
94
- // Indicator value: focused row is 1-based for human display
95
- // ("→ 9/20" reads better than "→ 8/20" when the operator is on
96
- // the ninth entry).
97
- const focusedDisplayIndex = Math.min(window.total, Math.max(1, props.focusedIndex + 1));
98
- return (_jsxs(Box, { flexDirection: "column", marginTop: 0, paddingLeft: 2, children: [window.visible.map((row, visibleIdx) => {
99
- const absoluteIdx = window.startIndex + visibleIdx;
100
- const focused = absoluteIdx === props.focusedIndex;
101
- const glyph = focused ? '▸' : '·';
102
- const cmd = `/${row.name}${row.args ? ` ${row.args}` : ''}`.padEnd(22, ' ');
103
- return (_jsxs(Box, { children: [_jsx(Text, { color: focused ? 'cyan' : 'gray', children: `${glyph} ` }), _jsx(Text, { bold: focused, color: focused ? 'cyan' : undefined, dimColor: !focused, children: cmd }), _jsx(Text, { dimColor: true, children: row.gloss })] }, row.name));
104
- }), overflow ? (_jsx(Box, { children: _jsx(Text, { dimColor: true, children: ` → ${focusedDisplayIndex}/${window.total}` }) })) : null, _jsx(Box, { children: _jsx(Text, { dimColor: true, children: ' ↑/↓ select · Tab complete · Enter run · Esc close' }) })] }));
105
- }
106
- //# sourceMappingURL=slash-palette.js.map
@@ -1,61 +0,0 @@
1
- import { homedir } from 'node:os';
2
- import { DEFAULT_API_URL, maskApiKey, normalizeApiUrl, readCredentialsFile, resolveActiveCredential, } from '../core/credentials.js';
3
- /**
4
- * Decode the JWT payload for display only — no signature check. The
5
- * splash never sends the token over the wire so a stale or malformed
6
- * JWT is still safe to show. Mirrors `decodeJwtPrincipal` in
7
- * runtime/cli.ts, intentionally duplicated rather than imported to
8
- * keep the TUI layer independent of the giant CLI module.
9
- */
10
- function decodeJwtPayload(token) {
11
- try {
12
- const parts = token.split('.');
13
- if (parts.length < 2)
14
- return null;
15
- const payload = parts[1];
16
- if (!payload)
17
- return null;
18
- const padded = payload
19
- .replace(/-/g, '+')
20
- .replace(/_/g, '/')
21
- .padEnd(payload.length + ((4 - (payload.length % 4)) % 4), '=');
22
- const json = Buffer.from(padded, 'base64').toString('utf8');
23
- const obj = JSON.parse(json);
24
- if (!obj || typeof obj !== 'object')
25
- return null;
26
- return {
27
- sub: typeof obj.sub === 'string' ? obj.sub : undefined,
28
- email: typeof obj.email === 'string' ? obj.email : undefined,
29
- customerId: typeof obj.customerId === 'string' ? obj.customerId : undefined,
30
- plan: typeof obj.plan === 'string' ? obj.plan : undefined,
31
- };
32
- }
33
- catch {
34
- return null;
35
- }
36
- }
37
- export function collectSplashData(input) {
38
- const env = input.env ?? process.env;
39
- const home = input.home ?? homedir();
40
- const credential = resolveActiveCredential(env, home);
41
- if (!credential) {
42
- const file = readCredentialsFile(home);
43
- const apiUrl = normalizeApiUrl(env.PUGI_API_URL ?? file.activeApiUrl ?? DEFAULT_API_URL);
44
- return {
45
- cliVersion: input.cliVersion,
46
- apiUrl,
47
- isAuthenticated: false,
48
- };
49
- }
50
- const principal = decodeJwtPayload(credential.apiKey);
51
- return {
52
- cliVersion: input.cliVersion,
53
- apiUrl: credential.apiUrl,
54
- isAuthenticated: true,
55
- apiKeyMasked: maskApiKey(credential.apiKey),
56
- ...(principal?.email ? { email: principal.email } : {}),
57
- ...(principal?.customerId ? { tenant: principal.customerId } : {}),
58
- ...(principal?.plan ? { plan: principal.plan } : {}),
59
- };
60
- }
61
- //# sourceMappingURL=splash-data.js.map
@@ -1,31 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Text } from 'ink';
3
- /**
4
- * Bare `pugi` (no args) splash. Rendered only on a real TTY by the
5
- * CLI dispatcher; non-TTY callers see the existing usage dump.
6
- *
7
- * Layout intentionally restrained: bold "pugi.io" wordmark, dim
8
- * version/endpoint metadata, neutral body. No background colors, no
9
- * emoji decoration, ASCII separators only.
10
- */
11
- export function Splash({ data }) {
12
- const accountLine = data.isAuthenticated
13
- ? `${data.email ?? data.apiKeyMasked ?? 'authenticated'}${data.tenant ? ` (tenant: ${data.tenant})` : ''}`
14
- : 'not signed in';
15
- const primaryHint = data.isAuthenticated
16
- ? {
17
- cmd: 'pugi code "fix the bug"',
18
- gloss: 'Run a one-shot coding task',
19
- }
20
- : {
21
- cmd: 'pugi login',
22
- gloss: 'Connect this terminal to your Pugi account',
23
- };
24
- return (_jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsx(Box, { children: _jsx(Text, { bold: true, color: "#3da9fc", children: "pugi.io" }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: `v${data.cliVersion} · ${data.apiUrl}` }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Account: " }), _jsx(Text, { children: accountLine })] }), data.isAuthenticated && data.plan ? (_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "Plan: " }), _jsx(Text, { children: data.plan })] })) : null] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { dimColor: true, children: "Quick start:" }), _jsx(HintRow, { command: primaryHint.cmd, gloss: primaryHint.gloss }), data.isAuthenticated ? (_jsx(HintRow, { command: 'pugi login', gloss: 'Re-authenticate or switch accounts' })) : (_jsx(HintRow, { command: 'pugi code "fix the bug"', gloss: 'Run a one-shot coding task' })), _jsx(HintRow, { command: 'pugi review --triple', gloss: 'Run the Anvil triple-review gate' }), _jsx(HintRow, { command: 'pugi help', gloss: 'Full command reference' })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Docs: https://pugi.dev \u00B7 Status: https://pugi.io/status" }) })] }));
25
- }
26
- function HintRow({ command, gloss }) {
27
- // Pad command names so the gloss column lines up across rows.
28
- const padded = command.padEnd(28, ' ');
29
- return (_jsxs(Text, { children: [_jsx(Text, { children: ` ${padded}` }), _jsx(Text, { dimColor: true, children: gloss })] }));
30
- }
31
- //# sourceMappingURL=splash.js.map