@mastra/core 1.9.0 → 1.10.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 +202 -0
- package/dist/agent/agent.d.ts +22 -3
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/index.cjs +13 -13
- 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/message-list.d.ts.map +1 -1
- package/dist/{chunk-IOY7Y5GV.js → chunk-3VVNJPTO.js} +602 -187
- package/dist/chunk-3VVNJPTO.js.map +1 -0
- package/dist/{chunk-VDKWYUGC.cjs → chunk-5WBEMKE2.cjs} +7 -3
- package/dist/chunk-5WBEMKE2.cjs.map +1 -0
- package/dist/{chunk-H5S4PS44.cjs → chunk-76Q75VI4.cjs} +602 -187
- package/dist/chunk-76Q75VI4.cjs.map +1 -0
- package/dist/{chunk-ZBESCKPX.cjs → chunk-7AHCLTZZ.cjs} +1572 -36
- package/dist/chunk-7AHCLTZZ.cjs.map +1 -0
- package/dist/{chunk-SEKQJ447.js → chunk-ACAILOJE.js} +166 -68
- package/dist/chunk-ACAILOJE.js.map +1 -0
- package/dist/{chunk-YIJZBU54.cjs → chunk-BCSVBOAN.cjs} +240 -463
- package/dist/chunk-BCSVBOAN.cjs.map +1 -0
- package/dist/{chunk-ZVWVQ6MG.js → chunk-CY4ZWL2X.js} +8 -3
- package/dist/chunk-CY4ZWL2X.js.map +1 -0
- package/dist/{chunk-ET7GXCHS.js → chunk-DIKRJVK6.js} +5 -5
- package/dist/{chunk-ET7GXCHS.js.map → chunk-DIKRJVK6.js.map} +1 -1
- package/dist/{chunk-P6ZX7OKT.cjs → chunk-E6I5LBDM.cjs} +7 -7
- package/dist/{chunk-P6ZX7OKT.cjs.map → chunk-E6I5LBDM.cjs.map} +1 -1
- package/dist/{chunk-BFV3GSGS.js → chunk-FT5Q6XTK.js} +1546 -22
- package/dist/chunk-FT5Q6XTK.js.map +1 -0
- package/dist/{chunk-K54LFB4P.js → chunk-FXOWXS4O.js} +3 -3
- package/dist/{chunk-K54LFB4P.js.map → chunk-FXOWXS4O.js.map} +1 -1
- package/dist/{chunk-QNXY3J6B.cjs → chunk-GCRPNAAR.cjs} +22 -19
- package/dist/chunk-GCRPNAAR.cjs.map +1 -0
- package/dist/{chunk-5M3RMO7U.js → chunk-GTA5BKXZ.js} +8 -8
- package/dist/{chunk-5M3RMO7U.js.map → chunk-GTA5BKXZ.js.map} +1 -1
- package/dist/{chunk-G5R2755Q.cjs → chunk-HAIQ57YB.cjs} +53 -20
- package/dist/chunk-HAIQ57YB.cjs.map +1 -0
- package/dist/{chunk-3ZBLD2Y4.cjs → chunk-HH76UOJL.cjs} +2 -2
- package/dist/{chunk-3ZBLD2Y4.cjs.map → chunk-HH76UOJL.cjs.map} +1 -1
- package/dist/{chunk-HAGCXIBX.cjs → chunk-HNYQITSV.cjs} +9 -9
- package/dist/{chunk-HAGCXIBX.cjs.map → chunk-HNYQITSV.cjs.map} +1 -1
- package/dist/{chunk-GJTLWOKJ.js → chunk-HQA3IBLZ.js} +51 -18
- package/dist/chunk-HQA3IBLZ.js.map +1 -0
- package/dist/{chunk-4BXXAZ75.js → chunk-HQTHWVAK.js} +15 -7
- package/dist/chunk-HQTHWVAK.js.map +1 -0
- package/dist/{chunk-CCLV5CAA.js → chunk-JGOH7RWL.js} +7 -3
- package/dist/chunk-JGOH7RWL.js.map +1 -0
- package/dist/{chunk-Y6TGIUGL.js → chunk-LSF5WJ6G.js} +2 -2
- package/dist/{chunk-Y6TGIUGL.js.map → chunk-LSF5WJ6G.js.map} +1 -1
- package/dist/{chunk-D6HO5QAM.cjs → chunk-M26GEN4C.cjs} +14 -9
- package/dist/chunk-M26GEN4C.cjs.map +1 -0
- package/dist/{chunk-4P35AVPE.cjs → chunk-MEMYFFOL.cjs} +256 -157
- package/dist/chunk-MEMYFFOL.cjs.map +1 -0
- package/dist/{chunk-BQ355Z3O.js → chunk-NUZWQA4J.js} +4 -4
- package/dist/{chunk-BQ355Z3O.js.map → chunk-NUZWQA4J.js.map} +1 -1
- package/dist/{chunk-JIRB5LX4.js → chunk-OHX36YXF.js} +5 -3
- package/dist/chunk-OHX36YXF.js.map +1 -0
- package/dist/{chunk-PKORY4ZZ.cjs → chunk-OOTLMVNN.cjs} +107 -7
- package/dist/chunk-OOTLMVNN.cjs.map +1 -0
- package/dist/{chunk-D4M6E4OQ.cjs → chunk-OWZ6QT24.cjs} +16 -8
- package/dist/chunk-OWZ6QT24.cjs.map +1 -0
- package/dist/{chunk-6OHS6ZQ3.js → chunk-PDJCIONR.js} +8 -8
- package/dist/{chunk-6OHS6ZQ3.js.map → chunk-PDJCIONR.js.map} +1 -1
- package/dist/{chunk-WU2P7XOU.cjs → chunk-PP4G2TZZ.cjs} +20 -20
- package/dist/{chunk-WU2P7XOU.cjs.map → chunk-PP4G2TZZ.cjs.map} +1 -1
- package/dist/{chunk-VWAK25TU.js → chunk-SBBWRNZA.js} +10 -7
- package/dist/chunk-SBBWRNZA.js.map +1 -0
- package/dist/{chunk-TU4YMXOQ.js → chunk-TJIFNVPX.js} +6 -6
- package/dist/{chunk-TU4YMXOQ.js.map → chunk-TJIFNVPX.js.map} +1 -1
- package/dist/{chunk-V5YNS2QO.cjs → chunk-XJNQHPBJ.cjs} +15 -15
- package/dist/{chunk-V5YNS2QO.cjs.map → chunk-XJNQHPBJ.cjs.map} +1 -1
- package/dist/{chunk-MVYP55NA.js → chunk-YC6Z75K2.js} +113 -336
- package/dist/chunk-YC6Z75K2.js.map +1 -0
- package/dist/{chunk-3ZF7IC6Q.cjs → chunk-YZMSJKAK.cjs} +5 -3
- package/dist/chunk-YZMSJKAK.cjs.map +1 -0
- package/dist/{chunk-L3WDI7HP.cjs → chunk-Z2X5VTYJ.cjs} +65 -65
- package/dist/{chunk-L3WDI7HP.cjs.map → chunk-Z2X5VTYJ.cjs.map} +1 -1
- package/dist/{chunk-BN5MV2QK.cjs → chunk-Z52OAJ73.cjs} +4 -4
- package/dist/{chunk-BN5MV2QK.cjs.map → chunk-Z52OAJ73.cjs.map} +1 -1
- package/dist/{chunk-WYPSC6CO.js → chunk-ZBU6P4JV.js} +104 -4
- package/dist/chunk-ZBU6P4JV.js.map +1 -0
- package/dist/datasets/experiment/index.d.ts.map +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/di/index.cjs +4 -4
- package/dist/di/index.js +1 -1
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +443 -384
- package/dist/docs/references/docs-agents-agent-approval.md +61 -31
- package/dist/docs/references/docs-agents-supervisor-agents.md +1 -1
- package/dist/docs/references/docs-memory-observational-memory.md +9 -0
- package/dist/docs/references/docs-memory-semantic-recall.md +17 -1
- package/dist/docs/references/docs-workspace-skills.md +7 -5
- package/dist/docs/references/reference-agents-agent.md +20 -20
- package/dist/docs/references/reference-agents-generate.md +200 -66
- package/dist/docs/references/reference-agents-generateLegacy.md +77 -35
- package/dist/docs/references/reference-agents-getDefaultGenerateOptions.md +4 -6
- package/dist/docs/references/reference-agents-getDefaultOptions.md +4 -6
- package/dist/docs/references/reference-agents-getDefaultStreamOptions.md +4 -6
- package/dist/docs/references/reference-agents-getDescription.md +1 -1
- package/dist/docs/references/reference-agents-getInstructions.md +4 -6
- package/dist/docs/references/reference-agents-getLLM.md +6 -8
- package/dist/docs/references/reference-agents-getMemory.md +4 -6
- package/dist/docs/references/reference-agents-getModel.md +4 -6
- package/dist/docs/references/reference-agents-getTools.md +5 -7
- package/dist/docs/references/reference-agents-getVoice.md +4 -6
- package/dist/docs/references/reference-agents-listAgents.md +4 -6
- package/dist/docs/references/reference-agents-listScorers.md +4 -6
- package/dist/docs/references/reference-agents-listTools.md +4 -6
- package/dist/docs/references/reference-agents-listWorkflows.md +4 -6
- package/dist/docs/references/reference-agents-network.md +69 -23
- package/dist/docs/references/reference-ai-sdk-chat-route.md +7 -7
- package/dist/docs/references/reference-ai-sdk-network-route.md +3 -3
- package/dist/docs/references/reference-ai-sdk-to-ai-sdk-stream.md +9 -9
- package/dist/docs/references/reference-ai-sdk-with-mastra.md +12 -12
- package/dist/docs/references/reference-ai-sdk-workflow-route.md +3 -3
- package/dist/docs/references/reference-auth-auth0.md +6 -6
- package/dist/docs/references/reference-auth-clerk.md +5 -5
- package/dist/docs/references/reference-auth-firebase.md +7 -7
- package/dist/docs/references/reference-auth-jwt.md +1 -1
- package/dist/docs/references/reference-auth-supabase.md +4 -4
- package/dist/docs/references/reference-auth-workos.md +6 -6
- package/dist/docs/references/reference-core-addGateway.md +2 -2
- package/dist/docs/references/reference-core-getAgent.md +2 -2
- package/dist/docs/references/reference-core-getAgentById.md +2 -2
- package/dist/docs/references/reference-core-getDeployer.md +1 -1
- package/dist/docs/references/reference-core-getGateway.md +2 -2
- package/dist/docs/references/reference-core-getGatewayById.md +2 -2
- package/dist/docs/references/reference-core-getLogger.md +1 -1
- package/dist/docs/references/reference-core-getMCPServer.md +2 -2
- package/dist/docs/references/reference-core-getMCPServerById.md +3 -3
- package/dist/docs/references/reference-core-getMemory.md +2 -2
- package/dist/docs/references/reference-core-getScorer.md +2 -2
- package/dist/docs/references/reference-core-getScorerById.md +2 -2
- package/dist/docs/references/reference-core-getServer.md +1 -1
- package/dist/docs/references/reference-core-getStorage.md +1 -1
- package/dist/docs/references/reference-core-getStoredAgentById.md +18 -20
- package/dist/docs/references/reference-core-getTelemetry.md +1 -1
- package/dist/docs/references/reference-core-getVector.md +2 -2
- package/dist/docs/references/reference-core-getWorkflow.md +3 -3
- package/dist/docs/references/reference-core-listAgents.md +1 -1
- package/dist/docs/references/reference-core-listGateways.md +1 -1
- package/dist/docs/references/reference-core-listLogs.md +9 -11
- package/dist/docs/references/reference-core-listLogsByRunId.md +9 -9
- package/dist/docs/references/reference-core-listMCPServers.md +1 -1
- package/dist/docs/references/reference-core-listMemory.md +1 -1
- package/dist/docs/references/reference-core-listScorers.md +1 -1
- package/dist/docs/references/reference-core-listStoredAgents.md +9 -11
- package/dist/docs/references/reference-core-listVectors.md +1 -1
- package/dist/docs/references/reference-core-listWorkflows.md +2 -2
- package/dist/docs/references/reference-core-mastra-class.md +17 -17
- package/dist/docs/references/reference-core-mastra-model-gateway.md +15 -15
- package/dist/docs/references/reference-core-setLogger.md +2 -4
- package/dist/docs/references/reference-core-setStorage.md +1 -1
- package/dist/docs/references/reference-datasets-addItem.md +20 -4
- package/dist/docs/references/reference-datasets-addItems.md +8 -2
- package/dist/docs/references/reference-datasets-compareExperiments.md +15 -3
- package/dist/docs/references/reference-datasets-create.md +6 -6
- package/dist/docs/references/reference-datasets-dataset.md +1 -1
- package/dist/docs/references/reference-datasets-delete.md +2 -2
- package/dist/docs/references/reference-datasets-deleteExperiment.md +2 -2
- package/dist/docs/references/reference-datasets-deleteItem.md +2 -2
- package/dist/docs/references/reference-datasets-deleteItems.md +2 -2
- package/dist/docs/references/reference-datasets-get.md +2 -2
- package/dist/docs/references/reference-datasets-getDetails.md +9 -9
- package/dist/docs/references/reference-datasets-getExperiment.md +2 -2
- package/dist/docs/references/reference-datasets-getItem.md +3 -3
- package/dist/docs/references/reference-datasets-getItemHistory.md +22 -2
- package/dist/docs/references/reference-datasets-list.md +7 -3
- package/dist/docs/references/reference-datasets-listExperimentResults.md +34 -4
- package/dist/docs/references/reference-datasets-listExperiments.md +41 -3
- package/dist/docs/references/reference-datasets-listItems.md +18 -6
- package/dist/docs/references/reference-datasets-listVersions.md +23 -3
- package/dist/docs/references/reference-datasets-startExperiment.md +62 -12
- package/dist/docs/references/reference-datasets-startExperimentAsync.md +5 -1
- package/dist/docs/references/reference-datasets-update.md +6 -6
- package/dist/docs/references/reference-datasets-updateItem.md +5 -5
- package/dist/docs/references/reference-evals-answer-relevancy.md +11 -11
- package/dist/docs/references/reference-evals-answer-similarity.md +17 -19
- package/dist/docs/references/reference-evals-bias.md +10 -10
- package/dist/docs/references/reference-evals-completeness.md +3 -3
- package/dist/docs/references/reference-evals-content-similarity.md +6 -6
- package/dist/docs/references/reference-evals-context-precision.md +4 -4
- package/dist/docs/references/reference-evals-create-scorer.md +47 -49
- package/dist/docs/references/reference-evals-faithfulness.md +11 -11
- package/dist/docs/references/reference-evals-hallucination.md +17 -21
- package/dist/docs/references/reference-evals-keyword-coverage.md +4 -4
- package/dist/docs/references/reference-evals-mastra-scorer.md +14 -14
- package/dist/docs/references/reference-evals-run-evals.md +16 -16
- package/dist/docs/references/reference-evals-scorer-utils.md +3 -3
- package/dist/docs/references/reference-evals-textual-difference.md +3 -3
- package/dist/docs/references/reference-evals-tone-consistency.md +3 -3
- package/dist/docs/references/reference-evals-toxicity.md +8 -8
- package/dist/docs/references/reference-harness-harness-class.md +34 -42
- package/dist/docs/references/reference-logging-pino-logger.md +5 -5
- package/dist/docs/references/reference-memory-deleteMessages.md +2 -2
- package/dist/docs/references/reference-memory-memory-class.md +12 -14
- package/dist/docs/references/reference-memory-observational-memory.md +102 -94
- package/dist/docs/references/reference-observability-tracing-configuration.md +27 -10
- package/dist/docs/references/reference-observability-tracing-exporters-console-exporter.md +4 -7
- package/dist/docs/references/reference-processors-batch-parts-processor.md +8 -10
- package/dist/docs/references/reference-processors-language-detector.md +14 -16
- package/dist/docs/references/reference-processors-message-history-processor.md +7 -9
- package/dist/docs/references/reference-processors-moderation-processor.md +13 -15
- package/dist/docs/references/reference-processors-pii-detector.md +14 -16
- package/dist/docs/references/reference-processors-processor-interface.md +62 -62
- package/dist/docs/references/reference-processors-prompt-injection-detector.md +11 -13
- package/dist/docs/references/reference-processors-semantic-recall-processor.md +14 -16
- package/dist/docs/references/reference-processors-system-prompt-scrubber.md +12 -14
- package/dist/docs/references/reference-processors-token-limiter-processor.md +11 -13
- package/dist/docs/references/reference-processors-tool-call-filter.md +5 -7
- package/dist/docs/references/reference-processors-tool-search-processor.md +9 -11
- package/dist/docs/references/reference-processors-unicode-normalizer.md +8 -10
- package/dist/docs/references/reference-processors-working-memory-processor.md +14 -18
- package/dist/docs/references/reference-rag-database-config.md +11 -7
- package/dist/docs/references/reference-rag-embeddings.md +12 -12
- package/dist/docs/references/reference-server-mastra-server.md +10 -10
- package/dist/docs/references/reference-server-register-api-route.md +13 -13
- package/dist/docs/references/reference-storage-cloudflare-d1.md +5 -5
- package/dist/docs/references/reference-storage-composite.md +9 -9
- package/dist/docs/references/reference-storage-lance.md +3 -3
- package/dist/docs/references/reference-storage-libsql.md +2 -2
- package/dist/docs/references/reference-storage-mongodb.md +5 -5
- package/dist/docs/references/reference-storage-mssql.md +2 -2
- package/dist/docs/references/reference-storage-postgresql.md +25 -25
- package/dist/docs/references/reference-storage-upstash.md +3 -3
- package/dist/docs/references/reference-streaming-ChunkType.md +251 -59
- package/dist/docs/references/reference-streaming-agents-MastraModelOutput.md +86 -16
- package/dist/docs/references/reference-streaming-agents-streamLegacy.md +79 -39
- package/dist/docs/references/reference-streaming-workflows-resumeStream.md +18 -8
- package/dist/docs/references/reference-streaming-workflows-stream.md +21 -9
- package/dist/docs/references/reference-streaming-workflows-timeTravelStream.md +4 -4
- package/dist/docs/references/reference-tools-create-tool.md +25 -21
- package/dist/docs/references/reference-tools-graph-rag-tool.md +16 -18
- package/dist/docs/references/reference-tools-mcp-client.md +38 -27
- package/dist/docs/references/reference-tools-mcp-server.md +45 -45
- package/dist/docs/references/reference-tools-vector-query-tool.md +34 -22
- package/dist/docs/references/reference-vectors-libsql.md +31 -31
- package/dist/docs/references/reference-vectors-mongodb.md +32 -32
- package/dist/docs/references/reference-vectors-pg.md +60 -44
- package/dist/docs/references/reference-vectors-upstash.md +25 -25
- package/dist/docs/references/reference-voice-composite-voice.md +10 -10
- package/dist/docs/references/reference-voice-mastra-voice.md +20 -20
- package/dist/docs/references/reference-voice-voice.addInstructions.md +1 -1
- package/dist/docs/references/reference-voice-voice.addTools.md +1 -1
- package/dist/docs/references/reference-voice-voice.connect.md +3 -3
- package/dist/docs/references/reference-voice-voice.events.md +11 -11
- package/dist/docs/references/reference-voice-voice.listen.md +9 -9
- package/dist/docs/references/reference-voice-voice.on.md +2 -2
- package/dist/docs/references/reference-voice-voice.speak.md +11 -11
- package/dist/docs/references/reference-workflows-run-methods-cancel.md +2 -2
- package/dist/docs/references/reference-workflows-run-methods-restart.md +17 -5
- package/dist/docs/references/reference-workflows-run-methods-resume.md +23 -9
- package/dist/docs/references/reference-workflows-run-methods-start.md +22 -8
- package/dist/docs/references/reference-workflows-run-methods-startAsync.md +12 -6
- package/dist/docs/references/reference-workflows-run-methods-timeTravel.md +29 -13
- package/dist/docs/references/reference-workflows-run.md +12 -12
- package/dist/docs/references/reference-workflows-step.md +24 -26
- package/dist/docs/references/reference-workflows-workflow-methods-branch.md +2 -2
- package/dist/docs/references/reference-workflows-workflow-methods-commit.md +1 -1
- package/dist/docs/references/reference-workflows-workflow-methods-create-run.md +4 -4
- package/dist/docs/references/reference-workflows-workflow-methods-dountil.md +3 -3
- package/dist/docs/references/reference-workflows-workflow-methods-dowhile.md +3 -3
- package/dist/docs/references/reference-workflows-workflow-methods-foreach.md +9 -9
- package/dist/docs/references/reference-workflows-workflow-methods-map.md +2 -2
- package/dist/docs/references/reference-workflows-workflow-methods-parallel.md +2 -2
- package/dist/docs/references/reference-workflows-workflow-methods-sleep.md +2 -2
- package/dist/docs/references/reference-workflows-workflow-methods-sleepUntil.md +2 -2
- package/dist/docs/references/reference-workflows-workflow-methods-then.md +2 -2
- package/dist/docs/references/reference-workflows-workflow.md +40 -50
- package/dist/docs/references/reference-workspace-filesystem.md +22 -22
- package/dist/docs/references/reference-workspace-local-filesystem.md +35 -35
- package/dist/docs/references/reference-workspace-local-sandbox.md +26 -26
- package/dist/docs/references/reference-workspace-sandbox.md +8 -8
- package/dist/docs/references/reference-workspace-workspace-class.md +30 -34
- package/dist/editor/types.d.ts +1 -0
- package/dist/editor/types.d.ts.map +1 -1
- package/dist/evals/index.cjs +20 -20
- package/dist/evals/index.js +3 -3
- package/dist/evals/scoreTraces/index.cjs +5 -5
- package/dist/evals/scoreTraces/index.js +2 -2
- package/dist/harness/harness.d.ts.map +1 -1
- package/dist/harness/index.cjs +25 -21
- package/dist/harness/index.cjs.map +1 -1
- package/dist/harness/index.js +15 -11
- 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 +12 -12
- package/dist/llm/index.js +3 -3
- package/dist/llm/model/model.d.ts.map +1 -1
- package/dist/llm/model/model.loop.d.ts.map +1 -1
- package/dist/llm/model/provider-types.generated.d.ts +5 -1
- package/dist/loop/index.cjs +14 -14
- package/dist/loop/index.js +1 -1
- package/dist/loop/workflows/agentic-loop/index.d.ts.map +1 -1
- package/dist/mastra/index.cjs +2 -2
- package/dist/mastra/index.js +1 -1
- package/dist/memory/index.cjs +14 -14
- package/dist/memory/index.js +1 -1
- package/dist/models-dev-2FJK72J2.cjs +12 -0
- package/dist/{models-dev-UVWCKPA2.cjs.map → models-dev-2FJK72J2.cjs.map} +1 -1
- package/dist/models-dev-CMQG6EMO.js +3 -0
- package/dist/{models-dev-W3LXZTEB.js.map → models-dev-CMQG6EMO.js.map} +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 +9 -42
- package/dist/processors/processors/skills.d.ts.map +1 -1
- package/dist/provider-registry-EHOAWHFE.cjs +40 -0
- package/dist/{provider-registry-4HLP2JRR.cjs.map → provider-registry-EHOAWHFE.cjs.map} +1 -1
- package/dist/provider-registry-LVP6T63V.js +3 -0
- package/dist/{provider-registry-K3DWQSMH.js.map → provider-registry-LVP6T63V.js.map} +1 -1
- package/dist/provider-registry.json +12 -4
- package/dist/relevance/index.cjs +3 -3
- package/dist/relevance/index.js +1 -1
- package/dist/request-context/index.cjs +4 -4
- package/dist/request-context/index.d.ts.map +1 -1
- package/dist/request-context/index.js +1 -1
- package/dist/storage/base.d.ts +34 -1
- package/dist/storage/base.d.ts.map +1 -1
- package/dist/storage/constants.cjs +56 -56
- package/dist/storage/constants.js +1 -1
- package/dist/storage/domains/agents/filesystem.d.ts +28 -0
- package/dist/storage/domains/agents/filesystem.d.ts.map +1 -0
- package/dist/storage/domains/agents/index.d.ts +1 -0
- package/dist/storage/domains/agents/index.d.ts.map +1 -1
- package/dist/storage/domains/experiments/inmemory.d.ts.map +1 -1
- package/dist/storage/domains/mcp-clients/filesystem.d.ts +28 -0
- package/dist/storage/domains/mcp-clients/filesystem.d.ts.map +1 -0
- package/dist/storage/domains/mcp-clients/index.d.ts +1 -0
- package/dist/storage/domains/mcp-clients/index.d.ts.map +1 -1
- package/dist/storage/domains/mcp-servers/filesystem.d.ts +28 -0
- package/dist/storage/domains/mcp-servers/filesystem.d.ts.map +1 -0
- package/dist/storage/domains/mcp-servers/index.d.ts +1 -0
- package/dist/storage/domains/mcp-servers/index.d.ts.map +1 -1
- package/dist/storage/domains/prompt-blocks/filesystem.d.ts +28 -0
- package/dist/storage/domains/prompt-blocks/filesystem.d.ts.map +1 -0
- package/dist/storage/domains/prompt-blocks/index.d.ts +1 -0
- package/dist/storage/domains/prompt-blocks/index.d.ts.map +1 -1
- package/dist/storage/domains/scorer-definitions/filesystem.d.ts +28 -0
- package/dist/storage/domains/scorer-definitions/filesystem.d.ts.map +1 -0
- package/dist/storage/domains/scorer-definitions/index.d.ts +1 -0
- package/dist/storage/domains/scorer-definitions/index.d.ts.map +1 -1
- package/dist/storage/domains/skills/filesystem.d.ts +28 -0
- package/dist/storage/domains/skills/filesystem.d.ts.map +1 -0
- package/dist/storage/domains/skills/index.d.ts +1 -0
- package/dist/storage/domains/skills/index.d.ts.map +1 -1
- package/dist/storage/domains/workspaces/filesystem.d.ts +28 -0
- package/dist/storage/domains/workspaces/filesystem.d.ts.map +1 -0
- package/dist/storage/domains/workspaces/index.d.ts +1 -0
- package/dist/storage/domains/workspaces/index.d.ts.map +1 -1
- package/dist/storage/filesystem-db.d.ts +82 -0
- package/dist/storage/filesystem-db.d.ts.map +1 -0
- package/dist/storage/filesystem-versioned.d.ts +148 -0
- package/dist/storage/filesystem-versioned.d.ts.map +1 -0
- package/dist/storage/filesystem.d.ts +39 -0
- package/dist/storage/filesystem.d.ts.map +1 -0
- package/dist/storage/git-history.d.ts +68 -0
- package/dist/storage/git-history.d.ts.map +1 -0
- package/dist/storage/index.cjs +208 -160
- package/dist/storage/index.d.ts +4 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +2 -2
- package/dist/storage/types.d.ts +1 -0
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/stream/RunOutput.d.ts +1 -1
- package/dist/stream/aisdk/v5/output-helpers.d.ts +6 -6
- package/dist/stream/base/output.d.ts +3 -3
- package/dist/stream/base/schema.d.ts +1 -1
- package/dist/stream/index.cjs +11 -11
- package/dist/stream/index.js +2 -2
- 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 +6 -6
- 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/tool-builder/builder.d.ts.map +1 -1
- package/dist/tools/tool.d.ts +6 -0
- package/dist/tools/tool.d.ts.map +1 -1
- package/dist/tools/types.d.ts +27 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/utils.cjs +23 -23
- package/dist/utils.js +1 -1
- package/dist/vector/index.cjs +9 -9
- package/dist/vector/index.js +2 -2
- 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/workspace/index.cjs +70 -66
- package/dist/workspace/index.d.ts +1 -0
- package/dist/workspace/index.d.ts.map +1 -1
- package/dist/workspace/index.js +1 -1
- package/dist/workspace/sandbox/execa.d.ts +9 -0
- package/dist/workspace/sandbox/execa.d.ts.map +1 -0
- package/dist/workspace/sandbox/local-process-manager.d.ts.map +1 -1
- package/dist/workspace/skills/index.d.ts +1 -0
- package/dist/workspace/skills/index.d.ts.map +1 -1
- package/dist/workspace/skills/tools.d.ts +36 -0
- package/dist/workspace/skills/tools.d.ts.map +1 -0
- package/dist/workspace/tools/execute-command.d.ts.map +1 -1
- package/dist/workspace/tools/output-helpers.d.ts +4 -3
- package/dist/workspace/tools/output-helpers.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/llm/model/provider-types.generated.d.ts +5 -1
- package/dist/chunk-3ZF7IC6Q.cjs.map +0 -1
- package/dist/chunk-4BXXAZ75.js.map +0 -1
- package/dist/chunk-4P35AVPE.cjs.map +0 -1
- package/dist/chunk-BFV3GSGS.js.map +0 -1
- package/dist/chunk-CCLV5CAA.js.map +0 -1
- package/dist/chunk-D4M6E4OQ.cjs.map +0 -1
- package/dist/chunk-D6HO5QAM.cjs.map +0 -1
- package/dist/chunk-G5R2755Q.cjs.map +0 -1
- package/dist/chunk-GJTLWOKJ.js.map +0 -1
- package/dist/chunk-H5S4PS44.cjs.map +0 -1
- package/dist/chunk-IOY7Y5GV.js.map +0 -1
- package/dist/chunk-JIRB5LX4.js.map +0 -1
- package/dist/chunk-MVYP55NA.js.map +0 -1
- package/dist/chunk-PKORY4ZZ.cjs.map +0 -1
- package/dist/chunk-QNXY3J6B.cjs.map +0 -1
- package/dist/chunk-SEKQJ447.js.map +0 -1
- package/dist/chunk-VDKWYUGC.cjs.map +0 -1
- package/dist/chunk-VWAK25TU.js.map +0 -1
- package/dist/chunk-WYPSC6CO.js.map +0 -1
- package/dist/chunk-YIJZBU54.cjs.map +0 -1
- package/dist/chunk-ZBESCKPX.cjs.map +0 -1
- package/dist/chunk-ZVWVQ6MG.js.map +0 -1
- package/dist/models-dev-UVWCKPA2.cjs +0 -12
- package/dist/models-dev-W3LXZTEB.js +0 -3
- package/dist/provider-registry-4HLP2JRR.cjs +0 -40
- package/dist/provider-registry-K3DWQSMH.js +0 -3
|
@@ -1,15 +1,27 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
3
|
+
var chunkYZMSJKAK_cjs = require('./chunk-YZMSJKAK.cjs');
|
|
4
|
+
var chunkHH76UOJL_cjs = require('./chunk-HH76UOJL.cjs');
|
|
5
|
+
var chunkGCRPNAAR_cjs = require('./chunk-GCRPNAAR.cjs');
|
|
6
6
|
var chunk4U7ZLI36_cjs = require('./chunk-4U7ZLI36.cjs');
|
|
7
7
|
var chunkRO47SMI7_cjs = require('./chunk-RO47SMI7.cjs');
|
|
8
8
|
var jsonToZod = require('@mastra/schema-compat/json-to-zod');
|
|
9
9
|
var zod = require('zod');
|
|
10
10
|
var crypto$1 = require('crypto');
|
|
11
|
+
var path = require('path');
|
|
12
|
+
var child_process = require('child_process');
|
|
13
|
+
var fs = require('fs');
|
|
11
14
|
|
|
12
15
|
// src/storage/base.ts
|
|
16
|
+
var EDITOR_DOMAINS = [
|
|
17
|
+
"agents",
|
|
18
|
+
"promptBlocks",
|
|
19
|
+
"scorerDefinitions",
|
|
20
|
+
"mcpClients",
|
|
21
|
+
"mcpServers",
|
|
22
|
+
"workspaces",
|
|
23
|
+
"skills"
|
|
24
|
+
];
|
|
13
25
|
function normalizePerPage(perPageInput, defaultValue) {
|
|
14
26
|
if (perPageInput === false) {
|
|
15
27
|
return Number.MAX_SAFE_INTEGER;
|
|
@@ -48,30 +60,39 @@ var MastraCompositeStore = class extends chunkRO47SMI7_cjs.MastraBase {
|
|
|
48
60
|
});
|
|
49
61
|
this.id = config.id;
|
|
50
62
|
this.disableInit = config.disableInit ?? false;
|
|
51
|
-
if (config.default || config.domains) {
|
|
63
|
+
if (config.default || config.editor || config.domains) {
|
|
52
64
|
const defaultStores = config.default?.stores;
|
|
65
|
+
const editorStores = config.editor?.stores;
|
|
53
66
|
const domainOverrides = config.domains ?? {};
|
|
54
67
|
const hasDefaultDomains = defaultStores && Object.values(defaultStores).some((v) => v !== void 0);
|
|
68
|
+
const hasEditorDomains = editorStores && Object.values(editorStores).some((v) => v !== void 0);
|
|
55
69
|
const hasOverrideDomains = Object.values(domainOverrides).some((v) => v !== void 0);
|
|
56
|
-
if (!hasDefaultDomains && !hasOverrideDomains) {
|
|
70
|
+
if (!hasDefaultDomains && !hasEditorDomains && !hasOverrideDomains) {
|
|
57
71
|
throw new Error(
|
|
58
|
-
"MastraCompositeStore requires at least one storage source. Provide
|
|
72
|
+
"MastraCompositeStore requires at least one storage source. Provide a default storage, an editor storage, or domain overrides."
|
|
59
73
|
);
|
|
60
74
|
}
|
|
75
|
+
const editorDomainSet = new Set(EDITOR_DOMAINS);
|
|
76
|
+
const resolve3 = (key) => {
|
|
77
|
+
if (domainOverrides[key] !== void 0) return domainOverrides[key];
|
|
78
|
+
if (editorDomainSet.has(key) && editorStores?.[key] !== void 0) return editorStores[key];
|
|
79
|
+
return defaultStores?.[key];
|
|
80
|
+
};
|
|
61
81
|
this.stores = {
|
|
62
|
-
memory:
|
|
63
|
-
workflows:
|
|
64
|
-
scores:
|
|
65
|
-
observability:
|
|
66
|
-
agents:
|
|
67
|
-
datasets:
|
|
68
|
-
experiments:
|
|
69
|
-
promptBlocks:
|
|
70
|
-
scorerDefinitions:
|
|
71
|
-
mcpClients:
|
|
72
|
-
mcpServers:
|
|
73
|
-
workspaces:
|
|
74
|
-
skills:
|
|
82
|
+
memory: resolve3("memory"),
|
|
83
|
+
workflows: resolve3("workflows"),
|
|
84
|
+
scores: resolve3("scores"),
|
|
85
|
+
observability: resolve3("observability"),
|
|
86
|
+
agents: resolve3("agents"),
|
|
87
|
+
datasets: resolve3("datasets"),
|
|
88
|
+
experiments: resolve3("experiments"),
|
|
89
|
+
promptBlocks: resolve3("promptBlocks"),
|
|
90
|
+
scorerDefinitions: resolve3("scorerDefinitions"),
|
|
91
|
+
mcpClients: resolve3("mcpClients"),
|
|
92
|
+
mcpServers: resolve3("mcpServers"),
|
|
93
|
+
workspaces: resolve3("workspaces"),
|
|
94
|
+
skills: resolve3("skills"),
|
|
95
|
+
blobs: resolve3("blobs")
|
|
75
96
|
};
|
|
76
97
|
}
|
|
77
98
|
}
|
|
@@ -384,7 +405,7 @@ var InMemoryAgentsStorage = class extends AgentsStorage {
|
|
|
384
405
|
if (metadata && Object.keys(metadata).length > 0) {
|
|
385
406
|
agents = agents.filter((agent) => {
|
|
386
407
|
if (!agent.metadata) return false;
|
|
387
|
-
return Object.entries(metadata).every(([key, value]) =>
|
|
408
|
+
return Object.entries(metadata).every(([key, value]) => chunkGCRPNAAR_cjs.deepEqual(agent.metadata[key], value));
|
|
388
409
|
});
|
|
389
410
|
}
|
|
390
411
|
const sortedAgents = this.sortAgents(agents, field, direction);
|
|
@@ -1240,6 +1261,7 @@ var ExperimentsInMemory = class extends ExperimentsStorage {
|
|
|
1240
1261
|
const updated = {
|
|
1241
1262
|
...existing,
|
|
1242
1263
|
status: input.status ?? existing.status,
|
|
1264
|
+
totalItems: input.totalItems ?? existing.totalItems,
|
|
1243
1265
|
succeededCount: input.succeededCount ?? existing.succeededCount,
|
|
1244
1266
|
failedCount: input.failedCount ?? existing.failedCount,
|
|
1245
1267
|
skippedCount: input.skippedCount ?? existing.skippedCount,
|
|
@@ -1514,7 +1536,7 @@ var InMemoryMCPClientsStorage = class extends MCPClientsStorage {
|
|
|
1514
1536
|
if (metadata && Object.keys(metadata).length > 0) {
|
|
1515
1537
|
configs = configs.filter((config) => {
|
|
1516
1538
|
if (!config.metadata) return false;
|
|
1517
|
-
return Object.entries(metadata).every(([key, value]) =>
|
|
1539
|
+
return Object.entries(metadata).every(([key, value]) => chunkGCRPNAAR_cjs.deepEqual(config.metadata[key], value));
|
|
1518
1540
|
});
|
|
1519
1541
|
}
|
|
1520
1542
|
const sortedConfigs = this.sortConfigs(configs, field, direction);
|
|
@@ -1782,7 +1804,7 @@ var InMemoryMCPServersStorage = class extends MCPServersStorage {
|
|
|
1782
1804
|
if (metadata && Object.keys(metadata).length > 0) {
|
|
1783
1805
|
configs = configs.filter((config) => {
|
|
1784
1806
|
if (!config.metadata) return false;
|
|
1785
|
-
return Object.entries(metadata).every(([key, value]) =>
|
|
1807
|
+
return Object.entries(metadata).every(([key, value]) => chunkGCRPNAAR_cjs.deepEqual(config.metadata[key], value));
|
|
1786
1808
|
});
|
|
1787
1809
|
}
|
|
1788
1810
|
const sortedConfigs = this.sortConfigs(configs, field, direction);
|
|
@@ -1953,7 +1975,7 @@ function safelyParseJSON(input) {
|
|
|
1953
1975
|
}
|
|
1954
1976
|
function transformRow(row, tableName, options = {}) {
|
|
1955
1977
|
const { preferredTimestampFields = {}, convertTimestamps = false, nullValuePattern, fieldMappings = {} } = options;
|
|
1956
|
-
const tableSchema =
|
|
1978
|
+
const tableSchema = chunkHH76UOJL_cjs.TABLE_SCHEMAS[tableName];
|
|
1957
1979
|
const result = {};
|
|
1958
1980
|
for (const [key, columnSchema] of Object.entries(tableSchema)) {
|
|
1959
1981
|
const sourceKey = fieldMappings[key] ?? key;
|
|
@@ -1984,7 +2006,7 @@ function transformRow(row, tableName, options = {}) {
|
|
|
1984
2006
|
return result;
|
|
1985
2007
|
}
|
|
1986
2008
|
function transformScoreRow(row, options = {}) {
|
|
1987
|
-
return transformRow(row,
|
|
2009
|
+
return transformRow(row, chunkHH76UOJL_cjs.TABLE_SCORERS, options);
|
|
1988
2010
|
}
|
|
1989
2011
|
function toUpperSnakeCase(str) {
|
|
1990
2012
|
return str.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/([A-Z])([A-Z][a-z])/g, "$1_$2").toUpperCase().replace(/[^A-Z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
@@ -2613,7 +2635,7 @@ var InMemoryMemory = class extends MemoryStorage {
|
|
|
2613
2635
|
});
|
|
2614
2636
|
const total = messages.length;
|
|
2615
2637
|
const paginatedMessages = messages.slice(offset, offset + perPage);
|
|
2616
|
-
const list = new
|
|
2638
|
+
const list = new chunkYZMSJKAK_cjs.MessageList().add(
|
|
2617
2639
|
paginatedMessages.map((m) => this.parseStoredMessage(m)),
|
|
2618
2640
|
"memory"
|
|
2619
2641
|
);
|
|
@@ -2647,7 +2669,7 @@ var InMemoryMemory = class extends MemoryStorage {
|
|
|
2647
2669
|
async listMessagesById({ messageIds }) {
|
|
2648
2670
|
this.logger.debug(`InMemoryMemory: listMessagesById called`);
|
|
2649
2671
|
const rawMessages = messageIds.map((id) => this.db.messages.get(id)).filter((message) => !!message);
|
|
2650
|
-
const list = new
|
|
2672
|
+
const list = new chunkYZMSJKAK_cjs.MessageList().add(
|
|
2651
2673
|
rawMessages.map((m) => this.parseStoredMessage(m)),
|
|
2652
2674
|
"memory"
|
|
2653
2675
|
);
|
|
@@ -2679,7 +2701,7 @@ var InMemoryMemory = class extends MemoryStorage {
|
|
|
2679
2701
|
};
|
|
2680
2702
|
this.db.messages.set(key, storageMessage);
|
|
2681
2703
|
}
|
|
2682
|
-
const list = new
|
|
2704
|
+
const list = new chunkYZMSJKAK_cjs.MessageList().add(messages, "memory");
|
|
2683
2705
|
return { messages: list.get.all.db() };
|
|
2684
2706
|
}
|
|
2685
2707
|
async updateMessages(args) {
|
|
@@ -3550,7 +3572,7 @@ var ObservabilityInMemory = class extends ObservabilityStorage {
|
|
|
3550
3572
|
};
|
|
3551
3573
|
}
|
|
3552
3574
|
async listTraces(args) {
|
|
3553
|
-
const { filters, pagination, orderBy } =
|
|
3575
|
+
const { filters, pagination, orderBy } = chunkHH76UOJL_cjs.listTracesArgsSchema.parse(args);
|
|
3554
3576
|
const matchingRootSpans = [];
|
|
3555
3577
|
for (const [, traceEntry] of this.db.traces) {
|
|
3556
3578
|
if (!traceEntry.rootSpan) continue;
|
|
@@ -3579,7 +3601,7 @@ var ObservabilityInMemory = class extends ObservabilityStorage {
|
|
|
3579
3601
|
const end = start + perPage;
|
|
3580
3602
|
const paged = matchingRootSpans.slice(start, end);
|
|
3581
3603
|
return {
|
|
3582
|
-
spans:
|
|
3604
|
+
spans: chunkHH76UOJL_cjs.toTraceSpans(paged),
|
|
3583
3605
|
pagination: { total, page, perPage, hasMore: end < total }
|
|
3584
3606
|
};
|
|
3585
3607
|
}
|
|
@@ -3845,7 +3867,7 @@ var InMemoryPromptBlocksStorage = class extends PromptBlocksStorage {
|
|
|
3845
3867
|
if (metadata && Object.keys(metadata).length > 0) {
|
|
3846
3868
|
blocks = blocks.filter((block) => {
|
|
3847
3869
|
if (!block.metadata) return false;
|
|
3848
|
-
return Object.entries(metadata).every(([key, value]) =>
|
|
3870
|
+
return Object.entries(metadata).every(([key, value]) => chunkGCRPNAAR_cjs.deepEqual(block.metadata[key], value));
|
|
3849
3871
|
});
|
|
3850
3872
|
}
|
|
3851
3873
|
const sortedBlocks = this.sortBlocks(blocks, field, direction);
|
|
@@ -4111,7 +4133,7 @@ var InMemoryScorerDefinitionsStorage = class extends ScorerDefinitionsStorage {
|
|
|
4111
4133
|
if (metadata && Object.keys(metadata).length > 0) {
|
|
4112
4134
|
scorers = scorers.filter((scorer) => {
|
|
4113
4135
|
if (!scorer.metadata) return false;
|
|
4114
|
-
return Object.entries(metadata).every(([key, value]) =>
|
|
4136
|
+
return Object.entries(metadata).every(([key, value]) => chunkGCRPNAAR_cjs.deepEqual(scorer.metadata[key], value));
|
|
4115
4137
|
});
|
|
4116
4138
|
}
|
|
4117
4139
|
const sortedScorers = this.sortScorers(scorers, field, direction);
|
|
@@ -5159,7 +5181,7 @@ var InMemoryWorkspacesStorage = class extends WorkspacesStorage {
|
|
|
5159
5181
|
if (metadata && Object.keys(metadata).length > 0) {
|
|
5160
5182
|
configs = configs.filter((config) => {
|
|
5161
5183
|
if (!config.metadata) return false;
|
|
5162
|
-
return Object.entries(metadata).every(([key, value]) =>
|
|
5184
|
+
return Object.entries(metadata).every(([key, value]) => chunkGCRPNAAR_cjs.deepEqual(config.metadata[key], value));
|
|
5163
5185
|
});
|
|
5164
5186
|
}
|
|
5165
5187
|
const sortedConfigs = this.sortConfigs(configs, field, direction);
|
|
@@ -5348,6 +5370,1508 @@ var InMemoryStore = class extends MastraCompositeStore {
|
|
|
5348
5370
|
}
|
|
5349
5371
|
};
|
|
5350
5372
|
var MockStore = InMemoryStore;
|
|
5373
|
+
var GitHistory = class {
|
|
5374
|
+
/** Cache: dir → repo root (string) or `false` if not a repo. */
|
|
5375
|
+
repoRootCache = /* @__PURE__ */ new Map();
|
|
5376
|
+
/** Cache: `dir:filename:limit` → ordered commits (newest first). */
|
|
5377
|
+
commitCache = /* @__PURE__ */ new Map();
|
|
5378
|
+
/** Cache: `dir:commitHash:filename` → parsed JSON. */
|
|
5379
|
+
snapshotCache = /* @__PURE__ */ new Map();
|
|
5380
|
+
// ===========================================================================
|
|
5381
|
+
// Public API
|
|
5382
|
+
// ===========================================================================
|
|
5383
|
+
/**
|
|
5384
|
+
* Returns `true` if `dir` is inside a Git repository.
|
|
5385
|
+
* Result is cached after the first call per directory.
|
|
5386
|
+
*/
|
|
5387
|
+
async isGitRepo(dir) {
|
|
5388
|
+
const cached = this.repoRootCache.get(dir);
|
|
5389
|
+
if (cached === false) return false;
|
|
5390
|
+
if (typeof cached === "string") return true;
|
|
5391
|
+
try {
|
|
5392
|
+
const root = (await this.exec(dir, ["rev-parse", "--show-toplevel"])).trim();
|
|
5393
|
+
this.repoRootCache.set(dir, root);
|
|
5394
|
+
return true;
|
|
5395
|
+
} catch {
|
|
5396
|
+
this.repoRootCache.set(dir, false);
|
|
5397
|
+
return false;
|
|
5398
|
+
}
|
|
5399
|
+
}
|
|
5400
|
+
/**
|
|
5401
|
+
* Get the list of commits that touched a specific file, newest first.
|
|
5402
|
+
* Returns an empty array if Git is unavailable or the file has no history.
|
|
5403
|
+
*
|
|
5404
|
+
* @param dir Absolute path to the storage directory
|
|
5405
|
+
* @param filename The JSON filename relative to `dir` (e.g., 'agents.json')
|
|
5406
|
+
* @param limit Maximum number of commits to retrieve
|
|
5407
|
+
*/
|
|
5408
|
+
async getFileHistory(dir, filename, limit = 50) {
|
|
5409
|
+
const cacheKey = `${dir}:${filename}:${limit}`;
|
|
5410
|
+
if (this.commitCache.has(cacheKey)) {
|
|
5411
|
+
return this.commitCache.get(cacheKey);
|
|
5412
|
+
}
|
|
5413
|
+
if (!await this.isGitRepo(dir)) {
|
|
5414
|
+
this.commitCache.set(cacheKey, []);
|
|
5415
|
+
return [];
|
|
5416
|
+
}
|
|
5417
|
+
try {
|
|
5418
|
+
const raw = await this.exec(dir, [
|
|
5419
|
+
"log",
|
|
5420
|
+
`--max-count=${limit}`,
|
|
5421
|
+
"--format=%H|%aI|%aN|%s",
|
|
5422
|
+
"--follow",
|
|
5423
|
+
"--",
|
|
5424
|
+
filename
|
|
5425
|
+
]);
|
|
5426
|
+
const commits = [];
|
|
5427
|
+
for (const line of raw.split("\n")) {
|
|
5428
|
+
const trimmed = line.trim();
|
|
5429
|
+
if (!trimmed) continue;
|
|
5430
|
+
const pipeIdx1 = trimmed.indexOf("|");
|
|
5431
|
+
const pipeIdx2 = trimmed.indexOf("|", pipeIdx1 + 1);
|
|
5432
|
+
const pipeIdx3 = trimmed.indexOf("|", pipeIdx2 + 1);
|
|
5433
|
+
if (pipeIdx1 === -1 || pipeIdx2 === -1 || pipeIdx3 === -1) continue;
|
|
5434
|
+
commits.push({
|
|
5435
|
+
hash: trimmed.slice(0, pipeIdx1),
|
|
5436
|
+
date: new Date(trimmed.slice(pipeIdx1 + 1, pipeIdx2)),
|
|
5437
|
+
author: trimmed.slice(pipeIdx2 + 1, pipeIdx3),
|
|
5438
|
+
message: trimmed.slice(pipeIdx3 + 1)
|
|
5439
|
+
});
|
|
5440
|
+
}
|
|
5441
|
+
this.commitCache.set(cacheKey, commits);
|
|
5442
|
+
return commits;
|
|
5443
|
+
} catch {
|
|
5444
|
+
this.commitCache.set(cacheKey, []);
|
|
5445
|
+
return [];
|
|
5446
|
+
}
|
|
5447
|
+
}
|
|
5448
|
+
/**
|
|
5449
|
+
* Read and parse a JSON file at a specific Git commit.
|
|
5450
|
+
* Returns the parsed entity map, or `null` if the file didn't exist at that commit.
|
|
5451
|
+
*
|
|
5452
|
+
* @param dir Absolute path to the storage directory
|
|
5453
|
+
* @param commitHash Full or abbreviated commit SHA
|
|
5454
|
+
* @param filename The JSON filename relative to `dir` (e.g., 'agents.json')
|
|
5455
|
+
*/
|
|
5456
|
+
async getFileAtCommit(dir, commitHash, filename) {
|
|
5457
|
+
const cacheKey = `${dir}:${commitHash}:${filename}`;
|
|
5458
|
+
if (this.snapshotCache.has(cacheKey)) {
|
|
5459
|
+
return this.snapshotCache.get(cacheKey);
|
|
5460
|
+
}
|
|
5461
|
+
if (!await this.isGitRepo(dir)) return null;
|
|
5462
|
+
try {
|
|
5463
|
+
const relPath = this.relativeToRepo(dir, filename);
|
|
5464
|
+
const raw = await this.exec(dir, ["show", `${commitHash}:${relPath}`]);
|
|
5465
|
+
const parsed = JSON.parse(raw);
|
|
5466
|
+
this.snapshotCache.set(cacheKey, parsed);
|
|
5467
|
+
return parsed;
|
|
5468
|
+
} catch {
|
|
5469
|
+
return null;
|
|
5470
|
+
}
|
|
5471
|
+
}
|
|
5472
|
+
/**
|
|
5473
|
+
* Invalidate all caches. Call after external operations that change Git state
|
|
5474
|
+
* (e.g., the user commits or pulls).
|
|
5475
|
+
*/
|
|
5476
|
+
invalidateCache() {
|
|
5477
|
+
this.repoRootCache.clear();
|
|
5478
|
+
this.commitCache.clear();
|
|
5479
|
+
this.snapshotCache.clear();
|
|
5480
|
+
}
|
|
5481
|
+
// ===========================================================================
|
|
5482
|
+
// Internals
|
|
5483
|
+
// ===========================================================================
|
|
5484
|
+
/**
|
|
5485
|
+
* Get the relative path from the Git repo root to a file in the storage directory.
|
|
5486
|
+
*/
|
|
5487
|
+
relativeToRepo(dir, filename) {
|
|
5488
|
+
const root = this.repoRootCache.get(dir);
|
|
5489
|
+
if (!root) {
|
|
5490
|
+
throw new Error(`Not a git repository: ${dir}`);
|
|
5491
|
+
}
|
|
5492
|
+
const realRoot = fs.realpathSync(root);
|
|
5493
|
+
const realDir = fs.realpathSync(dir);
|
|
5494
|
+
const relDir = path.relative(realRoot, realDir);
|
|
5495
|
+
return relDir ? `${relDir}/${filename}` : filename;
|
|
5496
|
+
}
|
|
5497
|
+
/**
|
|
5498
|
+
* Execute a git command and return stdout.
|
|
5499
|
+
*/
|
|
5500
|
+
exec(cwd, args) {
|
|
5501
|
+
return new Promise((resolve3, reject) => {
|
|
5502
|
+
child_process.execFile("git", args, { cwd, maxBuffer: 10 * 1024 * 1024 }, (error, stdout) => {
|
|
5503
|
+
if (error) reject(error);
|
|
5504
|
+
else resolve3(stdout);
|
|
5505
|
+
});
|
|
5506
|
+
});
|
|
5507
|
+
}
|
|
5508
|
+
};
|
|
5509
|
+
|
|
5510
|
+
// src/storage/filesystem-versioned.ts
|
|
5511
|
+
var GIT_VERSION_PREFIX = "git-";
|
|
5512
|
+
var FilesystemVersionedHelpers = class _FilesystemVersionedHelpers {
|
|
5513
|
+
db;
|
|
5514
|
+
entitiesFile;
|
|
5515
|
+
parentIdField;
|
|
5516
|
+
name;
|
|
5517
|
+
versionMetadataFields;
|
|
5518
|
+
gitHistoryLimit;
|
|
5519
|
+
/**
|
|
5520
|
+
* In-memory entity records (thin metadata), keyed by entity ID.
|
|
5521
|
+
*/
|
|
5522
|
+
entities = /* @__PURE__ */ new Map();
|
|
5523
|
+
/**
|
|
5524
|
+
* In-memory version records, keyed by version ID.
|
|
5525
|
+
* Includes both in-memory/hydrated versions and git-based versions (metadata only).
|
|
5526
|
+
*/
|
|
5527
|
+
versions = /* @__PURE__ */ new Map();
|
|
5528
|
+
/**
|
|
5529
|
+
* Whether we've loaded from disk yet.
|
|
5530
|
+
*/
|
|
5531
|
+
hydrated = false;
|
|
5532
|
+
/**
|
|
5533
|
+
* Git history utility instance (shared across all helpers).
|
|
5534
|
+
*/
|
|
5535
|
+
static gitHistory = new GitHistory();
|
|
5536
|
+
/**
|
|
5537
|
+
* Promise that resolves when git history has been loaded.
|
|
5538
|
+
* null means git history loading hasn't been triggered yet.
|
|
5539
|
+
*/
|
|
5540
|
+
gitHistoryPromise = null;
|
|
5541
|
+
/**
|
|
5542
|
+
* The highest version number from git history, per entity ID.
|
|
5543
|
+
* Used to assign version numbers to new in-memory versions that continue
|
|
5544
|
+
* after the git history.
|
|
5545
|
+
*/
|
|
5546
|
+
gitVersionCounts = /* @__PURE__ */ new Map();
|
|
5547
|
+
constructor(config) {
|
|
5548
|
+
this.db = config.db;
|
|
5549
|
+
this.entitiesFile = config.entitiesFile;
|
|
5550
|
+
this.parentIdField = config.parentIdField;
|
|
5551
|
+
this.name = config.name;
|
|
5552
|
+
this.versionMetadataFields = config.versionMetadataFields;
|
|
5553
|
+
this.gitHistoryLimit = config.gitHistoryLimit ?? 50;
|
|
5554
|
+
}
|
|
5555
|
+
/**
|
|
5556
|
+
* Check if a version ID represents a git-based version.
|
|
5557
|
+
*/
|
|
5558
|
+
static isGitVersion(id) {
|
|
5559
|
+
return id.startsWith(GIT_VERSION_PREFIX);
|
|
5560
|
+
}
|
|
5561
|
+
/**
|
|
5562
|
+
* Hydrate in-memory state from the on-disk JSON file.
|
|
5563
|
+
* For each entry on disk, creates an in-memory entity (status: 'published')
|
|
5564
|
+
* and a synthetic version with the snapshot config.
|
|
5565
|
+
*
|
|
5566
|
+
* Also kicks off async git history loading in the background.
|
|
5567
|
+
* Version numbers for hydrated entities are assigned as 1 initially,
|
|
5568
|
+
* but will be reassigned after git history loads.
|
|
5569
|
+
*/
|
|
5570
|
+
hydrate() {
|
|
5571
|
+
if (this.hydrated) return;
|
|
5572
|
+
this.hydrated = true;
|
|
5573
|
+
const diskData = this.db.readDomain(this.entitiesFile);
|
|
5574
|
+
for (const [entityId, snapshotConfig] of Object.entries(diskData)) {
|
|
5575
|
+
if (!snapshotConfig || typeof snapshotConfig !== "object") continue;
|
|
5576
|
+
const versionId = `hydrated-${entityId}-v1`;
|
|
5577
|
+
const now = /* @__PURE__ */ new Date();
|
|
5578
|
+
const entity = {
|
|
5579
|
+
id: entityId,
|
|
5580
|
+
status: "published",
|
|
5581
|
+
activeVersionId: versionId,
|
|
5582
|
+
createdAt: now,
|
|
5583
|
+
updatedAt: now
|
|
5584
|
+
};
|
|
5585
|
+
this.entities.set(entityId, entity);
|
|
5586
|
+
const version = {
|
|
5587
|
+
id: versionId,
|
|
5588
|
+
[this.parentIdField]: entityId,
|
|
5589
|
+
versionNumber: 1,
|
|
5590
|
+
...snapshotConfig,
|
|
5591
|
+
createdAt: now
|
|
5592
|
+
};
|
|
5593
|
+
this.versions.set(versionId, version);
|
|
5594
|
+
}
|
|
5595
|
+
this.gitHistoryPromise = this.loadGitHistory();
|
|
5596
|
+
}
|
|
5597
|
+
/**
|
|
5598
|
+
* Ensure git history has been loaded before proceeding.
|
|
5599
|
+
* Call this in version-related methods to ensure git versions are available.
|
|
5600
|
+
*/
|
|
5601
|
+
async ensureGitHistory() {
|
|
5602
|
+
this.hydrate();
|
|
5603
|
+
if (this.gitHistoryPromise) {
|
|
5604
|
+
await this.gitHistoryPromise;
|
|
5605
|
+
}
|
|
5606
|
+
}
|
|
5607
|
+
/**
|
|
5608
|
+
* Load git commit history for the domain's JSON file.
|
|
5609
|
+
* Creates read-only version records (metadata + snapshot config) for each
|
|
5610
|
+
* commit where an entity existed. Reassigns version numbers for
|
|
5611
|
+
* hydrated (current disk) versions to sit on top of git history.
|
|
5612
|
+
*/
|
|
5613
|
+
async loadGitHistory() {
|
|
5614
|
+
const git = _FilesystemVersionedHelpers.gitHistory;
|
|
5615
|
+
const dir = this.db.dir;
|
|
5616
|
+
const isRepo = await git.isGitRepo(dir);
|
|
5617
|
+
if (!isRepo) return;
|
|
5618
|
+
const commits = await git.getFileHistory(dir, this.entitiesFile, this.gitHistoryLimit);
|
|
5619
|
+
if (commits.length === 0) return;
|
|
5620
|
+
const orderedCommits = [...commits].reverse();
|
|
5621
|
+
const entityVersionCount = /* @__PURE__ */ new Map();
|
|
5622
|
+
const previousSnapshots = /* @__PURE__ */ new Map();
|
|
5623
|
+
for (let i = 0; i < orderedCommits.length; i++) {
|
|
5624
|
+
const commit = orderedCommits[i];
|
|
5625
|
+
const fileContent = await git.getFileAtCommit(
|
|
5626
|
+
dir,
|
|
5627
|
+
commit.hash,
|
|
5628
|
+
this.entitiesFile
|
|
5629
|
+
);
|
|
5630
|
+
if (!fileContent) continue;
|
|
5631
|
+
for (const [entityId, snapshotConfig] of Object.entries(fileContent)) {
|
|
5632
|
+
if (!snapshotConfig || typeof snapshotConfig !== "object") continue;
|
|
5633
|
+
const serialized = JSON.stringify(snapshotConfig);
|
|
5634
|
+
if (previousSnapshots.get(entityId) === serialized) continue;
|
|
5635
|
+
previousSnapshots.set(entityId, serialized);
|
|
5636
|
+
const count = (entityVersionCount.get(entityId) ?? 0) + 1;
|
|
5637
|
+
entityVersionCount.set(entityId, count);
|
|
5638
|
+
const versionId = `${GIT_VERSION_PREFIX}${commit.hash}-${entityId}`;
|
|
5639
|
+
if (this.versions.has(versionId)) continue;
|
|
5640
|
+
const version = {
|
|
5641
|
+
id: versionId,
|
|
5642
|
+
[this.parentIdField]: entityId,
|
|
5643
|
+
versionNumber: count,
|
|
5644
|
+
changeMessage: commit.message,
|
|
5645
|
+
...snapshotConfig,
|
|
5646
|
+
createdAt: commit.date
|
|
5647
|
+
};
|
|
5648
|
+
this.versions.set(versionId, version);
|
|
5649
|
+
}
|
|
5650
|
+
}
|
|
5651
|
+
this.gitVersionCounts = entityVersionCount;
|
|
5652
|
+
for (const [entityId, gitCount] of entityVersionCount) {
|
|
5653
|
+
const hydratedVersionId = `hydrated-${entityId}-v1`;
|
|
5654
|
+
const version = this.versions.get(hydratedVersionId);
|
|
5655
|
+
if (version) {
|
|
5656
|
+
version.versionNumber = gitCount + 1;
|
|
5657
|
+
}
|
|
5658
|
+
}
|
|
5659
|
+
}
|
|
5660
|
+
// ==========================================================================
|
|
5661
|
+
// Disk persistence — only published snapshot configs
|
|
5662
|
+
// ==========================================================================
|
|
5663
|
+
/**
|
|
5664
|
+
* Write the published snapshot config for an entity to disk.
|
|
5665
|
+
* Strips all entity metadata and version metadata fields, leaving only
|
|
5666
|
+
* the clean primitive configuration.
|
|
5667
|
+
*/
|
|
5668
|
+
persistToDisk() {
|
|
5669
|
+
const diskData = {};
|
|
5670
|
+
for (const [entityId, entity] of this.entities) {
|
|
5671
|
+
if (entity.status !== "published" || !entity.activeVersionId) continue;
|
|
5672
|
+
const version = this.versions.get(entity.activeVersionId);
|
|
5673
|
+
if (!version) continue;
|
|
5674
|
+
const snapshotConfig = this.extractSnapshotConfig(version);
|
|
5675
|
+
diskData[entityId] = snapshotConfig;
|
|
5676
|
+
}
|
|
5677
|
+
this.db.writeDomain(this.entitiesFile, diskData);
|
|
5678
|
+
}
|
|
5679
|
+
/**
|
|
5680
|
+
* Extract the snapshot config from a version, stripping version metadata fields.
|
|
5681
|
+
*/
|
|
5682
|
+
extractSnapshotConfig(version) {
|
|
5683
|
+
const metadataSet = new Set(this.versionMetadataFields);
|
|
5684
|
+
const result = {};
|
|
5685
|
+
for (const [key, value] of Object.entries(version)) {
|
|
5686
|
+
if (!metadataSet.has(key)) {
|
|
5687
|
+
result[key] = value;
|
|
5688
|
+
}
|
|
5689
|
+
}
|
|
5690
|
+
return result;
|
|
5691
|
+
}
|
|
5692
|
+
// ==========================================================================
|
|
5693
|
+
// Entity CRUD
|
|
5694
|
+
// ==========================================================================
|
|
5695
|
+
async getById(id) {
|
|
5696
|
+
this.hydrate();
|
|
5697
|
+
return this.entities.has(id) ? structuredClone(this.entities.get(id)) : null;
|
|
5698
|
+
}
|
|
5699
|
+
async createEntity(id, entity) {
|
|
5700
|
+
this.hydrate();
|
|
5701
|
+
if (this.entities.has(id)) {
|
|
5702
|
+
throw new Error(`${this.name}: entity with id ${id} already exists`);
|
|
5703
|
+
}
|
|
5704
|
+
this.entities.set(id, structuredClone(entity));
|
|
5705
|
+
return structuredClone(entity);
|
|
5706
|
+
}
|
|
5707
|
+
async updateEntity(id, updates) {
|
|
5708
|
+
this.hydrate();
|
|
5709
|
+
const existing = this.entities.get(id);
|
|
5710
|
+
if (!existing) {
|
|
5711
|
+
throw new Error(`${this.name}: entity with id ${id} not found`);
|
|
5712
|
+
}
|
|
5713
|
+
const updated = { ...existing };
|
|
5714
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
5715
|
+
if (key === "id") continue;
|
|
5716
|
+
if (value === void 0) continue;
|
|
5717
|
+
if (key === "metadata" && typeof value === "object" && value !== null) {
|
|
5718
|
+
updated["metadata"] = {
|
|
5719
|
+
...updated["metadata"] ?? {},
|
|
5720
|
+
...value
|
|
5721
|
+
};
|
|
5722
|
+
} else {
|
|
5723
|
+
updated[key] = value;
|
|
5724
|
+
}
|
|
5725
|
+
}
|
|
5726
|
+
updated["updatedAt"] = /* @__PURE__ */ new Date();
|
|
5727
|
+
const updatedEntity = updated;
|
|
5728
|
+
this.entities.set(id, structuredClone(updatedEntity));
|
|
5729
|
+
const wasPublished = existing.status === "published";
|
|
5730
|
+
const isPublished = updatedEntity.status === "published" && updatedEntity.activeVersionId;
|
|
5731
|
+
if (isPublished || wasPublished && updates["status"] !== void 0) {
|
|
5732
|
+
this.persistToDisk();
|
|
5733
|
+
}
|
|
5734
|
+
return structuredClone(updatedEntity);
|
|
5735
|
+
}
|
|
5736
|
+
async deleteEntity(id) {
|
|
5737
|
+
this.hydrate();
|
|
5738
|
+
this.entities.delete(id);
|
|
5739
|
+
await this.deleteVersionsByParentId(id);
|
|
5740
|
+
this.persistToDisk();
|
|
5741
|
+
}
|
|
5742
|
+
async listEntities(args) {
|
|
5743
|
+
this.hydrate();
|
|
5744
|
+
const { page = 0, perPage: perPageInput, orderBy, filters, listKey } = args;
|
|
5745
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
5746
|
+
if (page < 0) throw new Error("page must be >= 0");
|
|
5747
|
+
let entities = Array.from(this.entities.values());
|
|
5748
|
+
if (filters) {
|
|
5749
|
+
for (const [key, value] of Object.entries(filters)) {
|
|
5750
|
+
if (value === void 0) continue;
|
|
5751
|
+
if (key === "metadata" && typeof value === "object" && value !== null) {
|
|
5752
|
+
entities = entities.filter((e) => {
|
|
5753
|
+
const meta = e["metadata"];
|
|
5754
|
+
if (!meta) return false;
|
|
5755
|
+
return Object.entries(value).every(
|
|
5756
|
+
([k, v]) => JSON.stringify(meta[k]) === JSON.stringify(v)
|
|
5757
|
+
);
|
|
5758
|
+
});
|
|
5759
|
+
} else {
|
|
5760
|
+
entities = entities.filter((e) => e[key] === value);
|
|
5761
|
+
}
|
|
5762
|
+
}
|
|
5763
|
+
}
|
|
5764
|
+
const field = orderBy?.field ?? "createdAt";
|
|
5765
|
+
const direction = orderBy?.direction ?? "DESC";
|
|
5766
|
+
entities.sort((a, b) => {
|
|
5767
|
+
const aVal = new Date(a[field]).getTime();
|
|
5768
|
+
const bVal = new Date(b[field]).getTime();
|
|
5769
|
+
return direction === "ASC" ? aVal - bVal : bVal - aVal;
|
|
5770
|
+
});
|
|
5771
|
+
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
5772
|
+
return {
|
|
5773
|
+
[listKey]: entities.slice(offset, offset + perPage),
|
|
5774
|
+
total: entities.length,
|
|
5775
|
+
page,
|
|
5776
|
+
perPage: perPageForResponse,
|
|
5777
|
+
hasMore: offset + perPage < entities.length
|
|
5778
|
+
};
|
|
5779
|
+
}
|
|
5780
|
+
// ==========================================================================
|
|
5781
|
+
// Version Methods (in-memory + git history)
|
|
5782
|
+
// ==========================================================================
|
|
5783
|
+
async createVersion(input) {
|
|
5784
|
+
await this.ensureGitHistory();
|
|
5785
|
+
if (this.versions.has(input.id)) {
|
|
5786
|
+
throw new Error(`${this.name}: version with id ${input.id} already exists`);
|
|
5787
|
+
}
|
|
5788
|
+
const parentId = input[this.parentIdField];
|
|
5789
|
+
for (const v of this.versions.values()) {
|
|
5790
|
+
if (v[this.parentIdField] === parentId && v.versionNumber === input.versionNumber) {
|
|
5791
|
+
throw new Error(`${this.name}: version number ${input.versionNumber} already exists for entity ${parentId}`);
|
|
5792
|
+
}
|
|
5793
|
+
}
|
|
5794
|
+
const version = {
|
|
5795
|
+
...input,
|
|
5796
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
5797
|
+
};
|
|
5798
|
+
this.versions.set(input.id, structuredClone(version));
|
|
5799
|
+
return structuredClone(version);
|
|
5800
|
+
}
|
|
5801
|
+
async getVersion(id) {
|
|
5802
|
+
await this.ensureGitHistory();
|
|
5803
|
+
return this.versions.has(id) ? structuredClone(this.versions.get(id)) : null;
|
|
5804
|
+
}
|
|
5805
|
+
async getVersionByNumber(entityId, versionNumber) {
|
|
5806
|
+
await this.ensureGitHistory();
|
|
5807
|
+
for (const v of this.versions.values()) {
|
|
5808
|
+
if (v[this.parentIdField] === entityId && v.versionNumber === versionNumber) {
|
|
5809
|
+
return structuredClone(v);
|
|
5810
|
+
}
|
|
5811
|
+
}
|
|
5812
|
+
return null;
|
|
5813
|
+
}
|
|
5814
|
+
async getLatestVersion(entityId) {
|
|
5815
|
+
await this.ensureGitHistory();
|
|
5816
|
+
let latest = null;
|
|
5817
|
+
for (const v of this.versions.values()) {
|
|
5818
|
+
if (v[this.parentIdField] === entityId) {
|
|
5819
|
+
if (!latest || v.versionNumber > latest.versionNumber) {
|
|
5820
|
+
latest = v;
|
|
5821
|
+
}
|
|
5822
|
+
}
|
|
5823
|
+
}
|
|
5824
|
+
return latest ? structuredClone(latest) : null;
|
|
5825
|
+
}
|
|
5826
|
+
async listVersions(input, parentIdField) {
|
|
5827
|
+
await this.ensureGitHistory();
|
|
5828
|
+
const { page = 0, perPage: perPageInput, orderBy } = input;
|
|
5829
|
+
const entityId = input[parentIdField];
|
|
5830
|
+
const perPage = normalizePerPage(perPageInput, 20);
|
|
5831
|
+
if (page < 0) throw new Error("page must be >= 0");
|
|
5832
|
+
let versions = Array.from(this.versions.values()).filter(
|
|
5833
|
+
(v) => v[this.parentIdField] === entityId
|
|
5834
|
+
);
|
|
5835
|
+
const field = orderBy?.field ?? "versionNumber";
|
|
5836
|
+
const direction = orderBy?.direction ?? "DESC";
|
|
5837
|
+
versions.sort((a, b) => {
|
|
5838
|
+
const aVal = field === "createdAt" ? new Date(a.createdAt).getTime() : a.versionNumber;
|
|
5839
|
+
const bVal = field === "createdAt" ? new Date(b.createdAt).getTime() : b.versionNumber;
|
|
5840
|
+
return direction === "ASC" ? aVal - bVal : bVal - aVal;
|
|
5841
|
+
});
|
|
5842
|
+
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
5843
|
+
return {
|
|
5844
|
+
versions: versions.slice(offset, offset + perPage),
|
|
5845
|
+
total: versions.length,
|
|
5846
|
+
page,
|
|
5847
|
+
perPage: perPageForResponse,
|
|
5848
|
+
hasMore: offset + perPage < versions.length
|
|
5849
|
+
};
|
|
5850
|
+
}
|
|
5851
|
+
async deleteVersion(id) {
|
|
5852
|
+
await this.ensureGitHistory();
|
|
5853
|
+
if (_FilesystemVersionedHelpers.isGitVersion(id)) return;
|
|
5854
|
+
this.versions.delete(id);
|
|
5855
|
+
}
|
|
5856
|
+
async deleteVersionsByParentId(entityId) {
|
|
5857
|
+
await this.ensureGitHistory();
|
|
5858
|
+
for (const [versionId, version] of this.versions) {
|
|
5859
|
+
if (version[this.parentIdField] === entityId) {
|
|
5860
|
+
if (_FilesystemVersionedHelpers.isGitVersion(versionId)) continue;
|
|
5861
|
+
this.versions.delete(versionId);
|
|
5862
|
+
}
|
|
5863
|
+
}
|
|
5864
|
+
}
|
|
5865
|
+
async countVersions(entityId) {
|
|
5866
|
+
await this.ensureGitHistory();
|
|
5867
|
+
let count = 0;
|
|
5868
|
+
for (const v of this.versions.values()) {
|
|
5869
|
+
if (v[this.parentIdField] === entityId) {
|
|
5870
|
+
count++;
|
|
5871
|
+
}
|
|
5872
|
+
}
|
|
5873
|
+
return count;
|
|
5874
|
+
}
|
|
5875
|
+
async getNextVersionNumber(entityId) {
|
|
5876
|
+
await this.ensureGitHistory();
|
|
5877
|
+
return this._getNextVersionNumber(entityId);
|
|
5878
|
+
}
|
|
5879
|
+
_getNextVersionNumber(entityId) {
|
|
5880
|
+
const gitCount = this.gitVersionCounts.get(entityId) ?? 0;
|
|
5881
|
+
let maxVersion = gitCount;
|
|
5882
|
+
for (const v of this.versions.values()) {
|
|
5883
|
+
if (v[this.parentIdField] === entityId) {
|
|
5884
|
+
maxVersion = Math.max(maxVersion, v.versionNumber);
|
|
5885
|
+
}
|
|
5886
|
+
}
|
|
5887
|
+
return maxVersion + 1;
|
|
5888
|
+
}
|
|
5889
|
+
async dangerouslyClearAll() {
|
|
5890
|
+
this.entities.clear();
|
|
5891
|
+
this.versions.clear();
|
|
5892
|
+
this.gitVersionCounts.clear();
|
|
5893
|
+
this.gitHistoryPromise = null;
|
|
5894
|
+
this.hydrated = false;
|
|
5895
|
+
this.db.clearDomain(this.entitiesFile);
|
|
5896
|
+
}
|
|
5897
|
+
};
|
|
5898
|
+
|
|
5899
|
+
// src/storage/domains/agents/filesystem.ts
|
|
5900
|
+
var PERSISTED_SNAPSHOT_FIELDS = /* @__PURE__ */ new Set([
|
|
5901
|
+
"name",
|
|
5902
|
+
"instructions",
|
|
5903
|
+
"model",
|
|
5904
|
+
"tools",
|
|
5905
|
+
"integrationTools",
|
|
5906
|
+
"mcpClients",
|
|
5907
|
+
"requestContextSchema"
|
|
5908
|
+
]);
|
|
5909
|
+
function stripUnusedFields(obj) {
|
|
5910
|
+
const result = {};
|
|
5911
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
5912
|
+
if (PERSISTED_SNAPSHOT_FIELDS.has(key)) {
|
|
5913
|
+
result[key] = value;
|
|
5914
|
+
}
|
|
5915
|
+
}
|
|
5916
|
+
return result;
|
|
5917
|
+
}
|
|
5918
|
+
var FilesystemAgentsStorage = class extends AgentsStorage {
|
|
5919
|
+
helpers;
|
|
5920
|
+
constructor({ db }) {
|
|
5921
|
+
super();
|
|
5922
|
+
this.helpers = new FilesystemVersionedHelpers({
|
|
5923
|
+
db,
|
|
5924
|
+
entitiesFile: "agents.json",
|
|
5925
|
+
parentIdField: "agentId",
|
|
5926
|
+
name: "FilesystemAgentsStorage",
|
|
5927
|
+
versionMetadataFields: ["id", "agentId", "versionNumber", "changedFields", "changeMessage", "createdAt"]
|
|
5928
|
+
});
|
|
5929
|
+
}
|
|
5930
|
+
async init() {
|
|
5931
|
+
await this.helpers.db.init();
|
|
5932
|
+
}
|
|
5933
|
+
async dangerouslyClearAll() {
|
|
5934
|
+
await this.helpers.dangerouslyClearAll();
|
|
5935
|
+
}
|
|
5936
|
+
async getById(id) {
|
|
5937
|
+
return this.helpers.getById(id);
|
|
5938
|
+
}
|
|
5939
|
+
async create(input) {
|
|
5940
|
+
const { agent } = input;
|
|
5941
|
+
const now = /* @__PURE__ */ new Date();
|
|
5942
|
+
const entity = {
|
|
5943
|
+
id: agent.id,
|
|
5944
|
+
status: "draft",
|
|
5945
|
+
activeVersionId: void 0,
|
|
5946
|
+
authorId: agent.authorId,
|
|
5947
|
+
metadata: agent.metadata,
|
|
5948
|
+
createdAt: now,
|
|
5949
|
+
updatedAt: now
|
|
5950
|
+
};
|
|
5951
|
+
await this.helpers.createEntity(agent.id, entity);
|
|
5952
|
+
const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = agent;
|
|
5953
|
+
const filtered = stripUnusedFields(snapshotConfig);
|
|
5954
|
+
const versionId = crypto.randomUUID();
|
|
5955
|
+
await this.createVersion({
|
|
5956
|
+
id: versionId,
|
|
5957
|
+
agentId: agent.id,
|
|
5958
|
+
versionNumber: 1,
|
|
5959
|
+
...filtered,
|
|
5960
|
+
changedFields: Object.keys(filtered),
|
|
5961
|
+
changeMessage: "Initial version"
|
|
5962
|
+
});
|
|
5963
|
+
return structuredClone(entity);
|
|
5964
|
+
}
|
|
5965
|
+
async update(input) {
|
|
5966
|
+
const { id, ...updates } = input;
|
|
5967
|
+
const entityUpdates = {};
|
|
5968
|
+
const entityFields = /* @__PURE__ */ new Set(["authorId", "metadata", "activeVersionId", "status"]);
|
|
5969
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
5970
|
+
if (entityFields.has(key)) {
|
|
5971
|
+
entityUpdates[key] = value;
|
|
5972
|
+
}
|
|
5973
|
+
}
|
|
5974
|
+
return this.helpers.updateEntity(id, entityUpdates);
|
|
5975
|
+
}
|
|
5976
|
+
async delete(id) {
|
|
5977
|
+
await this.helpers.deleteEntity(id);
|
|
5978
|
+
}
|
|
5979
|
+
async list(args) {
|
|
5980
|
+
const { page, perPage, orderBy, authorId, metadata, status } = args || {};
|
|
5981
|
+
const result = await this.helpers.listEntities({
|
|
5982
|
+
page,
|
|
5983
|
+
perPage,
|
|
5984
|
+
orderBy,
|
|
5985
|
+
listKey: "agents",
|
|
5986
|
+
filters: { authorId, metadata, status }
|
|
5987
|
+
});
|
|
5988
|
+
return result;
|
|
5989
|
+
}
|
|
5990
|
+
async createVersion(input) {
|
|
5991
|
+
const { id, agentId, versionNumber, changedFields, changeMessage, ...snapshotFields } = input;
|
|
5992
|
+
const filtered = stripUnusedFields(snapshotFields);
|
|
5993
|
+
return this.helpers.createVersion({
|
|
5994
|
+
id,
|
|
5995
|
+
agentId,
|
|
5996
|
+
versionNumber,
|
|
5997
|
+
changedFields,
|
|
5998
|
+
changeMessage,
|
|
5999
|
+
...filtered
|
|
6000
|
+
});
|
|
6001
|
+
}
|
|
6002
|
+
async getVersion(id) {
|
|
6003
|
+
return this.helpers.getVersion(id);
|
|
6004
|
+
}
|
|
6005
|
+
async getVersionByNumber(agentId, versionNumber) {
|
|
6006
|
+
return this.helpers.getVersionByNumber(agentId, versionNumber);
|
|
6007
|
+
}
|
|
6008
|
+
async getLatestVersion(agentId) {
|
|
6009
|
+
return this.helpers.getLatestVersion(agentId);
|
|
6010
|
+
}
|
|
6011
|
+
async listVersions(input) {
|
|
6012
|
+
const result = await this.helpers.listVersions(input, "agentId");
|
|
6013
|
+
return result;
|
|
6014
|
+
}
|
|
6015
|
+
async deleteVersion(id) {
|
|
6016
|
+
await this.helpers.deleteVersion(id);
|
|
6017
|
+
}
|
|
6018
|
+
async deleteVersionsByParentId(entityId) {
|
|
6019
|
+
await this.helpers.deleteVersionsByParentId(entityId);
|
|
6020
|
+
}
|
|
6021
|
+
async countVersions(agentId) {
|
|
6022
|
+
return this.helpers.countVersions(agentId);
|
|
6023
|
+
}
|
|
6024
|
+
};
|
|
6025
|
+
|
|
6026
|
+
// src/storage/domains/mcp-clients/filesystem.ts
|
|
6027
|
+
var FilesystemMCPClientsStorage = class extends MCPClientsStorage {
|
|
6028
|
+
helpers;
|
|
6029
|
+
constructor({ db }) {
|
|
6030
|
+
super();
|
|
6031
|
+
this.helpers = new FilesystemVersionedHelpers({
|
|
6032
|
+
db,
|
|
6033
|
+
entitiesFile: "mcp-clients.json",
|
|
6034
|
+
parentIdField: "mcpClientId",
|
|
6035
|
+
name: "FilesystemMCPClientsStorage",
|
|
6036
|
+
versionMetadataFields: ["id", "mcpClientId", "versionNumber", "changedFields", "changeMessage", "createdAt"]
|
|
6037
|
+
});
|
|
6038
|
+
}
|
|
6039
|
+
async init() {
|
|
6040
|
+
await this.helpers.db.init();
|
|
6041
|
+
}
|
|
6042
|
+
async dangerouslyClearAll() {
|
|
6043
|
+
await this.helpers.dangerouslyClearAll();
|
|
6044
|
+
}
|
|
6045
|
+
async getById(id) {
|
|
6046
|
+
return this.helpers.getById(id);
|
|
6047
|
+
}
|
|
6048
|
+
async create(input) {
|
|
6049
|
+
const { mcpClient } = input;
|
|
6050
|
+
const now = /* @__PURE__ */ new Date();
|
|
6051
|
+
const entity = {
|
|
6052
|
+
id: mcpClient.id,
|
|
6053
|
+
status: "draft",
|
|
6054
|
+
activeVersionId: void 0,
|
|
6055
|
+
authorId: mcpClient.authorId,
|
|
6056
|
+
metadata: mcpClient.metadata,
|
|
6057
|
+
createdAt: now,
|
|
6058
|
+
updatedAt: now
|
|
6059
|
+
};
|
|
6060
|
+
await this.helpers.createEntity(mcpClient.id, entity);
|
|
6061
|
+
const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient;
|
|
6062
|
+
const versionId = crypto.randomUUID();
|
|
6063
|
+
await this.createVersion({
|
|
6064
|
+
id: versionId,
|
|
6065
|
+
mcpClientId: mcpClient.id,
|
|
6066
|
+
versionNumber: 1,
|
|
6067
|
+
...snapshotConfig,
|
|
6068
|
+
changedFields: Object.keys(snapshotConfig),
|
|
6069
|
+
changeMessage: "Initial version"
|
|
6070
|
+
});
|
|
6071
|
+
return structuredClone(entity);
|
|
6072
|
+
}
|
|
6073
|
+
async update(input) {
|
|
6074
|
+
const { id, ...updates } = input;
|
|
6075
|
+
return this.helpers.updateEntity(id, updates);
|
|
6076
|
+
}
|
|
6077
|
+
async delete(id) {
|
|
6078
|
+
await this.helpers.deleteEntity(id);
|
|
6079
|
+
}
|
|
6080
|
+
async list(args) {
|
|
6081
|
+
const { page, perPage, orderBy, authorId, metadata, status } = args || {};
|
|
6082
|
+
const result = await this.helpers.listEntities({
|
|
6083
|
+
page,
|
|
6084
|
+
perPage,
|
|
6085
|
+
orderBy,
|
|
6086
|
+
listKey: "mcpClients",
|
|
6087
|
+
filters: { authorId, metadata, status }
|
|
6088
|
+
});
|
|
6089
|
+
return result;
|
|
6090
|
+
}
|
|
6091
|
+
async createVersion(input) {
|
|
6092
|
+
return this.helpers.createVersion(input);
|
|
6093
|
+
}
|
|
6094
|
+
async getVersion(id) {
|
|
6095
|
+
return this.helpers.getVersion(id);
|
|
6096
|
+
}
|
|
6097
|
+
async getVersionByNumber(mcpClientId, versionNumber) {
|
|
6098
|
+
return this.helpers.getVersionByNumber(mcpClientId, versionNumber);
|
|
6099
|
+
}
|
|
6100
|
+
async getLatestVersion(mcpClientId) {
|
|
6101
|
+
return this.helpers.getLatestVersion(mcpClientId);
|
|
6102
|
+
}
|
|
6103
|
+
async listVersions(input) {
|
|
6104
|
+
const result = await this.helpers.listVersions(input, "mcpClientId");
|
|
6105
|
+
return result;
|
|
6106
|
+
}
|
|
6107
|
+
async deleteVersion(id) {
|
|
6108
|
+
await this.helpers.deleteVersion(id);
|
|
6109
|
+
}
|
|
6110
|
+
async deleteVersionsByParentId(entityId) {
|
|
6111
|
+
await this.helpers.deleteVersionsByParentId(entityId);
|
|
6112
|
+
}
|
|
6113
|
+
async countVersions(mcpClientId) {
|
|
6114
|
+
return this.helpers.countVersions(mcpClientId);
|
|
6115
|
+
}
|
|
6116
|
+
};
|
|
6117
|
+
|
|
6118
|
+
// src/storage/domains/mcp-servers/filesystem.ts
|
|
6119
|
+
var FilesystemMCPServersStorage = class extends MCPServersStorage {
|
|
6120
|
+
helpers;
|
|
6121
|
+
constructor({ db }) {
|
|
6122
|
+
super();
|
|
6123
|
+
this.helpers = new FilesystemVersionedHelpers({
|
|
6124
|
+
db,
|
|
6125
|
+
entitiesFile: "mcp-servers.json",
|
|
6126
|
+
parentIdField: "mcpServerId",
|
|
6127
|
+
name: "FilesystemMCPServersStorage",
|
|
6128
|
+
versionMetadataFields: ["id", "mcpServerId", "versionNumber", "changedFields", "changeMessage", "createdAt"]
|
|
6129
|
+
});
|
|
6130
|
+
}
|
|
6131
|
+
async init() {
|
|
6132
|
+
await this.helpers.db.init();
|
|
6133
|
+
}
|
|
6134
|
+
async dangerouslyClearAll() {
|
|
6135
|
+
await this.helpers.dangerouslyClearAll();
|
|
6136
|
+
}
|
|
6137
|
+
async getById(id) {
|
|
6138
|
+
return this.helpers.getById(id);
|
|
6139
|
+
}
|
|
6140
|
+
async create(input) {
|
|
6141
|
+
const { mcpServer } = input;
|
|
6142
|
+
const now = /* @__PURE__ */ new Date();
|
|
6143
|
+
const entity = {
|
|
6144
|
+
id: mcpServer.id,
|
|
6145
|
+
status: "draft",
|
|
6146
|
+
activeVersionId: void 0,
|
|
6147
|
+
authorId: mcpServer.authorId,
|
|
6148
|
+
metadata: mcpServer.metadata,
|
|
6149
|
+
createdAt: now,
|
|
6150
|
+
updatedAt: now
|
|
6151
|
+
};
|
|
6152
|
+
await this.helpers.createEntity(mcpServer.id, entity);
|
|
6153
|
+
const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpServer;
|
|
6154
|
+
const versionId = crypto.randomUUID();
|
|
6155
|
+
await this.createVersion({
|
|
6156
|
+
id: versionId,
|
|
6157
|
+
mcpServerId: mcpServer.id,
|
|
6158
|
+
versionNumber: 1,
|
|
6159
|
+
...snapshotConfig,
|
|
6160
|
+
changedFields: Object.keys(snapshotConfig),
|
|
6161
|
+
changeMessage: "Initial version"
|
|
6162
|
+
});
|
|
6163
|
+
return structuredClone(entity);
|
|
6164
|
+
}
|
|
6165
|
+
async update(input) {
|
|
6166
|
+
const { id, ...updates } = input;
|
|
6167
|
+
return this.helpers.updateEntity(id, updates);
|
|
6168
|
+
}
|
|
6169
|
+
async delete(id) {
|
|
6170
|
+
await this.helpers.deleteEntity(id);
|
|
6171
|
+
}
|
|
6172
|
+
async list(args) {
|
|
6173
|
+
const { page, perPage, orderBy, authorId, metadata, status } = args || {};
|
|
6174
|
+
const result = await this.helpers.listEntities({
|
|
6175
|
+
page,
|
|
6176
|
+
perPage,
|
|
6177
|
+
orderBy,
|
|
6178
|
+
listKey: "mcpServers",
|
|
6179
|
+
filters: { authorId, metadata, status }
|
|
6180
|
+
});
|
|
6181
|
+
return result;
|
|
6182
|
+
}
|
|
6183
|
+
async createVersion(input) {
|
|
6184
|
+
return this.helpers.createVersion(input);
|
|
6185
|
+
}
|
|
6186
|
+
async getVersion(id) {
|
|
6187
|
+
return this.helpers.getVersion(id);
|
|
6188
|
+
}
|
|
6189
|
+
async getVersionByNumber(mcpServerId, versionNumber) {
|
|
6190
|
+
return this.helpers.getVersionByNumber(mcpServerId, versionNumber);
|
|
6191
|
+
}
|
|
6192
|
+
async getLatestVersion(mcpServerId) {
|
|
6193
|
+
return this.helpers.getLatestVersion(mcpServerId);
|
|
6194
|
+
}
|
|
6195
|
+
async listVersions(input) {
|
|
6196
|
+
const result = await this.helpers.listVersions(input, "mcpServerId");
|
|
6197
|
+
return result;
|
|
6198
|
+
}
|
|
6199
|
+
async deleteVersion(id) {
|
|
6200
|
+
await this.helpers.deleteVersion(id);
|
|
6201
|
+
}
|
|
6202
|
+
async deleteVersionsByParentId(entityId) {
|
|
6203
|
+
await this.helpers.deleteVersionsByParentId(entityId);
|
|
6204
|
+
}
|
|
6205
|
+
async countVersions(mcpServerId) {
|
|
6206
|
+
return this.helpers.countVersions(mcpServerId);
|
|
6207
|
+
}
|
|
6208
|
+
};
|
|
6209
|
+
|
|
6210
|
+
// src/storage/domains/prompt-blocks/filesystem.ts
|
|
6211
|
+
var FilesystemPromptBlocksStorage = class extends PromptBlocksStorage {
|
|
6212
|
+
helpers;
|
|
6213
|
+
constructor({ db }) {
|
|
6214
|
+
super();
|
|
6215
|
+
this.helpers = new FilesystemVersionedHelpers({
|
|
6216
|
+
db,
|
|
6217
|
+
entitiesFile: "prompt-blocks.json",
|
|
6218
|
+
parentIdField: "blockId",
|
|
6219
|
+
name: "FilesystemPromptBlocksStorage",
|
|
6220
|
+
versionMetadataFields: ["id", "blockId", "versionNumber", "changedFields", "changeMessage", "createdAt"]
|
|
6221
|
+
});
|
|
6222
|
+
}
|
|
6223
|
+
async init() {
|
|
6224
|
+
await this.helpers.db.init();
|
|
6225
|
+
}
|
|
6226
|
+
async dangerouslyClearAll() {
|
|
6227
|
+
await this.helpers.dangerouslyClearAll();
|
|
6228
|
+
}
|
|
6229
|
+
async getById(id) {
|
|
6230
|
+
return this.helpers.getById(id);
|
|
6231
|
+
}
|
|
6232
|
+
async create(input) {
|
|
6233
|
+
const { promptBlock } = input;
|
|
6234
|
+
const now = /* @__PURE__ */ new Date();
|
|
6235
|
+
const entity = {
|
|
6236
|
+
id: promptBlock.id,
|
|
6237
|
+
status: "draft",
|
|
6238
|
+
activeVersionId: void 0,
|
|
6239
|
+
authorId: promptBlock.authorId,
|
|
6240
|
+
metadata: promptBlock.metadata,
|
|
6241
|
+
createdAt: now,
|
|
6242
|
+
updatedAt: now
|
|
6243
|
+
};
|
|
6244
|
+
await this.helpers.createEntity(promptBlock.id, entity);
|
|
6245
|
+
const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = promptBlock;
|
|
6246
|
+
const versionId = crypto.randomUUID();
|
|
6247
|
+
await this.createVersion({
|
|
6248
|
+
id: versionId,
|
|
6249
|
+
blockId: promptBlock.id,
|
|
6250
|
+
versionNumber: 1,
|
|
6251
|
+
...snapshotConfig,
|
|
6252
|
+
changedFields: Object.keys(snapshotConfig),
|
|
6253
|
+
changeMessage: "Initial version"
|
|
6254
|
+
});
|
|
6255
|
+
return structuredClone(entity);
|
|
6256
|
+
}
|
|
6257
|
+
async update(input) {
|
|
6258
|
+
const { id, ...updates } = input;
|
|
6259
|
+
return this.helpers.updateEntity(id, updates);
|
|
6260
|
+
}
|
|
6261
|
+
async delete(id) {
|
|
6262
|
+
await this.helpers.deleteEntity(id);
|
|
6263
|
+
}
|
|
6264
|
+
async list(args) {
|
|
6265
|
+
const { page, perPage, orderBy, authorId, metadata, status } = args || {};
|
|
6266
|
+
const result = await this.helpers.listEntities({
|
|
6267
|
+
page,
|
|
6268
|
+
perPage,
|
|
6269
|
+
orderBy,
|
|
6270
|
+
listKey: "promptBlocks",
|
|
6271
|
+
filters: { authorId, metadata, status }
|
|
6272
|
+
});
|
|
6273
|
+
return result;
|
|
6274
|
+
}
|
|
6275
|
+
async createVersion(input) {
|
|
6276
|
+
return this.helpers.createVersion(input);
|
|
6277
|
+
}
|
|
6278
|
+
async getVersion(id) {
|
|
6279
|
+
return this.helpers.getVersion(id);
|
|
6280
|
+
}
|
|
6281
|
+
async getVersionByNumber(blockId, versionNumber) {
|
|
6282
|
+
return this.helpers.getVersionByNumber(blockId, versionNumber);
|
|
6283
|
+
}
|
|
6284
|
+
async getLatestVersion(blockId) {
|
|
6285
|
+
return this.helpers.getLatestVersion(blockId);
|
|
6286
|
+
}
|
|
6287
|
+
async listVersions(input) {
|
|
6288
|
+
const result = await this.helpers.listVersions(input, "blockId");
|
|
6289
|
+
return result;
|
|
6290
|
+
}
|
|
6291
|
+
async deleteVersion(id) {
|
|
6292
|
+
await this.helpers.deleteVersion(id);
|
|
6293
|
+
}
|
|
6294
|
+
async deleteVersionsByParentId(entityId) {
|
|
6295
|
+
await this.helpers.deleteVersionsByParentId(entityId);
|
|
6296
|
+
}
|
|
6297
|
+
async countVersions(blockId) {
|
|
6298
|
+
return this.helpers.countVersions(blockId);
|
|
6299
|
+
}
|
|
6300
|
+
};
|
|
6301
|
+
|
|
6302
|
+
// src/storage/domains/scorer-definitions/filesystem.ts
|
|
6303
|
+
var FilesystemScorerDefinitionsStorage = class extends ScorerDefinitionsStorage {
|
|
6304
|
+
helpers;
|
|
6305
|
+
constructor({ db }) {
|
|
6306
|
+
super();
|
|
6307
|
+
this.helpers = new FilesystemVersionedHelpers({
|
|
6308
|
+
db,
|
|
6309
|
+
entitiesFile: "scorer-definitions.json",
|
|
6310
|
+
parentIdField: "scorerDefinitionId",
|
|
6311
|
+
name: "FilesystemScorerDefinitionsStorage",
|
|
6312
|
+
versionMetadataFields: [
|
|
6313
|
+
"id",
|
|
6314
|
+
"scorerDefinitionId",
|
|
6315
|
+
"versionNumber",
|
|
6316
|
+
"changedFields",
|
|
6317
|
+
"changeMessage",
|
|
6318
|
+
"createdAt"
|
|
6319
|
+
]
|
|
6320
|
+
});
|
|
6321
|
+
}
|
|
6322
|
+
async init() {
|
|
6323
|
+
await this.helpers.db.init();
|
|
6324
|
+
}
|
|
6325
|
+
async dangerouslyClearAll() {
|
|
6326
|
+
await this.helpers.dangerouslyClearAll();
|
|
6327
|
+
}
|
|
6328
|
+
async getById(id) {
|
|
6329
|
+
return this.helpers.getById(id);
|
|
6330
|
+
}
|
|
6331
|
+
async create(input) {
|
|
6332
|
+
const { scorerDefinition } = input;
|
|
6333
|
+
const now = /* @__PURE__ */ new Date();
|
|
6334
|
+
const entity = {
|
|
6335
|
+
id: scorerDefinition.id,
|
|
6336
|
+
status: "draft",
|
|
6337
|
+
activeVersionId: void 0,
|
|
6338
|
+
authorId: scorerDefinition.authorId,
|
|
6339
|
+
metadata: scorerDefinition.metadata,
|
|
6340
|
+
createdAt: now,
|
|
6341
|
+
updatedAt: now
|
|
6342
|
+
};
|
|
6343
|
+
await this.helpers.createEntity(scorerDefinition.id, entity);
|
|
6344
|
+
const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = scorerDefinition;
|
|
6345
|
+
const versionId = crypto.randomUUID();
|
|
6346
|
+
await this.createVersion({
|
|
6347
|
+
id: versionId,
|
|
6348
|
+
scorerDefinitionId: scorerDefinition.id,
|
|
6349
|
+
versionNumber: 1,
|
|
6350
|
+
...snapshotConfig,
|
|
6351
|
+
changedFields: Object.keys(snapshotConfig),
|
|
6352
|
+
changeMessage: "Initial version"
|
|
6353
|
+
});
|
|
6354
|
+
return structuredClone(entity);
|
|
6355
|
+
}
|
|
6356
|
+
async update(input) {
|
|
6357
|
+
const { id, ...updates } = input;
|
|
6358
|
+
return this.helpers.updateEntity(id, updates);
|
|
6359
|
+
}
|
|
6360
|
+
async delete(id) {
|
|
6361
|
+
await this.helpers.deleteEntity(id);
|
|
6362
|
+
}
|
|
6363
|
+
async list(args) {
|
|
6364
|
+
const { page, perPage, orderBy, authorId, metadata, status } = args || {};
|
|
6365
|
+
const result = await this.helpers.listEntities({
|
|
6366
|
+
page,
|
|
6367
|
+
perPage,
|
|
6368
|
+
orderBy,
|
|
6369
|
+
listKey: "scorerDefinitions",
|
|
6370
|
+
filters: { authorId, metadata, status }
|
|
6371
|
+
});
|
|
6372
|
+
return result;
|
|
6373
|
+
}
|
|
6374
|
+
async createVersion(input) {
|
|
6375
|
+
return this.helpers.createVersion(input);
|
|
6376
|
+
}
|
|
6377
|
+
async getVersion(id) {
|
|
6378
|
+
return this.helpers.getVersion(id);
|
|
6379
|
+
}
|
|
6380
|
+
async getVersionByNumber(scorerDefinitionId, versionNumber) {
|
|
6381
|
+
return this.helpers.getVersionByNumber(scorerDefinitionId, versionNumber);
|
|
6382
|
+
}
|
|
6383
|
+
async getLatestVersion(scorerDefinitionId) {
|
|
6384
|
+
return this.helpers.getLatestVersion(scorerDefinitionId);
|
|
6385
|
+
}
|
|
6386
|
+
async listVersions(input) {
|
|
6387
|
+
const result = await this.helpers.listVersions(input, "scorerDefinitionId");
|
|
6388
|
+
return result;
|
|
6389
|
+
}
|
|
6390
|
+
async deleteVersion(id) {
|
|
6391
|
+
await this.helpers.deleteVersion(id);
|
|
6392
|
+
}
|
|
6393
|
+
async deleteVersionsByParentId(entityId) {
|
|
6394
|
+
await this.helpers.deleteVersionsByParentId(entityId);
|
|
6395
|
+
}
|
|
6396
|
+
async countVersions(scorerDefinitionId) {
|
|
6397
|
+
return this.helpers.countVersions(scorerDefinitionId);
|
|
6398
|
+
}
|
|
6399
|
+
};
|
|
6400
|
+
|
|
6401
|
+
// src/storage/domains/skills/filesystem.ts
|
|
6402
|
+
var FilesystemSkillsStorage = class extends SkillsStorage {
|
|
6403
|
+
helpers;
|
|
6404
|
+
constructor({ db }) {
|
|
6405
|
+
super();
|
|
6406
|
+
this.helpers = new FilesystemVersionedHelpers({
|
|
6407
|
+
db,
|
|
6408
|
+
entitiesFile: "skills.json",
|
|
6409
|
+
parentIdField: "skillId",
|
|
6410
|
+
name: "FilesystemSkillsStorage",
|
|
6411
|
+
versionMetadataFields: ["id", "skillId", "versionNumber", "changedFields", "changeMessage", "createdAt"]
|
|
6412
|
+
});
|
|
6413
|
+
}
|
|
6414
|
+
async init() {
|
|
6415
|
+
await this.helpers.db.init();
|
|
6416
|
+
}
|
|
6417
|
+
async dangerouslyClearAll() {
|
|
6418
|
+
await this.helpers.dangerouslyClearAll();
|
|
6419
|
+
}
|
|
6420
|
+
async getById(id) {
|
|
6421
|
+
return this.helpers.getById(id);
|
|
6422
|
+
}
|
|
6423
|
+
async create(input) {
|
|
6424
|
+
const { skill } = input;
|
|
6425
|
+
const now = /* @__PURE__ */ new Date();
|
|
6426
|
+
const entity = {
|
|
6427
|
+
id: skill.id,
|
|
6428
|
+
status: "draft",
|
|
6429
|
+
activeVersionId: void 0,
|
|
6430
|
+
authorId: skill.authorId,
|
|
6431
|
+
createdAt: now,
|
|
6432
|
+
updatedAt: now
|
|
6433
|
+
};
|
|
6434
|
+
await this.helpers.createEntity(skill.id, entity);
|
|
6435
|
+
const { id: _id, authorId: _authorId, ...snapshotConfig } = skill;
|
|
6436
|
+
const versionId = crypto.randomUUID();
|
|
6437
|
+
await this.createVersion({
|
|
6438
|
+
id: versionId,
|
|
6439
|
+
skillId: skill.id,
|
|
6440
|
+
versionNumber: 1,
|
|
6441
|
+
...snapshotConfig,
|
|
6442
|
+
changedFields: Object.keys(snapshotConfig),
|
|
6443
|
+
changeMessage: "Initial version"
|
|
6444
|
+
});
|
|
6445
|
+
return structuredClone(entity);
|
|
6446
|
+
}
|
|
6447
|
+
async update(input) {
|
|
6448
|
+
const { id, ...updates } = input;
|
|
6449
|
+
const existing = await this.helpers.getById(id);
|
|
6450
|
+
if (!existing) {
|
|
6451
|
+
throw new Error(`FilesystemSkillsStorage: skill with id ${id} not found`);
|
|
6452
|
+
}
|
|
6453
|
+
const { authorId, activeVersionId, status, ...configFields } = updates;
|
|
6454
|
+
const configFieldNames = [
|
|
6455
|
+
"name",
|
|
6456
|
+
"description",
|
|
6457
|
+
"instructions",
|
|
6458
|
+
"license",
|
|
6459
|
+
"compatibility",
|
|
6460
|
+
"source",
|
|
6461
|
+
"references",
|
|
6462
|
+
"scripts",
|
|
6463
|
+
"assets",
|
|
6464
|
+
"metadata",
|
|
6465
|
+
"tree"
|
|
6466
|
+
];
|
|
6467
|
+
const hasConfigUpdate = configFieldNames.some((field) => field in configFields);
|
|
6468
|
+
if (hasConfigUpdate) {
|
|
6469
|
+
const latestVersion = await this.getLatestVersion(id);
|
|
6470
|
+
if (!latestVersion) {
|
|
6471
|
+
throw new Error(`No versions found for skill ${id}`);
|
|
6472
|
+
}
|
|
6473
|
+
const {
|
|
6474
|
+
id: _versionId,
|
|
6475
|
+
skillId: _skillId,
|
|
6476
|
+
versionNumber: _versionNumber,
|
|
6477
|
+
changedFields: _changedFields,
|
|
6478
|
+
changeMessage: _changeMessage,
|
|
6479
|
+
createdAt: _createdAt,
|
|
6480
|
+
...latestConfig
|
|
6481
|
+
} = latestVersion;
|
|
6482
|
+
const newConfig = {
|
|
6483
|
+
...latestConfig,
|
|
6484
|
+
...configFields
|
|
6485
|
+
};
|
|
6486
|
+
const changedFields = configFieldNames.filter(
|
|
6487
|
+
(field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
|
|
6488
|
+
);
|
|
6489
|
+
if (changedFields.length > 0) {
|
|
6490
|
+
const newVersionId = crypto.randomUUID();
|
|
6491
|
+
const newVersionNumber = latestVersion.versionNumber + 1;
|
|
6492
|
+
await this.createVersion({
|
|
6493
|
+
id: newVersionId,
|
|
6494
|
+
skillId: id,
|
|
6495
|
+
versionNumber: newVersionNumber,
|
|
6496
|
+
...newConfig,
|
|
6497
|
+
changedFields,
|
|
6498
|
+
changeMessage: `Updated ${changedFields.join(", ")}`
|
|
6499
|
+
});
|
|
6500
|
+
}
|
|
6501
|
+
}
|
|
6502
|
+
const entityUpdates = {
|
|
6503
|
+
...authorId !== void 0 && { authorId },
|
|
6504
|
+
...activeVersionId !== void 0 && { activeVersionId },
|
|
6505
|
+
...status !== void 0 && { status }
|
|
6506
|
+
};
|
|
6507
|
+
if (activeVersionId !== void 0 && status === void 0) {
|
|
6508
|
+
entityUpdates.status = "published";
|
|
6509
|
+
}
|
|
6510
|
+
return await this.helpers.updateEntity(id, entityUpdates);
|
|
6511
|
+
}
|
|
6512
|
+
async delete(id) {
|
|
6513
|
+
await this.helpers.deleteEntity(id);
|
|
6514
|
+
}
|
|
6515
|
+
async list(args) {
|
|
6516
|
+
const { page, perPage, orderBy, authorId, metadata } = args || {};
|
|
6517
|
+
const result = await this.helpers.listEntities({
|
|
6518
|
+
page,
|
|
6519
|
+
perPage,
|
|
6520
|
+
orderBy,
|
|
6521
|
+
listKey: "skills",
|
|
6522
|
+
filters: { authorId, metadata }
|
|
6523
|
+
});
|
|
6524
|
+
return result;
|
|
6525
|
+
}
|
|
6526
|
+
async createVersion(input) {
|
|
6527
|
+
return this.helpers.createVersion(input);
|
|
6528
|
+
}
|
|
6529
|
+
async getVersion(id) {
|
|
6530
|
+
return this.helpers.getVersion(id);
|
|
6531
|
+
}
|
|
6532
|
+
async getVersionByNumber(skillId, versionNumber) {
|
|
6533
|
+
return this.helpers.getVersionByNumber(skillId, versionNumber);
|
|
6534
|
+
}
|
|
6535
|
+
async getLatestVersion(skillId) {
|
|
6536
|
+
return this.helpers.getLatestVersion(skillId);
|
|
6537
|
+
}
|
|
6538
|
+
async listVersions(input) {
|
|
6539
|
+
const result = await this.helpers.listVersions(input, "skillId");
|
|
6540
|
+
return result;
|
|
6541
|
+
}
|
|
6542
|
+
async deleteVersion(id) {
|
|
6543
|
+
await this.helpers.deleteVersion(id);
|
|
6544
|
+
}
|
|
6545
|
+
async deleteVersionsByParentId(entityId) {
|
|
6546
|
+
await this.helpers.deleteVersionsByParentId(entityId);
|
|
6547
|
+
}
|
|
6548
|
+
async countVersions(skillId) {
|
|
6549
|
+
return this.helpers.countVersions(skillId);
|
|
6550
|
+
}
|
|
6551
|
+
};
|
|
6552
|
+
|
|
6553
|
+
// src/storage/domains/workspaces/filesystem.ts
|
|
6554
|
+
var FilesystemWorkspacesStorage = class extends WorkspacesStorage {
|
|
6555
|
+
helpers;
|
|
6556
|
+
constructor({ db }) {
|
|
6557
|
+
super();
|
|
6558
|
+
this.helpers = new FilesystemVersionedHelpers({
|
|
6559
|
+
db,
|
|
6560
|
+
entitiesFile: "workspaces.json",
|
|
6561
|
+
parentIdField: "workspaceId",
|
|
6562
|
+
name: "FilesystemWorkspacesStorage",
|
|
6563
|
+
versionMetadataFields: ["id", "workspaceId", "versionNumber", "changedFields", "changeMessage", "createdAt"]
|
|
6564
|
+
});
|
|
6565
|
+
}
|
|
6566
|
+
async init() {
|
|
6567
|
+
await this.helpers.db.init();
|
|
6568
|
+
}
|
|
6569
|
+
async dangerouslyClearAll() {
|
|
6570
|
+
await this.helpers.dangerouslyClearAll();
|
|
6571
|
+
}
|
|
6572
|
+
async getById(id) {
|
|
6573
|
+
return this.helpers.getById(id);
|
|
6574
|
+
}
|
|
6575
|
+
async create(input) {
|
|
6576
|
+
const { workspace } = input;
|
|
6577
|
+
const now = /* @__PURE__ */ new Date();
|
|
6578
|
+
const entity = {
|
|
6579
|
+
id: workspace.id,
|
|
6580
|
+
status: "draft",
|
|
6581
|
+
activeVersionId: void 0,
|
|
6582
|
+
authorId: workspace.authorId,
|
|
6583
|
+
metadata: workspace.metadata,
|
|
6584
|
+
createdAt: now,
|
|
6585
|
+
updatedAt: now
|
|
6586
|
+
};
|
|
6587
|
+
await this.helpers.createEntity(workspace.id, entity);
|
|
6588
|
+
const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace;
|
|
6589
|
+
const versionId = crypto.randomUUID();
|
|
6590
|
+
await this.createVersion({
|
|
6591
|
+
id: versionId,
|
|
6592
|
+
workspaceId: workspace.id,
|
|
6593
|
+
versionNumber: 1,
|
|
6594
|
+
...snapshotConfig,
|
|
6595
|
+
changedFields: Object.keys(snapshotConfig),
|
|
6596
|
+
changeMessage: "Initial version"
|
|
6597
|
+
});
|
|
6598
|
+
return structuredClone(entity);
|
|
6599
|
+
}
|
|
6600
|
+
async update(input) {
|
|
6601
|
+
const { id, ...updates } = input;
|
|
6602
|
+
return this.helpers.updateEntity(id, updates);
|
|
6603
|
+
}
|
|
6604
|
+
async delete(id) {
|
|
6605
|
+
await this.helpers.deleteEntity(id);
|
|
6606
|
+
}
|
|
6607
|
+
async list(args) {
|
|
6608
|
+
const { page, perPage, orderBy, authorId, metadata } = args || {};
|
|
6609
|
+
const result = await this.helpers.listEntities({
|
|
6610
|
+
page,
|
|
6611
|
+
perPage,
|
|
6612
|
+
orderBy,
|
|
6613
|
+
listKey: "workspaces",
|
|
6614
|
+
filters: { authorId, metadata }
|
|
6615
|
+
});
|
|
6616
|
+
return result;
|
|
6617
|
+
}
|
|
6618
|
+
async createVersion(input) {
|
|
6619
|
+
return this.helpers.createVersion(input);
|
|
6620
|
+
}
|
|
6621
|
+
async getVersion(id) {
|
|
6622
|
+
return this.helpers.getVersion(id);
|
|
6623
|
+
}
|
|
6624
|
+
async getVersionByNumber(workspaceId, versionNumber) {
|
|
6625
|
+
return this.helpers.getVersionByNumber(workspaceId, versionNumber);
|
|
6626
|
+
}
|
|
6627
|
+
async getLatestVersion(workspaceId) {
|
|
6628
|
+
return this.helpers.getLatestVersion(workspaceId);
|
|
6629
|
+
}
|
|
6630
|
+
async listVersions(input) {
|
|
6631
|
+
const result = await this.helpers.listVersions(input, "workspaceId");
|
|
6632
|
+
return result;
|
|
6633
|
+
}
|
|
6634
|
+
async deleteVersion(id) {
|
|
6635
|
+
await this.helpers.deleteVersion(id);
|
|
6636
|
+
}
|
|
6637
|
+
async deleteVersionsByParentId(entityId) {
|
|
6638
|
+
await this.helpers.deleteVersionsByParentId(entityId);
|
|
6639
|
+
}
|
|
6640
|
+
async countVersions(workspaceId) {
|
|
6641
|
+
return this.helpers.countVersions(workspaceId);
|
|
6642
|
+
}
|
|
6643
|
+
};
|
|
6644
|
+
var FilesystemDB = class {
|
|
6645
|
+
dir;
|
|
6646
|
+
/** In-memory cache of parsed domain data, keyed by filename */
|
|
6647
|
+
cache = /* @__PURE__ */ new Map();
|
|
6648
|
+
initialized = false;
|
|
6649
|
+
constructor(dir) {
|
|
6650
|
+
this.dir = dir;
|
|
6651
|
+
}
|
|
6652
|
+
/**
|
|
6653
|
+
* Initialize the storage directory. Called once; subsequent calls are no-ops.
|
|
6654
|
+
*/
|
|
6655
|
+
async init() {
|
|
6656
|
+
if (this.initialized) return;
|
|
6657
|
+
this.ensureDir();
|
|
6658
|
+
this.initialized = true;
|
|
6659
|
+
}
|
|
6660
|
+
/**
|
|
6661
|
+
* Ensure the storage directory and skills subdirectory exist.
|
|
6662
|
+
*/
|
|
6663
|
+
ensureDir() {
|
|
6664
|
+
if (!fs.existsSync(this.dir)) {
|
|
6665
|
+
fs.mkdirSync(this.dir, { recursive: true });
|
|
6666
|
+
}
|
|
6667
|
+
const skillsDir = path.join(this.dir, "skills");
|
|
6668
|
+
if (!fs.existsSync(skillsDir)) {
|
|
6669
|
+
fs.mkdirSync(skillsDir, { recursive: true });
|
|
6670
|
+
}
|
|
6671
|
+
}
|
|
6672
|
+
// ==========================================================================
|
|
6673
|
+
// Domain-level JSON operations
|
|
6674
|
+
// ==========================================================================
|
|
6675
|
+
/**
|
|
6676
|
+
* Read a domain JSON file and return its entity map.
|
|
6677
|
+
* Uses in-memory cache; reads from disk on first access.
|
|
6678
|
+
*/
|
|
6679
|
+
readDomain(filename) {
|
|
6680
|
+
if (this.cache.has(filename)) {
|
|
6681
|
+
return this.cache.get(filename);
|
|
6682
|
+
}
|
|
6683
|
+
const filePath = path.join(this.dir, filename);
|
|
6684
|
+
let data = {};
|
|
6685
|
+
if (fs.existsSync(filePath)) {
|
|
6686
|
+
try {
|
|
6687
|
+
const raw = fs.readFileSync(filePath, "utf-8");
|
|
6688
|
+
data = JSON.parse(raw, dateReviver);
|
|
6689
|
+
} catch {
|
|
6690
|
+
data = {};
|
|
6691
|
+
}
|
|
6692
|
+
}
|
|
6693
|
+
this.cache.set(filename, data);
|
|
6694
|
+
return data;
|
|
6695
|
+
}
|
|
6696
|
+
/**
|
|
6697
|
+
* Write a domain's full entity map to its JSON file.
|
|
6698
|
+
* Uses atomic write (write to .tmp, then rename) to prevent corruption.
|
|
6699
|
+
*/
|
|
6700
|
+
writeDomain(filename, data) {
|
|
6701
|
+
this.cache.set(filename, data);
|
|
6702
|
+
const filePath = path.join(this.dir, filename);
|
|
6703
|
+
const tmpPath = filePath + ".tmp";
|
|
6704
|
+
const parentDir = path.dirname(filePath);
|
|
6705
|
+
if (!fs.existsSync(parentDir)) {
|
|
6706
|
+
fs.mkdirSync(parentDir, { recursive: true });
|
|
6707
|
+
}
|
|
6708
|
+
fs.writeFileSync(tmpPath, JSON.stringify(data, null, 2), "utf-8");
|
|
6709
|
+
fs.renameSync(tmpPath, filePath);
|
|
6710
|
+
}
|
|
6711
|
+
/**
|
|
6712
|
+
* Clear all data from a domain JSON file.
|
|
6713
|
+
*/
|
|
6714
|
+
clearDomain(filename) {
|
|
6715
|
+
this.writeDomain(filename, {});
|
|
6716
|
+
}
|
|
6717
|
+
/**
|
|
6718
|
+
* Invalidate the in-memory cache for a domain, forcing a re-read from disk on next access.
|
|
6719
|
+
*/
|
|
6720
|
+
invalidateCache(filename) {
|
|
6721
|
+
if (filename) {
|
|
6722
|
+
this.cache.delete(filename);
|
|
6723
|
+
} else {
|
|
6724
|
+
this.cache.clear();
|
|
6725
|
+
}
|
|
6726
|
+
}
|
|
6727
|
+
// ==========================================================================
|
|
6728
|
+
// Entity-level convenience methods (used by FilesystemVersionedHelpers)
|
|
6729
|
+
// ==========================================================================
|
|
6730
|
+
/**
|
|
6731
|
+
* Get a single entity by ID from a domain JSON file.
|
|
6732
|
+
*/
|
|
6733
|
+
get(filename, id) {
|
|
6734
|
+
const data = this.readDomain(filename);
|
|
6735
|
+
return data[id] ?? null;
|
|
6736
|
+
}
|
|
6737
|
+
/**
|
|
6738
|
+
* Get all entities from a domain JSON file as an array.
|
|
6739
|
+
*/
|
|
6740
|
+
getAll(filename) {
|
|
6741
|
+
const data = this.readDomain(filename);
|
|
6742
|
+
return Object.values(data);
|
|
6743
|
+
}
|
|
6744
|
+
/**
|
|
6745
|
+
* Set (create or update) an entity in a domain JSON file.
|
|
6746
|
+
*/
|
|
6747
|
+
set(filename, id, entity) {
|
|
6748
|
+
const data = this.readDomain(filename);
|
|
6749
|
+
data[id] = entity;
|
|
6750
|
+
this.writeDomain(filename, data);
|
|
6751
|
+
}
|
|
6752
|
+
/**
|
|
6753
|
+
* Remove an entity by ID from a domain JSON file. No-op if not found.
|
|
6754
|
+
*/
|
|
6755
|
+
remove(filename, id) {
|
|
6756
|
+
const data = this.readDomain(filename);
|
|
6757
|
+
if (id in data) {
|
|
6758
|
+
delete data[id];
|
|
6759
|
+
this.writeDomain(filename, data);
|
|
6760
|
+
}
|
|
6761
|
+
}
|
|
6762
|
+
// =========================================================================
|
|
6763
|
+
// Skills directory operations (real file tree, not JSON)
|
|
6764
|
+
// =========================================================================
|
|
6765
|
+
/**
|
|
6766
|
+
* Get the path to a skill's directory.
|
|
6767
|
+
*/
|
|
6768
|
+
skillDir(skillName) {
|
|
6769
|
+
const skillsBase = path.join(this.dir, "skills");
|
|
6770
|
+
const dir = path.resolve(skillsBase, skillName);
|
|
6771
|
+
if (!dir.startsWith(skillsBase + path.sep) && dir !== skillsBase) {
|
|
6772
|
+
throw new Error(`Path traversal detected: skill name "${skillName}" escapes skills directory`);
|
|
6773
|
+
}
|
|
6774
|
+
return dir;
|
|
6775
|
+
}
|
|
6776
|
+
/**
|
|
6777
|
+
* Resolve a file path within a skill directory, throwing if it escapes.
|
|
6778
|
+
*/
|
|
6779
|
+
safeSkillPath(skillName, relativePath) {
|
|
6780
|
+
const base = this.skillDir(skillName);
|
|
6781
|
+
const resolved = path.resolve(base, relativePath);
|
|
6782
|
+
if (!resolved.startsWith(base + path.sep) && resolved !== base) {
|
|
6783
|
+
throw new Error(`Path traversal detected: "${relativePath}" escapes skill directory`);
|
|
6784
|
+
}
|
|
6785
|
+
return resolved;
|
|
6786
|
+
}
|
|
6787
|
+
/**
|
|
6788
|
+
* List all files in a skill's directory, returning relative paths.
|
|
6789
|
+
*/
|
|
6790
|
+
listSkillFiles(skillName) {
|
|
6791
|
+
const dir = this.skillDir(skillName);
|
|
6792
|
+
if (!fs.existsSync(dir)) return [];
|
|
6793
|
+
return walkDir(dir).map((abs) => path.relative(dir, abs).split(path.sep).join("/"));
|
|
6794
|
+
}
|
|
6795
|
+
/**
|
|
6796
|
+
* Read a file from a skill's directory.
|
|
6797
|
+
*/
|
|
6798
|
+
readSkillFile(skillName, relativePath) {
|
|
6799
|
+
const filePath = this.safeSkillPath(skillName, relativePath);
|
|
6800
|
+
if (!fs.existsSync(filePath)) return null;
|
|
6801
|
+
try {
|
|
6802
|
+
return fs.readFileSync(filePath);
|
|
6803
|
+
} catch {
|
|
6804
|
+
return null;
|
|
6805
|
+
}
|
|
6806
|
+
}
|
|
6807
|
+
/**
|
|
6808
|
+
* Write a file to a skill's directory.
|
|
6809
|
+
*/
|
|
6810
|
+
writeSkillFile(skillName, relativePath, content) {
|
|
6811
|
+
const filePath = this.safeSkillPath(skillName, relativePath);
|
|
6812
|
+
const parentDir = path.dirname(filePath);
|
|
6813
|
+
if (!fs.existsSync(parentDir)) {
|
|
6814
|
+
fs.mkdirSync(parentDir, { recursive: true });
|
|
6815
|
+
}
|
|
6816
|
+
fs.writeFileSync(filePath, content);
|
|
6817
|
+
}
|
|
6818
|
+
/**
|
|
6819
|
+
* Delete a skill's entire directory.
|
|
6820
|
+
*/
|
|
6821
|
+
deleteSkillDir(skillName) {
|
|
6822
|
+
const dir = this.skillDir(skillName);
|
|
6823
|
+
if (fs.existsSync(dir)) {
|
|
6824
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
6825
|
+
}
|
|
6826
|
+
}
|
|
6827
|
+
};
|
|
6828
|
+
function dateReviver(_key, value) {
|
|
6829
|
+
if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(value)) {
|
|
6830
|
+
const d = new Date(value);
|
|
6831
|
+
if (!isNaN(d.getTime())) return d;
|
|
6832
|
+
}
|
|
6833
|
+
return value;
|
|
6834
|
+
}
|
|
6835
|
+
function walkDir(dir) {
|
|
6836
|
+
const results = [];
|
|
6837
|
+
for (const entry of fs.readdirSync(dir)) {
|
|
6838
|
+
const fullPath = path.join(dir, entry);
|
|
6839
|
+
const stat = fs.statSync(fullPath);
|
|
6840
|
+
if (stat.isDirectory()) {
|
|
6841
|
+
results.push(...walkDir(fullPath));
|
|
6842
|
+
} else {
|
|
6843
|
+
results.push(fullPath);
|
|
6844
|
+
}
|
|
6845
|
+
}
|
|
6846
|
+
return results;
|
|
6847
|
+
}
|
|
6848
|
+
|
|
6849
|
+
// src/storage/filesystem.ts
|
|
6850
|
+
var FilesystemStore = class extends MastraCompositeStore {
|
|
6851
|
+
#db;
|
|
6852
|
+
#dir;
|
|
6853
|
+
constructor(config = {}) {
|
|
6854
|
+
const dir = path.resolve(config.dir ?? ".mastra-storage");
|
|
6855
|
+
super({ id: "filesystem", name: "FilesystemStore" });
|
|
6856
|
+
this.#dir = dir;
|
|
6857
|
+
this.#db = new FilesystemDB(dir);
|
|
6858
|
+
this.stores = {
|
|
6859
|
+
agents: new FilesystemAgentsStorage({ db: this.#db }),
|
|
6860
|
+
promptBlocks: new FilesystemPromptBlocksStorage({ db: this.#db }),
|
|
6861
|
+
scorerDefinitions: new FilesystemScorerDefinitionsStorage({ db: this.#db }),
|
|
6862
|
+
mcpClients: new FilesystemMCPClientsStorage({ db: this.#db }),
|
|
6863
|
+
mcpServers: new FilesystemMCPServersStorage({ db: this.#db }),
|
|
6864
|
+
workspaces: new FilesystemWorkspacesStorage({ db: this.#db }),
|
|
6865
|
+
skills: new FilesystemSkillsStorage({ db: this.#db })
|
|
6866
|
+
};
|
|
6867
|
+
}
|
|
6868
|
+
/**
|
|
6869
|
+
* The absolute path to the storage directory.
|
|
6870
|
+
*/
|
|
6871
|
+
get dir() {
|
|
6872
|
+
return this.#dir;
|
|
6873
|
+
}
|
|
6874
|
+
};
|
|
5351
6875
|
|
|
5352
6876
|
// src/storage/domains/operations/base.ts
|
|
5353
6877
|
var StoreOperations = class extends chunkRO47SMI7_cjs.MastraBase {
|
|
@@ -5497,7 +7021,7 @@ var StoreOperationsInMemory = class extends StoreOperations {
|
|
|
5497
7021
|
async insert({ tableName, record }) {
|
|
5498
7022
|
const table = this.data[tableName];
|
|
5499
7023
|
let key = record.id;
|
|
5500
|
-
if ([
|
|
7024
|
+
if ([chunkHH76UOJL_cjs.TABLE_WORKFLOW_SNAPSHOT].includes(tableName) && !record.id && record.run_id) {
|
|
5501
7025
|
key = record.workflow_name ? `${record.workflow_name}-${record.run_id}` : record.run_id;
|
|
5502
7026
|
record.id = key;
|
|
5503
7027
|
} else if (!record.id) {
|
|
@@ -5510,7 +7034,7 @@ var StoreOperationsInMemory = class extends StoreOperations {
|
|
|
5510
7034
|
const table = this.data[tableName];
|
|
5511
7035
|
for (const record of records) {
|
|
5512
7036
|
let key = record.id;
|
|
5513
|
-
if ([
|
|
7037
|
+
if ([chunkHH76UOJL_cjs.TABLE_WORKFLOW_SNAPSHOT].includes(tableName) && !record.id && record.run_id) {
|
|
5514
7038
|
key = record.run_id;
|
|
5515
7039
|
record.id = key;
|
|
5516
7040
|
} else if (!record.id) {
|
|
@@ -5557,8 +7081,20 @@ exports.AgentsStorage = AgentsStorage;
|
|
|
5557
7081
|
exports.BlobStore = BlobStore;
|
|
5558
7082
|
exports.DatasetsInMemory = DatasetsInMemory;
|
|
5559
7083
|
exports.DatasetsStorage = DatasetsStorage;
|
|
7084
|
+
exports.EDITOR_DOMAINS = EDITOR_DOMAINS;
|
|
5560
7085
|
exports.ExperimentsInMemory = ExperimentsInMemory;
|
|
5561
7086
|
exports.ExperimentsStorage = ExperimentsStorage;
|
|
7087
|
+
exports.FilesystemAgentsStorage = FilesystemAgentsStorage;
|
|
7088
|
+
exports.FilesystemDB = FilesystemDB;
|
|
7089
|
+
exports.FilesystemMCPClientsStorage = FilesystemMCPClientsStorage;
|
|
7090
|
+
exports.FilesystemMCPServersStorage = FilesystemMCPServersStorage;
|
|
7091
|
+
exports.FilesystemPromptBlocksStorage = FilesystemPromptBlocksStorage;
|
|
7092
|
+
exports.FilesystemScorerDefinitionsStorage = FilesystemScorerDefinitionsStorage;
|
|
7093
|
+
exports.FilesystemSkillsStorage = FilesystemSkillsStorage;
|
|
7094
|
+
exports.FilesystemStore = FilesystemStore;
|
|
7095
|
+
exports.FilesystemVersionedHelpers = FilesystemVersionedHelpers;
|
|
7096
|
+
exports.FilesystemWorkspacesStorage = FilesystemWorkspacesStorage;
|
|
7097
|
+
exports.GitHistory = GitHistory;
|
|
5562
7098
|
exports.InMemoryAgentsStorage = InMemoryAgentsStorage;
|
|
5563
7099
|
exports.InMemoryBlobStore = InMemoryBlobStore;
|
|
5564
7100
|
exports.InMemoryDB = InMemoryDB;
|
|
@@ -5610,5 +7146,5 @@ exports.safelyParseJSON = safelyParseJSON;
|
|
|
5610
7146
|
exports.serializeDate = serializeDate;
|
|
5611
7147
|
exports.transformRow = transformRow;
|
|
5612
7148
|
exports.transformScoreRow = transformScoreRow;
|
|
5613
|
-
//# sourceMappingURL=chunk-
|
|
5614
|
-
//# sourceMappingURL=chunk-
|
|
7149
|
+
//# sourceMappingURL=chunk-7AHCLTZZ.cjs.map
|
|
7150
|
+
//# sourceMappingURL=chunk-7AHCLTZZ.cjs.map
|