@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.
- package/LICENSE +1 -1
- package/README.md +11 -191
- package/bin/pugi +8 -0
- package/package.json +15 -71
- package/postinstall.mjs +31 -0
- package/CHANGELOG.md +0 -132
- package/THIRD_PARTY_NOTICES.md +0 -40
- package/assets/pugi-mascot.ansi +0 -16
- package/assets/pugi-prozr2-mascot.ansi +0 -9
- package/bin/run.js +0 -34
- package/dist/commands/deploy.js +0 -439
- package/dist/commands/flatten.js +0 -191
- package/dist/commands/jobs-watch.js +0 -201
- package/dist/commands/jobs.js +0 -260
- package/dist/commands/retro.js +0 -210
- package/dist/commands/smoke.js +0 -133
- package/dist/core/agent-progress/cleanup.js +0 -134
- package/dist/core/agent-progress/schema.js +0 -144
- package/dist/core/agent-progress/writer.js +0 -101
- package/dist/core/agents/adaptive-router.js +0 -330
- package/dist/core/agents/loader.js +0 -104
- package/dist/core/agents/query-decomposer.js +0 -297
- package/dist/core/agents/registry.js +0 -69
- package/dist/core/approvals/shortcut-resolver.js +0 -98
- package/dist/core/artifact-chain/dispatcher.js +0 -148
- package/dist/core/artifact-chain/exporter.js +0 -164
- package/dist/core/artifact-chain/state.js +0 -243
- package/dist/core/artifact-chain/steps.js +0 -169
- package/dist/core/ask-user/question.js +0 -92
- package/dist/core/audit/audit-trail.js +0 -275
- package/dist/core/auth/ensure-authenticated.js +0 -129
- package/dist/core/auth/env-provider.js +0 -238
- package/dist/core/auto-open-browser.js +0 -128
- package/dist/core/auto-update/channels.js +0 -122
- package/dist/core/auto-update/checker.js +0 -241
- package/dist/core/auto-update/state.js +0 -235
- package/dist/core/bare-mode/index.js +0 -107
- package/dist/core/bash/redirect.js +0 -281
- package/dist/core/bash-classifier.js +0 -1397
- package/dist/core/checkpoint/resumer.js +0 -149
- package/dist/core/checkpoint/rewinder.js +0 -291
- package/dist/core/checkpoints/shadow-git.js +0 -670
- package/dist/core/citations/parser.js +0 -109
- package/dist/core/classifier/yolo-classifier.js +0 -88
- package/dist/core/clipboard.js +0 -70
- package/dist/core/codegraph/decision-store.js +0 -248
- package/dist/core/codegraph/detect-repo.js +0 -459
- package/dist/core/codegraph/install.js +0 -134
- package/dist/core/codegraph/offer-hook.js +0 -220
- package/dist/core/compact/auto-trigger.js +0 -96
- package/dist/core/compact/buffer-rewriter.js +0 -115
- package/dist/core/compact/summarizer.js +0 -208
- package/dist/core/compact/token-counter.js +0 -108
- package/dist/core/consensus/anvil-fanout.js +0 -276
- package/dist/core/consensus/diff-capture.js +0 -491
- package/dist/core/consensus/rubric.js +0 -233
- package/dist/core/context/builder.js +0 -114
- package/dist/core/context/compaction-events.js +0 -99
- package/dist/core/context/compaction.js +0 -602
- package/dist/core/context/index.js +0 -28
- package/dist/core/context/invariants.js +0 -250
- package/dist/core/context/markdown-loader.js +0 -288
- package/dist/core/context/markdown-traverse.js +0 -255
- package/dist/core/context/pugiignore.js +0 -316
- package/dist/core/context/repo-skeleton.js +0 -533
- package/dist/core/context/tool-eviction.js +0 -55
- package/dist/core/context/watcher.js +0 -342
- package/dist/core/context/working-set.js +0 -165
- package/dist/core/coordinator/agent-tools.js +0 -77
- package/dist/core/coordinator/agent-toolset.js +0 -65
- package/dist/core/coordinator/fsm.js +0 -73
- package/dist/core/coordinator/mode-fsm.js +0 -70
- package/dist/core/cost/rate-card.js +0 -129
- package/dist/core/cost/tracker.js +0 -221
- package/dist/core/credentials.js +0 -355
- package/dist/core/cron/scheduler.js +0 -138
- package/dist/core/denial-tracking/index.js +0 -8
- package/dist/core/denial-tracking/state.js +0 -264
- package/dist/core/diagnostics/probe-runner.js +0 -93
- package/dist/core/diagnostics/probes/api.js +0 -46
- package/dist/core/diagnostics/probes/auth.js +0 -93
- package/dist/core/diagnostics/probes/bare-mode.js +0 -42
- package/dist/core/diagnostics/probes/cli-version.js +0 -127
- package/dist/core/diagnostics/probes/config.js +0 -72
- package/dist/core/diagnostics/probes/denial-tracking.js +0 -57
- package/dist/core/diagnostics/probes/disk.js +0 -81
- package/dist/core/diagnostics/probes/engine-live.js +0 -46
- package/dist/core/diagnostics/probes/git.js +0 -65
- package/dist/core/diagnostics/probes/hooks.js +0 -118
- package/dist/core/diagnostics/probes/mcp.js +0 -75
- package/dist/core/diagnostics/probes/node.js +0 -59
- package/dist/core/diagnostics/probes/pnpm.js +0 -36
- package/dist/core/diagnostics/probes/pugi-md.js +0 -89
- package/dist/core/diagnostics/probes/sandbox.js +0 -72
- package/dist/core/diagnostics/probes/session.js +0 -74
- package/dist/core/diagnostics/probes/status-snapshot.js +0 -488
- package/dist/core/diagnostics/probes/workspace.js +0 -63
- package/dist/core/diagnostics/types.js +0 -70
- package/dist/core/dispatch/cache-cleanup.js +0 -197
- package/dist/core/dispatch/cache-handoff.js +0 -295
- package/dist/core/edits/apply-patch-layer-e.js +0 -189
- package/dist/core/edits/dispatch.js +0 -511
- package/dist/core/edits/format-detector.js +0 -260
- package/dist/core/edits/format-matrix.js +0 -26
- package/dist/core/edits/fuzzy-ladder.js +0 -650
- package/dist/core/edits/index.js +0 -19
- package/dist/core/edits/journal.js +0 -199
- package/dist/core/edits/layer-a-apply.js +0 -217
- package/dist/core/edits/layer-a-fuzzy-apply.js +0 -198
- package/dist/core/edits/layer-b-apply.js +0 -211
- package/dist/core/edits/layer-c-apply.js +0 -160
- package/dist/core/edits/layer-d-ast.js +0 -572
- package/dist/core/edits/marker-parser.js +0 -401
- package/dist/core/edits/security-gate.js +0 -223
- package/dist/core/edits/verify-hook.js +0 -273
- package/dist/core/edits/worktree.js +0 -322
- package/dist/core/engine/adapter-runner.js +0 -8
- package/dist/core/engine/anvil-client.js +0 -344
- package/dist/core/engine/auto-compact.js +0 -179
- package/dist/core/engine/budgets.js +0 -195
- package/dist/core/engine/context-prefix.js +0 -155
- package/dist/core/engine/index.js +0 -12
- package/dist/core/engine/intensity.js +0 -163
- package/dist/core/engine/intent.js +0 -260
- package/dist/core/engine/native-pugi.js +0 -1616
- package/dist/core/engine/noop.js +0 -27
- package/dist/core/engine/prompts.js +0 -236
- package/dist/core/engine/strip-internal-fields.js +0 -124
- package/dist/core/engine/tool-bridge.js +0 -2173
- package/dist/core/engine/verification-patterns.js +0 -195
- package/dist/core/evaluation/golden-dataset.js +0 -293
- package/dist/core/feedback/queue.js +0 -177
- package/dist/core/feedback/submitter.js +0 -145
- package/dist/core/file-cache.js +0 -141
- package/dist/core/flatten/flatten-repo.js +0 -439
- package/dist/core/format/osc8-link.js +0 -28
- package/dist/core/hook-chains.js +0 -392
- package/dist/core/hooks/citation-verify-hook.js +0 -138
- package/dist/core/hooks/citation-verify.js +0 -112
- package/dist/core/hooks/events.js +0 -46
- package/dist/core/hooks/index.js +0 -15
- package/dist/core/hooks/registry.js +0 -216
- package/dist/core/hooks/runner.js +0 -236
- package/dist/core/hooks/v2/event-emitter.js +0 -115
- package/dist/core/hooks/v2/executor.js +0 -282
- package/dist/core/hooks/v2/index.js +0 -25
- package/dist/core/hooks/v2/lifecycle.js +0 -104
- package/dist/core/hooks/v2/loader.js +0 -216
- package/dist/core/hooks/v2/matcher.js +0 -125
- package/dist/core/hooks/v2/trust.js +0 -143
- package/dist/core/hooks/v2/types.js +0 -86
- package/dist/core/hooks/worktree-events.js +0 -158
- package/dist/core/hooks.js +0 -415
- package/dist/core/image/renderer.js +0 -71
- package/dist/core/index-store.js +0 -260
- package/dist/core/init/detector.js +0 -582
- package/dist/core/init/template-renderer.js +0 -242
- package/dist/core/jobs/registry.js +0 -462
- package/dist/core/ledger/results-tsv.js +0 -142
- package/dist/core/log-discipline/stdout-redirect.js +0 -51
- package/dist/core/lsp/cache.js +0 -105
- package/dist/core/lsp/client.js +0 -1229
- package/dist/core/lsp/language-detect.js +0 -66
- package/dist/core/lsp/post-edit-diagnostics.js +0 -171
- package/dist/core/lsp/server-detect.js +0 -173
- package/dist/core/lsp/symbol-cache.js +0 -162
- package/dist/core/lsp/symbol-tools.js +0 -664
- package/dist/core/mcp/client.js +0 -385
- package/dist/core/mcp/http-server.js +0 -553
- package/dist/core/mcp/orchestrator-config.js +0 -192
- package/dist/core/mcp/orchestrator-tools.js +0 -806
- package/dist/core/mcp/permission.js +0 -190
- package/dist/core/mcp/registry.js +0 -193
- package/dist/core/mcp/server-tools.js +0 -219
- package/dist/core/mcp/server.js +0 -397
- package/dist/core/mcp/trust.js +0 -91
- package/dist/core/memory/dual-write.js +0 -416
- package/dist/core/memory/passive-extract.js +0 -130
- package/dist/core/memory/phase1-kinds.js +0 -20
- package/dist/core/memory/secret-scanner.js +0 -304
- package/dist/core/memory-sync/queue.js +0 -170
- package/dist/core/metrics/extract.js +0 -113
- package/dist/core/modes/roo-modes.js +0 -68
- package/dist/core/onboarding/ensure-initialized.js +0 -133
- package/dist/core/onboarding/marker.js +0 -111
- package/dist/core/onboarding/telemetry-state.js +0 -108
- package/dist/core/output-style/presets.js +0 -176
- package/dist/core/output-style/state.js +0 -185
- package/dist/core/path-security.js +0 -345
- package/dist/core/permission.js +0 -369
- package/dist/core/permissions/auto-classifier.js +0 -124
- package/dist/core/permissions/bash-parser.js +0 -371
- package/dist/core/permissions/circuit-breaker.js +0 -83
- package/dist/core/permissions/constrained-edit.js +0 -91
- package/dist/core/permissions/gate.js +0 -278
- package/dist/core/permissions/index.js +0 -20
- package/dist/core/permissions/mode.js +0 -174
- package/dist/core/permissions/network-egress.js +0 -137
- package/dist/core/permissions/state.js +0 -241
- package/dist/core/permissions/tool-class.js +0 -107
- package/dist/core/plan-mode/ui-state.js +0 -51
- package/dist/core/plans/plan-artifact.js +0 -721
- package/dist/core/policy-limits/etag-store.js +0 -122
- package/dist/core/prd-check/parser.js +0 -215
- package/dist/core/prd-check/reporter.js +0 -127
- package/dist/core/prd-check/session-review.js +0 -557
- package/dist/core/prd-check/verifiers.js +0 -223
- package/dist/core/prompt-cache/client-cache.js +0 -99
- package/dist/core/prompts/assembly.js +0 -29
- package/dist/core/prompts/registry.js +0 -364
- package/dist/core/pugi-gitignore.js +0 -52
- package/dist/core/pugi-md/cc-compat-rules.js +0 -735
- package/dist/core/pugi-md/context-injector.js +0 -76
- package/dist/core/pugi-md/walk-up.js +0 -207
- package/dist/core/python/uv-installer.js +0 -270
- package/dist/core/python/uv-resolver.js +0 -83
- package/dist/core/rate-limit/narrator.js +0 -146
- package/dist/core/recipes/cli-types.js +0 -20
- package/dist/core/recipes/loader.js +0 -103
- package/dist/core/recipes/runner.js +0 -345
- package/dist/core/recipes/schema.js +0 -587
- package/dist/core/release-notes/parser.js +0 -241
- package/dist/core/release-notes/state.js +0 -116
- package/dist/core/repl/ask.js +0 -512
- package/dist/core/repl/cancellation.js +0 -98
- package/dist/core/repl/cap-warning.js +0 -91
- package/dist/core/repl/clipboard-read.js +0 -174
- package/dist/core/repl/dispatch-fsm.js +0 -220
- package/dist/core/repl/engine-bridge.js +0 -303
- package/dist/core/repl/history-search.js +0 -175
- package/dist/core/repl/history.js +0 -182
- package/dist/core/repl/kill-ring.js +0 -138
- package/dist/core/repl/model-pricing.js +0 -135
- package/dist/core/repl/privacy-banner.js +0 -71
- package/dist/core/repl/session.js +0 -4962
- package/dist/core/repl/slash-commands.js +0 -747
- package/dist/core/repl/store/index.js +0 -12
- package/dist/core/repl/store/jsonl-log.js +0 -321
- package/dist/core/repl/store/lockfile.js +0 -155
- package/dist/core/repl/store/session-store.js +0 -821
- package/dist/core/repl/store/types.js +0 -44
- package/dist/core/repl/store/uuid-v7.js +0 -68
- package/dist/core/repl/tool-route.js +0 -382
- package/dist/core/repl/workspace-context.js +0 -206
- package/dist/core/repo-map/build.js +0 -125
- package/dist/core/repo-map/cache.js +0 -185
- package/dist/core/repo-map/extractor.js +0 -254
- package/dist/core/repo-map/formatter.js +0 -145
- package/dist/core/repo-map/page-rank.js +0 -105
- package/dist/core/repo-map/scanner.js +0 -211
- package/dist/core/retro/git-collector.js +0 -251
- package/dist/core/retro/health-card.js +0 -25
- package/dist/core/retro/metrics.js +0 -342
- package/dist/core/retro/narrative.js +0 -249
- package/dist/core/retro/plane-collector.js +0 -274
- package/dist/core/retro/pr-issue-link.js +0 -65
- package/dist/core/retro/types.js +0 -16
- package/dist/core/retry-budget/budget.js +0 -284
- package/dist/core/retry-budget/index.js +0 -5
- package/dist/core/retry-budget/retry-cap.js +0 -74
- package/dist/core/routing/lead-worker.js +0 -43
- package/dist/core/routing/pre-flight-estimator.js +0 -108
- package/dist/core/runs/run-tree.js +0 -103
- package/dist/core/sandboxing/adapter.js +0 -29
- package/dist/core/sandboxing/index.js +0 -49
- package/dist/core/sandboxing/none.js +0 -19
- package/dist/core/sandboxing/seatbelt.js +0 -183
- package/dist/core/security/injection-scanner.js +0 -367
- package/dist/core/security/output-filter.js +0 -418
- package/dist/core/session/env-file.js +0 -105
- package/dist/core/session/section-budgets.js +0 -140
- package/dist/core/session.js +0 -377
- package/dist/core/settings.js +0 -400
- package/dist/core/share/formatter.js +0 -271
- package/dist/core/share/redactor.js +0 -221
- package/dist/core/share/uploader.js +0 -267
- package/dist/core/skills/defaults.js +0 -457
- package/dist/core/skills/loader.js +0 -454
- package/dist/core/skills/sources.js +0 -480
- package/dist/core/skills/trust.js +0 -172
- package/dist/core/smoke/headless-driver.js +0 -174
- package/dist/core/smoke/orchestrator.js +0 -194
- package/dist/core/smoke/runner.js +0 -238
- package/dist/core/smoke/scenario-parser.js +0 -316
- package/dist/core/statusline.js +0 -99
- package/dist/core/subagents/dispatcher-real.js +0 -600
- package/dist/core/subagents/dispatcher.js +0 -352
- package/dist/core/subagents/index.js +0 -39
- package/dist/core/subagents/isolation-matrix.js +0 -213
- package/dist/core/subagents/spawn.js +0 -101
- package/dist/core/telemetry/emitter.js +0 -229
- package/dist/core/telemetry/queue.js +0 -251
- package/dist/core/theme/context.js +0 -91
- package/dist/core/theme/presets.js +0 -228
- package/dist/core/theme/state.js +0 -181
- package/dist/core/todos/invariant.js +0 -10
- package/dist/core/todos/state.js +0 -177
- package/dist/core/tool-schema/compressor.js +0 -89
- package/dist/core/transport/version-interceptor.js +0 -166
- package/dist/core/trust.js +0 -109
- package/dist/core/tui/thinking-block.js +0 -64
- package/dist/core/vim/keymap.js +0 -288
- package/dist/core/vim/state.js +0 -92
- package/dist/core/watch-markers/marker-watcher.js +0 -133
- package/dist/core/worktree/include-parser.js +0 -249
- package/dist/core/worktree-manager/cleanup.js +0 -123
- package/dist/core/worktree-manager/manager.js +0 -303
- package/dist/index.js +0 -44
- package/dist/runtime/bootstrap.js +0 -190
- package/dist/runtime/cli.js +0 -8121
- package/dist/runtime/commands/agents.js +0 -385
- package/dist/runtime/commands/budget.js +0 -192
- package/dist/runtime/commands/cancel.js +0 -231
- package/dist/runtime/commands/chain.js +0 -489
- package/dist/runtime/commands/codegraph-status.js +0 -227
- package/dist/runtime/commands/compact.js +0 -297
- package/dist/runtime/commands/config.js +0 -595
- package/dist/runtime/commands/cost.js +0 -199
- package/dist/runtime/commands/delegate.js +0 -312
- package/dist/runtime/commands/dispatch.js +0 -126
- package/dist/runtime/commands/doctor.js +0 -579
- package/dist/runtime/commands/feedback.js +0 -184
- package/dist/runtime/commands/hooks.js +0 -187
- package/dist/runtime/commands/init.js +0 -254
- package/dist/runtime/commands/lsp.js +0 -368
- package/dist/runtime/commands/mcp.js +0 -935
- package/dist/runtime/commands/memory.js +0 -582
- package/dist/runtime/commands/model.js +0 -237
- package/dist/runtime/commands/onboarding.js +0 -275
- package/dist/runtime/commands/patch.js +0 -128
- package/dist/runtime/commands/permissions.js +0 -112
- package/dist/runtime/commands/plan.js +0 -143
- package/dist/runtime/commands/prd-check.js +0 -285
- package/dist/runtime/commands/privacy.js +0 -107
- package/dist/runtime/commands/recipe.js +0 -325
- package/dist/runtime/commands/redo-blob-store.js +0 -92
- package/dist/runtime/commands/redo.js +0 -361
- package/dist/runtime/commands/release-notes.js +0 -229
- package/dist/runtime/commands/repo-map.js +0 -95
- package/dist/runtime/commands/report.js +0 -299
- package/dist/runtime/commands/resume.js +0 -118
- package/dist/runtime/commands/review-consensus.js +0 -414
- package/dist/runtime/commands/rewind.js +0 -333
- package/dist/runtime/commands/roster.js +0 -117
- package/dist/runtime/commands/sessions.js +0 -163
- package/dist/runtime/commands/share.js +0 -316
- package/dist/runtime/commands/skills.js +0 -401
- package/dist/runtime/commands/status.js +0 -186
- package/dist/runtime/commands/stickers.js +0 -82
- package/dist/runtime/commands/style.js +0 -194
- package/dist/runtime/commands/theme.js +0 -196
- package/dist/runtime/commands/undo.js +0 -361
- package/dist/runtime/commands/update.js +0 -289
- package/dist/runtime/commands/vim.js +0 -140
- package/dist/runtime/commands/worktree.js +0 -177
- package/dist/runtime/commands/worktrees.js +0 -155
- package/dist/runtime/deprecation-warning.js +0 -69
- package/dist/runtime/engine-exit-code.js +0 -50
- package/dist/runtime/headless-repl.js +0 -195
- package/dist/runtime/headless.js +0 -548
- package/dist/runtime/load-hooks-or-exit.js +0 -71
- package/dist/runtime/plan-decompose.js +0 -531
- package/dist/runtime/sigint-guard.js +0 -272
- package/dist/runtime/stream-renderer.js +0 -195
- package/dist/runtime/update-check.js +0 -294
- package/dist/runtime/version.js +0 -65
- package/dist/runtime/worktree-bootstrap.js +0 -579
- package/dist/skills/bundled/batch.js +0 -617
- package/dist/skills/bundled/index.js +0 -45
- package/dist/skills/bundled/loop.js +0 -358
- package/dist/skills/bundled/remember.js +0 -383
- package/dist/skills/bundled/simplify.js +0 -289
- package/dist/skills/bundled/skillify.js +0 -373
- package/dist/skills/bundled/stuck.js +0 -558
- package/dist/skills/bundled/verify.js +0 -439
- package/dist/testing/vcr.js +0 -486
- package/dist/tools/agent-tool.js +0 -229
- package/dist/tools/apply-patch.js +0 -556
- package/dist/tools/ask-user-question.js +0 -337
- package/dist/tools/ask-user.js +0 -115
- package/dist/tools/bash.js +0 -1238
- package/dist/tools/brief.js +0 -224
- package/dist/tools/cron.js +0 -433
- package/dist/tools/enter-worktree.js +0 -250
- package/dist/tools/exit-worktree.js +0 -147
- package/dist/tools/file-tools.js +0 -553
- package/dist/tools/http-request.js +0 -336
- package/dist/tools/lsp-tools.js +0 -565
- package/dist/tools/mcp-tool.js +0 -260
- package/dist/tools/multi-edit.js +0 -361
- package/dist/tools/powershell.js +0 -268
- package/dist/tools/registry.js +0 -166
- package/dist/tools/server-tools.js +0 -892
- package/dist/tools/skill-tool.js +0 -96
- package/dist/tools/sleep.js +0 -99
- package/dist/tools/synthetic-output.js +0 -133
- package/dist/tools/tasks.js +0 -208
- package/dist/tools/todo-write.js +0 -184
- package/dist/tools/verify-plan-execution.js +0 -295
- package/dist/tools/web-fetch-injection-scanner.js +0 -207
- package/dist/tools/web-fetch.js +0 -720
- package/dist/tools/web-search.js +0 -458
- package/dist/tui/agent-progress-card.js +0 -111
- package/dist/tui/agent-tree-pane.js +0 -9
- package/dist/tui/agent-tree.js +0 -87
- package/dist/tui/ask-cli.js +0 -52
- package/dist/tui/ask-modal.js +0 -211
- package/dist/tui/ask-user-question-chips.js +0 -315
- package/dist/tui/ask-user-question-prompt.js +0 -203
- package/dist/tui/compact-banner.js +0 -81
- package/dist/tui/conversation-pane.js +0 -164
- package/dist/tui/cost-table.js +0 -111
- package/dist/tui/device-flow.js +0 -142
- package/dist/tui/doctor-table.js +0 -46
- package/dist/tui/feedback-prompt.js +0 -156
- package/dist/tui/input-box.js +0 -732
- package/dist/tui/login-picker.js +0 -69
- package/dist/tui/markdown-render.js +0 -266
- package/dist/tui/multi-file-diff-approval.js +0 -375
- package/dist/tui/onboarding-wizard.js +0 -240
- package/dist/tui/permissions-picker.js +0 -86
- package/dist/tui/render.js +0 -160
- package/dist/tui/repl-render.js +0 -770
- package/dist/tui/repl-splash-art.js +0 -64
- package/dist/tui/repl-splash-mascot.js +0 -154
- package/dist/tui/repl-splash.js +0 -117
- package/dist/tui/repl.js +0 -378
- package/dist/tui/slash-palette.js +0 -106
- package/dist/tui/splash-data.js +0 -61
- package/dist/tui/splash.js +0 -31
- package/dist/tui/status-bar.js +0 -209
- package/dist/tui/status-table.js +0 -7
- package/dist/tui/stickers-art.js +0 -136
- package/dist/tui/style-table.js +0 -28
- package/dist/tui/theme-table.js +0 -29
- package/dist/tui/thinking-spinner.js +0 -123
- package/dist/tui/tool-stream-pane.js +0 -140
- package/dist/tui/update-banner.js +0 -33
- package/dist/tui/vim-input.js +0 -267
- package/dist/tui/welcome-banner.js +0 -107
- package/dist/tui/welcome-data.js +0 -293
- package/dist/tui/workspace-context.js +0 -105
- package/docs/examples/codegraph.mcp.json +0 -10
- package/test/scenarios/codegen-create-file.scenario.txt +0 -13
- package/test/scenarios/compact-force.scenario.txt +0 -12
- package/test/scenarios/identity.scenario.txt +0 -11
- package/test/scenarios/persona-handoff.scenario.txt +0 -12
- package/test/scenarios/walkback.scenario.txt +0 -12
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { promises as fs } from 'node:fs';
|
|
2
|
-
import * as path from 'node:path';
|
|
3
|
-
const EXT_GROUP = 'ts|tsx|js|jsx|md|json|sh|py|yaml|yml';
|
|
4
|
-
const BRACKET_RE = new RegExp(String.raw `\[([^\]\s]+\.(?:` + EXT_GROUP + String.raw `)):(\d+)(?:-(\d+))?\]`, 'g');
|
|
5
|
-
const PAREN_RE = new RegExp(String.raw `\(([^()\s]+\.(?:` + EXT_GROUP + String.raw `)):(\d+)(?:-(\d+))?\)`, 'g');
|
|
6
|
-
function collect(text, re, out) {
|
|
7
|
-
re.lastIndex = 0;
|
|
8
|
-
let match;
|
|
9
|
-
while ((match = re.exec(text)) !== null) {
|
|
10
|
-
const raw = match[0];
|
|
11
|
-
const filePath = match[1];
|
|
12
|
-
const lineStr = match[2];
|
|
13
|
-
const endStr = match[3];
|
|
14
|
-
if (filePath === undefined || lineStr === undefined)
|
|
15
|
-
continue;
|
|
16
|
-
const line = Number.parseInt(lineStr, 10);
|
|
17
|
-
if (!Number.isFinite(line))
|
|
18
|
-
continue;
|
|
19
|
-
const citation = {
|
|
20
|
-
raw,
|
|
21
|
-
path: filePath,
|
|
22
|
-
line,
|
|
23
|
-
startOffset: match.index,
|
|
24
|
-
endOffset: match.index + raw.length,
|
|
25
|
-
};
|
|
26
|
-
if (endStr !== undefined) {
|
|
27
|
-
const endLine = Number.parseInt(endStr, 10);
|
|
28
|
-
if (Number.isFinite(endLine))
|
|
29
|
-
citation.endLine = endLine;
|
|
30
|
-
}
|
|
31
|
-
out.push(citation);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
export function parseCitations(text) {
|
|
35
|
-
const out = [];
|
|
36
|
-
collect(text, BRACKET_RE, out);
|
|
37
|
-
collect(text, PAREN_RE, out);
|
|
38
|
-
out.sort((a, b) => a.startOffset - b.startOffset);
|
|
39
|
-
return out;
|
|
40
|
-
}
|
|
41
|
-
function isTraversal(rawPath) {
|
|
42
|
-
if (path.isAbsolute(rawPath))
|
|
43
|
-
return true;
|
|
44
|
-
const segments = rawPath.split(/[/\\]+/);
|
|
45
|
-
return segments.includes('..');
|
|
46
|
-
}
|
|
47
|
-
function countLines(content) {
|
|
48
|
-
if (content.length === 0)
|
|
49
|
-
return 0;
|
|
50
|
-
const matches = content.match(/\n/g);
|
|
51
|
-
const nl = matches === null ? 0 : matches.length;
|
|
52
|
-
return content.endsWith('\n') ? nl : nl + 1;
|
|
53
|
-
}
|
|
54
|
-
export async function validateCitations(citations, workspaceRoot) {
|
|
55
|
-
const rootReal = await fs.realpath(workspaceRoot);
|
|
56
|
-
const results = [];
|
|
57
|
-
for (const citation of citations) {
|
|
58
|
-
if (isTraversal(citation.path)) {
|
|
59
|
-
results.push({ citation, valid: false, reason: 'path-traversal' });
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
const resolved = path.resolve(rootReal, citation.path);
|
|
63
|
-
let realResolved;
|
|
64
|
-
try {
|
|
65
|
-
realResolved = await fs.realpath(resolved);
|
|
66
|
-
}
|
|
67
|
-
catch {
|
|
68
|
-
results.push({ citation, valid: false, reason: 'file-missing' });
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
const rel = path.relative(rootReal, realResolved);
|
|
72
|
-
if (rel.startsWith('..') || path.isAbsolute(rel)) {
|
|
73
|
-
results.push({ citation, valid: false, reason: 'outside-workspace' });
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
let stat;
|
|
77
|
-
try {
|
|
78
|
-
stat = await fs.stat(realResolved);
|
|
79
|
-
}
|
|
80
|
-
catch {
|
|
81
|
-
results.push({ citation, valid: false, reason: 'file-missing' });
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
if (!stat.isFile()) {
|
|
85
|
-
results.push({ citation, valid: false, reason: 'file-missing' });
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
let content;
|
|
89
|
-
try {
|
|
90
|
-
content = await fs.readFile(realResolved, 'utf8');
|
|
91
|
-
}
|
|
92
|
-
catch {
|
|
93
|
-
results.push({ citation, valid: false, reason: 'file-missing' });
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
const totalLines = countLines(content);
|
|
97
|
-
const lastLine = citation.endLine ?? citation.line;
|
|
98
|
-
const rangeInvalid = citation.line < 1 ||
|
|
99
|
-
lastLine < citation.line ||
|
|
100
|
-
lastLine > totalLines;
|
|
101
|
-
if (rangeInvalid) {
|
|
102
|
-
results.push({ citation, valid: false, reason: 'line-out-of-range' });
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
|
-
results.push({ citation, valid: true });
|
|
106
|
-
}
|
|
107
|
-
return results;
|
|
108
|
-
}
|
|
109
|
-
//# sourceMappingURL=parser.js.map
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
export const DEFAULT_RULES = [
|
|
2
|
-
{ name: 'rm-recursive-force', pattern: /\brm\s+(-[a-zA-Z]*r[a-zA-Z]*f|-[a-zA-Z]*f[a-zA-Z]*r|-rf|-fr)\b/, kind: 'destructive', baseConfidence: 0.95 },
|
|
3
|
-
{ name: 'sudo-prefix', pattern: /^\s*sudo\b/, kind: 'destructive', baseConfidence: 0.85 },
|
|
4
|
-
{ name: 'git-force-push', pattern: /\bgit\s+push\b.*--force\b|\bgit\s+push\b.*\s-f\b/, kind: 'destructive', baseConfidence: 0.92 },
|
|
5
|
-
{ name: 'drop-table', pattern: /\bDROP\s+(TABLE|DATABASE|SCHEMA)\b/i, kind: 'destructive', baseConfidence: 0.95 },
|
|
6
|
-
{ name: 'mkfs', pattern: /\bmkfs(\.\w+)?\b/, kind: 'destructive', baseConfidence: 0.95 },
|
|
7
|
-
{ name: 'dd-of-device', pattern: /\bdd\b.*\bof=\/dev\//, kind: 'destructive', baseConfidence: 0.95 },
|
|
8
|
-
{ name: 'chmod-recursive-permissive', pattern: /\bchmod\s+-R\s+777\b/, kind: 'risky', baseConfidence: 0.8 },
|
|
9
|
-
{ name: 'curl-pipe-shell', pattern: /\bcurl\b[^|]*\|\s*(sudo\s+)?(ba)?sh\b/, kind: 'risky', baseConfidence: 0.85 },
|
|
10
|
-
{ name: 'ls-listing', pattern: /^\s*ls(\s|$)/, kind: 'safe', baseConfidence: 0.9 },
|
|
11
|
-
{ name: 'cd-navigate', pattern: /^\s*cd(\s|$)/, kind: 'safe', baseConfidence: 0.9 },
|
|
12
|
-
{ name: 'cat-read', pattern: /^\s*cat\s+/, kind: 'safe', baseConfidence: 0.88 },
|
|
13
|
-
{ name: 'echo-print', pattern: /^\s*echo\s+/, kind: 'safe', baseConfidence: 0.9 },
|
|
14
|
-
{ name: 'pwd-print', pattern: /^\s*pwd\s*$/, kind: 'safe', baseConfidence: 0.95 },
|
|
15
|
-
{ name: 'git-status', pattern: /^\s*git\s+(status|log|diff|branch|show)\b/, kind: 'safe', baseConfidence: 0.9 },
|
|
16
|
-
];
|
|
17
|
-
const DEFAULT_AMBIGUITY_THRESHOLD = 0.7;
|
|
18
|
-
function parseLlmResponse(raw) {
|
|
19
|
-
let parsed;
|
|
20
|
-
try {
|
|
21
|
-
parsed = JSON.parse(raw);
|
|
22
|
-
}
|
|
23
|
-
catch {
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
if (!parsed || typeof parsed !== 'object')
|
|
27
|
-
return null;
|
|
28
|
-
const kind = parsed.kind;
|
|
29
|
-
const confidence = parsed.confidence;
|
|
30
|
-
if (kind !== 'safe' && kind !== 'risky' && kind !== 'destructive' && kind !== 'unknown') {
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
if (typeof confidence !== 'number' || !Number.isFinite(confidence)) {
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
const clamped = Math.max(0, Math.min(1, confidence));
|
|
37
|
-
return { kind, confidence: clamped };
|
|
38
|
-
}
|
|
39
|
-
function matchRules(input, rules) {
|
|
40
|
-
for (const rule of rules) {
|
|
41
|
-
if (rule.pattern.test(input)) {
|
|
42
|
-
return { rule };
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
export async function classifyInput(input, options = {}) {
|
|
48
|
-
const rules = options.rules ?? DEFAULT_RULES;
|
|
49
|
-
const threshold = options.ambiguityThreshold ?? DEFAULT_AMBIGUITY_THRESHOLD;
|
|
50
|
-
const transport = options.transport;
|
|
51
|
-
const match = matchRules(input, rules);
|
|
52
|
-
if (match && match.rule.baseConfidence >= threshold) {
|
|
53
|
-
return {
|
|
54
|
-
kind: match.rule.kind,
|
|
55
|
-
confidence: match.rule.baseConfidence,
|
|
56
|
-
stage: 'regex',
|
|
57
|
-
matchedRule: match.rule.name,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
if (!transport) {
|
|
61
|
-
if (match) {
|
|
62
|
-
return {
|
|
63
|
-
kind: match.rule.kind,
|
|
64
|
-
confidence: match.rule.baseConfidence,
|
|
65
|
-
stage: 'regex',
|
|
66
|
-
matchedRule: match.rule.name,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
return { kind: 'unknown', confidence: 0, stage: 'fallback' };
|
|
70
|
-
}
|
|
71
|
-
let raw;
|
|
72
|
-
try {
|
|
73
|
-
raw = await transport(input);
|
|
74
|
-
}
|
|
75
|
-
catch {
|
|
76
|
-
return { kind: 'unknown', confidence: 0, stage: 'fallback' };
|
|
77
|
-
}
|
|
78
|
-
const parsed = parseLlmResponse(raw);
|
|
79
|
-
if (!parsed) {
|
|
80
|
-
return { kind: 'unknown', confidence: 0, stage: 'fallback' };
|
|
81
|
-
}
|
|
82
|
-
return {
|
|
83
|
-
kind: parsed.kind,
|
|
84
|
-
confidence: parsed.confidence,
|
|
85
|
-
stage: 'llm',
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
//# sourceMappingURL=yolo-classifier.js.map
|
package/dist/core/clipboard.js
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { spawn } from 'node:child_process';
|
|
2
|
-
/**
|
|
3
|
-
* Write `text` to the platform clipboard. Best-effort, async.
|
|
4
|
-
*/
|
|
5
|
-
export async function writeClipboard(text, deps = {}) {
|
|
6
|
-
const platform = deps.platform ?? process.platform;
|
|
7
|
-
const spawnWrite = deps.spawnWrite ?? defaultSpawnWrite;
|
|
8
|
-
if (platform === 'darwin') {
|
|
9
|
-
const ok = await spawnWrite('pbcopy', [], text);
|
|
10
|
-
return { copied: ok };
|
|
11
|
-
}
|
|
12
|
-
if (platform === 'win32') {
|
|
13
|
-
// clip.exe is shipped with every Windows >= XP. UTF-16LE would be
|
|
14
|
-
// ideal, but a UTF-8 BOM-less write covers the ASCII subset that
|
|
15
|
-
// device-flow URLs use (no non-ASCII characters reach this path).
|
|
16
|
-
const ok = await spawnWrite('clip', [], text);
|
|
17
|
-
return { copied: ok };
|
|
18
|
-
}
|
|
19
|
-
if (platform === 'linux' || platform === 'freebsd' || platform === 'openbsd') {
|
|
20
|
-
// Wayland-native sessions usually have wl-copy and not xclip. Try
|
|
21
|
-
// wl-copy first if WAYLAND_DISPLAY is set, otherwise prefer xclip.
|
|
22
|
-
const order = process.env.WAYLAND_DISPLAY
|
|
23
|
-
? ['wl-copy', 'xclip', 'xsel']
|
|
24
|
-
: ['xclip', 'wl-copy', 'xsel'];
|
|
25
|
-
for (const tool of order) {
|
|
26
|
-
const args = tool === 'xclip' ? ['-selection', 'clipboard'] : tool === 'xsel' ? ['--clipboard', '--input'] : [];
|
|
27
|
-
const ok = await spawnWrite(tool, args, text);
|
|
28
|
-
if (ok)
|
|
29
|
-
return { copied: true };
|
|
30
|
-
}
|
|
31
|
-
return { copied: false };
|
|
32
|
-
}
|
|
33
|
-
return { copied: false };
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Real spawn. Writes `text` to the child's stdin and resolves with
|
|
37
|
-
* `true` only when the child exits 0. Errors (missing binary,
|
|
38
|
-
* permission denied, non-zero exit) flip the result to `false`.
|
|
39
|
-
*/
|
|
40
|
-
function defaultSpawnWrite(cmd, args, text) {
|
|
41
|
-
return new Promise((resolve) => {
|
|
42
|
-
let settled = false;
|
|
43
|
-
const settle = (value) => {
|
|
44
|
-
if (settled)
|
|
45
|
-
return;
|
|
46
|
-
settled = true;
|
|
47
|
-
resolve(value);
|
|
48
|
-
};
|
|
49
|
-
try {
|
|
50
|
-
const options = {
|
|
51
|
-
stdio: ['pipe', 'ignore', 'ignore'],
|
|
52
|
-
shell: false,
|
|
53
|
-
};
|
|
54
|
-
const child = spawn(cmd, args.slice(), options);
|
|
55
|
-
child.on('error', () => settle(false));
|
|
56
|
-
child.on('close', (code) => settle(code === 0));
|
|
57
|
-
const stdin = child.stdin;
|
|
58
|
-
if (!stdin) {
|
|
59
|
-
settle(false);
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
stdin.on('error', () => settle(false));
|
|
63
|
-
stdin.end(text, 'utf8');
|
|
64
|
-
}
|
|
65
|
-
catch {
|
|
66
|
-
settle(false);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
//# sourceMappingURL=clipboard.js.map
|
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Codegraph install-decision store — .
|
|
3
|
-
*
|
|
4
|
-
* Persists the operator's verdict on the codegraph install prompt so we
|
|
5
|
-
* never spam them after a single decline. The 30-day reminder cadence
|
|
6
|
-
* lets us re-surface the offer on big-enough repos in case the operator
|
|
7
|
-
* said "not now" the first time and then forgot codegraph exists.
|
|
8
|
-
*
|
|
9
|
-
* Schema (workspace-scoped at `.pugi/codegraph-decision.json`):
|
|
10
|
-
*
|
|
11
|
-
* {
|
|
12
|
-
* "schema": 1,
|
|
13
|
-
* "offeredAt": "2026-05-27T00:00:00.000Z",
|
|
14
|
-
* "accepted": false,
|
|
15
|
-
* "decliningCount": 1,
|
|
16
|
-
* "remindAfter": "2026-06-26T00:00:00.000Z", // 30 days from offeredAt
|
|
17
|
-
* "lastIndexedAt": null, // ISO date string OR null
|
|
18
|
-
* "lastReindexCheckAt": null
|
|
19
|
-
* }
|
|
20
|
-
*
|
|
21
|
-
* The store is workspace-local (each repo gets its own decision) so
|
|
22
|
-
* declining codegraph in repo A does not suppress the prompt in repo B.
|
|
23
|
-
* `.pugi/` already exists by the time we land here (pugi init scaffolds
|
|
24
|
-
* it), so the directory creation is best-effort defence-in-depth.
|
|
25
|
-
*
|
|
26
|
-
* Concurrency: every write is `tmp + rename` so a partial write cannot
|
|
27
|
-
* surface a corrupt JSON. Reads tolerate missing files + corrupt JSON
|
|
28
|
-
* by returning `null` — the caller decides whether to fall back to
|
|
29
|
-
* "offer again" (safe default) or "do nothing" (cold-start path).
|
|
30
|
-
*
|
|
31
|
-
* Pure persistence. No telemetry, no logging. The emitter lives in the
|
|
32
|
-
* call sites so the decision store stays unit-testable in isolation.
|
|
33
|
-
*/
|
|
34
|
-
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from 'node:fs';
|
|
35
|
-
import { resolve } from 'node:path';
|
|
36
|
-
/**
|
|
37
|
-
* Reminder cadence — 30 days from the last decline. Operators who said
|
|
38
|
-
* no in a small repo that grew к medium during a sprint deserve a
|
|
39
|
-
* follow-up; operators who said no last week do not. The window is
|
|
40
|
-
* exposed as a const so the spec can pin it.
|
|
41
|
-
*/
|
|
42
|
-
export const REMIND_AFTER_DAYS = 30;
|
|
43
|
-
/**
|
|
44
|
-
* Stale-index threshold for the cold-start "refresh me" reminder.
|
|
45
|
-
* Seven days is the cadence the upstream codegraph docs recommend for
|
|
46
|
-
* monorepos that ship multiple times a day; lower repos can wait
|
|
47
|
-
* longer. The spec pins it.
|
|
48
|
-
*/
|
|
49
|
-
export const STALE_INDEX_DAYS = 7;
|
|
50
|
-
/**
|
|
51
|
-
* Resolve the decision file path for a workspace root. Pure — exposed
|
|
52
|
-
* для spec parity.
|
|
53
|
-
*/
|
|
54
|
-
export function decisionPath(workspaceRoot) {
|
|
55
|
-
return resolve(workspaceRoot, '.pugi/codegraph-decision.json');
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Read the persisted decision. Returns null on missing file, malformed
|
|
59
|
-
* JSON, or wrong schema version. The caller MUST treat null as "no
|
|
60
|
-
* decision yet" — not "operator declined".
|
|
61
|
-
*/
|
|
62
|
-
export function readDecision(workspaceRoot) {
|
|
63
|
-
const path = decisionPath(workspaceRoot);
|
|
64
|
-
if (!existsSync(path))
|
|
65
|
-
return null;
|
|
66
|
-
let raw;
|
|
67
|
-
try {
|
|
68
|
-
raw = readFileSync(path, 'utf8');
|
|
69
|
-
}
|
|
70
|
-
catch {
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
let parsed;
|
|
74
|
-
try {
|
|
75
|
-
parsed = JSON.parse(raw);
|
|
76
|
-
}
|
|
77
|
-
catch {
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
if (!isDecisionShape(parsed))
|
|
81
|
-
return null;
|
|
82
|
-
return parsed;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Type guard. Defensive — a future schema bump should land a migration
|
|
86
|
-
* here. For now: schema MUST be 1; required string fields MUST be
|
|
87
|
-
* strings; optional fields may be null OR string.
|
|
88
|
-
*/
|
|
89
|
-
function isDecisionShape(value) {
|
|
90
|
-
if (!value || typeof value !== 'object')
|
|
91
|
-
return false;
|
|
92
|
-
const v = value;
|
|
93
|
-
if (v.schema !== 1)
|
|
94
|
-
return false;
|
|
95
|
-
if (typeof v.offeredAt !== 'string')
|
|
96
|
-
return false;
|
|
97
|
-
if (typeof v.accepted !== 'boolean')
|
|
98
|
-
return false;
|
|
99
|
-
if (typeof v.decliningCount !== 'number' || !Number.isFinite(v.decliningCount))
|
|
100
|
-
return false;
|
|
101
|
-
if (typeof v.remindAfter !== 'string')
|
|
102
|
-
return false;
|
|
103
|
-
if (v.lastIndexedAt !== null && typeof v.lastIndexedAt !== 'string')
|
|
104
|
-
return false;
|
|
105
|
-
if (v.lastReindexCheckAt !== null && typeof v.lastReindexCheckAt !== 'string')
|
|
106
|
-
return false;
|
|
107
|
-
return true;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Atomic write. Creates `.pugi/` if it does not exist (pugi init owns
|
|
111
|
-
* that surface ordinarily; we defend the rare cold-start path).
|
|
112
|
-
*/
|
|
113
|
-
export function writeDecision(workspaceRoot, decision) {
|
|
114
|
-
const path = decisionPath(workspaceRoot);
|
|
115
|
-
const dir = resolve(workspaceRoot, '.pugi');
|
|
116
|
-
if (!existsSync(dir)) {
|
|
117
|
-
mkdirSync(dir, { recursive: true });
|
|
118
|
-
}
|
|
119
|
-
const tmp = `${path}.tmp.${process.pid}`;
|
|
120
|
-
writeFileSync(tmp, `${JSON.stringify(decision, null, 2)}\n`, { mode: 0o600 });
|
|
121
|
-
try {
|
|
122
|
-
renameSync(tmp, path);
|
|
123
|
-
}
|
|
124
|
-
catch (error) {
|
|
125
|
-
// Rename can fail if the destination was concurrently swapped on
|
|
126
|
-
// some platforms (Windows). Fall back to unlink + rename so the
|
|
127
|
-
// best-effort write does not throw to the caller.
|
|
128
|
-
try {
|
|
129
|
-
unlinkSync(path);
|
|
130
|
-
}
|
|
131
|
-
catch {
|
|
132
|
-
// ignore
|
|
133
|
-
}
|
|
134
|
-
renameSync(tmp, path);
|
|
135
|
-
void error;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Decide whether to surface the install prompt on init. Returns the
|
|
140
|
-
* full decision shape for callers that want to inspect the cadence;
|
|
141
|
-
* a `true` verdict means "yes, ask the operator now".
|
|
142
|
-
*/
|
|
143
|
-
export function shouldOfferOnInit(workspaceRoot, nowIso = new Date().toISOString()) {
|
|
144
|
-
const prior = readDecision(workspaceRoot);
|
|
145
|
-
if (!prior) {
|
|
146
|
-
return { shouldOffer: true, reason: 'first-run' };
|
|
147
|
-
}
|
|
148
|
-
if (prior.accepted) {
|
|
149
|
-
return { shouldOffer: false, reason: 'accepted-already' };
|
|
150
|
-
}
|
|
151
|
-
if (Date.parse(nowIso) >= Date.parse(prior.remindAfter)) {
|
|
152
|
-
return { shouldOffer: true, reason: 'reminder-due' };
|
|
153
|
-
}
|
|
154
|
-
return { shouldOffer: false, reason: 'recent-decline' };
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Record the operator's decision atomically. Mirrors the structure on
|
|
158
|
-
* disk — callers do NOT hand-craft the schema.
|
|
159
|
-
*/
|
|
160
|
-
export function recordDecision(workspaceRoot, input) {
|
|
161
|
-
const nowIso = input.nowIso ?? new Date().toISOString();
|
|
162
|
-
const prior = readDecision(workspaceRoot);
|
|
163
|
-
const decliningCount = input.accepted ? 0 : (prior?.decliningCount ?? 0) + 1;
|
|
164
|
-
const remindAfter = new Date(Date.parse(nowIso) + REMIND_AFTER_DAYS * 24 * 60 * 60 * 1000).toISOString();
|
|
165
|
-
const decision = {
|
|
166
|
-
schema: 1,
|
|
167
|
-
offeredAt: nowIso,
|
|
168
|
-
accepted: input.accepted,
|
|
169
|
-
decliningCount,
|
|
170
|
-
remindAfter,
|
|
171
|
-
lastIndexedAt: prior?.lastIndexedAt ?? null,
|
|
172
|
-
lastReindexCheckAt: prior?.lastReindexCheckAt ?? null,
|
|
173
|
-
};
|
|
174
|
-
writeDecision(workspaceRoot, decision);
|
|
175
|
-
return decision;
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Stamp the last-indexed timestamp. Called by /codegraph-status when
|
|
179
|
-
* the operator triggers a reindex from inside Pugi. Updates the
|
|
180
|
-
* `accepted` decision in place — never flips the install state.
|
|
181
|
-
*/
|
|
182
|
-
export function markIndexed(workspaceRoot, nowIso = new Date().toISOString()) {
|
|
183
|
-
const prior = readDecision(workspaceRoot);
|
|
184
|
-
if (!prior)
|
|
185
|
-
return null;
|
|
186
|
-
const next = {
|
|
187
|
-
...prior,
|
|
188
|
-
lastIndexedAt: nowIso,
|
|
189
|
-
lastReindexCheckAt: nowIso,
|
|
190
|
-
};
|
|
191
|
-
writeDecision(workspaceRoot, next);
|
|
192
|
-
return next;
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Stamp the last reindex-check timestamp without changing the index
|
|
196
|
-
* itself. Used by the cold-start hook so we do not show the "index is
|
|
197
|
-
* stale" hint on every keystroke once the operator has acknowledged
|
|
198
|
-
* it.
|
|
199
|
-
*/
|
|
200
|
-
export function markReindexChecked(workspaceRoot, nowIso = new Date().toISOString()) {
|
|
201
|
-
const prior = readDecision(workspaceRoot);
|
|
202
|
-
if (!prior)
|
|
203
|
-
return null;
|
|
204
|
-
const next = {
|
|
205
|
-
...prior,
|
|
206
|
-
lastReindexCheckAt: nowIso,
|
|
207
|
-
};
|
|
208
|
-
writeDecision(workspaceRoot, next);
|
|
209
|
-
return next;
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* Compute the staleness of the codegraph index. Pure — no IO.
|
|
213
|
-
*
|
|
214
|
-
* - returns null when `lastIndexedAt` is null (never indexed)
|
|
215
|
-
* - returns the day-delta (rounded down) otherwise
|
|
216
|
-
*/
|
|
217
|
-
export function indexAgeDays(decision, nowIso = new Date().toISOString()) {
|
|
218
|
-
if (!decision.lastIndexedAt)
|
|
219
|
-
return null;
|
|
220
|
-
const deltaMs = Date.parse(nowIso) - Date.parse(decision.lastIndexedAt);
|
|
221
|
-
if (!Number.isFinite(deltaMs) || deltaMs < 0)
|
|
222
|
-
return 0;
|
|
223
|
-
return Math.floor(deltaMs / (24 * 60 * 60 * 1000));
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Convenience predicate — should the cold-start hook show the stale-
|
|
227
|
-
* index reminder? `true` when the index is older than STALE_INDEX_DAYS
|
|
228
|
-
* AND we did NOT already remind the operator today.
|
|
229
|
-
*/
|
|
230
|
-
export function shouldNudgeStaleIndex(decision, nowIso = new Date().toISOString()) {
|
|
231
|
-
if (!decision.accepted)
|
|
232
|
-
return false;
|
|
233
|
-
const age = indexAgeDays(decision, nowIso);
|
|
234
|
-
if (age === null)
|
|
235
|
-
return false;
|
|
236
|
-
if (age < STALE_INDEX_DAYS)
|
|
237
|
-
return false;
|
|
238
|
-
// Throttle the nudge to once per day so the operator does not see it
|
|
239
|
-
// on every REPL keystroke.
|
|
240
|
-
if (decision.lastReindexCheckAt) {
|
|
241
|
-
const lastCheckDelta = Date.parse(nowIso) - Date.parse(decision.lastReindexCheckAt);
|
|
242
|
-
if (Number.isFinite(lastCheckDelta) && lastCheckDelta < 24 * 60 * 60 * 1000) {
|
|
243
|
-
return false;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
return true;
|
|
247
|
-
}
|
|
248
|
-
//# sourceMappingURL=decision-store.js.map
|