@hcu-lab.me/mcp-device 1.0.9 → 1.0.12
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/PRIVACY.md +21 -0
- package/README.md +58 -3
- package/SECURITY.md +67 -0
- package/config/revoked-approvals.json +1 -0
- package/control-plane/config/mcp-servers.example.toml +52 -0
- package/control-plane/config/mcp-servers.toml +52 -0
- package/control-plane/contracts/device-public-contract-v1.json +733 -0
- package/control-plane/scripts/GATEWAY-LICENSE.txt +7 -0
- package/control-plane/scripts/account-http.mjs +220 -0
- package/control-plane/scripts/account-store.mjs +368 -0
- package/control-plane/scripts/admin.mjs +68 -0
- package/control-plane/scripts/auth-session.mjs +411 -0
- package/control-plane/scripts/authenticated-mcp-wrapper.mjs +1281 -0
- package/control-plane/scripts/benchmark-command.mjs +9 -0
- package/control-plane/scripts/benchmark-mcp-catalog.mjs +174 -0
- package/control-plane/scripts/catalog-budget.mjs +87 -0
- package/control-plane/scripts/check-device-public-contract.mjs +20 -0
- package/control-plane/scripts/custom-tools/index.mjs +221 -0
- package/control-plane/scripts/custom-tools/path-utils.mjs +117 -0
- package/control-plane/scripts/custom-tools/response-utils.mjs +34 -0
- package/control-plane/scripts/dashboard-http.mjs +598 -0
- package/control-plane/scripts/device-access-policy.mjs +205 -0
- package/control-plane/scripts/device-admin.mjs +43 -0
- package/control-plane/scripts/device-audit.mjs +63 -0
- package/control-plane/scripts/device-broker.mjs +1461 -0
- package/control-plane/scripts/device-execution-tool-definitions.mjs +217 -0
- package/control-plane/scripts/device-inventory.mjs +128 -0
- package/control-plane/scripts/device-pairing-http.mjs +109 -0
- package/control-plane/scripts/device-pairing-store.mjs +245 -0
- package/control-plane/scripts/device-public-contract.mjs +165 -0
- package/control-plane/scripts/device-release.mjs +95 -0
- package/control-plane/scripts/device-secure-transport.mjs +128 -0
- package/control-plane/scripts/device-store.mjs +283 -0
- package/control-plane/scripts/device-usage.mjs +657 -0
- package/control-plane/scripts/embedded-device.mjs +149 -0
- package/control-plane/scripts/enduser-ui.mjs +45 -0
- package/control-plane/scripts/external-tool-broker.mjs +179 -0
- package/control-plane/scripts/oauth-authorization-server.mjs +589 -0
- package/control-plane/scripts/operator-dashboard-http.mjs +81 -0
- package/control-plane/scripts/project-inspection.mjs +227 -0
- package/control-plane/scripts/projects/project-id.mjs +69 -0
- package/control-plane/scripts/projects/trusted-roots-projects.mjs +375 -0
- package/control-plane/scripts/prompts/index.mjs +60 -0
- package/control-plane/scripts/remote-process-sessions.mjs +78 -0
- package/control-plane/scripts/remote-tool-result.mjs +9 -0
- package/control-plane/scripts/resources/index.mjs +166 -0
- package/control-plane/scripts/runtime-profile.mjs +54 -0
- package/control-plane/scripts/shell-tool-descriptor.mjs +17 -0
- package/control-plane/scripts/skill-source-safety.mjs +46 -0
- package/control-plane/scripts/skills/README.md +70 -0
- package/control-plane/scripts/skills/_upstream_licenses/anthropic-THIRD_PARTY_NOTICES.md +405 -0
- package/control-plane/scripts/skills/_upstream_licenses/hallmark-LICENSE.txt +21 -0
- package/control-plane/scripts/skills/_upstream_licenses/ponytail-LICENSE.txt +21 -0
- package/control-plane/scripts/skills/_upstream_licenses/stitch-skills-LICENSE.txt +201 -0
- package/control-plane/scripts/skills/_upstream_licenses/superpowers-LICENSE.txt +21 -0
- package/control-plane/scripts/skills/algorithmic-art/LICENSE.txt +202 -0
- package/control-plane/scripts/skills/algorithmic-art/SKILL.md +405 -0
- package/control-plane/scripts/skills/algorithmic-art/templates/generator_template.js +223 -0
- package/control-plane/scripts/skills/algorithmic-art/templates/viewer.html +599 -0
- package/control-plane/scripts/skills/brainstorming/SKILL.md +285 -0
- package/control-plane/scripts/skills/brainstorming/scripts/frame-template.html +213 -0
- package/control-plane/scripts/skills/brainstorming/scripts/helper.js +167 -0
- package/control-plane/scripts/skills/brainstorming/scripts/server.cjs +723 -0
- package/control-plane/scripts/skills/brainstorming/scripts/start-server.sh +209 -0
- package/control-plane/scripts/skills/brainstorming/scripts/stop-server.sh +120 -0
- package/control-plane/scripts/skills/brainstorming/spec-document-reviewer-prompt.md +49 -0
- package/control-plane/scripts/skills/brainstorming/visual-companion.md +299 -0
- package/control-plane/scripts/skills/brand-guidelines/LICENSE.txt +202 -0
- package/control-plane/scripts/skills/brand-guidelines/SKILL.md +73 -0
- package/control-plane/scripts/skills/claude-api/LICENSE.txt +202 -0
- package/control-plane/scripts/skills/claude-api/SKILL.md +570 -0
- package/control-plane/scripts/skills/claude-api/csharp/claude-api/README.md +362 -0
- package/control-plane/scripts/skills/claude-api/csharp/claude-api/batches.md +14 -0
- package/control-plane/scripts/skills/claude-api/csharp/claude-api/files-api.md +25 -0
- package/control-plane/scripts/skills/claude-api/csharp/claude-api/streaming.md +28 -0
- package/control-plane/scripts/skills/claude-api/csharp/claude-api/tool-use.md +164 -0
- package/control-plane/scripts/skills/claude-api/curl/examples.md +256 -0
- package/control-plane/scripts/skills/claude-api/curl/managed-agents.md +371 -0
- package/control-plane/scripts/skills/claude-api/go/claude-api/README.md +188 -0
- package/control-plane/scripts/skills/claude-api/go/claude-api/files-api.md +23 -0
- package/control-plane/scripts/skills/claude-api/go/claude-api/streaming.md +43 -0
- package/control-plane/scripts/skills/claude-api/go/claude-api/tool-use.md +220 -0
- package/control-plane/scripts/skills/claude-api/go/managed-agents/README.md +564 -0
- package/control-plane/scripts/skills/claude-api/java/claude-api/README.md +238 -0
- package/control-plane/scripts/skills/claude-api/java/claude-api/files-api.md +27 -0
- package/control-plane/scripts/skills/claude-api/java/claude-api/streaming.md +24 -0
- package/control-plane/scripts/skills/claude-api/java/claude-api/tool-use.md +228 -0
- package/control-plane/scripts/skills/claude-api/java/managed-agents/README.md +443 -0
- package/control-plane/scripts/skills/claude-api/php/claude-api/README.md +174 -0
- package/control-plane/scripts/skills/claude-api/php/claude-api/batches.md +15 -0
- package/control-plane/scripts/skills/claude-api/php/claude-api/files-api.md +13 -0
- package/control-plane/scripts/skills/claude-api/php/claude-api/streaming.md +27 -0
- package/control-plane/scripts/skills/claude-api/php/claude-api/tool-use.md +253 -0
- package/control-plane/scripts/skills/claude-api/php/managed-agents/README.md +443 -0
- package/control-plane/scripts/skills/claude-api/python/claude-api/README.md +565 -0
- package/control-plane/scripts/skills/claude-api/python/claude-api/batches.md +198 -0
- package/control-plane/scripts/skills/claude-api/python/claude-api/files-api.md +170 -0
- package/control-plane/scripts/skills/claude-api/python/claude-api/sdk-upgrade.md +286 -0
- package/control-plane/scripts/skills/claude-api/python/claude-api/streaming.md +179 -0
- package/control-plane/scripts/skills/claude-api/python/claude-api/tool-use.md +627 -0
- package/control-plane/scripts/skills/claude-api/python/managed-agents/README.md +335 -0
- package/control-plane/scripts/skills/claude-api/ruby/claude-api/README.md +134 -0
- package/control-plane/scripts/skills/claude-api/ruby/claude-api/streaming.md +16 -0
- package/control-plane/scripts/skills/claude-api/ruby/claude-api/tool-use.md +41 -0
- package/control-plane/scripts/skills/claude-api/ruby/managed-agents/README.md +394 -0
- package/control-plane/scripts/skills/claude-api/shared/admin-api.md +179 -0
- package/control-plane/scripts/skills/claude-api/shared/agent-design.md +101 -0
- package/control-plane/scripts/skills/claude-api/shared/anthropic-cli.md +269 -0
- package/control-plane/scripts/skills/claude-api/shared/claude-platform-on-aws.md +59 -0
- package/control-plane/scripts/skills/claude-api/shared/cost-optimization.md +233 -0
- package/control-plane/scripts/skills/claude-api/shared/error-codes.md +262 -0
- package/control-plane/scripts/skills/claude-api/shared/live-sources.md +166 -0
- package/control-plane/scripts/skills/claude-api/shared/managed-agents-api-reference.md +455 -0
- package/control-plane/scripts/skills/claude-api/shared/managed-agents-client-patterns.md +220 -0
- package/control-plane/scripts/skills/claude-api/shared/managed-agents-core.md +359 -0
- package/control-plane/scripts/skills/claude-api/shared/managed-agents-environments.md +226 -0
- package/control-plane/scripts/skills/claude-api/shared/managed-agents-events.md +290 -0
- package/control-plane/scripts/skills/claude-api/shared/managed-agents-memory.md +201 -0
- package/control-plane/scripts/skills/claude-api/shared/managed-agents-multiagent.md +260 -0
- package/control-plane/scripts/skills/claude-api/shared/managed-agents-onboarding.md +82 -0
- package/control-plane/scripts/skills/claude-api/shared/managed-agents-outcomes.md +108 -0
- package/control-plane/scripts/skills/claude-api/shared/managed-agents-overview.md +77 -0
- package/control-plane/scripts/skills/claude-api/shared/managed-agents-scheduled-deployments.md +156 -0
- package/control-plane/scripts/skills/claude-api/shared/managed-agents-self-hosted-sandboxes.md +282 -0
- package/control-plane/scripts/skills/claude-api/shared/managed-agents-tools.md +504 -0
- package/control-plane/scripts/skills/claude-api/shared/managed-agents-webhooks.md +143 -0
- package/control-plane/scripts/skills/claude-api/shared/model-migration.md +1872 -0
- package/control-plane/scripts/skills/claude-api/shared/models.md +142 -0
- package/control-plane/scripts/skills/claude-api/shared/platform-availability.md +52 -0
- package/control-plane/scripts/skills/claude-api/shared/prompt-audit.md +223 -0
- package/control-plane/scripts/skills/claude-api/shared/prompt-caching.md +292 -0
- package/control-plane/scripts/skills/claude-api/shared/token-counting.md +56 -0
- package/control-plane/scripts/skills/claude-api/shared/tool-use-concepts.md +526 -0
- package/control-plane/scripts/skills/claude-api/typescript/claude-api/README.md +405 -0
- package/control-plane/scripts/skills/claude-api/typescript/claude-api/batches.md +106 -0
- package/control-plane/scripts/skills/claude-api/typescript/claude-api/files-api.md +98 -0
- package/control-plane/scripts/skills/claude-api/typescript/claude-api/streaming.md +178 -0
- package/control-plane/scripts/skills/claude-api/typescript/claude-api/tool-use.md +586 -0
- package/control-plane/scripts/skills/claude-api/typescript/managed-agents/README.md +359 -0
- package/control-plane/scripts/skills/dispatching-parallel-agents/SKILL.md +167 -0
- package/control-plane/scripts/skills/enhance-prompt/README.md +34 -0
- package/control-plane/scripts/skills/enhance-prompt/SKILL.md +204 -0
- package/control-plane/scripts/skills/enhance-prompt/references/KEYWORDS.md +114 -0
- package/control-plane/scripts/skills/executing-plans/SKILL.md +371 -0
- package/control-plane/scripts/skills/executing-plans/scripts/task-done +52 -0
- package/control-plane/scripts/skills/executing-plans/scripts/task-start +28 -0
- package/control-plane/scripts/skills/extract-design-md/SKILL.md +358 -0
- package/control-plane/scripts/skills/extract-design-md/examples/DESIGN.md +210 -0
- package/control-plane/scripts/skills/extract-design-md/references/angular.md +122 -0
- package/control-plane/scripts/skills/extract-design-md/references/plain-css.md +161 -0
- package/control-plane/scripts/skills/extract-design-md/references/react-tailwind.md +157 -0
- package/control-plane/scripts/skills/extract-design-md/references/svelte.md +101 -0
- package/control-plane/scripts/skills/extract-design-md/references/vue.md +107 -0
- package/control-plane/scripts/skills/finishing-a-development-branch/SKILL.md +225 -0
- package/control-plane/scripts/skills/frontend-design/LICENSE.txt +177 -0
- package/control-plane/scripts/skills/frontend-design/SKILL.md +71 -0
- package/control-plane/scripts/skills/hallmark/SKILL.md +558 -0
- package/control-plane/scripts/skills/hallmark/references/anti-patterns.md +418 -0
- package/control-plane/scripts/skills/hallmark/references/assets.md +406 -0
- package/control-plane/scripts/skills/hallmark/references/color.md +95 -0
- package/control-plane/scripts/skills/hallmark/references/component-cookbook.md +263 -0
- package/control-plane/scripts/skills/hallmark/references/components/c1-outlined-chip.md +12 -0
- package/control-plane/scripts/skills/hallmark/references/components/c2-inline-form-as-cta.md +16 -0
- package/control-plane/scripts/skills/hallmark/references/components/c3-typographic-link.md +8 -0
- package/control-plane/scripts/skills/hallmark/references/components/c4-sticky-bottom-bar.md +16 -0
- package/control-plane/scripts/skills/hallmark/references/components/f1-bento-grid.md +20 -0
- package/control-plane/scripts/skills/hallmark/references/components/f2-sticky-scroll-stack.md +20 -0
- package/control-plane/scripts/skills/hallmark/references/components/f3-tabular-spec-sheet.md +11 -0
- package/control-plane/scripts/skills/hallmark/references/components/f4-step-sequence.md +11 -0
- package/control-plane/scripts/skills/hallmark/references/components/f5-annotated-screenshot.md +11 -0
- package/control-plane/scripts/skills/hallmark/references/components/f6-product-card-grid.md +41 -0
- package/control-plane/scripts/skills/hallmark/references/components/ft1-mast-headed.md +13 -0
- package/control-plane/scripts/skills/hallmark/references/components/ft2-inline-rule-single-line.md +10 -0
- package/control-plane/scripts/skills/hallmark/references/components/ft3-index-style-category-list.md +12 -0
- package/control-plane/scripts/skills/hallmark/references/components/ft4-dense-typographic.md +10 -0
- package/control-plane/scripts/skills/hallmark/references/components/ft5-statement.md +21 -0
- package/control-plane/scripts/skills/hallmark/references/components/ft6-letter-close.md +19 -0
- package/control-plane/scripts/skills/hallmark/references/components/ft7-newsletter-first.md +27 -0
- package/control-plane/scripts/skills/hallmark/references/components/ft8-marquee-scroll.md +25 -0
- package/control-plane/scripts/skills/hallmark/references/components/h1-marquee.md +15 -0
- package/control-plane/scripts/skills/hallmark/references/components/h2-split-diptych.md +15 -0
- package/control-plane/scripts/skills/hallmark/references/components/h3-quote-led.md +11 -0
- package/control-plane/scripts/skills/hallmark/references/components/h4-stat-led.md +14 -0
- package/control-plane/scripts/skills/hallmark/references/components/h5-letter-hero.md +11 -0
- package/control-plane/scripts/skills/hallmark/references/components/h6-photographic-fold.md +16 -0
- package/control-plane/scripts/skills/hallmark/references/components/h7-demo-video-clipped-by-viewport-edge.md +27 -0
- package/control-plane/scripts/skills/hallmark/references/components/h8-mockup-split-browser-framed.md +23 -0
- package/control-plane/scripts/skills/hallmark/references/components/h9-custom-illustration-centerpiece.md +27 -0
- package/control-plane/scripts/skills/hallmark/references/components/n1-wordmark-2-links.md +12 -0
- package/control-plane/scripts/skills/hallmark/references/components/n10-floating-on-scroll-morph.md +19 -0
- package/control-plane/scripts/skills/hallmark/references/components/n11-mega-menu.md +40 -0
- package/control-plane/scripts/skills/hallmark/references/components/n12-banner-retract.md +34 -0
- package/control-plane/scripts/skills/hallmark/references/components/n13-inline-cmdk-pill.md +39 -0
- package/control-plane/scripts/skills/hallmark/references/components/n1b-saas-three-section.md +35 -0
- package/control-plane/scripts/skills/hallmark/references/components/n2-floating-chip.md +14 -0
- package/control-plane/scripts/skills/hallmark/references/components/n3-side-rail.md +14 -0
- package/control-plane/scripts/skills/hallmark/references/components/n4-hidden-behind-k.md +9 -0
- package/control-plane/scripts/skills/hallmark/references/components/n5-floating-pill.md +28 -0
- package/control-plane/scripts/skills/hallmark/references/components/n6-newspaper-masthead.md +24 -0
- package/control-plane/scripts/skills/hallmark/references/components/n7-brutal-slab.md +22 -0
- package/control-plane/scripts/skills/hallmark/references/components/n8-terminal-command.md +21 -0
- package/control-plane/scripts/skills/hallmark/references/components/n9-edge-aligned-minimal.md +17 -0
- package/control-plane/scripts/skills/hallmark/references/components/s1-left-margin-numbered.md +15 -0
- package/control-plane/scripts/skills/hallmark/references/components/s2-hanging.md +13 -0
- package/control-plane/scripts/skills/hallmark/references/components/s3-sticky-pinned.md +19 -0
- package/control-plane/scripts/skills/hallmark/references/components/s4-inline-no-break.md +11 -0
- package/control-plane/scripts/skills/hallmark/references/components/s5-bottom-anchored.md +13 -0
- package/control-plane/scripts/skills/hallmark/references/components/t1-pull-quote-with-marginalia.md +12 -0
- package/control-plane/scripts/skills/hallmark/references/components/t2-logo-wall-hairline.md +19 -0
- package/control-plane/scripts/skills/hallmark/references/components/t3-single-huge-quote.md +11 -0
- package/control-plane/scripts/skills/hallmark/references/components/t4-numbered-stat-strip.md +14 -0
- package/control-plane/scripts/skills/hallmark/references/contract.md +25 -0
- package/control-plane/scripts/skills/hallmark/references/copy.md +182 -0
- package/control-plane/scripts/skills/hallmark/references/custom-craft.md +626 -0
- package/control-plane/scripts/skills/hallmark/references/custom-theme.md +367 -0
- package/control-plane/scripts/skills/hallmark/references/design-md.md +116 -0
- package/control-plane/scripts/skills/hallmark/references/export-formats.md +329 -0
- package/control-plane/scripts/skills/hallmark/references/floating-nav.md +89 -0
- package/control-plane/scripts/skills/hallmark/references/genres/atmospheric.md +69 -0
- package/control-plane/scripts/skills/hallmark/references/genres/editorial.md +72 -0
- package/control-plane/scripts/skills/hallmark/references/genres/modern-minimal.md +71 -0
- package/control-plane/scripts/skills/hallmark/references/genres/playful.md +70 -0
- package/control-plane/scripts/skills/hallmark/references/hero-enrichment.md +475 -0
- package/control-plane/scripts/skills/hallmark/references/imagery-kit.md +170 -0
- package/control-plane/scripts/skills/hallmark/references/interaction-and-states.md +208 -0
- package/control-plane/scripts/skills/hallmark/references/layout-and-space.md +112 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/01-bento-grid.md +35 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/02-long-document.md +34 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/03-marquee-hero.md +31 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/04-stat-led.md +34 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/05-workbench.md +32 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/06-conversational-faq.md +33 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/07-manifesto.md +32 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/08-photographic.md +34 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/09-quote-led.md +32 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/10-specimen.md +32 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/11-catalogue.md +23 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/12-letter.md +23 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/13-index-first.md +23 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/14-narrative-workflow.md +23 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/15-split-studio.md +23 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/16-feature-stack.md +23 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/17-type-specimen.md +23 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/18-portfolio-grid.md +23 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/19-map-diagram.md +23 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/20-ecosystem-index.md +23 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures/21-component-playground.md +23 -0
- package/control-plane/scripts/skills/hallmark/references/macrostructures.md +89 -0
- package/control-plane/scripts/skills/hallmark/references/microinteractions.md +258 -0
- package/control-plane/scripts/skills/hallmark/references/motion.md +109 -0
- package/control-plane/scripts/skills/hallmark/references/preview-examples.md +49 -0
- package/control-plane/scripts/skills/hallmark/references/responsive.md +138 -0
- package/control-plane/scripts/skills/hallmark/references/slop-test.md +192 -0
- package/control-plane/scripts/skills/hallmark/references/structure.md +160 -0
- package/control-plane/scripts/skills/hallmark/references/study.md +509 -0
- package/control-plane/scripts/skills/hallmark/references/themes/carnival.md +301 -0
- package/control-plane/scripts/skills/hallmark/references/themes/cobalt.md +146 -0
- package/control-plane/scripts/skills/hallmark/references/themes/grid.md +161 -0
- package/control-plane/scripts/skills/hallmark/references/themes/hum.md +403 -0
- package/control-plane/scripts/skills/hallmark/references/themes/lumen.md +478 -0
- package/control-plane/scripts/skills/hallmark/references/typography.md +243 -0
- package/control-plane/scripts/skills/hallmark/references/upstream/recipes.md +186 -0
- package/control-plane/scripts/skills/hallmark/references/upstream/study-examples.md +176 -0
- package/control-plane/scripts/skills/hallmark/references/upstream/tokens.css +1221 -0
- package/control-plane/scripts/skills/hallmark/references/verbs/audit.md +25 -0
- package/control-plane/scripts/skills/hallmark/references/verbs/redesign.md +269 -0
- package/control-plane/scripts/skills/human-comms/SKILL.md +29 -0
- package/control-plane/scripts/skills/index.mjs +432 -0
- package/control-plane/scripts/skills/internal-comms/LICENSE.txt +202 -0
- package/control-plane/scripts/skills/internal-comms/SKILL.md +32 -0
- package/control-plane/scripts/skills/internal-comms/examples/3p-updates.md +47 -0
- package/control-plane/scripts/skills/internal-comms/examples/company-newsletter.md +65 -0
- package/control-plane/scripts/skills/internal-comms/examples/faq-answers.md +30 -0
- package/control-plane/scripts/skills/internal-comms/examples/general-comms.md +16 -0
- package/control-plane/scripts/skills/mcp-adapter.mjs +94 -0
- package/control-plane/scripts/skills/mcp-builder/LICENSE.txt +202 -0
- package/control-plane/scripts/skills/mcp-builder/SKILL.md +236 -0
- package/control-plane/scripts/skills/mcp-builder/reference/evaluation.md +602 -0
- package/control-plane/scripts/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
- package/control-plane/scripts/skills/mcp-builder/reference/node_mcp_server.md +970 -0
- package/control-plane/scripts/skills/mcp-builder/reference/python_mcp_server.md +719 -0
- package/control-plane/scripts/skills/mcp-builder/scripts/connections.py +151 -0
- package/control-plane/scripts/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/control-plane/scripts/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/control-plane/scripts/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/control-plane/scripts/skills/ponytail/SKILL.md +120 -0
- package/control-plane/scripts/skills/ponytail-audit/SKILL.md +41 -0
- package/control-plane/scripts/skills/ponytail-debt/SKILL.md +44 -0
- package/control-plane/scripts/skills/ponytail-gain/SKILL.md +50 -0
- package/control-plane/scripts/skills/ponytail-help/SKILL.md +71 -0
- package/control-plane/scripts/skills/ponytail-review/SKILL.md +57 -0
- package/control-plane/scripts/skills/receiving-code-review/SKILL.md +205 -0
- package/control-plane/scripts/skills/requesting-code-review/SKILL.md +95 -0
- package/control-plane/scripts/skills/requesting-code-review/code-reviewer.md +198 -0
- package/control-plane/scripts/skills/skill-creator/LICENSE.txt +202 -0
- package/control-plane/scripts/skills/skill-creator/SKILL.md +485 -0
- package/control-plane/scripts/skills/skill-creator/agents/analyzer.md +274 -0
- package/control-plane/scripts/skills/skill-creator/agents/comparator.md +202 -0
- package/control-plane/scripts/skills/skill-creator/agents/grader.md +223 -0
- package/control-plane/scripts/skills/skill-creator/assets/eval_review.html +146 -0
- package/control-plane/scripts/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/control-plane/scripts/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/control-plane/scripts/skills/skill-creator/references/schemas.md +430 -0
- package/control-plane/scripts/skills/skill-creator/scripts/__init__.py +0 -0
- package/control-plane/scripts/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/control-plane/scripts/skills/skill-creator/scripts/generate_report.py +326 -0
- package/control-plane/scripts/skills/skill-creator/scripts/improve_description.py +247 -0
- package/control-plane/scripts/skills/skill-creator/scripts/package_skill.py +136 -0
- package/control-plane/scripts/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/control-plane/scripts/skills/skill-creator/scripts/run_eval.py +310 -0
- package/control-plane/scripts/skills/skill-creator/scripts/run_loop.py +328 -0
- package/control-plane/scripts/skills/skill-creator/scripts/utils.py +47 -0
- package/control-plane/scripts/skills/slack-gif-creator/LICENSE.txt +202 -0
- package/control-plane/scripts/skills/slack-gif-creator/SKILL.md +254 -0
- package/control-plane/scripts/skills/slack-gif-creator/core/easing.py +234 -0
- package/control-plane/scripts/skills/slack-gif-creator/core/frame_composer.py +176 -0
- package/control-plane/scripts/skills/slack-gif-creator/core/gif_builder.py +269 -0
- package/control-plane/scripts/skills/slack-gif-creator/core/validators.py +136 -0
- package/control-plane/scripts/skills/slack-gif-creator/requirements.txt +4 -0
- package/control-plane/scripts/skills/sources.json +401 -0
- package/control-plane/scripts/skills/sources.lock.json +416 -0
- package/control-plane/scripts/skills/subagent-driven-development/SKILL.md +570 -0
- package/control-plane/scripts/skills/subagent-driven-development/implementer-prompt.md +154 -0
- package/control-plane/scripts/skills/subagent-driven-development/re-review-prompt.md +115 -0
- package/control-plane/scripts/skills/subagent-driven-development/scripts/review-package +53 -0
- package/control-plane/scripts/skills/subagent-driven-development/scripts/sdd-workspace +82 -0
- package/control-plane/scripts/skills/subagent-driven-development/scripts/task-brief +43 -0
- package/control-plane/scripts/skills/subagent-driven-development/task-reviewer-prompt.md +207 -0
- package/control-plane/scripts/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/control-plane/scripts/skills/systematic-debugging/SKILL.md +283 -0
- package/control-plane/scripts/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/control-plane/scripts/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/control-plane/scripts/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/control-plane/scripts/skills/systematic-debugging/find-polluter.sh +72 -0
- package/control-plane/scripts/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/control-plane/scripts/skills/systematic-debugging/test-academic.md +14 -0
- package/control-plane/scripts/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/control-plane/scripts/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/control-plane/scripts/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/control-plane/scripts/skills/test-driven-development/SKILL.md +330 -0
- package/control-plane/scripts/skills/test-driven-development/writing-good-tests.md +198 -0
- package/control-plane/scripts/skills/theme-factory/LICENSE.txt +202 -0
- package/control-plane/scripts/skills/theme-factory/SKILL.md +59 -0
- package/control-plane/scripts/skills/theme-factory/theme-showcase.pdf +0 -0
- package/control-plane/scripts/skills/theme-factory/themes/arctic-frost.md +19 -0
- package/control-plane/scripts/skills/theme-factory/themes/botanical-garden.md +19 -0
- package/control-plane/scripts/skills/theme-factory/themes/desert-rose.md +19 -0
- package/control-plane/scripts/skills/theme-factory/themes/forest-canopy.md +19 -0
- package/control-plane/scripts/skills/theme-factory/themes/golden-hour.md +19 -0
- package/control-plane/scripts/skills/theme-factory/themes/midnight-galaxy.md +19 -0
- package/control-plane/scripts/skills/theme-factory/themes/modern-minimalist.md +19 -0
- package/control-plane/scripts/skills/theme-factory/themes/ocean-depths.md +19 -0
- package/control-plane/scripts/skills/theme-factory/themes/sunset-boulevard.md +19 -0
- package/control-plane/scripts/skills/theme-factory/themes/tech-innovation.md +19 -0
- package/control-plane/scripts/skills/using-git-worktrees/SKILL.md +167 -0
- package/control-plane/scripts/skills/verification-before-completion/SKILL.md +120 -0
- package/control-plane/scripts/skills/web-artifacts-builder/LICENSE.txt +202 -0
- package/control-plane/scripts/skills/web-artifacts-builder/SKILL.md +74 -0
- package/control-plane/scripts/skills/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/control-plane/scripts/skills/web-artifacts-builder/scripts/init-artifact.sh +322 -0
- package/control-plane/scripts/skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/control-plane/scripts/skills/webapp-testing/LICENSE.txt +202 -0
- package/control-plane/scripts/skills/webapp-testing/SKILL.md +96 -0
- package/control-plane/scripts/skills/webapp-testing/examples/console_logging.py +35 -0
- package/control-plane/scripts/skills/webapp-testing/examples/element_discovery.py +40 -0
- package/control-plane/scripts/skills/webapp-testing/examples/static_html_automation.py +33 -0
- package/control-plane/scripts/skills/webapp-testing/scripts/with_server.py +106 -0
- package/control-plane/scripts/skills/writing-plans/SKILL.md +192 -0
- package/control-plane/scripts/skills/writing-plans/plan-document-reviewer-prompt.md +49 -0
- package/control-plane/scripts/skills/writing-skills/SKILL.md +681 -0
- package/control-plane/scripts/skills/writing-skills/anthropic-best-practices.md +1150 -0
- package/control-plane/scripts/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- package/control-plane/scripts/skills/writing-skills/graphviz-conventions.dot +172 -0
- package/control-plane/scripts/skills/writing-skills/persuasion-principles.md +187 -0
- package/control-plane/scripts/skills/writing-skills/render-graphs.js +169 -0
- package/control-plane/scripts/skills/writing-skills/testing-skills-with-subagents.md +384 -0
- package/control-plane/scripts/smoke-mcp-schemas.mjs +30 -0
- package/control-plane/scripts/surface-config.mjs +45 -0
- package/control-plane/scripts/sync-skills.mjs +370 -0
- package/control-plane/scripts/tool-metrics.mjs +74 -0
- package/control-plane/scripts/tool-risk.mjs +156 -0
- package/control-plane/scripts/tool-surface-stability.mjs +38 -0
- package/control-plane/scripts/upstreams/catalog-cache.mjs +28 -0
- package/control-plane/scripts/upstreams/config.mjs +158 -0
- package/control-plane/scripts/upstreams/diagnostics.mjs +21 -0
- package/control-plane/scripts/upstreams/http-client.mjs +67 -0
- package/control-plane/scripts/upstreams/manager.mjs +535 -0
- package/control-plane/scripts/upstreams/names.mjs +55 -0
- package/control-plane/scripts/upstreams/presets.mjs +60 -0
- package/control-plane/scripts/upstreams/resource-uri.mjs +29 -0
- package/control-plane/scripts/upstreams/stdio-client.mjs +73 -0
- package/control-plane/scripts/workspace-registry.mjs +147 -0
- package/dist/context/authorization.d.ts +5 -0
- package/dist/context/authorization.js +70 -0
- package/dist/context/capture.d.ts +46 -0
- package/dist/context/capture.js +187 -0
- package/dist/context/cli.d.ts +47 -0
- package/dist/context/cli.js +287 -0
- package/dist/context/device-adapter.d.ts +102 -0
- package/dist/context/device-adapter.js +79 -0
- package/dist/context/gateway.d.ts +354 -0
- package/dist/context/gateway.js +50 -0
- package/dist/context/graph.d.ts +63 -0
- package/dist/context/graph.js +214 -0
- package/dist/context/importer.d.ts +8 -0
- package/dist/context/importer.js +69 -0
- package/dist/context/indexer.d.ts +14 -0
- package/dist/context/indexer.js +57 -0
- package/dist/context/migrations/index.d.ts +4 -0
- package/dist/context/migrations/index.js +87 -0
- package/dist/context/redact.d.ts +15 -0
- package/dist/context/redact.js +43 -0
- package/dist/context/repositories.d.ts +9 -0
- package/dist/context/repositories.js +45 -0
- package/dist/context/search.d.ts +63 -0
- package/dist/context/search.js +207 -0
- package/dist/context/service.d.ts +278 -0
- package/dist/context/service.js +160 -0
- package/dist/context/store.d.ts +134 -0
- package/dist/context/store.js +722 -0
- package/dist/context/text.d.ts +4 -0
- package/dist/context/text.js +14 -0
- package/dist/context/tool-contract.d.ts +534 -0
- package/dist/context/tool-contract.js +45 -0
- package/dist/device/core.d.ts +29 -0
- package/dist/device/core.js +66 -0
- package/dist/device/device.d.ts +5 -0
- package/dist/device/device.js +94 -37
- package/dist/device/gateway-channel.d.ts +8 -1
- package/dist/device/gateway-channel.js +51 -3
- package/dist/device/gateway-tool-adapter.d.ts +11 -3
- package/dist/device/gateway-tool-adapter.js +141 -98
- package/dist/device/official-trust.d.ts +12 -0
- package/dist/device/official-trust.js +25 -1
- package/dist/device/runtime-owner.js +9 -1
- package/dist/distribution.d.ts +4 -0
- package/dist/distribution.js +8 -0
- package/dist/handlers/filesystem-handlers.js +53 -37
- package/dist/handlers/search-handlers.d.ts +1 -0
- package/dist/handlers/search-handlers.js +51 -1
- package/dist/log-palace/cli.d.ts +7 -0
- package/dist/log-palace/cli.js +89 -0
- package/dist/log-palace/formats.d.ts +26 -0
- package/dist/log-palace/formats.js +126 -0
- package/dist/log-palace/store.d.ts +129 -0
- package/dist/log-palace/store.js +856 -0
- package/dist/mcp-device.d.ts +1 -1
- package/dist/mcp-device.js +28 -6
- package/dist/npm-scripts/remote.js +1 -0
- package/dist/platform/activity-journal.d.ts +16 -0
- package/dist/platform/activity-journal.js +68 -0
- package/dist/platform/cli.d.ts +1 -0
- package/dist/platform/cli.js +300 -0
- package/dist/platform/coordination-lock.d.ts +45 -0
- package/dist/platform/coordination-lock.js +233 -0
- package/dist/platform/device-runtime.d.ts +16 -0
- package/dist/platform/device-runtime.js +83 -0
- package/dist/platform/knowledge-contract.d.ts +46 -0
- package/dist/platform/knowledge-contract.js +1 -0
- package/dist/platform/knowledge-mcp.d.ts +29 -0
- package/dist/platform/knowledge-mcp.js +95 -0
- package/dist/platform/knowledge-router.d.ts +64 -0
- package/dist/platform/knowledge-router.js +320 -0
- package/dist/platform/plugin-child.d.ts +1 -0
- package/dist/platform/plugin-child.js +115 -0
- package/dist/platform/plugin-contract.d.ts +76 -0
- package/dist/platform/plugin-contract.js +53 -0
- package/dist/platform/plugin-driver.d.ts +8 -0
- package/dist/platform/plugin-driver.js +443 -0
- package/dist/platform/plugin-host.d.ts +88 -0
- package/dist/platform/plugin-host.js +817 -0
- package/dist/platform/plugin-policy.d.ts +3 -0
- package/dist/platform/plugin-policy.js +29 -0
- package/dist/platform/plugin-services.d.ts +14 -0
- package/dist/platform/plugin-services.js +32 -0
- package/dist/platform/process-identity.d.ts +9 -0
- package/dist/platform/process-identity.js +68 -0
- package/dist/platform/runtime-lease.d.ts +4 -0
- package/dist/platform/runtime-lease.js +58 -0
- package/dist/platform/runtime-root.d.ts +9 -0
- package/dist/platform/runtime-root.js +61 -0
- package/dist/platform/state-backup.d.ts +92 -0
- package/dist/platform/state-backup.js +399 -0
- package/dist/plugins/reference/plugin.d.ts +3 -0
- package/dist/plugins/reference/plugin.js +13 -0
- package/dist/search-manager.d.ts +6 -0
- package/dist/search-manager.js +123 -0
- package/dist/server.d.ts +13 -0
- package/dist/server.js +7 -3
- package/dist/terminal-manager.d.ts +16 -0
- package/dist/terminal-manager.js +137 -42
- package/dist/tool-dispatcher.d.ts +11 -0
- package/dist/tool-dispatcher.js +228 -0
- package/dist/tools/edit.js +72 -1
- package/dist/tools/filesystem.d.ts +1 -1
- package/dist/tools/filesystem.js +2 -2
- package/dist/tools/improved-process-tools.js +91 -108
- package/dist/tools/schemas.d.ts +94 -2
- package/dist/tools/schemas.js +20 -6
- package/dist/types.d.ts +8 -0
- package/dist/utils/output-budget.d.ts +6 -0
- package/dist/utils/output-budget.js +15 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +29 -6
- package/skills/mcp-device-context/SKILL.md +40 -0
package/dist/terminal-manager.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
2
3
|
import path from 'path';
|
|
3
4
|
import { DEFAULT_COMMAND_TIMEOUT } from './config.js';
|
|
4
5
|
import { configManager } from './config-manager.js';
|
|
@@ -102,6 +103,11 @@ export class TerminalManager {
|
|
|
102
103
|
constructor() {
|
|
103
104
|
this.sessions = new Map();
|
|
104
105
|
this.completedSessions = new Map();
|
|
106
|
+
this.runtimeGeneration = randomUUID();
|
|
107
|
+
}
|
|
108
|
+
processIdentity(pid) {
|
|
109
|
+
const session = this.sessions.get(pid) ?? this.completedSessions.get(pid);
|
|
110
|
+
return session ? { execution_id: session.executionId, runtime_generation: this.runtimeGeneration, pid } : undefined;
|
|
105
111
|
}
|
|
106
112
|
/**
|
|
107
113
|
* Send input to a running process
|
|
@@ -129,6 +135,9 @@ export class TerminalManager {
|
|
|
129
135
|
}
|
|
130
136
|
}
|
|
131
137
|
async executeCommand(command, timeoutMs = DEFAULT_COMMAND_TIMEOUT, shell, collectTiming = false, workingDirectory) {
|
|
138
|
+
const configuredWaitCap = Number(await configManager.getValue('maxProcessWaitMs'));
|
|
139
|
+
const waitCapMs = Number.isFinite(configuredWaitCap) && configuredWaitCap > 0 ? configuredWaitCap : 180000;
|
|
140
|
+
const effectiveWaitMs = Math.min(Math.max(0, timeoutMs), waitCapMs);
|
|
132
141
|
// Get the shell from config if not specified
|
|
133
142
|
let shellToUse = shell;
|
|
134
143
|
if (!shellToUse) {
|
|
@@ -185,6 +194,8 @@ export class TerminalManager {
|
|
|
185
194
|
...(workingDirectory ? { cwd: workingDirectory } : {})
|
|
186
195
|
};
|
|
187
196
|
}
|
|
197
|
+
// Inherited by nested shells/PTYs: a process-tool terminal is not owner-admin consent.
|
|
198
|
+
spawnOptions.env.MCP_DEVICE_SESSION = 'process-tool';
|
|
188
199
|
// Repair PATHEXT on Windows before spawning. On some Windows DXT launches
|
|
189
200
|
// the server process inherits a corrupted PATHEXT (e.g. ".CPL"), which we
|
|
190
201
|
// would otherwise propagate via { ...process.env } and break command
|
|
@@ -229,11 +240,32 @@ export class TerminalManager {
|
|
|
229
240
|
isBlocked: false
|
|
230
241
|
};
|
|
231
242
|
}
|
|
243
|
+
// PID collision / reuse stopgap (1.0.10 P2.1):
|
|
244
|
+
// If a session with this PID already exists:
|
|
245
|
+
// - Check active sessions: if still live, reject with an explicit error to prevent aliasing.
|
|
246
|
+
// - Check completed sessions: if stale completed session exists, evict it cleanly.
|
|
247
|
+
if (this.sessions.has(childProcess.pid)) {
|
|
248
|
+
try {
|
|
249
|
+
childProcess.kill();
|
|
250
|
+
}
|
|
251
|
+
catch (killErr) {
|
|
252
|
+
console.error(`Failed to kill conflicting child process ${childProcess.pid}:`, killErr);
|
|
253
|
+
}
|
|
254
|
+
throw new Error(`PID collision detected: process ${childProcess.pid} is already running under an active session.`);
|
|
255
|
+
}
|
|
256
|
+
if (this.completedSessions.has(childProcess.pid)) {
|
|
257
|
+
console.warn(`[PID Collision] Evicting stale completed session for PID ${childProcess.pid}`);
|
|
258
|
+
this.completedSessions.delete(childProcess.pid);
|
|
259
|
+
}
|
|
232
260
|
const session = {
|
|
261
|
+
executionId: randomUUID(),
|
|
233
262
|
pid: childProcess.pid,
|
|
234
263
|
process: childProcess,
|
|
235
264
|
outputLines: [], // Line-based buffer
|
|
236
265
|
lastReadIndex: 0, // Track where "new" output starts
|
|
266
|
+
lastReadOffset: 0, // Character offset inside a partially consumed line
|
|
267
|
+
outputVersion: 0,
|
|
268
|
+
outputWaiters: new Set(),
|
|
237
269
|
isBlocked: false,
|
|
238
270
|
startTime: new Date(),
|
|
239
271
|
bufferedChars: 0,
|
|
@@ -256,6 +288,10 @@ export class TerminalManager {
|
|
|
256
288
|
if (resolved)
|
|
257
289
|
return;
|
|
258
290
|
resolved = true;
|
|
291
|
+
if (session.outputLines.length > 0) {
|
|
292
|
+
const lineIndex = session.outputLines.length - 1;
|
|
293
|
+
result.deliveredCursor = { lineIndex, lineOffset: session.outputLines[lineIndex].length };
|
|
294
|
+
}
|
|
259
295
|
if (periodicCheck)
|
|
260
296
|
clearInterval(periodicCheck);
|
|
261
297
|
// Add timing info if requested
|
|
@@ -388,32 +424,36 @@ export class TerminalManager {
|
|
|
388
424
|
output,
|
|
389
425
|
isBlocked: true
|
|
390
426
|
});
|
|
391
|
-
},
|
|
427
|
+
}, effectiveWaitMs);
|
|
428
|
+
let processExitCode = null;
|
|
392
429
|
childProcess.on('exit', (code) => {
|
|
393
|
-
|
|
394
|
-
// Store completed session before removing active session
|
|
395
|
-
this.completedSessions.set(childProcess.pid, {
|
|
396
|
-
pid: childProcess.pid,
|
|
397
|
-
outputLines: [...session.outputLines], // Copy line buffer
|
|
398
|
-
exitCode: code,
|
|
399
|
-
startTime: session.startTime,
|
|
400
|
-
endTime: new Date(),
|
|
401
|
-
evictedLines: session.evictedLines,
|
|
402
|
-
evictedChars: session.evictedChars
|
|
403
|
-
});
|
|
404
|
-
// Keep only last 100 completed sessions
|
|
405
|
-
if (this.completedSessions.size > 100) {
|
|
406
|
-
const oldestKey = Array.from(this.completedSessions.keys())[0];
|
|
407
|
-
this.completedSessions.delete(oldestKey);
|
|
408
|
-
}
|
|
409
|
-
this.sessions.delete(childProcess.pid);
|
|
410
|
-
}
|
|
430
|
+
processExitCode = code;
|
|
411
431
|
exitReason = 'process_exit';
|
|
412
|
-
resolveOnce({
|
|
432
|
+
resolveOnce({ pid: childProcess.pid, output, isBlocked: false });
|
|
433
|
+
});
|
|
434
|
+
// Finalize only after stdio has closed so fast-exit stdout/stderr cannot be lost.
|
|
435
|
+
childProcess.on('close', (code) => {
|
|
436
|
+
if (!childProcess.pid)
|
|
437
|
+
return;
|
|
438
|
+
this.completedSessions.set(childProcess.pid, {
|
|
439
|
+
executionId: session.executionId,
|
|
413
440
|
pid: childProcess.pid,
|
|
414
|
-
|
|
415
|
-
|
|
441
|
+
outputLines: [...session.outputLines],
|
|
442
|
+
exitCode: processExitCode ?? code,
|
|
443
|
+
startTime: session.startTime,
|
|
444
|
+
endTime: new Date(),
|
|
445
|
+
evictedLines: session.evictedLines,
|
|
446
|
+
evictedChars: session.evictedChars,
|
|
447
|
+
lastReadIndex: session.lastReadIndex,
|
|
448
|
+
lastReadOffset: session.lastReadOffset,
|
|
449
|
+
bufferedChars: session.bufferedChars
|
|
416
450
|
});
|
|
451
|
+
if (this.completedSessions.size > 100) {
|
|
452
|
+
const oldestKey = Array.from(this.completedSessions.keys())[0];
|
|
453
|
+
this.completedSessions.delete(oldestKey);
|
|
454
|
+
}
|
|
455
|
+
this.notifyOutputProgress(session);
|
|
456
|
+
this.sessions.delete(childProcess.pid);
|
|
417
457
|
});
|
|
418
458
|
});
|
|
419
459
|
}
|
|
@@ -421,6 +461,27 @@ export class TerminalManager {
|
|
|
421
461
|
* Append text to a session's line buffer
|
|
422
462
|
* Handles partial lines and newline splitting
|
|
423
463
|
*/
|
|
464
|
+
notifyOutputProgress(session) {
|
|
465
|
+
session.outputVersion++;
|
|
466
|
+
for (const waiter of session.outputWaiters)
|
|
467
|
+
waiter();
|
|
468
|
+
session.outputWaiters.clear();
|
|
469
|
+
}
|
|
470
|
+
async waitForOutputProgress(pid, sinceVersion, timeoutMs) {
|
|
471
|
+
const session = this.sessions.get(pid);
|
|
472
|
+
if (!session || session.outputVersion !== sinceVersion)
|
|
473
|
+
return;
|
|
474
|
+
await new Promise((resolve) => {
|
|
475
|
+
let timer;
|
|
476
|
+
const done = () => {
|
|
477
|
+
session.outputWaiters.delete(done);
|
|
478
|
+
clearTimeout(timer);
|
|
479
|
+
resolve();
|
|
480
|
+
};
|
|
481
|
+
session.outputWaiters.add(done);
|
|
482
|
+
timer = setTimeout(done, timeoutMs);
|
|
483
|
+
});
|
|
484
|
+
}
|
|
424
485
|
appendToLineBuffer(session, text) {
|
|
425
486
|
if (!text)
|
|
426
487
|
return;
|
|
@@ -469,6 +530,7 @@ export class TerminalManager {
|
|
|
469
530
|
if (session.lastReadIndex > 0)
|
|
470
531
|
session.lastReadIndex--;
|
|
471
532
|
}
|
|
533
|
+
this.notifyOutputProgress(session);
|
|
472
534
|
}
|
|
473
535
|
/**
|
|
474
536
|
* Read process output with pagination (like file reading)
|
|
@@ -477,9 +539,33 @@ export class TerminalManager {
|
|
|
477
539
|
* @param length Max lines to return
|
|
478
540
|
* @param updateReadIndex Whether to update lastReadIndex (default: true for offset=0)
|
|
479
541
|
*/
|
|
542
|
+
markOutputConsumed(pid, cursor) {
|
|
543
|
+
if (!cursor)
|
|
544
|
+
return;
|
|
545
|
+
const session = this.sessions.get(pid);
|
|
546
|
+
if (session) {
|
|
547
|
+
session.lastReadIndex = Math.min(cursor.lineIndex, Math.max(0, session.outputLines.length - 1));
|
|
548
|
+
session.lastReadOffset = cursor.lineOffset;
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
const completed = this.completedSessions.get(pid);
|
|
552
|
+
if (completed) {
|
|
553
|
+
completed.lastReadIndex = Math.min(cursor.lineIndex, Math.max(0, completed.outputLines.length - 1));
|
|
554
|
+
completed.lastReadOffset = cursor.lineOffset;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
480
557
|
readOutputPaginated(pid, offset = 0, length = 1000) {
|
|
481
558
|
// First check active sessions
|
|
482
559
|
const session = this.sessions.get(pid);
|
|
560
|
+
if (session && offset === 0 && session.outputLines.length > 0) {
|
|
561
|
+
const start = Math.min(session.lastReadIndex, session.outputLines.length - 1);
|
|
562
|
+
const first = session.outputLines[start].slice(session.lastReadOffset);
|
|
563
|
+
const tail = session.outputLines.slice(start + 1, start + length);
|
|
564
|
+
const lines = first || tail.length === 0 ? [first, ...tail] : tail;
|
|
565
|
+
session.lastReadIndex = Math.min(start + lines.length - 1, session.outputLines.length - 1);
|
|
566
|
+
session.lastReadOffset = session.outputLines[session.lastReadIndex].length;
|
|
567
|
+
return { lines, totalLines: session.outputLines.length, readFrom: start, readCount: lines.length, remaining: Math.max(0, session.outputLines.length - start - lines.length), isComplete: false, evictedLines: session.evictedLines };
|
|
568
|
+
}
|
|
483
569
|
if (session) {
|
|
484
570
|
const result = this.readFromLineBuffer(session.outputLines, offset, length, session.lastReadIndex, (newIndex) => { session.lastReadIndex = newIndex; }, false, undefined);
|
|
485
571
|
result.evictedLines = session.evictedLines;
|
|
@@ -489,7 +575,7 @@ export class TerminalManager {
|
|
|
489
575
|
const completedSession = this.completedSessions.get(pid);
|
|
490
576
|
if (completedSession) {
|
|
491
577
|
const runtimeMs = completedSession.endTime.getTime() - completedSession.startTime.getTime();
|
|
492
|
-
const result = this.readFromLineBuffer(completedSession.outputLines, offset, length, 0, //
|
|
578
|
+
const result = this.readFromLineBuffer(completedSession.outputLines, offset, length, 0, // Protected baseline: completed sessions read from beginning and remain replayable
|
|
493
579
|
() => { }, // No-op for completed sessions
|
|
494
580
|
true, completedSession.exitCode, runtimeMs);
|
|
495
581
|
result.evictedLines = completedSession.evictedLines;
|
|
@@ -588,17 +674,12 @@ export class TerminalManager {
|
|
|
588
674
|
*/
|
|
589
675
|
captureOutputSnapshot(pid) {
|
|
590
676
|
const session = this.sessions.get(pid);
|
|
591
|
-
if (session)
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
totalChars: session.evictedChars + fullOutput.length,
|
|
598
|
-
lineCount: session.evictedLines + session.outputLines.length
|
|
599
|
-
};
|
|
600
|
-
}
|
|
601
|
-
return null;
|
|
677
|
+
if (!session)
|
|
678
|
+
return null;
|
|
679
|
+
return {
|
|
680
|
+
totalChars: session.evictedChars + session.bufferedChars,
|
|
681
|
+
lineCount: session.evictedLines + session.outputLines.length
|
|
682
|
+
};
|
|
602
683
|
}
|
|
603
684
|
/**
|
|
604
685
|
* Get output that appeared since a snapshot was taken.
|
|
@@ -609,12 +690,12 @@ export class TerminalManager {
|
|
|
609
690
|
// Check active session first
|
|
610
691
|
const session = this.sessions.get(pid);
|
|
611
692
|
if (session) {
|
|
612
|
-
return TerminalManager.outputSinceSnapshot(session.outputLines, session.evictedChars, snapshot.totalChars);
|
|
693
|
+
return TerminalManager.outputSinceSnapshot(session.outputLines, session.bufferedChars, session.evictedChars, snapshot.totalChars);
|
|
613
694
|
}
|
|
614
695
|
// Fallback to completed sessions - process may have finished between snapshot and poll
|
|
615
696
|
const completedSession = this.completedSessions.get(pid);
|
|
616
697
|
if (completedSession) {
|
|
617
|
-
return TerminalManager.outputSinceSnapshot(completedSession.outputLines, completedSession.evictedChars, snapshot.totalChars);
|
|
698
|
+
return TerminalManager.outputSinceSnapshot(completedSession.outputLines, completedSession.bufferedChars, completedSession.evictedChars, snapshot.totalChars);
|
|
618
699
|
}
|
|
619
700
|
return null;
|
|
620
701
|
}
|
|
@@ -623,13 +704,27 @@ export class TerminalManager {
|
|
|
623
704
|
* If eviction dropped part of the unseen output, returns what the buffer
|
|
624
705
|
* still holds — the oldest unseen chars are lost to the cap.
|
|
625
706
|
*/
|
|
626
|
-
static outputSinceSnapshot(outputLines, evictedChars, snapshotTotalChars) {
|
|
627
|
-
const
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
707
|
+
static outputSinceSnapshot(outputLines, bufferedChars, evictedChars, snapshotTotalChars) {
|
|
708
|
+
const newChars = evictedChars + bufferedChars - snapshotTotalChars;
|
|
709
|
+
if (newChars <= 0)
|
|
710
|
+
return '';
|
|
711
|
+
let remaining = newChars;
|
|
712
|
+
const parts = [];
|
|
713
|
+
for (let i = outputLines.length - 1; i >= 0 && remaining > 0; i--) {
|
|
714
|
+
const line = outputLines[i];
|
|
715
|
+
const separator = i < outputLines.length - 1 ? 1 : 0;
|
|
716
|
+
const available = line.length + separator;
|
|
717
|
+
if (remaining >= available) {
|
|
718
|
+
parts.push((separator ? '\n' : '') + line);
|
|
719
|
+
remaining -= available;
|
|
720
|
+
}
|
|
721
|
+
else {
|
|
722
|
+
const suffixLength = Math.max(0, remaining - separator);
|
|
723
|
+
parts.push((separator ? '\n' : '') + line.slice(Math.max(0, line.length - suffixLength)));
|
|
724
|
+
remaining = 0;
|
|
725
|
+
}
|
|
631
726
|
}
|
|
632
|
-
return
|
|
727
|
+
return parts.reverse().join('');
|
|
633
728
|
}
|
|
634
729
|
/**
|
|
635
730
|
* Get a session by PID
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ServerResult } from './types.js';
|
|
2
|
+
export interface DispatchToolOptions {
|
|
3
|
+
isRemote?: boolean;
|
|
4
|
+
clientInfo?: {
|
|
5
|
+
name?: string;
|
|
6
|
+
version?: string;
|
|
7
|
+
};
|
|
8
|
+
origin?: string;
|
|
9
|
+
metadata?: any;
|
|
10
|
+
}
|
|
11
|
+
export declare function dispatchToolCall(name: string, args: any, options?: DispatchToolOptions): Promise<ServerResult>;
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import * as handlers from './handlers/index.js';
|
|
2
|
+
import { getConfig, setConfigValue } from './tools/config.js';
|
|
3
|
+
import { getUsageStats } from './tools/usage.js';
|
|
4
|
+
import { getPrompts } from './tools/prompts.js';
|
|
5
|
+
import { trackToolCall } from './utils/trackTools.js';
|
|
6
|
+
import { usageTracker } from './utils/usageTracker.js';
|
|
7
|
+
import { toolHistory } from './utils/toolHistory.js';
|
|
8
|
+
import { observePublicInvocation, isCapturingInvocation } from './context/capture.js';
|
|
9
|
+
import { capture } from './utils/capture.js';
|
|
10
|
+
import { currentCallIsRemote, setCurrentCallIsRemote, setCurrentRemoteClient, } from './server.js';
|
|
11
|
+
export async function dispatchToolCall(name, args, options = {}) {
|
|
12
|
+
return observePublicInvocation({ tool: name, args }, () => executeToolCall(name, args, options));
|
|
13
|
+
}
|
|
14
|
+
async function executeToolCall(name, args, options) {
|
|
15
|
+
const startTime = Date.now();
|
|
16
|
+
let telemetryData = { tool_name: name };
|
|
17
|
+
let result;
|
|
18
|
+
let isError = false;
|
|
19
|
+
try {
|
|
20
|
+
const isRemoteCall = Boolean(options.isRemote);
|
|
21
|
+
setCurrentCallIsRemote(isRemoteCall);
|
|
22
|
+
if (isRemoteCall) {
|
|
23
|
+
telemetryData.remote = String(options.isRemote);
|
|
24
|
+
const remoteClient = options.clientInfo && (options.clientInfo.name || options.clientInfo.version)
|
|
25
|
+
? options.clientInfo
|
|
26
|
+
: { name: 'remote-unknown', version: 'unknown' };
|
|
27
|
+
setCurrentRemoteClient(remoteClient);
|
|
28
|
+
telemetryData.client_name = remoteClient.name;
|
|
29
|
+
telemetryData.client_version = remoteClient.version;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
setCurrentRemoteClient(null);
|
|
33
|
+
}
|
|
34
|
+
if (name === 'set_config_value' && args && typeof args === 'object' && 'key' in args) {
|
|
35
|
+
telemetryData.set_config_value_key_name = args.key;
|
|
36
|
+
}
|
|
37
|
+
if (name === 'get_prompts' && args && typeof args === 'object') {
|
|
38
|
+
const promptArgs = args;
|
|
39
|
+
telemetryData.action = promptArgs.action;
|
|
40
|
+
if (promptArgs.category) {
|
|
41
|
+
telemetryData.category = promptArgs.category;
|
|
42
|
+
telemetryData.has_category_filter = true;
|
|
43
|
+
}
|
|
44
|
+
if (promptArgs.promptId) {
|
|
45
|
+
telemetryData.prompt_id = promptArgs.promptId;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
trackToolCall(name, args);
|
|
49
|
+
switch (name) {
|
|
50
|
+
case 'get_config':
|
|
51
|
+
try {
|
|
52
|
+
result = await getConfig();
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
capture('server_request_error', { message: `Error in get_config handler: ${error}` });
|
|
56
|
+
result = {
|
|
57
|
+
content: [{ type: 'text', text: 'Error: Failed to get configuration' }],
|
|
58
|
+
isError: true,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
break;
|
|
62
|
+
case 'set_config_value':
|
|
63
|
+
try {
|
|
64
|
+
result = await setConfigValue(args);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
capture('server_request_error', { message: `Error in set_config_value handler: ${error}` });
|
|
68
|
+
result = {
|
|
69
|
+
content: [{ type: 'text', text: 'Error: Failed to set configuration value' }],
|
|
70
|
+
isError: true,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
case 'get_usage_stats':
|
|
75
|
+
try {
|
|
76
|
+
result = await getUsageStats();
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
capture('server_request_error', { message: `Error in get_usage_stats handler: ${error}` });
|
|
80
|
+
result = {
|
|
81
|
+
content: [{ type: 'text', text: 'Error: Failed to get usage statistics' }],
|
|
82
|
+
isError: true,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
break;
|
|
86
|
+
case 'get_prompts':
|
|
87
|
+
try {
|
|
88
|
+
result = await getPrompts(args || {});
|
|
89
|
+
if (args && typeof args === 'object' && !result.isError) {
|
|
90
|
+
const action = args.action;
|
|
91
|
+
try {
|
|
92
|
+
if (action === 'get_prompt' && args.promptId) {
|
|
93
|
+
const { loadPromptsData } = await import('./tools/prompts.js');
|
|
94
|
+
const promptsData = await loadPromptsData();
|
|
95
|
+
const prompt = promptsData.prompts.find(p => p.id === args.promptId);
|
|
96
|
+
if (prompt) {
|
|
97
|
+
await capture('server_get_prompt', {
|
|
98
|
+
prompt_id: prompt.id,
|
|
99
|
+
prompt_title: prompt.title,
|
|
100
|
+
category: prompt.categories[0] || 'uncategorized',
|
|
101
|
+
author: prompt.author,
|
|
102
|
+
verified: prompt.verified,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (error) { }
|
|
108
|
+
}
|
|
109
|
+
const onboardingState = await usageTracker.getOnboardingState();
|
|
110
|
+
if (onboardingState.attemptsShown > 0 && !onboardingState.promptsUsed) {
|
|
111
|
+
await usageTracker.markOnboardingPromptsUsed();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
capture('server_request_error', { message: `Error in get_prompts handler: ${error}` });
|
|
116
|
+
result = {
|
|
117
|
+
content: [{ type: 'text', text: 'Error: Failed to retrieve prompts' }],
|
|
118
|
+
isError: true,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
break;
|
|
122
|
+
case 'get_recent_tool_calls':
|
|
123
|
+
try {
|
|
124
|
+
result = await handlers.handleGetRecentToolCalls(args);
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
capture('server_request_error', { message: `Error in get_recent_tool_calls handler: ${error}` });
|
|
128
|
+
result = {
|
|
129
|
+
content: [{ type: 'text', text: 'Error: Failed to get tool call history' }],
|
|
130
|
+
isError: true,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
break;
|
|
134
|
+
case 'track_ui_event':
|
|
135
|
+
try {
|
|
136
|
+
result = await handlers.handleTrackUiEvent(args);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
capture('server_request_error', { message: `Error in track_ui_event handler: ${error}` });
|
|
140
|
+
result = {
|
|
141
|
+
content: [{ type: 'text', text: 'Error: Failed to track UI event' }],
|
|
142
|
+
isError: true,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
break;
|
|
146
|
+
case 'start_process':
|
|
147
|
+
result = await handlers.handleStartProcess(args);
|
|
148
|
+
break;
|
|
149
|
+
case 'read_process_output':
|
|
150
|
+
result = await handlers.handleReadProcessOutput(args);
|
|
151
|
+
break;
|
|
152
|
+
case 'interact_with_process':
|
|
153
|
+
result = await handlers.handleInteractWithProcess(args);
|
|
154
|
+
break;
|
|
155
|
+
case 'force_terminate':
|
|
156
|
+
result = await handlers.handleForceTerminate(args);
|
|
157
|
+
break;
|
|
158
|
+
case 'list_sessions':
|
|
159
|
+
result = await handlers.handleListSessions();
|
|
160
|
+
break;
|
|
161
|
+
case 'list_processes':
|
|
162
|
+
result = await handlers.handleListProcesses();
|
|
163
|
+
break;
|
|
164
|
+
case 'kill_process':
|
|
165
|
+
result = await handlers.handleKillProcess(args);
|
|
166
|
+
break;
|
|
167
|
+
case 'read_file':
|
|
168
|
+
result = await handlers.handleReadFile(args);
|
|
169
|
+
break;
|
|
170
|
+
case 'read_multiple_files':
|
|
171
|
+
result = await handlers.handleReadMultipleFiles(args);
|
|
172
|
+
break;
|
|
173
|
+
case 'write_file':
|
|
174
|
+
result = await handlers.handleWriteFile(args);
|
|
175
|
+
break;
|
|
176
|
+
case 'write_pdf':
|
|
177
|
+
result = await handlers.handleWritePdf(args);
|
|
178
|
+
break;
|
|
179
|
+
case 'create_directory':
|
|
180
|
+
result = await handlers.handleCreateDirectory(args);
|
|
181
|
+
break;
|
|
182
|
+
case 'list_directory':
|
|
183
|
+
result = await handlers.handleListDirectory(args);
|
|
184
|
+
break;
|
|
185
|
+
case 'move_file':
|
|
186
|
+
result = await handlers.handleMoveFile(args);
|
|
187
|
+
break;
|
|
188
|
+
case 'start_search':
|
|
189
|
+
result = await handlers.handleStartSearch(args);
|
|
190
|
+
break;
|
|
191
|
+
case 'get_more_search_results':
|
|
192
|
+
result = await handlers.handleGetMoreSearchResults(args);
|
|
193
|
+
break;
|
|
194
|
+
case 'stop_search':
|
|
195
|
+
result = await handlers.handleStopSearch(args);
|
|
196
|
+
break;
|
|
197
|
+
case 'list_searches':
|
|
198
|
+
result = await handlers.handleListSearches();
|
|
199
|
+
break;
|
|
200
|
+
case 'get_file_info':
|
|
201
|
+
result = await handlers.handleGetFileInfo(args);
|
|
202
|
+
break;
|
|
203
|
+
case 'edit_block':
|
|
204
|
+
result = await handlers.handleEditBlock(args);
|
|
205
|
+
break;
|
|
206
|
+
default:
|
|
207
|
+
capture('server_unknown_tool', { name });
|
|
208
|
+
result = {
|
|
209
|
+
content: [{ type: 'text', text: `Error: Unknown tool: ${name}` }],
|
|
210
|
+
isError: true,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
const duration = Date.now() - startTime;
|
|
214
|
+
isError = !!result.isError;
|
|
215
|
+
const EXCLUDED_TOOLS = ['get_recent_tool_calls', 'track_ui_event'];
|
|
216
|
+
if (!isCapturingInvocation() && !currentCallIsRemote && process.env.MCP_DEVICE_REMOTE !== 'true' && !EXCLUDED_TOOLS.includes(name)) {
|
|
217
|
+
toolHistory.addCall(name, args, result, duration);
|
|
218
|
+
}
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
capture('server_unhandled_tool_error', { name, error: error?.message || String(error) });
|
|
223
|
+
return {
|
|
224
|
+
content: [{ type: 'text', text: `Error executing ${name}: ${error?.message || String(error)}` }],
|
|
225
|
+
isError: true,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
}
|
package/dist/tools/edit.js
CHANGED
|
@@ -82,7 +82,26 @@ function getCharacterCodeData(expected, actual) {
|
|
|
82
82
|
diffLength: fullDiff.length
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
|
-
|
|
85
|
+
const editChains = new Map();
|
|
86
|
+
async function withFileEditLock(filePath, operation) {
|
|
87
|
+
const resolved = path.resolve(filePath);
|
|
88
|
+
const key = process.platform === 'win32' ? resolved.toLowerCase() : resolved;
|
|
89
|
+
const previous = editChains.get(key) ?? Promise.resolve();
|
|
90
|
+
let release;
|
|
91
|
+
const current = new Promise(resolve => { release = resolve; });
|
|
92
|
+
const tail = previous.then(() => current);
|
|
93
|
+
editChains.set(key, tail);
|
|
94
|
+
await previous;
|
|
95
|
+
try {
|
|
96
|
+
return await operation();
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
release();
|
|
100
|
+
if (editChains.get(key) === tail)
|
|
101
|
+
editChains.delete(key);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async function performSearchReplaceUnlocked(filePath, block, expectedReplacements = 1, origin) {
|
|
86
105
|
// Get file extension for telemetry using path module
|
|
87
106
|
const fileExtension = path.extname(filePath).toLowerCase();
|
|
88
107
|
// Capture file extension and string sizes in telemetry without capturing the file path
|
|
@@ -288,6 +307,49 @@ RECOMMENDATION: For large search/replace operations, consider breaking them into
|
|
|
288
307
|
}
|
|
289
308
|
throw new Error("Unexpected error during search and replace operation.");
|
|
290
309
|
}
|
|
310
|
+
export async function performSearchReplace(filePath, block, expectedReplacements = 1, origin) {
|
|
311
|
+
return withFileEditLock(filePath, () => performSearchReplaceUnlocked(filePath, block, expectedReplacements, origin));
|
|
312
|
+
}
|
|
313
|
+
async function performExactBatch(filePath, edits, origin) {
|
|
314
|
+
return withFileEditLock(filePath, async () => {
|
|
315
|
+
const validPath = await validatePath(filePath);
|
|
316
|
+
const original = await readFileInternal(validPath, 0, Number.MAX_SAFE_INTEGER);
|
|
317
|
+
const fileLineEnding = detectLineEnding(original);
|
|
318
|
+
let next = original;
|
|
319
|
+
for (const edit of edits) {
|
|
320
|
+
const search = normalizeLineEndings(edit.old_string, fileLineEnding);
|
|
321
|
+
const replacement = normalizeLineEndings(edit.new_string, fileLineEnding);
|
|
322
|
+
let count = 0;
|
|
323
|
+
let pos = next.indexOf(search);
|
|
324
|
+
while (pos !== -1) {
|
|
325
|
+
count++;
|
|
326
|
+
pos = next.indexOf(search, pos + Math.max(1, search.length));
|
|
327
|
+
}
|
|
328
|
+
if (count !== edit.expected_replacements) {
|
|
329
|
+
return createErrorResponse(`Expected ${edit.expected_replacements} occurrences but found ${count} for batched edit in ${filePath}. No changes were written.`);
|
|
330
|
+
}
|
|
331
|
+
next = count === 1
|
|
332
|
+
? next.replace(search, replacement)
|
|
333
|
+
: next.split(search).join(replacement);
|
|
334
|
+
}
|
|
335
|
+
await writeFile(filePath, next);
|
|
336
|
+
const resolvedEditPath = resolveAbsolutePath(filePath);
|
|
337
|
+
return {
|
|
338
|
+
content: [{
|
|
339
|
+
type: "text",
|
|
340
|
+
text: `Successfully applied ${edits.length} exact edit(s) to ${filePath}`
|
|
341
|
+
}],
|
|
342
|
+
...(origin === 'ui' ? {
|
|
343
|
+
structuredContent: {
|
|
344
|
+
fileName: path.basename(resolvedEditPath),
|
|
345
|
+
filePath: resolvedEditPath,
|
|
346
|
+
fileType: resolvePreviewFileType(resolvedEditPath),
|
|
347
|
+
...await getDefaultEditorMetadata(resolvedEditPath),
|
|
348
|
+
},
|
|
349
|
+
} : {}),
|
|
350
|
+
};
|
|
351
|
+
});
|
|
352
|
+
}
|
|
291
353
|
/**
|
|
292
354
|
* Generates a character-level diff using standard {-removed-}{+added+} format
|
|
293
355
|
* @param expected The string that was searched for
|
|
@@ -350,6 +412,15 @@ export async function handleEditBlock(args) {
|
|
|
350
412
|
return createErrorResponse(errorMessage);
|
|
351
413
|
}
|
|
352
414
|
const hasEditRange = 'editRange' in handler && typeof handler.editRange === 'function';
|
|
415
|
+
// Compact hot path: multiple exact text replacements share one read/write.
|
|
416
|
+
// Structured handlers keep their existing editRange behavior and do not
|
|
417
|
+
// opt into this text-only batch contract.
|
|
418
|
+
if (parsed.edits) {
|
|
419
|
+
if (hasEditRange) {
|
|
420
|
+
return createErrorResponse(`Batched exact text edits are not supported for structured file ${parsed.file_path}; use the existing range/text edit contract for that file type.`);
|
|
421
|
+
}
|
|
422
|
+
return performExactBatch(parsed.file_path, parsed.edits, parsed.origin);
|
|
423
|
+
}
|
|
353
424
|
// Path 1: Range rewrite (Excel, etc.) — range + content
|
|
354
425
|
if (hasRange && hasContent) {
|
|
355
426
|
// Parse content if it's a JSON string (AI often sends arrays as JSON strings)
|
|
@@ -57,7 +57,7 @@ export interface MultiFileResult {
|
|
|
57
57
|
isPdf?: boolean;
|
|
58
58
|
payload?: FileResultPayloads;
|
|
59
59
|
}
|
|
60
|
-
export declare function readMultipleFiles(paths: string[]): Promise<MultiFileResult[]>;
|
|
60
|
+
export declare function readMultipleFiles(paths: string[], options?: ReadOptions): Promise<MultiFileResult[]>;
|
|
61
61
|
export declare function createDirectory(dirPath: string): Promise<void>;
|
|
62
62
|
export declare function listDirectory(dirPath: string, depth?: number): Promise<string[]>;
|
|
63
63
|
export declare function moveFile(sourcePath: string, destinationPath: string): Promise<void>;
|
package/dist/tools/filesystem.js
CHANGED
|
@@ -563,11 +563,11 @@ export async function writeFile(filePath, content, mode = 'rewrite') {
|
|
|
563
563
|
// Use handler to write the file
|
|
564
564
|
await handler.write(validPath, content, mode);
|
|
565
565
|
}
|
|
566
|
-
export async function readMultipleFiles(paths) {
|
|
566
|
+
export async function readMultipleFiles(paths, options) {
|
|
567
567
|
return Promise.all(paths.map(async (filePath) => {
|
|
568
568
|
try {
|
|
569
569
|
const validPath = await validatePath(filePath);
|
|
570
|
-
const fileResult = await readFile(validPath);
|
|
570
|
+
const fileResult = await readFile(validPath, options);
|
|
571
571
|
// Handle content conversion properly for images vs text
|
|
572
572
|
let content;
|
|
573
573
|
if (typeof fileResult.content === 'string') {
|