@evalops/maestro 0.10.23 → 0.10.25
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/README.md +4 -4
- package/dist/agent/agent.d.ts +2 -2
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +1 -1
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/keys.d.ts +2 -5
- package/dist/agent/keys.d.ts.map +1 -1
- package/dist/agent/keys.js +4 -5
- package/dist/agent/keys.js.map +1 -1
- package/dist/agent/modes.d.ts +2 -2
- package/dist/agent/modes.d.ts.map +1 -1
- package/dist/agent/modes.js +6 -7
- package/dist/agent/modes.js.map +1 -1
- package/dist/agent/providers/anthropic.d.ts.map +1 -1
- package/dist/agent/providers/anthropic.js +4 -4
- package/dist/agent/providers/anthropic.js.map +1 -1
- package/dist/agent/providers/google.js +1 -1
- package/dist/agent/swarm/executor.d.ts +2 -0
- package/dist/agent/swarm/executor.d.ts.map +1 -1
- package/dist/agent/swarm/executor.js +208 -35
- package/dist/agent/swarm/executor.js.map +1 -1
- package/dist/agent/swarm/types.d.ts +2 -0
- package/dist/agent/swarm/types.d.ts.map +1 -1
- package/dist/agent/swarm/types.js.map +1 -1
- package/dist/agent/tool-capability-types.d.ts +36 -0
- package/dist/agent/tool-capability-types.d.ts.map +1 -0
- package/dist/agent/tool-capability-types.js +2 -0
- package/dist/agent/tool-capability-types.js.map +1 -0
- package/dist/agent/transport/tool-execution-bridge.d.ts +13 -0
- package/dist/agent/transport/tool-execution-bridge.d.ts.map +1 -1
- package/dist/agent/transport/tool-execution-bridge.js +28 -15
- package/dist/agent/transport/tool-execution-bridge.js.map +1 -1
- package/dist/agent/transport/transport-utils.d.ts.map +1 -1
- package/dist/agent/transport/transport-utils.js +2 -3
- package/dist/agent/transport/transport-utils.js.map +1 -1
- package/dist/agent/transport.js +1 -1
- package/dist/agent/transport.js.map +1 -1
- package/dist/agent/type-guards.d.ts +1 -1
- package/dist/agent/type-guards.js +1 -1
- package/dist/agent/type-guards.js.map +1 -1
- package/dist/agent/types.d.ts +5 -3
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js +2 -2
- package/dist/agent/types.js.map +1 -1
- package/dist/app-server/daemon-lifecycle-api.d.ts +31 -0
- package/dist/app-server/daemon-lifecycle-api.d.ts.map +1 -0
- package/dist/app-server/daemon-lifecycle-api.js +259 -0
- package/dist/app-server/daemon-lifecycle-api.js.map +1 -0
- package/dist/app-server/external-agent-import-api.d.ts +30 -0
- package/dist/app-server/external-agent-import-api.d.ts.map +1 -0
- package/dist/app-server/external-agent-import-api.js +553 -0
- package/dist/app-server/external-agent-import-api.js.map +1 -0
- package/dist/app-server/host-control-api.d.ts +30 -0
- package/dist/app-server/host-control-api.d.ts.map +1 -0
- package/dist/app-server/host-control-api.js +343 -0
- package/dist/app-server/host-control-api.js.map +1 -0
- package/dist/app-server/in-process-client.d.ts +2 -2
- package/dist/app-server/in-process-client.d.ts.map +1 -1
- package/dist/app-server/in-process-client.js.map +1 -1
- package/dist/app-server/network-governance-api.d.ts +26 -0
- package/dist/app-server/network-governance-api.d.ts.map +1 -0
- package/dist/app-server/network-governance-api.js +476 -0
- package/dist/app-server/network-governance-api.js.map +1 -0
- package/dist/app-server/plugin-bundle-api.d.ts +17 -0
- package/dist/app-server/plugin-bundle-api.d.ts.map +1 -0
- package/dist/app-server/plugin-bundle-api.js +219 -0
- package/dist/app-server/plugin-bundle-api.js.map +1 -0
- package/dist/app-server/policy-control-api.d.ts +14 -0
- package/dist/app-server/policy-control-api.d.ts.map +1 -0
- package/dist/app-server/policy-control-api.js +200 -0
- package/dist/app-server/policy-control-api.js.map +1 -0
- package/dist/app-server/protocol-modes-api.d.ts +22 -0
- package/dist/app-server/protocol-modes-api.d.ts.map +1 -0
- package/dist/app-server/protocol-modes-api.js +124 -0
- package/dist/app-server/protocol-modes-api.js.map +1 -0
- package/dist/app-server/sandbox-proof-api.d.ts +21 -0
- package/dist/app-server/sandbox-proof-api.d.ts.map +1 -0
- package/dist/app-server/sandbox-proof-api.js +127 -0
- package/dist/app-server/sandbox-proof-api.js.map +1 -0
- package/dist/app-server/session-api.d.ts +93 -3
- package/dist/app-server/session-api.d.ts.map +1 -1
- package/dist/app-server/session-api.js +706 -18
- package/dist/app-server/session-api.js.map +1 -1
- package/dist/audit/logger.d.ts +1 -1
- package/dist/bootstrap/auth-setup.d.ts.map +1 -1
- package/dist/bootstrap/auth-setup.js +17 -2
- package/dist/bootstrap/auth-setup.js.map +1 -1
- package/dist/bootstrap/model-resolution-setup.d.ts.map +1 -1
- package/dist/bootstrap/model-resolution-setup.js +19 -4
- package/dist/bootstrap/model-resolution-setup.js.map +1 -1
- package/dist/cli/args.d.ts +2 -2
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +2 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/commands/a2a.d.ts.map +1 -1
- package/dist/cli/commands/a2a.js +226 -14
- package/dist/cli/commands/a2a.js.map +1 -1
- package/dist/cli/commands/anthropic.d.ts +1 -1
- package/dist/cli/commands/anthropic.d.ts.map +1 -1
- package/dist/cli/commands/anthropic.js +3 -68
- package/dist/cli/commands/anthropic.js.map +1 -1
- package/dist/cli/commands/modes.js +1 -1
- package/dist/cli/commands/modes.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +5 -7
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/rpc-mode.d.ts +1 -1
- package/dist/cli/rpc-mode.js +1 -1
- package/dist/cli/rpc-mode.js.map +1 -1
- package/dist/cli/session.js +1 -1
- package/dist/cli/session.js.map +1 -1
- package/dist/cli-tui/commands/command-catalog.d.ts.map +1 -1
- package/dist/cli-tui/commands/command-catalog.js +7 -12
- package/dist/cli-tui/commands/command-catalog.js.map +1 -1
- package/dist/cli-tui/commands/subcommands/auth-commands.d.ts +1 -1
- package/dist/cli-tui/commands/subcommands/auth-commands.d.ts.map +1 -1
- package/dist/cli-tui/commands/subcommands/auth-commands.js +4 -12
- package/dist/cli-tui/commands/subcommands/auth-commands.js.map +1 -1
- package/dist/cli-tui/custom-editor.d.ts +1 -1
- package/dist/cli-tui/custom-editor.js +2 -2
- package/dist/cli-tui/custom-editor.js.map +1 -1
- package/dist/cli-tui/oauth/oauth-flow-controller.d.ts.map +1 -1
- package/dist/cli-tui/oauth/oauth-flow-controller.js +19 -23
- package/dist/cli-tui/oauth/oauth-flow-controller.js.map +1 -1
- package/dist/cli-tui/selectors/model-selector.d.ts.map +1 -1
- package/dist/cli-tui/selectors/model-selector.js +0 -1
- package/dist/cli-tui/selectors/model-selector.js.map +1 -1
- package/dist/cli-tui/selectors/oauth-selector-view.d.ts +2 -2
- package/dist/cli-tui/selectors/oauth-selector-view.d.ts.map +1 -1
- package/dist/cli-tui/selectors/oauth-selector-view.js.map +1 -1
- package/dist/cli-tui/selectors/oauth-selector.d.ts +2 -2
- package/dist/cli-tui/selectors/oauth-selector.d.ts.map +1 -1
- package/dist/cli-tui/selectors/oauth-selector.js +3 -4
- package/dist/cli-tui/selectors/oauth-selector.js.map +1 -1
- package/dist/cli-tui/tui-renderer/mcp-events-setup.js +1 -1
- package/dist/cli-tui/tui-renderer/mcp-events-setup.js.map +1 -1
- package/dist/cli-tui/tui-renderer.js +2 -2
- package/dist/cli-tui/tui-renderer.js.map +1 -1
- package/dist/cli-tui/utils/footer-utils.d.ts +1 -1
- package/dist/cli-tui/utils/footer-utils.js +1 -1
- package/dist/cli-tui/utils/footer-utils.js.map +1 -1
- package/dist/cli.js +15156 -14232
- package/dist/commands/prompts.d.ts +1 -1
- package/dist/commands/prompts.js +1 -1
- package/dist/commands/prompts.js.map +1 -1
- package/dist/config/constants.d.ts +2 -2
- package/dist/config/constants.d.ts.map +1 -1
- package/dist/config/constants.js +2 -2
- package/dist/config/constants.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.js +1 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/toml-config.js +3 -3
- package/dist/config/toml-config.js.map +1 -1
- package/dist/db/client.d.ts +2 -2
- package/dist/db/client.js +2 -2
- package/dist/db/client.js.map +1 -1
- package/dist/db/migrate.d.ts +1 -1
- package/dist/db/migrate.js +1 -1
- package/dist/db/migrate.js.map +1 -1
- package/dist/db/schema.d.ts +2 -2
- package/dist/db/schema.js +1 -1
- package/dist/db/schema.js.map +1 -1
- package/dist/errors/index.d.ts +2 -2
- package/dist/errors/index.js +2 -2
- package/dist/errors/index.js.map +1 -1
- package/dist/main.d.ts +4 -5
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +17 -14
- package/dist/main.js.map +1 -1
- package/dist/mcp/config.d.ts +15 -2
- package/dist/mcp/config.d.ts.map +1 -1
- package/dist/mcp/config.js +50 -26
- package/dist/mcp/config.js.map +1 -1
- package/dist/mcp/fathom-cua.d.ts.map +1 -1
- package/dist/mcp/fathom-cua.js +10 -0
- package/dist/mcp/fathom-cua.js.map +1 -1
- package/dist/mcp/manager.d.ts.map +1 -1
- package/dist/mcp/manager.js +32 -1
- package/dist/mcp/manager.js.map +1 -1
- package/dist/mcp/tool-bridge.d.ts.map +1 -1
- package/dist/mcp/tool-bridge.js +12 -3
- package/dist/mcp/tool-bridge.js.map +1 -1
- package/dist/mcp/tool-capabilities.d.ts +5 -0
- package/dist/mcp/tool-capabilities.d.ts.map +1 -0
- package/dist/mcp/tool-capabilities.js +271 -0
- package/dist/mcp/tool-capabilities.js.map +1 -0
- package/dist/mcp/types.d.ts +6 -1
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/mcp/types.js.map +1 -1
- package/dist/models/config-loader.d.ts +1 -1
- package/dist/models/factory-integration.d.ts +1 -1
- package/dist/models/factory-integration.js +1 -1
- package/dist/models/factory-integration.js.map +1 -1
- package/dist/node_modules/@evalops/contracts/dist/index.d.ts +3 -3
- package/dist/node_modules/@evalops/contracts/dist/index.js +2 -2
- package/dist/node_modules/@evalops/contracts/dist/index.js.map +1 -1
- package/dist/node_modules/@evalops/contracts/dist/maestro-app-server.d.ts +1182 -14
- package/dist/node_modules/@evalops/contracts/dist/maestro-app-server.d.ts.map +1 -1
- package/dist/node_modules/@evalops/contracts/dist/maestro-app-server.js +450 -1
- package/dist/node_modules/@evalops/contracts/dist/maestro-app-server.js.map +1 -1
- package/dist/node_modules/@evalops/contracts/package.json +1 -1
- package/dist/node_modules/@evalops/tui/package.json +1 -1
- package/dist/oauth/connectors.d.ts +2 -2
- package/dist/oauth/connectors.d.ts.map +1 -1
- package/dist/oauth/connectors.js +3 -5
- package/dist/oauth/connectors.js.map +1 -1
- package/dist/oauth/github-copilot.d.ts +1 -1
- package/dist/oauth/github-copilot.js +1 -1
- package/dist/oauth/github-copilot.js.map +1 -1
- package/dist/oauth/index.d.ts +10 -8
- package/dist/oauth/index.d.ts.map +1 -1
- package/dist/oauth/index.js +54 -31
- package/dist/oauth/index.js.map +1 -1
- package/dist/oauth/openai.d.ts +1 -1
- package/dist/oauth/openai.js +2 -2
- package/dist/oauth/openai.js.map +1 -1
- package/dist/platform/a2a-completion-audit.d.ts +41 -0
- package/dist/platform/a2a-completion-audit.d.ts.map +1 -0
- package/dist/platform/a2a-completion-audit.js +177 -0
- package/dist/platform/a2a-completion-audit.js.map +1 -0
- package/dist/platform/a2a-task-ledger.d.ts.map +1 -1
- package/dist/platform/a2a-task-ledger.js +17 -0
- package/dist/platform/a2a-task-ledger.js.map +1 -1
- package/dist/platform/a2a-telemetry-inspect.d.ts +58 -0
- package/dist/platform/a2a-telemetry-inspect.d.ts.map +1 -0
- package/dist/platform/a2a-telemetry-inspect.js +224 -0
- package/dist/platform/a2a-telemetry-inspect.js.map +1 -0
- package/dist/platform/agent-registry-client.d.ts +8 -0
- package/dist/platform/agent-registry-client.d.ts.map +1 -1
- package/dist/platform/agent-registry-client.js +9 -1
- package/dist/platform/agent-registry-client.js.map +1 -1
- package/dist/providers/api-keys.d.ts +2 -2
- package/dist/providers/api-keys.js +2 -2
- package/dist/providers/api-keys.js.map +1 -1
- package/dist/providers/auth.d.ts +3 -6
- package/dist/providers/auth.d.ts.map +1 -1
- package/dist/providers/auth.js +1 -40
- package/dist/providers/auth.js.map +1 -1
- package/dist/rpc/index.d.ts +2 -2
- package/dist/rpc/index.js +2 -2
- package/dist/rpc/index.js.map +1 -1
- package/dist/rpc/rpc-types.d.ts +1 -1
- package/dist/rpc/rpc-types.js +1 -1
- package/dist/rpc/rpc-types.js.map +1 -1
- package/dist/safety/nested-agent-guard.js +1 -1
- package/dist/safety/nested-agent-guard.js.map +1 -1
- package/dist/safety/policy.d.ts +2 -2
- package/dist/safety/policy.js +2 -2
- package/dist/safety/policy.js.map +1 -1
- package/dist/safety/validators/network-policy-validator.d.ts +8 -0
- package/dist/safety/validators/network-policy-validator.d.ts.map +1 -1
- package/dist/safety/validators/network-policy-validator.js +29 -4
- package/dist/safety/validators/network-policy-validator.js.map +1 -1
- package/dist/sandbox/local-sandbox.d.ts +1 -1
- package/dist/sandbox/local-sandbox.js +1 -1
- package/dist/sandbox/local-sandbox.js.map +1 -1
- package/dist/server/app-context.d.ts +2 -0
- package/dist/server/app-context.d.ts.map +1 -1
- package/dist/server/app-context.js.map +1 -1
- package/dist/server/handlers/attachments.d.ts.map +1 -1
- package/dist/server/handlers/attachments.js +1 -0
- package/dist/server/handlers/attachments.js.map +1 -1
- package/dist/server/handlers/models.d.ts.map +1 -1
- package/dist/server/handlers/models.js +3 -1
- package/dist/server/handlers/models.js.map +1 -1
- package/dist/server/handlers/session-attachments.d.ts.map +1 -1
- package/dist/server/handlers/session-attachments.js +2 -0
- package/dist/server/handlers/session-attachments.js.map +1 -1
- package/dist/server/handlers/sessions.js +1 -1
- package/dist/server/handlers/sessions.js.map +1 -1
- package/dist/server/handlers/status.d.ts +2 -0
- package/dist/server/handlers/status.d.ts.map +1 -1
- package/dist/server/handlers/status.js +3 -2
- package/dist/server/handlers/status.js.map +1 -1
- package/dist/server/headless-runtime-service.d.ts.map +1 -1
- package/dist/server/headless-runtime-service.js +32 -3
- package/dist/server/headless-runtime-service.js.map +1 -1
- package/dist/server/hosted-session-manager.d.ts +2 -0
- package/dist/server/hosted-session-manager.d.ts.map +1 -1
- package/dist/server/hosted-session-manager.js +9 -0
- package/dist/server/hosted-session-manager.js.map +1 -1
- package/dist/server/model-selection.d.ts.map +1 -1
- package/dist/server/model-selection.js +9 -1
- package/dist/server/model-selection.js.map +1 -1
- package/dist/server/rate-limiter.d.ts +1 -1
- package/dist/server/rate-limiter.js +1 -1
- package/dist/server/rate-limiter.js.map +1 -1
- package/dist/server/router.d.ts +2 -2
- package/dist/server/router.js.map +1 -1
- package/dist/server/session-serialization.d.ts +9 -9
- package/dist/server/session-serialization.js +15 -15
- package/dist/server/session-serialization.js.map +1 -1
- package/dist/session/manager.d.ts +5 -0
- package/dist/session/manager.d.ts.map +1 -1
- package/dist/session/manager.js +56 -8
- package/dist/session/manager.js.map +1 -1
- package/dist/session/session-catalog.d.ts +2 -0
- package/dist/session/session-catalog.d.ts.map +1 -1
- package/dist/session/session-catalog.js +6 -0
- package/dist/session/session-catalog.js.map +1 -1
- package/dist/session/session-context.d.ts +2 -0
- package/dist/session/session-context.d.ts.map +1 -1
- package/dist/session/session-context.js +15 -0
- package/dist/session/session-context.js.map +1 -1
- package/dist/session/types.d.ts +7 -0
- package/dist/session/types.d.ts.map +1 -1
- package/dist/session/types.js.map +1 -1
- package/dist/session/wire-format.generated.d.ts +1 -0
- package/dist/session/wire-format.generated.d.ts.map +1 -1
- package/dist/session/wire-format.generated.js +1 -0
- package/dist/session/wire-format.generated.js.map +1 -1
- package/dist/shared-memory/contract.d.ts +4 -4
- package/dist/shared-memory/contract.js +2 -2
- package/dist/shared-memory/contract.js.map +1 -1
- package/dist/telemetry/index.d.ts +2 -2
- package/dist/telemetry/index.d.ts.map +1 -1
- package/dist/telemetry/index.js +2 -2
- package/dist/telemetry/index.js.map +1 -1
- package/dist/telemetry/maestro-event-bus.d.ts +57 -0
- package/dist/telemetry/maestro-event-bus.d.ts.map +1 -1
- package/dist/telemetry/maestro-event-bus.js +59 -1
- package/dist/telemetry/maestro-event-bus.js.map +1 -1
- package/dist/telemetry/maestro-event-catalog.d.ts +17 -1
- package/dist/telemetry/maestro-event-catalog.d.ts.map +1 -1
- package/dist/telemetry/maestro-event-catalog.js +24 -0
- package/dist/telemetry/maestro-event-catalog.js.map +1 -1
- package/dist/telemetry/mcp-beacon.d.ts +2 -0
- package/dist/telemetry/mcp-beacon.d.ts.map +1 -1
- package/dist/telemetry/mcp-beacon.js +15 -0
- package/dist/telemetry/mcp-beacon.js.map +1 -1
- package/dist/telemetry/metrics.d.ts +62 -0
- package/dist/telemetry/metrics.d.ts.map +1 -1
- package/dist/telemetry/metrics.js +84 -0
- package/dist/telemetry/metrics.js.map +1 -1
- package/dist/telemetry.d.ts +44 -0
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +84 -2
- package/dist/telemetry.js.map +1 -1
- package/dist/theme/theme-loader.js +2 -2
- package/dist/theme/theme-loader.js.map +1 -1
- package/dist/theme/theme-schema.json +2 -2
- package/dist/theme/theme.d.ts +1 -1
- package/dist/theme/theme.js.map +1 -1
- package/dist/tools/background/task-types.d.ts +1 -1
- package/dist/tools/extract-document.d.ts +1 -0
- package/dist/tools/extract-document.d.ts.map +1 -1
- package/dist/tools/extract-document.js +2 -1
- package/dist/tools/extract-document.js.map +1 -1
- package/dist/tools/index.d.ts +55 -55
- package/dist/tools/index.js +1 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/tool-dsl.d.ts +1 -1
- package/dist/tools/tool-dsl.js +1 -1
- package/dist/tools/tool-dsl.js.map +1 -1
- package/dist/utils/document-extractor.d.ts +1 -0
- package/dist/utils/document-extractor.d.ts.map +1 -1
- package/dist/utils/document-extractor.js +320 -40
- package/dist/utils/document-extractor.js.map +1 -1
- package/dist/utils/logger.d.ts +1 -1
- package/dist/utils/logger.js +1 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/version.json +2 -2
- package/dist/web-server.d.ts +1 -1
- package/dist/web-server.d.ts.map +1 -1
- package/dist/web-server.js +12 -8
- package/dist/web-server.js.map +1 -1
- package/package.json +4 -2
- package/dist/oauth/anthropic.d.ts +0 -17
- package/dist/oauth/anthropic.d.ts.map +0 -1
- package/dist/oauth/anthropic.js +0 -81
- package/dist/oauth/anthropic.js.map +0 -1
- package/dist/providers/anthropic-auth.d.ts +0 -75
- package/dist/providers/anthropic-auth.d.ts.map +0 -1
- package/dist/providers/anthropic-auth.js +0 -221
- package/dist/providers/anthropic-auth.js.map +0 -1
|
@@ -0,0 +1,553 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
import { existsSync, mkdirSync, mkdtempSync, readFileSync, renameSync, rmSync, statSync, writeFileSync, } from "node:fs";
|
|
3
|
+
import { dirname, extname, join, posix, resolve, win32 } from "node:path";
|
|
4
|
+
import { parse as parseTOML, stringify as stringifyTOML } from "smol-toml";
|
|
5
|
+
import { PATHS } from "../config/constants.js";
|
|
6
|
+
import { getWritablePackageConfigPath } from "../config/toml-config.js";
|
|
7
|
+
import { clearConfigCache } from "../config/toml-config.js";
|
|
8
|
+
import { getProjectHooksConfigPath, getUserHooksConfigPath, } from "../hooks/config.js";
|
|
9
|
+
import { addMcpServersToConfig, inferRemoteMcpTransport, validateMcpServersForConfig, } from "../mcp/config.js";
|
|
10
|
+
import { mcpServerSchema } from "../mcp/schema.js";
|
|
11
|
+
import { normalizeSessionEntry, tryParseSessionEntry, } from "../session/types.js";
|
|
12
|
+
const PORTABLE_SESSION_EXPORT_FORMAT = "maestro-session-export.v1";
|
|
13
|
+
export class MaestroAppServerExternalAgentImportError extends Error {
|
|
14
|
+
constructor(code, message) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.code = code;
|
|
17
|
+
this.name = "MaestroAppServerExternalAgentImportError";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function isRecord(value) {
|
|
21
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22
|
+
}
|
|
23
|
+
function stringValue(value) {
|
|
24
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
25
|
+
}
|
|
26
|
+
function booleanValue(value, fallback) {
|
|
27
|
+
return typeof value === "boolean" ? value : fallback;
|
|
28
|
+
}
|
|
29
|
+
export function normalizeExternalAgentImportParams(value) {
|
|
30
|
+
if (value === undefined || value === null) {
|
|
31
|
+
return {};
|
|
32
|
+
}
|
|
33
|
+
if (!isRecord(value)) {
|
|
34
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Invalid params");
|
|
35
|
+
}
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
function artifactScope(artifact, fallback) {
|
|
39
|
+
const scope = stringValue(artifact.scope);
|
|
40
|
+
if (scope === "project" || scope === "local" || scope === "user") {
|
|
41
|
+
return scope;
|
|
42
|
+
}
|
|
43
|
+
return fallback;
|
|
44
|
+
}
|
|
45
|
+
function requireArtifacts(params) {
|
|
46
|
+
const artifacts = params.artifacts;
|
|
47
|
+
if (!Array.isArray(artifacts)) {
|
|
48
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "External agent import requires artifacts");
|
|
49
|
+
}
|
|
50
|
+
if (artifacts.some((artifact) => !isRecord(artifact))) {
|
|
51
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "External agent import artifacts must be objects");
|
|
52
|
+
}
|
|
53
|
+
return artifacts;
|
|
54
|
+
}
|
|
55
|
+
function importSource(params) {
|
|
56
|
+
const source = isRecord(params.source) ? params.source : {};
|
|
57
|
+
return {
|
|
58
|
+
name: stringValue(source.name) ?? "external-agent",
|
|
59
|
+
type: stringValue(source.type),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function safeSkillName(value) {
|
|
63
|
+
const name = stringValue(value);
|
|
64
|
+
if (!name || !/^[a-z0-9][a-z0-9_-]{0,63}$/.test(name)) {
|
|
65
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Skill artifact requires a safe skill name");
|
|
66
|
+
}
|
|
67
|
+
return name;
|
|
68
|
+
}
|
|
69
|
+
function safeRelativePath(value) {
|
|
70
|
+
const relativePath = stringValue(value);
|
|
71
|
+
if (!relativePath) {
|
|
72
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Imported file requires a relative path");
|
|
73
|
+
}
|
|
74
|
+
const slashPath = relativePath.replaceAll("\\", "/");
|
|
75
|
+
const normalized = posix.normalize(slashPath);
|
|
76
|
+
const winNormalized = win32.normalize(relativePath);
|
|
77
|
+
if (posix.isAbsolute(normalized) ||
|
|
78
|
+
win32.isAbsolute(relativePath) ||
|
|
79
|
+
/^[A-Za-z]:/.test(relativePath) ||
|
|
80
|
+
normalized === ".." ||
|
|
81
|
+
normalized.startsWith("../") ||
|
|
82
|
+
normalized.includes("/../") ||
|
|
83
|
+
winNormalized === ".." ||
|
|
84
|
+
winNormalized.startsWith("..\\") ||
|
|
85
|
+
winNormalized.includes("\\..\\")) {
|
|
86
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Imported file path must stay inside its target directory");
|
|
87
|
+
}
|
|
88
|
+
return normalized;
|
|
89
|
+
}
|
|
90
|
+
function artifactMessage(error) {
|
|
91
|
+
return error instanceof Error ? error.message : String(error);
|
|
92
|
+
}
|
|
93
|
+
function hasOwn(record, key) {
|
|
94
|
+
return Object.prototype.hasOwnProperty.call(record, key);
|
|
95
|
+
}
|
|
96
|
+
function readJsonObject(path) {
|
|
97
|
+
if (!existsSync(path)) {
|
|
98
|
+
return {};
|
|
99
|
+
}
|
|
100
|
+
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
101
|
+
return isRecord(parsed) ? parsed : {};
|
|
102
|
+
}
|
|
103
|
+
function writeJsonObject(path, value) {
|
|
104
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
105
|
+
writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`, "utf8");
|
|
106
|
+
}
|
|
107
|
+
function mergeRecords(base, incoming) {
|
|
108
|
+
const merged = { ...base };
|
|
109
|
+
for (const [key, value] of Object.entries(incoming)) {
|
|
110
|
+
const current = merged[key];
|
|
111
|
+
if (isRecord(current) && isRecord(value)) {
|
|
112
|
+
merged[key] = mergeRecords(current, value);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
merged[key] = value;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return merged;
|
|
119
|
+
}
|
|
120
|
+
function configContent(artifact) {
|
|
121
|
+
if (isRecord(artifact.values)) {
|
|
122
|
+
return artifact.values;
|
|
123
|
+
}
|
|
124
|
+
const content = stringValue(artifact.content);
|
|
125
|
+
if (!content) {
|
|
126
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Config artifact requires values or TOML content");
|
|
127
|
+
}
|
|
128
|
+
const parsed = parseTOML(content);
|
|
129
|
+
if (!isRecord(parsed)) {
|
|
130
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Config TOML must parse to an object");
|
|
131
|
+
}
|
|
132
|
+
return parsed;
|
|
133
|
+
}
|
|
134
|
+
function writeConfigImport(artifact, projectRoot, dryRun) {
|
|
135
|
+
const scope = artifactScope(artifact, "local");
|
|
136
|
+
const path = getWritablePackageConfigPath(scope, projectRoot);
|
|
137
|
+
const incoming = configContent(artifact);
|
|
138
|
+
const existing = existsSync(path)
|
|
139
|
+
? parseTOML(readFileSync(path, "utf8"))
|
|
140
|
+
: {};
|
|
141
|
+
const merged = mergeRecords(isRecord(existing) ? existing : {}, incoming);
|
|
142
|
+
if (!dryRun) {
|
|
143
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
144
|
+
const rendered = stringifyTOML(merged).trim();
|
|
145
|
+
writeFileSync(path, rendered ? `${rendered}\n` : "", "utf8");
|
|
146
|
+
clearConfigCache();
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
kind: "config",
|
|
150
|
+
status: dryRun ? "planned" : "imported",
|
|
151
|
+
scope,
|
|
152
|
+
path,
|
|
153
|
+
message: dryRun ? "Config TOML merge planned" : "Config TOML merged",
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function hooksContent(artifact) {
|
|
157
|
+
if (isRecord(artifact.config)) {
|
|
158
|
+
return artifact.config;
|
|
159
|
+
}
|
|
160
|
+
if (isRecord(artifact.hooks)) {
|
|
161
|
+
return { hooks: artifact.hooks };
|
|
162
|
+
}
|
|
163
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Hooks artifact requires config or hooks");
|
|
164
|
+
}
|
|
165
|
+
function mergeHooksConfig(existing, incoming) {
|
|
166
|
+
const existingHooks = isRecord(existing.hooks) ? existing.hooks : {};
|
|
167
|
+
const incomingHooks = isRecord(incoming.hooks) ? incoming.hooks : {};
|
|
168
|
+
const hooks = { ...existingHooks };
|
|
169
|
+
for (const [eventType, matchers] of Object.entries(incomingHooks)) {
|
|
170
|
+
hooks[eventType] = [
|
|
171
|
+
...(Array.isArray(existingHooks[eventType])
|
|
172
|
+
? existingHooks[eventType]
|
|
173
|
+
: []),
|
|
174
|
+
...(Array.isArray(matchers) ? matchers : []),
|
|
175
|
+
];
|
|
176
|
+
}
|
|
177
|
+
return mergeRecords(mergeRecords(existing, incoming), { hooks });
|
|
178
|
+
}
|
|
179
|
+
function hooksConfigPath(scope, projectRoot) {
|
|
180
|
+
if (scope === "user") {
|
|
181
|
+
return getUserHooksConfigPath();
|
|
182
|
+
}
|
|
183
|
+
if (scope === "local") {
|
|
184
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Hooks artifact does not support local scope");
|
|
185
|
+
}
|
|
186
|
+
return getProjectHooksConfigPath(projectRoot);
|
|
187
|
+
}
|
|
188
|
+
function writeHooksImport(artifact, projectRoot, dryRun) {
|
|
189
|
+
const scope = artifactScope(artifact, "project");
|
|
190
|
+
const path = hooksConfigPath(scope, projectRoot);
|
|
191
|
+
const incoming = hooksContent(artifact);
|
|
192
|
+
const existing = readJsonObject(path);
|
|
193
|
+
if (!dryRun) {
|
|
194
|
+
writeJsonObject(path, mergeHooksConfig(existing, incoming));
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
kind: "hooks",
|
|
198
|
+
status: dryRun ? "planned" : "imported",
|
|
199
|
+
scope,
|
|
200
|
+
path,
|
|
201
|
+
message: dryRun ? "Hooks config merge planned" : "Hooks config merged",
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function mcpServers(artifact) {
|
|
205
|
+
if (Array.isArray(artifact.servers)) {
|
|
206
|
+
if (!artifact.servers.every(isRecord)) {
|
|
207
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "MCP artifact servers must be objects");
|
|
208
|
+
}
|
|
209
|
+
return artifact.servers;
|
|
210
|
+
}
|
|
211
|
+
if (hasOwn(artifact, "server")) {
|
|
212
|
+
if (!isRecord(artifact.server)) {
|
|
213
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "MCP artifact server must be an object");
|
|
214
|
+
}
|
|
215
|
+
return [artifact.server];
|
|
216
|
+
}
|
|
217
|
+
return [];
|
|
218
|
+
}
|
|
219
|
+
function validateMcpServerForImport(server, name) {
|
|
220
|
+
return mcpServerSchema.parse({
|
|
221
|
+
...server,
|
|
222
|
+
name,
|
|
223
|
+
transport: server.transport ??
|
|
224
|
+
(typeof server.url === "string"
|
|
225
|
+
? inferRemoteMcpTransport(server.url)
|
|
226
|
+
: "stdio"),
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
function writeMcpImport(artifact, projectRoot, dryRun) {
|
|
230
|
+
const scope = artifactScope(artifact, "local");
|
|
231
|
+
const servers = mcpServers(artifact);
|
|
232
|
+
if (servers.length === 0) {
|
|
233
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "MCP artifact requires a server or servers");
|
|
234
|
+
}
|
|
235
|
+
const validatedServers = servers.map((server) => {
|
|
236
|
+
const name = stringValue(server.name) ?? "(unnamed)";
|
|
237
|
+
return validateMcpServerForImport(server, name);
|
|
238
|
+
});
|
|
239
|
+
const result = dryRun
|
|
240
|
+
? validateMcpServersForConfig({
|
|
241
|
+
projectRoot,
|
|
242
|
+
scope,
|
|
243
|
+
servers: validatedServers,
|
|
244
|
+
})
|
|
245
|
+
: addMcpServersToConfig({
|
|
246
|
+
projectRoot,
|
|
247
|
+
scope,
|
|
248
|
+
servers: validatedServers,
|
|
249
|
+
});
|
|
250
|
+
const imported = [];
|
|
251
|
+
for (const validatedServer of validatedServers) {
|
|
252
|
+
if (dryRun) {
|
|
253
|
+
imported.push({
|
|
254
|
+
kind: "mcp",
|
|
255
|
+
status: "planned",
|
|
256
|
+
scope,
|
|
257
|
+
id: validatedServer.name,
|
|
258
|
+
path: result.path,
|
|
259
|
+
message: "MCP server import planned",
|
|
260
|
+
});
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
imported.push({
|
|
264
|
+
kind: "mcp",
|
|
265
|
+
status: "imported",
|
|
266
|
+
scope,
|
|
267
|
+
id: validatedServer.name,
|
|
268
|
+
path: result.path,
|
|
269
|
+
message: "MCP server imported",
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
return imported;
|
|
273
|
+
}
|
|
274
|
+
function skillRootPath(scope, projectRoot) {
|
|
275
|
+
return scope === "user"
|
|
276
|
+
? join(PATHS.MAESTRO_HOME, "skills")
|
|
277
|
+
: join(projectRoot, ".maestro", "skills");
|
|
278
|
+
}
|
|
279
|
+
function fileContent(file) {
|
|
280
|
+
const content = typeof file.content === "string" ? file.content : undefined;
|
|
281
|
+
if (content !== undefined) {
|
|
282
|
+
return content;
|
|
283
|
+
}
|
|
284
|
+
const contentBase64 = typeof file.contentBase64 === "string" ? file.contentBase64 : undefined;
|
|
285
|
+
if (contentBase64 !== undefined) {
|
|
286
|
+
const compact = contentBase64.replaceAll(/\s/g, "");
|
|
287
|
+
if (compact.length === 0 ||
|
|
288
|
+
compact.length % 4 !== 0 ||
|
|
289
|
+
!/^[A-Za-z0-9+/]*={0,2}$/.test(compact)) {
|
|
290
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Skill file contentBase64 is not valid base64");
|
|
291
|
+
}
|
|
292
|
+
return Buffer.from(compact, "base64");
|
|
293
|
+
}
|
|
294
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Skill file requires content or contentBase64");
|
|
295
|
+
}
|
|
296
|
+
function writeSkillImport(artifact, projectRoot, dryRun) {
|
|
297
|
+
const scope = artifactScope(artifact, "project");
|
|
298
|
+
const name = safeSkillName(artifact.name);
|
|
299
|
+
const files = Array.isArray(artifact.files) ? artifact.files : [];
|
|
300
|
+
if (!files.every(isRecord)) {
|
|
301
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Skill artifact files must be objects");
|
|
302
|
+
}
|
|
303
|
+
if (files.length === 0) {
|
|
304
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Skill artifact requires files");
|
|
305
|
+
}
|
|
306
|
+
if (!files.some((file) => safeRelativePath(file.path) === "SKILL.md")) {
|
|
307
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Skill artifact requires SKILL.md");
|
|
308
|
+
}
|
|
309
|
+
const targetDir = join(skillRootPath(scope, projectRoot), name);
|
|
310
|
+
const plannedFiles = files.map((file) => ({
|
|
311
|
+
relativePath: safeRelativePath(file.path),
|
|
312
|
+
content: fileContent(file),
|
|
313
|
+
}));
|
|
314
|
+
if (!dryRun) {
|
|
315
|
+
const skillRoot = dirname(targetDir);
|
|
316
|
+
mkdirSync(skillRoot, { recursive: true });
|
|
317
|
+
let stagingDir = mkdtempSync(join(skillRoot, `.${name}-import-`));
|
|
318
|
+
let backupDir;
|
|
319
|
+
let promoted = false;
|
|
320
|
+
try {
|
|
321
|
+
for (const file of plannedFiles) {
|
|
322
|
+
const stagedPath = join(stagingDir, file.relativePath);
|
|
323
|
+
mkdirSync(dirname(stagedPath), { recursive: true });
|
|
324
|
+
if (typeof file.content === "string") {
|
|
325
|
+
writeFileSync(stagedPath, file.content, "utf8");
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
writeFileSync(stagedPath, file.content);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
if (existsSync(targetDir)) {
|
|
332
|
+
backupDir = mkdtempSync(join(skillRoot, `.${name}-backup-`));
|
|
333
|
+
rmSync(backupDir, { recursive: true, force: true });
|
|
334
|
+
renameSync(targetDir, backupDir);
|
|
335
|
+
}
|
|
336
|
+
try {
|
|
337
|
+
renameSync(stagingDir, targetDir);
|
|
338
|
+
promoted = true;
|
|
339
|
+
}
|
|
340
|
+
catch (error) {
|
|
341
|
+
if (backupDir && !existsSync(targetDir)) {
|
|
342
|
+
try {
|
|
343
|
+
renameSync(backupDir, targetDir);
|
|
344
|
+
backupDir = undefined;
|
|
345
|
+
}
|
|
346
|
+
catch {
|
|
347
|
+
// Leave the backup in place rather than deleting the previous skill.
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
throw error;
|
|
351
|
+
}
|
|
352
|
+
stagingDir = undefined;
|
|
353
|
+
if (backupDir) {
|
|
354
|
+
rmSync(backupDir, { recursive: true, force: true });
|
|
355
|
+
backupDir = undefined;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
finally {
|
|
359
|
+
if (stagingDir) {
|
|
360
|
+
rmSync(stagingDir, { recursive: true, force: true });
|
|
361
|
+
}
|
|
362
|
+
if (backupDir && promoted) {
|
|
363
|
+
rmSync(backupDir, { recursive: true, force: true });
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return {
|
|
368
|
+
kind: "skill",
|
|
369
|
+
status: dryRun ? "planned" : "imported",
|
|
370
|
+
scope,
|
|
371
|
+
id: name,
|
|
372
|
+
path: targetDir,
|
|
373
|
+
message: dryRun ? "Skill file import planned" : "Skill files imported",
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
function validatedSessionEntries(value) {
|
|
377
|
+
if (!Array.isArray(value)) {
|
|
378
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Session artifact entries must be an array");
|
|
379
|
+
}
|
|
380
|
+
const entries = value.map((entry) => normalizeSessionEntry(structuredClone(entry)));
|
|
381
|
+
if (entries.some((entry) => entry === null)) {
|
|
382
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Session artifact entries must contain valid session entries");
|
|
383
|
+
}
|
|
384
|
+
if (entries.length === 0) {
|
|
385
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Imported session file is empty or unreadable.");
|
|
386
|
+
}
|
|
387
|
+
if (!entries.some((entry) => entry?.type === "session")) {
|
|
388
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Imported session file is missing a session header.");
|
|
389
|
+
}
|
|
390
|
+
return entries;
|
|
391
|
+
}
|
|
392
|
+
function validatePortableSessionPath(sourcePath) {
|
|
393
|
+
const resolvedSource = resolve(sourcePath);
|
|
394
|
+
if (!existsSync(resolvedSource)) {
|
|
395
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, `Session file not found: ${resolvedSource}`);
|
|
396
|
+
}
|
|
397
|
+
if (!statSync(resolvedSource).isFile()) {
|
|
398
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, `Session path is not a file: ${resolvedSource}`);
|
|
399
|
+
}
|
|
400
|
+
return resolvedSource;
|
|
401
|
+
}
|
|
402
|
+
function validatePortableSessionJsonExport(sourcePath) {
|
|
403
|
+
let parsed;
|
|
404
|
+
try {
|
|
405
|
+
parsed = JSON.parse(readFileSync(sourcePath, "utf8"));
|
|
406
|
+
}
|
|
407
|
+
catch (error) {
|
|
408
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, `Portable session export is not valid JSON: ${artifactMessage(error)}`);
|
|
409
|
+
}
|
|
410
|
+
if (!isRecord(parsed)) {
|
|
411
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Portable session export must be a JSON object.");
|
|
412
|
+
}
|
|
413
|
+
if (parsed.format !== PORTABLE_SESSION_EXPORT_FORMAT) {
|
|
414
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, `Portable session export format must be ${PORTABLE_SESSION_EXPORT_FORMAT}.`);
|
|
415
|
+
}
|
|
416
|
+
if (Array.isArray(parsed.entries)) {
|
|
417
|
+
validatedSessionEntries(parsed.entries);
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
if (Array.isArray(parsed.sessions) && parsed.sessions.length > 0) {
|
|
421
|
+
for (const [index, session] of parsed.sessions.entries()) {
|
|
422
|
+
if (!isRecord(session)) {
|
|
423
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, `Portable session export contains an invalid bundled session at index ${index}.`);
|
|
424
|
+
}
|
|
425
|
+
if (typeof session.sessionId !== "string") {
|
|
426
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, `Portable session export is missing a sessionId for bundled session ${index}.`);
|
|
427
|
+
}
|
|
428
|
+
if (!Array.isArray(session.entries)) {
|
|
429
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, `Portable session export is missing entries for bundled session ${session.sessionId}.`);
|
|
430
|
+
}
|
|
431
|
+
validatedSessionEntries(session.entries);
|
|
432
|
+
}
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Portable session export is missing both entries and bundled sessions.");
|
|
436
|
+
}
|
|
437
|
+
function validatePortableSessionJsonl(sourcePath) {
|
|
438
|
+
const contents = readFileSync(sourcePath, "utf8").trim();
|
|
439
|
+
const entries = contents
|
|
440
|
+
? contents
|
|
441
|
+
.split("\n")
|
|
442
|
+
.map((line) => tryParseSessionEntry(line))
|
|
443
|
+
.filter((entry) => Boolean(entry))
|
|
444
|
+
: [];
|
|
445
|
+
validatedSessionEntries(entries);
|
|
446
|
+
}
|
|
447
|
+
function validatePortableSessionContents(sourcePath) {
|
|
448
|
+
if (extname(sourcePath).toLowerCase() === ".json") {
|
|
449
|
+
validatePortableSessionJsonExport(sourcePath);
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
validatePortableSessionJsonl(sourcePath);
|
|
453
|
+
}
|
|
454
|
+
function importSessionArtifact(store, artifact, dryRun) {
|
|
455
|
+
if (!store?.importSessionEntries && !store?.importPortableSession) {
|
|
456
|
+
return {
|
|
457
|
+
kind: "session",
|
|
458
|
+
status: "skipped",
|
|
459
|
+
message: "Session import is not available",
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
if (hasOwn(artifact, "entries") && store.importSessionEntries) {
|
|
463
|
+
const entries = validatedSessionEntries(artifact.entries);
|
|
464
|
+
if (dryRun) {
|
|
465
|
+
return {
|
|
466
|
+
kind: "session",
|
|
467
|
+
status: "planned",
|
|
468
|
+
message: "Session import planned",
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
const result = store.importSessionEntries(entries);
|
|
472
|
+
return {
|
|
473
|
+
kind: "session",
|
|
474
|
+
status: "imported",
|
|
475
|
+
id: result.sessionId,
|
|
476
|
+
path: result.sessionFile,
|
|
477
|
+
message: `Imported ${result.importedCount} session(s)`,
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
const sourcePath = stringValue(artifact.path);
|
|
481
|
+
if (sourcePath && store.importPortableSession) {
|
|
482
|
+
const resolvedSource = validatePortableSessionPath(sourcePath);
|
|
483
|
+
validatePortableSessionContents(resolvedSource);
|
|
484
|
+
if (dryRun) {
|
|
485
|
+
return {
|
|
486
|
+
kind: "session",
|
|
487
|
+
status: "planned",
|
|
488
|
+
message: "Session import planned",
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
const result = store.importPortableSession(resolvedSource);
|
|
492
|
+
return {
|
|
493
|
+
kind: "session",
|
|
494
|
+
status: "imported",
|
|
495
|
+
id: result.sessionId,
|
|
496
|
+
path: result.sessionFile,
|
|
497
|
+
message: `Imported ${result.importedCount} session(s)`,
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Session artifact requires entries or path");
|
|
501
|
+
}
|
|
502
|
+
function importArtifact(store, artifact, projectRoot, dryRun) {
|
|
503
|
+
const kind = stringValue(artifact.kind);
|
|
504
|
+
try {
|
|
505
|
+
switch (kind) {
|
|
506
|
+
case "session":
|
|
507
|
+
return [importSessionArtifact(store, artifact, dryRun)];
|
|
508
|
+
case "config":
|
|
509
|
+
return [writeConfigImport(artifact, projectRoot, dryRun)];
|
|
510
|
+
case "hooks":
|
|
511
|
+
return [writeHooksImport(artifact, projectRoot, dryRun)];
|
|
512
|
+
case "mcp":
|
|
513
|
+
return writeMcpImport(artifact, projectRoot, dryRun);
|
|
514
|
+
case "skill":
|
|
515
|
+
return [writeSkillImport(artifact, projectRoot, dryRun)];
|
|
516
|
+
default:
|
|
517
|
+
throw new MaestroAppServerExternalAgentImportError(-32602, "Unsupported external agent artifact kind");
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
catch (error) {
|
|
521
|
+
return [
|
|
522
|
+
{
|
|
523
|
+
kind: ["session", "config", "hooks", "mcp", "skill"].includes(kind ?? "")
|
|
524
|
+
? kind
|
|
525
|
+
: "config",
|
|
526
|
+
status: "skipped",
|
|
527
|
+
message: artifactMessage(error),
|
|
528
|
+
},
|
|
529
|
+
];
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
export function createMaestroAppServerExternalAgentImport(options = {}) {
|
|
533
|
+
return {
|
|
534
|
+
async importBundle(params = {}) {
|
|
535
|
+
const normalizedParams = normalizeExternalAgentImportParams(params);
|
|
536
|
+
const artifacts = requireArtifacts(normalizedParams);
|
|
537
|
+
const dryRun = booleanValue(normalizedParams.dryRun, true);
|
|
538
|
+
const projectRoot = resolve(stringValue(normalizedParams.projectRoot) ??
|
|
539
|
+
options.projectRoot ??
|
|
540
|
+
process.cwd());
|
|
541
|
+
const imported = artifacts.flatMap((artifact) => importArtifact(options.store, artifact, projectRoot, dryRun));
|
|
542
|
+
return {
|
|
543
|
+
source: importSource(normalizedParams),
|
|
544
|
+
dryRun,
|
|
545
|
+
imported,
|
|
546
|
+
warnings: imported
|
|
547
|
+
.filter((artifact) => artifact.status === "skipped")
|
|
548
|
+
.map((artifact) => artifact.message ?? "Artifact skipped"),
|
|
549
|
+
};
|
|
550
|
+
},
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
//# sourceMappingURL=external-agent-import-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-agent-import-api.js","sourceRoot":"","sources":["../../src/app-server/external-agent-import-api.ts"],"names":[],"mappings":"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","sourcesContent":["import { Buffer } from \"node:buffer\";\nimport {\n\texistsSync,\n\tmkdirSync,\n\tmkdtempSync,\n\treadFileSync,\n\trenameSync,\n\trmSync,\n\tstatSync,\n\twriteFileSync,\n} from \"node:fs\";\nimport { dirname, extname, join, posix, resolve, win32 } from \"node:path\";\nimport type {\n\tMaestroAppServerExternalAgentImportResult,\n\tMaestroAppServerExternalAgentImportScope,\n\tMaestroAppServerExternalAgentImportedArtifact,\n} from \"@evalops/contracts\";\nimport { parse as parseTOML, stringify as stringifyTOML } from \"smol-toml\";\nimport { PATHS } from \"../config/constants.js\";\nimport { getWritablePackageConfigPath } from \"../config/toml-config.js\";\nimport { clearConfigCache } from \"../config/toml-config.js\";\nimport {\n\tgetProjectHooksConfigPath,\n\tgetUserHooksConfigPath,\n} from \"../hooks/config.js\";\nimport {\n\ttype WritableMcpScope,\n\taddMcpServersToConfig,\n\tinferRemoteMcpTransport,\n\tvalidateMcpServersForConfig,\n} from \"../mcp/config.js\";\nimport { type McpServerInput, mcpServerSchema } from \"../mcp/schema.js\";\nimport {\n\ttype SessionEntry,\n\tnormalizeSessionEntry,\n\ttryParseSessionEntry,\n} from \"../session/types.js\";\n\ntype UnknownRecord = Record<string, unknown>;\nconst PORTABLE_SESSION_EXPORT_FORMAT = \"maestro-session-export.v1\";\n\nexport class MaestroAppServerExternalAgentImportError extends Error {\n\tconstructor(\n\t\treadonly code: number,\n\t\tmessage: string,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"MaestroAppServerExternalAgentImportError\";\n\t}\n}\n\nexport interface MaestroAppServerExternalAgentSessionImporter {\n\timportSessionEntries?: (entries: SessionEntry[]) => {\n\t\tsessionFile: string;\n\t\tsessionId: string;\n\t\timportedCount: number;\n\t};\n\timportPortableSession?: (path: string) => {\n\t\tsessionFile: string;\n\t\tsessionId: string;\n\t\timportedCount: number;\n\t};\n}\n\nexport interface MaestroAppServerExternalAgentImport {\n\timportBundle(\n\t\tparams?: UnknownRecord,\n\t): Promise<MaestroAppServerExternalAgentImportResult>;\n}\n\nexport interface MaestroAppServerExternalAgentImportOptions {\n\tstore?: MaestroAppServerExternalAgentSessionImporter;\n\tprojectRoot?: string;\n}\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction stringValue(value: unknown): string | undefined {\n\treturn typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction booleanValue(value: unknown, fallback: boolean): boolean {\n\treturn typeof value === \"boolean\" ? value : fallback;\n}\n\nexport function normalizeExternalAgentImportParams(\n\tvalue: unknown,\n): UnknownRecord {\n\tif (value === undefined || value === null) {\n\t\treturn {};\n\t}\n\tif (!isRecord(value)) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"Invalid params\",\n\t\t);\n\t}\n\treturn value;\n}\n\nfunction artifactScope(\n\tartifact: UnknownRecord,\n\tfallback: MaestroAppServerExternalAgentImportScope,\n): MaestroAppServerExternalAgentImportScope {\n\tconst scope = stringValue(artifact.scope);\n\tif (scope === \"project\" || scope === \"local\" || scope === \"user\") {\n\t\treturn scope;\n\t}\n\treturn fallback;\n}\n\nfunction requireArtifacts(params: UnknownRecord): UnknownRecord[] {\n\tconst artifacts = params.artifacts;\n\tif (!Array.isArray(artifacts)) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"External agent import requires artifacts\",\n\t\t);\n\t}\n\tif (artifacts.some((artifact) => !isRecord(artifact))) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"External agent import artifacts must be objects\",\n\t\t);\n\t}\n\treturn artifacts;\n}\n\nfunction importSource(params: UnknownRecord): { name: string; type?: string } {\n\tconst source = isRecord(params.source) ? params.source : {};\n\treturn {\n\t\tname: stringValue(source.name) ?? \"external-agent\",\n\t\ttype: stringValue(source.type),\n\t};\n}\n\nfunction safeSkillName(value: unknown): string {\n\tconst name = stringValue(value);\n\tif (!name || !/^[a-z0-9][a-z0-9_-]{0,63}$/.test(name)) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"Skill artifact requires a safe skill name\",\n\t\t);\n\t}\n\treturn name;\n}\n\nfunction safeRelativePath(value: unknown): string {\n\tconst relativePath = stringValue(value);\n\tif (!relativePath) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"Imported file requires a relative path\",\n\t\t);\n\t}\n\tconst slashPath = relativePath.replaceAll(\"\\\\\", \"/\");\n\tconst normalized = posix.normalize(slashPath);\n\tconst winNormalized = win32.normalize(relativePath);\n\tif (\n\t\tposix.isAbsolute(normalized) ||\n\t\twin32.isAbsolute(relativePath) ||\n\t\t/^[A-Za-z]:/.test(relativePath) ||\n\t\tnormalized === \"..\" ||\n\t\tnormalized.startsWith(\"../\") ||\n\t\tnormalized.includes(\"/../\") ||\n\t\twinNormalized === \"..\" ||\n\t\twinNormalized.startsWith(\"..\\\\\") ||\n\t\twinNormalized.includes(\"\\\\..\\\\\")\n\t) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"Imported file path must stay inside its target directory\",\n\t\t);\n\t}\n\treturn normalized;\n}\n\nfunction artifactMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction hasOwn(record: UnknownRecord, key: string): boolean {\n\treturn Object.prototype.hasOwnProperty.call(record, key);\n}\n\nfunction readJsonObject(path: string): UnknownRecord {\n\tif (!existsSync(path)) {\n\t\treturn {};\n\t}\n\tconst parsed = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\n\treturn isRecord(parsed) ? parsed : {};\n}\n\nfunction writeJsonObject(path: string, value: UnknownRecord): void {\n\tmkdirSync(dirname(path), { recursive: true });\n\twriteFileSync(path, `${JSON.stringify(value, null, 2)}\\n`, \"utf8\");\n}\n\nfunction mergeRecords(\n\tbase: UnknownRecord,\n\tincoming: UnknownRecord,\n): UnknownRecord {\n\tconst merged: UnknownRecord = { ...base };\n\tfor (const [key, value] of Object.entries(incoming)) {\n\t\tconst current = merged[key];\n\t\tif (isRecord(current) && isRecord(value)) {\n\t\t\tmerged[key] = mergeRecords(current, value);\n\t\t} else {\n\t\t\tmerged[key] = value;\n\t\t}\n\t}\n\treturn merged;\n}\n\nfunction configContent(artifact: UnknownRecord): UnknownRecord {\n\tif (isRecord(artifact.values)) {\n\t\treturn artifact.values;\n\t}\n\tconst content = stringValue(artifact.content);\n\tif (!content) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"Config artifact requires values or TOML content\",\n\t\t);\n\t}\n\tconst parsed = parseTOML(content) as unknown;\n\tif (!isRecord(parsed)) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"Config TOML must parse to an object\",\n\t\t);\n\t}\n\treturn parsed;\n}\n\nfunction writeConfigImport(\n\tartifact: UnknownRecord,\n\tprojectRoot: string,\n\tdryRun: boolean,\n): MaestroAppServerExternalAgentImportedArtifact {\n\tconst scope = artifactScope(artifact, \"local\");\n\tconst path = getWritablePackageConfigPath(scope, projectRoot);\n\tconst incoming = configContent(artifact);\n\tconst existing = existsSync(path)\n\t\t? (parseTOML(readFileSync(path, \"utf8\")) as unknown)\n\t\t: {};\n\tconst merged = mergeRecords(isRecord(existing) ? existing : {}, incoming);\n\tif (!dryRun) {\n\t\tmkdirSync(dirname(path), { recursive: true });\n\t\tconst rendered = stringifyTOML(merged).trim();\n\t\twriteFileSync(path, rendered ? `${rendered}\\n` : \"\", \"utf8\");\n\t\tclearConfigCache();\n\t}\n\treturn {\n\t\tkind: \"config\",\n\t\tstatus: dryRun ? \"planned\" : \"imported\",\n\t\tscope,\n\t\tpath,\n\t\tmessage: dryRun ? \"Config TOML merge planned\" : \"Config TOML merged\",\n\t};\n}\n\nfunction hooksContent(artifact: UnknownRecord): UnknownRecord {\n\tif (isRecord(artifact.config)) {\n\t\treturn artifact.config;\n\t}\n\tif (isRecord(artifact.hooks)) {\n\t\treturn { hooks: artifact.hooks };\n\t}\n\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t-32602,\n\t\t\"Hooks artifact requires config or hooks\",\n\t);\n}\n\nfunction mergeHooksConfig(\n\texisting: UnknownRecord,\n\tincoming: UnknownRecord,\n): UnknownRecord {\n\tconst existingHooks = isRecord(existing.hooks) ? existing.hooks : {};\n\tconst incomingHooks = isRecord(incoming.hooks) ? incoming.hooks : {};\n\tconst hooks: UnknownRecord = { ...existingHooks };\n\tfor (const [eventType, matchers] of Object.entries(incomingHooks)) {\n\t\thooks[eventType] = [\n\t\t\t...(Array.isArray(existingHooks[eventType])\n\t\t\t\t? existingHooks[eventType]\n\t\t\t\t: []),\n\t\t\t...(Array.isArray(matchers) ? matchers : []),\n\t\t];\n\t}\n\treturn mergeRecords(mergeRecords(existing, incoming), { hooks });\n}\n\nfunction hooksConfigPath(\n\tscope: MaestroAppServerExternalAgentImportScope,\n\tprojectRoot: string,\n): string {\n\tif (scope === \"user\") {\n\t\treturn getUserHooksConfigPath();\n\t}\n\tif (scope === \"local\") {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"Hooks artifact does not support local scope\",\n\t\t);\n\t}\n\treturn getProjectHooksConfigPath(projectRoot);\n}\n\nfunction writeHooksImport(\n\tartifact: UnknownRecord,\n\tprojectRoot: string,\n\tdryRun: boolean,\n): MaestroAppServerExternalAgentImportedArtifact {\n\tconst scope = artifactScope(artifact, \"project\");\n\tconst path = hooksConfigPath(scope, projectRoot);\n\tconst incoming = hooksContent(artifact);\n\tconst existing = readJsonObject(path);\n\tif (!dryRun) {\n\t\twriteJsonObject(path, mergeHooksConfig(existing, incoming));\n\t}\n\treturn {\n\t\tkind: \"hooks\",\n\t\tstatus: dryRun ? \"planned\" : \"imported\",\n\t\tscope,\n\t\tpath,\n\t\tmessage: dryRun ? \"Hooks config merge planned\" : \"Hooks config merged\",\n\t};\n}\n\nfunction mcpServers(artifact: UnknownRecord): UnknownRecord[] {\n\tif (Array.isArray(artifact.servers)) {\n\t\tif (!artifact.servers.every(isRecord)) {\n\t\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t\t-32602,\n\t\t\t\t\"MCP artifact servers must be objects\",\n\t\t\t);\n\t\t}\n\t\treturn artifact.servers;\n\t}\n\tif (hasOwn(artifact, \"server\")) {\n\t\tif (!isRecord(artifact.server)) {\n\t\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t\t-32602,\n\t\t\t\t\"MCP artifact server must be an object\",\n\t\t\t);\n\t\t}\n\t\treturn [artifact.server];\n\t}\n\treturn [];\n}\n\nfunction validateMcpServerForImport(\n\tserver: UnknownRecord,\n\tname: string,\n): McpServerInput & { name: string } {\n\treturn mcpServerSchema.parse({\n\t\t...server,\n\t\tname,\n\t\ttransport:\n\t\t\tserver.transport ??\n\t\t\t(typeof server.url === \"string\"\n\t\t\t\t? inferRemoteMcpTransport(server.url)\n\t\t\t\t: \"stdio\"),\n\t});\n}\n\nfunction writeMcpImport(\n\tartifact: UnknownRecord,\n\tprojectRoot: string,\n\tdryRun: boolean,\n): MaestroAppServerExternalAgentImportedArtifact[] {\n\tconst scope = artifactScope(artifact, \"local\") as WritableMcpScope;\n\tconst servers = mcpServers(artifact);\n\tif (servers.length === 0) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"MCP artifact requires a server or servers\",\n\t\t);\n\t}\n\tconst validatedServers = servers.map((server) => {\n\t\tconst name = stringValue(server.name) ?? \"(unnamed)\";\n\t\treturn validateMcpServerForImport(server, name);\n\t});\n\tconst result = dryRun\n\t\t? validateMcpServersForConfig({\n\t\t\t\tprojectRoot,\n\t\t\t\tscope,\n\t\t\t\tservers: validatedServers,\n\t\t\t})\n\t\t: addMcpServersToConfig({\n\t\t\t\tprojectRoot,\n\t\t\t\tscope,\n\t\t\t\tservers: validatedServers,\n\t\t\t});\n\tconst imported: MaestroAppServerExternalAgentImportedArtifact[] = [];\n\tfor (const validatedServer of validatedServers) {\n\t\tif (dryRun) {\n\t\t\timported.push({\n\t\t\t\tkind: \"mcp\",\n\t\t\t\tstatus: \"planned\",\n\t\t\t\tscope,\n\t\t\t\tid: validatedServer.name,\n\t\t\t\tpath: result.path,\n\t\t\t\tmessage: \"MCP server import planned\",\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\timported.push({\n\t\t\tkind: \"mcp\",\n\t\t\tstatus: \"imported\",\n\t\t\tscope,\n\t\t\tid: validatedServer.name,\n\t\t\tpath: result.path,\n\t\t\tmessage: \"MCP server imported\",\n\t\t});\n\t}\n\treturn imported;\n}\n\nfunction skillRootPath(\n\tscope: MaestroAppServerExternalAgentImportScope,\n\tprojectRoot: string,\n): string {\n\treturn scope === \"user\"\n\t\t? join(PATHS.MAESTRO_HOME, \"skills\")\n\t\t: join(projectRoot, \".maestro\", \"skills\");\n}\n\nfunction fileContent(file: UnknownRecord): string | Buffer {\n\tconst content = typeof file.content === \"string\" ? file.content : undefined;\n\tif (content !== undefined) {\n\t\treturn content;\n\t}\n\tconst contentBase64 =\n\t\ttypeof file.contentBase64 === \"string\" ? file.contentBase64 : undefined;\n\tif (contentBase64 !== undefined) {\n\t\tconst compact = contentBase64.replaceAll(/\\s/g, \"\");\n\t\tif (\n\t\t\tcompact.length === 0 ||\n\t\t\tcompact.length % 4 !== 0 ||\n\t\t\t!/^[A-Za-z0-9+/]*={0,2}$/.test(compact)\n\t\t) {\n\t\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t\t-32602,\n\t\t\t\t\"Skill file contentBase64 is not valid base64\",\n\t\t\t);\n\t\t}\n\t\treturn Buffer.from(compact, \"base64\");\n\t}\n\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t-32602,\n\t\t\"Skill file requires content or contentBase64\",\n\t);\n}\n\nfunction writeSkillImport(\n\tartifact: UnknownRecord,\n\tprojectRoot: string,\n\tdryRun: boolean,\n): MaestroAppServerExternalAgentImportedArtifact {\n\tconst scope = artifactScope(artifact, \"project\");\n\tconst name = safeSkillName(artifact.name);\n\tconst files = Array.isArray(artifact.files) ? artifact.files : [];\n\tif (!files.every(isRecord)) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"Skill artifact files must be objects\",\n\t\t);\n\t}\n\tif (files.length === 0) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"Skill artifact requires files\",\n\t\t);\n\t}\n\tif (!files.some((file) => safeRelativePath(file.path) === \"SKILL.md\")) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"Skill artifact requires SKILL.md\",\n\t\t);\n\t}\n\tconst targetDir = join(skillRootPath(scope, projectRoot), name);\n\tconst plannedFiles = files.map((file) => ({\n\t\trelativePath: safeRelativePath(file.path),\n\t\tcontent: fileContent(file),\n\t}));\n\tif (!dryRun) {\n\t\tconst skillRoot = dirname(targetDir);\n\t\tmkdirSync(skillRoot, { recursive: true });\n\t\tlet stagingDir: string | undefined = mkdtempSync(\n\t\t\tjoin(skillRoot, `.${name}-import-`),\n\t\t);\n\t\tlet backupDir: string | undefined;\n\t\tlet promoted = false;\n\t\ttry {\n\t\t\tfor (const file of plannedFiles) {\n\t\t\t\tconst stagedPath = join(stagingDir, file.relativePath);\n\t\t\t\tmkdirSync(dirname(stagedPath), { recursive: true });\n\t\t\t\tif (typeof file.content === \"string\") {\n\t\t\t\t\twriteFileSync(stagedPath, file.content, \"utf8\");\n\t\t\t\t} else {\n\t\t\t\t\twriteFileSync(stagedPath, file.content);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (existsSync(targetDir)) {\n\t\t\t\tbackupDir = mkdtempSync(join(skillRoot, `.${name}-backup-`));\n\t\t\t\trmSync(backupDir, { recursive: true, force: true });\n\t\t\t\trenameSync(targetDir, backupDir);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\trenameSync(stagingDir, targetDir);\n\t\t\t\tpromoted = true;\n\t\t\t} catch (error) {\n\t\t\t\tif (backupDir && !existsSync(targetDir)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\trenameSync(backupDir, targetDir);\n\t\t\t\t\t\tbackupDir = undefined;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Leave the backup in place rather than deleting the previous skill.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tstagingDir = undefined;\n\t\t\tif (backupDir) {\n\t\t\t\trmSync(backupDir, { recursive: true, force: true });\n\t\t\t\tbackupDir = undefined;\n\t\t\t}\n\t\t} finally {\n\t\t\tif (stagingDir) {\n\t\t\t\trmSync(stagingDir, { recursive: true, force: true });\n\t\t\t}\n\t\t\tif (backupDir && promoted) {\n\t\t\t\trmSync(backupDir, { recursive: true, force: true });\n\t\t\t}\n\t\t}\n\t}\n\treturn {\n\t\tkind: \"skill\",\n\t\tstatus: dryRun ? \"planned\" : \"imported\",\n\t\tscope,\n\t\tid: name,\n\t\tpath: targetDir,\n\t\tmessage: dryRun ? \"Skill file import planned\" : \"Skill files imported\",\n\t};\n}\n\nfunction validatedSessionEntries(value: unknown): SessionEntry[] {\n\tif (!Array.isArray(value)) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"Session artifact entries must be an array\",\n\t\t);\n\t}\n\tconst entries = value.map((entry) =>\n\t\tnormalizeSessionEntry(structuredClone(entry)),\n\t);\n\tif (entries.some((entry) => entry === null)) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"Session artifact entries must contain valid session entries\",\n\t\t);\n\t}\n\tif (entries.length === 0) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"Imported session file is empty or unreadable.\",\n\t\t);\n\t}\n\tif (!entries.some((entry) => entry?.type === \"session\")) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"Imported session file is missing a session header.\",\n\t\t);\n\t}\n\treturn entries as SessionEntry[];\n}\n\nfunction validatePortableSessionPath(sourcePath: string): string {\n\tconst resolvedSource = resolve(sourcePath);\n\tif (!existsSync(resolvedSource)) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t`Session file not found: ${resolvedSource}`,\n\t\t);\n\t}\n\tif (!statSync(resolvedSource).isFile()) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t`Session path is not a file: ${resolvedSource}`,\n\t\t);\n\t}\n\treturn resolvedSource;\n}\n\nfunction validatePortableSessionJsonExport(sourcePath: string): void {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(readFileSync(sourcePath, \"utf8\"));\n\t} catch (error) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t`Portable session export is not valid JSON: ${artifactMessage(error)}`,\n\t\t);\n\t}\n\tif (!isRecord(parsed)) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t\"Portable session export must be a JSON object.\",\n\t\t);\n\t}\n\tif (parsed.format !== PORTABLE_SESSION_EXPORT_FORMAT) {\n\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t-32602,\n\t\t\t`Portable session export format must be ${PORTABLE_SESSION_EXPORT_FORMAT}.`,\n\t\t);\n\t}\n\tif (Array.isArray(parsed.entries)) {\n\t\tvalidatedSessionEntries(parsed.entries);\n\t\treturn;\n\t}\n\tif (Array.isArray(parsed.sessions) && parsed.sessions.length > 0) {\n\t\tfor (const [index, session] of parsed.sessions.entries()) {\n\t\t\tif (!isRecord(session)) {\n\t\t\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t\t\t-32602,\n\t\t\t\t\t`Portable session export contains an invalid bundled session at index ${index}.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (typeof session.sessionId !== \"string\") {\n\t\t\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t\t\t-32602,\n\t\t\t\t\t`Portable session export is missing a sessionId for bundled session ${index}.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!Array.isArray(session.entries)) {\n\t\t\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t\t\t-32602,\n\t\t\t\t\t`Portable session export is missing entries for bundled session ${session.sessionId}.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tvalidatedSessionEntries(session.entries);\n\t\t}\n\t\treturn;\n\t}\n\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t-32602,\n\t\t\"Portable session export is missing both entries and bundled sessions.\",\n\t);\n}\n\nfunction validatePortableSessionJsonl(sourcePath: string): void {\n\tconst contents = readFileSync(sourcePath, \"utf8\").trim();\n\tconst entries = contents\n\t\t? contents\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.map((line) => tryParseSessionEntry(line))\n\t\t\t\t.filter((entry): entry is SessionEntry => Boolean(entry))\n\t\t: [];\n\tvalidatedSessionEntries(entries);\n}\n\nfunction validatePortableSessionContents(sourcePath: string): void {\n\tif (extname(sourcePath).toLowerCase() === \".json\") {\n\t\tvalidatePortableSessionJsonExport(sourcePath);\n\t\treturn;\n\t}\n\tvalidatePortableSessionJsonl(sourcePath);\n}\n\nfunction importSessionArtifact(\n\tstore: MaestroAppServerExternalAgentSessionImporter | undefined,\n\tartifact: UnknownRecord,\n\tdryRun: boolean,\n): MaestroAppServerExternalAgentImportedArtifact {\n\tif (!store?.importSessionEntries && !store?.importPortableSession) {\n\t\treturn {\n\t\t\tkind: \"session\",\n\t\t\tstatus: \"skipped\",\n\t\t\tmessage: \"Session import is not available\",\n\t\t};\n\t}\n\tif (hasOwn(artifact, \"entries\") && store.importSessionEntries) {\n\t\tconst entries = validatedSessionEntries(artifact.entries);\n\t\tif (dryRun) {\n\t\t\treturn {\n\t\t\t\tkind: \"session\",\n\t\t\t\tstatus: \"planned\",\n\t\t\t\tmessage: \"Session import planned\",\n\t\t\t};\n\t\t}\n\t\tconst result = store.importSessionEntries(entries);\n\t\treturn {\n\t\t\tkind: \"session\",\n\t\t\tstatus: \"imported\",\n\t\t\tid: result.sessionId,\n\t\t\tpath: result.sessionFile,\n\t\t\tmessage: `Imported ${result.importedCount} session(s)`,\n\t\t};\n\t}\n\tconst sourcePath = stringValue(artifact.path);\n\tif (sourcePath && store.importPortableSession) {\n\t\tconst resolvedSource = validatePortableSessionPath(sourcePath);\n\t\tvalidatePortableSessionContents(resolvedSource);\n\t\tif (dryRun) {\n\t\t\treturn {\n\t\t\t\tkind: \"session\",\n\t\t\t\tstatus: \"planned\",\n\t\t\t\tmessage: \"Session import planned\",\n\t\t\t};\n\t\t}\n\t\tconst result = store.importPortableSession(resolvedSource);\n\t\treturn {\n\t\t\tkind: \"session\",\n\t\t\tstatus: \"imported\",\n\t\t\tid: result.sessionId,\n\t\t\tpath: result.sessionFile,\n\t\t\tmessage: `Imported ${result.importedCount} session(s)`,\n\t\t};\n\t}\n\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t-32602,\n\t\t\"Session artifact requires entries or path\",\n\t);\n}\n\nfunction importArtifact(\n\tstore: MaestroAppServerExternalAgentSessionImporter | undefined,\n\tartifact: UnknownRecord,\n\tprojectRoot: string,\n\tdryRun: boolean,\n): MaestroAppServerExternalAgentImportedArtifact[] {\n\tconst kind = stringValue(artifact.kind);\n\ttry {\n\t\tswitch (kind) {\n\t\t\tcase \"session\":\n\t\t\t\treturn [importSessionArtifact(store, artifact, dryRun)];\n\t\t\tcase \"config\":\n\t\t\t\treturn [writeConfigImport(artifact, projectRoot, dryRun)];\n\t\t\tcase \"hooks\":\n\t\t\t\treturn [writeHooksImport(artifact, projectRoot, dryRun)];\n\t\t\tcase \"mcp\":\n\t\t\t\treturn writeMcpImport(artifact, projectRoot, dryRun);\n\t\t\tcase \"skill\":\n\t\t\t\treturn [writeSkillImport(artifact, projectRoot, dryRun)];\n\t\t\tdefault:\n\t\t\t\tthrow new MaestroAppServerExternalAgentImportError(\n\t\t\t\t\t-32602,\n\t\t\t\t\t\"Unsupported external agent artifact kind\",\n\t\t\t\t);\n\t\t}\n\t} catch (error) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tkind: [\"session\", \"config\", \"hooks\", \"mcp\", \"skill\"].includes(\n\t\t\t\t\tkind ?? \"\",\n\t\t\t\t)\n\t\t\t\t\t? (kind as MaestroAppServerExternalAgentImportedArtifact[\"kind\"])\n\t\t\t\t\t: \"config\",\n\t\t\t\tstatus: \"skipped\",\n\t\t\t\tmessage: artifactMessage(error),\n\t\t\t},\n\t\t];\n\t}\n}\n\nexport function createMaestroAppServerExternalAgentImport(\n\toptions: MaestroAppServerExternalAgentImportOptions = {},\n): MaestroAppServerExternalAgentImport {\n\treturn {\n\t\tasync importBundle(params = {}) {\n\t\t\tconst normalizedParams = normalizeExternalAgentImportParams(params);\n\t\t\tconst artifacts = requireArtifacts(normalizedParams);\n\t\t\tconst dryRun = booleanValue(normalizedParams.dryRun, true);\n\t\t\tconst projectRoot = resolve(\n\t\t\t\tstringValue(normalizedParams.projectRoot) ??\n\t\t\t\t\toptions.projectRoot ??\n\t\t\t\t\tprocess.cwd(),\n\t\t\t);\n\t\t\tconst imported = artifacts.flatMap((artifact) =>\n\t\t\t\timportArtifact(options.store, artifact, projectRoot, dryRun),\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tsource: importSource(normalizedParams),\n\t\t\t\tdryRun,\n\t\t\t\timported,\n\t\t\t\twarnings: imported\n\t\t\t\t\t.filter((artifact) => artifact.status === \"skipped\")\n\t\t\t\t\t.map((artifact) => artifact.message ?? \"Artifact skipped\"),\n\t\t\t};\n\t\t},\n\t};\n}\n"]}
|