@pugi/cli 0.1.0-beta.9 → 0.1.0-beta.90
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/CHANGELOG.md +132 -0
- package/LICENSE +1 -1
- package/assets/pugi-prozr2-mascot.ansi +9 -0
- package/bin/run.js +33 -1
- package/dist/commands/deploy.js +40 -40
- package/dist/commands/flatten.js +191 -0
- package/dist/commands/jobs-watch.js +201 -0
- package/dist/commands/jobs.js +42 -27
- package/dist/commands/smoke.js +133 -0
- package/dist/core/agent-progress/cleanup.js +134 -0
- package/dist/core/agent-progress/schema.js +144 -0
- package/dist/core/agent-progress/writer.js +101 -0
- package/dist/core/agents/adaptive-router.js +330 -0
- package/dist/core/agents/query-decomposer.js +297 -0
- package/dist/core/agents/registry.js +3 -3
- package/dist/core/approvals/shortcut-resolver.js +98 -0
- package/dist/core/artifact-chain/dispatcher.js +148 -0
- package/dist/core/artifact-chain/exporter.js +164 -0
- package/dist/core/artifact-chain/state.js +243 -0
- package/dist/core/artifact-chain/steps.js +169 -0
- package/dist/core/ask-user/question.js +92 -0
- package/dist/core/audit/audit-trail.js +275 -0
- package/dist/core/auth/ensure-authenticated.js +129 -0
- package/dist/core/auth/env-provider.js +238 -0
- package/dist/core/auto-open-browser.js +4 -4
- package/dist/core/auto-update/channels.js +122 -0
- package/dist/core/auto-update/checker.js +241 -0
- package/dist/core/auto-update/state.js +235 -0
- package/dist/core/bare-mode/index.js +107 -0
- package/dist/core/bash/redirect.js +281 -0
- package/dist/core/bash-classifier.js +436 -40
- package/dist/core/checkpoint/resumer.js +149 -0
- package/dist/core/checkpoint/rewinder.js +291 -0
- package/dist/core/checkpoints/shadow-git.js +670 -0
- package/dist/core/citations/parser.js +109 -0
- package/dist/core/classifier/yolo-classifier.js +88 -0
- package/dist/core/codegraph/decision-store.js +248 -0
- package/dist/core/codegraph/detect-repo.js +459 -0
- package/dist/core/codegraph/install.js +134 -0
- package/dist/core/codegraph/offer-hook.js +220 -0
- package/dist/core/compact/auto-trigger.js +96 -0
- package/dist/core/compact/buffer-rewriter.js +115 -0
- package/dist/core/compact/summarizer.js +208 -0
- package/dist/core/compact/token-counter.js +108 -0
- package/dist/core/consensus/anvil-fanout.js +25 -25
- package/dist/core/consensus/diff-capture.js +121 -12
- package/dist/core/consensus/rubric.js +21 -21
- package/dist/core/context/builder.js +6 -6
- package/dist/core/context/compaction-events.js +8 -8
- package/dist/core/context/compaction.js +31 -31
- package/dist/core/context/index.js +15 -8
- package/dist/core/context/invariants.js +51 -51
- package/dist/core/context/markdown-loader.js +28 -10
- package/dist/core/context/markdown-traverse.js +255 -0
- package/dist/core/context/pugiignore.js +41 -41
- package/dist/core/context/repo-skeleton.js +37 -37
- package/dist/core/context/tool-eviction.js +55 -0
- package/dist/core/context/watcher.js +32 -32
- package/dist/core/context/working-set.js +23 -23
- package/dist/core/coordinator/agent-tools.js +77 -0
- package/dist/core/coordinator/agent-toolset.js +65 -0
- package/dist/core/coordinator/fsm.js +73 -0
- package/dist/core/coordinator/mode-fsm.js +70 -0
- package/dist/core/cost/rate-card.js +129 -0
- package/dist/core/cost/tracker.js +221 -0
- package/dist/core/credentials.js +13 -13
- package/dist/core/cron/scheduler.js +138 -0
- package/dist/core/denial-tracking/index.js +8 -0
- package/dist/core/denial-tracking/state.js +264 -0
- package/dist/core/diagnostics/probe-runner.js +93 -0
- package/dist/core/diagnostics/probes/api.js +46 -0
- package/dist/core/diagnostics/probes/auth.js +93 -0
- package/dist/core/diagnostics/probes/bare-mode.js +42 -0
- package/dist/core/diagnostics/probes/cli-version.js +127 -0
- package/dist/core/diagnostics/probes/config.js +72 -0
- package/dist/core/diagnostics/probes/denial-tracking.js +57 -0
- package/dist/core/diagnostics/probes/disk.js +81 -0
- package/dist/core/diagnostics/probes/engine-live.js +46 -0
- package/dist/core/diagnostics/probes/git.js +65 -0
- package/dist/core/diagnostics/probes/hooks.js +118 -0
- package/dist/core/diagnostics/probes/mcp.js +75 -0
- package/dist/core/diagnostics/probes/node.js +59 -0
- package/dist/core/diagnostics/probes/pnpm.js +36 -0
- package/dist/core/diagnostics/probes/pugi-md.js +89 -0
- package/dist/core/diagnostics/probes/sandbox.js +40 -0
- package/dist/core/diagnostics/probes/session.js +74 -0
- package/dist/core/diagnostics/probes/status-snapshot.js +488 -0
- package/dist/core/diagnostics/probes/workspace.js +63 -0
- package/dist/core/diagnostics/types.js +70 -0
- package/dist/core/dispatch/cache-cleanup.js +197 -0
- package/dist/core/dispatch/cache-handoff.js +295 -0
- package/dist/core/edits/apply-patch-layer-e.js +189 -0
- package/dist/core/edits/dispatch.js +333 -7
- package/dist/core/edits/format-detector.js +260 -0
- package/dist/core/edits/format-matrix.js +26 -0
- package/dist/core/edits/fuzzy-ladder.js +650 -0
- package/dist/core/edits/index.js +5 -1
- package/dist/core/edits/journal.js +199 -0
- package/dist/core/edits/layer-a-apply.js +15 -15
- package/dist/core/edits/layer-a-fuzzy-apply.js +198 -0
- package/dist/core/edits/layer-b-apply.js +9 -9
- package/dist/core/edits/layer-c-apply.js +6 -6
- package/dist/core/edits/layer-d-ast.js +557 -14
- package/dist/core/edits/marker-parser.js +12 -12
- package/dist/core/edits/security-gate.js +27 -27
- package/dist/core/edits/verify-hook.js +273 -0
- package/dist/core/edits/worktree.js +29 -29
- package/dist/core/engine/anvil-client.js +214 -26
- package/dist/core/engine/auto-compact.js +179 -0
- package/dist/core/engine/budgets.js +186 -0
- package/dist/core/engine/context-prefix.js +155 -0
- package/dist/core/engine/index.js +1 -1
- package/dist/core/engine/intensity.js +158 -0
- package/dist/core/engine/intent.js +260 -0
- package/dist/core/engine/native-pugi.js +1295 -227
- package/dist/core/engine/prompts.js +129 -19
- package/dist/core/engine/strip-internal-fields.js +124 -0
- package/dist/core/engine/tool-bridge.js +1731 -59
- package/dist/core/evaluation/golden-dataset.js +293 -0
- package/dist/core/feedback/queue.js +177 -0
- package/dist/core/feedback/submitter.js +145 -0
- package/dist/core/file-cache.js +113 -1
- package/dist/core/flatten/flatten-repo.js +439 -0
- package/dist/core/format/osc8-link.js +28 -0
- package/dist/core/hook-chains.js +392 -0
- package/dist/core/hooks/citation-verify-hook.js +138 -0
- package/dist/core/hooks/citation-verify.js +112 -0
- package/dist/core/hooks/events.js +46 -0
- package/dist/core/hooks/index.js +15 -0
- package/dist/core/hooks/registry.js +216 -0
- package/dist/core/hooks/runner.js +236 -0
- package/dist/core/hooks/v2/event-emitter.js +115 -0
- package/dist/core/hooks/v2/executor.js +282 -0
- package/dist/core/hooks/v2/index.js +25 -0
- package/dist/core/hooks/v2/lifecycle.js +104 -0
- package/dist/core/hooks/v2/loader.js +216 -0
- package/dist/core/hooks/v2/matcher.js +125 -0
- package/dist/core/hooks/v2/trust.js +143 -0
- package/dist/core/hooks/v2/types.js +86 -0
- package/dist/core/hooks/worktree-events.js +158 -0
- package/dist/core/image/renderer.js +71 -0
- package/dist/core/init/detector.js +582 -0
- package/dist/core/init/template-renderer.js +242 -0
- package/dist/core/jobs/registry.js +18 -18
- package/dist/core/ledger/results-tsv.js +142 -0
- package/dist/core/log-discipline/stdout-redirect.js +51 -0
- package/dist/core/lsp/cache.js +105 -0
- package/dist/core/lsp/client.js +551 -41
- package/dist/core/lsp/language-detect.js +66 -0
- package/dist/core/lsp/post-edit-diagnostics.js +171 -0
- package/dist/core/lsp/server-detect.js +173 -0
- package/dist/core/lsp/symbol-cache.js +162 -0
- package/dist/core/lsp/symbol-tools.js +664 -0
- package/dist/core/mcp/client.js +97 -28
- package/dist/core/mcp/http-server.js +553 -0
- package/dist/core/mcp/orchestrator-tools.js +662 -0
- package/dist/core/mcp/permission.js +190 -0
- package/dist/core/mcp/registry.js +39 -17
- package/dist/core/mcp/server-tools.js +219 -0
- package/dist/core/mcp/server.js +397 -0
- package/dist/core/mcp/trust.js +10 -10
- package/dist/core/memory/dual-write.js +416 -0
- package/dist/core/memory/passive-extract.js +130 -0
- package/dist/core/memory/phase1-kinds.js +20 -0
- package/dist/core/memory/secret-scanner.js +304 -0
- package/dist/core/memory-sync/queue.js +170 -0
- package/dist/core/metrics/extract.js +113 -0
- package/dist/core/modes/roo-modes.js +68 -0
- package/dist/core/onboarding/ensure-initialized.js +133 -0
- package/dist/core/onboarding/marker.js +111 -0
- package/dist/core/onboarding/telemetry-state.js +108 -0
- package/dist/core/output-style/presets.js +176 -0
- package/dist/core/output-style/state.js +185 -0
- package/dist/core/path-security.js +287 -5
- package/dist/core/permission.js +82 -22
- package/dist/core/permissions/auto-classifier.js +124 -0
- package/dist/core/permissions/bash-parser.js +371 -0
- package/dist/core/permissions/circuit-breaker.js +83 -0
- package/dist/core/permissions/constrained-edit.js +91 -0
- package/dist/core/permissions/gate.js +278 -0
- package/dist/core/permissions/index.js +20 -0
- package/dist/core/permissions/mode.js +174 -0
- package/dist/core/permissions/network-egress.js +137 -0
- package/dist/core/permissions/state.js +241 -0
- package/dist/core/permissions/tool-class.js +93 -0
- package/dist/core/plan-mode/ui-state.js +51 -0
- package/dist/core/plans/plan-artifact.js +721 -0
- package/dist/core/policy-limits/etag-store.js +122 -0
- package/dist/core/prd-check/parser.js +215 -0
- package/dist/core/prd-check/reporter.js +127 -0
- package/dist/core/prd-check/session-review.js +557 -0
- package/dist/core/prd-check/verifiers.js +223 -0
- package/dist/core/prompt-cache/client-cache.js +99 -0
- package/dist/core/prompts/assembly.js +29 -0
- package/dist/core/prompts/registry.js +364 -0
- package/dist/core/pugi-md/cc-compat-rules.js +735 -0
- package/dist/core/pugi-md/context-injector.js +76 -0
- package/dist/core/pugi-md/walk-up.js +207 -0
- package/dist/core/python/uv-installer.js +270 -0
- package/dist/core/python/uv-resolver.js +83 -0
- package/dist/core/rate-limit/narrator.js +146 -0
- package/dist/core/recipes/cli-types.js +20 -0
- package/dist/core/recipes/loader.js +103 -0
- package/dist/core/recipes/runner.js +345 -0
- package/dist/core/recipes/schema.js +587 -0
- package/dist/core/release-notes/parser.js +241 -0
- package/dist/core/release-notes/state.js +116 -0
- package/dist/core/repl/ask.js +37 -37
- package/dist/core/repl/cancellation.js +26 -26
- package/dist/core/repl/cap-warning.js +4 -4
- package/dist/core/repl/clipboard-read.js +11 -11
- package/dist/core/repl/dispatch-fsm.js +12 -12
- package/dist/core/repl/history-search.js +15 -15
- package/dist/core/repl/history.js +28 -18
- package/dist/core/repl/kill-ring.js +5 -5
- package/dist/core/repl/model-pricing.js +135 -0
- package/dist/core/repl/privacy-banner.js +22 -22
- package/dist/core/repl/session.js +2148 -217
- package/dist/core/repl/slash-commands.js +501 -41
- package/dist/core/repl/store/index.js +1 -1
- package/dist/core/repl/store/jsonl-log.js +22 -22
- package/dist/core/repl/store/lockfile.js +10 -10
- package/dist/core/repl/store/session-store.js +136 -107
- package/dist/core/repl/store/types.js +15 -15
- package/dist/core/repl/store/uuid-v7.js +12 -12
- package/dist/core/repl/workspace-context.js +43 -21
- package/dist/core/repo-map/build.js +125 -0
- package/dist/core/repo-map/cache.js +185 -0
- package/dist/core/repo-map/extractor.js +254 -0
- package/dist/core/repo-map/formatter.js +145 -0
- package/dist/core/repo-map/page-rank.js +105 -0
- package/dist/core/repo-map/scanner.js +211 -0
- package/dist/core/retry-budget/budget.js +284 -0
- package/dist/core/retry-budget/index.js +5 -0
- package/dist/core/retry-budget/retry-cap.js +74 -0
- package/dist/core/routing/lead-worker.js +43 -0
- package/dist/core/routing/pre-flight-estimator.js +108 -0
- package/dist/core/runs/run-tree.js +103 -0
- package/dist/core/security/injection-scanner.js +367 -0
- package/dist/core/security/output-filter.js +418 -0
- package/dist/core/session/env-file.js +105 -0
- package/dist/core/session/section-budgets.js +140 -0
- package/dist/core/session.js +92 -0
- package/dist/core/settings.js +324 -5
- package/dist/core/share/formatter.js +271 -0
- package/dist/core/share/redactor.js +221 -0
- package/dist/core/share/uploader.js +267 -0
- package/dist/core/skills/defaults.js +30 -30
- package/dist/core/skills/loader.js +22 -22
- package/dist/core/skills/sources.js +27 -27
- package/dist/core/smoke/headless-driver.js +174 -0
- package/dist/core/smoke/orchestrator.js +194 -0
- package/dist/core/smoke/runner.js +238 -0
- package/dist/core/smoke/scenario-parser.js +316 -0
- package/dist/core/statusline.js +99 -0
- package/dist/core/subagents/dispatcher-real.js +600 -0
- package/dist/core/subagents/dispatcher.js +132 -43
- package/dist/core/subagents/index.js +19 -6
- package/dist/core/subagents/isolation-matrix.js +213 -0
- package/dist/core/subagents/spawn.js +19 -4
- package/dist/core/telemetry/emitter.js +229 -0
- package/dist/core/telemetry/queue.js +251 -0
- package/dist/core/theme/context.js +91 -0
- package/dist/core/theme/presets.js +228 -0
- package/dist/core/theme/state.js +181 -0
- package/dist/core/todos/invariant.js +10 -0
- package/dist/core/todos/state.js +177 -0
- package/dist/core/tool-schema/compressor.js +89 -0
- package/dist/core/transport/version-interceptor.js +166 -0
- package/dist/core/trust.js +2 -2
- package/dist/core/tui/thinking-block.js +64 -0
- package/dist/core/vim/keymap.js +288 -0
- package/dist/core/vim/state.js +92 -0
- package/dist/core/watch-markers/marker-watcher.js +133 -0
- package/dist/core/worktree/include-parser.js +249 -0
- package/dist/core/worktree-manager/cleanup.js +123 -0
- package/dist/core/worktree-manager/manager.js +303 -0
- package/dist/index.js +36 -0
- package/dist/runtime/bootstrap.js +190 -0
- package/dist/runtime/cli.js +4185 -549
- package/dist/runtime/commands/agents.js +31 -31
- package/dist/runtime/commands/budget.js +5 -5
- package/dist/runtime/commands/cancel.js +231 -0
- package/dist/runtime/commands/chain.js +489 -0
- package/dist/runtime/commands/codegraph-status.js +227 -0
- package/dist/runtime/commands/compact.js +297 -0
- package/dist/runtime/commands/config.js +73 -39
- package/dist/runtime/commands/cost.js +199 -0
- package/dist/runtime/commands/delegate.js +27 -4
- package/dist/runtime/commands/dispatch.js +126 -0
- package/dist/runtime/commands/doctor.js +579 -0
- package/dist/runtime/commands/feedback.js +184 -0
- package/dist/runtime/commands/hooks.js +187 -0
- package/dist/runtime/commands/init.js +254 -0
- package/dist/runtime/commands/lsp.js +200 -38
- package/dist/runtime/commands/mcp.js +879 -0
- package/dist/runtime/commands/memory.js +582 -0
- package/dist/runtime/commands/model.js +237 -0
- package/dist/runtime/commands/onboarding.js +275 -0
- package/dist/runtime/commands/patch.js +12 -12
- package/dist/runtime/commands/permissions.js +112 -0
- package/dist/runtime/commands/plan.js +143 -0
- package/dist/runtime/commands/prd-check.js +285 -0
- package/dist/runtime/commands/privacy.js +17 -17
- package/dist/runtime/commands/recipe.js +325 -0
- package/dist/runtime/commands/redo-blob-store.js +92 -0
- package/dist/runtime/commands/redo.js +361 -0
- package/dist/runtime/commands/release-notes.js +229 -0
- package/dist/runtime/commands/repo-map.js +95 -0
- package/dist/runtime/commands/report.js +299 -0
- package/dist/runtime/commands/resume.js +118 -0
- package/dist/runtime/commands/review-consensus.js +68 -53
- package/dist/runtime/commands/rewind.js +333 -0
- package/dist/runtime/commands/roster.js +14 -14
- package/dist/runtime/commands/sessions.js +163 -0
- package/dist/runtime/commands/share.js +316 -0
- package/dist/runtime/commands/skills.js +31 -31
- package/dist/runtime/commands/status.js +186 -0
- package/dist/runtime/commands/stickers.js +82 -0
- package/dist/runtime/commands/style.js +194 -0
- package/dist/runtime/commands/theme.js +196 -0
- package/dist/runtime/commands/undo.js +54 -22
- package/dist/runtime/commands/update.js +289 -0
- package/dist/runtime/commands/vim.js +140 -0
- package/dist/runtime/commands/worktree.js +8 -8
- package/dist/runtime/commands/worktrees.js +155 -0
- package/dist/runtime/headless-repl.js +195 -0
- package/dist/runtime/headless.js +543 -0
- package/dist/runtime/load-hooks-or-exit.js +71 -0
- package/dist/runtime/plan-decompose.js +22 -22
- package/dist/runtime/sigint-guard.js +272 -0
- package/dist/runtime/update-check.js +28 -28
- package/dist/runtime/version.js +65 -0
- package/dist/runtime/worktree-bootstrap.js +579 -0
- package/dist/skills/bundled/batch.js +617 -0
- package/dist/skills/bundled/index.js +45 -0
- package/dist/skills/bundled/loop.js +358 -0
- package/dist/skills/bundled/remember.js +383 -0
- package/dist/skills/bundled/simplify.js +289 -0
- package/dist/skills/bundled/skillify.js +373 -0
- package/dist/skills/bundled/stuck.js +558 -0
- package/dist/skills/bundled/verify.js +439 -0
- package/dist/testing/vcr.js +486 -0
- package/dist/tools/agent-tool.js +229 -0
- package/dist/tools/apply-patch.js +89 -28
- package/dist/tools/ask-user-question.js +337 -0
- package/dist/tools/ask-user.js +115 -0
- package/dist/tools/bash.js +624 -46
- package/dist/tools/brief.js +224 -0
- package/dist/tools/enter-worktree.js +250 -0
- package/dist/tools/exit-worktree.js +147 -0
- package/dist/tools/file-tools.js +161 -44
- package/dist/tools/lsp-tools.js +377 -1
- package/dist/tools/mcp-tool.js +260 -0
- package/dist/tools/multi-edit.js +361 -0
- package/dist/tools/powershell.js +268 -0
- package/dist/tools/registry.js +86 -4
- package/dist/tools/skill-tool.js +96 -0
- package/dist/tools/sleep.js +99 -0
- package/dist/tools/synthetic-output.js +133 -0
- package/dist/tools/tasks.js +208 -0
- package/dist/tools/todo-write.js +184 -0
- package/dist/tools/verify-plan-execution.js +295 -0
- package/dist/tools/web-fetch-injection-scanner.js +207 -0
- package/dist/tools/web-fetch.js +195 -10
- package/dist/tools/web-search.js +458 -0
- package/dist/tui/agent-progress-card.js +111 -0
- package/dist/tui/agent-tree.js +11 -1
- package/dist/tui/ask-modal.js +14 -14
- package/dist/tui/ask-user-question-chips.js +315 -0
- package/dist/tui/ask-user-question-prompt.js +203 -0
- package/dist/tui/compact-banner.js +81 -0
- package/dist/tui/conversation-pane.js +85 -11
- package/dist/tui/cost-table.js +111 -0
- package/dist/tui/device-flow.js +2 -2
- package/dist/tui/doctor-table.js +46 -0
- package/dist/tui/feedback-prompt.js +156 -0
- package/dist/tui/input-box.js +247 -32
- package/dist/tui/login-picker.js +3 -3
- package/dist/tui/markdown-render.js +6 -6
- package/dist/tui/onboarding-wizard.js +240 -0
- package/dist/tui/permissions-picker.js +86 -0
- package/dist/tui/render.js +36 -1
- package/dist/tui/repl-render.js +176 -25
- package/dist/tui/repl-splash-art.js +16 -16
- package/dist/tui/repl-splash-mascot.js +48 -24
- package/dist/tui/repl-splash.js +22 -22
- package/dist/tui/repl.js +125 -45
- package/dist/tui/slash-palette.js +6 -6
- package/dist/tui/splash.js +2 -2
- package/dist/tui/status-bar.js +109 -31
- package/dist/tui/status-table.js +7 -0
- package/dist/tui/stickers-art.js +136 -0
- package/dist/tui/style-table.js +28 -0
- package/dist/tui/theme-table.js +29 -0
- package/dist/tui/thinking-spinner.js +123 -0
- package/dist/tui/tool-stream-pane.js +53 -4
- package/dist/tui/update-banner.js +27 -2
- package/dist/tui/vim-input.js +267 -0
- package/dist/tui/welcome-banner.js +107 -0
- package/dist/tui/welcome-data.js +293 -0
- package/dist/tui/workspace-context.js +2 -2
- package/package.json +31 -16
- package/test/scenarios/codegen-create-file.scenario.txt +13 -0
- package/test/scenarios/compact-force.scenario.txt +12 -0
- package/test/scenarios/identity.scenario.txt +12 -0
- package/test/scenarios/persona-handoff.scenario.txt +12 -0
- package/test/scenarios/walkback.scenario.txt +12 -0
- package/dist/core/engine/compaction-hook.js +0 -154
package/dist/core/mcp/client.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
+
import { createWriteStream } from 'node:fs';
|
|
2
3
|
import { z } from 'zod';
|
|
3
4
|
/**
|
|
4
5
|
* Minimal JSON-RPC 2.0 over stdio MCP client for Pugi CLI M1.
|
|
5
6
|
*
|
|
6
7
|
* Spec reference: https://modelcontextprotocol.io/specification
|
|
7
8
|
*
|
|
8
|
-
* Scope deliberately narrowed to what the CLI needs for
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* Scope deliberately narrowed to what the CLI needs for :
|
|
10
|
+
* - initialize handshake (protocol version + capabilities exchange)
|
|
11
|
+
* - tools/list
|
|
12
|
+
* - tools/call
|
|
13
|
+
* - graceful shutdown (SIGTERM, 5s grace, SIGKILL)
|
|
13
14
|
*
|
|
14
15
|
* NOT implemented for M1: resources, prompts, sampling, notifications, SSE
|
|
15
16
|
* transport, batching, progress tokens. Those layer onto this surface later
|
|
@@ -18,29 +19,38 @@ import { z } from 'zod';
|
|
|
18
19
|
* extend `RpcMethod` and the response parsers.
|
|
19
20
|
*
|
|
20
21
|
* Why hand-roll instead of `@modelcontextprotocol/sdk`:
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
22
|
+
* - The official SDK is ~3 MB compressed and pulls in 30+ transitive deps
|
|
23
|
+
* to support every transport. The CLI ships as `npm i -g pugi` and every
|
|
24
|
+
* dep is a maintenance + supply-chain risk. Hand-rolled JSON-RPC over
|
|
25
|
+
* stdio is <200 LOC; that is the right tradeoff for an alpha that ships.
|
|
26
|
+
* - We retain wire-level control to add Pugi-specific extensions later
|
|
27
|
+
* (per-call permission gates, trust-aware tool filtering at the
|
|
28
|
+
* transport layer) without forking the SDK.
|
|
28
29
|
*
|
|
29
30
|
* Strict typing notes:
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
31
|
+
* - All wire messages parse through Zod before reaching consumer code.
|
|
32
|
+
* - `unknown` is preferred over `any` in every public surface.
|
|
33
|
+
* - Timeouts are mandatory; a stuck child process never blocks the CLI
|
|
34
|
+
* forever.
|
|
34
35
|
*/
|
|
35
36
|
export const mcpServerConfigSchema = z.object({
|
|
36
37
|
command: z.string().min(1),
|
|
38
|
+
/**
|
|
39
|
+
* β4 r2 P1 #1 — operator's literal `command` argument as supplied to
|
|
40
|
+
* `pugi mcp install`. `command` above is now the RESOLVED absolute path
|
|
41
|
+
* we actually spawn. `originalCommand` is preserved for display/audit
|
|
42
|
+
* (`pugi mcp list`, audit logs) so operators can still see how they
|
|
43
|
+
* typed the install. Optional because pre-r2 mcp.json files do not
|
|
44
|
+
* carry the field — the loader treats absence as "use command directly".
|
|
45
|
+
*/
|
|
46
|
+
originalCommand: z.string().min(1).optional(),
|
|
37
47
|
args: z.array(z.string()).default([]),
|
|
38
48
|
env: z.record(z.string()).default({}),
|
|
39
49
|
/**
|
|
40
50
|
* Per-server trust state. Mirrors `trust.ts` ledger semantics:
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
51
|
+
* - `pending` — declared but not yet approved. Connections refused.
|
|
52
|
+
* - `trusted` — operator has approved this server's command line.
|
|
53
|
+
* - `denied` — operator explicitly blocked it; never auto-connect.
|
|
44
54
|
*
|
|
45
55
|
* Note this is the runtime trust state stored INSIDE `.pugi/mcp.json` /
|
|
46
56
|
* `~/.pugi/mcp.json`. The trust LEDGER at `~/.pugi/trust-mcp.json` is the
|
|
@@ -59,9 +69,9 @@ const SHUTDOWN_GRACE_MS = 5_000;
|
|
|
59
69
|
* Spawn an MCP server child process and complete the initialize handshake.
|
|
60
70
|
*
|
|
61
71
|
* Throws if:
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
72
|
+
* - the child fails to spawn (ENOENT, permission denied, etc),
|
|
73
|
+
* - the initialize response does not arrive within the timeout,
|
|
74
|
+
* - the server returns a JSON-RPC error in response to initialize.
|
|
65
75
|
*
|
|
66
76
|
* The caller is responsible for calling `disconnect` to free the child.
|
|
67
77
|
*/
|
|
@@ -70,6 +80,22 @@ export async function connect(serverName, config, options = {}) {
|
|
|
70
80
|
env: { ...process.env, ...config.env },
|
|
71
81
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
72
82
|
});
|
|
83
|
+
// L13: optional stderr → log file. We open the stream lazily so a bad
|
|
84
|
+
// path surfaces synchronously to the caller instead of getting buried
|
|
85
|
+
// in the child's stderr handler. `mkdir -p` of the parent dir is the
|
|
86
|
+
// caller's responsibility (the registry does it once per session).
|
|
87
|
+
let logStream;
|
|
88
|
+
if (options.logFile) {
|
|
89
|
+
try {
|
|
90
|
+
logStream = createWriteStream(options.logFile, { flags: 'a' });
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// Log directory missing or unwritable — degrade silently rather
|
|
94
|
+
// than refuse the handshake. The operator still gets the same
|
|
95
|
+
// surface they had pre-L13 (stderr dropped on the floor).
|
|
96
|
+
logStream = undefined;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
73
99
|
const connection = {
|
|
74
100
|
serverName,
|
|
75
101
|
child,
|
|
@@ -77,6 +103,8 @@ export async function connect(serverName, config, options = {}) {
|
|
|
77
103
|
pending: new Map(),
|
|
78
104
|
nextId: 1,
|
|
79
105
|
closed: false,
|
|
106
|
+
...(logStream ? { logStream } : {}),
|
|
107
|
+
startedAt: Date.now(),
|
|
80
108
|
};
|
|
81
109
|
// Attach the spawn-error handler BEFORE the reader: ENOENT and similar
|
|
82
110
|
// are emitted asynchronously on the next tick, and without this
|
|
@@ -184,11 +212,25 @@ export async function callTool(connection, name, args, options = {}) {
|
|
|
184
212
|
* SIGKILL if the child has not exited. Safe to call multiple times.
|
|
185
213
|
*/
|
|
186
214
|
export async function disconnect(connection) {
|
|
187
|
-
|
|
215
|
+
const closeLogStream = () => {
|
|
216
|
+
const stream = connection.logStream;
|
|
217
|
+
if (!stream)
|
|
218
|
+
return;
|
|
219
|
+
try {
|
|
220
|
+
stream.end();
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
// Best-effort — stream may already be destroyed.
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
if (connection.closed) {
|
|
227
|
+
closeLogStream();
|
|
188
228
|
return;
|
|
229
|
+
}
|
|
189
230
|
const { child } = connection;
|
|
190
231
|
if (child.exitCode !== null || child.killed) {
|
|
191
232
|
connection.closed = true;
|
|
233
|
+
closeLogStream();
|
|
192
234
|
return;
|
|
193
235
|
}
|
|
194
236
|
return new Promise((resolveDone) => {
|
|
@@ -198,6 +240,7 @@ export async function disconnect(connection) {
|
|
|
198
240
|
return;
|
|
199
241
|
settled = true;
|
|
200
242
|
connection.closed = true;
|
|
243
|
+
closeLogStream();
|
|
201
244
|
resolveDone();
|
|
202
245
|
};
|
|
203
246
|
child.once('exit', settle);
|
|
@@ -223,6 +266,22 @@ export async function disconnect(connection) {
|
|
|
223
266
|
}, SHUTDOWN_GRACE_MS);
|
|
224
267
|
});
|
|
225
268
|
}
|
|
269
|
+
/**
|
|
270
|
+
* L13: cheap liveness probe for `pugi mcp doctor`. True when the child
|
|
271
|
+
* process is still running AND the connection has not been torn down.
|
|
272
|
+
* Does NOT issue a JSON-RPC call — that would race with in-flight tool
|
|
273
|
+
* dispatch and the doctor surface is read-only.
|
|
274
|
+
*/
|
|
275
|
+
export function isAlive(connection) {
|
|
276
|
+
if (connection.closed)
|
|
277
|
+
return false;
|
|
278
|
+
const { child } = connection;
|
|
279
|
+
if (child.killed)
|
|
280
|
+
return false;
|
|
281
|
+
if (child.exitCode !== null)
|
|
282
|
+
return false;
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
226
285
|
function writeFrame(connection, message) {
|
|
227
286
|
if (connection.closed) {
|
|
228
287
|
throw new Error(`mcp server "${connection.serverName}" connection is closed`);
|
|
@@ -274,11 +333,21 @@ function attachReader(connection) {
|
|
|
274
333
|
newlineIndex = buffer.indexOf('\n');
|
|
275
334
|
}
|
|
276
335
|
});
|
|
277
|
-
// stderr is captured
|
|
278
|
-
//
|
|
279
|
-
//
|
|
280
|
-
//
|
|
281
|
-
connection.child.stderr.on('data', () => {
|
|
336
|
+
// stderr is captured and (when `connect({ logFile })` was set) mirrored
|
|
337
|
+
// to a per-server log file under `.pugi/logs/`. Operators can tail the
|
|
338
|
+
// file via `pugi mcp logs <server>`. Default sink remains "drop on the
|
|
339
|
+
// floor" so the CLI stdout stays pure JSON envelope output.
|
|
340
|
+
connection.child.stderr.on('data', (chunk) => {
|
|
341
|
+
const stream = connection.logStream;
|
|
342
|
+
if (!stream || stream.destroyed)
|
|
343
|
+
return;
|
|
344
|
+
try {
|
|
345
|
+
stream.write(typeof chunk === 'string' ? chunk : chunk);
|
|
346
|
+
}
|
|
347
|
+
catch {
|
|
348
|
+
// Disk full / fd revoked — drop silently. Mirroring is best-effort.
|
|
349
|
+
}
|
|
350
|
+
});
|
|
282
351
|
}
|
|
283
352
|
function handleLine(connection, line) {
|
|
284
353
|
let parsed;
|