@pugi/cli 0.1.0-beta.10 → 0.1.0-beta.101

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 (464) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/LICENSE +1 -1
  3. package/README.md +55 -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 +598 -0
  45. package/dist/core/codegraph/queries/go.scm +57 -0
  46. package/dist/core/codegraph/queries/javascript.scm +56 -0
  47. package/dist/core/codegraph/queries/python.scm +55 -0
  48. package/dist/core/codegraph/queries/rust.scm +63 -0
  49. package/dist/core/codegraph/queries/typescript.scm +91 -0
  50. package/dist/core/codegraph/reindex.js +218 -0
  51. package/dist/core/codegraph/resolve-edges.js +107 -0
  52. package/dist/core/codegraph/types.js +34 -0
  53. package/dist/core/codegraph/watcher.js +440 -0
  54. package/dist/core/compact/auto-trigger.js +96 -0
  55. package/dist/core/compact/buffer-rewriter.js +115 -0
  56. package/dist/core/compact/summarizer.js +208 -0
  57. package/dist/core/compact/token-counter.js +108 -0
  58. package/dist/core/consensus/anvil-fanout.js +25 -25
  59. package/dist/core/consensus/diff-capture.js +121 -12
  60. package/dist/core/consensus/rubric.js +21 -21
  61. package/dist/core/context/builder.js +6 -6
  62. package/dist/core/context/compaction-events.js +8 -8
  63. package/dist/core/context/compaction.js +31 -31
  64. package/dist/core/context/index.js +15 -8
  65. package/dist/core/context/invariants.js +51 -51
  66. package/dist/core/context/markdown-loader.js +28 -10
  67. package/dist/core/context/markdown-traverse.js +255 -0
  68. package/dist/core/context/pugiignore.js +41 -41
  69. package/dist/core/context/repo-skeleton.js +37 -37
  70. package/dist/core/context/tool-eviction.js +55 -0
  71. package/dist/core/context/watcher.js +32 -32
  72. package/dist/core/context/working-set.js +23 -23
  73. package/dist/core/coordinator/agent-tools.js +77 -0
  74. package/dist/core/coordinator/agent-toolset.js +65 -0
  75. package/dist/core/coordinator/fsm.js +73 -0
  76. package/dist/core/coordinator/mode-fsm.js +70 -0
  77. package/dist/core/cost/rate-card.js +129 -0
  78. package/dist/core/cost/tracker.js +221 -0
  79. package/dist/core/credentials.js +13 -13
  80. package/dist/core/cron/scheduler.js +138 -0
  81. package/dist/core/denial-tracking/index.js +8 -0
  82. package/dist/core/denial-tracking/state.js +264 -0
  83. package/dist/core/diagnostics/probe-runner.js +93 -0
  84. package/dist/core/diagnostics/probes/api.js +46 -0
  85. package/dist/core/diagnostics/probes/auth.js +93 -0
  86. package/dist/core/diagnostics/probes/bare-mode.js +42 -0
  87. package/dist/core/diagnostics/probes/cli-version.js +127 -0
  88. package/dist/core/diagnostics/probes/config.js +72 -0
  89. package/dist/core/diagnostics/probes/denial-tracking.js +57 -0
  90. package/dist/core/diagnostics/probes/disk.js +81 -0
  91. package/dist/core/diagnostics/probes/engine-live.js +46 -0
  92. package/dist/core/diagnostics/probes/git.js +65 -0
  93. package/dist/core/diagnostics/probes/hooks.js +118 -0
  94. package/dist/core/diagnostics/probes/mcp.js +75 -0
  95. package/dist/core/diagnostics/probes/node.js +59 -0
  96. package/dist/core/diagnostics/probes/pnpm.js +36 -0
  97. package/dist/core/diagnostics/probes/pugi-md.js +89 -0
  98. package/dist/core/diagnostics/probes/sandbox.js +67 -0
  99. package/dist/core/diagnostics/probes/session.js +74 -0
  100. package/dist/core/diagnostics/probes/status-snapshot.js +488 -0
  101. package/dist/core/diagnostics/probes/workspace.js +63 -0
  102. package/dist/core/diagnostics/types.js +70 -0
  103. package/dist/core/dispatch/cache-cleanup.js +197 -0
  104. package/dist/core/dispatch/cache-handoff.js +295 -0
  105. package/dist/core/edits/apply-patch-layer-e.js +189 -0
  106. package/dist/core/edits/dispatch.js +333 -7
  107. package/dist/core/edits/format-detector.js +260 -0
  108. package/dist/core/edits/format-matrix.js +26 -0
  109. package/dist/core/edits/fuzzy-ladder.js +650 -0
  110. package/dist/core/edits/index.js +5 -1
  111. package/dist/core/edits/journal.js +199 -0
  112. package/dist/core/edits/layer-a-apply.js +15 -15
  113. package/dist/core/edits/layer-a-fuzzy-apply.js +198 -0
  114. package/dist/core/edits/layer-b-apply.js +9 -9
  115. package/dist/core/edits/layer-c-apply.js +6 -6
  116. package/dist/core/edits/layer-d-ast.js +557 -14
  117. package/dist/core/edits/marker-parser.js +12 -12
  118. package/dist/core/edits/security-gate.js +27 -27
  119. package/dist/core/edits/verify-hook.js +273 -0
  120. package/dist/core/edits/worktree.js +29 -29
  121. package/dist/core/engine/anvil-client.js +214 -26
  122. package/dist/core/engine/auto-compact.js +247 -0
  123. package/dist/core/engine/budgets.js +220 -0
  124. package/dist/core/engine/compact-llm-summarizer.js +124 -0
  125. package/dist/core/engine/context-prefix.js +155 -0
  126. package/dist/core/engine/index.js +1 -1
  127. package/dist/core/engine/intensity.js +163 -0
  128. package/dist/core/engine/intent.js +260 -0
  129. package/dist/core/engine/native-pugi.js +1559 -227
  130. package/dist/core/engine/prompts.js +219 -19
  131. package/dist/core/engine/strip-internal-fields.js +124 -0
  132. package/dist/core/engine/tool-bridge.js +1887 -59
  133. package/dist/core/engine/verification-patterns.js +195 -0
  134. package/dist/core/eval/v1/ledger.js +83 -0
  135. package/dist/core/eval/v1/runner.js +280 -0
  136. package/dist/core/eval/v1/scoring.js +68 -0
  137. package/dist/core/eval/v1/task-loader.js +191 -0
  138. package/dist/core/eval/v1/types.js +14 -0
  139. package/dist/core/eval/v1/verifier.js +176 -0
  140. package/dist/core/eval/v1/yaml-parser.js +250 -0
  141. package/dist/core/evaluation/golden-dataset.js +293 -0
  142. package/dist/core/feedback/queue.js +177 -0
  143. package/dist/core/feedback/submitter.js +145 -0
  144. package/dist/core/file-cache.js +113 -1
  145. package/dist/core/flatten/flatten-repo.js +439 -0
  146. package/dist/core/format/osc8-link.js +28 -0
  147. package/dist/core/hook-chains.js +392 -0
  148. package/dist/core/hooks/citation-verify-hook.js +138 -0
  149. package/dist/core/hooks/citation-verify.js +112 -0
  150. package/dist/core/hooks/events.js +46 -0
  151. package/dist/core/hooks/index.js +15 -0
  152. package/dist/core/hooks/registry.js +216 -0
  153. package/dist/core/hooks/runner.js +236 -0
  154. package/dist/core/hooks/v2/event-emitter.js +115 -0
  155. package/dist/core/hooks/v2/executor.js +282 -0
  156. package/dist/core/hooks/v2/index.js +25 -0
  157. package/dist/core/hooks/v2/lifecycle.js +104 -0
  158. package/dist/core/hooks/v2/loader.js +216 -0
  159. package/dist/core/hooks/v2/matcher.js +125 -0
  160. package/dist/core/hooks/v2/trust.js +143 -0
  161. package/dist/core/hooks/v2/types.js +86 -0
  162. package/dist/core/hooks/worktree-events.js +158 -0
  163. package/dist/core/image/renderer.js +71 -0
  164. package/dist/core/init/detector.js +582 -0
  165. package/dist/core/init/template-renderer.js +242 -0
  166. package/dist/core/jobs/registry.js +18 -18
  167. package/dist/core/ledger/results-tsv.js +142 -0
  168. package/dist/core/log-discipline/stdout-redirect.js +51 -0
  169. package/dist/core/lsp/cache.js +105 -0
  170. package/dist/core/lsp/client.js +551 -41
  171. package/dist/core/lsp/language-detect.js +66 -0
  172. package/dist/core/lsp/post-edit-diagnostics.js +171 -0
  173. package/dist/core/lsp/server-detect.js +173 -0
  174. package/dist/core/lsp/symbol-cache.js +162 -0
  175. package/dist/core/lsp/symbol-tools.js +664 -0
  176. package/dist/core/mcp/client.js +97 -28
  177. package/dist/core/mcp/http-server.js +553 -0
  178. package/dist/core/mcp/orchestrator-config.js +192 -0
  179. package/dist/core/mcp/orchestrator-tools.js +806 -0
  180. package/dist/core/mcp/permission.js +190 -0
  181. package/dist/core/mcp/registry.js +39 -17
  182. package/dist/core/mcp/server-tools.js +219 -0
  183. package/dist/core/mcp/server.js +397 -0
  184. package/dist/core/mcp/trust.js +10 -10
  185. package/dist/core/memory/dual-write.js +416 -0
  186. package/dist/core/memory/passive-extract.js +130 -0
  187. package/dist/core/memory/phase1-kinds.js +20 -0
  188. package/dist/core/memory/secret-scanner.js +304 -0
  189. package/dist/core/memory-sync/queue.js +170 -0
  190. package/dist/core/metrics/extract.js +113 -0
  191. package/dist/core/modes/roo-modes.js +68 -0
  192. package/dist/core/notes/notes-paths.js +113 -0
  193. package/dist/core/notes/notes-recorder.js +140 -0
  194. package/dist/core/notes/notes-writer.js +53 -0
  195. package/dist/core/notes/renderers.js +0 -0
  196. package/dist/core/notes/slug.js +105 -0
  197. package/dist/core/onboarding/ensure-initialized.js +133 -0
  198. package/dist/core/onboarding/marker.js +111 -0
  199. package/dist/core/onboarding/telemetry-state.js +108 -0
  200. package/dist/core/output-style/presets.js +176 -0
  201. package/dist/core/output-style/state.js +185 -0
  202. package/dist/core/path-security.js +287 -5
  203. package/dist/core/permission.js +82 -22
  204. package/dist/core/permissions/auto-classifier.js +124 -0
  205. package/dist/core/permissions/bash-parser.js +371 -0
  206. package/dist/core/permissions/circuit-breaker.js +83 -0
  207. package/dist/core/permissions/constrained-edit.js +91 -0
  208. package/dist/core/permissions/gate.js +278 -0
  209. package/dist/core/permissions/index.js +20 -0
  210. package/dist/core/permissions/mode.js +174 -0
  211. package/dist/core/permissions/network-egress.js +137 -0
  212. package/dist/core/permissions/state.js +241 -0
  213. package/dist/core/permissions/tool-class.js +107 -0
  214. package/dist/core/plan-mode/ui-state.js +51 -0
  215. package/dist/core/plans/plan-artifact.js +721 -0
  216. package/dist/core/policy-limits/etag-store.js +122 -0
  217. package/dist/core/prd-check/parser.js +215 -0
  218. package/dist/core/prd-check/reporter.js +127 -0
  219. package/dist/core/prd-check/session-review.js +557 -0
  220. package/dist/core/prd-check/verifiers.js +223 -0
  221. package/dist/core/prompt-cache/client-cache.js +99 -0
  222. package/dist/core/prompts/assembly.js +29 -0
  223. package/dist/core/prompts/registry.js +364 -0
  224. package/dist/core/pugi-gitignore.js +52 -0
  225. package/dist/core/pugi-md/cc-compat-rules.js +735 -0
  226. package/dist/core/pugi-md/context-injector.js +76 -0
  227. package/dist/core/pugi-md/walk-up.js +207 -0
  228. package/dist/core/python/uv-installer.js +270 -0
  229. package/dist/core/python/uv-resolver.js +83 -0
  230. package/dist/core/rate-limit/narrator.js +146 -0
  231. package/dist/core/recipes/cli-types.js +20 -0
  232. package/dist/core/recipes/loader.js +103 -0
  233. package/dist/core/recipes/runner.js +345 -0
  234. package/dist/core/recipes/schema.js +587 -0
  235. package/dist/core/release-notes/parser.js +241 -0
  236. package/dist/core/release-notes/state.js +116 -0
  237. package/dist/core/repl/ask.js +37 -37
  238. package/dist/core/repl/cancellation.js +26 -26
  239. package/dist/core/repl/cap-warning.js +4 -4
  240. package/dist/core/repl/clipboard-read.js +11 -11
  241. package/dist/core/repl/dispatch-fsm.js +12 -12
  242. package/dist/core/repl/engine-bridge.js +303 -0
  243. package/dist/core/repl/history-search.js +15 -15
  244. package/dist/core/repl/history.js +28 -18
  245. package/dist/core/repl/kill-ring.js +5 -5
  246. package/dist/core/repl/model-pricing.js +135 -0
  247. package/dist/core/repl/privacy-banner.js +22 -22
  248. package/dist/core/repl/session.js +2690 -229
  249. package/dist/core/repl/slash-commands.js +540 -41
  250. package/dist/core/repl/store/index.js +1 -1
  251. package/dist/core/repl/store/jsonl-log.js +22 -22
  252. package/dist/core/repl/store/lockfile.js +10 -10
  253. package/dist/core/repl/store/session-store.js +136 -107
  254. package/dist/core/repl/store/types.js +15 -15
  255. package/dist/core/repl/store/uuid-v7.js +12 -12
  256. package/dist/core/repl/tool-route.js +382 -0
  257. package/dist/core/repl/workspace-context.js +43 -21
  258. package/dist/core/repo-map/build.js +125 -0
  259. package/dist/core/repo-map/cache.js +185 -0
  260. package/dist/core/repo-map/extractor.js +254 -0
  261. package/dist/core/repo-map/formatter.js +145 -0
  262. package/dist/core/repo-map/page-rank.js +105 -0
  263. package/dist/core/repo-map/scanner.js +211 -0
  264. package/dist/core/retro/git-collector.js +251 -0
  265. package/dist/core/retro/health-card.js +25 -0
  266. package/dist/core/retro/metrics.js +342 -0
  267. package/dist/core/retro/narrative.js +249 -0
  268. package/dist/core/retro/plane-collector.js +274 -0
  269. package/dist/core/retro/pr-issue-link.js +65 -0
  270. package/dist/core/retro/types.js +16 -0
  271. package/dist/core/retry-budget/budget.js +284 -0
  272. package/dist/core/retry-budget/index.js +5 -0
  273. package/dist/core/retry-budget/retry-cap.js +74 -0
  274. package/dist/core/routing/lead-worker.js +43 -0
  275. package/dist/core/routing/pre-flight-estimator.js +108 -0
  276. package/dist/core/runs/run-tree.js +103 -0
  277. package/dist/core/sandboxing/adapter.js +43 -0
  278. package/dist/core/sandboxing/bubblewrap.js +209 -0
  279. package/dist/core/sandboxing/index.js +78 -0
  280. package/dist/core/sandboxing/none.js +19 -0
  281. package/dist/core/sandboxing/policy.js +97 -0
  282. package/dist/core/sandboxing/seatbelt.js +231 -0
  283. package/dist/core/security/injection-scanner.js +367 -0
  284. package/dist/core/security/output-filter.js +418 -0
  285. package/dist/core/session/env-file.js +105 -0
  286. package/dist/core/session/section-budgets.js +140 -0
  287. package/dist/core/session.js +119 -0
  288. package/dist/core/settings.js +402 -5
  289. package/dist/core/share/formatter.js +271 -0
  290. package/dist/core/share/redactor.js +221 -0
  291. package/dist/core/share/uploader.js +267 -0
  292. package/dist/core/skills/defaults.js +30 -30
  293. package/dist/core/skills/loader.js +22 -22
  294. package/dist/core/skills/sources.js +27 -27
  295. package/dist/core/smoke/headless-driver.js +174 -0
  296. package/dist/core/smoke/orchestrator.js +194 -0
  297. package/dist/core/smoke/runner.js +238 -0
  298. package/dist/core/smoke/scenario-parser.js +316 -0
  299. package/dist/core/statusline.js +99 -0
  300. package/dist/core/subagents/dispatcher-real.js +600 -0
  301. package/dist/core/subagents/dispatcher.js +146 -52
  302. package/dist/core/subagents/index.js +19 -6
  303. package/dist/core/subagents/isolation-matrix.js +213 -0
  304. package/dist/core/subagents/spawn.js +19 -4
  305. package/dist/core/telemetry/emitter.js +229 -0
  306. package/dist/core/telemetry/queue.js +251 -0
  307. package/dist/core/theme/context.js +91 -0
  308. package/dist/core/theme/presets.js +228 -0
  309. package/dist/core/theme/state.js +181 -0
  310. package/dist/core/todos/invariant.js +10 -0
  311. package/dist/core/todos/state.js +177 -0
  312. package/dist/core/tool-schema/compressor.js +89 -0
  313. package/dist/core/transport/version-interceptor.js +166 -0
  314. package/dist/core/trust.js +2 -2
  315. package/dist/core/tui/thinking-block.js +64 -0
  316. package/dist/core/vim/keymap.js +288 -0
  317. package/dist/core/vim/state.js +92 -0
  318. package/dist/core/watch-markers/marker-watcher.js +133 -0
  319. package/dist/core/worktree/include-parser.js +249 -0
  320. package/dist/core/worktree-manager/cleanup.js +123 -0
  321. package/dist/core/worktree-manager/manager.js +303 -0
  322. package/dist/index.js +36 -0
  323. package/dist/runtime/bootstrap.js +190 -0
  324. package/dist/runtime/cli.js +4403 -561
  325. package/dist/runtime/commands/agents.js +31 -31
  326. package/dist/runtime/commands/budget.js +5 -5
  327. package/dist/runtime/commands/cancel.js +231 -0
  328. package/dist/runtime/commands/chain.js +489 -0
  329. package/dist/runtime/commands/codegraph-status.js +227 -0
  330. package/dist/runtime/commands/compact.js +297 -0
  331. package/dist/runtime/commands/config.js +74 -40
  332. package/dist/runtime/commands/cost.js +199 -0
  333. package/dist/runtime/commands/delegate.js +27 -4
  334. package/dist/runtime/commands/dispatch.js +126 -0
  335. package/dist/runtime/commands/doctor.js +579 -0
  336. package/dist/runtime/commands/eval-v1.js +266 -0
  337. package/dist/runtime/commands/feedback.js +184 -0
  338. package/dist/runtime/commands/hooks.js +187 -0
  339. package/dist/runtime/commands/index-cmd.js +459 -0
  340. package/dist/runtime/commands/init.js +254 -0
  341. package/dist/runtime/commands/lsp.js +200 -38
  342. package/dist/runtime/commands/mcp.js +935 -0
  343. package/dist/runtime/commands/memory.js +582 -0
  344. package/dist/runtime/commands/model.js +237 -0
  345. package/dist/runtime/commands/onboarding.js +275 -0
  346. package/dist/runtime/commands/patch.js +12 -12
  347. package/dist/runtime/commands/permissions.js +112 -0
  348. package/dist/runtime/commands/plan.js +143 -0
  349. package/dist/runtime/commands/prd-check.js +285 -0
  350. package/dist/runtime/commands/privacy.js +17 -17
  351. package/dist/runtime/commands/recipe.js +325 -0
  352. package/dist/runtime/commands/redo-blob-store.js +92 -0
  353. package/dist/runtime/commands/redo.js +361 -0
  354. package/dist/runtime/commands/release-notes.js +229 -0
  355. package/dist/runtime/commands/repo-map.js +95 -0
  356. package/dist/runtime/commands/report.js +299 -0
  357. package/dist/runtime/commands/resume.js +118 -0
  358. package/dist/runtime/commands/review-consensus.js +68 -53
  359. package/dist/runtime/commands/rewind.js +333 -0
  360. package/dist/runtime/commands/roster.js +14 -14
  361. package/dist/runtime/commands/servers-cli.js +182 -0
  362. package/dist/runtime/commands/servers.js +236 -0
  363. package/dist/runtime/commands/sessions.js +163 -0
  364. package/dist/runtime/commands/share.js +316 -0
  365. package/dist/runtime/commands/skills.js +31 -31
  366. package/dist/runtime/commands/status.js +186 -0
  367. package/dist/runtime/commands/stickers.js +82 -0
  368. package/dist/runtime/commands/style.js +194 -0
  369. package/dist/runtime/commands/theme.js +196 -0
  370. package/dist/runtime/commands/undo.js +54 -22
  371. package/dist/runtime/commands/update.js +289 -0
  372. package/dist/runtime/commands/vim.js +140 -0
  373. package/dist/runtime/commands/worktree.js +8 -8
  374. package/dist/runtime/commands/worktrees.js +155 -0
  375. package/dist/runtime/deprecation-warning.js +69 -0
  376. package/dist/runtime/engine-exit-code.js +50 -0
  377. package/dist/runtime/headless-repl.js +195 -0
  378. package/dist/runtime/headless.js +548 -0
  379. package/dist/runtime/load-hooks-or-exit.js +71 -0
  380. package/dist/runtime/plan-decompose.js +22 -22
  381. package/dist/runtime/sigint-guard.js +272 -0
  382. package/dist/runtime/stream-renderer.js +195 -0
  383. package/dist/runtime/update-check.js +28 -28
  384. package/dist/runtime/version.js +65 -0
  385. package/dist/runtime/worktree-bootstrap.js +579 -0
  386. package/dist/skills/bundled/batch.js +617 -0
  387. package/dist/skills/bundled/index.js +45 -0
  388. package/dist/skills/bundled/loop.js +358 -0
  389. package/dist/skills/bundled/remember.js +383 -0
  390. package/dist/skills/bundled/simplify.js +289 -0
  391. package/dist/skills/bundled/skillify.js +373 -0
  392. package/dist/skills/bundled/stuck.js +558 -0
  393. package/dist/skills/bundled/verify.js +439 -0
  394. package/dist/testing/vcr.js +486 -0
  395. package/dist/tools/agent-tool.js +229 -0
  396. package/dist/tools/apply-patch.js +89 -28
  397. package/dist/tools/ask-user-question.js +337 -0
  398. package/dist/tools/ask-user.js +115 -0
  399. package/dist/tools/bash.js +811 -49
  400. package/dist/tools/brief.js +224 -0
  401. package/dist/tools/cron.js +433 -0
  402. package/dist/tools/enter-worktree.js +250 -0
  403. package/dist/tools/exit-worktree.js +147 -0
  404. package/dist/tools/file-tools.js +161 -44
  405. package/dist/tools/http-request.js +336 -0
  406. package/dist/tools/lsp-tools.js +377 -1
  407. package/dist/tools/mcp-tool.js +260 -0
  408. package/dist/tools/multi-edit.js +361 -0
  409. package/dist/tools/powershell.js +268 -0
  410. package/dist/tools/registry.js +120 -5
  411. package/dist/tools/server-tools.js +892 -0
  412. package/dist/tools/skill-tool.js +96 -0
  413. package/dist/tools/sleep.js +99 -0
  414. package/dist/tools/synthetic-output.js +133 -0
  415. package/dist/tools/tasks.js +208 -0
  416. package/dist/tools/todo-write.js +184 -0
  417. package/dist/tools/verify-plan-execution.js +295 -0
  418. package/dist/tools/web-fetch-injection-scanner.js +207 -0
  419. package/dist/tools/web-fetch.js +195 -10
  420. package/dist/tools/web-search.js +458 -0
  421. package/dist/tui/agent-progress-card.js +111 -0
  422. package/dist/tui/agent-tree.js +22 -1
  423. package/dist/tui/ask-modal.js +14 -14
  424. package/dist/tui/ask-user-question-chips.js +315 -0
  425. package/dist/tui/ask-user-question-prompt.js +203 -0
  426. package/dist/tui/compact-banner.js +81 -0
  427. package/dist/tui/conversation-pane.js +85 -11
  428. package/dist/tui/cost-table.js +111 -0
  429. package/dist/tui/device-flow.js +2 -2
  430. package/dist/tui/doctor-table.js +46 -0
  431. package/dist/tui/feedback-prompt.js +156 -0
  432. package/dist/tui/input-box.js +247 -32
  433. package/dist/tui/login-picker.js +3 -3
  434. package/dist/tui/markdown-render.js +6 -6
  435. package/dist/tui/multi-file-diff-approval.js +375 -0
  436. package/dist/tui/onboarding-wizard.js +240 -0
  437. package/dist/tui/permissions-picker.js +86 -0
  438. package/dist/tui/render.js +36 -1
  439. package/dist/tui/repl-render.js +239 -25
  440. package/dist/tui/repl-splash-art.js +16 -16
  441. package/dist/tui/repl-splash-mascot.js +48 -24
  442. package/dist/tui/repl-splash.js +22 -22
  443. package/dist/tui/repl.js +125 -45
  444. package/dist/tui/slash-palette.js +6 -6
  445. package/dist/tui/splash.js +2 -2
  446. package/dist/tui/status-bar.js +109 -31
  447. package/dist/tui/status-table.js +7 -0
  448. package/dist/tui/stickers-art.js +136 -0
  449. package/dist/tui/style-table.js +28 -0
  450. package/dist/tui/theme-table.js +29 -0
  451. package/dist/tui/thinking-spinner.js +123 -0
  452. package/dist/tui/tool-stream-pane.js +53 -4
  453. package/dist/tui/update-banner.js +27 -2
  454. package/dist/tui/vim-input.js +267 -0
  455. package/dist/tui/welcome-banner.js +107 -0
  456. package/dist/tui/welcome-data.js +293 -0
  457. package/dist/tui/workspace-context.js +2 -2
  458. package/package.json +29 -6
  459. package/test/scenarios/codegen-create-file.scenario.txt +13 -0
  460. package/test/scenarios/compact-force.scenario.txt +12 -0
  461. package/test/scenarios/identity.scenario.txt +11 -0
  462. package/test/scenarios/persona-handoff.scenario.txt +12 -0
  463. package/test/scenarios/walkback.scenario.txt +12 -0
  464. package/dist/core/engine/compaction-hook.js +0 -154
