@pugi/cli 0.1.0-beta.10 → 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 (445) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/LICENSE +1 -1
  3. package/README.md +53 -11
  4. package/assets/pugi-prozr2-mascot.ansi +9 -0
  5. package/bin/run.js +33 -1
  6. package/dist/commands/deploy.js +40 -40
  7. package/dist/commands/flatten.js +191 -0
  8. package/dist/commands/jobs-watch.js +201 -0
  9. package/dist/commands/jobs.js +42 -27
  10. package/dist/commands/retro.js +210 -0
  11. package/dist/commands/smoke.js +133 -0
  12. package/dist/core/agent-progress/cleanup.js +134 -0
  13. package/dist/core/agent-progress/schema.js +144 -0
  14. package/dist/core/agent-progress/writer.js +101 -0
  15. package/dist/core/agents/adaptive-router.js +330 -0
  16. package/dist/core/agents/query-decomposer.js +297 -0
  17. package/dist/core/agents/registry.js +3 -3
  18. package/dist/core/approvals/shortcut-resolver.js +98 -0
  19. package/dist/core/artifact-chain/dispatcher.js +148 -0
  20. package/dist/core/artifact-chain/exporter.js +164 -0
  21. package/dist/core/artifact-chain/state.js +243 -0
  22. package/dist/core/artifact-chain/steps.js +169 -0
  23. package/dist/core/ask-user/question.js +92 -0
  24. package/dist/core/audit/audit-trail.js +275 -0
  25. package/dist/core/auth/ensure-authenticated.js +129 -0
  26. package/dist/core/auth/env-provider.js +238 -0
  27. package/dist/core/auto-open-browser.js +4 -4
  28. package/dist/core/auto-update/channels.js +122 -0
  29. package/dist/core/auto-update/checker.js +241 -0
  30. package/dist/core/auto-update/state.js +235 -0
  31. package/dist/core/bare-mode/index.js +107 -0
  32. package/dist/core/bash/redirect.js +281 -0
  33. package/dist/core/bash-classifier.js +436 -40
  34. package/dist/core/checkpoint/resumer.js +149 -0
  35. package/dist/core/checkpoint/rewinder.js +291 -0
  36. package/dist/core/checkpoints/shadow-git.js +670 -0
  37. package/dist/core/citations/parser.js +109 -0
  38. package/dist/core/classifier/yolo-classifier.js +88 -0
  39. package/dist/core/codegraph/db.js +506 -0
  40. package/dist/core/codegraph/decision-store.js +248 -0
  41. package/dist/core/codegraph/detect-repo.js +459 -0
  42. package/dist/core/codegraph/install.js +134 -0
  43. package/dist/core/codegraph/offer-hook.js +220 -0
  44. package/dist/core/codegraph/parser.js +71 -0
  45. package/dist/core/codegraph/types.js +34 -0
  46. package/dist/core/compact/auto-trigger.js +96 -0
  47. package/dist/core/compact/buffer-rewriter.js +115 -0
  48. package/dist/core/compact/summarizer.js +208 -0
  49. package/dist/core/compact/token-counter.js +108 -0
  50. package/dist/core/consensus/anvil-fanout.js +25 -25
  51. package/dist/core/consensus/diff-capture.js +121 -12
  52. package/dist/core/consensus/rubric.js +21 -21
  53. package/dist/core/context/builder.js +6 -6
  54. package/dist/core/context/compaction-events.js +8 -8
  55. package/dist/core/context/compaction.js +31 -31
  56. package/dist/core/context/index.js +15 -8
  57. package/dist/core/context/invariants.js +51 -51
  58. package/dist/core/context/markdown-loader.js +28 -10
  59. package/dist/core/context/markdown-traverse.js +255 -0
  60. package/dist/core/context/pugiignore.js +41 -41
  61. package/dist/core/context/repo-skeleton.js +37 -37
  62. package/dist/core/context/tool-eviction.js +55 -0
  63. package/dist/core/context/watcher.js +32 -32
  64. package/dist/core/context/working-set.js +23 -23
  65. package/dist/core/coordinator/agent-tools.js +77 -0
  66. package/dist/core/coordinator/agent-toolset.js +65 -0
  67. package/dist/core/coordinator/fsm.js +73 -0
  68. package/dist/core/coordinator/mode-fsm.js +70 -0
  69. package/dist/core/cost/rate-card.js +129 -0
  70. package/dist/core/cost/tracker.js +221 -0
  71. package/dist/core/credentials.js +13 -13
  72. package/dist/core/cron/scheduler.js +138 -0
  73. package/dist/core/denial-tracking/index.js +8 -0
  74. package/dist/core/denial-tracking/state.js +264 -0
  75. package/dist/core/diagnostics/probe-runner.js +93 -0
  76. package/dist/core/diagnostics/probes/api.js +46 -0
  77. package/dist/core/diagnostics/probes/auth.js +93 -0
  78. package/dist/core/diagnostics/probes/bare-mode.js +42 -0
  79. package/dist/core/diagnostics/probes/cli-version.js +127 -0
  80. package/dist/core/diagnostics/probes/config.js +72 -0
  81. package/dist/core/diagnostics/probes/denial-tracking.js +57 -0
  82. package/dist/core/diagnostics/probes/disk.js +81 -0
  83. package/dist/core/diagnostics/probes/engine-live.js +46 -0
  84. package/dist/core/diagnostics/probes/git.js +65 -0
  85. package/dist/core/diagnostics/probes/hooks.js +118 -0
  86. package/dist/core/diagnostics/probes/mcp.js +75 -0
  87. package/dist/core/diagnostics/probes/node.js +59 -0
  88. package/dist/core/diagnostics/probes/pnpm.js +36 -0
  89. package/dist/core/diagnostics/probes/pugi-md.js +89 -0
  90. package/dist/core/diagnostics/probes/sandbox.js +72 -0
  91. package/dist/core/diagnostics/probes/session.js +74 -0
  92. package/dist/core/diagnostics/probes/status-snapshot.js +488 -0
  93. package/dist/core/diagnostics/probes/workspace.js +63 -0
  94. package/dist/core/diagnostics/types.js +70 -0
  95. package/dist/core/dispatch/cache-cleanup.js +197 -0
  96. package/dist/core/dispatch/cache-handoff.js +295 -0
  97. package/dist/core/edits/apply-patch-layer-e.js +189 -0
  98. package/dist/core/edits/dispatch.js +333 -7
  99. package/dist/core/edits/format-detector.js +260 -0
  100. package/dist/core/edits/format-matrix.js +26 -0
  101. package/dist/core/edits/fuzzy-ladder.js +650 -0
  102. package/dist/core/edits/index.js +5 -1
  103. package/dist/core/edits/journal.js +199 -0
  104. package/dist/core/edits/layer-a-apply.js +15 -15
  105. package/dist/core/edits/layer-a-fuzzy-apply.js +198 -0
  106. package/dist/core/edits/layer-b-apply.js +9 -9
  107. package/dist/core/edits/layer-c-apply.js +6 -6
  108. package/dist/core/edits/layer-d-ast.js +557 -14
  109. package/dist/core/edits/marker-parser.js +12 -12
  110. package/dist/core/edits/security-gate.js +27 -27
  111. package/dist/core/edits/verify-hook.js +273 -0
  112. package/dist/core/edits/worktree.js +29 -29
  113. package/dist/core/engine/anvil-client.js +214 -26
  114. package/dist/core/engine/auto-compact.js +247 -0
  115. package/dist/core/engine/budgets.js +220 -0
  116. package/dist/core/engine/compact-llm-summarizer.js +124 -0
  117. package/dist/core/engine/context-prefix.js +155 -0
  118. package/dist/core/engine/index.js +1 -1
  119. package/dist/core/engine/intensity.js +163 -0
  120. package/dist/core/engine/intent.js +260 -0
  121. package/dist/core/engine/native-pugi.js +1559 -227
  122. package/dist/core/engine/prompts.js +187 -19
  123. package/dist/core/engine/strip-internal-fields.js +124 -0
  124. package/dist/core/engine/tool-bridge.js +1887 -59
  125. package/dist/core/engine/verification-patterns.js +195 -0
  126. package/dist/core/evaluation/golden-dataset.js +293 -0
  127. package/dist/core/feedback/queue.js +177 -0
  128. package/dist/core/feedback/submitter.js +145 -0
  129. package/dist/core/file-cache.js +113 -1
  130. package/dist/core/flatten/flatten-repo.js +439 -0
  131. package/dist/core/format/osc8-link.js +28 -0
  132. package/dist/core/hook-chains.js +392 -0
  133. package/dist/core/hooks/citation-verify-hook.js +138 -0
  134. package/dist/core/hooks/citation-verify.js +112 -0
  135. package/dist/core/hooks/events.js +46 -0
  136. package/dist/core/hooks/index.js +15 -0
  137. package/dist/core/hooks/registry.js +216 -0
  138. package/dist/core/hooks/runner.js +236 -0
  139. package/dist/core/hooks/v2/event-emitter.js +115 -0
  140. package/dist/core/hooks/v2/executor.js +282 -0
  141. package/dist/core/hooks/v2/index.js +25 -0
  142. package/dist/core/hooks/v2/lifecycle.js +104 -0
  143. package/dist/core/hooks/v2/loader.js +216 -0
  144. package/dist/core/hooks/v2/matcher.js +125 -0
  145. package/dist/core/hooks/v2/trust.js +143 -0
  146. package/dist/core/hooks/v2/types.js +86 -0
  147. package/dist/core/hooks/worktree-events.js +158 -0
  148. package/dist/core/image/renderer.js +71 -0
  149. package/dist/core/init/detector.js +582 -0
  150. package/dist/core/init/template-renderer.js +242 -0
  151. package/dist/core/jobs/registry.js +18 -18
  152. package/dist/core/ledger/results-tsv.js +142 -0
  153. package/dist/core/log-discipline/stdout-redirect.js +51 -0
  154. package/dist/core/lsp/cache.js +105 -0
  155. package/dist/core/lsp/client.js +551 -41
  156. package/dist/core/lsp/language-detect.js +66 -0
  157. package/dist/core/lsp/post-edit-diagnostics.js +171 -0
  158. package/dist/core/lsp/server-detect.js +173 -0
  159. package/dist/core/lsp/symbol-cache.js +162 -0
  160. package/dist/core/lsp/symbol-tools.js +664 -0
  161. package/dist/core/mcp/client.js +97 -28
  162. package/dist/core/mcp/http-server.js +553 -0
  163. package/dist/core/mcp/orchestrator-config.js +192 -0
  164. package/dist/core/mcp/orchestrator-tools.js +806 -0
  165. package/dist/core/mcp/permission.js +190 -0
  166. package/dist/core/mcp/registry.js +39 -17
  167. package/dist/core/mcp/server-tools.js +219 -0
  168. package/dist/core/mcp/server.js +397 -0
  169. package/dist/core/mcp/trust.js +10 -10
  170. package/dist/core/memory/dual-write.js +416 -0
  171. package/dist/core/memory/passive-extract.js +130 -0
  172. package/dist/core/memory/phase1-kinds.js +20 -0
  173. package/dist/core/memory/secret-scanner.js +304 -0
  174. package/dist/core/memory-sync/queue.js +170 -0
  175. package/dist/core/metrics/extract.js +113 -0
  176. package/dist/core/modes/roo-modes.js +68 -0
  177. package/dist/core/notes/notes-paths.js +113 -0
  178. package/dist/core/notes/notes-recorder.js +140 -0
  179. package/dist/core/notes/notes-writer.js +53 -0
  180. package/dist/core/notes/renderers.js +0 -0
  181. package/dist/core/notes/slug.js +105 -0
  182. package/dist/core/onboarding/ensure-initialized.js +133 -0
  183. package/dist/core/onboarding/marker.js +111 -0
  184. package/dist/core/onboarding/telemetry-state.js +108 -0
  185. package/dist/core/output-style/presets.js +176 -0
  186. package/dist/core/output-style/state.js +185 -0
  187. package/dist/core/path-security.js +287 -5
  188. package/dist/core/permission.js +82 -22
  189. package/dist/core/permissions/auto-classifier.js +124 -0
  190. package/dist/core/permissions/bash-parser.js +371 -0
  191. package/dist/core/permissions/circuit-breaker.js +83 -0
  192. package/dist/core/permissions/constrained-edit.js +91 -0
  193. package/dist/core/permissions/gate.js +278 -0
  194. package/dist/core/permissions/index.js +20 -0
  195. package/dist/core/permissions/mode.js +174 -0
  196. package/dist/core/permissions/network-egress.js +137 -0
  197. package/dist/core/permissions/state.js +241 -0
  198. package/dist/core/permissions/tool-class.js +107 -0
  199. package/dist/core/plan-mode/ui-state.js +51 -0
  200. package/dist/core/plans/plan-artifact.js +721 -0
  201. package/dist/core/policy-limits/etag-store.js +122 -0
  202. package/dist/core/prd-check/parser.js +215 -0
  203. package/dist/core/prd-check/reporter.js +127 -0
  204. package/dist/core/prd-check/session-review.js +557 -0
  205. package/dist/core/prd-check/verifiers.js +223 -0
  206. package/dist/core/prompt-cache/client-cache.js +99 -0
  207. package/dist/core/prompts/assembly.js +29 -0
  208. package/dist/core/prompts/registry.js +364 -0
  209. package/dist/core/pugi-gitignore.js +52 -0
  210. package/dist/core/pugi-md/cc-compat-rules.js +735 -0
  211. package/dist/core/pugi-md/context-injector.js +76 -0
  212. package/dist/core/pugi-md/walk-up.js +207 -0
  213. package/dist/core/python/uv-installer.js +270 -0
  214. package/dist/core/python/uv-resolver.js +83 -0
  215. package/dist/core/rate-limit/narrator.js +146 -0
  216. package/dist/core/recipes/cli-types.js +20 -0
  217. package/dist/core/recipes/loader.js +103 -0
  218. package/dist/core/recipes/runner.js +345 -0
  219. package/dist/core/recipes/schema.js +587 -0
  220. package/dist/core/release-notes/parser.js +241 -0
  221. package/dist/core/release-notes/state.js +116 -0
  222. package/dist/core/repl/ask.js +37 -37
  223. package/dist/core/repl/cancellation.js +26 -26
  224. package/dist/core/repl/cap-warning.js +4 -4
  225. package/dist/core/repl/clipboard-read.js +11 -11
  226. package/dist/core/repl/dispatch-fsm.js +12 -12
  227. package/dist/core/repl/engine-bridge.js +303 -0
  228. package/dist/core/repl/history-search.js +15 -15
  229. package/dist/core/repl/history.js +28 -18
  230. package/dist/core/repl/kill-ring.js +5 -5
  231. package/dist/core/repl/model-pricing.js +135 -0
  232. package/dist/core/repl/privacy-banner.js +22 -22
  233. package/dist/core/repl/session.js +2690 -229
  234. package/dist/core/repl/slash-commands.js +540 -41
  235. package/dist/core/repl/store/index.js +1 -1
  236. package/dist/core/repl/store/jsonl-log.js +22 -22
  237. package/dist/core/repl/store/lockfile.js +10 -10
  238. package/dist/core/repl/store/session-store.js +136 -107
  239. package/dist/core/repl/store/types.js +15 -15
  240. package/dist/core/repl/store/uuid-v7.js +12 -12
  241. package/dist/core/repl/tool-route.js +382 -0
  242. package/dist/core/repl/workspace-context.js +43 -21
  243. package/dist/core/repo-map/build.js +125 -0
  244. package/dist/core/repo-map/cache.js +185 -0
  245. package/dist/core/repo-map/extractor.js +254 -0
  246. package/dist/core/repo-map/formatter.js +145 -0
  247. package/dist/core/repo-map/page-rank.js +105 -0
  248. package/dist/core/repo-map/scanner.js +211 -0
  249. package/dist/core/retro/git-collector.js +251 -0
  250. package/dist/core/retro/health-card.js +25 -0
  251. package/dist/core/retro/metrics.js +342 -0
  252. package/dist/core/retro/narrative.js +249 -0
  253. package/dist/core/retro/plane-collector.js +274 -0
  254. package/dist/core/retro/pr-issue-link.js +65 -0
  255. package/dist/core/retro/types.js +16 -0
  256. package/dist/core/retry-budget/budget.js +284 -0
  257. package/dist/core/retry-budget/index.js +5 -0
  258. package/dist/core/retry-budget/retry-cap.js +74 -0
  259. package/dist/core/routing/lead-worker.js +43 -0
  260. package/dist/core/routing/pre-flight-estimator.js +108 -0
  261. package/dist/core/runs/run-tree.js +103 -0
  262. package/dist/core/sandboxing/adapter.js +29 -0
  263. package/dist/core/sandboxing/index.js +49 -0
  264. package/dist/core/sandboxing/none.js +19 -0
  265. package/dist/core/sandboxing/seatbelt.js +183 -0
  266. package/dist/core/security/injection-scanner.js +367 -0
  267. package/dist/core/security/output-filter.js +418 -0
  268. package/dist/core/session/env-file.js +105 -0
  269. package/dist/core/session/section-budgets.js +140 -0
  270. package/dist/core/session.js +119 -0
  271. package/dist/core/settings.js +378 -5
  272. package/dist/core/share/formatter.js +271 -0
  273. package/dist/core/share/redactor.js +221 -0
  274. package/dist/core/share/uploader.js +267 -0
  275. package/dist/core/skills/defaults.js +30 -30
  276. package/dist/core/skills/loader.js +22 -22
  277. package/dist/core/skills/sources.js +27 -27
  278. package/dist/core/smoke/headless-driver.js +174 -0
  279. package/dist/core/smoke/orchestrator.js +194 -0
  280. package/dist/core/smoke/runner.js +238 -0
  281. package/dist/core/smoke/scenario-parser.js +316 -0
  282. package/dist/core/statusline.js +99 -0
  283. package/dist/core/subagents/dispatcher-real.js +600 -0
  284. package/dist/core/subagents/dispatcher.js +146 -52
  285. package/dist/core/subagents/index.js +19 -6
  286. package/dist/core/subagents/isolation-matrix.js +213 -0
  287. package/dist/core/subagents/spawn.js +19 -4
  288. package/dist/core/telemetry/emitter.js +229 -0
  289. package/dist/core/telemetry/queue.js +251 -0
  290. package/dist/core/theme/context.js +91 -0
  291. package/dist/core/theme/presets.js +228 -0
  292. package/dist/core/theme/state.js +181 -0
  293. package/dist/core/todos/invariant.js +10 -0
  294. package/dist/core/todos/state.js +177 -0
  295. package/dist/core/tool-schema/compressor.js +89 -0
  296. package/dist/core/transport/version-interceptor.js +166 -0
  297. package/dist/core/trust.js +2 -2
  298. package/dist/core/tui/thinking-block.js +64 -0
  299. package/dist/core/vim/keymap.js +288 -0
  300. package/dist/core/vim/state.js +92 -0
  301. package/dist/core/watch-markers/marker-watcher.js +133 -0
  302. package/dist/core/worktree/include-parser.js +249 -0
  303. package/dist/core/worktree-manager/cleanup.js +123 -0
  304. package/dist/core/worktree-manager/manager.js +303 -0
  305. package/dist/index.js +36 -0
  306. package/dist/runtime/bootstrap.js +190 -0
  307. package/dist/runtime/cli.js +4345 -561
  308. package/dist/runtime/commands/agents.js +31 -31
  309. package/dist/runtime/commands/budget.js +5 -5
  310. package/dist/runtime/commands/cancel.js +231 -0
  311. package/dist/runtime/commands/chain.js +489 -0
  312. package/dist/runtime/commands/codegraph-status.js +227 -0
  313. package/dist/runtime/commands/compact.js +297 -0
  314. package/dist/runtime/commands/config.js +74 -40
  315. package/dist/runtime/commands/cost.js +199 -0
  316. package/dist/runtime/commands/delegate.js +27 -4
  317. package/dist/runtime/commands/dispatch.js +126 -0
  318. package/dist/runtime/commands/doctor.js +579 -0
  319. package/dist/runtime/commands/feedback.js +184 -0
  320. package/dist/runtime/commands/hooks.js +187 -0
  321. package/dist/runtime/commands/index-cmd.js +353 -0
  322. package/dist/runtime/commands/init.js +254 -0
  323. package/dist/runtime/commands/lsp.js +200 -38
  324. package/dist/runtime/commands/mcp.js +935 -0
  325. package/dist/runtime/commands/memory.js +582 -0
  326. package/dist/runtime/commands/model.js +237 -0
  327. package/dist/runtime/commands/onboarding.js +275 -0
  328. package/dist/runtime/commands/patch.js +12 -12
  329. package/dist/runtime/commands/permissions.js +112 -0
  330. package/dist/runtime/commands/plan.js +143 -0
  331. package/dist/runtime/commands/prd-check.js +285 -0
  332. package/dist/runtime/commands/privacy.js +17 -17
  333. package/dist/runtime/commands/recipe.js +325 -0
  334. package/dist/runtime/commands/redo-blob-store.js +92 -0
  335. package/dist/runtime/commands/redo.js +361 -0
  336. package/dist/runtime/commands/release-notes.js +229 -0
  337. package/dist/runtime/commands/repo-map.js +95 -0
  338. package/dist/runtime/commands/report.js +299 -0
  339. package/dist/runtime/commands/resume.js +118 -0
  340. package/dist/runtime/commands/review-consensus.js +68 -53
  341. package/dist/runtime/commands/rewind.js +333 -0
  342. package/dist/runtime/commands/roster.js +14 -14
  343. package/dist/runtime/commands/servers.js +236 -0
  344. package/dist/runtime/commands/sessions.js +163 -0
  345. package/dist/runtime/commands/share.js +316 -0
  346. package/dist/runtime/commands/skills.js +31 -31
  347. package/dist/runtime/commands/status.js +186 -0
  348. package/dist/runtime/commands/stickers.js +82 -0
  349. package/dist/runtime/commands/style.js +194 -0
  350. package/dist/runtime/commands/theme.js +196 -0
  351. package/dist/runtime/commands/undo.js +54 -22
  352. package/dist/runtime/commands/update.js +289 -0
  353. package/dist/runtime/commands/vim.js +140 -0
  354. package/dist/runtime/commands/worktree.js +8 -8
  355. package/dist/runtime/commands/worktrees.js +155 -0
  356. package/dist/runtime/deprecation-warning.js +69 -0
  357. package/dist/runtime/engine-exit-code.js +50 -0
  358. package/dist/runtime/headless-repl.js +195 -0
  359. package/dist/runtime/headless.js +548 -0
  360. package/dist/runtime/load-hooks-or-exit.js +71 -0
  361. package/dist/runtime/plan-decompose.js +22 -22
  362. package/dist/runtime/sigint-guard.js +272 -0
  363. package/dist/runtime/stream-renderer.js +195 -0
  364. package/dist/runtime/update-check.js +28 -28
  365. package/dist/runtime/version.js +65 -0
  366. package/dist/runtime/worktree-bootstrap.js +579 -0
  367. package/dist/skills/bundled/batch.js +617 -0
  368. package/dist/skills/bundled/index.js +45 -0
  369. package/dist/skills/bundled/loop.js +358 -0
  370. package/dist/skills/bundled/remember.js +383 -0
  371. package/dist/skills/bundled/simplify.js +289 -0
  372. package/dist/skills/bundled/skillify.js +373 -0
  373. package/dist/skills/bundled/stuck.js +558 -0
  374. package/dist/skills/bundled/verify.js +439 -0
  375. package/dist/testing/vcr.js +486 -0
  376. package/dist/tools/agent-tool.js +229 -0
  377. package/dist/tools/apply-patch.js +89 -28
  378. package/dist/tools/ask-user-question.js +337 -0
  379. package/dist/tools/ask-user.js +115 -0
  380. package/dist/tools/bash.js +624 -46
  381. package/dist/tools/brief.js +224 -0
  382. package/dist/tools/cron.js +433 -0
  383. package/dist/tools/enter-worktree.js +250 -0
  384. package/dist/tools/exit-worktree.js +147 -0
  385. package/dist/tools/file-tools.js +161 -44
  386. package/dist/tools/http-request.js +336 -0
  387. package/dist/tools/lsp-tools.js +377 -1
  388. package/dist/tools/mcp-tool.js +260 -0
  389. package/dist/tools/multi-edit.js +361 -0
  390. package/dist/tools/powershell.js +268 -0
  391. package/dist/tools/registry.js +120 -5
  392. package/dist/tools/server-tools.js +892 -0
  393. package/dist/tools/skill-tool.js +96 -0
  394. package/dist/tools/sleep.js +99 -0
  395. package/dist/tools/synthetic-output.js +133 -0
  396. package/dist/tools/tasks.js +208 -0
  397. package/dist/tools/todo-write.js +184 -0
  398. package/dist/tools/verify-plan-execution.js +295 -0
  399. package/dist/tools/web-fetch-injection-scanner.js +207 -0
  400. package/dist/tools/web-fetch.js +195 -10
  401. package/dist/tools/web-search.js +458 -0
  402. package/dist/tui/agent-progress-card.js +111 -0
  403. package/dist/tui/agent-tree.js +22 -1
  404. package/dist/tui/ask-modal.js +14 -14
  405. package/dist/tui/ask-user-question-chips.js +315 -0
  406. package/dist/tui/ask-user-question-prompt.js +203 -0
  407. package/dist/tui/compact-banner.js +81 -0
  408. package/dist/tui/conversation-pane.js +85 -11
  409. package/dist/tui/cost-table.js +111 -0
  410. package/dist/tui/device-flow.js +2 -2
  411. package/dist/tui/doctor-table.js +46 -0
  412. package/dist/tui/feedback-prompt.js +156 -0
  413. package/dist/tui/input-box.js +247 -32
  414. package/dist/tui/login-picker.js +3 -3
  415. package/dist/tui/markdown-render.js +6 -6
  416. package/dist/tui/multi-file-diff-approval.js +375 -0
  417. package/dist/tui/onboarding-wizard.js +240 -0
  418. package/dist/tui/permissions-picker.js +86 -0
  419. package/dist/tui/render.js +36 -1
  420. package/dist/tui/repl-render.js +239 -25
  421. package/dist/tui/repl-splash-art.js +16 -16
  422. package/dist/tui/repl-splash-mascot.js +48 -24
  423. package/dist/tui/repl-splash.js +22 -22
  424. package/dist/tui/repl.js +125 -45
  425. package/dist/tui/slash-palette.js +6 -6
  426. package/dist/tui/splash.js +2 -2
  427. package/dist/tui/status-bar.js +109 -31
  428. package/dist/tui/status-table.js +7 -0
  429. package/dist/tui/stickers-art.js +136 -0
  430. package/dist/tui/style-table.js +28 -0
  431. package/dist/tui/theme-table.js +29 -0
  432. package/dist/tui/thinking-spinner.js +123 -0
  433. package/dist/tui/tool-stream-pane.js +53 -4
  434. package/dist/tui/update-banner.js +27 -2
  435. package/dist/tui/vim-input.js +267 -0
  436. package/dist/tui/welcome-banner.js +107 -0
  437. package/dist/tui/welcome-data.js +293 -0
  438. package/dist/tui/workspace-context.js +2 -2
  439. package/package.json +21 -5
  440. package/test/scenarios/codegen-create-file.scenario.txt +13 -0
  441. package/test/scenarios/compact-force.scenario.txt +12 -0
  442. package/test/scenarios/identity.scenario.txt +11 -0
  443. package/test/scenarios/persona-handoff.scenario.txt +12 -0
  444. package/test/scenarios/walkback.scenario.txt +12 -0
  445. package/dist/core/engine/compaction-hook.js +0 -154
