@mastra/core 1.7.0 → 1.8.0
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 +218 -0
- package/dist/agent/agent-legacy.d.ts +15 -0
- package/dist/agent/agent-legacy.d.ts.map +1 -1
- package/dist/agent/agent.d.ts +7 -0
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.types.d.ts +311 -2
- package/dist/agent/agent.types.d.ts.map +1 -1
- package/dist/agent/index.cjs +13 -13
- package/dist/agent/index.d.ts +3 -1
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +2 -2
- package/dist/agent/message-list/index.cjs +18 -18
- package/dist/agent/message-list/index.js +1 -1
- package/dist/agent/message-list/merge/MessageMerger.d.ts.map +1 -1
- package/dist/agent/message-list/message-list.d.ts.map +1 -1
- package/dist/agent/workflows/prepare-stream/map-results-step.d.ts.map +1 -1
- package/dist/agent/workflows/prepare-stream/prepare-tools-step.d.ts.map +1 -1
- package/dist/{chunk-A72NTLFT.cjs → chunk-2IO5Q7OZ.cjs} +7 -7
- package/dist/{chunk-A72NTLFT.cjs.map → chunk-2IO5Q7OZ.cjs.map} +1 -1
- package/dist/{chunk-DFCRXDVK.js → chunk-2KHPZJNU.js} +10 -8
- package/dist/chunk-2KHPZJNU.js.map +1 -0
- package/dist/{chunk-R4N65TLG.js → chunk-2R5MQMSA.js} +35 -16
- package/dist/chunk-2R5MQMSA.js.map +1 -0
- package/dist/{chunk-ZSBM2SVU.js → chunk-4H5F6AFP.js} +1064 -226
- package/dist/chunk-4H5F6AFP.js.map +1 -0
- package/dist/{chunk-BQHWJLXU.js → chunk-63G75DJE.js} +9 -3
- package/dist/chunk-63G75DJE.js.map +1 -0
- package/dist/{chunk-SBOHDNIZ.cjs → chunk-6GSWC5ZA.cjs} +2 -2
- package/dist/{chunk-SBOHDNIZ.cjs.map → chunk-6GSWC5ZA.cjs.map} +1 -1
- package/dist/{chunk-QTAS3HND.cjs → chunk-6Q2UD3XF.cjs} +21 -14
- package/dist/chunk-6Q2UD3XF.cjs.map +1 -0
- package/dist/{chunk-GPJGPARM.js → chunk-DTPR3JAM.js} +2 -2
- package/dist/{chunk-GPJGPARM.js.map → chunk-DTPR3JAM.js.map} +1 -1
- package/dist/{chunk-NN26FSKL.js → chunk-FHJ2KIU5.js} +3 -3
- package/dist/{chunk-NN26FSKL.js.map → chunk-FHJ2KIU5.js.map} +1 -1
- package/dist/{chunk-RABITNTG.cjs → chunk-HWG7NPJA.cjs} +55 -55
- package/dist/{chunk-RABITNTG.cjs.map → chunk-HWG7NPJA.cjs.map} +1 -1
- package/dist/{chunk-HB6T4554.cjs → chunk-KH3G65IS.cjs} +10 -8
- package/dist/chunk-KH3G65IS.cjs.map +1 -0
- package/dist/{chunk-YQG7NBPR.cjs → chunk-KZ4IKNPN.cjs} +25 -23
- package/dist/chunk-KZ4IKNPN.cjs.map +1 -0
- package/dist/{chunk-6DUTLERJ.js → chunk-MRV5NCPC.js} +3 -3
- package/dist/{chunk-6DUTLERJ.js.map → chunk-MRV5NCPC.js.map} +1 -1
- package/dist/{chunk-O7PZ4VOO.cjs → chunk-N3ROEJG4.cjs} +12 -10
- package/dist/chunk-N3ROEJG4.cjs.map +1 -0
- package/dist/{chunk-7EXW4AAG.js → chunk-NXKI2L4X.js} +6 -4
- package/dist/chunk-NXKI2L4X.js.map +1 -0
- package/dist/{chunk-QWTB53GS.js → chunk-OSEPGSLN.js} +6 -6
- package/dist/{chunk-QWTB53GS.js.map → chunk-OSEPGSLN.js.map} +1 -1
- package/dist/{chunk-6OXW5E2O.js → chunk-PI7ONENO.js} +4 -4
- package/dist/{chunk-6OXW5E2O.js.map → chunk-PI7ONENO.js.map} +1 -1
- package/dist/{chunk-KUXNBWN7.js → chunk-Q4MV4XKX.js} +8 -6
- package/dist/chunk-Q4MV4XKX.js.map +1 -0
- package/dist/{chunk-7UAJ6LMR.cjs → chunk-QKQGKEN7.cjs} +1078 -241
- package/dist/chunk-QKQGKEN7.cjs.map +1 -0
- package/dist/{chunk-IC5OUWKJ.js → chunk-SP7P6Z4L.js} +19 -2
- package/dist/chunk-SP7P6Z4L.js.map +1 -0
- package/dist/{chunk-QDH6MVJ7.cjs → chunk-TGUDI64A.cjs} +14 -14
- package/dist/{chunk-QDH6MVJ7.cjs.map → chunk-TGUDI64A.cjs.map} +1 -1
- package/dist/{chunk-EAZ6YDCQ.cjs → chunk-U3HBG2GU.cjs} +9 -2
- package/dist/chunk-U3HBG2GU.cjs.map +1 -0
- package/dist/{chunk-6QBN6MZY.cjs → chunk-VAKB5EXJ.cjs} +42 -23
- package/dist/chunk-VAKB5EXJ.cjs.map +1 -0
- package/dist/{chunk-QSHV7GPT.js → chunk-VBPU6CLZ.js} +3808 -3026
- package/dist/chunk-VBPU6CLZ.js.map +1 -0
- package/dist/{chunk-2X66GWF5.cjs → chunk-VTVCMIAI.cjs} +3905 -3121
- package/dist/chunk-VTVCMIAI.cjs.map +1 -0
- package/dist/{chunk-PHHJLGZU.cjs → chunk-XNWF6CYR.cjs} +6 -6
- package/dist/{chunk-PHHJLGZU.cjs.map → chunk-XNWF6CYR.cjs.map} +1 -1
- package/dist/{chunk-T6GAM3SQ.js → chunk-ZRPTWYWJ.js} +18 -11
- package/dist/chunk-ZRPTWYWJ.js.map +1 -0
- package/dist/{chunk-DB7U2C5B.cjs → chunk-ZXOWG32X.cjs} +19 -2
- package/dist/chunk-ZXOWG32X.cjs.map +1 -0
- package/dist/datasets/experiment/index.d.ts.map +1 -1
- package/dist/datasets/experiment/scorer.d.ts +1 -1
- package/dist/datasets/experiment/scorer.d.ts.map +1 -1
- package/dist/datasets/index.cjs +17 -17
- package/dist/datasets/index.js +2 -2
- package/dist/docs/SKILL.md +300 -0
- package/dist/docs/assets/SOURCE_MAP.json +1423 -0
- package/dist/docs/references/docs-agents-adding-voice.md +349 -0
- package/dist/docs/references/docs-agents-agent-approval.md +558 -0
- package/dist/docs/references/docs-agents-agent-memory.md +209 -0
- package/dist/docs/references/docs-agents-guardrails.md +374 -0
- package/dist/docs/references/docs-agents-network-approval.md +275 -0
- package/dist/docs/references/docs-agents-networks.md +299 -0
- package/dist/docs/references/docs-agents-overview.md +304 -0
- package/dist/docs/references/docs-agents-processors.md +622 -0
- package/dist/docs/references/docs-agents-structured-output.md +273 -0
- package/dist/docs/references/docs-agents-supervisor-agents.md +304 -0
- package/dist/docs/references/docs-agents-using-tools.md +214 -0
- package/dist/docs/references/docs-evals-custom-scorers.md +519 -0
- package/dist/docs/references/docs-evals-overview.md +141 -0
- package/dist/docs/references/docs-evals-running-in-ci.md +124 -0
- package/dist/docs/references/docs-memory-memory-processors.md +314 -0
- package/dist/docs/references/docs-memory-observational-memory.md +248 -0
- package/dist/docs/references/docs-memory-overview.md +45 -0
- package/dist/docs/references/docs-memory-semantic-recall.md +272 -0
- package/dist/docs/references/docs-memory-storage.md +261 -0
- package/dist/docs/references/docs-memory-working-memory.md +400 -0
- package/dist/docs/references/docs-observability-datasets-overview.md +198 -0
- package/dist/docs/references/docs-observability-datasets-running-experiments.md +274 -0
- package/dist/docs/references/docs-observability-logging.md +99 -0
- package/dist/docs/references/docs-observability-overview.md +70 -0
- package/dist/docs/references/docs-observability-tracing-bridges-otel.md +209 -0
- package/dist/docs/references/docs-observability-tracing-exporters-arize.md +272 -0
- package/dist/docs/references/docs-observability-tracing-exporters-braintrust.md +111 -0
- package/dist/docs/references/docs-observability-tracing-exporters-cloud.md +127 -0
- package/dist/docs/references/docs-observability-tracing-exporters-datadog.md +187 -0
- package/dist/docs/references/docs-observability-tracing-exporters-default.md +209 -0
- package/dist/docs/references/docs-observability-tracing-exporters-laminar.md +100 -0
- package/dist/docs/references/docs-observability-tracing-exporters-langfuse.md +213 -0
- package/dist/docs/references/docs-observability-tracing-exporters-langsmith.md +198 -0
- package/dist/docs/references/docs-observability-tracing-exporters-otel.md +476 -0
- package/dist/docs/references/docs-observability-tracing-exporters-posthog.md +148 -0
- package/dist/docs/references/docs-observability-tracing-overview.md +1112 -0
- package/dist/docs/references/docs-rag-chunking-and-embedding.md +183 -0
- package/dist/docs/references/docs-rag-graph-rag.md +215 -0
- package/dist/docs/references/docs-rag-overview.md +72 -0
- package/dist/docs/references/docs-rag-retrieval.md +515 -0
- package/dist/docs/references/docs-rag-vector-databases.md +645 -0
- package/dist/docs/references/docs-server-auth-auth0.md +220 -0
- package/dist/docs/references/docs-server-auth-clerk.md +132 -0
- package/dist/docs/references/docs-server-auth-composite-auth.md +234 -0
- package/dist/docs/references/docs-server-auth-custom-auth-provider.md +513 -0
- package/dist/docs/references/docs-server-auth-firebase.md +272 -0
- package/dist/docs/references/docs-server-auth-jwt.md +110 -0
- package/dist/docs/references/docs-server-auth-simple-auth.md +180 -0
- package/dist/docs/references/docs-server-auth-supabase.md +117 -0
- package/dist/docs/references/docs-server-auth-workos.md +186 -0
- package/dist/docs/references/docs-server-custom-adapters.md +378 -0
- package/dist/docs/references/docs-server-custom-api-routes.md +267 -0
- package/dist/docs/references/docs-server-mastra-client.md +243 -0
- package/dist/docs/references/docs-server-mastra-server.md +71 -0
- package/dist/docs/references/docs-server-middleware.md +225 -0
- package/dist/docs/references/docs-server-request-context.md +471 -0
- package/dist/docs/references/docs-streaming-events.md +237 -0
- package/dist/docs/references/docs-streaming-tool-streaming.md +175 -0
- package/dist/docs/references/docs-streaming-workflow-streaming.md +109 -0
- package/dist/docs/references/docs-voice-overview.md +959 -0
- package/dist/docs/references/docs-voice-speech-to-speech.md +102 -0
- package/dist/docs/references/docs-voice-speech-to-text.md +79 -0
- package/dist/docs/references/docs-voice-text-to-speech.md +83 -0
- package/dist/docs/references/docs-workflows-agents-and-tools.md +166 -0
- package/dist/docs/references/docs-workflows-control-flow.md +822 -0
- package/dist/docs/references/docs-workflows-error-handling.md +360 -0
- package/dist/docs/references/docs-workflows-human-in-the-loop.md +215 -0
- package/dist/docs/references/docs-workflows-overview.md +370 -0
- package/dist/docs/references/docs-workflows-snapshots.md +238 -0
- package/dist/docs/references/docs-workflows-suspend-and-resume.md +205 -0
- package/dist/docs/references/docs-workflows-time-travel.md +309 -0
- package/dist/docs/references/docs-workflows-workflow-state.md +181 -0
- package/dist/docs/references/docs-workspace-filesystem.md +164 -0
- package/dist/docs/references/docs-workspace-overview.md +239 -0
- package/dist/docs/references/docs-workspace-sandbox.md +63 -0
- package/dist/docs/references/docs-workspace-search.md +243 -0
- package/dist/docs/references/docs-workspace-skills.md +169 -0
- package/dist/docs/references/guides-agent-frameworks-ai-sdk.md +140 -0
- package/dist/docs/references/reference-agents-agent.md +141 -0
- package/dist/docs/references/reference-agents-generate.md +186 -0
- package/dist/docs/references/reference-agents-generateLegacy.md +173 -0
- package/dist/docs/references/reference-agents-getDefaultGenerateOptions.md +36 -0
- package/dist/docs/references/reference-agents-getDefaultOptions.md +34 -0
- package/dist/docs/references/reference-agents-getDefaultStreamOptions.md +36 -0
- package/dist/docs/references/reference-agents-getDescription.md +21 -0
- package/dist/docs/references/reference-agents-getInstructions.md +34 -0
- package/dist/docs/references/reference-agents-getLLM.md +37 -0
- package/dist/docs/references/reference-agents-getMemory.md +34 -0
- package/dist/docs/references/reference-agents-getModel.md +34 -0
- package/dist/docs/references/reference-agents-getTools.md +29 -0
- package/dist/docs/references/reference-agents-getVoice.md +34 -0
- package/dist/docs/references/reference-agents-listAgents.md +35 -0
- package/dist/docs/references/reference-agents-listScorers.md +34 -0
- package/dist/docs/references/reference-agents-listTools.md +34 -0
- package/dist/docs/references/reference-agents-listWorkflows.md +34 -0
- package/dist/docs/references/reference-agents-network.md +133 -0
- package/dist/docs/references/reference-ai-sdk-chat-route.md +82 -0
- package/dist/docs/references/reference-ai-sdk-network-route.md +74 -0
- package/dist/docs/references/reference-ai-sdk-to-ai-sdk-stream.md +231 -0
- package/dist/docs/references/reference-ai-sdk-with-mastra.md +59 -0
- package/dist/docs/references/reference-ai-sdk-workflow-route.md +79 -0
- package/dist/docs/references/reference-auth-auth0.md +73 -0
- package/dist/docs/references/reference-auth-clerk.md +36 -0
- package/dist/docs/references/reference-auth-firebase.md +80 -0
- package/dist/docs/references/reference-auth-jwt.md +26 -0
- package/dist/docs/references/reference-auth-supabase.md +33 -0
- package/dist/docs/references/reference-auth-workos.md +84 -0
- package/dist/docs/references/reference-client-js-agents.md +437 -0
- package/dist/docs/references/reference-configuration.md +752 -0
- package/dist/docs/references/reference-core-addGateway.md +42 -0
- package/dist/docs/references/reference-core-getAgent.md +21 -0
- package/dist/docs/references/reference-core-getAgentById.md +21 -0
- package/dist/docs/references/reference-core-getDeployer.md +22 -0
- package/dist/docs/references/reference-core-getGateway.md +38 -0
- package/dist/docs/references/reference-core-getGatewayById.md +41 -0
- package/dist/docs/references/reference-core-getLogger.md +22 -0
- package/dist/docs/references/reference-core-getMCPServer.md +47 -0
- package/dist/docs/references/reference-core-getMCPServerById.md +55 -0
- package/dist/docs/references/reference-core-getMemory.md +50 -0
- package/dist/docs/references/reference-core-getScorer.md +54 -0
- package/dist/docs/references/reference-core-getScorerById.md +54 -0
- package/dist/docs/references/reference-core-getServer.md +22 -0
- package/dist/docs/references/reference-core-getStorage.md +22 -0
- package/dist/docs/references/reference-core-getStoredAgentById.md +89 -0
- package/dist/docs/references/reference-core-getTelemetry.md +22 -0
- package/dist/docs/references/reference-core-getVector.md +22 -0
- package/dist/docs/references/reference-core-getWorkflow.md +42 -0
- package/dist/docs/references/reference-core-listAgents.md +21 -0
- package/dist/docs/references/reference-core-listGateways.md +40 -0
- package/dist/docs/references/reference-core-listLogs.md +38 -0
- package/dist/docs/references/reference-core-listLogsByRunId.md +36 -0
- package/dist/docs/references/reference-core-listMCPServers.md +55 -0
- package/dist/docs/references/reference-core-listMemory.md +56 -0
- package/dist/docs/references/reference-core-listScorers.md +29 -0
- package/dist/docs/references/reference-core-listStoredAgents.md +93 -0
- package/dist/docs/references/reference-core-listVectors.md +22 -0
- package/dist/docs/references/reference-core-listWorkflows.md +21 -0
- package/dist/docs/references/reference-core-mastra-class.md +66 -0
- package/dist/docs/references/reference-core-mastra-model-gateway.md +153 -0
- package/dist/docs/references/reference-core-setLogger.md +26 -0
- package/dist/docs/references/reference-core-setStorage.md +27 -0
- package/dist/docs/references/reference-datasets-addItem.md +37 -0
- package/dist/docs/references/reference-datasets-addItems.md +35 -0
- package/dist/docs/references/reference-datasets-compareExperiments.md +52 -0
- package/dist/docs/references/reference-datasets-create.md +51 -0
- package/dist/docs/references/reference-datasets-dataset.md +82 -0
- package/dist/docs/references/reference-datasets-datasets-manager.md +94 -0
- package/dist/docs/references/reference-datasets-delete.md +25 -0
- package/dist/docs/references/reference-datasets-deleteExperiment.md +27 -0
- package/dist/docs/references/reference-datasets-deleteItem.md +27 -0
- package/dist/docs/references/reference-datasets-deleteItems.md +29 -0
- package/dist/docs/references/reference-datasets-get.md +31 -0
- package/dist/docs/references/reference-datasets-getDetails.md +47 -0
- package/dist/docs/references/reference-datasets-getExperiment.md +30 -0
- package/dist/docs/references/reference-datasets-getItem.md +33 -0
- package/dist/docs/references/reference-datasets-getItemHistory.md +31 -0
- package/dist/docs/references/reference-datasets-list.md +31 -0
- package/dist/docs/references/reference-datasets-listExperimentResults.md +39 -0
- package/dist/docs/references/reference-datasets-listExperiments.md +33 -0
- package/dist/docs/references/reference-datasets-listItems.md +46 -0
- package/dist/docs/references/reference-datasets-listVersions.md +33 -0
- package/dist/docs/references/reference-datasets-startExperiment.md +62 -0
- package/dist/docs/references/reference-datasets-startExperimentAsync.md +43 -0
- package/dist/docs/references/reference-datasets-update.md +48 -0
- package/dist/docs/references/reference-datasets-updateItem.md +38 -0
- package/dist/docs/references/reference-evals-answer-relevancy.md +105 -0
- package/dist/docs/references/reference-evals-answer-similarity.md +99 -0
- package/dist/docs/references/reference-evals-bias.md +120 -0
- package/dist/docs/references/reference-evals-completeness.md +136 -0
- package/dist/docs/references/reference-evals-content-similarity.md +101 -0
- package/dist/docs/references/reference-evals-context-precision.md +196 -0
- package/dist/docs/references/reference-evals-create-scorer.md +270 -0
- package/dist/docs/references/reference-evals-faithfulness.md +114 -0
- package/dist/docs/references/reference-evals-hallucination.md +213 -0
- package/dist/docs/references/reference-evals-keyword-coverage.md +128 -0
- package/dist/docs/references/reference-evals-mastra-scorer.md +123 -0
- package/dist/docs/references/reference-evals-run-evals.md +179 -0
- package/dist/docs/references/reference-evals-scorer-utils.md +326 -0
- package/dist/docs/references/reference-evals-textual-difference.md +113 -0
- package/dist/docs/references/reference-evals-tone-consistency.md +119 -0
- package/dist/docs/references/reference-evals-toxicity.md +123 -0
- package/dist/docs/references/reference-harness-harness-class.md +708 -0
- package/dist/docs/references/reference-logging-pino-logger.md +117 -0
- package/dist/docs/references/reference-memory-deleteMessages.md +38 -0
- package/dist/docs/references/reference-memory-memory-class.md +147 -0
- package/dist/docs/references/reference-memory-observational-memory.md +565 -0
- package/dist/docs/references/reference-observability-tracing-bridges-otel.md +131 -0
- package/dist/docs/references/reference-observability-tracing-configuration.md +178 -0
- package/dist/docs/references/reference-observability-tracing-exporters-console-exporter.md +138 -0
- package/dist/docs/references/reference-observability-tracing-exporters-datadog.md +116 -0
- package/dist/docs/references/reference-observability-tracing-instances.md +107 -0
- package/dist/docs/references/reference-observability-tracing-interfaces.md +743 -0
- package/dist/docs/references/reference-observability-tracing-processors-sensitive-data-filter.md +144 -0
- package/dist/docs/references/reference-observability-tracing-spans.md +224 -0
- package/dist/docs/references/reference-processors-batch-parts-processor.md +61 -0
- package/dist/docs/references/reference-processors-language-detector.md +82 -0
- package/dist/docs/references/reference-processors-message-history-processor.md +85 -0
- package/dist/docs/references/reference-processors-moderation-processor.md +104 -0
- package/dist/docs/references/reference-processors-pii-detector.md +108 -0
- package/dist/docs/references/reference-processors-processor-interface.md +521 -0
- package/dist/docs/references/reference-processors-prompt-injection-detector.md +72 -0
- package/dist/docs/references/reference-processors-semantic-recall-processor.md +117 -0
- package/dist/docs/references/reference-processors-system-prompt-scrubber.md +80 -0
- package/dist/docs/references/reference-processors-token-limiter-processor.md +115 -0
- package/dist/docs/references/reference-processors-tool-call-filter.md +85 -0
- package/dist/docs/references/reference-processors-tool-search-processor.md +111 -0
- package/dist/docs/references/reference-processors-unicode-normalizer.md +62 -0
- package/dist/docs/references/reference-processors-working-memory-processor.md +152 -0
- package/dist/docs/references/reference-rag-database-config.md +261 -0
- package/dist/docs/references/reference-rag-embeddings.md +92 -0
- package/dist/docs/references/reference-server-mastra-server.md +298 -0
- package/dist/docs/references/reference-server-register-api-route.md +249 -0
- package/dist/docs/references/reference-storage-cloudflare-d1.md +218 -0
- package/dist/docs/references/reference-storage-composite.md +235 -0
- package/dist/docs/references/reference-storage-lance.md +131 -0
- package/dist/docs/references/reference-storage-libsql.md +135 -0
- package/dist/docs/references/reference-storage-mongodb.md +262 -0
- package/dist/docs/references/reference-storage-mssql.md +157 -0
- package/dist/docs/references/reference-storage-overview.md +121 -0
- package/dist/docs/references/reference-storage-postgresql.md +526 -0
- package/dist/docs/references/reference-storage-upstash.md +160 -0
- package/dist/docs/references/reference-streaming-ChunkType.md +292 -0
- package/dist/docs/references/reference-streaming-agents-MastraModelOutput.md +182 -0
- package/dist/docs/references/reference-streaming-agents-streamLegacy.md +142 -0
- package/dist/docs/references/reference-streaming-workflows-observeStream.md +42 -0
- package/dist/docs/references/reference-streaming-workflows-resumeStream.md +61 -0
- package/dist/docs/references/reference-streaming-workflows-stream.md +88 -0
- package/dist/docs/references/reference-streaming-workflows-timeTravelStream.md +142 -0
- package/dist/docs/references/reference-templates-overview.md +194 -0
- package/dist/docs/references/reference-tools-create-tool.md +237 -0
- package/dist/docs/references/reference-tools-graph-rag-tool.md +182 -0
- package/dist/docs/references/reference-tools-mcp-client.md +954 -0
- package/dist/docs/references/reference-tools-mcp-server.md +1271 -0
- package/dist/docs/references/reference-tools-vector-query-tool.md +459 -0
- package/dist/docs/references/reference-vectors-libsql.md +305 -0
- package/dist/docs/references/reference-vectors-mongodb.md +295 -0
- package/dist/docs/references/reference-vectors-pg.md +408 -0
- package/dist/docs/references/reference-vectors-upstash.md +294 -0
- package/dist/docs/references/reference-voice-composite-voice.md +121 -0
- package/dist/docs/references/reference-voice-mastra-voice.md +311 -0
- package/dist/docs/references/reference-voice-voice.addInstructions.md +55 -0
- package/dist/docs/references/reference-voice-voice.addTools.md +67 -0
- package/dist/docs/references/reference-voice-voice.connect.md +94 -0
- package/dist/docs/references/reference-voice-voice.events.md +37 -0
- package/dist/docs/references/reference-voice-voice.listen.md +164 -0
- package/dist/docs/references/reference-voice-voice.on.md +111 -0
- package/dist/docs/references/reference-voice-voice.speak.md +157 -0
- package/dist/docs/references/reference-workflows-run-methods-cancel.md +86 -0
- package/dist/docs/references/reference-workflows-run-methods-restart.md +33 -0
- package/dist/docs/references/reference-workflows-run-methods-resume.md +59 -0
- package/dist/docs/references/reference-workflows-run-methods-start.md +58 -0
- package/dist/docs/references/reference-workflows-run-methods-startAsync.md +67 -0
- package/dist/docs/references/reference-workflows-run-methods-timeTravel.md +142 -0
- package/dist/docs/references/reference-workflows-run.md +59 -0
- package/dist/docs/references/reference-workflows-step.md +119 -0
- package/dist/docs/references/reference-workflows-workflow-methods-branch.md +25 -0
- package/dist/docs/references/reference-workflows-workflow-methods-commit.md +17 -0
- package/dist/docs/references/reference-workflows-workflow-methods-create-run.md +63 -0
- package/dist/docs/references/reference-workflows-workflow-methods-dountil.md +25 -0
- package/dist/docs/references/reference-workflows-workflow-methods-dowhile.md +25 -0
- package/dist/docs/references/reference-workflows-workflow-methods-foreach.md +118 -0
- package/dist/docs/references/reference-workflows-workflow-methods-map.md +93 -0
- package/dist/docs/references/reference-workflows-workflow-methods-parallel.md +21 -0
- package/dist/docs/references/reference-workflows-workflow-methods-sleep.md +35 -0
- package/dist/docs/references/reference-workflows-workflow-methods-sleepUntil.md +35 -0
- package/dist/docs/references/reference-workflows-workflow-methods-then.md +21 -0
- package/dist/docs/references/reference-workflows-workflow.md +157 -0
- package/dist/docs/references/reference-workspace-filesystem.md +255 -0
- package/dist/docs/references/reference-workspace-local-filesystem.md +343 -0
- package/dist/docs/references/reference-workspace-local-sandbox.md +301 -0
- package/dist/docs/references/reference-workspace-sandbox.md +87 -0
- package/dist/docs/references/reference-workspace-workspace-class.md +244 -0
- package/dist/docs/references/reference.md +277 -0
- package/dist/evals/index.cjs +20 -20
- package/dist/evals/index.js +3 -3
- package/dist/evals/run/index.d.ts +9 -2
- package/dist/evals/run/index.d.ts.map +1 -1
- package/dist/evals/scoreTraces/index.cjs +5 -5
- package/dist/evals/scoreTraces/index.js +2 -2
- package/dist/harness/harness.d.ts +6 -0
- package/dist/harness/harness.d.ts.map +1 -1
- package/dist/harness/index.cjs +28 -13
- package/dist/harness/index.cjs.map +1 -1
- package/dist/harness/index.js +20 -5
- package/dist/harness/index.js.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.js +1 -1
- package/dist/integration/index.cjs +2 -2
- package/dist/integration/index.js +1 -1
- package/dist/llm/index.cjs +6 -6
- package/dist/llm/index.js +1 -1
- package/dist/llm/model/embedding-router.d.ts.map +1 -1
- package/dist/llm/model/model.loop.d.ts +1 -1
- package/dist/llm/model/model.loop.d.ts.map +1 -1
- package/dist/loop/index.cjs +20 -12
- package/dist/loop/index.js +1 -1
- package/dist/loop/network/index.d.ts.map +1 -1
- package/dist/loop/network/validation.d.ts +51 -0
- package/dist/loop/network/validation.d.ts.map +1 -1
- package/dist/loop/test-utils/generateText.d.ts.map +1 -1
- package/dist/loop/test-utils/options.d.ts.map +1 -1
- package/dist/loop/test-utils/streamObject.d.ts.map +1 -1
- package/dist/loop/types.d.ts +15 -0
- package/dist/loop/types.d.ts.map +1 -1
- package/dist/loop/workflows/agentic-execution/index.d.ts +3 -0
- package/dist/loop/workflows/agentic-execution/index.d.ts.map +1 -1
- package/dist/loop/workflows/agentic-execution/is-task-complete-step.d.ts +126 -0
- package/dist/loop/workflows/agentic-execution/is-task-complete-step.d.ts.map +1 -0
- package/dist/loop/workflows/agentic-execution/llm-execution-step.d.ts +3 -1
- package/dist/loop/workflows/agentic-execution/llm-execution-step.d.ts.map +1 -1
- package/dist/loop/workflows/agentic-execution/llm-mapping-step.d.ts +1 -0
- package/dist/loop/workflows/agentic-execution/llm-mapping-step.d.ts.map +1 -1
- package/dist/loop/workflows/agentic-execution/tool-call-step.d.ts.map +1 -1
- package/dist/loop/workflows/agentic-loop/index.d.ts +3 -0
- package/dist/loop/workflows/agentic-loop/index.d.ts.map +1 -1
- package/dist/loop/workflows/schema.d.ts +3 -0
- package/dist/loop/workflows/schema.d.ts.map +1 -1
- package/dist/mastra/index.cjs +2 -2
- package/dist/mastra/index.d.ts +9 -5
- package/dist/mastra/index.d.ts.map +1 -1
- package/dist/mastra/index.js +1 -1
- package/dist/memory/index.cjs +14 -14
- package/dist/memory/index.js +1 -1
- package/dist/processor-provider/index.cjs +10 -10
- package/dist/processor-provider/index.js +1 -1
- package/dist/processors/index.cjs +42 -42
- package/dist/processors/index.js +1 -1
- package/dist/processors/processors/skills.d.ts.map +1 -1
- package/dist/relevance/index.cjs +3 -3
- package/dist/relevance/index.js +1 -1
- package/dist/storage/constants.cjs +56 -56
- package/dist/storage/constants.js +1 -1
- package/dist/storage/domains/memory/inmemory.d.ts.map +1 -1
- package/dist/storage/index.cjs +160 -160
- package/dist/storage/index.js +2 -2
- package/dist/storage/types.d.ts +2 -3
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/stream/aisdk/v5/compat/prepare-tools.d.ts.map +1 -1
- package/dist/stream/base/output.d.ts +1 -0
- package/dist/stream/base/output.d.ts.map +1 -1
- package/dist/stream/index.cjs +11 -11
- package/dist/stream/index.js +2 -2
- package/dist/stream/types.d.ts +27 -1
- package/dist/stream/types.d.ts.map +1 -1
- package/dist/test-utils/llm-mock.cjs +4 -4
- package/dist/test-utils/llm-mock.js +1 -1
- package/dist/tool-loop-agent/index.cjs +4 -4
- package/dist/tool-loop-agent/index.js +1 -1
- package/dist/tools/index.cjs +9 -5
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +1 -1
- package/dist/tools/is-vercel-tool.cjs +2 -2
- package/dist/tools/is-vercel-tool.js +1 -1
- package/dist/tools/toolchecks.d.ts +10 -0
- package/dist/tools/toolchecks.d.ts.map +1 -1
- package/dist/utils.cjs +23 -23
- package/dist/utils.js +1 -1
- package/dist/vector/index.cjs +7 -7
- package/dist/vector/index.js +1 -1
- package/dist/vector/types.d.ts +9 -1
- package/dist/vector/types.d.ts.map +1 -1
- package/dist/workflows/evented/index.cjs +10 -10
- package/dist/workflows/evented/index.js +1 -1
- package/dist/workflows/index.cjs +25 -25
- package/dist/workflows/index.js +1 -1
- package/dist/workflows/types.d.ts +14 -1
- package/dist/workflows/types.d.ts.map +1 -1
- package/dist/workflows/workflow.d.ts +3 -17
- package/dist/workflows/workflow.d.ts.map +1 -1
- package/dist/workspace/filesystem/composite-filesystem.d.ts +5 -0
- package/dist/workspace/filesystem/composite-filesystem.d.ts.map +1 -1
- package/dist/workspace/filesystem/filesystem.d.ts +12 -0
- package/dist/workspace/filesystem/filesystem.d.ts.map +1 -1
- package/dist/workspace/filesystem/fs-utils.d.ts +12 -0
- package/dist/workspace/filesystem/fs-utils.d.ts.map +1 -1
- package/dist/workspace/filesystem/local-filesystem.d.ts +6 -0
- package/dist/workspace/filesystem/local-filesystem.d.ts.map +1 -1
- package/dist/workspace/index.cjs +66 -66
- package/dist/workspace/index.js +1 -1
- package/dist/workspace/lsp/client.d.ts +76 -0
- package/dist/workspace/lsp/client.d.ts.map +1 -0
- package/dist/workspace/lsp/index.d.ts +6 -0
- package/dist/workspace/lsp/index.d.ts.map +1 -0
- package/dist/workspace/lsp/language.d.ts +16 -0
- package/dist/workspace/lsp/language.d.ts.map +1 -0
- package/dist/workspace/lsp/manager.d.ts +72 -0
- package/dist/workspace/lsp/manager.d.ts.map +1 -0
- package/dist/workspace/lsp/servers.d.ts +43 -0
- package/dist/workspace/lsp/servers.d.ts.map +1 -0
- package/dist/workspace/lsp/types.d.ts +45 -0
- package/dist/workspace/lsp/types.d.ts.map +1 -0
- package/dist/workspace/tools/ast-edit.d.ts.map +1 -1
- package/dist/workspace/tools/edit-file.d.ts.map +1 -1
- package/dist/workspace/tools/helpers.d.ts +13 -0
- package/dist/workspace/tools/helpers.d.ts.map +1 -1
- package/dist/workspace/tools/write-file.d.ts.map +1 -1
- package/dist/workspace/workspace.d.ts +33 -0
- package/dist/workspace/workspace.d.ts.map +1 -1
- package/package.json +10 -8
- package/dist/chunk-2X66GWF5.cjs.map +0 -1
- package/dist/chunk-6QBN6MZY.cjs.map +0 -1
- package/dist/chunk-7EXW4AAG.js.map +0 -1
- package/dist/chunk-7UAJ6LMR.cjs.map +0 -1
- package/dist/chunk-BQHWJLXU.js.map +0 -1
- package/dist/chunk-DB7U2C5B.cjs.map +0 -1
- package/dist/chunk-DFCRXDVK.js.map +0 -1
- package/dist/chunk-EAZ6YDCQ.cjs.map +0 -1
- package/dist/chunk-HB6T4554.cjs.map +0 -1
- package/dist/chunk-IC5OUWKJ.js.map +0 -1
- package/dist/chunk-KUXNBWN7.js.map +0 -1
- package/dist/chunk-O7PZ4VOO.cjs.map +0 -1
- package/dist/chunk-QSHV7GPT.js.map +0 -1
- package/dist/chunk-QTAS3HND.cjs.map +0 -1
- package/dist/chunk-R4N65TLG.js.map +0 -1
- package/dist/chunk-T6GAM3SQ.js.map +0 -1
- package/dist/chunk-YQG7NBPR.cjs.map +0 -1
- package/dist/chunk-ZSBM2SVU.js.map +0 -1
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
import { createTool } from './chunk-
|
|
1
|
+
import { createTool } from './chunk-63G75DJE.js';
|
|
2
2
|
import { MastraBase } from './chunk-WCAFTXGK.js';
|
|
3
3
|
import { RegisteredLogger } from './chunk-X2WMFSPB.js';
|
|
4
4
|
import posixPath from 'path/posix';
|
|
5
|
-
import { constants } from 'fs';
|
|
5
|
+
import { constants, existsSync } from 'fs';
|
|
6
6
|
import * as fs2 from 'fs/promises';
|
|
7
7
|
import * as nodePath from 'path';
|
|
8
|
+
import nodePath__default, { parse, join, dirname } from 'path';
|
|
8
9
|
import picomatch from 'picomatch';
|
|
10
|
+
import { createRequire } from 'module';
|
|
11
|
+
import { pathToFileURL } from 'url';
|
|
12
|
+
import * as childProcess from 'child_process';
|
|
13
|
+
import { execFileSync } from 'child_process';
|
|
9
14
|
import * as crypto from 'crypto';
|
|
10
15
|
import { createHash } from 'crypto';
|
|
11
16
|
import matter from 'gray-matter';
|
|
12
17
|
import * as os from 'os';
|
|
13
18
|
import os__default from 'os';
|
|
14
|
-
import * as childProcess from 'child_process';
|
|
15
|
-
import { execFileSync } from 'child_process';
|
|
16
19
|
import { Readable, Writable } from 'stream';
|
|
17
|
-
import { createRequire } from 'module';
|
|
18
20
|
import { z } from 'zod';
|
|
19
21
|
|
|
20
22
|
// src/workspace/errors.ts
|
|
@@ -69,59 +71,59 @@ var WorkspaceReadOnlyError = class extends WorkspaceError {
|
|
|
69
71
|
}
|
|
70
72
|
};
|
|
71
73
|
var FilesystemError = class extends Error {
|
|
72
|
-
constructor(message, code,
|
|
74
|
+
constructor(message, code, path6) {
|
|
73
75
|
super(message);
|
|
74
76
|
this.code = code;
|
|
75
|
-
this.path =
|
|
77
|
+
this.path = path6;
|
|
76
78
|
this.name = "FilesystemError";
|
|
77
79
|
}
|
|
78
80
|
};
|
|
79
81
|
var FileNotFoundError = class extends FilesystemError {
|
|
80
|
-
constructor(
|
|
81
|
-
super(`File not found: ${
|
|
82
|
+
constructor(path6) {
|
|
83
|
+
super(`File not found: ${path6}`, "ENOENT", path6);
|
|
82
84
|
this.name = "FileNotFoundError";
|
|
83
85
|
}
|
|
84
86
|
};
|
|
85
87
|
var DirectoryNotFoundError = class extends FilesystemError {
|
|
86
|
-
constructor(
|
|
87
|
-
super(`Directory not found: ${
|
|
88
|
+
constructor(path6) {
|
|
89
|
+
super(`Directory not found: ${path6}`, "ENOENT", path6);
|
|
88
90
|
this.name = "DirectoryNotFoundError";
|
|
89
91
|
}
|
|
90
92
|
};
|
|
91
93
|
var FileExistsError = class extends FilesystemError {
|
|
92
|
-
constructor(
|
|
93
|
-
super(`File already exists: ${
|
|
94
|
+
constructor(path6) {
|
|
95
|
+
super(`File already exists: ${path6}`, "EEXIST", path6);
|
|
94
96
|
this.name = "FileExistsError";
|
|
95
97
|
}
|
|
96
98
|
};
|
|
97
99
|
var IsDirectoryError = class extends FilesystemError {
|
|
98
|
-
constructor(
|
|
99
|
-
super(`Path is a directory: ${
|
|
100
|
+
constructor(path6) {
|
|
101
|
+
super(`Path is a directory: ${path6}`, "EISDIR", path6);
|
|
100
102
|
this.name = "IsDirectoryError";
|
|
101
103
|
}
|
|
102
104
|
};
|
|
103
105
|
var NotDirectoryError = class extends FilesystemError {
|
|
104
|
-
constructor(
|
|
105
|
-
super(`Path is not a directory: ${
|
|
106
|
+
constructor(path6) {
|
|
107
|
+
super(`Path is not a directory: ${path6}`, "ENOTDIR", path6);
|
|
106
108
|
this.name = "NotDirectoryError";
|
|
107
109
|
}
|
|
108
110
|
};
|
|
109
111
|
var DirectoryNotEmptyError = class extends FilesystemError {
|
|
110
|
-
constructor(
|
|
111
|
-
super(`Directory not empty: ${
|
|
112
|
+
constructor(path6) {
|
|
113
|
+
super(`Directory not empty: ${path6}`, "ENOTEMPTY", path6);
|
|
112
114
|
this.name = "DirectoryNotEmptyError";
|
|
113
115
|
}
|
|
114
116
|
};
|
|
115
117
|
var PermissionError = class extends FilesystemError {
|
|
116
|
-
constructor(
|
|
117
|
-
super(`Permission denied: ${operation} on ${
|
|
118
|
+
constructor(path6, operation) {
|
|
119
|
+
super(`Permission denied: ${operation} on ${path6}`, "EACCES", path6);
|
|
118
120
|
this.operation = operation;
|
|
119
121
|
this.name = "PermissionError";
|
|
120
122
|
}
|
|
121
123
|
};
|
|
122
124
|
var FileReadRequiredError = class extends FilesystemError {
|
|
123
|
-
constructor(
|
|
124
|
-
super(reason, "EREAD_REQUIRED",
|
|
125
|
+
constructor(path6, reason) {
|
|
126
|
+
super(reason, "EREAD_REQUIRED", path6);
|
|
125
127
|
this.name = "FileReadRequiredError";
|
|
126
128
|
}
|
|
127
129
|
};
|
|
@@ -157,8 +159,8 @@ var CompositeFilesystem = class {
|
|
|
157
159
|
constructor(config) {
|
|
158
160
|
this.id = `cfs-${Date.now().toString(36)}`;
|
|
159
161
|
this._mounts = /* @__PURE__ */ new Map();
|
|
160
|
-
for (const [
|
|
161
|
-
const normalized = this.normalizePath(
|
|
162
|
+
for (const [path6, fs5] of Object.entries(config.mounts)) {
|
|
163
|
+
const normalized = this.normalizePath(path6);
|
|
162
164
|
this._mounts.set(normalized, fs5);
|
|
163
165
|
}
|
|
164
166
|
if (this._mounts.size === 0) {
|
|
@@ -209,27 +211,36 @@ var CompositeFilesystem = class {
|
|
|
209
211
|
* Get the underlying filesystem for a given path.
|
|
210
212
|
* Returns undefined if the path doesn't resolve to any mount.
|
|
211
213
|
*/
|
|
212
|
-
getFilesystemForPath(
|
|
213
|
-
const resolved = this.resolveMount(
|
|
214
|
+
getFilesystemForPath(path6) {
|
|
215
|
+
const resolved = this.resolveMount(path6);
|
|
214
216
|
return resolved?.fs;
|
|
215
217
|
}
|
|
216
218
|
/**
|
|
217
219
|
* Get the mount path for a given path.
|
|
218
220
|
* Returns undefined if the path doesn't resolve to any mount.
|
|
219
221
|
*/
|
|
220
|
-
getMountPathForPath(
|
|
221
|
-
const resolved = this.resolveMount(
|
|
222
|
+
getMountPathForPath(path6) {
|
|
223
|
+
const resolved = this.resolveMount(path6);
|
|
222
224
|
return resolved?.mountPath;
|
|
223
225
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
226
|
+
/**
|
|
227
|
+
* Resolve a workspace-relative path to an absolute disk path.
|
|
228
|
+
* Strips the mount prefix and delegates to the underlying filesystem.
|
|
229
|
+
*/
|
|
230
|
+
resolveAbsolutePath(path6) {
|
|
231
|
+
const r = this.resolveMount(path6);
|
|
232
|
+
if (!r) return void 0;
|
|
233
|
+
return r.fs.resolveAbsolutePath?.(r.fsPath);
|
|
234
|
+
}
|
|
235
|
+
normalizePath(path6) {
|
|
236
|
+
if (!path6 || path6 === "/") return "/";
|
|
237
|
+
let n = posixPath.normalize(path6);
|
|
227
238
|
if (!n.startsWith("/")) n = `/${n}`;
|
|
228
239
|
if (n.length > 1 && n.endsWith("/")) n = n.slice(0, -1);
|
|
229
240
|
return n;
|
|
230
241
|
}
|
|
231
|
-
resolveMount(
|
|
232
|
-
const normalized = this.normalizePath(
|
|
242
|
+
resolveMount(path6) {
|
|
243
|
+
const normalized = this.normalizePath(path6);
|
|
233
244
|
let best = null;
|
|
234
245
|
for (const [mountPath, fs5] of this._mounts) {
|
|
235
246
|
if (normalized === mountPath || normalized.startsWith(mountPath + "/")) {
|
|
@@ -244,8 +255,8 @@ var CompositeFilesystem = class {
|
|
|
244
255
|
if (!fsPath.startsWith("/")) fsPath = "/" + fsPath;
|
|
245
256
|
return { fs: best.fs, fsPath, mountPath: best.mountPath };
|
|
246
257
|
}
|
|
247
|
-
getVirtualEntries(
|
|
248
|
-
const normalized = this.normalizePath(
|
|
258
|
+
getVirtualEntries(path6) {
|
|
259
|
+
const normalized = this.normalizePath(path6);
|
|
249
260
|
if (this.resolveMount(normalized)) return null;
|
|
250
261
|
const entriesMap = /* @__PURE__ */ new Map();
|
|
251
262
|
for (const [mountPath, fs5] of this._mounts.entries()) {
|
|
@@ -272,8 +283,8 @@ var CompositeFilesystem = class {
|
|
|
272
283
|
}
|
|
273
284
|
return entriesMap.size > 0 ? Array.from(entriesMap.values()) : null;
|
|
274
285
|
}
|
|
275
|
-
isVirtualPath(
|
|
276
|
-
const normalized = this.normalizePath(
|
|
286
|
+
isVirtualPath(path6) {
|
|
287
|
+
const normalized = this.normalizePath(path6);
|
|
277
288
|
if (normalized === "/" && !this._mounts.has("/")) return true;
|
|
278
289
|
for (const mountPath of this._mounts.keys()) {
|
|
279
290
|
if (mountPath.startsWith(normalized + "/")) return true;
|
|
@@ -284,9 +295,9 @@ var CompositeFilesystem = class {
|
|
|
284
295
|
* Assert that a filesystem is writable (not read-only).
|
|
285
296
|
* @throws {PermissionError} if the filesystem is read-only
|
|
286
297
|
*/
|
|
287
|
-
assertWritable(fs5,
|
|
298
|
+
assertWritable(fs5, path6, operation) {
|
|
288
299
|
if (fs5.readOnly) {
|
|
289
|
-
throw new PermissionError(
|
|
300
|
+
throw new PermissionError(path6, `${operation} (filesystem is read-only)`);
|
|
290
301
|
}
|
|
291
302
|
}
|
|
292
303
|
// ===========================================================================
|
|
@@ -320,27 +331,27 @@ var CompositeFilesystem = class {
|
|
|
320
331
|
}
|
|
321
332
|
this.status = "destroyed";
|
|
322
333
|
}
|
|
323
|
-
async readFile(
|
|
324
|
-
const r = this.resolveMount(
|
|
325
|
-
if (!r) throw new Error(`No mount for path: ${
|
|
334
|
+
async readFile(path6, options) {
|
|
335
|
+
const r = this.resolveMount(path6);
|
|
336
|
+
if (!r) throw new Error(`No mount for path: ${path6}`);
|
|
326
337
|
return r.fs.readFile(r.fsPath, options);
|
|
327
338
|
}
|
|
328
|
-
async writeFile(
|
|
329
|
-
const r = this.resolveMount(
|
|
330
|
-
if (!r) throw new Error(`No mount for path: ${
|
|
331
|
-
this.assertWritable(r.fs,
|
|
339
|
+
async writeFile(path6, content, options) {
|
|
340
|
+
const r = this.resolveMount(path6);
|
|
341
|
+
if (!r) throw new Error(`No mount for path: ${path6}`);
|
|
342
|
+
this.assertWritable(r.fs, path6, "writeFile");
|
|
332
343
|
return r.fs.writeFile(r.fsPath, content, options);
|
|
333
344
|
}
|
|
334
|
-
async appendFile(
|
|
335
|
-
const r = this.resolveMount(
|
|
336
|
-
if (!r) throw new Error(`No mount for path: ${
|
|
337
|
-
this.assertWritable(r.fs,
|
|
345
|
+
async appendFile(path6, content) {
|
|
346
|
+
const r = this.resolveMount(path6);
|
|
347
|
+
if (!r) throw new Error(`No mount for path: ${path6}`);
|
|
348
|
+
this.assertWritable(r.fs, path6, "appendFile");
|
|
338
349
|
return r.fs.appendFile(r.fsPath, content);
|
|
339
350
|
}
|
|
340
|
-
async deleteFile(
|
|
341
|
-
const r = this.resolveMount(
|
|
342
|
-
if (!r) throw new Error(`No mount for path: ${
|
|
343
|
-
this.assertWritable(r.fs,
|
|
351
|
+
async deleteFile(path6, options) {
|
|
352
|
+
const r = this.resolveMount(path6);
|
|
353
|
+
if (!r) throw new Error(`No mount for path: ${path6}`);
|
|
354
|
+
this.assertWritable(r.fs, path6, "deleteFile");
|
|
344
355
|
return r.fs.deleteFile(r.fsPath, options);
|
|
345
356
|
}
|
|
346
357
|
async copyFile(src, dest, options) {
|
|
@@ -368,35 +379,35 @@ var CompositeFilesystem = class {
|
|
|
368
379
|
await this.copyFile(src, dest, options);
|
|
369
380
|
await srcR.fs.deleteFile(srcR.fsPath);
|
|
370
381
|
}
|
|
371
|
-
async readdir(
|
|
372
|
-
const virtual = this.getVirtualEntries(
|
|
382
|
+
async readdir(path6, options) {
|
|
383
|
+
const virtual = this.getVirtualEntries(path6);
|
|
373
384
|
if (virtual) return virtual;
|
|
374
|
-
const r = this.resolveMount(
|
|
375
|
-
if (!r) throw new Error(`No mount for path: ${
|
|
385
|
+
const r = this.resolveMount(path6);
|
|
386
|
+
if (!r) throw new Error(`No mount for path: ${path6}`);
|
|
376
387
|
return r.fs.readdir(r.fsPath, options);
|
|
377
388
|
}
|
|
378
|
-
async mkdir(
|
|
379
|
-
const r = this.resolveMount(
|
|
380
|
-
if (!r) throw new Error(`No mount for path: ${
|
|
381
|
-
this.assertWritable(r.fs,
|
|
389
|
+
async mkdir(path6, options) {
|
|
390
|
+
const r = this.resolveMount(path6);
|
|
391
|
+
if (!r) throw new Error(`No mount for path: ${path6}`);
|
|
392
|
+
this.assertWritable(r.fs, path6, "mkdir");
|
|
382
393
|
return r.fs.mkdir(r.fsPath, options);
|
|
383
394
|
}
|
|
384
|
-
async rmdir(
|
|
385
|
-
const r = this.resolveMount(
|
|
386
|
-
if (!r) throw new Error(`No mount for path: ${
|
|
387
|
-
this.assertWritable(r.fs,
|
|
395
|
+
async rmdir(path6, options) {
|
|
396
|
+
const r = this.resolveMount(path6);
|
|
397
|
+
if (!r) throw new Error(`No mount for path: ${path6}`);
|
|
398
|
+
this.assertWritable(r.fs, path6, "rmdir");
|
|
388
399
|
return r.fs.rmdir(r.fsPath, options);
|
|
389
400
|
}
|
|
390
|
-
async exists(
|
|
391
|
-
if (this.isVirtualPath(
|
|
392
|
-
const r = this.resolveMount(
|
|
401
|
+
async exists(path6) {
|
|
402
|
+
if (this.isVirtualPath(path6)) return true;
|
|
403
|
+
const r = this.resolveMount(path6);
|
|
393
404
|
if (!r) return false;
|
|
394
405
|
if (r.fsPath === "/") return true;
|
|
395
406
|
return r.fs.exists(r.fsPath);
|
|
396
407
|
}
|
|
397
|
-
async stat(
|
|
398
|
-
const normalized = this.normalizePath(
|
|
399
|
-
if (this.isVirtualPath(
|
|
408
|
+
async stat(path6) {
|
|
409
|
+
const normalized = this.normalizePath(path6);
|
|
410
|
+
if (this.isVirtualPath(path6)) {
|
|
400
411
|
const parts = normalized.split("/").filter(Boolean);
|
|
401
412
|
const now = /* @__PURE__ */ new Date();
|
|
402
413
|
return {
|
|
@@ -408,8 +419,8 @@ var CompositeFilesystem = class {
|
|
|
408
419
|
modifiedAt: now
|
|
409
420
|
};
|
|
410
421
|
}
|
|
411
|
-
const r = this.resolveMount(
|
|
412
|
-
if (!r) throw new Error(`No mount for path: ${
|
|
422
|
+
const r = this.resolveMount(path6);
|
|
423
|
+
if (!r) throw new Error(`No mount for path: ${path6}`);
|
|
413
424
|
if (r.fsPath === "/") {
|
|
414
425
|
const parts = normalized.split("/").filter(Boolean);
|
|
415
426
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -424,9 +435,9 @@ var CompositeFilesystem = class {
|
|
|
424
435
|
}
|
|
425
436
|
return r.fs.stat(r.fsPath);
|
|
426
437
|
}
|
|
427
|
-
async isFile(
|
|
428
|
-
if (this.isVirtualPath(
|
|
429
|
-
const r = this.resolveMount(
|
|
438
|
+
async isFile(path6) {
|
|
439
|
+
if (this.isVirtualPath(path6)) return false;
|
|
440
|
+
const r = this.resolveMount(path6);
|
|
430
441
|
if (!r) return false;
|
|
431
442
|
try {
|
|
432
443
|
const stat3 = await r.fs.stat(r.fsPath);
|
|
@@ -435,9 +446,9 @@ var CompositeFilesystem = class {
|
|
|
435
446
|
return false;
|
|
436
447
|
}
|
|
437
448
|
}
|
|
438
|
-
async isDirectory(
|
|
439
|
-
if (this.isVirtualPath(
|
|
440
|
-
const r = this.resolveMount(
|
|
449
|
+
async isDirectory(path6) {
|
|
450
|
+
if (this.isVirtualPath(path6)) return true;
|
|
451
|
+
const r = this.resolveMount(path6);
|
|
441
452
|
if (!r) return false;
|
|
442
453
|
if (r.fsPath === "/") return true;
|
|
443
454
|
try {
|
|
@@ -740,6 +751,17 @@ function isTextFile(filename) {
|
|
|
740
751
|
const ext = nodePath.extname(filename).toLowerCase();
|
|
741
752
|
return TEXT_EXTENSIONS.has(ext);
|
|
742
753
|
}
|
|
754
|
+
function resolveWorkspacePath(basePath, filePath) {
|
|
755
|
+
if (nodePath.isAbsolute(filePath)) {
|
|
756
|
+
const normalizedBase = nodePath.normalize(basePath);
|
|
757
|
+
const normalizedFile = nodePath.normalize(filePath);
|
|
758
|
+
const rel = nodePath.relative(normalizedBase, normalizedFile);
|
|
759
|
+
if (!rel.startsWith("..") && !nodePath.isAbsolute(rel)) {
|
|
760
|
+
return normalizedFile;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
return nodePath.join(basePath, filePath.replace(/^\/+/, ""));
|
|
764
|
+
}
|
|
743
765
|
async function fsExists(absolutePath) {
|
|
744
766
|
try {
|
|
745
767
|
await fs2.access(absolutePath);
|
|
@@ -827,8 +849,8 @@ var LocalFilesystem = class extends MastraFilesystem {
|
|
|
827
849
|
_isWithinAnyRoot(absolutePath) {
|
|
828
850
|
const roots = [this._basePath, ...this._allowedPaths];
|
|
829
851
|
return roots.some((root) => {
|
|
830
|
-
const
|
|
831
|
-
return !
|
|
852
|
+
const relative3 = nodePath.relative(root, absolutePath);
|
|
853
|
+
return !relative3.startsWith("..") && !nodePath.isAbsolute(relative3);
|
|
832
854
|
});
|
|
833
855
|
}
|
|
834
856
|
toBuffer(content) {
|
|
@@ -845,12 +867,10 @@ var LocalFilesystem = class extends MastraFilesystem {
|
|
|
845
867
|
if (this._isWithinAnyRoot(normalized)) {
|
|
846
868
|
absolutePath = normalized;
|
|
847
869
|
} else {
|
|
848
|
-
|
|
849
|
-
absolutePath = nodePath.resolve(this._basePath, nodePath.normalize(cleanedPath));
|
|
870
|
+
absolutePath = resolveWorkspacePath(this._basePath, inputPath);
|
|
850
871
|
}
|
|
851
872
|
} else {
|
|
852
|
-
|
|
853
|
-
absolutePath = nodePath.resolve(this._basePath, nodePath.normalize(cleanedPath));
|
|
873
|
+
absolutePath = resolveWorkspacePath(this._basePath, inputPath);
|
|
854
874
|
}
|
|
855
875
|
if (this._contained) {
|
|
856
876
|
if (!this._isWithinAnyRoot(absolutePath)) {
|
|
@@ -859,6 +879,18 @@ var LocalFilesystem = class extends MastraFilesystem {
|
|
|
859
879
|
}
|
|
860
880
|
return absolutePath;
|
|
861
881
|
}
|
|
882
|
+
/**
|
|
883
|
+
* Resolve a workspace-relative path to an absolute disk path.
|
|
884
|
+
* Uses the same resolution logic as internal file operations.
|
|
885
|
+
* Returns `undefined` if the path violates containment.
|
|
886
|
+
*/
|
|
887
|
+
resolveAbsolutePath(inputPath) {
|
|
888
|
+
try {
|
|
889
|
+
return this.resolvePath(inputPath);
|
|
890
|
+
} catch {
|
|
891
|
+
return void 0;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
862
894
|
toRelativePath(absolutePath) {
|
|
863
895
|
return "/" + nodePath.relative(this._basePath, absolutePath).replace(/\\/g, "/");
|
|
864
896
|
}
|
|
@@ -1292,35 +1324,35 @@ var LocalFilesystem = class extends MastraFilesystem {
|
|
|
1292
1324
|
};
|
|
1293
1325
|
var InMemoryFileReadTracker = class {
|
|
1294
1326
|
records = /* @__PURE__ */ new Map();
|
|
1295
|
-
recordRead(
|
|
1296
|
-
const normalizedPath = this.normalizePath(
|
|
1327
|
+
recordRead(path6, modifiedAt) {
|
|
1328
|
+
const normalizedPath = this.normalizePath(path6);
|
|
1297
1329
|
this.records.set(normalizedPath, {
|
|
1298
1330
|
path: normalizedPath,
|
|
1299
1331
|
readAt: /* @__PURE__ */ new Date(),
|
|
1300
1332
|
modifiedAtRead: modifiedAt
|
|
1301
1333
|
});
|
|
1302
1334
|
}
|
|
1303
|
-
getReadRecord(
|
|
1304
|
-
return this.records.get(this.normalizePath(
|
|
1335
|
+
getReadRecord(path6) {
|
|
1336
|
+
return this.records.get(this.normalizePath(path6));
|
|
1305
1337
|
}
|
|
1306
|
-
needsReRead(
|
|
1307
|
-
const record = this.getReadRecord(
|
|
1338
|
+
needsReRead(path6, currentModifiedAt) {
|
|
1339
|
+
const record = this.getReadRecord(path6);
|
|
1308
1340
|
if (!record) {
|
|
1309
1341
|
return {
|
|
1310
1342
|
needsReRead: true,
|
|
1311
|
-
reason: `File "${
|
|
1343
|
+
reason: `File "${path6}" has not been read. You must read a file before writing to it.`
|
|
1312
1344
|
};
|
|
1313
1345
|
}
|
|
1314
1346
|
if (currentModifiedAt.getTime() > record.modifiedAtRead.getTime()) {
|
|
1315
1347
|
return {
|
|
1316
1348
|
needsReRead: true,
|
|
1317
|
-
reason: `File "${
|
|
1349
|
+
reason: `File "${path6}" was modified since last read (read at: ${record.modifiedAtRead.toISOString()}, current: ${currentModifiedAt.toISOString()}). Please re-read the file to get the latest contents.`
|
|
1318
1350
|
};
|
|
1319
1351
|
}
|
|
1320
1352
|
return { needsReRead: false };
|
|
1321
1353
|
}
|
|
1322
|
-
clearReadRecord(
|
|
1323
|
-
this.records.delete(this.normalizePath(
|
|
1354
|
+
clearReadRecord(path6) {
|
|
1355
|
+
this.records.delete(this.normalizePath(path6));
|
|
1324
1356
|
}
|
|
1325
1357
|
clear() {
|
|
1326
1358
|
this.records.clear();
|
|
@@ -1408,11 +1440,721 @@ function createGlobMatcher(patterns, options) {
|
|
|
1408
1440
|
posix: true,
|
|
1409
1441
|
dot: options?.dot ?? false
|
|
1410
1442
|
});
|
|
1411
|
-
return (
|
|
1443
|
+
return (path6) => matcher(normalizeForMatch(path6));
|
|
1444
|
+
}
|
|
1445
|
+
function matchGlob(path6, pattern, options) {
|
|
1446
|
+
return createGlobMatcher(pattern, options)(path6);
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
// src/workspace/lsp/language.ts
|
|
1450
|
+
var LANGUAGE_EXTENSIONS = {
|
|
1451
|
+
// TypeScript/JavaScript
|
|
1452
|
+
".ts": "typescript",
|
|
1453
|
+
".tsx": "typescriptreact",
|
|
1454
|
+
".js": "javascript",
|
|
1455
|
+
".jsx": "javascriptreact",
|
|
1456
|
+
".mjs": "javascript",
|
|
1457
|
+
".cjs": "javascript",
|
|
1458
|
+
// Python
|
|
1459
|
+
".py": "python",
|
|
1460
|
+
".pyi": "python",
|
|
1461
|
+
// Go
|
|
1462
|
+
".go": "go",
|
|
1463
|
+
// Rust
|
|
1464
|
+
".rs": "rust",
|
|
1465
|
+
// C/C++
|
|
1466
|
+
".c": "c",
|
|
1467
|
+
".cpp": "cpp",
|
|
1468
|
+
".cc": "cpp",
|
|
1469
|
+
".cxx": "cpp",
|
|
1470
|
+
".h": "c",
|
|
1471
|
+
".hpp": "cpp",
|
|
1472
|
+
// Java
|
|
1473
|
+
".java": "java",
|
|
1474
|
+
// JSON
|
|
1475
|
+
".json": "json",
|
|
1476
|
+
".jsonc": "jsonc",
|
|
1477
|
+
// YAML
|
|
1478
|
+
".yaml": "yaml",
|
|
1479
|
+
".yml": "yaml",
|
|
1480
|
+
// Markdown
|
|
1481
|
+
".md": "markdown",
|
|
1482
|
+
// HTML/CSS
|
|
1483
|
+
".html": "html",
|
|
1484
|
+
".css": "css",
|
|
1485
|
+
".scss": "scss",
|
|
1486
|
+
".sass": "sass",
|
|
1487
|
+
".less": "less"
|
|
1488
|
+
};
|
|
1489
|
+
function getLanguageId(filePath) {
|
|
1490
|
+
const dotIndex = filePath.lastIndexOf(".");
|
|
1491
|
+
if (dotIndex === -1) return void 0;
|
|
1492
|
+
const ext = filePath.substring(dotIndex);
|
|
1493
|
+
return LANGUAGE_EXTENSIONS[ext];
|
|
1494
|
+
}
|
|
1495
|
+
var jsonrpcModule;
|
|
1496
|
+
var lspProtocolModule;
|
|
1497
|
+
function isLSPAvailable() {
|
|
1498
|
+
if (jsonrpcModule !== void 0) {
|
|
1499
|
+
return jsonrpcModule !== null;
|
|
1500
|
+
}
|
|
1501
|
+
try {
|
|
1502
|
+
const req = createRequire(import.meta.url);
|
|
1503
|
+
req.resolve("vscode-jsonrpc/node");
|
|
1504
|
+
req.resolve("vscode-languageserver-protocol");
|
|
1505
|
+
return true;
|
|
1506
|
+
} catch {
|
|
1507
|
+
return false;
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
async function loadLSPDeps() {
|
|
1511
|
+
if (jsonrpcModule !== void 0 && lspProtocolModule !== void 0) {
|
|
1512
|
+
if (jsonrpcModule === null || lspProtocolModule === null) return null;
|
|
1513
|
+
return { ...jsonrpcModule, ...lspProtocolModule };
|
|
1514
|
+
}
|
|
1515
|
+
try {
|
|
1516
|
+
const req = createRequire(import.meta.url);
|
|
1517
|
+
const jsonrpc = req("vscode-jsonrpc/node");
|
|
1518
|
+
const protocol = req("vscode-languageserver-protocol");
|
|
1519
|
+
jsonrpcModule = {
|
|
1520
|
+
StreamMessageReader: jsonrpc.StreamMessageReader,
|
|
1521
|
+
StreamMessageWriter: jsonrpc.StreamMessageWriter,
|
|
1522
|
+
createMessageConnection: jsonrpc.createMessageConnection
|
|
1523
|
+
};
|
|
1524
|
+
lspProtocolModule = {
|
|
1525
|
+
TextDocumentIdentifier: protocol.TextDocumentIdentifier,
|
|
1526
|
+
Position: protocol.Position
|
|
1527
|
+
};
|
|
1528
|
+
return { ...jsonrpcModule, ...lspProtocolModule };
|
|
1529
|
+
} catch {
|
|
1530
|
+
jsonrpcModule = null;
|
|
1531
|
+
lspProtocolModule = null;
|
|
1532
|
+
return null;
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
function toFileUri(fsPath) {
|
|
1536
|
+
return pathToFileURL(fsPath).toString();
|
|
1537
|
+
}
|
|
1538
|
+
var LSPClient = class {
|
|
1539
|
+
connection = null;
|
|
1540
|
+
handle = null;
|
|
1541
|
+
serverDef;
|
|
1542
|
+
workspaceRoot;
|
|
1543
|
+
processManager;
|
|
1544
|
+
diagnostics = /* @__PURE__ */ new Map();
|
|
1545
|
+
initializationOptions = null;
|
|
1546
|
+
constructor(serverDef, workspaceRoot, processManager) {
|
|
1547
|
+
this.serverDef = serverDef;
|
|
1548
|
+
this.workspaceRoot = workspaceRoot;
|
|
1549
|
+
this.processManager = processManager;
|
|
1550
|
+
}
|
|
1551
|
+
/** Whether the underlying server process is still running. */
|
|
1552
|
+
get isAlive() {
|
|
1553
|
+
return this.handle !== null && this.handle.exitCode === void 0;
|
|
1554
|
+
}
|
|
1555
|
+
/**
|
|
1556
|
+
* Initialize the LSP connection — spawns the server and performs the handshake.
|
|
1557
|
+
*/
|
|
1558
|
+
async initialize(initTimeout = 1e4) {
|
|
1559
|
+
const deps = await loadLSPDeps();
|
|
1560
|
+
if (!deps) {
|
|
1561
|
+
throw new Error("LSP dependencies (vscode-jsonrpc) are not available");
|
|
1562
|
+
}
|
|
1563
|
+
const { StreamMessageReader, StreamMessageWriter, createMessageConnection } = deps;
|
|
1564
|
+
const command = this.serverDef.command(this.workspaceRoot);
|
|
1565
|
+
if (!command) {
|
|
1566
|
+
throw new Error("Failed to resolve LSP server command");
|
|
1567
|
+
}
|
|
1568
|
+
this.handle = await this.processManager.spawn(command, { cwd: this.workspaceRoot });
|
|
1569
|
+
const initializationOptions = this.serverDef.initialization?.(this.workspaceRoot);
|
|
1570
|
+
const reader = new StreamMessageReader(this.handle.reader);
|
|
1571
|
+
const writer = new StreamMessageWriter(this.handle.writer);
|
|
1572
|
+
this.connection = createMessageConnection(reader, writer);
|
|
1573
|
+
this.connection.onError(() => {
|
|
1574
|
+
});
|
|
1575
|
+
this.connection.onNotification("textDocument/publishDiagnostics", (params) => {
|
|
1576
|
+
this.diagnostics.set(params.uri, params.diagnostics);
|
|
1577
|
+
});
|
|
1578
|
+
this.connection.listen();
|
|
1579
|
+
const initParams = {
|
|
1580
|
+
processId: process.pid,
|
|
1581
|
+
rootUri: toFileUri(this.workspaceRoot),
|
|
1582
|
+
workspaceFolders: [
|
|
1583
|
+
{
|
|
1584
|
+
name: "workspace",
|
|
1585
|
+
uri: toFileUri(this.workspaceRoot)
|
|
1586
|
+
}
|
|
1587
|
+
],
|
|
1588
|
+
capabilities: {
|
|
1589
|
+
window: { workDoneProgress: true },
|
|
1590
|
+
workspace: { configuration: true },
|
|
1591
|
+
textDocument: {
|
|
1592
|
+
publishDiagnostics: {
|
|
1593
|
+
relatedInformation: true,
|
|
1594
|
+
tagSupport: { valueSet: [1, 2] },
|
|
1595
|
+
versionSupport: false
|
|
1596
|
+
},
|
|
1597
|
+
synchronization: {
|
|
1598
|
+
didOpen: true,
|
|
1599
|
+
didChange: true,
|
|
1600
|
+
dynamicRegistration: false,
|
|
1601
|
+
willSave: false,
|
|
1602
|
+
willSaveWaitUntil: false,
|
|
1603
|
+
didSave: false
|
|
1604
|
+
},
|
|
1605
|
+
completion: {
|
|
1606
|
+
dynamicRegistration: false,
|
|
1607
|
+
completionItem: {
|
|
1608
|
+
snippetSupport: false,
|
|
1609
|
+
commitCharactersSupport: false,
|
|
1610
|
+
documentationFormat: ["markdown", "plaintext"],
|
|
1611
|
+
deprecatedSupport: false,
|
|
1612
|
+
preselectSupport: false
|
|
1613
|
+
}
|
|
1614
|
+
},
|
|
1615
|
+
definition: { dynamicRegistration: false, linkSupport: true },
|
|
1616
|
+
typeDefinition: { dynamicRegistration: false, linkSupport: true },
|
|
1617
|
+
implementation: { dynamicRegistration: false, linkSupport: true },
|
|
1618
|
+
references: { dynamicRegistration: false },
|
|
1619
|
+
documentHighlight: { dynamicRegistration: false },
|
|
1620
|
+
documentSymbol: { dynamicRegistration: false, hierarchicalDocumentSymbolSupport: true },
|
|
1621
|
+
codeAction: {
|
|
1622
|
+
dynamicRegistration: false,
|
|
1623
|
+
codeActionLiteralSupport: {
|
|
1624
|
+
codeActionKind: {
|
|
1625
|
+
valueSet: [
|
|
1626
|
+
"quickfix",
|
|
1627
|
+
"refactor",
|
|
1628
|
+
"refactor.extract",
|
|
1629
|
+
"refactor.inline",
|
|
1630
|
+
"refactor.rewrite",
|
|
1631
|
+
"source",
|
|
1632
|
+
"source.organizeImports"
|
|
1633
|
+
]
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
},
|
|
1637
|
+
hover: { dynamicRegistration: false, contentFormat: ["markdown", "plaintext"] }
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
};
|
|
1641
|
+
if (initializationOptions) {
|
|
1642
|
+
initParams.initializationOptions = initializationOptions;
|
|
1643
|
+
this.initializationOptions = initializationOptions;
|
|
1644
|
+
}
|
|
1645
|
+
this.connection.onRequest("workspace/configuration", (params) => {
|
|
1646
|
+
return params.items?.map(() => ({})) || [];
|
|
1647
|
+
});
|
|
1648
|
+
this.connection.onRequest("window/workDoneProgress/create", () => null);
|
|
1649
|
+
let initTimer;
|
|
1650
|
+
await Promise.race([
|
|
1651
|
+
this.connection.sendRequest("initialize", initParams),
|
|
1652
|
+
new Promise((_, reject) => {
|
|
1653
|
+
initTimer = setTimeout(() => reject(new Error("LSP initialize request timed out")), initTimeout);
|
|
1654
|
+
})
|
|
1655
|
+
]).finally(() => clearTimeout(initTimer));
|
|
1656
|
+
this.connection.sendNotification("initialized", {});
|
|
1657
|
+
this.connection.sendNotification("workspace/didChangeConfiguration", {
|
|
1658
|
+
settings: this.initializationOptions ?? {}
|
|
1659
|
+
});
|
|
1660
|
+
}
|
|
1661
|
+
/**
|
|
1662
|
+
* Notify the server that a document has been opened.
|
|
1663
|
+
*/
|
|
1664
|
+
notifyOpen(filePath, content, languageId) {
|
|
1665
|
+
if (!this.connection) return;
|
|
1666
|
+
const uri = toFileUri(filePath);
|
|
1667
|
+
this.diagnostics.delete(uri);
|
|
1668
|
+
this.connection.sendNotification("textDocument/didOpen", {
|
|
1669
|
+
textDocument: { uri, languageId, version: 0, text: content }
|
|
1670
|
+
});
|
|
1671
|
+
}
|
|
1672
|
+
/**
|
|
1673
|
+
* Notify the server that a document has changed.
|
|
1674
|
+
*/
|
|
1675
|
+
notifyChange(filePath, content, version) {
|
|
1676
|
+
if (!this.connection) return;
|
|
1677
|
+
this.connection.sendNotification("textDocument/didChange", {
|
|
1678
|
+
textDocument: { uri: toFileUri(filePath), version },
|
|
1679
|
+
contentChanges: [{ text: content }]
|
|
1680
|
+
});
|
|
1681
|
+
}
|
|
1682
|
+
/**
|
|
1683
|
+
* Wait for diagnostics to arrive for a file.
|
|
1684
|
+
*
|
|
1685
|
+
* When `waitForChange` is false (default), returns as soon as diagnostics
|
|
1686
|
+
* are available. To avoid returning a premature empty array (servers may
|
|
1687
|
+
* publish `[]` first while still analysing), empty results trigger a short
|
|
1688
|
+
* settle window: polling continues for up to `settleMs` (default 500ms)
|
|
1689
|
+
* to see if non-empty diagnostics arrive. Non-empty results are returned
|
|
1690
|
+
* immediately.
|
|
1691
|
+
*/
|
|
1692
|
+
async waitForDiagnostics(filePath, timeoutMs = 5e3, waitForChange = false, settleMs = 500) {
|
|
1693
|
+
if (!this.connection) return [];
|
|
1694
|
+
const uri = toFileUri(filePath);
|
|
1695
|
+
const startTime = Date.now();
|
|
1696
|
+
const initialDiagnostics = this.diagnostics.get(uri);
|
|
1697
|
+
let emptyReceivedAt;
|
|
1698
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
1699
|
+
const currentDiagnostics = this.diagnostics.get(uri);
|
|
1700
|
+
if (waitForChange) {
|
|
1701
|
+
if (currentDiagnostics !== void 0 && currentDiagnostics !== initialDiagnostics) {
|
|
1702
|
+
return currentDiagnostics;
|
|
1703
|
+
}
|
|
1704
|
+
} else {
|
|
1705
|
+
if (currentDiagnostics !== void 0) {
|
|
1706
|
+
if (currentDiagnostics.length > 0) return currentDiagnostics;
|
|
1707
|
+
if (emptyReceivedAt === void 0) emptyReceivedAt = Date.now();
|
|
1708
|
+
if (Date.now() - emptyReceivedAt >= settleMs) return currentDiagnostics;
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
await new Promise((resolve3) => setTimeout(resolve3, 100));
|
|
1712
|
+
}
|
|
1713
|
+
return waitForChange ? initialDiagnostics || [] : this.diagnostics.get(uri) || [];
|
|
1714
|
+
}
|
|
1715
|
+
/**
|
|
1716
|
+
* Notify the server that a document was closed.
|
|
1717
|
+
*/
|
|
1718
|
+
notifyClose(filePath) {
|
|
1719
|
+
if (!this.connection) return;
|
|
1720
|
+
const uri = toFileUri(filePath);
|
|
1721
|
+
this.diagnostics.delete(uri);
|
|
1722
|
+
this.connection.sendNotification("textDocument/didClose", {
|
|
1723
|
+
textDocument: { uri }
|
|
1724
|
+
});
|
|
1725
|
+
}
|
|
1726
|
+
/**
|
|
1727
|
+
* Shutdown the connection and kill the process.
|
|
1728
|
+
*/
|
|
1729
|
+
async shutdown() {
|
|
1730
|
+
if (this.connection) {
|
|
1731
|
+
try {
|
|
1732
|
+
if (this.handle && this.handle.exitCode === void 0) {
|
|
1733
|
+
let shutdownTimer;
|
|
1734
|
+
await Promise.race([
|
|
1735
|
+
this.connection.sendRequest("shutdown"),
|
|
1736
|
+
new Promise((_, reject) => {
|
|
1737
|
+
shutdownTimer = setTimeout(() => reject(new Error("Shutdown request timed out")), 1e3);
|
|
1738
|
+
})
|
|
1739
|
+
]).finally(() => clearTimeout(shutdownTimer));
|
|
1740
|
+
this.connection.sendNotification("exit");
|
|
1741
|
+
}
|
|
1742
|
+
} catch {
|
|
1743
|
+
}
|
|
1744
|
+
try {
|
|
1745
|
+
this.connection.dispose();
|
|
1746
|
+
} catch {
|
|
1747
|
+
}
|
|
1748
|
+
this.connection = null;
|
|
1749
|
+
}
|
|
1750
|
+
if (this.handle) {
|
|
1751
|
+
try {
|
|
1752
|
+
await this.handle.kill();
|
|
1753
|
+
} catch {
|
|
1754
|
+
}
|
|
1755
|
+
this.handle = null;
|
|
1756
|
+
}
|
|
1757
|
+
this.diagnostics = /* @__PURE__ */ new Map();
|
|
1758
|
+
}
|
|
1759
|
+
};
|
|
1760
|
+
function whichSync(binary) {
|
|
1761
|
+
try {
|
|
1762
|
+
const cmd = process.platform === "win32" ? "where" : "which";
|
|
1763
|
+
execFileSync(cmd, [binary], { stdio: "ignore" });
|
|
1764
|
+
return true;
|
|
1765
|
+
} catch {
|
|
1766
|
+
return false;
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
function resolveRequire(root, moduleId) {
|
|
1770
|
+
try {
|
|
1771
|
+
const req = createRequire(pathToFileURL(join(root, "package.json")));
|
|
1772
|
+
return { require: req, resolved: req.resolve(moduleId) };
|
|
1773
|
+
} catch {
|
|
1774
|
+
}
|
|
1775
|
+
try {
|
|
1776
|
+
const req = createRequire(pathToFileURL(join(process.cwd(), "package.json")));
|
|
1777
|
+
return { require: req, resolved: req.resolve(moduleId) };
|
|
1778
|
+
} catch {
|
|
1779
|
+
return null;
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
function walkUp(startDir, markers) {
|
|
1783
|
+
let current = startDir;
|
|
1784
|
+
const fsRoot = parse(current).root;
|
|
1785
|
+
while (true) {
|
|
1786
|
+
for (const marker of markers) {
|
|
1787
|
+
if (existsSync(join(current, marker))) {
|
|
1788
|
+
return current;
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
if (current === fsRoot) break;
|
|
1792
|
+
const parent = dirname(current);
|
|
1793
|
+
if (parent === current) break;
|
|
1794
|
+
current = parent;
|
|
1795
|
+
}
|
|
1796
|
+
return null;
|
|
1412
1797
|
}
|
|
1413
|
-
function
|
|
1414
|
-
|
|
1798
|
+
async function walkUpAsync(startDir, markers, fs5) {
|
|
1799
|
+
let current = startDir;
|
|
1800
|
+
const fsRoot = parse(current).root;
|
|
1801
|
+
while (true) {
|
|
1802
|
+
for (const marker of markers) {
|
|
1803
|
+
if (await fs5.exists(join(current, marker))) {
|
|
1804
|
+
return current;
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
if (current === fsRoot) break;
|
|
1808
|
+
const parent = dirname(current);
|
|
1809
|
+
if (parent === current) break;
|
|
1810
|
+
current = parent;
|
|
1811
|
+
}
|
|
1812
|
+
return null;
|
|
1813
|
+
}
|
|
1814
|
+
var DEFAULT_MARKERS = [
|
|
1815
|
+
"tsconfig.json",
|
|
1816
|
+
"package.json",
|
|
1817
|
+
"pyproject.toml",
|
|
1818
|
+
"go.mod",
|
|
1819
|
+
"Cargo.toml",
|
|
1820
|
+
"composer.json",
|
|
1821
|
+
".git"
|
|
1822
|
+
];
|
|
1823
|
+
function findProjectRoot(startDir) {
|
|
1824
|
+
return walkUp(startDir, DEFAULT_MARKERS);
|
|
1825
|
+
}
|
|
1826
|
+
var BUILTIN_SERVERS = {
|
|
1827
|
+
typescript: {
|
|
1828
|
+
id: "typescript",
|
|
1829
|
+
name: "TypeScript Language Server",
|
|
1830
|
+
languageIds: ["typescript", "typescriptreact", "javascript", "javascriptreact"],
|
|
1831
|
+
markers: ["tsconfig.json", "package.json"],
|
|
1832
|
+
command: (root) => {
|
|
1833
|
+
const ts = resolveRequire(root, "typescript/lib/tsserver.js");
|
|
1834
|
+
if (!ts) return void 0;
|
|
1835
|
+
const localBin = join(root, "node_modules", ".bin", "typescript-language-server");
|
|
1836
|
+
const cwdBin = join(process.cwd(), "node_modules", ".bin", "typescript-language-server");
|
|
1837
|
+
if (existsSync(localBin)) return `${localBin} --stdio`;
|
|
1838
|
+
if (existsSync(cwdBin)) return `${cwdBin} --stdio`;
|
|
1839
|
+
return void 0;
|
|
1840
|
+
},
|
|
1841
|
+
initialization: (root) => {
|
|
1842
|
+
const ts = resolveRequire(root, "typescript/lib/tsserver.js");
|
|
1843
|
+
if (!ts) return void 0;
|
|
1844
|
+
return {
|
|
1845
|
+
tsserver: {
|
|
1846
|
+
path: ts.resolved,
|
|
1847
|
+
logVerbosity: "off"
|
|
1848
|
+
}
|
|
1849
|
+
};
|
|
1850
|
+
}
|
|
1851
|
+
},
|
|
1852
|
+
eslint: {
|
|
1853
|
+
id: "eslint",
|
|
1854
|
+
name: "ESLint Language Server",
|
|
1855
|
+
languageIds: ["typescript", "typescriptreact", "javascript", "javascriptreact"],
|
|
1856
|
+
markers: [
|
|
1857
|
+
"package.json",
|
|
1858
|
+
".eslintrc.js",
|
|
1859
|
+
".eslintrc.json",
|
|
1860
|
+
".eslintrc.yml",
|
|
1861
|
+
".eslintrc.yaml",
|
|
1862
|
+
"eslint.config.js",
|
|
1863
|
+
"eslint.config.mjs",
|
|
1864
|
+
"eslint.config.ts"
|
|
1865
|
+
],
|
|
1866
|
+
command: (root) => {
|
|
1867
|
+
const localBin = join(root, "node_modules", ".bin", "vscode-eslint-language-server");
|
|
1868
|
+
const cwdBin = join(process.cwd(), "node_modules", ".bin", "vscode-eslint-language-server");
|
|
1869
|
+
if (existsSync(localBin)) return `${localBin} --stdio`;
|
|
1870
|
+
if (existsSync(cwdBin)) return `${cwdBin} --stdio`;
|
|
1871
|
+
return void 0;
|
|
1872
|
+
}
|
|
1873
|
+
},
|
|
1874
|
+
python: {
|
|
1875
|
+
id: "python",
|
|
1876
|
+
name: "Python Language Server (Pyright)",
|
|
1877
|
+
languageIds: ["python"],
|
|
1878
|
+
markers: ["pyproject.toml", "setup.py", "requirements.txt", "setup.cfg"],
|
|
1879
|
+
command: (root) => {
|
|
1880
|
+
const localBin = join(root, "node_modules", ".bin", "pyright-langserver");
|
|
1881
|
+
const cwdBin = join(process.cwd(), "node_modules", ".bin", "pyright-langserver");
|
|
1882
|
+
if (existsSync(localBin)) return `${localBin} --stdio`;
|
|
1883
|
+
if (existsSync(cwdBin)) return `${cwdBin} --stdio`;
|
|
1884
|
+
return whichSync("pyright-langserver") ? "pyright-langserver --stdio" : void 0;
|
|
1885
|
+
}
|
|
1886
|
+
},
|
|
1887
|
+
go: {
|
|
1888
|
+
id: "go",
|
|
1889
|
+
name: "Go Language Server (gopls)",
|
|
1890
|
+
languageIds: ["go"],
|
|
1891
|
+
markers: ["go.mod"],
|
|
1892
|
+
command: () => {
|
|
1893
|
+
return whichSync("gopls") ? "gopls serve" : void 0;
|
|
1894
|
+
}
|
|
1895
|
+
},
|
|
1896
|
+
rust: {
|
|
1897
|
+
id: "rust",
|
|
1898
|
+
name: "Rust Language Server (rust-analyzer)",
|
|
1899
|
+
languageIds: ["rust"],
|
|
1900
|
+
markers: ["Cargo.toml"],
|
|
1901
|
+
command: () => {
|
|
1902
|
+
return whichSync("rust-analyzer") ? "rust-analyzer --stdio" : void 0;
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
};
|
|
1906
|
+
function getServersForFile(filePath, disabledServers) {
|
|
1907
|
+
const languageId = getLanguageId(filePath);
|
|
1908
|
+
if (!languageId) return [];
|
|
1909
|
+
const disabled = new Set(disabledServers ?? []);
|
|
1910
|
+
return Object.values(BUILTIN_SERVERS).filter(
|
|
1911
|
+
(server) => !disabled.has(server.id) && server.languageIds.includes(languageId)
|
|
1912
|
+
);
|
|
1415
1913
|
}
|
|
1914
|
+
function mapSeverity(severity) {
|
|
1915
|
+
switch (severity) {
|
|
1916
|
+
case 1:
|
|
1917
|
+
return "error";
|
|
1918
|
+
case 2:
|
|
1919
|
+
return "warning";
|
|
1920
|
+
case 3:
|
|
1921
|
+
return "info";
|
|
1922
|
+
case 4:
|
|
1923
|
+
return "hint";
|
|
1924
|
+
default:
|
|
1925
|
+
return "warning";
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
var LSPManager = class {
|
|
1929
|
+
clients = /* @__PURE__ */ new Map();
|
|
1930
|
+
initPromises = /* @__PURE__ */ new Map();
|
|
1931
|
+
fileLocks = /* @__PURE__ */ new Map();
|
|
1932
|
+
processManager;
|
|
1933
|
+
_root;
|
|
1934
|
+
config;
|
|
1935
|
+
filesystem;
|
|
1936
|
+
constructor(processManager, root, config = {}, filesystem) {
|
|
1937
|
+
this.processManager = processManager;
|
|
1938
|
+
this._root = root;
|
|
1939
|
+
this.config = config;
|
|
1940
|
+
this.filesystem = filesystem;
|
|
1941
|
+
}
|
|
1942
|
+
/** Default project root (fallback when per-file walkup finds nothing). */
|
|
1943
|
+
get root() {
|
|
1944
|
+
return this._root;
|
|
1945
|
+
}
|
|
1946
|
+
/**
|
|
1947
|
+
* Resolve the project root for a given file path using the server's markers.
|
|
1948
|
+
* Uses the workspace filesystem when available (supports remote filesystems),
|
|
1949
|
+
* falls back to sync walkUp (local disk) otherwise.
|
|
1950
|
+
*/
|
|
1951
|
+
async resolveRoot(filePath, markers) {
|
|
1952
|
+
const fileDir = nodePath__default.dirname(filePath);
|
|
1953
|
+
if (this.filesystem) {
|
|
1954
|
+
return await walkUpAsync(fileDir, markers, this.filesystem) ?? this._root;
|
|
1955
|
+
}
|
|
1956
|
+
return walkUp(fileDir, markers) ?? this._root;
|
|
1957
|
+
}
|
|
1958
|
+
/**
|
|
1959
|
+
* Acquire a per-file lock so that concurrent getDiagnostics calls for the
|
|
1960
|
+
* same file are serialized (preventing interleaved open/change/close).
|
|
1961
|
+
* Different files can run in parallel.
|
|
1962
|
+
*/
|
|
1963
|
+
async acquireFileLock(filePath) {
|
|
1964
|
+
while (this.fileLocks.has(filePath)) {
|
|
1965
|
+
await this.fileLocks.get(filePath);
|
|
1966
|
+
}
|
|
1967
|
+
let release;
|
|
1968
|
+
const lockPromise = new Promise((resolve3) => {
|
|
1969
|
+
release = resolve3;
|
|
1970
|
+
});
|
|
1971
|
+
this.fileLocks.set(filePath, lockPromise);
|
|
1972
|
+
return () => {
|
|
1973
|
+
this.fileLocks.delete(filePath);
|
|
1974
|
+
release();
|
|
1975
|
+
};
|
|
1976
|
+
}
|
|
1977
|
+
/**
|
|
1978
|
+
* Initialize an LSP client for the given server definition and project root.
|
|
1979
|
+
* Handles timeout, deduplication of concurrent init calls, and caching.
|
|
1980
|
+
*/
|
|
1981
|
+
async initClient(serverDef, projectRoot, key) {
|
|
1982
|
+
if (this.initPromises.has(key)) {
|
|
1983
|
+
await this.initPromises.get(key);
|
|
1984
|
+
return this.clients.get(key) || null;
|
|
1985
|
+
}
|
|
1986
|
+
const initTimeout = this.config.initTimeout ?? 15e3;
|
|
1987
|
+
let timedOut = false;
|
|
1988
|
+
const initPromise = (async () => {
|
|
1989
|
+
const client = new LSPClient(serverDef, projectRoot, this.processManager);
|
|
1990
|
+
await client.initialize(initTimeout);
|
|
1991
|
+
if (timedOut) {
|
|
1992
|
+
await client.shutdown().catch(() => {
|
|
1993
|
+
});
|
|
1994
|
+
return;
|
|
1995
|
+
}
|
|
1996
|
+
this.clients.set(key, client);
|
|
1997
|
+
})();
|
|
1998
|
+
this.initPromises.set(key, initPromise);
|
|
1999
|
+
initPromise.catch(() => {
|
|
2000
|
+
});
|
|
2001
|
+
try {
|
|
2002
|
+
await Promise.race([
|
|
2003
|
+
initPromise,
|
|
2004
|
+
new Promise(
|
|
2005
|
+
(_, reject) => setTimeout(() => reject(new Error("LSP client initialization timed out")), initTimeout + 1e3)
|
|
2006
|
+
)
|
|
2007
|
+
]);
|
|
2008
|
+
return this.clients.get(key) || null;
|
|
2009
|
+
} catch {
|
|
2010
|
+
timedOut = true;
|
|
2011
|
+
this.clients.delete(key);
|
|
2012
|
+
return null;
|
|
2013
|
+
} finally {
|
|
2014
|
+
this.initPromises.delete(key);
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
/**
|
|
2018
|
+
* Get or create an LSP client for a file path.
|
|
2019
|
+
* Resolves the project root per-file using the server's markers.
|
|
2020
|
+
* Returns null if no server is available.
|
|
2021
|
+
*/
|
|
2022
|
+
async getClient(filePath) {
|
|
2023
|
+
const servers = getServersForFile(filePath, this.config.disableServers);
|
|
2024
|
+
if (servers.length === 0) return null;
|
|
2025
|
+
const serverDef = servers.find(
|
|
2026
|
+
(s) => s.languageIds.includes("typescript") || s.languageIds.includes("javascript") || s.languageIds.includes("python") || s.languageIds.includes("go")
|
|
2027
|
+
) ?? servers[0];
|
|
2028
|
+
const projectRoot = await this.resolveRoot(filePath, serverDef.markers);
|
|
2029
|
+
if (serverDef.command(projectRoot) === void 0) return null;
|
|
2030
|
+
const key = `${serverDef.name}:${projectRoot}`;
|
|
2031
|
+
if (this.clients.has(key)) {
|
|
2032
|
+
const existing = this.clients.get(key);
|
|
2033
|
+
if (!existing.isAlive) {
|
|
2034
|
+
this.clients.delete(key);
|
|
2035
|
+
existing.shutdown().catch(() => {
|
|
2036
|
+
});
|
|
2037
|
+
} else {
|
|
2038
|
+
return existing;
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
return this.initClient(serverDef, projectRoot, key);
|
|
2042
|
+
}
|
|
2043
|
+
/**
|
|
2044
|
+
* Convenience method: open file, send content, wait for diagnostics, return normalized results.
|
|
2045
|
+
* Returns an empty array on any failure (non-blocking).
|
|
2046
|
+
* Uses a per-file lock to serialize concurrent calls for the same file.
|
|
2047
|
+
*/
|
|
2048
|
+
async getDiagnostics(filePath, content) {
|
|
2049
|
+
const release = await this.acquireFileLock(filePath);
|
|
2050
|
+
try {
|
|
2051
|
+
const client = await this.getClient(filePath);
|
|
2052
|
+
if (!client) return [];
|
|
2053
|
+
const languageId = getLanguageId(filePath);
|
|
2054
|
+
if (!languageId) return [];
|
|
2055
|
+
client.notifyOpen(filePath, content, languageId);
|
|
2056
|
+
client.notifyChange(filePath, content, 1);
|
|
2057
|
+
const diagnosticTimeout = this.config.diagnosticTimeout ?? 5e3;
|
|
2058
|
+
let rawDiagnostics;
|
|
2059
|
+
try {
|
|
2060
|
+
rawDiagnostics = await client.waitForDiagnostics(filePath, diagnosticTimeout);
|
|
2061
|
+
} finally {
|
|
2062
|
+
client.notifyClose(filePath);
|
|
2063
|
+
}
|
|
2064
|
+
return rawDiagnostics.map((d) => ({
|
|
2065
|
+
severity: mapSeverity(d.severity),
|
|
2066
|
+
message: d.message,
|
|
2067
|
+
line: (d.range?.start?.line ?? 0) + 1,
|
|
2068
|
+
// LSP is 0-indexed, we report 1-indexed
|
|
2069
|
+
character: (d.range?.start?.character ?? 0) + 1,
|
|
2070
|
+
source: d.source
|
|
2071
|
+
}));
|
|
2072
|
+
} catch {
|
|
2073
|
+
return [];
|
|
2074
|
+
} finally {
|
|
2075
|
+
release();
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
/**
|
|
2079
|
+
* Get diagnostics from ALL matching language servers for a file.
|
|
2080
|
+
* Deduplicates results by (line, character, message).
|
|
2081
|
+
* Individual server failures don't block other servers.
|
|
2082
|
+
*/
|
|
2083
|
+
async getDiagnosticsMulti(filePath, content) {
|
|
2084
|
+
const servers = getServersForFile(filePath, this.config.disableServers);
|
|
2085
|
+
if (servers.length === 0) return [];
|
|
2086
|
+
const release = await this.acquireFileLock(filePath);
|
|
2087
|
+
try {
|
|
2088
|
+
const languageId = getLanguageId(filePath);
|
|
2089
|
+
if (!languageId) return [];
|
|
2090
|
+
const allDiagnostics = [];
|
|
2091
|
+
const results = await Promise.allSettled(
|
|
2092
|
+
servers.map(async (serverDef) => {
|
|
2093
|
+
const projectRoot = await this.resolveRoot(filePath, serverDef.markers);
|
|
2094
|
+
if (serverDef.command(projectRoot) === void 0) return [];
|
|
2095
|
+
const key = `${serverDef.name}:${projectRoot}`;
|
|
2096
|
+
if (this.clients.has(key)) {
|
|
2097
|
+
const existing = this.clients.get(key);
|
|
2098
|
+
if (!existing.isAlive) {
|
|
2099
|
+
this.clients.delete(key);
|
|
2100
|
+
existing.shutdown().catch(() => {
|
|
2101
|
+
});
|
|
2102
|
+
} else {
|
|
2103
|
+
return this.collectDiagnostics(existing, filePath, content, languageId);
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
const client = await this.initClient(serverDef, projectRoot, key);
|
|
2107
|
+
if (!client) return [];
|
|
2108
|
+
return this.collectDiagnostics(client, filePath, content, languageId);
|
|
2109
|
+
})
|
|
2110
|
+
);
|
|
2111
|
+
for (const result of results) {
|
|
2112
|
+
if (result.status === "fulfilled") {
|
|
2113
|
+
allDiagnostics.push(...result.value);
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2117
|
+
return allDiagnostics.filter((d) => {
|
|
2118
|
+
const key = `${d.line}:${d.character}:${d.message}`;
|
|
2119
|
+
if (seen.has(key)) return false;
|
|
2120
|
+
seen.add(key);
|
|
2121
|
+
return true;
|
|
2122
|
+
});
|
|
2123
|
+
} finally {
|
|
2124
|
+
release();
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
/**
|
|
2128
|
+
* Collect diagnostics from a single client for a file.
|
|
2129
|
+
*/
|
|
2130
|
+
async collectDiagnostics(client, filePath, content, languageId) {
|
|
2131
|
+
client.notifyOpen(filePath, content, languageId);
|
|
2132
|
+
client.notifyChange(filePath, content, 1);
|
|
2133
|
+
const diagnosticTimeout = this.config.diagnosticTimeout ?? 5e3;
|
|
2134
|
+
let rawDiagnostics;
|
|
2135
|
+
try {
|
|
2136
|
+
rawDiagnostics = await client.waitForDiagnostics(filePath, diagnosticTimeout);
|
|
2137
|
+
} finally {
|
|
2138
|
+
client.notifyClose(filePath);
|
|
2139
|
+
}
|
|
2140
|
+
return rawDiagnostics.map((d) => ({
|
|
2141
|
+
severity: mapSeverity(d.severity),
|
|
2142
|
+
message: d.message,
|
|
2143
|
+
line: (d.range?.start?.line ?? 0) + 1,
|
|
2144
|
+
character: (d.range?.start?.character ?? 0) + 1,
|
|
2145
|
+
source: d.source
|
|
2146
|
+
}));
|
|
2147
|
+
}
|
|
2148
|
+
/**
|
|
2149
|
+
* Shutdown all managed LSP clients.
|
|
2150
|
+
*/
|
|
2151
|
+
async shutdownAll() {
|
|
2152
|
+
await Promise.allSettled(Array.from(this.clients.values()).map((client) => client.shutdown()));
|
|
2153
|
+
this.clients.clear();
|
|
2154
|
+
this.initPromises.clear();
|
|
2155
|
+
this.fileLocks.clear();
|
|
2156
|
+
}
|
|
2157
|
+
};
|
|
1416
2158
|
|
|
1417
2159
|
// src/workspace/sandbox/errors.ts
|
|
1418
2160
|
var SandboxError = class extends Error {
|
|
@@ -1522,14 +2264,14 @@ var MountManager = class {
|
|
|
1522
2264
|
/**
|
|
1523
2265
|
* Get a mount entry by path.
|
|
1524
2266
|
*/
|
|
1525
|
-
get(
|
|
1526
|
-
return this._entries.get(
|
|
2267
|
+
get(path6) {
|
|
2268
|
+
return this._entries.get(path6);
|
|
1527
2269
|
}
|
|
1528
2270
|
/**
|
|
1529
2271
|
* Check if a mount exists at the given path.
|
|
1530
2272
|
*/
|
|
1531
|
-
has(
|
|
1532
|
-
return this._entries.has(
|
|
2273
|
+
has(path6) {
|
|
2274
|
+
return this._entries.has(path6);
|
|
1533
2275
|
}
|
|
1534
2276
|
// ---------------------------------------------------------------------------
|
|
1535
2277
|
// Entry Modification
|
|
@@ -1541,8 +2283,8 @@ var MountManager = class {
|
|
|
1541
2283
|
add(mounts) {
|
|
1542
2284
|
const paths = Object.keys(mounts);
|
|
1543
2285
|
this.logger.debug(`Adding ${paths.length} pending mount(s)`, { paths });
|
|
1544
|
-
for (const [
|
|
1545
|
-
this._entries.set(
|
|
2286
|
+
for (const [path6, filesystem] of Object.entries(mounts)) {
|
|
2287
|
+
this._entries.set(path6, {
|
|
1546
2288
|
filesystem,
|
|
1547
2289
|
state: "pending"
|
|
1548
2290
|
});
|
|
@@ -1552,8 +2294,8 @@ var MountManager = class {
|
|
|
1552
2294
|
* Update a mount entry's state.
|
|
1553
2295
|
* Creates the entry if it doesn't exist.
|
|
1554
2296
|
*/
|
|
1555
|
-
set(
|
|
1556
|
-
const existing = this._entries.get(
|
|
2297
|
+
set(path6, updates) {
|
|
2298
|
+
const existing = this._entries.get(path6);
|
|
1557
2299
|
if (existing) {
|
|
1558
2300
|
existing.state = updates.state;
|
|
1559
2301
|
if (updates.config) {
|
|
@@ -1564,7 +2306,7 @@ var MountManager = class {
|
|
|
1564
2306
|
existing.error = updates.error;
|
|
1565
2307
|
}
|
|
1566
2308
|
} else if (updates.filesystem) {
|
|
1567
|
-
this._entries.set(
|
|
2309
|
+
this._entries.set(path6, {
|
|
1568
2310
|
filesystem: updates.filesystem,
|
|
1569
2311
|
state: updates.state,
|
|
1570
2312
|
config: updates.config,
|
|
@@ -1572,14 +2314,14 @@ var MountManager = class {
|
|
|
1572
2314
|
error: updates.error
|
|
1573
2315
|
});
|
|
1574
2316
|
} else {
|
|
1575
|
-
this.logger.debug(`set() called for unknown path "${
|
|
2317
|
+
this.logger.debug(`set() called for unknown path "${path6}" without filesystem \u2014 no entry created`);
|
|
1576
2318
|
}
|
|
1577
2319
|
}
|
|
1578
2320
|
/**
|
|
1579
2321
|
* Delete a mount entry.
|
|
1580
2322
|
*/
|
|
1581
|
-
delete(
|
|
1582
|
-
return this._entries.delete(
|
|
2323
|
+
delete(path6) {
|
|
2324
|
+
return this._entries.delete(path6);
|
|
1583
2325
|
}
|
|
1584
2326
|
/**
|
|
1585
2327
|
* Clear all mount entries.
|
|
@@ -1600,7 +2342,7 @@ var MountManager = class {
|
|
|
1600
2342
|
return;
|
|
1601
2343
|
}
|
|
1602
2344
|
this.logger.debug(`Processing ${pendingCount} pending mount(s)`);
|
|
1603
|
-
for (const [
|
|
2345
|
+
for (const [path6, entry] of this._entries) {
|
|
1604
2346
|
if (entry.state !== "pending") {
|
|
1605
2347
|
continue;
|
|
1606
2348
|
}
|
|
@@ -1610,7 +2352,7 @@ var MountManager = class {
|
|
|
1610
2352
|
try {
|
|
1611
2353
|
const hookResult = await this._onMount({
|
|
1612
2354
|
filesystem: entry.filesystem,
|
|
1613
|
-
mountPath:
|
|
2355
|
+
mountPath: path6,
|
|
1614
2356
|
config,
|
|
1615
2357
|
sandbox: this._sandbox,
|
|
1616
2358
|
workspace: this._workspace
|
|
@@ -1618,7 +2360,7 @@ var MountManager = class {
|
|
|
1618
2360
|
if (hookResult === false) {
|
|
1619
2361
|
entry.state = "unsupported";
|
|
1620
2362
|
entry.error = "Skipped by onMount hook";
|
|
1621
|
-
this.logger.debug(`Mount skipped by onMount hook`, { path:
|
|
2363
|
+
this.logger.debug(`Mount skipped by onMount hook`, { path: path6, provider: fsProvider });
|
|
1622
2364
|
continue;
|
|
1623
2365
|
}
|
|
1624
2366
|
if (hookResult && typeof hookResult === "object") {
|
|
@@ -1626,45 +2368,45 @@ var MountManager = class {
|
|
|
1626
2368
|
entry.state = "mounted";
|
|
1627
2369
|
entry.config = config;
|
|
1628
2370
|
entry.configHash = config ? this.hashConfig(config) : void 0;
|
|
1629
|
-
this.logger.info(`Mount handled by onMount hook`, { path:
|
|
2371
|
+
this.logger.info(`Mount handled by onMount hook`, { path: path6, provider: fsProvider });
|
|
1630
2372
|
} else {
|
|
1631
2373
|
entry.state = "error";
|
|
1632
2374
|
entry.error = hookResult.error ?? "Mount hook failed";
|
|
1633
|
-
this.logger.error(`Mount hook failed`, { path:
|
|
2375
|
+
this.logger.error(`Mount hook failed`, { path: path6, provider: fsProvider, error: entry.error });
|
|
1634
2376
|
}
|
|
1635
2377
|
continue;
|
|
1636
2378
|
}
|
|
1637
2379
|
} catch (err) {
|
|
1638
2380
|
entry.state = "error";
|
|
1639
2381
|
entry.error = `Mount hook error: ${String(err)}`;
|
|
1640
|
-
this.logger.error(`Mount hook threw error`, { path:
|
|
2382
|
+
this.logger.error(`Mount hook threw error`, { path: path6, provider: fsProvider, error: entry.error });
|
|
1641
2383
|
continue;
|
|
1642
2384
|
}
|
|
1643
2385
|
}
|
|
1644
2386
|
if (!config) {
|
|
1645
2387
|
entry.state = "unsupported";
|
|
1646
2388
|
entry.error = "Filesystem does not support mounting";
|
|
1647
|
-
this.logger.debug(`Filesystem does not support mounting`, { path:
|
|
2389
|
+
this.logger.debug(`Filesystem does not support mounting`, { path: path6, provider: fsProvider });
|
|
1648
2390
|
continue;
|
|
1649
2391
|
}
|
|
1650
2392
|
entry.config = config;
|
|
1651
2393
|
entry.configHash = this.hashConfig(config);
|
|
1652
2394
|
entry.state = "mounting";
|
|
1653
|
-
this.logger.debug(`Mounting filesystem`, { path:
|
|
2395
|
+
this.logger.debug(`Mounting filesystem`, { path: path6, provider: fsProvider, type: config.type });
|
|
1654
2396
|
try {
|
|
1655
|
-
const result = await this._mountFn(entry.filesystem,
|
|
2397
|
+
const result = await this._mountFn(entry.filesystem, path6);
|
|
1656
2398
|
if (result.success) {
|
|
1657
2399
|
entry.state = "mounted";
|
|
1658
|
-
this.logger.info(`Mount successful`, { path:
|
|
2400
|
+
this.logger.info(`Mount successful`, { path: path6, provider: fsProvider });
|
|
1659
2401
|
} else {
|
|
1660
2402
|
entry.state = "error";
|
|
1661
2403
|
entry.error = result.error ?? "Mount failed";
|
|
1662
|
-
this.logger.error(`Mount failed`, { path:
|
|
2404
|
+
this.logger.error(`Mount failed`, { path: path6, provider: fsProvider, error: entry.error });
|
|
1663
2405
|
}
|
|
1664
2406
|
} catch (err) {
|
|
1665
2407
|
entry.state = "error";
|
|
1666
2408
|
entry.error = String(err);
|
|
1667
|
-
this.logger.error(`Mount threw error`, { path:
|
|
2409
|
+
this.logger.error(`Mount threw error`, { path: path6, provider: fsProvider, error: entry.error });
|
|
1668
2410
|
}
|
|
1669
2411
|
}
|
|
1670
2412
|
}
|
|
@@ -1712,10 +2454,10 @@ var MountManager = class {
|
|
|
1712
2454
|
if (separatorIndex <= 0) {
|
|
1713
2455
|
return null;
|
|
1714
2456
|
}
|
|
1715
|
-
const
|
|
2457
|
+
const path6 = content.slice(0, separatorIndex);
|
|
1716
2458
|
const configHash = content.slice(separatorIndex + 1);
|
|
1717
|
-
if (!
|
|
1718
|
-
return { path:
|
|
2459
|
+
if (!path6 || !configHash) return null;
|
|
2460
|
+
return { path: path6, configHash };
|
|
1719
2461
|
}
|
|
1720
2462
|
/**
|
|
1721
2463
|
* Check if a config hash matches the expected hash for a mount path.
|
|
@@ -2937,18 +3679,18 @@ var VersionedSkillSource = class {
|
|
|
2937
3679
|
/**
|
|
2938
3680
|
* Normalize a path by stripping leading/trailing slashes and dots.
|
|
2939
3681
|
*/
|
|
2940
|
-
#normalizePath(
|
|
2941
|
-
let normalized =
|
|
3682
|
+
#normalizePath(path6) {
|
|
3683
|
+
let normalized = path6.replace(/^[./\\]+|[/\\]+$/g, "");
|
|
2942
3684
|
if (normalized === "") return "";
|
|
2943
3685
|
return normalized;
|
|
2944
3686
|
}
|
|
2945
|
-
async exists(
|
|
2946
|
-
const normalized = this.#normalizePath(
|
|
3687
|
+
async exists(path6) {
|
|
3688
|
+
const normalized = this.#normalizePath(path6);
|
|
2947
3689
|
if (this.#tree.entries[normalized]) return true;
|
|
2948
3690
|
return this.#directories.has(normalized);
|
|
2949
3691
|
}
|
|
2950
|
-
async stat(
|
|
2951
|
-
const normalized = this.#normalizePath(
|
|
3692
|
+
async stat(path6) {
|
|
3693
|
+
const normalized = this.#normalizePath(path6);
|
|
2952
3694
|
const name = normalized.split("/").pop() || normalized || ".";
|
|
2953
3695
|
const entry = this.#tree.entries[normalized];
|
|
2954
3696
|
if (entry) {
|
|
@@ -2970,27 +3712,27 @@ var VersionedSkillSource = class {
|
|
|
2970
3712
|
modifiedAt: this.#versionCreatedAt
|
|
2971
3713
|
};
|
|
2972
3714
|
}
|
|
2973
|
-
throw new Error(`Path not found in skill version tree: ${
|
|
3715
|
+
throw new Error(`Path not found in skill version tree: ${path6}`);
|
|
2974
3716
|
}
|
|
2975
|
-
async readFile(
|
|
2976
|
-
const normalized = this.#normalizePath(
|
|
3717
|
+
async readFile(path6) {
|
|
3718
|
+
const normalized = this.#normalizePath(path6);
|
|
2977
3719
|
const entry = this.#tree.entries[normalized];
|
|
2978
3720
|
if (!entry) {
|
|
2979
|
-
throw new Error(`File not found in skill version tree: ${
|
|
3721
|
+
throw new Error(`File not found in skill version tree: ${path6}`);
|
|
2980
3722
|
}
|
|
2981
3723
|
const blob = await this.#blobStore.get(entry.blobHash);
|
|
2982
3724
|
if (!blob) {
|
|
2983
|
-
throw new Error(`Blob not found for hash ${entry.blobHash} (file: ${
|
|
3725
|
+
throw new Error(`Blob not found for hash ${entry.blobHash} (file: ${path6})`);
|
|
2984
3726
|
}
|
|
2985
3727
|
if (entry.encoding === "base64") {
|
|
2986
3728
|
return Buffer.from(blob.content, "base64");
|
|
2987
3729
|
}
|
|
2988
3730
|
return blob.content;
|
|
2989
3731
|
}
|
|
2990
|
-
async readdir(
|
|
2991
|
-
const normalized = this.#normalizePath(
|
|
3732
|
+
async readdir(path6) {
|
|
3733
|
+
const normalized = this.#normalizePath(path6);
|
|
2992
3734
|
if (!this.#directories.has(normalized)) {
|
|
2993
|
-
throw new Error(`Directory not found in skill version tree: ${
|
|
3735
|
+
throw new Error(`Directory not found in skill version tree: ${path6}`);
|
|
2994
3736
|
}
|
|
2995
3737
|
const prefix = normalized === "" ? "" : normalized + "/";
|
|
2996
3738
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -3023,15 +3765,15 @@ var CompositeVersionedSkillSource = class {
|
|
|
3023
3765
|
this.#fallback = options?.fallback;
|
|
3024
3766
|
this.#fallbackSkills = new Set(options?.fallbackSkills ?? []);
|
|
3025
3767
|
}
|
|
3026
|
-
#normalizePath(
|
|
3027
|
-
return
|
|
3768
|
+
#normalizePath(path6) {
|
|
3769
|
+
return path6.replace(/^[./\\]+|[/\\]+$/g, "");
|
|
3028
3770
|
}
|
|
3029
3771
|
/**
|
|
3030
3772
|
* Route a path to the correct source.
|
|
3031
3773
|
* Returns the source and the remaining path within that source.
|
|
3032
3774
|
*/
|
|
3033
|
-
#routePath(
|
|
3034
|
-
const normalized = this.#normalizePath(
|
|
3775
|
+
#routePath(path6) {
|
|
3776
|
+
const normalized = this.#normalizePath(path6);
|
|
3035
3777
|
if (normalized === "") return null;
|
|
3036
3778
|
const segments = normalized.split("/");
|
|
3037
3779
|
const skillDir = segments[0];
|
|
@@ -3048,15 +3790,15 @@ var CompositeVersionedSkillSource = class {
|
|
|
3048
3790
|
}
|
|
3049
3791
|
return null;
|
|
3050
3792
|
}
|
|
3051
|
-
async exists(
|
|
3052
|
-
const normalized = this.#normalizePath(
|
|
3793
|
+
async exists(path6) {
|
|
3794
|
+
const normalized = this.#normalizePath(path6);
|
|
3053
3795
|
if (normalized === "") return true;
|
|
3054
|
-
const route = this.#routePath(
|
|
3796
|
+
const route = this.#routePath(path6);
|
|
3055
3797
|
if (!route) return false;
|
|
3056
3798
|
return route.source.exists(route.subPath);
|
|
3057
3799
|
}
|
|
3058
|
-
async stat(
|
|
3059
|
-
const normalized = this.#normalizePath(
|
|
3800
|
+
async stat(path6) {
|
|
3801
|
+
const normalized = this.#normalizePath(path6);
|
|
3060
3802
|
if (normalized === "") {
|
|
3061
3803
|
return {
|
|
3062
3804
|
name: ".",
|
|
@@ -3066,21 +3808,21 @@ var CompositeVersionedSkillSource = class {
|
|
|
3066
3808
|
modifiedAt: /* @__PURE__ */ new Date()
|
|
3067
3809
|
};
|
|
3068
3810
|
}
|
|
3069
|
-
const route = this.#routePath(
|
|
3811
|
+
const route = this.#routePath(path6);
|
|
3070
3812
|
if (!route) {
|
|
3071
|
-
throw new Error(`Path not found in composite skill source: ${
|
|
3813
|
+
throw new Error(`Path not found in composite skill source: ${path6}`);
|
|
3072
3814
|
}
|
|
3073
3815
|
return route.source.stat(route.subPath);
|
|
3074
3816
|
}
|
|
3075
|
-
async readFile(
|
|
3076
|
-
const route = this.#routePath(
|
|
3817
|
+
async readFile(path6) {
|
|
3818
|
+
const route = this.#routePath(path6);
|
|
3077
3819
|
if (!route) {
|
|
3078
|
-
throw new Error(`File not found in composite skill source: ${
|
|
3820
|
+
throw new Error(`File not found in composite skill source: ${path6}`);
|
|
3079
3821
|
}
|
|
3080
3822
|
return route.source.readFile(route.subPath);
|
|
3081
3823
|
}
|
|
3082
|
-
async readdir(
|
|
3083
|
-
const normalized = this.#normalizePath(
|
|
3824
|
+
async readdir(path6) {
|
|
3825
|
+
const normalized = this.#normalizePath(path6);
|
|
3084
3826
|
if (normalized === "") {
|
|
3085
3827
|
const entries = [];
|
|
3086
3828
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -3096,9 +3838,9 @@ var CompositeVersionedSkillSource = class {
|
|
|
3096
3838
|
}
|
|
3097
3839
|
return entries;
|
|
3098
3840
|
}
|
|
3099
|
-
const route = this.#routePath(
|
|
3841
|
+
const route = this.#routePath(path6);
|
|
3100
3842
|
if (!route) {
|
|
3101
|
-
throw new Error(`Directory not found in composite skill source: ${
|
|
3843
|
+
throw new Error(`Directory not found in composite skill source: ${path6}`);
|
|
3102
3844
|
}
|
|
3103
3845
|
return route.source.readdir(route.subPath);
|
|
3104
3846
|
}
|
|
@@ -3222,7 +3964,7 @@ var WorkspaceSkillsImpl = class _WorkspaceSkillsImpl {
|
|
|
3222
3964
|
if (a.length !== b.length) return false;
|
|
3223
3965
|
const sortedA = [...a].sort();
|
|
3224
3966
|
const sortedB = [...b].sort();
|
|
3225
|
-
return sortedA.every((
|
|
3967
|
+
return sortedA.every((path6, i) => path6 === sortedB[i]);
|
|
3226
3968
|
}
|
|
3227
3969
|
// ===========================================================================
|
|
3228
3970
|
// Search
|
|
@@ -3270,7 +4012,7 @@ var WorkspaceSkillsImpl = class _WorkspaceSkillsImpl {
|
|
|
3270
4012
|
const skill = this.#skills.get(skillName);
|
|
3271
4013
|
if (!skill) return null;
|
|
3272
4014
|
const safeRefPath = this.#assertRelativePath(referencePath, "reference");
|
|
3273
|
-
const refFilePath = this.#joinPath(skill.path,
|
|
4015
|
+
const refFilePath = this.#joinPath(skill.path, safeRefPath);
|
|
3274
4016
|
if (!await this.#source.exists(refFilePath)) {
|
|
3275
4017
|
return null;
|
|
3276
4018
|
}
|
|
@@ -3286,7 +4028,7 @@ var WorkspaceSkillsImpl = class _WorkspaceSkillsImpl {
|
|
|
3286
4028
|
const skill = this.#skills.get(skillName);
|
|
3287
4029
|
if (!skill) return null;
|
|
3288
4030
|
const safeScriptPath = this.#assertRelativePath(scriptPath, "script");
|
|
3289
|
-
const scriptFilePath = this.#joinPath(skill.path,
|
|
4031
|
+
const scriptFilePath = this.#joinPath(skill.path, safeScriptPath);
|
|
3290
4032
|
if (!await this.#source.exists(scriptFilePath)) {
|
|
3291
4033
|
return null;
|
|
3292
4034
|
}
|
|
@@ -3302,7 +4044,7 @@ var WorkspaceSkillsImpl = class _WorkspaceSkillsImpl {
|
|
|
3302
4044
|
const skill = this.#skills.get(skillName);
|
|
3303
4045
|
if (!skill) return null;
|
|
3304
4046
|
const safeAssetPath = this.#assertRelativePath(assetPath, "asset");
|
|
3305
|
-
const assetFilePath = this.#joinPath(skill.path,
|
|
4047
|
+
const assetFilePath = this.#joinPath(skill.path, safeAssetPath);
|
|
3306
4048
|
if (!await this.#source.exists(assetFilePath)) {
|
|
3307
4049
|
return null;
|
|
3308
4050
|
}
|
|
@@ -3748,7 +4490,7 @@ ${validation.errors.join("\n")}`);
|
|
|
3748
4490
|
if (includeReferences) {
|
|
3749
4491
|
for (const refPath of skill.references) {
|
|
3750
4492
|
if (results.length >= topK) break;
|
|
3751
|
-
const content = await this.getReference(skill.name, refPath);
|
|
4493
|
+
const content = await this.getReference(skill.name, `references/${refPath}`);
|
|
3752
4494
|
if (content && content.toLowerCase().includes(queryLower)) {
|
|
3753
4495
|
results.push({
|
|
3754
4496
|
skillName: skill.name,
|
|
@@ -3791,8 +4533,8 @@ ${validation.errors.join("\n")}`);
|
|
|
3791
4533
|
*/
|
|
3792
4534
|
#assertRelativePath(input, label) {
|
|
3793
4535
|
const normalized = input.replace(/\\/g, "/");
|
|
3794
|
-
const segments = normalized.split("/").filter(Boolean);
|
|
3795
|
-
if (normalized.startsWith("/") || segments.some((seg) => seg === "
|
|
4536
|
+
const segments = normalized.split("/").filter((seg) => Boolean(seg) && seg !== ".");
|
|
4537
|
+
if (normalized.startsWith("/") || segments.some((seg) => seg === "..")) {
|
|
3796
4538
|
throw new Error(`Invalid ${label} path: ${input}`);
|
|
3797
4539
|
}
|
|
3798
4540
|
return segments.join("/");
|
|
@@ -3800,9 +4542,9 @@ ${validation.errors.join("\n")}`);
|
|
|
3800
4542
|
/**
|
|
3801
4543
|
* Get parent path
|
|
3802
4544
|
*/
|
|
3803
|
-
#getParentPath(
|
|
3804
|
-
const lastSlash =
|
|
3805
|
-
return lastSlash > 0 ?
|
|
4545
|
+
#getParentPath(path6) {
|
|
4546
|
+
const lastSlash = path6.lastIndexOf("/");
|
|
4547
|
+
return lastSlash > 0 ? path6.substring(0, lastSlash) : "/";
|
|
3806
4548
|
}
|
|
3807
4549
|
};
|
|
3808
4550
|
function hashContent(content) {
|
|
@@ -3963,6 +4705,7 @@ var Workspace = class {
|
|
|
3963
4705
|
_config;
|
|
3964
4706
|
_searchEngine;
|
|
3965
4707
|
_skills;
|
|
4708
|
+
_lsp;
|
|
3966
4709
|
constructor(config) {
|
|
3967
4710
|
this.id = config.id ?? this.generateId();
|
|
3968
4711
|
this.name = config.name ?? `workspace-${this.id.slice(0, 8)}`;
|
|
@@ -4019,6 +4762,26 @@ var Workspace = class {
|
|
|
4019
4762
|
} : void 0
|
|
4020
4763
|
});
|
|
4021
4764
|
}
|
|
4765
|
+
if (config.lsp) {
|
|
4766
|
+
const processes = this._sandbox?.processes;
|
|
4767
|
+
if (!this._sandbox) {
|
|
4768
|
+
console.warn(
|
|
4769
|
+
`[Workspace "${this.name}"] lsp: true requires a sandbox with a process manager. No sandbox configured \u2014 LSP disabled.`
|
|
4770
|
+
);
|
|
4771
|
+
} else if (!processes) {
|
|
4772
|
+
console.warn(
|
|
4773
|
+
`[Workspace "${this.name}"] lsp: true requires a sandbox with a process manager. Sandbox "${this._sandbox.name ?? "unknown"}" does not provide one \u2014 LSP disabled.`
|
|
4774
|
+
);
|
|
4775
|
+
} else if (!isLSPAvailable()) {
|
|
4776
|
+
console.warn(
|
|
4777
|
+
`[Workspace "${this.name}"] lsp: true requires vscode-jsonrpc and vscode-languageserver-protocol packages. Install them to enable LSP diagnostics.`
|
|
4778
|
+
);
|
|
4779
|
+
} else {
|
|
4780
|
+
const lspConfig = config.lsp === true ? {} : config.lsp;
|
|
4781
|
+
const defaultRoot = lspConfig.root ?? findProjectRoot(process.cwd()) ?? process.cwd();
|
|
4782
|
+
this._lsp = new LSPManager(processes, defaultRoot, lspConfig, this._fs);
|
|
4783
|
+
}
|
|
4784
|
+
}
|
|
4022
4785
|
if (!this._fs && !this._sandbox && !this.hasSkillsConfig()) {
|
|
4023
4786
|
throw new WorkspaceError("Workspace requires at least a filesystem, sandbox, or skills", "NO_PROVIDERS");
|
|
4024
4787
|
}
|
|
@@ -4057,6 +4820,13 @@ var Workspace = class {
|
|
|
4057
4820
|
getToolsConfig() {
|
|
4058
4821
|
return this._config.tools;
|
|
4059
4822
|
}
|
|
4823
|
+
/**
|
|
4824
|
+
* The LSP manager (if configured, initialized, and a process manager is available).
|
|
4825
|
+
* Returns undefined if LSP is not configured, deps are missing, or sandbox has no process manager.
|
|
4826
|
+
*/
|
|
4827
|
+
get lsp() {
|
|
4828
|
+
return this._lsp;
|
|
4829
|
+
}
|
|
4060
4830
|
/**
|
|
4061
4831
|
* Update the per-tool configuration for this workspace.
|
|
4062
4832
|
* Takes effect on the next `createWorkspaceTools()` call.
|
|
@@ -4137,13 +4907,13 @@ var Workspace = class {
|
|
|
4137
4907
|
* @param options - Index options (metadata, type hints)
|
|
4138
4908
|
* @throws {SearchNotAvailableError} if search is not configured
|
|
4139
4909
|
*/
|
|
4140
|
-
async index(
|
|
4910
|
+
async index(path6, content, options) {
|
|
4141
4911
|
if (!this._searchEngine) {
|
|
4142
4912
|
throw new SearchNotAvailableError();
|
|
4143
4913
|
}
|
|
4144
4914
|
this.lastAccessedAt = /* @__PURE__ */ new Date();
|
|
4145
4915
|
const doc = {
|
|
4146
|
-
id:
|
|
4916
|
+
id: path6,
|
|
4147
4917
|
content,
|
|
4148
4918
|
metadata: {
|
|
4149
4919
|
type: options?.type,
|
|
@@ -4260,6 +5030,13 @@ var Workspace = class {
|
|
|
4260
5030
|
async destroy() {
|
|
4261
5031
|
this._status = "destroying";
|
|
4262
5032
|
try {
|
|
5033
|
+
if (this._lsp) {
|
|
5034
|
+
try {
|
|
5035
|
+
await this._lsp.shutdownAll();
|
|
5036
|
+
} catch {
|
|
5037
|
+
}
|
|
5038
|
+
this._lsp = void 0;
|
|
5039
|
+
}
|
|
4263
5040
|
if (this._sandbox) {
|
|
4264
5041
|
await callLifecycle(this._sandbox, "destroy");
|
|
4265
5042
|
}
|
|
@@ -4850,11 +5627,11 @@ function buildBwrapCommand(command, workspacePath, config) {
|
|
|
4850
5627
|
}
|
|
4851
5628
|
bwrapArgs.push("--proc", "/proc");
|
|
4852
5629
|
bwrapArgs.push("--tmpfs", "/tmp");
|
|
4853
|
-
for (const
|
|
4854
|
-
bwrapArgs.push("--ro-bind-try",
|
|
5630
|
+
for (const path6 of DEFAULT_READONLY_BINDS) {
|
|
5631
|
+
bwrapArgs.push("--ro-bind-try", path6, path6);
|
|
4855
5632
|
}
|
|
4856
|
-
for (const
|
|
4857
|
-
bwrapArgs.push("--ro-bind",
|
|
5633
|
+
for (const path6 of config.readOnlyPaths ?? []) {
|
|
5634
|
+
bwrapArgs.push("--ro-bind", path6, path6);
|
|
4858
5635
|
}
|
|
4859
5636
|
if (config.allowSystemBinaries !== false) {
|
|
4860
5637
|
const nodePath4 = process.execPath;
|
|
@@ -4866,8 +5643,8 @@ function buildBwrapCommand(command, workspacePath, config) {
|
|
|
4866
5643
|
bwrapArgs.push("--ro-bind-try", "/snap", "/snap");
|
|
4867
5644
|
}
|
|
4868
5645
|
bwrapArgs.push("--bind", workspacePath, workspacePath);
|
|
4869
|
-
for (const
|
|
4870
|
-
bwrapArgs.push("--bind",
|
|
5646
|
+
for (const path6 of config.readWritePaths ?? []) {
|
|
5647
|
+
bwrapArgs.push("--bind", path6, path6);
|
|
4871
5648
|
}
|
|
4872
5649
|
bwrapArgs.push("--chdir", workspacePath);
|
|
4873
5650
|
bwrapArgs.push("--die-with-parent");
|
|
@@ -5112,8 +5889,6 @@ var WORKSPACE_TOOLS = {
|
|
|
5112
5889
|
INDEX: `${WORKSPACE_TOOLS_PREFIX}_index`
|
|
5113
5890
|
}
|
|
5114
5891
|
};
|
|
5115
|
-
|
|
5116
|
-
// src/workspace/tools/helpers.ts
|
|
5117
5892
|
function requireWorkspace(context) {
|
|
5118
5893
|
if (!context?.workspace) {
|
|
5119
5894
|
throw new WorkspaceNotAvailableError();
|
|
@@ -5143,6 +5918,63 @@ async function emitWorkspaceMetadata(context, toolName) {
|
|
|
5143
5918
|
data: { toolName, toolCallId, ...info }
|
|
5144
5919
|
});
|
|
5145
5920
|
}
|
|
5921
|
+
async function getEditDiagnosticsText(workspace, filePath, content) {
|
|
5922
|
+
try {
|
|
5923
|
+
const lspManager = workspace.lsp;
|
|
5924
|
+
if (!lspManager) return "";
|
|
5925
|
+
const absolutePath = workspace.filesystem?.resolveAbsolutePath?.(filePath) ?? nodePath__default.resolve(lspManager.root, filePath.replace(/^\/+/, ""));
|
|
5926
|
+
const DIAG_TIMEOUT_MS = 1e4;
|
|
5927
|
+
let diagTimer;
|
|
5928
|
+
const diagnostics = await Promise.race([
|
|
5929
|
+
lspManager.getDiagnostics(absolutePath, content),
|
|
5930
|
+
new Promise((_, reject) => {
|
|
5931
|
+
diagTimer = setTimeout(() => reject(new Error("LSP diagnostics timeout")), DIAG_TIMEOUT_MS);
|
|
5932
|
+
})
|
|
5933
|
+
]).finally(() => clearTimeout(diagTimer));
|
|
5934
|
+
if (diagnostics.length === 0) return "";
|
|
5935
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5936
|
+
const deduped = diagnostics.filter((d) => {
|
|
5937
|
+
const key = `${d.severity}:${d.line}:${d.character}:${d.message}`;
|
|
5938
|
+
if (seen.has(key)) return false;
|
|
5939
|
+
seen.add(key);
|
|
5940
|
+
return true;
|
|
5941
|
+
});
|
|
5942
|
+
const groups = {
|
|
5943
|
+
error: [],
|
|
5944
|
+
warning: [],
|
|
5945
|
+
info: [],
|
|
5946
|
+
hint: []
|
|
5947
|
+
};
|
|
5948
|
+
for (const d of deduped) {
|
|
5949
|
+
groups[d.severity].push(d);
|
|
5950
|
+
}
|
|
5951
|
+
const lines = ["\n\nLSP Diagnostics:"];
|
|
5952
|
+
const severityLabels = [
|
|
5953
|
+
["error", "Errors"],
|
|
5954
|
+
["warning", "Warnings"],
|
|
5955
|
+
["info", "Info"],
|
|
5956
|
+
["hint", "Hints"]
|
|
5957
|
+
];
|
|
5958
|
+
for (const [severity, label] of severityLabels) {
|
|
5959
|
+
const items = groups[severity];
|
|
5960
|
+
if (items.length === 0) continue;
|
|
5961
|
+
lines.push(`${label}:`);
|
|
5962
|
+
for (const d of items) {
|
|
5963
|
+
const source = d.source ? ` [${d.source}]` : "";
|
|
5964
|
+
lines.push(` ${d.line}:${d.character} - ${d.message}${source}`);
|
|
5965
|
+
}
|
|
5966
|
+
}
|
|
5967
|
+
let result = lines.join("\n");
|
|
5968
|
+
const maxChars = 2e3;
|
|
5969
|
+
if (result.length > maxChars) {
|
|
5970
|
+
const cutoff = result.lastIndexOf("\n", maxChars);
|
|
5971
|
+
result = result.slice(0, cutoff > 0 ? cutoff : maxChars) + "\n ... (truncated)";
|
|
5972
|
+
}
|
|
5973
|
+
return result;
|
|
5974
|
+
} catch {
|
|
5975
|
+
return "";
|
|
5976
|
+
}
|
|
5977
|
+
}
|
|
5146
5978
|
|
|
5147
5979
|
// src/workspace/tools/ast-edit.ts
|
|
5148
5980
|
var astGrepModule;
|
|
@@ -5373,8 +6205,8 @@ Pattern replace (for everything else):
|
|
|
5373
6205
|
isDefault: z.boolean().optional().describe("Whether the first name is a default import")
|
|
5374
6206
|
}).optional().describe("Required for add-import transform. Specifies the module and names to import.")
|
|
5375
6207
|
}),
|
|
5376
|
-
execute: async ({ path:
|
|
5377
|
-
const { filesystem } = requireFilesystem(context);
|
|
6208
|
+
execute: async ({ path: path6, pattern, replacement, transform, targetName, newName, importSpec }, context) => {
|
|
6209
|
+
const { workspace, filesystem } = requireFilesystem(context);
|
|
5378
6210
|
await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.AST_EDIT);
|
|
5379
6211
|
if (filesystem.readOnly) {
|
|
5380
6212
|
throw new WorkspaceReadOnlyError("ast_edit");
|
|
@@ -5383,24 +6215,24 @@ Pattern replace (for everything else):
|
|
|
5383
6215
|
if (!astGrep) {
|
|
5384
6216
|
return "@ast-grep/napi is not available. Install it to use AST editing.";
|
|
5385
6217
|
}
|
|
5386
|
-
const { parse, Lang } = astGrep;
|
|
6218
|
+
const { parse: parse2, Lang } = astGrep;
|
|
5387
6219
|
let content;
|
|
5388
6220
|
try {
|
|
5389
|
-
content = await filesystem.readFile(
|
|
6221
|
+
content = await filesystem.readFile(path6, { encoding: "utf-8" });
|
|
5390
6222
|
} catch (error) {
|
|
5391
6223
|
if (error instanceof FileNotFoundError) {
|
|
5392
|
-
return `File not found: ${
|
|
6224
|
+
return `File not found: ${path6}. Use ${WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE} to create it first.`;
|
|
5393
6225
|
}
|
|
5394
6226
|
throw error;
|
|
5395
6227
|
}
|
|
5396
6228
|
if (typeof content !== "string") {
|
|
5397
6229
|
return `Cannot perform AST edits on binary files. Use ${WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE} instead.`;
|
|
5398
6230
|
}
|
|
5399
|
-
const lang = getLanguageFromPath(
|
|
6231
|
+
const lang = getLanguageFromPath(path6, Lang);
|
|
5400
6232
|
if (!lang) {
|
|
5401
|
-
return `Unsupported file type for AST editing: ${
|
|
6233
|
+
return `Unsupported file type for AST editing: ${path6}`;
|
|
5402
6234
|
}
|
|
5403
|
-
const ast =
|
|
6235
|
+
const ast = parse2(lang, content);
|
|
5404
6236
|
const root = ast.root();
|
|
5405
6237
|
let modifiedContent = content;
|
|
5406
6238
|
const changes = [];
|
|
@@ -5448,12 +6280,14 @@ Pattern replace (for everything else):
|
|
|
5448
6280
|
}
|
|
5449
6281
|
const wasModified = modifiedContent !== content;
|
|
5450
6282
|
if (wasModified) {
|
|
5451
|
-
await filesystem.writeFile(
|
|
6283
|
+
await filesystem.writeFile(path6, modifiedContent, { overwrite: true });
|
|
5452
6284
|
}
|
|
5453
6285
|
if (!wasModified) {
|
|
5454
|
-
return `No changes made to ${
|
|
6286
|
+
return `No changes made to ${path6} (${changes.join("; ")})`;
|
|
5455
6287
|
}
|
|
5456
|
-
|
|
6288
|
+
let output = `${path6}: ${changes.join("; ")}`;
|
|
6289
|
+
output += await getEditDiagnosticsText(workspace, path6, modifiedContent);
|
|
6290
|
+
return output;
|
|
5457
6291
|
}
|
|
5458
6292
|
});
|
|
5459
6293
|
var deleteFileTool = createTool({
|
|
@@ -5463,19 +6297,19 @@ var deleteFileTool = createTool({
|
|
|
5463
6297
|
path: z.string().describe("The path to the file or directory to delete"),
|
|
5464
6298
|
recursive: z.boolean().optional().default(false).describe("If true, delete directories and their contents recursively. Required for non-empty directories.")
|
|
5465
6299
|
}),
|
|
5466
|
-
execute: async ({ path:
|
|
6300
|
+
execute: async ({ path: path6, recursive }, context) => {
|
|
5467
6301
|
const { filesystem } = requireFilesystem(context);
|
|
5468
6302
|
await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.DELETE);
|
|
5469
6303
|
if (filesystem.readOnly) {
|
|
5470
6304
|
throw new WorkspaceReadOnlyError("delete");
|
|
5471
6305
|
}
|
|
5472
|
-
const stat3 = await filesystem.stat(
|
|
6306
|
+
const stat3 = await filesystem.stat(path6);
|
|
5473
6307
|
if (stat3.type === "directory") {
|
|
5474
|
-
await filesystem.rmdir(
|
|
6308
|
+
await filesystem.rmdir(path6, { recursive, force: recursive });
|
|
5475
6309
|
} else {
|
|
5476
|
-
await filesystem.deleteFile(
|
|
6310
|
+
await filesystem.deleteFile(path6);
|
|
5477
6311
|
}
|
|
5478
|
-
return `Deleted ${
|
|
6312
|
+
return `Deleted ${path6}`;
|
|
5479
6313
|
}
|
|
5480
6314
|
});
|
|
5481
6315
|
var editFileTool = createTool({
|
|
@@ -5493,20 +6327,22 @@ Usage:
|
|
|
5493
6327
|
new_string: z.string().describe("The text to replace old_string with"),
|
|
5494
6328
|
replace_all: z.boolean().optional().default(false).describe("If true, replace all occurrences. If false (default), old_string must be unique.")
|
|
5495
6329
|
}),
|
|
5496
|
-
execute: async ({ path:
|
|
5497
|
-
const { filesystem } = requireFilesystem(context);
|
|
6330
|
+
execute: async ({ path: path6, old_string, new_string, replace_all }, context) => {
|
|
6331
|
+
const { workspace, filesystem } = requireFilesystem(context);
|
|
5498
6332
|
await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.EDIT_FILE);
|
|
5499
6333
|
if (filesystem.readOnly) {
|
|
5500
6334
|
throw new WorkspaceReadOnlyError("edit_file");
|
|
5501
6335
|
}
|
|
5502
6336
|
try {
|
|
5503
|
-
const content = await filesystem.readFile(
|
|
6337
|
+
const content = await filesystem.readFile(path6, { encoding: "utf-8" });
|
|
5504
6338
|
if (typeof content !== "string") {
|
|
5505
6339
|
return `Cannot edit binary files. Use ${WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE} instead.`;
|
|
5506
6340
|
}
|
|
5507
6341
|
const result = replaceString(content, old_string, new_string, replace_all);
|
|
5508
|
-
await filesystem.writeFile(
|
|
5509
|
-
|
|
6342
|
+
await filesystem.writeFile(path6, result.content, { overwrite: true });
|
|
6343
|
+
let output = `Replaced ${result.replacements} occurrence${result.replacements !== 1 ? "s" : ""} in ${path6}`;
|
|
6344
|
+
output += await getEditDiagnosticsText(workspace, path6, result.content);
|
|
6345
|
+
return output;
|
|
5510
6346
|
} catch (error) {
|
|
5511
6347
|
if (error instanceof StringNotFoundError) {
|
|
5512
6348
|
return error.message;
|
|
@@ -5663,19 +6499,19 @@ var fileStatTool = createTool({
|
|
|
5663
6499
|
inputSchema: z.object({
|
|
5664
6500
|
path: z.string().describe("The path to check")
|
|
5665
6501
|
}),
|
|
5666
|
-
execute: async ({ path:
|
|
6502
|
+
execute: async ({ path: path6 }, context) => {
|
|
5667
6503
|
const { filesystem } = requireFilesystem(context);
|
|
5668
6504
|
await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.FILE_STAT);
|
|
5669
6505
|
try {
|
|
5670
|
-
const stat3 = await filesystem.stat(
|
|
6506
|
+
const stat3 = await filesystem.stat(path6);
|
|
5671
6507
|
const modifiedAt = stat3.modifiedAt.toISOString();
|
|
5672
|
-
const parts = [`${
|
|
6508
|
+
const parts = [`${path6}`, `Type: ${stat3.type}`];
|
|
5673
6509
|
if (stat3.size !== void 0) parts.push(`Size: ${stat3.size} bytes`);
|
|
5674
6510
|
parts.push(`Modified: ${modifiedAt}`);
|
|
5675
6511
|
return parts.join(" ");
|
|
5676
6512
|
} catch (error) {
|
|
5677
6513
|
if (error instanceof FileNotFoundError) {
|
|
5678
|
-
return `${
|
|
6514
|
+
return `${path6}: not found`;
|
|
5679
6515
|
}
|
|
5680
6516
|
throw error;
|
|
5681
6517
|
}
|
|
@@ -5906,11 +6742,11 @@ var indexContentTool = createTool({
|
|
|
5906
6742
|
content: z.string().describe("The text content to index"),
|
|
5907
6743
|
metadata: z.record(z.unknown()).optional().describe("Optional metadata to store with the document")
|
|
5908
6744
|
}),
|
|
5909
|
-
execute: async ({ path:
|
|
6745
|
+
execute: async ({ path: path6, content, metadata }, context) => {
|
|
5910
6746
|
const workspace = requireWorkspace(context);
|
|
5911
6747
|
await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.SEARCH.INDEX);
|
|
5912
|
-
await workspace.index(
|
|
5913
|
-
return `Indexed ${
|
|
6748
|
+
await workspace.index(path6, content, { metadata });
|
|
6749
|
+
return `Indexed ${path6}`;
|
|
5914
6750
|
}
|
|
5915
6751
|
});
|
|
5916
6752
|
var KILL_TAIL_LINES = 50;
|
|
@@ -5968,7 +6804,7 @@ var BRANCH = "\u251C\u2500\u2500 ";
|
|
|
5968
6804
|
var LAST_BRANCH = "\u2514\u2500\u2500 ";
|
|
5969
6805
|
var VERTICAL = "\u2502 ";
|
|
5970
6806
|
var SPACE = " ";
|
|
5971
|
-
async function formatAsTree(fs5,
|
|
6807
|
+
async function formatAsTree(fs5, path6, options) {
|
|
5972
6808
|
const maxDepth = options?.maxDepth ?? Infinity;
|
|
5973
6809
|
const showHidden = options?.showHidden ?? false;
|
|
5974
6810
|
const dirsOnly = options?.dirsOnly ?? false;
|
|
@@ -6024,12 +6860,12 @@ async function formatAsTree(fs5, path4, options) {
|
|
|
6024
6860
|
if (globMatcher && !dirsOnly) {
|
|
6025
6861
|
filtered = filtered.filter((e) => {
|
|
6026
6862
|
if (e.type === "directory") return true;
|
|
6027
|
-
const entryPath = currentPath ===
|
|
6863
|
+
const entryPath = currentPath === path6 ? e.name : `${currentPath === "/" ? "" : currentPath}/${e.name}`;
|
|
6028
6864
|
let relativePath;
|
|
6029
|
-
if (
|
|
6865
|
+
if (path6 === "/" || path6 === "") {
|
|
6030
6866
|
relativePath = entryPath.startsWith("/") ? entryPath.slice(1) : entryPath;
|
|
6031
6867
|
} else {
|
|
6032
|
-
relativePath = entryPath.startsWith(
|
|
6868
|
+
relativePath = entryPath.startsWith(path6 + "/") ? entryPath.slice(path6.length + 1) : entryPath;
|
|
6033
6869
|
if (!relativePath) relativePath = entryPath;
|
|
6034
6870
|
}
|
|
6035
6871
|
return globMatcher(relativePath);
|
|
@@ -6058,7 +6894,7 @@ async function formatAsTree(fs5, path4, options) {
|
|
|
6058
6894
|
}
|
|
6059
6895
|
}
|
|
6060
6896
|
}
|
|
6061
|
-
await buildTree(
|
|
6897
|
+
await buildTree(path6, "", 0);
|
|
6062
6898
|
const dirPart = dirCount === 1 ? "1 directory" : `${dirCount} directories`;
|
|
6063
6899
|
const filePart = fileCount === 1 ? "1 file" : `${fileCount} files`;
|
|
6064
6900
|
let summary = `${dirPart}, ${filePart}`;
|
|
@@ -6107,10 +6943,10 @@ Examples:
|
|
|
6107
6943
|
'Glob pattern(s) to filter files. Examples: "**/*.ts", "src/**/*.test.ts", "*.config.{js,ts}". Directories always pass through.'
|
|
6108
6944
|
)
|
|
6109
6945
|
}),
|
|
6110
|
-
execute: async ({ path:
|
|
6946
|
+
execute: async ({ path: path6 = "./", maxDepth = 3, showHidden, dirsOnly, exclude, extension, pattern }, context) => {
|
|
6111
6947
|
const { filesystem } = requireFilesystem(context);
|
|
6112
6948
|
await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.LIST_FILES);
|
|
6113
|
-
const result = await formatAsTree(filesystem,
|
|
6949
|
+
const result = await formatAsTree(filesystem, path6, {
|
|
6114
6950
|
maxDepth,
|
|
6115
6951
|
showHidden,
|
|
6116
6952
|
dirsOnly,
|
|
@@ -6130,14 +6966,14 @@ var mkdirTool = createTool({
|
|
|
6130
6966
|
path: z.string().describe("The path of the directory to create"),
|
|
6131
6967
|
recursive: z.boolean().optional().default(true).describe("Whether to create parent directories if they do not exist")
|
|
6132
6968
|
}),
|
|
6133
|
-
execute: async ({ path:
|
|
6969
|
+
execute: async ({ path: path6, recursive }, context) => {
|
|
6134
6970
|
const { filesystem } = requireFilesystem(context);
|
|
6135
6971
|
await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.MKDIR);
|
|
6136
6972
|
if (filesystem.readOnly) {
|
|
6137
6973
|
throw new WorkspaceReadOnlyError("mkdir");
|
|
6138
6974
|
}
|
|
6139
|
-
await filesystem.mkdir(
|
|
6140
|
-
return `Created directory ${
|
|
6975
|
+
await filesystem.mkdir(path6, { recursive });
|
|
6976
|
+
return `Created directory ${path6}`;
|
|
6141
6977
|
}
|
|
6142
6978
|
});
|
|
6143
6979
|
var readFileTool = createTool({
|
|
@@ -6150,12 +6986,12 @@ var readFileTool = createTool({
|
|
|
6150
6986
|
limit: z.number().optional().describe("Maximum number of lines to read. If omitted, reads to the end of the file."),
|
|
6151
6987
|
showLineNumbers: z.boolean().optional().default(true).describe("Whether to prefix each line with its line number (default: true)")
|
|
6152
6988
|
}),
|
|
6153
|
-
execute: async ({ path:
|
|
6989
|
+
execute: async ({ path: path6, encoding, offset, limit, showLineNumbers }, context) => {
|
|
6154
6990
|
const { filesystem } = requireFilesystem(context);
|
|
6155
6991
|
await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.READ_FILE);
|
|
6156
6992
|
const effectiveEncoding = encoding ?? "utf-8";
|
|
6157
|
-
const fullContent = await filesystem.readFile(
|
|
6158
|
-
const stat3 = await filesystem.stat(
|
|
6993
|
+
const fullContent = await filesystem.readFile(path6, { encoding: effectiveEncoding });
|
|
6994
|
+
const stat3 = await filesystem.stat(path6);
|
|
6159
6995
|
const isTextEncoding = !encoding || encoding === "utf-8" || encoding === "utf8";
|
|
6160
6996
|
if (!isTextEncoding) {
|
|
6161
6997
|
return `${stat3.path} (${stat3.size} bytes, ${effectiveEncoding})
|
|
@@ -6214,15 +7050,17 @@ var writeFileTool = createTool({
|
|
|
6214
7050
|
content: z.string().describe("The content to write to the file"),
|
|
6215
7051
|
overwrite: z.boolean().optional().default(true).describe("Whether to overwrite the file if it already exists")
|
|
6216
7052
|
}),
|
|
6217
|
-
execute: async ({ path:
|
|
6218
|
-
const { filesystem } = requireFilesystem(context);
|
|
7053
|
+
execute: async ({ path: path6, content, overwrite }, context) => {
|
|
7054
|
+
const { workspace, filesystem } = requireFilesystem(context);
|
|
6219
7055
|
await emitWorkspaceMetadata(context, WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE);
|
|
6220
7056
|
if (filesystem.readOnly) {
|
|
6221
7057
|
throw new WorkspaceReadOnlyError("write_file");
|
|
6222
7058
|
}
|
|
6223
|
-
await filesystem.writeFile(
|
|
7059
|
+
await filesystem.writeFile(path6, content, { overwrite });
|
|
6224
7060
|
const size = Buffer.byteLength(content, "utf-8");
|
|
6225
|
-
|
|
7061
|
+
let output = `Wrote ${size} bytes to ${path6}`;
|
|
7062
|
+
output += await getEditDiagnosticsText(workspace, path6, content);
|
|
7063
|
+
return output;
|
|
6226
7064
|
}
|
|
6227
7065
|
});
|
|
6228
7066
|
|
|
@@ -6378,5 +7216,5 @@ function createWorkspaceTools(workspace) {
|
|
|
6378
7216
|
}
|
|
6379
7217
|
|
|
6380
7218
|
export { BM25Index, CompositeFilesystem, CompositeVersionedSkillSource, DirectoryNotEmptyError, DirectoryNotFoundError, FileExistsError, FileNotFoundError, FileReadRequiredError, FilesystemError, FilesystemNotAvailableError, FilesystemNotMountableError, FilesystemNotReadyError, IsDirectoryError, IsolationUnavailableError, LocalFilesystem, LocalSandbox, LocalSkillSource, MastraFilesystem, MastraSandbox, MountError, MountManager, MountNotSupportedError, NotDirectoryError, PermissionError, ProcessHandle, SandboxError, SandboxExecutionError, SandboxFeatureNotSupportedError, SandboxNotAvailableError, SandboxNotReadyError, SandboxProcessManager, SandboxTimeoutError, SearchNotAvailableError, VersionedSkillSource, WORKSPACE_TOOLS, WORKSPACE_TOOLS_PREFIX, Workspace, WorkspaceError, WorkspaceNotAvailableError, WorkspaceNotReadyError, WorkspaceReadOnlyError, callLifecycle, collectSkillForPublish, createGlobMatcher, createWorkspaceTools, deleteFileTool, detectIsolation, editFileTool, executeCommandTool, extractGlobBase, extractLines, fileStatTool, getRecommendedIsolation, indexContentTool, isGlobPattern, isIsolationAvailable, listFilesTool, matchGlob, mkdirTool, publishSkillFromSource, readFileTool, requireFilesystem, requireSandbox, requireWorkspace, resolveToolConfig, searchTool, writeFileTool };
|
|
6381
|
-
//# sourceMappingURL=chunk-
|
|
6382
|
-
//# sourceMappingURL=chunk-
|
|
7219
|
+
//# sourceMappingURL=chunk-4H5F6AFP.js.map
|
|
7220
|
+
//# sourceMappingURL=chunk-4H5F6AFP.js.map
|