@@ -0,0 +1,108 @@
1
+ /**
2
+ * — Telemetry consent state.
3
+ *
4
+ * The onboarding wizard's Step 5 asks the operator for telemetry
5
+ * consent. We persist the verdict in the user-tier
6
+ * `~/.pugi/config.json::telemetry` field so a future REPL boot can
7
+ * read it without re-asking. Choices mirror `core/settings.ts`'s
8
+ * `privacy.telemetry` enum:
9
+ *
10
+ * - `off` — no telemetry of any kind (default).
11
+ * - `anonymous` — counts + error categories only, no payloads.
12
+ * - `community` — anonymous + opt-in skill/usage panels.
13
+ *
14
+ * This module is intentionally narrow: it only owns the `telemetry`
15
+ * key inside `~/.pugi/config.json`. The full settings parsing lives in
16
+ * `core/settings.ts` (workspace-tier `.pugi/settings.json`); we do NOT
17
+ * route through it here because:
18
+ *
19
+ * 1. The settings schema is workspace-scoped — its file path is
20
+ * `<root>/.pugi/settings.json`, not `~/.pugi/config.json`.
21
+ * 2. The wizard records a user-level default that workspace settings
22
+ * can later override. Mixing the two would conflate scope.
23
+ * 3. Read-modify-write on a partial JSON file is the same pattern
24
+ * L6 / L18 use for adjacent keys — keeping it self-contained
25
+ * preserves the "one module, one key" invariant.
26
+ */
27
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, } from 'node:fs';
28
+ import { homedir } from 'node:os';
29
+ import { dirname, resolve } from 'node:path';
30
+ import { PUGI_HOME_ENV } from './marker.js';
31
+ export const TELEMETRY_CHOICES = Object.freeze([
32
+ 'off',
33
+ 'anonymous',
34
+ 'community',
35
+ ]);
36
+ export const DEFAULT_TELEMETRY = 'off';
37
+ /**
38
+ * Path to the user-tier config. Mirrors `userConfigPath()` from L18
39
+ * `output-style/state.ts` — duplicated here (not imported) to keep the
40
+ * marker + telemetry module self-contained. Any future drift between
41
+ * the two would surface a spec failure: both modules read the same
42
+ * file in the spec sandbox.
43
+ */
44
+ export function telemetryConfigPath(env = process.env) {
45
+ const home = env[PUGI_HOME_ENV] ?? resolve(homedir(), '.pugi');
46
+ return resolve(home, 'config.json');
47
+ }
48
+ /**
49
+ * Type guard for arbitrary string input (CLI argv, config.json
50
+ * deserialisation). Returns false for any non-string or out-of-set
51
+ * value so a malformed config degrades to the default verdict.
52
+ */
53
+ export function isTelemetryChoice(value) {
54
+ return (typeof value === 'string'
55
+ && TELEMETRY_CHOICES.includes(value));
56
+ }
57
+ /**
58
+ * Read the persisted telemetry verdict. Returns the default (`'off'`)
59
+ * when the file is absent, empty, malformed, or holds an unknown
60
+ * value. Never throws — the wizard re-asks every time it runs, so a
61
+ * defensive read is the right posture.
62
+ */
63
+ export function readTelemetryChoice(io = {}) {
64
+ const config = readConfigFile(telemetryConfigPath(io.env ?? process.env));
65
+ return isTelemetryChoice(config.telemetry) ? config.telemetry : DEFAULT_TELEMETRY;
66
+ }
67
+ /**
68
+ * Persist the telemetry verdict. Read-modify-write preserves any
69
+ * neighbouring keys (`outputStyle`, `defaultPermissionMode`, …) the
70
+ * other tier-state modules own.
71
+ */
72
+ export function writeTelemetryChoice(choice, io = {}) {
73
+ const path = telemetryConfigPath(io.env ?? process.env);
74
+ const config = readConfigFile(path);
75
+ config.telemetry = choice;
76
+ writeConfigFile(path, config);
77
+ }
78
+ function readConfigFile(path) {
79
+ if (!existsSync(path))
80
+ return {};
81
+ let raw;
82
+ try {
83
+ raw = readFileSync(path, 'utf8');
84
+ }
85
+ catch {
86
+ return {};
87
+ }
88
+ if (raw.trim().length === 0)
89
+ return {};
90
+ let parsed;
91
+ try {
92
+ parsed = JSON.parse(raw);
93
+ }
94
+ catch {
95
+ return {};
96
+ }
97
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
98
+ return {};
99
+ return parsed;
100
+ }
101
+ function writeConfigFile(path, config) {
102
+ mkdirSync(dirname(path), { recursive: true });
103
+ writeFileSync(path, `${JSON.stringify(config, null, 2)}\n`, {
104
+ encoding: 'utf8',
105
+ mode: 0o600,
106
+ });
107
+ }
108
+ //# sourceMappingURL=telemetry-state.js.map
@@ -0,0 +1,176 @@
1
+ /**
2
+ * — Output-style presets.
3
+ *
4
+ * Mirror of the upstream tool's `/output-style` surface: a small closed set of
5
+ * named voice presets the operator can flip between at session start so
6
+ * the model's prose lands in the register they prefer. The preset
7
+ * compiles into an `<output-style>` rule block appended to the engine
8
+ * system prompt; tool-use / code-block formatting / file edits are NOT
9
+ * affected — the preset only steers prose register.
10
+ *
11
+ * Design contract:
12
+ *
13
+ * - The catalogue is intentionally tiny (5 entries) so the operator
14
+ * can hold the full surface in working memory. Adding entries means
15
+ * adding a row in `OUTPUT_STYLES` plus a spec assertion; there is
16
+ * no plugin surface today.
17
+ *
18
+ * - `default` is the only preset that emits NO rule block. The
19
+ * "current Pugi voice" already lives in the base engine prompt
20
+ * (jargon ban, brand voice, terse register), so re-stating it
21
+ * under `<output-style>` would double the model's instruction load
22
+ * for the most-common case. Other presets emit the block.
23
+ *
24
+ * - Rule-block prose stays terse and operator-grade (brandbook §08).
25
+ * No friendly hedging, no AI-assistant framing. The bullets are
26
+ * the model's contract; the section title carries the preset name
27
+ * so the model can self-correct mid-turn if it drifts ("I am in
28
+ * terse mode → drop articles").
29
+ *
30
+ * - The Russian-formal preset uses вы-form explicitly. Russian/
31
+ * Ukrainian chat is permitted by the base voice contract; this
32
+ * preset hardens the register for B2B / enterprise demo flows
33
+ * where ты-form reads as too casual.
34
+ *
35
+ * - The Casual preset RELAXES the jargon ban — contractions, jokes,
36
+ * informal phrasing are allowed. It does NOT lift the brand-voice
37
+ * em-dash / emoji ban; those are typographic, not register, and
38
+ * remain off across every preset.
39
+ *
40
+ * Test surface: `test/commands/output-style-presets.spec.ts` exercises
41
+ * the catalogue invariants (5 entries, unique slugs, every non-default
42
+ * preset emits a non-empty block, the block starts with the expected
43
+ * marker so the engine prompt appender can locate it for stripping).
44
+ */
45
+ /**
46
+ * The closed list of preset slugs in catalogue order. Mirror used by
47
+ * the CLI surface (`/style` table, `pugi style --list`) so the
48
+ * operator sees presets in a stable order regardless of catalogue
49
+ * iteration order.
50
+ */
51
+ export const OUTPUT_STYLE_SLUGS = Object.freeze([
52
+ 'default',
53
+ 'terse',
54
+ 'explanatory',
55
+ 'russian-formal',
56
+ 'casual',
57
+ ]);
58
+ /**
59
+ * Default slug used when no workspace-/user-level preference is set.
60
+ * Exported so `state.ts` and the CLI handler share one constant.
61
+ */
62
+ export const DEFAULT_OUTPUT_STYLE = 'default';
63
+ /**
64
+ * Catalogue keyed by slug. Frozen so callers cannot mutate the
65
+ * shared rows; the CLI handler returns slugs, not preset references,
66
+ * to keep the boundary clean.
67
+ */
68
+ export const OUTPUT_STYLES = Object.freeze({
69
+ default: Object.freeze({
70
+ slug: 'default',
71
+ title: 'Default',
72
+ gloss: 'Current Pugi voice (no override). Base engine prompt rules apply unchanged.',
73
+ rules: Object.freeze([]),
74
+ }),
75
+ terse: Object.freeze({
76
+ slug: 'terse',
77
+ title: 'Terse',
78
+ gloss: 'Fragments, dropped articles, one short sentence per turn.',
79
+ rules: Object.freeze([
80
+ 'Drop articles, fillers, hedging',
81
+ '1 short sentence per turn for prose answers',
82
+ 'Code blocks unchanged — never abbreviate code',
83
+ 'Quote errors verbatim with no paraphrase',
84
+ ]),
85
+ }),
86
+ explanatory: Object.freeze({
87
+ slug: 'explanatory',
88
+ title: 'Explanatory',
89
+ gloss: 'Verbose, walks reasoning step by step, links concepts.',
90
+ rules: Object.freeze([
91
+ 'Explain reasoning, not just the conclusion',
92
+ 'Cite relevant files + line numbers when grounding claims',
93
+ 'Link adjacent concepts the operator may want to chase',
94
+ 'Code blocks unchanged — annotate around, not inside',
95
+ ]),
96
+ }),
97
+ 'russian-formal': Object.freeze({
98
+ slug: 'russian-formal',
99
+ title: 'Russian formal',
100
+ gloss: 'Russian вы-form, professional register, no slang.',
101
+ rules: Object.freeze([
102
+ 'Pisat\' otvety po-russki (Russian prose; ASCII transliteration permitted in this rule block only)',
103
+ 'Address the operator using вы-form, never ты',
104
+ 'No slang, no contractions of Russian forms',
105
+ 'Code blocks + identifiers stay in English unchanged',
106
+ 'Error messages quoted verbatim in the original language',
107
+ ]),
108
+ }),
109
+ casual: Object.freeze({
110
+ slug: 'casual',
111
+ title: 'Casual',
112
+ gloss: 'Informal register, contractions OK, dry jokes welcome.',
113
+ rules: Object.freeze([
114
+ 'Contractions allowed (it\'s, don\'t, you\'re)',
115
+ 'Dry, deadpan jokes welcome when they do not displace signal',
116
+ 'No em-dashes, no emoji — typographic rules unchanged',
117
+ 'Stay terse — casual is register, not verbosity',
118
+ ]),
119
+ }),
120
+ });
121
+ /**
122
+ * Type-narrowing predicate. Used by the slash-command parser + state
123
+ * loader so an unknown string from operator input or a stale config
124
+ * file degrades to the default preset instead of crashing.
125
+ */
126
+ export function isOutputStyleSlug(value) {
127
+ return (typeof value === 'string'
128
+ && OUTPUT_STYLE_SLUGS.includes(value));
129
+ }
130
+ /**
131
+ * Compile a preset into the `<output-style>` rule block injected at
132
+ * the tail of the engine system prompt.
133
+ *
134
+ * Returns empty string when the preset is `default` (or any preset
135
+ * with an empty rules array). Empty string is a load-bearing signal —
136
+ * the engine prompt appender uses it to skip injection entirely so
137
+ * the model sees a clean prompt for the default register.
138
+ *
139
+ * The block opens with `<output-style>` and closes with `</output-style>`
140
+ * (XML-shaped marker, matching the engine prompt's existing `<intent>`
141
+ * grammar). The `Active style:` line gives the model a self-correction
142
+ * anchor when it drifts mid-turn.
143
+ */
144
+ export function compileStyleBlock(slug) {
145
+ const preset = OUTPUT_STYLES[slug];
146
+ if (preset.rules.length === 0)
147
+ return '';
148
+ const lines = [];
149
+ lines.push('<output-style>');
150
+ lines.push(` Active style: ${preset.slug}`);
151
+ for (const rule of preset.rules) {
152
+ lines.push(` - ${rule}`);
153
+ }
154
+ lines.push('</output-style>');
155
+ return lines.join('\n');
156
+ }
157
+ /**
158
+ * Render the preset catalogue as a plain-text table for the `/style`
159
+ * + `pugi style` surfaces. Marks the active slug with `*` so the
160
+ * operator can see at a glance which preset is in effect.
161
+ *
162
+ * Pure renderer (no fs, no env). Identical text is emitted from both
163
+ * the slash dispatcher and the top-level CLI command so operators
164
+ * trained on one surface read the same table on the other.
165
+ */
166
+ export function renderStyleTable(active) {
167
+ const slugWidth = Math.max('NAME'.length, ...OUTPUT_STYLE_SLUGS.map((slug) => slug.length));
168
+ const header = `${'NAME'.padEnd(slugWidth)} GLOSS`;
169
+ const rows = OUTPUT_STYLE_SLUGS.map((slug) => {
170
+ const preset = OUTPUT_STYLES[slug];
171
+ const marker = slug === active ? '*' : ' ';
172
+ return `${marker} ${slug.padEnd(slugWidth)} ${preset.gloss}`;
173
+ });
174
+ return [header, ...rows].join('\n');
175
+ }
176
+ //# sourceMappingURL=presets.js.map
@@ -0,0 +1,185 @@
1
+ /**
2
+ * — Output-style state persistence.
3
+ *
4
+ * Two-tier storage:
5
+ *
6
+ * 1. **Workspace** — `<workspaceRoot>/.pugi/config.json`. Set by
7
+ * `/style <name>` from inside the REPL or `pugi style <name>`
8
+ * without `--persist`. Overrides the user default for the
9
+ * current workspace only. Survives sessions because the same
10
+ * `.pugi/` survives sessions.
11
+ *
12
+ * 2. **User default** — `~/.pugi/config.json` (PUGI_HOME-aware).
13
+ * Set by `pugi style <name> --persist` or
14
+ * `/style <name> --persist`. Applies to every workspace that
15
+ * has no workspace-level override.
16
+ *
17
+ * Precedence (highest → lowest):
18
+ *
19
+ * workspace value > user value > DEFAULT_OUTPUT_STYLE ('default')
20
+ *
21
+ * Both files live under the same `pugi-config-v1` JSON envelope as
22
+ * other settings (permissionMode, privacy, model, preferredEndpoint).
23
+ * The schema is intentionally NOT shared with `runtime/commands/config.ts`'s
24
+ * strict Zod schema — `outputStyle` is read/written ONLY through this
25
+ * module so `pugi config set outputStyle=…` is NOT a supported path
26
+ * (it would silently bypass the slug validator). Operators get a
27
+ * single surface: `/style` + `pugi style`.
28
+ *
29
+ * File layout (one config.json, multiple keys; this module owns the
30
+ * `outputStyle` key only):
31
+ *
32
+ * {
33
+ * "permissionMode": "ask",
34
+ * "outputStyle": "terse",
35
+ * ...
36
+ * }
37
+ *
38
+ * The reader tolerates:
39
+ * - missing file (returns the default slug),
40
+ * - empty file (returns the default slug),
41
+ * - malformed JSON (returns the default slug — DO NOT crash REPL
42
+ * boot because of a hand-edited config),
43
+ * - unknown slug (returns the default slug + emits no error; the
44
+ * operator can `/style` to see the table and re-set).
45
+ *
46
+ * The writer is a read-modify-write to preserve neighbouring keys
47
+ * (permissionMode etc.) — overwriting the whole file would clobber
48
+ * the other tier's settings.
49
+ *
50
+ * Test surface: `test/commands/output-style-state.spec.ts` exercises
51
+ * precedence, malformed-config tolerance, persistence across reads,
52
+ * the `--persist` (user-default) path, and reset semantics.
53
+ */
54
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, } from 'node:fs';
55
+ import { homedir } from 'node:os';
56
+ import { dirname, resolve } from 'node:path';
57
+ import { DEFAULT_OUTPUT_STYLE, isOutputStyleSlug, } from './presets.js';
58
+ /**
59
+ * Env override for `~/.pugi` so the spec can sandbox both tiers
60
+ * without touching the developer's real config. Matches the existing
61
+ * `runtime/commands/config.ts` convention.
62
+ */
63
+ export const PUGI_HOME_ENV = 'PUGI_HOME';
64
+ /**
65
+ * Resolve the active output style for the workspace, applying the
66
+ * precedence ladder (workspace > user > default).
67
+ *
68
+ * Pure read. Never writes, never throws — every IO failure degrades
69
+ * to the default slug. The function returns the source label too so
70
+ * the CLI surface can show the operator where the value came from.
71
+ */
72
+ export function resolveOutputStyle(io) {
73
+ const workspaceSlug = readSlugFromFile(workspaceConfigPath(io.workspaceRoot));
74
+ if (workspaceSlug)
75
+ return { slug: workspaceSlug, source: 'workspace' };
76
+ const userSlug = readSlugFromFile(userConfigPath(io.env ?? process.env));
77
+ if (userSlug)
78
+ return { slug: userSlug, source: 'user' };
79
+ return { slug: DEFAULT_OUTPUT_STYLE, source: 'default' };
80
+ }
81
+ /**
82
+ * Write `slug` to the workspace tier. Creates `<workspaceRoot>/.pugi/`
83
+ * if missing. Preserves neighbouring config keys via read-modify-write.
84
+ */
85
+ export function setWorkspaceOutputStyle(slug, io) {
86
+ writeSlugToFile(workspaceConfigPath(io.workspaceRoot), slug);
87
+ }
88
+ /**
89
+ * Write `slug` to the user tier (`~/.pugi/config.json`).
90
+ *
91
+ * Mirrors the workspace writer's read-modify-write so the user's
92
+ * `permissionMode` / `privacy` / `model` keys survive a style flip.
93
+ */
94
+ export function setUserOutputStyle(slug, io) {
95
+ writeSlugToFile(userConfigPath(io.env ?? process.env), slug);
96
+ }
97
+ /**
98
+ * Clear the workspace tier's `outputStyle` key. The user tier (and
99
+ * therefore the eventual resolved style) is left untouched.
100
+ *
101
+ * Used by `/style --reset` so the operator can revert a workspace
102
+ * override without nuking the rest of their workspace config.
103
+ */
104
+ export function clearWorkspaceOutputStyle(io) {
105
+ clearSlugInFile(workspaceConfigPath(io.workspaceRoot));
106
+ }
107
+ /**
108
+ * Clear the user tier's `outputStyle` key. Lower-blast-radius reset
109
+ * for operators who want every workspace to fall back to `default`
110
+ * unless an explicit workspace value is set.
111
+ */
112
+ export function clearUserOutputStyle(io) {
113
+ clearSlugInFile(userConfigPath(io.env ?? process.env));
114
+ }
115
+ /**
116
+ * Workspace config path. Exported for the spec; production callers
117
+ * should use the `setWorkspace…` / `resolveOutputStyle` helpers.
118
+ */
119
+ export function workspaceConfigPath(workspaceRoot) {
120
+ return resolve(workspaceRoot, '.pugi', 'config.json');
121
+ }
122
+ /**
123
+ * User config path resolved against `PUGI_HOME` (or `~/.pugi`).
124
+ * Exported for the spec.
125
+ */
126
+ export function userConfigPath(env = process.env) {
127
+ const home = env[PUGI_HOME_ENV] ?? resolve(homedir(), '.pugi');
128
+ return resolve(home, 'config.json');
129
+ }
130
+ /**
131
+ * Read + parse a config file. Returns an empty object on any IO or
132
+ * parse error. Caller-provided JSON must be a plain object; arrays /
133
+ * scalars / null are treated as "no config" so a hand-edited file
134
+ * never crashes the REPL.
135
+ */
136
+ function readConfigFile(path) {
137
+ if (!existsSync(path))
138
+ return {};
139
+ let raw;
140
+ try {
141
+ raw = readFileSync(path, 'utf8');
142
+ }
143
+ catch {
144
+ return {};
145
+ }
146
+ if (raw.trim().length === 0)
147
+ return {};
148
+ let parsed;
149
+ try {
150
+ parsed = JSON.parse(raw);
151
+ }
152
+ catch {
153
+ return {};
154
+ }
155
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
156
+ return {};
157
+ return parsed;
158
+ }
159
+ function writeConfigFile(path, config) {
160
+ mkdirSync(dirname(path), { recursive: true });
161
+ // 0o600 mirrors `runtime/commands/config.ts` — the config file may
162
+ // hold `preferredEndpoint` URLs that should not be world-readable.
163
+ writeFileSync(path, `${JSON.stringify(config, null, 2)}\n`, {
164
+ encoding: 'utf8',
165
+ mode: 0o600,
166
+ });
167
+ }
168
+ function readSlugFromFile(path) {
169
+ const config = readConfigFile(path);
170
+ const candidate = config.outputStyle;
171
+ return isOutputStyleSlug(candidate) ? candidate : null;
172
+ }
173
+ function writeSlugToFile(path, slug) {
174
+ const config = readConfigFile(path);
175
+ config.outputStyle = slug;
176
+ writeConfigFile(path, config);
177
+ }
178
+ function clearSlugInFile(path) {
179
+ const config = readConfigFile(path);
180
+ if (!('outputStyle' in config))
181
+ return;
182
+ delete config.outputStyle;
183
+ writeConfigFile(path, config);
184
+ }
185
+ //# sourceMappingURL=state.js.map