@@ -5,11 +5,11 @@
5
5
  * Per `docs/research/pugi-cli-corpus/patterns/context-compaction.md` §6,
6
6
  * static and dynamic context live in different sections:
7
7
  *
8
- * STATIC DYNAMIC
9
- * - system instructions - transcript turns (recent)
10
- * - tool schemas (sorted) - session memory ref
11
- * - safety rules - open task graph snapshot
12
- * - PUGI.md + AGENTS.md
8
+ * STATIC DYNAMIC
9
+ * - system instructions - transcript turns (recent)
10
+ * - tool schemas (sorted) - session memory ref
11
+ * - safety rules - open task graph snapshot
12
+ * - PUGI.md + AGENTS.md
13
13
  *
14
14
  * Static blocks hash deterministically; identical session starts emit
15
15
  * identical static prefixes, hitting the model provider's prompt cache.
@@ -50,7 +50,7 @@ export async function buildContext(input) {
50
50
  bytes: Buffer.byteLength(instructionsContent, 'utf8'),
51
51
  });
52
52
  // 3. Safety rules — optional, hashed into the instructions block via
53
- // concatenation when present so consumers can read both as one.
53
+ // concatenation when present so consumers can read both as one.
54
54
  if (input.safetyRules) {
55
55
  const safety = normalizeNewlines(input.safetyRules);
56
56
  blocks.push({
@@ -3,11 +3,11 @@
3
3
  * session's events.jsonl using the shared AuditEvent discriminated union
4
4
  * in `@pugi/sdk/audit-trace.ts`.
5
5
  *
6
- * Until PR #307 these events were written with the ad-hoc shape
6
+ * Until PR these events were written with the ad-hoc shape
7
7
  * `{ id, ts, sessionId, ... }` and the comment in this header claimed
8
8
  * "we keep `session.ts` untouched and write our events through a
9
9
  * dedicated helper that bypasses the AuditEvent schema". The downside,
10
- * caught by Claude review on PR #307, is that every consumer that
10
+ * caught by Claude review on PR, is that every consumer that
11
11
  * calls `auditEventSchema.parse(line)` (cabinet UI, replay tooling,
12
12
  * `core/index-store.ts`) would throw on every compaction event, and
13
13
  * `safeParse` consumers would silently drop them.
@@ -19,12 +19,12 @@
19
19
  *
20
20
  * Events emitted:
21
21
  *
22
- * compaction.started { sessionId, tier, trigger }
23
- * compaction.completed { sessionId, tier, bytesReclaimed,
24
- * newContextSize, artifactsCreated }
25
- * compaction.skipped { sessionId, tier, reason }
26
- * compaction.invariant_violated { sessionId, invariant, evidence,
27
- * artifactRef? }
22
+ * compaction.started { sessionId, tier, trigger }
23
+ * compaction.completed { sessionId, tier, bytesReclaimed,
24
+ * newContextSize, artifactsCreated }
25
+ * compaction.skipped { sessionId, tier, reason }
26
+ * compaction.invariant_violated { sessionId, invariant, evidence,
27
+ * artifactRef? }
28
28
  *
29
29
  * All four are appended in mode 0o600 and respect the
30
30
  * `session.enabled` flag (no-op when `.pugi/` is absent).
@@ -2,42 +2,42 @@
2
2
  * Six-tier context compaction engine for the Pugi CLI agent loop.
3
3
  *
4
4
  * Spec: `docs/research/pugi-cli-corpus/patterns/context-compaction.md`,
5
- * sprint slot: ADR-0056 §α5.5.
5
+ * sprint slot: §.
6
6
  *
7
7
  * Tiers and triggers (selectTier rules):
8
8
  *
9
- * pressure | tier
10
- * --------------+----------------------------------------------------
11
- * < 0.5 | microcompact (only if redundant tool outputs)
12
- * 0.5 .. 0.7 | cached_microcompact
13
- * 0.7 .. 0.85 | reactive_summary
14
- * 0.85 .. 0.95 | full_compaction
15
- * > 0.95 | reset (with checkpoint)
9
+ * pressure | tier
10
+ * --------------+----------------------------------------------------
11
+ * < 0.5 | microcompact (only if redundant tool outputs)
12
+ * 0.5 .. 0.7 | cached_microcompact
13
+ * 0.7 .. 0.85 | reactive_summary
14
+ * 0.85 .. 0.95 | full_compaction
15
+ * > 0.95 | reset (with checkpoint)
16
16
  *
17
17
  * Tier behaviours (per pattern card §3):
18
18
  *
19
- * 1. microcompact — sync; strip redundant token deltas,
20
- * collapse repeated status lines, dedupe
21
- * identical tool argument echoes; keep
22
- * tool RESULTS verbatim; target 10-20%
23
- * 2. cached_microcompact — sync; replace inline tool output with
24
- * { artifactRef, size } when an artifact
25
- * with matching sha256 already exists;
26
- * target 30-50% on repetitive sessions
27
- * 3. reactive_summary — async-shaped; summarize the last N=10
28
- * turns into a structured turn-summary
29
- * artifact; replace those turns with a
30
- * single turn_summary event
31
- * 4. session_memory — async-shaped; distill long-running build
32
- * state into .pugi/session.db (or jsonl
33
- * fallback if SQLite not yet present)
34
- * 5. full_compaction — sync, slow; rebuild from event log +
35
- * artifacts + session_memory + PUGI.md;
36
- * keep open decisions, FSM state, active
37
- * tool calls, last 3 turns verbatim
38
- * 6. reset — manual or >0.95; save full state to
39
- * .pugi/checkpoints/<name>/ and start
40
- * fresh with only PUGI.md + session_memory
19
+ * 1. microcompact — sync; strip redundant token deltas,
20
+ * collapse repeated status lines, dedupe
21
+ * identical tool argument echoes; keep
22
+ * tool RESULTS verbatim; target 10-20%
23
+ * 2. cached_microcompact — sync; replace inline tool output with
24
+ * { artifactRef, size } when an artifact
25
+ * with matching sha256 already exists;
26
+ * target 30-50% on repetitive sessions
27
+ * 3. reactive_summary — async-shaped; summarize the last N=10
28
+ * turns into a structured turn-summary
29
+ * artifact; replace those turns with a
30
+ * single turn_summary event
31
+ * 4. session_memory — async-shaped; distill long-running build
32
+ * state into .pugi/session.db (or jsonl
33
+ * fallback if SQLite not yet present)
34
+ * 5. full_compaction — sync, slow; rebuild from event log +
35
+ * artifacts + session_memory + PUGI.md;
36
+ * keep open decisions, FSM state, active
37
+ * tool calls, last 3 turns verbatim
38
+ * 6. reset — manual or >0.95; save full state to
39
+ * .pugi/checkpoints/<name>/ and start
40
+ * fresh with only PUGI.md + session_memory
41
41
  *
42
42
  * The compaction NEVER touches static blocks. Invariants enforce that
43
43
  * (static-hash-unchanged) plus secrets-never-summarize and
@@ -316,7 +316,7 @@ function tierSessionMemory(input) {
316
316
  const summaryText = JSON.stringify(memory, null, 2);
317
317
  const artifactsCreated = [];
318
318
  if (input.workspaceRoot) {
319
- // SQLite migration arrives in α6.4 (per spec). Until then we append
319
+ // SQLite migration arrives in (per spec). Until then we append
320
320
  // a JSONL line to .pugi/session-memory.jsonl, which the next session
321
321
  // bootstraps into context.
322
322
  const path = resolve(input.workspaceRoot, '.pugi', 'session-memory.jsonl');
@@ -1,16 +1,16 @@
1
1
  /**
2
- * Three-tier context model - α6.5 Phase 1 barrel.
2
+ * Three-tier context model - Phase 1 barrel.
3
3
  *
4
4
  * Bundles the four primitives so the REPL bootstrap can import from a
5
5
  * single path:
6
6
  *
7
- * import {
8
- * loadPugiIgnore,
9
- * buildRepoSkeleton,
10
- * renderSkeleton,
11
- * WorkingSet,
12
- * PugiWatcher,
13
- * } from '../context/index.js';
7
+ * import {
8
+ * loadPugiIgnore,
9
+ * buildRepoSkeleton,
10
+ * renderSkeleton,
11
+ * WorkingSet,
12
+ * PugiWatcher,
13
+ * } from '../context/index.js';
14
14
  *
15
15
  * No new logic lives here - just re-exports.
16
16
  */
@@ -18,4 +18,11 @@ export { BASELINE_IGNORE_PATTERNS, SECRET_IGNORE_PATTERNS, globalPugiIgnorePath,
18
18
  export { COLLAPSE_DIR_ENTRIES, MAX_README_LINES, MAX_SKELETON_BYTES, MAX_TREE_DEPTH, MAX_WALK_NODES, TOP_LANGUAGES, buildRepoSkeleton, detectPackageManager, languageForExtension, readGitBranch, readPackageJson, readReadme, renderSkeleton, topLanguages, } from './repo-skeleton.js';
19
19
  export { DEFAULT_WORKING_SET_CAPACITY, WorkingSet, } from './working-set.js';
20
20
  export { MAX_WATCHED_PATHS, PugiWatcher, THROTTLE_WINDOW_MS, } from './watcher.js';
21
+ /**
22
+ * β5a R4+P5 — per-directory PUGI.md / AGENTS.md / CLAUDE.md / GEMINI.md
23
+ * traverse-up. Loads agent-context markdown at every directory between
24
+ * `cwd` and `workspaceRoot` (workspace root file is owned by
25
+ * `loadMarkdownContext` in `markdown-loader.ts` — no double-load).
26
+ */
27
+ export { MAX_TRAVERSE_BYTES, MAX_TRAVERSE_PER_FILE_BYTES, MAX_TRAVERSE_DEPTH, TRAVERSE_SOURCES, loadTraversedMarkdown, } from './markdown-traverse.js';
21
28
  //# sourceMappingURL=index.js.map
@@ -3,10 +3,10 @@
3
3
  * compaction result is allowed to replace the original transcript.
4
4
  *
5
5
  * Per pattern card §2:
6
- * - principle 4: never summarize secrets into durable memory
7
- * - principle 5: do not erase open decisions
8
- * - principle 6: cache stable prompt parts (static hash must survive
9
- * compaction unchanged)
6
+ * - principle 4: never summarize secrets into durable memory
7
+ * - principle 5: do not erase open decisions
8
+ * - principle 6: cache stable prompt parts (static hash must survive
9
+ * compaction unchanged)
10
10
  *
11
11
  * Plus our own physical-integrity invariant: artifact refs emitted by
12
12
  * the compaction must point to files that exist on disk and match the
@@ -26,12 +26,12 @@ import { existsSync, readFileSync } from 'node:fs';
26
26
  *
27
27
  * Coverage spans two shapes:
28
28
  *
29
- * 1. Cooperative `keyword = value` / `keyword: value` pairs covering
30
- * api_key, access_token, password, client_secret, private_key,
31
- * .env.* etc.
32
- * 2. Provider-specific bare tokens that travel without a keyword:
33
- * Bearer JWTs, AWS access keys, GitHub PATs, Slack tokens, Stripe
34
- * keys, Anthropic/OpenAI keys, and PEM private key blocks.
29
+ * 1. Cooperative `keyword = value` / `keyword: value` pairs covering
30
+ * api_key, access_token, password, client_secret, private_key,
31
+ * .env.* etc.
32
+ * 2. Provider-specific bare tokens that travel without a keyword:
33
+ * Bearer JWTs, AWS access keys, GitHub PATs, Slack tokens, Stripe
34
+ * keys, Anthropic/OpenAI keys, and PEM private key blocks.
35
35
  *
36
36
  * High-entropy base64-shaped blobs after a `:` or `=` are also caught
37
37
  * as a defence in depth — operators who exfiltrate keys via raw JSON
@@ -44,12 +44,12 @@ const SECRET_PATTERNS = [
44
44
  // 1. Keyword=value / keyword: value — the cooperative shape.
45
45
  /(api[_-]?key|access[_-]?token|id[_-]?token|password|passwd|client[_-]?secret|private[_-]?key|\.env\.[A-Z_]+|(?<![a-z])token|(?<![a-z])secret)\s*[:=]\s*\S+/gi,
46
46
  // 2. Authorization: Bearer <jwt-or-opaque-token>. JWTs are eyJ... but
47
- // we accept any non-whitespace token after Bearer so opaque bearer
48
- // tokens are also caught.
47
+ // we accept any non-whitespace token after Bearer so opaque bearer
48
+ // tokens are also caught.
49
49
  /Authorization\s*:\s*Bearer\s+\S+/gi,
50
50
  /\bBearer\s+(?:eyJ[A-Za-z0-9_\-.]{16,}|[A-Za-z0-9_\-.]{20,})/g,
51
51
  // 3. AWS access keys. AKIA prefix is the long-lived IAM key shape;
52
- // aws_access_key_id is the typical .aws/credentials shape.
52
+ // aws_access_key_id is the typical .aws/credentials shape.
53
53
  /\bAKIA[0-9A-Z]{16}\b/g,
54
54
  /aws_access_key_id\s*[:=]\s*\S+/gi,
55
55
  /aws_secret_access_key\s*[:=]\s*\S+/gi,
@@ -65,24 +65,24 @@ const SECRET_PATTERNS = [
65
65
  // 6. Stripe live/test secret keys.
66
66
  /\bsk_(?:live|test)_[A-Za-z0-9]{24,}\b/g,
67
67
  // 7. Anthropic and OpenAI API keys. Anthropic uses sk-ant-<32+chars>;
68
- // OpenAI legacy keys are sk-<40+chars>. Both share the sk- prefix
69
- // so we keep them in their own patterns to avoid catching every
70
- // Stripe sk_ as well (Stripe uses an underscore, not a dash).
68
+ // OpenAI legacy keys are sk-<40+chars>. Both share the sk- prefix
69
+ // so we keep them in their own patterns to avoid catching every
70
+ // Stripe sk_ as well (Stripe uses an underscore, not a dash).
71
71
  /\bsk-ant-[A-Za-z0-9_-]{32,}\b/g,
72
72
  /\bsk-(?!ant-)[A-Za-z0-9]{40,}\b/g,
73
73
  // 8. PEM-encoded private key blocks. Matches RSA / EC / DSA / OPENSSH
74
- // and the bare PRIVATE KEY variant. The body may contain real
75
- // newlines (when scanning raw transcript content) OR literal `\n`
76
- // sequences (when scanning JSON.stringify'd summaries) — both are
77
- // covered by the broad character class.
74
+ // and the bare PRIVATE KEY variant. The body may contain real
75
+ // newlines (when scanning raw transcript content) OR literal `\n`
76
+ // sequences (when scanning JSON.stringify'd summaries) — both are
77
+ // covered by the broad character class.
78
78
  /-----BEGIN (?:RSA |EC |DSA |OPENSSH |ENCRYPTED |)PRIVATE KEY-----[\s\S\\n]*?-----END (?:RSA |EC |DSA |OPENSSH |ENCRYPTED |)PRIVATE KEY-----/g,
79
79
  // 8b. Lone PEM begin/end markers — survive even when the body is too
80
- // long to capture or escaped beyond recognition.
80
+ // long to capture or escaped beyond recognition.
81
81
  /-----BEGIN (?:RSA |EC |DSA |OPENSSH |ENCRYPTED |)PRIVATE KEY-----/g,
82
82
  // 9. High-entropy base64-shaped blobs after a colon or equals. 40+ chars
83
- // of the base64url alphabet is well above the ~6 bytes/char threshold
84
- // where false positives become rare. Word-boundary anchored so prose
85
- // is not swept up.
83
+ // of the base64url alphabet is well above the ~6 bytes/char threshold
84
+ // where false positives become rare. Word-boundary anchored so prose
85
+ // is not swept up.
86
86
  /[:=]\s*"?([A-Za-z0-9_\-+/]{40,}={0,2})"?(?=\s|,|\}|$)/g,
87
87
  ];
88
88
  /**
@@ -97,23 +97,23 @@ const DECISION_RX = /^\s*(?:DECISION|OPEN|BLOCKED|REJECTED):/;
97
97
  * violation must cause the engine to drop the compaction result.
98
98
  *
99
99
  * Inputs:
100
- * - `before`: the compaction input snapshot the caller computed
101
- * - `after`: the compaction result the tier function produced
102
- * - `summaryText`: the concrete prose / structured summary the
103
- * compaction wrote into the dynamic block (or empty string for
104
- * microcompact tiers that only reshape existing content)
105
- * - `staticHashBefore` / `staticHashAfter`: instructions+toolSchema
106
- * hash from the context builder, captured before and after the
107
- * compaction (compaction must never touch static blocks)
100
+ * - `before`: the compaction input snapshot the caller computed
101
+ * - `after`: the compaction result the tier function produced
102
+ * - `summaryText`: the concrete prose / structured summary the
103
+ * compaction wrote into the dynamic block (or empty string for
104
+ * microcompact tiers that only reshape existing content)
105
+ * - `staticHashBefore` / `staticHashAfter`: instructions+toolSchema
106
+ * hash from the context builder, captured before and after the
107
+ * compaction (compaction must never touch static blocks)
108
108
  */
109
109
  export function checkInvariants(args) {
110
110
  const { before, after, summaryText } = args;
111
111
  const violations = [];
112
112
  // 1. secrets-never-summarize — sweep the post-compaction summary text.
113
- // `summaryText` is what gets written to .pugi/session.db / replaces
114
- // the transcript turns. We grep there, not the input, because the
115
- // pre-compaction transcript is the operator's own data; we only
116
- // police what we are about to make durable.
113
+ // `summaryText` is what gets written to .pugi/session.db / replaces
114
+ // the transcript turns. We grep there, not the input, because the
115
+ // pre-compaction transcript is the operator's own data; we only
116
+ // police what we are about to make durable.
117
117
  if (summaryText.length > 0) {
118
118
  const firstMatch = findFirstSecret(summaryText);
119
119
  if (firstMatch !== null) {
@@ -124,10 +124,10 @@ export function checkInvariants(args) {
124
124
  }
125
125
  }
126
126
  // 2. open-decisions-preserved — every DECISION/OPEN/BLOCKED/REJECTED
127
- // line in the pre-compaction transcript must appear verbatim in
128
- // the post-compaction summary OR remain in the after-state's
129
- // `decisionsPreserved`. The compaction result surfaces the latter
130
- // so we cross-check both.
127
+ // line in the pre-compaction transcript must appear verbatim in
128
+ // the post-compaction summary OR remain in the after-state's
129
+ // `decisionsPreserved`. The compaction result surfaces the latter
130
+ // so we cross-check both.
131
131
  const beforeDecisions = [];
132
132
  for (const turn of before.transcript) {
133
133
  for (const line of turn.content.split('\n')) {
@@ -147,17 +147,17 @@ export function checkInvariants(args) {
147
147
  }
148
148
  }
149
149
  // 3. artifact-refs-resolvable — every artifact ref must point to a
150
- // file under .pugi/artifacts/ that exists and SHA256-matches the
151
- // ref. We compute the hash physically rather than trusting the
152
- // bookkeeping; if the disk write was corrupted, we want to know
153
- // before we promote the compaction.
150
+ // file under .pugi/artifacts/ that exists and SHA256-matches the
151
+ // ref. We compute the hash physically rather than trusting the
152
+ // bookkeeping; if the disk write was corrupted, we want to know
153
+ // before we promote the compaction.
154
154
  for (const ref of after.artifactsCreated) {
155
155
  const violation = verifyArtifact(ref);
156
156
  if (violation)
157
157
  violations.push(violation);
158
158
  }
159
159
  // 4. static-hash-unchanged — instructions and tool schema hashes
160
- // must be byte-identical before and after compaction.
160
+ // must be byte-identical before and after compaction.
161
161
  if (args.staticHashBefore.instructionsHash !== args.staticHashAfter.instructionsHash) {
162
162
  violations.push({
163
163
  invariant: 'static-hash-unchanged',
@@ -219,16 +219,16 @@ function findFirstSecret(summaryText) {
219
219
  function redact(input) {
220
220
  // Two shapes to handle:
221
221
  //
222
- // 1. Keyword=value / keyword: value — keep the keyword visible so
223
- // the operator can see which secret leaked, but mask the value.
224
- // 2. Bare token (Bearer ..., AKIA..., PEM block, etc.) — keep the
225
- // first 2 and last 2 chars of the token; mask the middle. PEM
226
- // blocks are dropped entirely except for the BEGIN line.
222
+ // 1. Keyword=value / keyword: value — keep the keyword visible so
223
+ // the operator can see which secret leaked, but mask the value.
224
+ // 2. Bare token (Bearer ..., AKIA..., PEM block, etc.) — keep the
225
+ // first 2 and last 2 chars of the token; mask the middle. PEM
226
+ // blocks are dropped entirely except for the BEGIN line.
227
227
  if (input.startsWith('-----BEGIN')) {
228
228
  // PEM blocks may arrive with real newlines, with escaped `\n`
229
229
  // (JSON-stringified payloads), or with `\r\n` (Windows). Cut on
230
230
  // the BEGIN header end so the body never leaks.
231
- // Codex P1 retro 2026-05-24: matching on `\n` only let the
231
+ // Codex P1 retro: matching on `\n` only let the
232
232
  // escaped-newline case dump the full PEM into invariant evidence.
233
233
  const headerEnd = input.search(/-----(\r?\n|\\r?\\n|$)/);
234
234
  const firstLine = headerEnd > 0 ? input.slice(0, headerEnd + 5) : '-----BEGIN PRIVATE KEY-----';
@@ -6,11 +6,11 @@
6
6
  * context block. They are loaded once per session, deterministically, with
7
7
  * the following safety budget:
8
8
  *
9
- * - max import depth: 3 (deeper chains are skipped, not fatal)
10
- * - max total loaded bytes: 64 KB across PUGI.md + AGENTS.md + all imports
11
- * - HTML comment stripping (`<!-- ... -->`) — comments often carry stale
12
- * annotations that bias the model long after they go out of date
13
- * - workspace containment — `@import ../../../etc/passwd` is rejected
9
+ * - max import depth: 3 (deeper chains are skipped, not fatal)
10
+ * - max total loaded bytes: 64 KB across PUGI.md + AGENTS.md + all imports
11
+ * - HTML comment stripping (`<!-- ... -->`) — comments often carry stale
12
+ * annotations that bias the model long after they go out of date
13
+ * - workspace containment — `@import ../../../etc/passwd` is rejected
14
14
  *
15
15
  * Missing files are not errors. If `PUGI.md` is absent we simply skip it
16
16
  * and report nothing; the engine builds its context from instructions +
@@ -26,22 +26,40 @@ export const MAX_TOTAL_BYTES = 64 * 1024;
26
26
  /**
27
27
  * Source filenames we look for at the workspace root. Order matters:
28
28
  * PUGI.md is the canonical Pugi-native file; AGENTS.md is the
29
- * cross-CLI compatibility shim used by other agentic CLIs.
29
+ * cross-CLI compatibility shim used by other agentic CLIs; CLAUDE.md
30
+ * is the the upstream tool drop-in compat shim —
31
+ * operators migrating from CC routinely keep a workspace-root
32
+ * `CLAUDE.md` documenting project conventions, and we pick it up so
33
+ * Pugi sees the same ambient guidance without a manual rename.
34
+ *
35
+ * All three files are loaded when present (no "first one wins"
36
+ * dropdown). Each entry is HTML-stripped + @import-expanded + capped
37
+ * against the shared 64 KB budget. Pugi's precedence convention is
38
+ * "shown last = highest specificity"; PUGI.md / AGENTS.md / CLAUDE.md
39
+ * each have a stable position in this list so the context builder's
40
+ * render order is deterministic.
30
41
  */
31
- export const MARKDOWN_SOURCES = ['PUGI.md', 'AGENTS.md'];
42
+ export const MARKDOWN_SOURCES = ['PUGI.md', 'AGENTS.md', 'CLAUDE.md'];
32
43
  /**
33
44
  * Load PUGI.md + AGENTS.md from `workspaceRoot`. Either or both may be
34
45
  * absent. Returns the combined load result with per-file detail plus a
35
46
  * flat list of warnings (best-effort: a missing file is a warning, not
36
47
  * an error).
37
48
  */
38
- export async function loadMarkdownContext(workspaceRoot) {
49
+ export async function loadMarkdownContext(workspaceRoot, env = process.env) {
39
50
  const warnings = [];
40
51
  const loaded = [];
41
52
  let budgetRemaining = MAX_TOTAL_BYTES;
42
53
  const visited = new Set();
43
54
  const absRoot = resolve(workspaceRoot);
44
- for (const source of MARKDOWN_SOURCES) {
55
+ // #20 : allow operators to opt OUT of CLAUDE.md
56
+ // ingest via `PUGI_CC_COMPAT_DISABLE=1`. PUGI.md / AGENTS.md remain
57
+ // loaded — they are Pugi-native surfaces, not shims.
58
+ const ccCompatDisabled = env.PUGI_CC_COMPAT_DISABLE === '1';
59
+ const activeSources = ccCompatDisabled
60
+ ? MARKDOWN_SOURCES.filter((s) => s !== 'CLAUDE.md')
61
+ : MARKDOWN_SOURCES;
62
+ for (const source of activeSources) {
45
63
  const candidate = resolve(absRoot, source);
46
64
  if (!existsSync(candidate)) {
47
65
  warnings.push({
@@ -200,7 +218,7 @@ function expandFile(input) {
200
218
  // readFileSync then follows the symlink and inlines arbitrary
201
219
  // contents into the static context. Realpath the target AND the
202
220
  // workspace root so the comparison runs against the physical paths.
203
- // Mirrors the apps/pugi-cli/src/core/trust.ts pattern from PR #305.
221
+ // Mirrors the apps/pugi-cli/src/core/trust.ts pattern from PR.
204
222
  let realTarget;
205
223
  let realRoot;
206
224
  try {