@pugi/cli 0.1.0-beta.99 → 1.0.0-alpha.1
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,303 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WorktreeManager — .
|
|
3
|
-
*
|
|
4
|
-
* the upstream tool spawns a separate git worktree per dispatched sub-agent so
|
|
5
|
-
* parallel agents never collide on the filesystem. This module is Pugi's
|
|
6
|
-
* parity surface: it binds a worktree to an `agentId` (the same kebab-case
|
|
7
|
-
* id the agent-progress JSON uses) and exposes a tiny CRUD-shaped API
|
|
8
|
-
* the dispatcher can call before/after spawning a sub-persona.
|
|
9
|
-
*
|
|
10
|
-
* Differences from the existing `core/edits/worktree.ts` primitive:
|
|
11
|
-
*
|
|
12
|
-
* - The edits primitive keys worktrees by UUID and serves the manual
|
|
13
|
-
* `pugi worktree create/promote/drop` operator surface (one-shot
|
|
14
|
-
* scratch trees that get promoted back to the operator's tree).
|
|
15
|
-
* - This manager keys worktrees by AGENT ID so the dispatcher (and any
|
|
16
|
-
* observer like `pugi worktrees list`) can correlate a worktree
|
|
17
|
-
* with the in-flight agent driving it.
|
|
18
|
-
*
|
|
19
|
-
* The two namespaces coexist safely because the directory shapes differ:
|
|
20
|
-
*
|
|
21
|
-
* - manager: `<cwd>/.pugi/worktrees/<agent-id>/` (kebab-case)
|
|
22
|
-
* - primitive `<cwd>/.pugi/worktrees/<uuid>/` (dashed hex)
|
|
23
|
-
*
|
|
24
|
-
* The manager refuses to operate on a path whose basename does not match
|
|
25
|
-
* the agent-id regex `[a-zA-Z0-9_-]+` and does NOT collide with the UUID
|
|
26
|
-
* shape (`^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`).
|
|
27
|
-
*
|
|
28
|
-
* Concurrency:
|
|
29
|
-
*
|
|
30
|
-
* - `create(agentId)` is mutex'd per agent-id in process so two
|
|
31
|
-
* concurrent dispatch hooks racing on the same id resolve to the
|
|
32
|
-
* same handle (the second call awaits the first).
|
|
33
|
-
* - At the filesystem level the worktree dir's existence is the lock:
|
|
34
|
-
* if a stale dir for an agent-id survives from a previous process
|
|
35
|
-
* `create` returns `already_exists` so the caller can decide to
|
|
36
|
-
* reuse-or-cleanup explicitly (avoids `git worktree add` racing on
|
|
37
|
-
* the same path which surfaces a noisy git error).
|
|
38
|
-
*
|
|
39
|
-
* Brand voice: ASCII only, no emoji, no banned words.
|
|
40
|
-
*/
|
|
41
|
-
import { spawnSync } from 'node:child_process';
|
|
42
|
-
import { existsSync, mkdirSync, readdirSync, statSync } from 'node:fs';
|
|
43
|
-
import { resolve, sep } from 'node:path';
|
|
44
|
-
/**
|
|
45
|
-
* Filename-safe + dispatcher-safe agent id.
|
|
46
|
-
*
|
|
47
|
-
* Mirrors the regex on `AgentProgress.agentId` so an id that can write a
|
|
48
|
-
* progress file is exactly the id this manager will accept. The UUID
|
|
49
|
-
* exclusion below makes sure a caller never accidentally collides with
|
|
50
|
-
* the existing UUID-based scratch worktrees managed by
|
|
51
|
-
* `core/edits/worktree.ts`.
|
|
52
|
-
*/
|
|
53
|
-
const AGENT_ID_RE = /^[a-zA-Z0-9_-]+$/;
|
|
54
|
-
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
55
|
-
/** Validate an agent id. Exported for spec coverage + caller pre-checks. */
|
|
56
|
-
export function isValidAgentId(id) {
|
|
57
|
-
if (typeof id !== 'string' || id.length === 0 || id.length > 128)
|
|
58
|
-
return false;
|
|
59
|
-
if (!AGENT_ID_RE.test(id))
|
|
60
|
-
return false;
|
|
61
|
-
if (UUID_RE.test(id))
|
|
62
|
-
return false;
|
|
63
|
-
// Disallow `.` / `..` and the archive subdir name reserved by
|
|
64
|
-
// agent-progress cleanup so list/scan never crosses paths.
|
|
65
|
-
if (id === '.' || id === '..' || id === 'archive')
|
|
66
|
-
return false;
|
|
67
|
-
return true;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Build the absolute path for an agent's worktree without touching the
|
|
71
|
-
* filesystem. Exposed so the dispatcher can compute a `cwd` for the
|
|
72
|
-
* spawned child without invoking the manager (useful in dry-run paths).
|
|
73
|
-
*/
|
|
74
|
-
export function worktreePathFor(cwd, agentId) {
|
|
75
|
-
return resolve(cwd, '.pugi', 'worktrees', agentId);
|
|
76
|
-
}
|
|
77
|
-
/** Shape an agent-id + slug into the canonical branch name. */
|
|
78
|
-
export function branchNameFor(agentId, slug) {
|
|
79
|
-
const clean = (slug ?? '')
|
|
80
|
-
.toLowerCase()
|
|
81
|
-
.replace(/[^a-z0-9-]+/g, '-')
|
|
82
|
-
.replace(/^-+|-+$/g, '')
|
|
83
|
-
.slice(0, 24);
|
|
84
|
-
return clean.length > 0 ? `agent/${agentId}-${clean}` : `agent/${agentId}`;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Class wrapping git worktree operations for a single workspace root.
|
|
88
|
-
* Stateless across instances except for the per-agent-id mutex map.
|
|
89
|
-
*/
|
|
90
|
-
export class WorktreeManager {
|
|
91
|
-
cwd;
|
|
92
|
-
spawnGit;
|
|
93
|
-
inFlight = new Map();
|
|
94
|
-
constructor(options) {
|
|
95
|
-
this.cwd = options.cwd;
|
|
96
|
-
this.spawnGit = options.spawnGit ?? defaultSpawnGit;
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Create a worktree bound to `agentId`. Idempotent under concurrent
|
|
100
|
-
* callers: the second concurrent `create(<same id>)` awaits the first.
|
|
101
|
-
* A subsequent `create()` after a process restart on an EXISTING dir
|
|
102
|
-
* returns `already_exists` so the caller can choose to cleanup-then-
|
|
103
|
-
* recreate explicitly.
|
|
104
|
-
*/
|
|
105
|
-
async create(agentId, options = {}) {
|
|
106
|
-
if (!isValidAgentId(agentId)) {
|
|
107
|
-
return { ok: false, reason: 'invalid_agent_id', detail: `agent id ${String(agentId)} does not match ${AGENT_ID_RE} or collides with UUID shape` };
|
|
108
|
-
}
|
|
109
|
-
const pending = this.inFlight.get(agentId);
|
|
110
|
-
if (pending)
|
|
111
|
-
return pending;
|
|
112
|
-
const promise = this.createUnlocked(agentId, options);
|
|
113
|
-
this.inFlight.set(agentId, promise);
|
|
114
|
-
try {
|
|
115
|
-
return await promise;
|
|
116
|
-
}
|
|
117
|
-
finally {
|
|
118
|
-
this.inFlight.delete(agentId);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
async createUnlocked(agentId, options) {
|
|
122
|
-
const gitDir = this.spawnGit(['rev-parse', '--git-dir'], this.cwd);
|
|
123
|
-
if (gitDir.status !== 0) {
|
|
124
|
-
return { ok: false, reason: 'not_a_git_repo', detail: `not a git repo: ${this.cwd}` };
|
|
125
|
-
}
|
|
126
|
-
const target = worktreePathFor(this.cwd, agentId);
|
|
127
|
-
if (existsSync(target)) {
|
|
128
|
-
return {
|
|
129
|
-
ok: false,
|
|
130
|
-
reason: 'already_exists',
|
|
131
|
-
detail: `worktree already exists at ${target}; call cleanup(${agentId}) first if reuse intended`,
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
const baseRef = options.baseRef ?? 'HEAD';
|
|
135
|
-
const baseShaResult = this.spawnGit(['rev-parse', baseRef], this.cwd);
|
|
136
|
-
if (baseShaResult.status !== 0) {
|
|
137
|
-
return {
|
|
138
|
-
ok: false,
|
|
139
|
-
reason: 'git_command_failed',
|
|
140
|
-
detail: `cannot resolve base ref ${baseRef}: ${baseShaResult.stderr}`,
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
const baseSha = baseShaResult.stdout.trim();
|
|
144
|
-
const branch = branchNameFor(agentId, options.slug);
|
|
145
|
-
// Ensure the parent exists before git creates the leaf. git worktree
|
|
146
|
-
// add will create the leaf itself; pre-creating .pugi/worktrees/ keeps
|
|
147
|
-
// the failure mode local to git (we never have to mkdir the leaf).
|
|
148
|
-
const worktreesRoot = resolve(this.cwd, '.pugi', 'worktrees');
|
|
149
|
-
mkdirSync(worktreesRoot, { recursive: true });
|
|
150
|
-
// `-b <branch> <path> <base>` creates a NEW branch off `base`,
|
|
151
|
-
// checked out at `path`. We deliberately do NOT use `--detach` here
|
|
152
|
-
// (unlike the scratch primitive) so the branch survives across
|
|
153
|
-
// process restarts and the operator can `git push agent/<id>-<slug>`
|
|
154
|
-
// if they want to inspect the child's work outside the worktree.
|
|
155
|
-
const create = this.spawnGit(['worktree', 'add', '-b', branch, target, baseSha], this.cwd);
|
|
156
|
-
if (create.status !== 0) {
|
|
157
|
-
return {
|
|
158
|
-
ok: false,
|
|
159
|
-
reason: 'git_command_failed',
|
|
160
|
-
detail: `git worktree add failed: ${create.stderr || create.stdout}`,
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
return {
|
|
164
|
-
ok: true,
|
|
165
|
-
value: { agentId, path: target, branch, baseSha },
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Remove the worktree bound to `agentId`. Idempotent: a missing path
|
|
170
|
-
* surfaces `worktree_missing` rather than throwing, so a double-call
|
|
171
|
-
* during dispatch teardown never crashes the parent.
|
|
172
|
-
*/
|
|
173
|
-
cleanup(agentId) {
|
|
174
|
-
if (!isValidAgentId(agentId)) {
|
|
175
|
-
return { ok: false, reason: 'invalid_agent_id', detail: `agent id ${String(agentId)} is invalid` };
|
|
176
|
-
}
|
|
177
|
-
const target = worktreePathFor(this.cwd, agentId);
|
|
178
|
-
// Guard: never let cleanup touch a path that escapes the worktrees
|
|
179
|
-
// root (defensive — the worktreePathFor builder is already bounded
|
|
180
|
-
// because the agent id regex rejects '..', but containment check
|
|
181
|
-
// is cheap and gives us a second line of defense).
|
|
182
|
-
const root = resolve(this.cwd, '.pugi', 'worktrees');
|
|
183
|
-
if (!target.startsWith(root + sep)) {
|
|
184
|
-
return { ok: false, reason: 'invalid_agent_id', detail: `resolved path ${target} escapes ${root}` };
|
|
185
|
-
}
|
|
186
|
-
if (!existsSync(target)) {
|
|
187
|
-
// Best-effort prune so a metadata-only orphan goes away too.
|
|
188
|
-
this.spawnGit(['worktree', 'prune'], this.cwd);
|
|
189
|
-
return { ok: false, reason: 'worktree_missing', detail: `no worktree at ${target}` };
|
|
190
|
-
}
|
|
191
|
-
const remove = this.spawnGit(['worktree', 'remove', '--force', target], this.cwd);
|
|
192
|
-
if (remove.status !== 0) {
|
|
193
|
-
return {
|
|
194
|
-
ok: false,
|
|
195
|
-
reason: 'git_command_failed',
|
|
196
|
-
detail: `git worktree remove failed: ${remove.stderr || remove.stdout}`,
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
return { ok: true, value: { removed: target } };
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Enumerate worktrees the manager knows about. Read-only and never
|
|
203
|
-
* touches git metadata; the optional `gitTracked` flag on each entry
|
|
204
|
-
* surfaces the cross-check against `git worktree list --porcelain`.
|
|
205
|
-
*/
|
|
206
|
-
list() {
|
|
207
|
-
const root = resolve(this.cwd, '.pugi', 'worktrees');
|
|
208
|
-
if (!existsSync(root)) {
|
|
209
|
-
return { ok: true, value: [] };
|
|
210
|
-
}
|
|
211
|
-
let entries;
|
|
212
|
-
try {
|
|
213
|
-
entries = readdirSync(root);
|
|
214
|
-
}
|
|
215
|
-
catch (err) {
|
|
216
|
-
return {
|
|
217
|
-
ok: false,
|
|
218
|
-
reason: 'git_command_failed',
|
|
219
|
-
detail: `readdir ${root} failed: ${err.message}`,
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
const tracked = this.collectGitTrackedWorktrees();
|
|
223
|
-
const out = [];
|
|
224
|
-
for (const name of entries) {
|
|
225
|
-
if (!isValidAgentId(name))
|
|
226
|
-
continue;
|
|
227
|
-
const path = resolve(root, name);
|
|
228
|
-
let isDir = false;
|
|
229
|
-
try {
|
|
230
|
-
isDir = statSync(path).isDirectory();
|
|
231
|
-
}
|
|
232
|
-
catch {
|
|
233
|
-
continue;
|
|
234
|
-
}
|
|
235
|
-
if (!isDir)
|
|
236
|
-
continue;
|
|
237
|
-
const meta = tracked.get(path);
|
|
238
|
-
const branch = meta?.branch ?? branchNameFor(name);
|
|
239
|
-
const baseSha = meta?.head ?? '';
|
|
240
|
-
out.push({
|
|
241
|
-
agentId: name,
|
|
242
|
-
path,
|
|
243
|
-
branch,
|
|
244
|
-
baseSha,
|
|
245
|
-
gitTracked: meta !== undefined,
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
return { ok: true, value: out };
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Parse `git worktree list --porcelain` into a `path → {branch, head}`
|
|
252
|
-
* map. Errors degrade to an empty map — `list()` still surfaces the
|
|
253
|
-
* directory entries; the caller sees `gitTracked: false` rows and can
|
|
254
|
-
* decide.
|
|
255
|
-
*/
|
|
256
|
-
collectGitTrackedWorktrees() {
|
|
257
|
-
const out = new Map();
|
|
258
|
-
const list = this.spawnGit(['worktree', 'list', '--porcelain'], this.cwd);
|
|
259
|
-
if (list.status !== 0)
|
|
260
|
-
return out;
|
|
261
|
-
let currentPath = null;
|
|
262
|
-
let currentHead = '';
|
|
263
|
-
let currentBranch = '';
|
|
264
|
-
const commit = () => {
|
|
265
|
-
if (currentPath) {
|
|
266
|
-
out.set(currentPath, { branch: currentBranch, head: currentHead });
|
|
267
|
-
}
|
|
268
|
-
currentPath = null;
|
|
269
|
-
currentHead = '';
|
|
270
|
-
currentBranch = '';
|
|
271
|
-
};
|
|
272
|
-
for (const raw of list.stdout.split('\n')) {
|
|
273
|
-
const line = raw.trimEnd();
|
|
274
|
-
if (line.length === 0) {
|
|
275
|
-
commit();
|
|
276
|
-
continue;
|
|
277
|
-
}
|
|
278
|
-
if (line.startsWith('worktree ')) {
|
|
279
|
-
// New record — flush the previous one if any.
|
|
280
|
-
commit();
|
|
281
|
-
currentPath = line.slice('worktree '.length);
|
|
282
|
-
}
|
|
283
|
-
else if (line.startsWith('HEAD ')) {
|
|
284
|
-
currentHead = line.slice('HEAD '.length);
|
|
285
|
-
}
|
|
286
|
-
else if (line.startsWith('branch ')) {
|
|
287
|
-
// `branch refs/heads/agent/foo` → `agent/foo`
|
|
288
|
-
const ref = line.slice('branch '.length);
|
|
289
|
-
currentBranch = ref.replace(/^refs\/heads\//, '');
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
commit();
|
|
293
|
-
return out;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
function defaultSpawnGit(args, cwd) {
|
|
297
|
-
return spawnSync('git', args, {
|
|
298
|
-
cwd,
|
|
299
|
-
encoding: 'utf8',
|
|
300
|
-
maxBuffer: 16 * 1024 * 1024,
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
//# sourceMappingURL=manager.js.map
|
package/dist/index.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { runCli } from './runtime/cli.js';
|
|
3
|
-
import { PugiCliUpgradeRequiredError } from './core/transport/version-interceptor.js';
|
|
4
|
-
import { installSigintGuard } from './runtime/sigint-guard.js';
|
|
5
|
-
// PUGI-469 — install the top-level double-press Ctrl+C exit guard
|
|
6
|
-
// BEFORE any other init. Operators reported single ^C exiting the
|
|
7
|
-
// CLI; the guard requires a second press inside a 2s window (or
|
|
8
|
-
// emits a clean session-end envelope on the headless path) so a
|
|
9
|
-
// stray keystroke never kills the session. See the module header
|
|
10
|
-
// in `runtime/sigint-guard.ts` for the full behavior spec.
|
|
11
|
-
installSigintGuard();
|
|
12
|
-
runCli(process.argv.slice(2)).catch((error) => {
|
|
13
|
-
// PR-CLI-SERVER-VERSION-HANDSHAKE . When the admin-api returns
|
|
14
|
-
// 426 Upgrade Required, the engine transport throws a typed
|
|
15
|
-
// PugiCliUpgradeRequiredError. Render an operator-friendly banner
|
|
16
|
-
// (vs. the bland `pugi: <message>` default) so the upgrade command
|
|
17
|
-
// is obvious + copy-pasteable. Plain console.error rather than Ink
|
|
18
|
-
// here because the error may surface during one-shot commands where
|
|
19
|
-
// no Ink renderer is mounted (REPL paths catch via runtime/cli.ts).
|
|
20
|
-
if (error instanceof PugiCliUpgradeRequiredError) {
|
|
21
|
-
const lines = [
|
|
22
|
-
'',
|
|
23
|
-
'Pugi CLI upgrade required',
|
|
24
|
-
'',
|
|
25
|
-
` Your installed version: ${error.installedVersion}`,
|
|
26
|
-
` Server requires minimum: ${error.minClientVersion}`,
|
|
27
|
-
` Latest recommended: ${error.recommendedVersion}`,
|
|
28
|
-
'',
|
|
29
|
-
` Upgrade: ${error.upgradeCommand}`,
|
|
30
|
-
` Docs: ${error.upgradeUrl}`,
|
|
31
|
-
'',
|
|
32
|
-
' Until you upgrade, the server will reject your requests.',
|
|
33
|
-
' This protects you from silent protocol-drift bugs.',
|
|
34
|
-
'',
|
|
35
|
-
];
|
|
36
|
-
console.error(lines.join('\n'));
|
|
37
|
-
process.exitCode = 1;
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
41
|
-
console.error(`pugi: ${message}`);
|
|
42
|
-
process.exitCode = 1;
|
|
43
|
-
});
|
|
44
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bootstrap helpers — β1b U7 / U8 .
|
|
3
|
-
*
|
|
4
|
-
* Two related contracts:
|
|
5
|
-
*
|
|
6
|
-
* - U7: when `pugi` runs in a bare directory (no `.pugi/` and no
|
|
7
|
-
* project-marker file like `package.json` / `Cargo.toml` / `go.mod`)
|
|
8
|
-
* AND we have a TTY, offer an interactive `pugi init`.
|
|
9
|
-
*
|
|
10
|
-
* - U8: when `pugi` runs in a sub-directory of one or more parent
|
|
11
|
-
* projects (each carrying a `.pugi/settings.json` OR a git root),
|
|
12
|
-
* present a picker — "Found N projects: <list>. Pick OR /init here".
|
|
13
|
-
*
|
|
14
|
-
* Both checks are pure file-system queries; the interactive bridge
|
|
15
|
-
* lives one layer up (REPL bootstrap, slash-command palette). This
|
|
16
|
-
* module surfaces the structured result and the caller decides UX.
|
|
17
|
-
*
|
|
18
|
-
* Project markers we recognise (first match wins):
|
|
19
|
-
* - `.pugi/settings.json` (highest priority — Pugi-aware project)
|
|
20
|
-
* - `package.json` (Node / TypeScript / pnpm monorepo)
|
|
21
|
-
* - `Cargo.toml`
|
|
22
|
-
* - `go.mod`
|
|
23
|
-
* - `pyproject.toml` / `requirements.txt` / `setup.py`
|
|
24
|
-
* - `Gemfile`
|
|
25
|
-
* - `composer.json`
|
|
26
|
-
* - `pom.xml` / `build.gradle` / `build.gradle.kts`
|
|
27
|
-
* - `.git/` directory (last resort — git repo root)
|
|
28
|
-
*
|
|
29
|
-
* Walk depth is capped at 12 ancestors. Anything deeper is operator
|
|
30
|
-
* error (running `pugi` from `/Users/x/Library/.../node_modules/...`)
|
|
31
|
-
* and a deeper walk would be slow + surprising.
|
|
32
|
-
*
|
|
33
|
-
* Brand voice: ASCII only.
|
|
34
|
-
*/
|
|
35
|
-
import { existsSync, statSync } from 'node:fs';
|
|
36
|
-
import { dirname, resolve, basename } from 'node:path';
|
|
37
|
-
const PROJECT_MARKER_FILES = [
|
|
38
|
-
'.pugi/settings.json',
|
|
39
|
-
'package.json',
|
|
40
|
-
'Cargo.toml',
|
|
41
|
-
'go.mod',
|
|
42
|
-
'pyproject.toml',
|
|
43
|
-
'requirements.txt',
|
|
44
|
-
'setup.py',
|
|
45
|
-
'Gemfile',
|
|
46
|
-
'composer.json',
|
|
47
|
-
'pom.xml',
|
|
48
|
-
'build.gradle',
|
|
49
|
-
'build.gradle.kts',
|
|
50
|
-
];
|
|
51
|
-
const MAX_PARENT_WALK = 12;
|
|
52
|
-
/**
|
|
53
|
-
* Detect the workspace state at `cwd`. Pure file-system query; never
|
|
54
|
-
* throws. The caller pairs this with the TTY / --no-tty / --json flags
|
|
55
|
-
* to decide whether to prompt the operator.
|
|
56
|
-
*/
|
|
57
|
-
export function detectWorkspaceState(cwd) {
|
|
58
|
-
const absCwd = resolve(cwd);
|
|
59
|
-
// `.pugi/` at cwd always wins — we are already initialised.
|
|
60
|
-
if (hasPugiDir(absCwd)) {
|
|
61
|
-
return { kind: 'existing_pugi', root: absCwd };
|
|
62
|
-
}
|
|
63
|
-
// Project marker at cwd → proceed without prompting.
|
|
64
|
-
const cwdMarker = findMarkerAt(absCwd);
|
|
65
|
-
if (cwdMarker) {
|
|
66
|
-
return { kind: 'existing_project', root: absCwd, marker: cwdMarker };
|
|
67
|
-
}
|
|
68
|
-
// Walk parents — collect every ancestor that looks like a project.
|
|
69
|
-
const parents = findParentProjects(absCwd);
|
|
70
|
-
if (parents.length > 0) {
|
|
71
|
-
return { kind: 'inside_parent_projects', parents };
|
|
72
|
-
}
|
|
73
|
-
return { kind: 'bare' };
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Walk parent directories up to MAX_PARENT_WALK ancestors, collecting
|
|
77
|
-
* every directory that has a project marker. Nearest-first. Stops at
|
|
78
|
-
* the filesystem root. Exported for U8 spec coverage + for callers
|
|
79
|
-
* that want the raw list (e.g. a /workspaces shell command).
|
|
80
|
-
*/
|
|
81
|
-
export function findParentProjects(cwd) {
|
|
82
|
-
const out = [];
|
|
83
|
-
let current = dirname(resolve(cwd));
|
|
84
|
-
let last = '';
|
|
85
|
-
let hops = 0;
|
|
86
|
-
while (current && current !== last && hops < MAX_PARENT_WALK) {
|
|
87
|
-
const marker = findMarkerAt(current);
|
|
88
|
-
if (marker) {
|
|
89
|
-
out.push({ root: current, marker });
|
|
90
|
-
}
|
|
91
|
-
last = current;
|
|
92
|
-
current = dirname(current);
|
|
93
|
-
hops += 1;
|
|
94
|
-
}
|
|
95
|
-
return out;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Return the first matching project marker filename inside `dir`, or
|
|
99
|
-
* null when none of the candidates exist. `.pugi/settings.json` is a
|
|
100
|
-
* file (not the directory), so we test both for symmetry — if the
|
|
101
|
-
* operator has `.pugi/` but no settings.json yet, we treat it as a
|
|
102
|
-
* Pugi-aware project (the directory itself is the signal).
|
|
103
|
-
*/
|
|
104
|
-
function findMarkerAt(dir) {
|
|
105
|
-
for (const marker of PROJECT_MARKER_FILES) {
|
|
106
|
-
const path = resolve(dir, marker);
|
|
107
|
-
try {
|
|
108
|
-
if (existsSync(path))
|
|
109
|
-
return marker;
|
|
110
|
-
}
|
|
111
|
-
catch {
|
|
112
|
-
/* permission error — treat as missing */
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
// `.git/` last — costly because it touches the FS but only when no
|
|
116
|
-
// other marker hit. Skip if `.git/` is a file (worktree shim) since
|
|
117
|
-
// we still want the worktree path.
|
|
118
|
-
const gitPath = resolve(dir, '.git');
|
|
119
|
-
try {
|
|
120
|
-
if (existsSync(gitPath))
|
|
121
|
-
return '.git';
|
|
122
|
-
}
|
|
123
|
-
catch {
|
|
124
|
-
/* ignore */
|
|
125
|
-
}
|
|
126
|
-
return null;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* True iff the directory has a `.pugi/` subdirectory. We check the
|
|
130
|
-
* directory itself (not the settings.json inside) because the moment
|
|
131
|
-
* `.pugi/` exists Pugi is "set up here" from the operator's POV —
|
|
132
|
-
* settings.json may be empty / lazily written.
|
|
133
|
-
*/
|
|
134
|
-
function hasPugiDir(dir) {
|
|
135
|
-
const path = resolve(dir, '.pugi');
|
|
136
|
-
try {
|
|
137
|
-
if (!existsSync(path))
|
|
138
|
-
return false;
|
|
139
|
-
return statSync(path).isDirectory();
|
|
140
|
-
}
|
|
141
|
-
catch {
|
|
142
|
-
return false;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Build a human-friendly label for a project root: prefer the basename
|
|
147
|
-
* suffixed with the marker (`pugi (package.json)`). Used by the U8
|
|
148
|
-
* picker to render the list. Exported for spec coverage.
|
|
149
|
-
*/
|
|
150
|
-
export function projectLabel(root, marker) {
|
|
151
|
-
const name = basename(root) || root;
|
|
152
|
-
return `${name} (${marker})`;
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Should we proactively offer `pugi init` in this invocation?
|
|
156
|
-
*
|
|
157
|
-
* - kind === 'bare' → yes (U7)
|
|
158
|
-
* - kind === 'inside_parent_projects' → yes (U8 picker, "or init here")
|
|
159
|
-
* - existing_pugi / existing_project → no
|
|
160
|
-
*
|
|
161
|
-
* Caller must additionally gate on TTY + non-json mode. Exported so a
|
|
162
|
-
* UI layer can reuse the same decision rule without re-implementing
|
|
163
|
-
* the state switch.
|
|
164
|
-
*/
|
|
165
|
-
export function shouldOfferInit(state) {
|
|
166
|
-
return state.kind === 'bare' || state.kind === 'inside_parent_projects';
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Convenience formatter: synthesize the prompt text U7 / U8 callers
|
|
170
|
-
* surface to the operator on the bare/inside-parents paths. The text
|
|
171
|
-
* is plain ASCII; the UI layer wraps it in Ink as needed.
|
|
172
|
-
*/
|
|
173
|
-
export function formatInitPrompt(state, cwd) {
|
|
174
|
-
switch (state.kind) {
|
|
175
|
-
case 'bare':
|
|
176
|
-
return `No project detected at ${cwd}. Run \`pugi init\` here?`;
|
|
177
|
-
case 'inside_parent_projects': {
|
|
178
|
-
const lines = state.parents.map((p) => ` - ${projectLabel(p.root, p.marker)} (${p.root})`);
|
|
179
|
-
return `Found ${state.parents.length} parent project(s):\n${lines.join('\n')}\nPick one above or run \`pugi init\` here.`;
|
|
180
|
-
}
|
|
181
|
-
default:
|
|
182
|
-
return '';
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
/* β1b r1: dropped the `_internal` re-export. It was a leftover from
|
|
186
|
-
* an earlier spec that asserted module load order; the test was
|
|
187
|
-
* removed but the export lingered. No callers consume it inside the
|
|
188
|
-
* monorepo (verified via repo-wide grep), and `verbatimModuleSyntax`
|
|
189
|
-
* is happy with the module's regular exports. */
|
|
190
|
-
//# sourceMappingURL=bootstrap.js.map
|