@alan-ai-hq/agent-manager 0.1.113 → 0.1.115
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/LICENSE +88 -0
- package/dist/__tests__/binding-switch-git.test.d.ts +2 -0
- package/dist/__tests__/binding-switch-git.test.d.ts.map +1 -0
- package/dist/__tests__/binding-switch-git.test.js +555 -0
- package/dist/__tests__/binding-switch-git.test.js.map +1 -0
- package/dist/__tests__/cli-ensure-install.test.d.ts +2 -0
- package/dist/__tests__/cli-ensure-install.test.d.ts.map +1 -0
- package/dist/__tests__/cli-ensure-install.test.js +177 -0
- package/dist/__tests__/cli-ensure-install.test.js.map +1 -0
- package/dist/__tests__/cli-executable.test.d.ts +2 -0
- package/dist/__tests__/cli-executable.test.d.ts.map +1 -0
- package/dist/__tests__/cli-executable.test.js +155 -0
- package/dist/__tests__/cli-executable.test.js.map +1 -0
- package/dist/__tests__/cli-executable.windows.test.d.ts +2 -0
- package/dist/__tests__/cli-executable.windows.test.d.ts.map +1 -0
- package/dist/__tests__/cli-executable.windows.test.js +123 -0
- package/dist/__tests__/cli-executable.windows.test.js.map +1 -0
- package/dist/__tests__/cli-help.test.d.ts +2 -0
- package/dist/__tests__/cli-help.test.d.ts.map +1 -0
- package/dist/__tests__/cli-help.test.js +47 -0
- package/dist/__tests__/cli-help.test.js.map +1 -0
- package/dist/__tests__/computer-readiness.test.d.ts +2 -0
- package/dist/__tests__/computer-readiness.test.d.ts.map +1 -0
- package/dist/__tests__/computer-readiness.test.js +63 -0
- package/dist/__tests__/computer-readiness.test.js.map +1 -0
- package/dist/__tests__/core-agent-provider-auth-env.test.d.ts +2 -0
- package/dist/__tests__/core-agent-provider-auth-env.test.d.ts.map +1 -0
- package/dist/__tests__/core-agent-provider-auth-env.test.js +93 -0
- package/dist/__tests__/core-agent-provider-auth-env.test.js.map +1 -0
- package/dist/__tests__/core-agent-workflow-context.test.d.ts +2 -0
- package/dist/__tests__/core-agent-workflow-context.test.d.ts.map +1 -0
- package/dist/__tests__/core-agent-workflow-context.test.js +139 -0
- package/dist/__tests__/core-agent-workflow-context.test.js.map +1 -0
- package/dist/__tests__/daemon-native-hooks.test.d.ts +2 -0
- package/dist/__tests__/daemon-native-hooks.test.d.ts.map +1 -0
- package/dist/__tests__/daemon-native-hooks.test.js +94 -0
- package/dist/__tests__/daemon-native-hooks.test.js.map +1 -0
- package/dist/__tests__/daemon-reconcile-ask.test.d.ts +2 -0
- package/dist/__tests__/daemon-reconcile-ask.test.d.ts.map +1 -0
- package/dist/__tests__/daemon-reconcile-ask.test.js +100 -0
- package/dist/__tests__/daemon-reconcile-ask.test.js.map +1 -0
- package/dist/__tests__/daemon-runner-status.test.d.ts +2 -0
- package/dist/__tests__/daemon-runner-status.test.d.ts.map +1 -0
- package/dist/__tests__/daemon-runner-status.test.js +102 -0
- package/dist/__tests__/daemon-runner-status.test.js.map +1 -0
- package/dist/__tests__/daemon-socket.integration.test.d.ts +2 -0
- package/dist/__tests__/daemon-socket.integration.test.d.ts.map +1 -0
- package/dist/__tests__/daemon-socket.integration.test.js +435 -0
- package/dist/__tests__/daemon-socket.integration.test.js.map +1 -0
- package/dist/__tests__/daemon.test.d.ts +2 -0
- package/dist/__tests__/daemon.test.d.ts.map +1 -0
- package/dist/__tests__/daemon.test.js +4884 -0
- package/dist/__tests__/daemon.test.js.map +1 -0
- package/dist/__tests__/ensure-shared-checkout-branch.test.d.ts +2 -0
- package/dist/__tests__/ensure-shared-checkout-branch.test.d.ts.map +1 -0
- package/dist/__tests__/ensure-shared-checkout-branch.test.js +129 -0
- package/dist/__tests__/ensure-shared-checkout-branch.test.js.map +1 -0
- package/dist/__tests__/event-journal-stress.test.d.ts +2 -0
- package/dist/__tests__/event-journal-stress.test.d.ts.map +1 -0
- package/dist/__tests__/event-journal-stress.test.js +124 -0
- package/dist/__tests__/event-journal-stress.test.js.map +1 -0
- package/dist/__tests__/event-journal.test.d.ts +2 -0
- package/dist/__tests__/event-journal.test.d.ts.map +1 -0
- package/dist/__tests__/event-journal.test.js +264 -0
- package/dist/__tests__/event-journal.test.js.map +1 -0
- package/dist/__tests__/event-outbox-persist-failure.test.d.ts +2 -0
- package/dist/__tests__/event-outbox-persist-failure.test.d.ts.map +1 -0
- package/dist/__tests__/event-outbox-persist-failure.test.js +143 -0
- package/dist/__tests__/event-outbox-persist-failure.test.js.map +1 -0
- package/dist/__tests__/event-outbox.test.d.ts +2 -0
- package/dist/__tests__/event-outbox.test.d.ts.map +1 -0
- package/dist/__tests__/event-outbox.test.js +602 -0
- package/dist/__tests__/event-outbox.test.js.map +1 -0
- package/dist/__tests__/execution-activity-tracker.test.d.ts +2 -0
- package/dist/__tests__/execution-activity-tracker.test.d.ts.map +1 -0
- package/dist/__tests__/execution-activity-tracker.test.js +64 -0
- package/dist/__tests__/execution-activity-tracker.test.js.map +1 -0
- package/dist/__tests__/execution-lease-client.test.d.ts +2 -0
- package/dist/__tests__/execution-lease-client.test.d.ts.map +1 -0
- package/dist/__tests__/execution-lease-client.test.js +274 -0
- package/dist/__tests__/execution-lease-client.test.js.map +1 -0
- package/dist/__tests__/fake-provider-cli.test.d.ts +2 -0
- package/dist/__tests__/fake-provider-cli.test.d.ts.map +1 -0
- package/dist/__tests__/fake-provider-cli.test.js +46 -0
- package/dist/__tests__/fake-provider-cli.test.js.map +1 -0
- package/dist/__tests__/generated-images.test.d.ts +2 -0
- package/dist/__tests__/generated-images.test.d.ts.map +1 -0
- package/dist/__tests__/generated-images.test.js +132 -0
- package/dist/__tests__/generated-images.test.js.map +1 -0
- package/dist/__tests__/helpers/sandbox-outbox.d.ts +3 -0
- package/dist/__tests__/helpers/sandbox-outbox.d.ts.map +1 -0
- package/dist/__tests__/helpers/sandbox-outbox.js +23 -0
- package/dist/__tests__/helpers/sandbox-outbox.js.map +1 -0
- package/dist/__tests__/install-command.test.d.ts +2 -0
- package/dist/__tests__/install-command.test.d.ts.map +1 -0
- package/dist/__tests__/install-command.test.js +185 -0
- package/dist/__tests__/install-command.test.js.map +1 -0
- package/dist/__tests__/integration-cli.test.d.ts +2 -0
- package/dist/__tests__/integration-cli.test.d.ts.map +1 -0
- package/dist/__tests__/integration-cli.test.js +150 -0
- package/dist/__tests__/integration-cli.test.js.map +1 -0
- package/dist/__tests__/lifecycle-contracts.test.d.ts +2 -0
- package/dist/__tests__/lifecycle-contracts.test.d.ts.map +1 -0
- package/dist/__tests__/lifecycle-contracts.test.js +66 -0
- package/dist/__tests__/lifecycle-contracts.test.js.map +1 -0
- package/dist/__tests__/lifecycle-logger.test.d.ts +2 -0
- package/dist/__tests__/lifecycle-logger.test.d.ts.map +1 -0
- package/dist/__tests__/lifecycle-logger.test.js +49 -0
- package/dist/__tests__/lifecycle-logger.test.js.map +1 -0
- package/dist/__tests__/local-daemon-lifecycle.test.d.ts +2 -0
- package/dist/__tests__/local-daemon-lifecycle.test.d.ts.map +1 -0
- package/dist/__tests__/local-daemon-lifecycle.test.js +594 -0
- package/dist/__tests__/local-daemon-lifecycle.test.js.map +1 -0
- package/dist/__tests__/local-git-status.test.d.ts +2 -0
- package/dist/__tests__/local-git-status.test.d.ts.map +1 -0
- package/dist/__tests__/local-git-status.test.js +31 -0
- package/dist/__tests__/local-git-status.test.js.map +1 -0
- package/dist/__tests__/mcp-config-adapters-files.test.d.ts +2 -0
- package/dist/__tests__/mcp-config-adapters-files.test.d.ts.map +1 -0
- package/dist/__tests__/mcp-config-adapters-files.test.js +486 -0
- package/dist/__tests__/mcp-config-adapters-files.test.js.map +1 -0
- package/dist/__tests__/mcp-config-adapters.test.d.ts +2 -0
- package/dist/__tests__/mcp-config-adapters.test.d.ts.map +1 -0
- package/dist/__tests__/mcp-config-adapters.test.js +492 -0
- package/dist/__tests__/mcp-config-adapters.test.js.map +1 -0
- package/dist/__tests__/mcp-sync.test.d.ts +2 -0
- package/dist/__tests__/mcp-sync.test.d.ts.map +1 -0
- package/dist/__tests__/mcp-sync.test.js +21 -0
- package/dist/__tests__/mcp-sync.test.js.map +1 -0
- package/dist/__tests__/model-scan-runner.test.d.ts +2 -0
- package/dist/__tests__/model-scan-runner.test.d.ts.map +1 -0
- package/dist/__tests__/model-scan-runner.test.js +80 -0
- package/dist/__tests__/model-scan-runner.test.js.map +1 -0
- package/dist/__tests__/native-hook-command.test.d.ts +2 -0
- package/dist/__tests__/native-hook-command.test.d.ts.map +1 -0
- package/dist/__tests__/native-hook-command.test.js +386 -0
- package/dist/__tests__/native-hook-command.test.js.map +1 -0
- package/dist/__tests__/native-hook-config.test.d.ts +2 -0
- package/dist/__tests__/native-hook-config.test.d.ts.map +1 -0
- package/dist/__tests__/native-hook-config.test.js +374 -0
- package/dist/__tests__/native-hook-config.test.js.map +1 -0
- package/dist/__tests__/native-hook-drain.test.d.ts +2 -0
- package/dist/__tests__/native-hook-drain.test.d.ts.map +1 -0
- package/dist/__tests__/native-hook-drain.test.js +197 -0
- package/dist/__tests__/native-hook-drain.test.js.map +1 -0
- package/dist/__tests__/native-hook-inbox.test.d.ts +2 -0
- package/dist/__tests__/native-hook-inbox.test.d.ts.map +1 -0
- package/dist/__tests__/native-hook-inbox.test.js +139 -0
- package/dist/__tests__/native-hook-inbox.test.js.map +1 -0
- package/dist/__tests__/native-session.test.d.ts +2 -0
- package/dist/__tests__/native-session.test.d.ts.map +1 -0
- package/dist/__tests__/native-session.test.js +41 -0
- package/dist/__tests__/native-session.test.js.map +1 -0
- package/dist/__tests__/native-stream-outbox.test.d.ts +2 -0
- package/dist/__tests__/native-stream-outbox.test.d.ts.map +1 -0
- package/dist/__tests__/native-stream-outbox.test.js +231 -0
- package/dist/__tests__/native-stream-outbox.test.js.map +1 -0
- package/dist/__tests__/native-stream-platform.test.d.ts +2 -0
- package/dist/__tests__/native-stream-platform.test.d.ts.map +1 -0
- package/dist/__tests__/native-stream-platform.test.js +20 -0
- package/dist/__tests__/native-stream-platform.test.js.map +1 -0
- package/dist/__tests__/native-transcript-cursor.test.d.ts +2 -0
- package/dist/__tests__/native-transcript-cursor.test.d.ts.map +1 -0
- package/dist/__tests__/native-transcript-cursor.test.js +60 -0
- package/dist/__tests__/native-transcript-cursor.test.js.map +1 -0
- package/dist/__tests__/native-transcript-stream.test.d.ts +2 -0
- package/dist/__tests__/native-transcript-stream.test.d.ts.map +1 -0
- package/dist/__tests__/native-transcript-stream.test.js +378 -0
- package/dist/__tests__/native-transcript-stream.test.js.map +1 -0
- package/dist/__tests__/network-diagnostics.test.d.ts +2 -0
- package/dist/__tests__/network-diagnostics.test.d.ts.map +1 -0
- package/dist/__tests__/network-diagnostics.test.js +26 -0
- package/dist/__tests__/network-diagnostics.test.js.map +1 -0
- package/dist/__tests__/observable-map.test.d.ts +2 -0
- package/dist/__tests__/observable-map.test.d.ts.map +1 -0
- package/dist/__tests__/observable-map.test.js +54 -0
- package/dist/__tests__/observable-map.test.js.map +1 -0
- package/dist/__tests__/outbox-baseline.bench.test.d.ts +2 -0
- package/dist/__tests__/outbox-baseline.bench.test.d.ts.map +1 -0
- package/dist/__tests__/outbox-baseline.bench.test.js +108 -0
- package/dist/__tests__/outbox-baseline.bench.test.js.map +1 -0
- package/dist/__tests__/provider-auth-preflight.test.d.ts +2 -0
- package/dist/__tests__/provider-auth-preflight.test.d.ts.map +1 -0
- package/dist/__tests__/provider-auth-preflight.test.js +123 -0
- package/dist/__tests__/provider-auth-preflight.test.js.map +1 -0
- package/dist/__tests__/provider-model-discovery.test.d.ts +2 -0
- package/dist/__tests__/provider-model-discovery.test.d.ts.map +1 -0
- package/dist/__tests__/provider-model-discovery.test.js +1071 -0
- package/dist/__tests__/provider-model-discovery.test.js.map +1 -0
- package/dist/__tests__/resource-diagnostics.test.d.ts +2 -0
- package/dist/__tests__/resource-diagnostics.test.d.ts.map +1 -0
- package/dist/__tests__/resource-diagnostics.test.js +138 -0
- package/dist/__tests__/resource-diagnostics.test.js.map +1 -0
- package/dist/__tests__/resume-fallback-env.test.d.ts +2 -0
- package/dist/__tests__/resume-fallback-env.test.d.ts.map +1 -0
- package/dist/__tests__/resume-fallback-env.test.js +28 -0
- package/dist/__tests__/resume-fallback-env.test.js.map +1 -0
- package/dist/__tests__/run-journal.test.d.ts +2 -0
- package/dist/__tests__/run-journal.test.d.ts.map +1 -0
- package/dist/__tests__/run-journal.test.js +121 -0
- package/dist/__tests__/run-journal.test.js.map +1 -0
- package/dist/__tests__/run-start-gate.test.d.ts +2 -0
- package/dist/__tests__/run-start-gate.test.d.ts.map +1 -0
- package/dist/__tests__/run-start-gate.test.js +18 -0
- package/dist/__tests__/run-start-gate.test.js.map +1 -0
- package/dist/__tests__/runtime-capabilities-sync.test.d.ts +2 -0
- package/dist/__tests__/runtime-capabilities-sync.test.d.ts.map +1 -0
- package/dist/__tests__/runtime-capabilities-sync.test.js +66 -0
- package/dist/__tests__/runtime-capabilities-sync.test.js.map +1 -0
- package/dist/__tests__/runtime-config.test.d.ts +2 -0
- package/dist/__tests__/runtime-config.test.d.ts.map +1 -0
- package/dist/__tests__/runtime-config.test.js +137 -0
- package/dist/__tests__/runtime-config.test.js.map +1 -0
- package/dist/__tests__/runtime-presenter-heartbeat.test.d.ts +2 -0
- package/dist/__tests__/runtime-presenter-heartbeat.test.d.ts.map +1 -0
- package/dist/__tests__/runtime-presenter-heartbeat.test.js +253 -0
- package/dist/__tests__/runtime-presenter-heartbeat.test.js.map +1 -0
- package/dist/__tests__/runtime-registration.test.d.ts +2 -0
- package/dist/__tests__/runtime-registration.test.d.ts.map +1 -0
- package/dist/__tests__/runtime-registration.test.js +109 -0
- package/dist/__tests__/runtime-registration.test.js.map +1 -0
- package/dist/__tests__/sandbox-outbox-storage.test.d.ts +2 -0
- package/dist/__tests__/sandbox-outbox-storage.test.d.ts.map +1 -0
- package/dist/__tests__/sandbox-outbox-storage.test.js +81 -0
- package/dist/__tests__/sandbox-outbox-storage.test.js.map +1 -0
- package/dist/__tests__/sandbox-outbox.test.d.ts +2 -0
- package/dist/__tests__/sandbox-outbox.test.d.ts.map +1 -0
- package/dist/__tests__/sandbox-outbox.test.js +300 -0
- package/dist/__tests__/sandbox-outbox.test.js.map +1 -0
- package/dist/__tests__/sandbox-workflow-context.test.d.ts +2 -0
- package/dist/__tests__/sandbox-workflow-context.test.d.ts.map +1 -0
- package/dist/__tests__/sandbox-workflow-context.test.js +600 -0
- package/dist/__tests__/sandbox-workflow-context.test.js.map +1 -0
- package/dist/__tests__/service-manager-deadline.test.d.ts +2 -0
- package/dist/__tests__/service-manager-deadline.test.d.ts.map +1 -0
- package/dist/__tests__/service-manager-deadline.test.js +36 -0
- package/dist/__tests__/service-manager-deadline.test.js.map +1 -0
- package/dist/__tests__/service-manager.test.d.ts +2 -0
- package/dist/__tests__/service-manager.test.d.ts.map +1 -0
- package/dist/__tests__/service-manager.test.js +769 -0
- package/dist/__tests__/service-manager.test.js.map +1 -0
- package/dist/__tests__/service-stop-ownership.test.d.ts +2 -0
- package/dist/__tests__/service-stop-ownership.test.d.ts.map +1 -0
- package/dist/__tests__/service-stop-ownership.test.js +89 -0
- package/dist/__tests__/service-stop-ownership.test.js.map +1 -0
- package/dist/__tests__/skill-invocation.test.d.ts +2 -0
- package/dist/__tests__/skill-invocation.test.d.ts.map +1 -0
- package/dist/__tests__/skill-invocation.test.js +40 -0
- package/dist/__tests__/skill-invocation.test.js.map +1 -0
- package/dist/__tests__/sleep-inhibitor-real.test.d.ts +2 -0
- package/dist/__tests__/sleep-inhibitor-real.test.d.ts.map +1 -0
- package/dist/__tests__/sleep-inhibitor-real.test.js +68 -0
- package/dist/__tests__/sleep-inhibitor-real.test.js.map +1 -0
- package/dist/__tests__/sleep-inhibitor.test.d.ts +2 -0
- package/dist/__tests__/sleep-inhibitor.test.d.ts.map +1 -0
- package/dist/__tests__/sleep-inhibitor.test.js +236 -0
- package/dist/__tests__/sleep-inhibitor.test.js.map +1 -0
- package/dist/__tests__/status-local-workspace.test.d.ts +2 -0
- package/dist/__tests__/status-local-workspace.test.d.ts.map +1 -0
- package/dist/__tests__/status-local-workspace.test.js +121 -0
- package/dist/__tests__/status-local-workspace.test.js.map +1 -0
- package/dist/__tests__/suspension-detector.test.d.ts +2 -0
- package/dist/__tests__/suspension-detector.test.d.ts.map +1 -0
- package/dist/__tests__/suspension-detector.test.js +112 -0
- package/dist/__tests__/suspension-detector.test.js.map +1 -0
- package/dist/__tests__/web-presenter-parent-events.test.d.ts +2 -0
- package/dist/__tests__/web-presenter-parent-events.test.d.ts.map +1 -0
- package/dist/__tests__/web-presenter-parent-events.test.js +168 -0
- package/dist/__tests__/web-presenter-parent-events.test.js.map +1 -0
- package/dist/__tests__/workspace-probe-concurrency.test.d.ts +2 -0
- package/dist/__tests__/workspace-probe-concurrency.test.d.ts.map +1 -0
- package/dist/__tests__/workspace-probe-concurrency.test.js +54 -0
- package/dist/__tests__/workspace-probe-concurrency.test.js.map +1 -0
- package/dist/__tests__/workspace-relocation.test.d.ts +2 -0
- package/dist/__tests__/workspace-relocation.test.d.ts.map +1 -0
- package/dist/__tests__/workspace-relocation.test.js +66 -0
- package/dist/__tests__/workspace-relocation.test.js.map +1 -0
- package/dist/__tests__/workspace-rpc.test.d.ts +2 -0
- package/dist/__tests__/workspace-rpc.test.d.ts.map +1 -0
- package/dist/__tests__/workspace-rpc.test.js +90 -0
- package/dist/__tests__/workspace-rpc.test.js.map +1 -0
- package/dist/__tests__/workspace-run-lease.test.d.ts +2 -0
- package/dist/__tests__/workspace-run-lease.test.d.ts.map +1 -0
- package/dist/__tests__/workspace-run-lease.test.js +331 -0
- package/dist/__tests__/workspace-run-lease.test.js.map +1 -0
- package/dist/__tests__/ws-client-connection.test.d.ts +2 -0
- package/dist/__tests__/ws-client-connection.test.d.ts.map +1 -0
- package/dist/__tests__/ws-client-connection.test.js +295 -0
- package/dist/__tests__/ws-client-connection.test.js.map +1 -0
- package/dist/__tests__/ws-client-heartbeat-volatile.test.d.ts +2 -0
- package/dist/__tests__/ws-client-heartbeat-volatile.test.d.ts.map +1 -0
- package/dist/__tests__/ws-client-heartbeat-volatile.test.js +63 -0
- package/dist/__tests__/ws-client-heartbeat-volatile.test.js.map +1 -0
- package/dist/__tests__/ws-client-heartbeat.integration.test.d.ts +2 -0
- package/dist/__tests__/ws-client-heartbeat.integration.test.d.ts.map +1 -0
- package/dist/__tests__/ws-client-heartbeat.integration.test.js +236 -0
- package/dist/__tests__/ws-client-heartbeat.integration.test.js.map +1 -0
- package/dist/__tests__/ws-client-user-message-ack.integration.test.d.ts +2 -0
- package/dist/__tests__/ws-client-user-message-ack.integration.test.d.ts.map +1 -0
- package/dist/__tests__/ws-client-user-message-ack.integration.test.js +211 -0
- package/dist/__tests__/ws-client-user-message-ack.integration.test.js.map +1 -0
- package/dist/antigravity-api-key-config.d.ts +2 -0
- package/dist/antigravity-api-key-config.d.ts.map +1 -0
- package/dist/antigravity-api-key-config.js +79 -0
- package/dist/antigravity-api-key-config.js.map +1 -0
- package/dist/binding-switch-git.d.ts +26 -0
- package/dist/binding-switch-git.d.ts.map +1 -0
- package/dist/binding-switch-git.js +871 -0
- package/dist/binding-switch-git.js.map +1 -0
- package/dist/cli-ensure-install.d.ts +34 -0
- package/dist/cli-ensure-install.d.ts.map +1 -0
- package/dist/cli-ensure-install.js +154 -0
- package/dist/cli-ensure-install.js.map +1 -0
- package/dist/cli-executable.d.ts +44 -0
- package/dist/cli-executable.d.ts.map +1 -0
- package/dist/cli-executable.js +435 -0
- package/dist/cli-executable.js.map +1 -0
- package/dist/cli-help.d.ts +11 -0
- package/dist/cli-help.d.ts.map +1 -0
- package/dist/cli-help.js +65 -0
- package/dist/cli-help.js.map +1 -0
- package/dist/computer-readiness.d.ts +41 -0
- package/dist/computer-readiness.d.ts.map +1 -0
- package/dist/computer-readiness.js +191 -0
- package/dist/computer-readiness.js.map +1 -0
- package/dist/core-agent.d.ts +32 -0
- package/dist/core-agent.d.ts.map +1 -0
- package/dist/core-agent.js +331 -0
- package/dist/core-agent.js.map +1 -0
- package/dist/daemon-execute.d.ts +42 -0
- package/dist/daemon-execute.d.ts.map +1 -0
- package/dist/daemon-execute.js +666 -0
- package/dist/daemon-execute.js.map +1 -0
- package/dist/daemon-helpers.d.ts +150 -0
- package/dist/daemon-helpers.d.ts.map +1 -0
- package/dist/daemon-helpers.js +157 -0
- package/dist/daemon-helpers.js.map +1 -0
- package/dist/daemon-local-control.d.ts +208 -0
- package/dist/daemon-local-control.d.ts.map +1 -0
- package/dist/daemon-local-control.js +826 -0
- package/dist/daemon-local-control.js.map +1 -0
- package/dist/daemon-local-http.d.ts +57 -0
- package/dist/daemon-local-http.d.ts.map +1 -0
- package/dist/daemon-local-http.js +375 -0
- package/dist/daemon-local-http.js.map +1 -0
- package/dist/daemon-native-hooks.d.ts +17 -0
- package/dist/daemon-native-hooks.d.ts.map +1 -0
- package/dist/daemon-native-hooks.js +54 -0
- package/dist/daemon-native-hooks.js.map +1 -0
- package/dist/daemon-provider-scan.d.ts +33 -0
- package/dist/daemon-provider-scan.d.ts.map +1 -0
- package/dist/daemon-provider-scan.js +187 -0
- package/dist/daemon-provider-scan.js.map +1 -0
- package/dist/daemon-runner-status.d.ts +164 -0
- package/dist/daemon-runner-status.d.ts.map +1 -0
- package/dist/daemon-runner-status.js +424 -0
- package/dist/daemon-runner-status.js.map +1 -0
- package/dist/daemon-start.d.ts +5 -0
- package/dist/daemon-start.d.ts.map +1 -0
- package/dist/daemon-start.js +1313 -0
- package/dist/daemon-start.js.map +1 -0
- package/dist/daemon-workspace.d.ts +36 -0
- package/dist/daemon-workspace.d.ts.map +1 -0
- package/dist/daemon-workspace.js +154 -0
- package/dist/daemon-workspace.js.map +1 -0
- package/dist/daemon.d.ts +59 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +681 -0
- package/dist/daemon.js.map +1 -0
- package/dist/event-journal-crypto.d.ts +14 -0
- package/dist/event-journal-crypto.d.ts.map +1 -0
- package/dist/event-journal-crypto.js +89 -0
- package/dist/event-journal-crypto.js.map +1 -0
- package/dist/event-journal-paths.d.ts +10 -0
- package/dist/event-journal-paths.d.ts.map +1 -0
- package/dist/event-journal-paths.js +29 -0
- package/dist/event-journal-paths.js.map +1 -0
- package/dist/event-journal-recovery.d.ts +83 -0
- package/dist/event-journal-recovery.d.ts.map +1 -0
- package/dist/event-journal-recovery.js +333 -0
- package/dist/event-journal-recovery.js.map +1 -0
- package/dist/event-journal-types.d.ts +54 -0
- package/dist/event-journal-types.d.ts.map +1 -0
- package/dist/event-journal-types.js +10 -0
- package/dist/event-journal-types.js.map +1 -0
- package/dist/event-journal-writer.d.ts +44 -0
- package/dist/event-journal-writer.d.ts.map +1 -0
- package/dist/event-journal-writer.js +182 -0
- package/dist/event-journal-writer.js.map +1 -0
- package/dist/event-outbox.d.ts +113 -0
- package/dist/event-outbox.d.ts.map +1 -0
- package/dist/event-outbox.js +707 -0
- package/dist/event-outbox.js.map +1 -0
- package/dist/execution-activity-tracker.d.ts +43 -0
- package/dist/execution-activity-tracker.d.ts.map +1 -0
- package/dist/execution-activity-tracker.js +116 -0
- package/dist/execution-activity-tracker.js.map +1 -0
- package/dist/execution-lease-client.d.ts +62 -0
- package/dist/execution-lease-client.d.ts.map +1 -0
- package/dist/execution-lease-client.js +271 -0
- package/dist/execution-lease-client.js.map +1 -0
- package/dist/fake-provider-cli.d.ts +13 -0
- package/dist/fake-provider-cli.d.ts.map +1 -0
- package/dist/fake-provider-cli.js +53 -0
- package/dist/fake-provider-cli.js.map +1 -0
- package/dist/generated-images.d.ts +2 -0
- package/dist/generated-images.d.ts.map +1 -0
- package/dist/generated-images.js +2 -0
- package/dist/generated-images.js.map +1 -0
- package/dist/index.cjs +47033 -45514
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +224 -0
- package/dist/index.js.map +1 -0
- package/dist/install-command.d.ts +2 -0
- package/dist/install-command.d.ts.map +1 -0
- package/dist/install-command.js +96 -0
- package/dist/install-command.js.map +1 -0
- package/dist/integration-cli.d.ts +14 -0
- package/dist/integration-cli.d.ts.map +1 -0
- package/dist/integration-cli.js +80 -0
- package/dist/integration-cli.js.map +1 -0
- package/dist/lifecycle-logger.d.ts +25 -0
- package/dist/lifecycle-logger.d.ts.map +1 -0
- package/dist/lifecycle-logger.js +73 -0
- package/dist/lifecycle-logger.js.map +1 -0
- package/dist/local-daemon-lifecycle.d.ts +112 -0
- package/dist/local-daemon-lifecycle.d.ts.map +1 -0
- package/dist/local-daemon-lifecycle.js +433 -0
- package/dist/local-daemon-lifecycle.js.map +1 -0
- package/dist/local-git-status.d.ts +14 -0
- package/dist/local-git-status.d.ts.map +1 -0
- package/dist/local-git-status.js +43 -0
- package/dist/local-git-status.js.map +1 -0
- package/dist/managed-mcp.d.ts +7 -0
- package/dist/managed-mcp.d.ts.map +1 -0
- package/dist/managed-mcp.js +16 -0
- package/dist/managed-mcp.js.map +1 -0
- package/dist/mcp-config-adapters.d.ts +57 -0
- package/dist/mcp-config-adapters.d.ts.map +1 -0
- package/dist/mcp-config-adapters.js +929 -0
- package/dist/mcp-config-adapters.js.map +1 -0
- package/dist/mcp-sync.d.ts +44 -0
- package/dist/mcp-sync.d.ts.map +1 -0
- package/dist/mcp-sync.js +68 -0
- package/dist/mcp-sync.js.map +1 -0
- package/dist/model-scan-runner.d.ts +15 -0
- package/dist/model-scan-runner.d.ts.map +1 -0
- package/dist/model-scan-runner.js +56 -0
- package/dist/model-scan-runner.js.map +1 -0
- package/dist/native-hook-command.d.ts +31 -0
- package/dist/native-hook-command.d.ts.map +1 -0
- package/dist/native-hook-command.js +289 -0
- package/dist/native-hook-command.js.map +1 -0
- package/dist/native-hook-config.d.ts +43 -0
- package/dist/native-hook-config.d.ts.map +1 -0
- package/dist/native-hook-config.js +601 -0
- package/dist/native-hook-config.js.map +1 -0
- package/dist/native-hook-drain.d.ts +34 -0
- package/dist/native-hook-drain.d.ts.map +1 -0
- package/dist/native-hook-drain.js +83 -0
- package/dist/native-hook-drain.js.map +1 -0
- package/dist/native-hook-inbox.d.ts +40 -0
- package/dist/native-hook-inbox.d.ts.map +1 -0
- package/dist/native-hook-inbox.js +217 -0
- package/dist/native-hook-inbox.js.map +1 -0
- package/dist/native-project-config.d.ts +11 -0
- package/dist/native-project-config.d.ts.map +1 -0
- package/dist/native-project-config.js +49 -0
- package/dist/native-project-config.js.map +1 -0
- package/dist/native-session.d.ts +20 -0
- package/dist/native-session.d.ts.map +1 -0
- package/dist/native-session.js +213 -0
- package/dist/native-session.js.map +1 -0
- package/dist/native-stream-journal.d.ts +22 -0
- package/dist/native-stream-journal.d.ts.map +1 -0
- package/dist/native-stream-journal.js +98 -0
- package/dist/native-stream-journal.js.map +1 -0
- package/dist/native-stream-outbox.d.ts +40 -0
- package/dist/native-stream-outbox.d.ts.map +1 -0
- package/dist/native-stream-outbox.js +358 -0
- package/dist/native-stream-outbox.js.map +1 -0
- package/dist/native-stream-platform.d.ts +4 -0
- package/dist/native-stream-platform.d.ts.map +1 -0
- package/dist/native-stream-platform.js +11 -0
- package/dist/native-stream-platform.js.map +1 -0
- package/dist/native-transcript-cursor.d.ts +33 -0
- package/dist/native-transcript-cursor.d.ts.map +1 -0
- package/dist/native-transcript-cursor.js +108 -0
- package/dist/native-transcript-cursor.js.map +1 -0
- package/dist/native-transcript-stream.d.ts +20 -0
- package/dist/native-transcript-stream.d.ts.map +1 -0
- package/dist/native-transcript-stream.js +438 -0
- package/dist/native-transcript-stream.js.map +1 -0
- package/dist/network-diagnostics.d.ts +8 -0
- package/dist/network-diagnostics.d.ts.map +1 -0
- package/dist/network-diagnostics.js +56 -0
- package/dist/network-diagnostics.js.map +1 -0
- package/dist/observable-map.d.ts +13 -0
- package/dist/observable-map.d.ts.map +1 -0
- package/dist/observable-map.js +30 -0
- package/dist/observable-map.js.map +1 -0
- package/dist/provider-auth-preflight.d.ts +19 -0
- package/dist/provider-auth-preflight.d.ts.map +1 -0
- package/dist/provider-auth-preflight.js +107 -0
- package/dist/provider-auth-preflight.js.map +1 -0
- package/dist/provider-model-discovery.d.ts +33 -0
- package/dist/provider-model-discovery.d.ts.map +1 -0
- package/dist/provider-model-discovery.js +731 -0
- package/dist/provider-model-discovery.js.map +1 -0
- package/dist/resource-diagnostics.d.ts +21 -0
- package/dist/resource-diagnostics.d.ts.map +1 -0
- package/dist/resource-diagnostics.js +161 -0
- package/dist/resource-diagnostics.js.map +1 -0
- package/dist/resume-fallback-env.d.ts +3 -0
- package/dist/resume-fallback-env.d.ts.map +1 -0
- package/dist/resume-fallback-env.js +14 -0
- package/dist/resume-fallback-env.js.map +1 -0
- package/dist/run-journal.d.ts +51 -0
- package/dist/run-journal.d.ts.map +1 -0
- package/dist/run-journal.js +193 -0
- package/dist/run-journal.js.map +1 -0
- package/dist/runtime-backends.d.ts +2 -0
- package/dist/runtime-backends.d.ts.map +1 -0
- package/dist/runtime-backends.js +2 -0
- package/dist/runtime-backends.js.map +1 -0
- package/dist/runtime-capabilities-sync.d.ts +40 -0
- package/dist/runtime-capabilities-sync.d.ts.map +1 -0
- package/dist/runtime-capabilities-sync.js +56 -0
- package/dist/runtime-capabilities-sync.js.map +1 -0
- package/dist/runtime-config.d.ts +26 -0
- package/dist/runtime-config.d.ts.map +1 -0
- package/dist/runtime-config.js +170 -0
- package/dist/runtime-config.js.map +1 -0
- package/dist/runtime-presenter.d.ts +81 -0
- package/dist/runtime-presenter.d.ts.map +1 -0
- package/dist/runtime-presenter.js +422 -0
- package/dist/runtime-presenter.js.map +1 -0
- package/dist/runtime-registration.d.ts +40 -0
- package/dist/runtime-registration.d.ts.map +1 -0
- package/dist/runtime-registration.js +143 -0
- package/dist/runtime-registration.js.map +1 -0
- package/dist/sandbox-outbox-storage.d.ts +13 -0
- package/dist/sandbox-outbox-storage.d.ts.map +1 -0
- package/dist/sandbox-outbox-storage.js +98 -0
- package/dist/sandbox-outbox-storage.js.map +1 -0
- package/dist/sandbox-outbox.d.ts +115 -0
- package/dist/sandbox-outbox.d.ts.map +1 -0
- package/dist/sandbox-outbox.js +213 -0
- package/dist/sandbox-outbox.js.map +1 -0
- package/dist/sandbox.d.ts +34 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +469 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/service-manager.d.ts +113 -0
- package/dist/service-manager.d.ts.map +1 -0
- package/dist/service-manager.js +1065 -0
- package/dist/service-manager.js.map +1 -0
- package/dist/skills/__tests__/local-skill-source.test.d.ts +2 -0
- package/dist/skills/__tests__/local-skill-source.test.d.ts.map +1 -0
- package/dist/skills/__tests__/local-skill-source.test.js +373 -0
- package/dist/skills/__tests__/local-skill-source.test.js.map +1 -0
- package/dist/skills/__tests__/managed-skill-store.test.d.ts +2 -0
- package/dist/skills/__tests__/managed-skill-store.test.d.ts.map +1 -0
- package/dist/skills/__tests__/managed-skill-store.test.js +114 -0
- package/dist/skills/__tests__/managed-skill-store.test.js.map +1 -0
- package/dist/skills/__tests__/runtime-skill-coordinator.test.d.ts +2 -0
- package/dist/skills/__tests__/runtime-skill-coordinator.test.d.ts.map +1 -0
- package/dist/skills/__tests__/runtime-skill-coordinator.test.js +251 -0
- package/dist/skills/__tests__/runtime-skill-coordinator.test.js.map +1 -0
- package/dist/skills/__tests__/runtime-skill-manager.test.d.ts +2 -0
- package/dist/skills/__tests__/runtime-skill-manager.test.d.ts.map +1 -0
- package/dist/skills/__tests__/runtime-skill-manager.test.js +664 -0
- package/dist/skills/__tests__/runtime-skill-manager.test.js.map +1 -0
- package/dist/skills/__tests__/skill-bundle.test.d.ts +2 -0
- package/dist/skills/__tests__/skill-bundle.test.d.ts.map +1 -0
- package/dist/skills/__tests__/skill-bundle.test.js +42 -0
- package/dist/skills/__tests__/skill-bundle.test.js.map +1 -0
- package/dist/skills/__tests__/skill-control-client.test.d.ts +2 -0
- package/dist/skills/__tests__/skill-control-client.test.d.ts.map +1 -0
- package/dist/skills/__tests__/skill-control-client.test.js +49 -0
- package/dist/skills/__tests__/skill-control-client.test.js.map +1 -0
- package/dist/skills/__tests__/skill-source-config.test.d.ts +2 -0
- package/dist/skills/__tests__/skill-source-config.test.d.ts.map +1 -0
- package/dist/skills/__tests__/skill-source-config.test.js +295 -0
- package/dist/skills/__tests__/skill-source-config.test.js.map +1 -0
- package/dist/skills/local-skill-source.d.ts +77 -0
- package/dist/skills/local-skill-source.d.ts.map +1 -0
- package/dist/skills/local-skill-source.js +660 -0
- package/dist/skills/local-skill-source.js.map +1 -0
- package/dist/skills/managed-skill-store.d.ts +44 -0
- package/dist/skills/managed-skill-store.d.ts.map +1 -0
- package/dist/skills/managed-skill-store.js +160 -0
- package/dist/skills/managed-skill-store.js.map +1 -0
- package/dist/skills/runtime-skill-coordinator.d.ts +35 -0
- package/dist/skills/runtime-skill-coordinator.d.ts.map +1 -0
- package/dist/skills/runtime-skill-coordinator.js +166 -0
- package/dist/skills/runtime-skill-coordinator.js.map +1 -0
- package/dist/skills/runtime-skill-manager.d.ts +89 -0
- package/dist/skills/runtime-skill-manager.d.ts.map +1 -0
- package/dist/skills/runtime-skill-manager.js +934 -0
- package/dist/skills/runtime-skill-manager.js.map +1 -0
- package/dist/skills/skill-bundle.d.ts +2 -0
- package/dist/skills/skill-bundle.d.ts.map +1 -0
- package/dist/skills/skill-bundle.js +2 -0
- package/dist/skills/skill-bundle.js.map +1 -0
- package/dist/skills/skill-cli.d.ts +2 -0
- package/dist/skills/skill-cli.d.ts.map +1 -0
- package/dist/skills/skill-cli.js +81 -0
- package/dist/skills/skill-cli.js.map +1 -0
- package/dist/skills/skill-control-client.d.ts +20 -0
- package/dist/skills/skill-control-client.d.ts.map +1 -0
- package/dist/skills/skill-control-client.js +56 -0
- package/dist/skills/skill-control-client.js.map +1 -0
- package/dist/skills/skill-invocation.d.ts +10 -0
- package/dist/skills/skill-invocation.d.ts.map +1 -0
- package/dist/skills/skill-invocation.js +24 -0
- package/dist/skills/skill-invocation.js.map +1 -0
- package/dist/sleep-inhibitor.d.ts +32 -0
- package/dist/sleep-inhibitor.d.ts.map +1 -0
- package/dist/sleep-inhibitor.js +297 -0
- package/dist/sleep-inhibitor.js.map +1 -0
- package/dist/suspension-detector.d.ts +24 -0
- package/dist/suspension-detector.d.ts.map +1 -0
- package/dist/suspension-detector.js +59 -0
- package/dist/suspension-detector.js.map +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/dist/web-presenter.d.ts +52 -0
- package/dist/web-presenter.d.ts.map +1 -0
- package/dist/web-presenter.js +264 -0
- package/dist/web-presenter.js.map +1 -0
- package/dist/workspace-relocation.d.ts +22 -0
- package/dist/workspace-relocation.d.ts.map +1 -0
- package/dist/workspace-relocation.js +90 -0
- package/dist/workspace-relocation.js.map +1 -0
- package/dist/workspace-rpc.d.ts +2 -0
- package/dist/workspace-rpc.d.ts.map +1 -0
- package/dist/workspace-rpc.js +15 -0
- package/dist/workspace-rpc.js.map +1 -0
- package/dist/workspace-run-lease.d.ts +116 -0
- package/dist/workspace-run-lease.d.ts.map +1 -0
- package/dist/workspace-run-lease.js +320 -0
- package/dist/workspace-run-lease.js.map +1 -0
- package/dist/ws-client.d.ts +168 -0
- package/dist/ws-client.d.ts.map +1 -0
- package/dist/ws-client.js +440 -0
- package/dist/ws-client.js.map +1 -0
- package/package.json +4 -3
|
@@ -0,0 +1,934 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
3
|
+
import { cp, lstat, mkdir, readdir, readFile, readlink, rename, rm, stat, symlink, writeFile, } from "node:fs/promises";
|
|
4
|
+
import { dirname, join, resolve } from "node:path";
|
|
5
|
+
import { inspectSkillPackage, readSkillPackageFile } from "@alan-ai/shared/node/skill-package";
|
|
6
|
+
import { desiredSkillManifestSchema, SKILL_PACKAGE_LIMITS, SKILLS_PROTOCOL_VERSION, } from "@alan-ai/shared/skills";
|
|
7
|
+
import { LocalSkillSource } from "./local-skill-source.js";
|
|
8
|
+
import { ManagedSkillStore } from "./managed-skill-store.js";
|
|
9
|
+
import { createSkillBundle, extractSkillBundle } from "./skill-bundle.js";
|
|
10
|
+
import { uploadPreparedSkillBundle } from "./skill-control-client.js";
|
|
11
|
+
export class RuntimeSkillManager {
|
|
12
|
+
skillsStateDirectory;
|
|
13
|
+
managedSkillsDirectory;
|
|
14
|
+
compatibilitySkillsDirectory;
|
|
15
|
+
legacyManifestPath;
|
|
16
|
+
storageNamespace;
|
|
17
|
+
store;
|
|
18
|
+
downloadBundle;
|
|
19
|
+
localSource;
|
|
20
|
+
controlClient;
|
|
21
|
+
reconcileTail = Promise.resolve();
|
|
22
|
+
constructor(skillsStateDirectory, managedSkillsDirectory, compatibilitySkillsDirectory, legacyManifestPath, storageNamespace, store, downloadBundle, localSource, controlClient) {
|
|
23
|
+
this.skillsStateDirectory = skillsStateDirectory;
|
|
24
|
+
this.managedSkillsDirectory = managedSkillsDirectory;
|
|
25
|
+
this.compatibilitySkillsDirectory = compatibilitySkillsDirectory;
|
|
26
|
+
this.legacyManifestPath = legacyManifestPath;
|
|
27
|
+
this.storageNamespace = storageNamespace;
|
|
28
|
+
this.store = store;
|
|
29
|
+
this.downloadBundle = downloadBundle;
|
|
30
|
+
this.localSource = localSource;
|
|
31
|
+
this.controlClient = controlClient;
|
|
32
|
+
}
|
|
33
|
+
static async open(options) {
|
|
34
|
+
const storageNamespace = resolveStorageNamespace(options.endpointProfile, options.profileStorageIdentity);
|
|
35
|
+
const skillsStateDirectory = storageNamespace
|
|
36
|
+
? join(options.homeDirectory, ".alan", "skills", "profiles", storageNamespace)
|
|
37
|
+
: join(options.homeDirectory, ".alan", "skills");
|
|
38
|
+
const managedSkillsDirectory = join(options.homeDirectory, ".agents", "skills");
|
|
39
|
+
const store = await ManagedSkillStore.open(skillsStateDirectory);
|
|
40
|
+
return new RuntimeSkillManager(skillsStateDirectory, managedSkillsDirectory, join(options.homeDirectory, ".claude", "skills"), join(options.homeDirectory, ".alan", "sync-manifest.json"), storageNamespace, store, options.downloadBundle ?? downloadBundleWithFetch, options.localSource ?? new LocalSkillSource(), options.controlClient);
|
|
41
|
+
}
|
|
42
|
+
async scan(input) {
|
|
43
|
+
const outcome = await this.localSource.scan(input);
|
|
44
|
+
if (outcome.status === "complete") {
|
|
45
|
+
await this.store.recordCompleteScan({
|
|
46
|
+
revision: outcome.inventoryRevision,
|
|
47
|
+
candidates: outcome.candidates.map((candidate) => {
|
|
48
|
+
const absolutePath = this.localSource.resolvePackage(candidate.localKey);
|
|
49
|
+
if (!absolutePath)
|
|
50
|
+
throw new Error(`Complete scan lost source for ${candidate.localKey}`);
|
|
51
|
+
return {
|
|
52
|
+
localKey: candidate.localKey,
|
|
53
|
+
absolutePath,
|
|
54
|
+
contentHash: candidate.contentHash,
|
|
55
|
+
};
|
|
56
|
+
}),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return outcome;
|
|
60
|
+
}
|
|
61
|
+
async publish(input) {
|
|
62
|
+
const source = this.store.resolveSource(input.localKey);
|
|
63
|
+
if (!source)
|
|
64
|
+
throw new Error("Skill source is not present in the last complete scan");
|
|
65
|
+
if (source.contentHash !== input.expectedContentHash) {
|
|
66
|
+
throw new Error("Skill source changed after the preview was requested; refresh and review again");
|
|
67
|
+
}
|
|
68
|
+
if (Date.parse(input.uploadGrant.expiresAt) <= Date.now()) {
|
|
69
|
+
throw new Error("Skill upload grant expired; retry the preview");
|
|
70
|
+
}
|
|
71
|
+
const bundle = await createSkillBundle(source.absolutePath);
|
|
72
|
+
if (bundle.contentHash !== input.expectedContentHash) {
|
|
73
|
+
throw new Error("Skill source changed while preparing the preview; refresh and review again");
|
|
74
|
+
}
|
|
75
|
+
if (bundle.bytes.byteLength > input.uploadGrant.maxBytes) {
|
|
76
|
+
throw new Error("Prepared Skill bundle exceeds its upload grant limit");
|
|
77
|
+
}
|
|
78
|
+
await (this.controlClient
|
|
79
|
+
? this.controlClient.uploadPreparedBundle(input.uploadGrant, bundle.bytes)
|
|
80
|
+
: uploadPreparedSkillBundle(input.uploadGrant, bundle.bytes));
|
|
81
|
+
return {
|
|
82
|
+
commandId: input.commandId,
|
|
83
|
+
previewId: input.previewId,
|
|
84
|
+
localKey: input.localKey,
|
|
85
|
+
contentHash: bundle.contentHash,
|
|
86
|
+
archiveHash: bundle.archiveHash,
|
|
87
|
+
compressedBytes: bundle.bytes.byteLength,
|
|
88
|
+
state: "uploaded",
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
async inspectLocalPackage(input) {
|
|
92
|
+
const source = this.requireCurrentLocalSource(input);
|
|
93
|
+
const inspected = await this.localSource.inspectPackage(source.absolutePath, input.expectedContentHash);
|
|
94
|
+
if (inspected.contentHash !== input.expectedContentHash) {
|
|
95
|
+
throw new Error("Skill source changed after the last scan; scan folders again");
|
|
96
|
+
}
|
|
97
|
+
const preview = {
|
|
98
|
+
localKey: input.localKey,
|
|
99
|
+
package: {
|
|
100
|
+
path: inspected.metadata.name,
|
|
101
|
+
name: inspected.metadata.name,
|
|
102
|
+
description: inspected.metadata.description,
|
|
103
|
+
contentHash: inspected.contentHash,
|
|
104
|
+
fileCount: inspected.fileCount,
|
|
105
|
+
totalBytes: inspected.totalBytes,
|
|
106
|
+
files: inspected.files,
|
|
107
|
+
diagnostics: inspected.diagnostics,
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
return preview;
|
|
111
|
+
}
|
|
112
|
+
async readLocalPackageFile(input) {
|
|
113
|
+
const source = this.requireCurrentLocalSource(input);
|
|
114
|
+
const { file, bytes } = await readSkillPackageFile(source.absolutePath, input.path, input.expectedFileHash);
|
|
115
|
+
if (file.preview === "markdown" || file.preview === "text" || file.preview === "code") {
|
|
116
|
+
return {
|
|
117
|
+
file,
|
|
118
|
+
encoding: "utf8",
|
|
119
|
+
content: new TextDecoder("utf-8", { fatal: true }).decode(bytes),
|
|
120
|
+
mediaType: localTextMediaType(file.path),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
const mediaType = localRasterMediaType(file.path);
|
|
124
|
+
if (file.preview === "image" && mediaType && bytes.byteLength <= 2 * 1024 * 1024) {
|
|
125
|
+
return { file, encoding: "base64", content: bytes.toString("base64"), mediaType };
|
|
126
|
+
}
|
|
127
|
+
return { file, encoding: "metadata", ...(mediaType ? { mediaType } : {}) };
|
|
128
|
+
}
|
|
129
|
+
requireCurrentLocalSource(input) {
|
|
130
|
+
const source = this.store.resolveSource(input.localKey);
|
|
131
|
+
if (!source)
|
|
132
|
+
throw new Error("Skill source is not present in the last complete scan");
|
|
133
|
+
if (source.contentHash !== input.expectedContentHash) {
|
|
134
|
+
throw new Error("Skill source changed after the last scan; scan folders again");
|
|
135
|
+
}
|
|
136
|
+
return source;
|
|
137
|
+
}
|
|
138
|
+
async reconcile(input) {
|
|
139
|
+
return this.runExclusively(() => this.withMachineLock(() => this.reconcileUnlocked(input.manifest)));
|
|
140
|
+
}
|
|
141
|
+
async resolveConflict(input) {
|
|
142
|
+
return this.runExclusively(() => this.withMachineLock(() => this.resolveConflictUnlocked(input)));
|
|
143
|
+
}
|
|
144
|
+
async inspect() {
|
|
145
|
+
const status = this.store.inspect();
|
|
146
|
+
return {
|
|
147
|
+
stateIntegrity: status.integrity,
|
|
148
|
+
appliedRevision: status.appliedRevision,
|
|
149
|
+
projectionCount: status.projectionCount,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Resolve a server-authorized invocation to the exact package currently on disk.
|
|
154
|
+
* Display names are deliberately ignored: identity and observed content must match.
|
|
155
|
+
*/
|
|
156
|
+
async resolveInvocation(runtimeId, invocation) {
|
|
157
|
+
if (invocation.kind === "local_skill") {
|
|
158
|
+
if (invocation.runtimeId !== runtimeId) {
|
|
159
|
+
throw new Error("Selected local Skill belongs to a different runtime");
|
|
160
|
+
}
|
|
161
|
+
const source = this.store.resolveSource(invocation.localKey);
|
|
162
|
+
if (!source || source.contentHash !== invocation.contentHash) {
|
|
163
|
+
throw new Error("Selected local Skill is no longer present in the last complete scan");
|
|
164
|
+
}
|
|
165
|
+
const inspected = await inspectSkillPackage(source.absolutePath, { expectedName: null });
|
|
166
|
+
if (inspected.contentHash !== invocation.contentHash) {
|
|
167
|
+
throw new Error("Selected local Skill changed after it was chosen; refresh the picker");
|
|
168
|
+
}
|
|
169
|
+
return { invocation, packageDirectory: source.absolutePath };
|
|
170
|
+
}
|
|
171
|
+
const runtimeDirectory = this.store.runtimeDirectoryFor(invocation.skillId, invocation.versionId);
|
|
172
|
+
if (!runtimeDirectory) {
|
|
173
|
+
throw new Error("Selected Skill version is not installed on this runtime");
|
|
174
|
+
}
|
|
175
|
+
const packageDirectory = this.projectionDirectory(runtimeDirectory);
|
|
176
|
+
const marker = await readMarker(packageDirectory);
|
|
177
|
+
if (!marker ||
|
|
178
|
+
marker.skillId !== invocation.skillId ||
|
|
179
|
+
marker.versionId !== invocation.versionId) {
|
|
180
|
+
throw new Error("Selected Skill projection is missing or no longer owned by Alan");
|
|
181
|
+
}
|
|
182
|
+
const inspected = await inspectSkillPackage(packageDirectory, { expectedName: null });
|
|
183
|
+
if (inspected.contentHash !== marker.contentHash) {
|
|
184
|
+
throw new Error("Selected Skill projection failed its content verification");
|
|
185
|
+
}
|
|
186
|
+
return { invocation, packageDirectory };
|
|
187
|
+
}
|
|
188
|
+
async reconcileUnlocked(manifest) {
|
|
189
|
+
const desired = desiredSkillManifestSchema.parse(manifest);
|
|
190
|
+
await mkdir(this.managedSkillsDirectory, { recursive: true, mode: 0o700 });
|
|
191
|
+
await mkdir(join(this.skillsStateDirectory, "cache", "sha256"), {
|
|
192
|
+
recursive: true,
|
|
193
|
+
mode: 0o700,
|
|
194
|
+
});
|
|
195
|
+
await mkdir(join(this.skillsStateDirectory, "tmp"), { recursive: true, mode: 0o700 });
|
|
196
|
+
const results = [];
|
|
197
|
+
const nextProjections = {};
|
|
198
|
+
for (const entry of desired.skills) {
|
|
199
|
+
try {
|
|
200
|
+
requireSafeRuntimeDirectory(entry.runtimeDirectory);
|
|
201
|
+
await this.adoptLegacyProjection(entry);
|
|
202
|
+
await this.requireReplaceable(entry);
|
|
203
|
+
const observedHash = await this.reuseCurrentProjection(entry);
|
|
204
|
+
const appliedHash = observedHash ?? (await this.project(entry, await this.ensureCached(entry)));
|
|
205
|
+
nextProjections[entry.runtimeDirectory] = {
|
|
206
|
+
skillId: entry.skillId,
|
|
207
|
+
versionId: entry.versionId,
|
|
208
|
+
contentHash: entry.contentHash,
|
|
209
|
+
};
|
|
210
|
+
results.push({
|
|
211
|
+
skillId: entry.skillId,
|
|
212
|
+
versionId: entry.versionId,
|
|
213
|
+
contentHash: entry.contentHash,
|
|
214
|
+
observedHash: appliedHash,
|
|
215
|
+
state: "applied",
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
const code = errorCode(error);
|
|
220
|
+
const conflict = isUnmanagedConflict(error)
|
|
221
|
+
? await this.observeConflict(entry, code).catch(() => null)
|
|
222
|
+
: null;
|
|
223
|
+
results.push({
|
|
224
|
+
skillId: entry.skillId,
|
|
225
|
+
versionId: entry.versionId,
|
|
226
|
+
contentHash: entry.contentHash,
|
|
227
|
+
state: isUnmanagedConflict(error) ? "conflict" : "failed",
|
|
228
|
+
errorCode: code,
|
|
229
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
230
|
+
...(conflict ? { conflict } : {}),
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (results.every((result) => result.state === "applied")) {
|
|
235
|
+
results.push(...(await this.removeNoLongerDesired(nextProjections)));
|
|
236
|
+
}
|
|
237
|
+
if (results.every((result) => result.state === "applied")) {
|
|
238
|
+
await this.store.recordApplied({ revision: desired.revision, projections: nextProjections });
|
|
239
|
+
await this.retireLegacySyncManifest();
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
attemptId: randomUUID(),
|
|
243
|
+
desiredRevision: desired.revision,
|
|
244
|
+
skills: results,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
async resolveConflictUnlocked(input) {
|
|
248
|
+
const manifest = desiredSkillManifestSchema.parse(input.manifest);
|
|
249
|
+
const entry = manifest.skills.find((candidate) => candidate.skillId === input.skillId && candidate.versionId === input.versionId);
|
|
250
|
+
if (!entry || entry.runtimeDirectory !== input.expectedConflict.runtimeDirectory) {
|
|
251
|
+
return resolutionFailure(input, "stale", "SKILL_CONFLICT_STALE", "The Skill conflict changed. Refresh and try again.");
|
|
252
|
+
}
|
|
253
|
+
const current = await this.observeConflict(entry, input.expectedConflict.kind === "managed_destination"
|
|
254
|
+
? "UNMANAGED_PATH_CONFLICT"
|
|
255
|
+
: "COMPATIBILITY_PATH_CONFLICT").catch(() => null);
|
|
256
|
+
if (!current || !sameConflict(current, input.expectedConflict)) {
|
|
257
|
+
return resolutionFailure(input, "stale", "SKILL_CONFLICT_STALE", "The local Skill changed. Refresh and try again.");
|
|
258
|
+
}
|
|
259
|
+
try {
|
|
260
|
+
if (input.resolution.kind === "rename_local") {
|
|
261
|
+
await this.renameLocalConflict(entry, current, input.resolution.name);
|
|
262
|
+
const reconciled = await this.reconcileUnlocked(manifest);
|
|
263
|
+
return resolutionFromReconcile(input, reconciled);
|
|
264
|
+
}
|
|
265
|
+
return await this.overwriteLocalConflict(input, entry, current, manifest);
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
return resolutionFailure(input, errorCode(error) === "SKILL_CONFLICT_STALE" ? "stale" : "failed", errorCode(error), error instanceof Error ? error.message : String(error));
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
async observeConflict(entry, code) {
|
|
272
|
+
const kind = code === "COMPATIBILITY_PATH_CONFLICT" ? "compatibility_destination" : "managed_destination";
|
|
273
|
+
const directory = this.conflictDirectory(entry.runtimeDirectory, kind);
|
|
274
|
+
const inspected = await inspectSkillPackage(directory, { expectedName: null });
|
|
275
|
+
return {
|
|
276
|
+
kind,
|
|
277
|
+
runtimeDirectory: entry.runtimeDirectory,
|
|
278
|
+
observedHash: inspected.contentHash,
|
|
279
|
+
observedName: inspected.metadata.name,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
conflictDirectory(runtimeDirectory, kind) {
|
|
283
|
+
requireSafeRuntimeDirectory(runtimeDirectory);
|
|
284
|
+
return join(kind === "managed_destination"
|
|
285
|
+
? this.managedSkillsDirectory
|
|
286
|
+
: this.compatibilitySkillsDirectory, this.projectionDirectoryName(runtimeDirectory));
|
|
287
|
+
}
|
|
288
|
+
async renameLocalConflict(entry, conflict, name) {
|
|
289
|
+
requirePortableSkillName(name);
|
|
290
|
+
const source = this.conflictDirectory(entry.runtimeDirectory, conflict.kind);
|
|
291
|
+
const destination = join(dirname(source), name);
|
|
292
|
+
if (await pathExists(destination)) {
|
|
293
|
+
throw Object.assign(new Error(`A local Skill named ${name} already exists`), {
|
|
294
|
+
code: "SKILL_LOCAL_NAME_CONFLICT",
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
const suffix = `${process.pid}-${randomBytes(8).toString("hex")}`;
|
|
298
|
+
const backup = `${source}.rename-backup-${suffix}`;
|
|
299
|
+
const pending = `${source}.rename-pending-${suffix}`;
|
|
300
|
+
let sourceMoved = false;
|
|
301
|
+
let destinationInstalled = false;
|
|
302
|
+
try {
|
|
303
|
+
await rename(source, backup);
|
|
304
|
+
sourceMoved = true;
|
|
305
|
+
await cp(backup, pending, { recursive: true, errorOnExist: true, force: false });
|
|
306
|
+
const skillMarkdown = join(pending, "SKILL.md");
|
|
307
|
+
await writeFile(skillMarkdown, rewriteSkillMarkdownName(await readFile(skillMarkdown, "utf8"), name), {
|
|
308
|
+
encoding: "utf8",
|
|
309
|
+
mode: 0o644,
|
|
310
|
+
});
|
|
311
|
+
await inspectSkillPackage(pending, { expectedName: name });
|
|
312
|
+
await rename(pending, destination);
|
|
313
|
+
destinationInstalled = true;
|
|
314
|
+
await rm(backup, { recursive: true, force: true });
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
if (destinationInstalled)
|
|
318
|
+
await rm(destination, { recursive: true, force: true });
|
|
319
|
+
if (sourceMoved && (await pathExists(backup)) && !(await pathExists(source))) {
|
|
320
|
+
await rename(backup, source);
|
|
321
|
+
}
|
|
322
|
+
throw error;
|
|
323
|
+
}
|
|
324
|
+
finally {
|
|
325
|
+
await rm(pending, { recursive: true, force: true });
|
|
326
|
+
if (!sourceMoved || destinationInstalled) {
|
|
327
|
+
await rm(backup, { recursive: true, force: true });
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
async overwriteLocalConflict(input, entry, conflict, manifest) {
|
|
332
|
+
const source = this.conflictDirectory(entry.runtimeDirectory, conflict.kind);
|
|
333
|
+
const backup = `${source}.overwrite-backup-${process.pid}-${randomBytes(8).toString("hex")}`;
|
|
334
|
+
await rename(source, backup);
|
|
335
|
+
try {
|
|
336
|
+
const reconciled = await this.reconcileUnlocked(manifest);
|
|
337
|
+
const result = resolutionFromReconcile(input, reconciled);
|
|
338
|
+
if (result.state !== "applied") {
|
|
339
|
+
await this.removeResolvedProjection(entry, conflict.kind);
|
|
340
|
+
await rename(backup, source);
|
|
341
|
+
return result;
|
|
342
|
+
}
|
|
343
|
+
await rm(backup, { recursive: true, force: true });
|
|
344
|
+
return result;
|
|
345
|
+
}
|
|
346
|
+
catch (error) {
|
|
347
|
+
await this.removeResolvedProjection(entry, conflict.kind).catch(() => undefined);
|
|
348
|
+
if (!(await pathExists(source)) && (await pathExists(backup)))
|
|
349
|
+
await rename(backup, source);
|
|
350
|
+
throw error;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
async removeResolvedProjection(entry, conflictKind) {
|
|
354
|
+
const destination = this.conflictDirectory(entry.runtimeDirectory, conflictKind);
|
|
355
|
+
if (!(await pathExists(destination)))
|
|
356
|
+
return;
|
|
357
|
+
if (conflictKind === "managed_destination") {
|
|
358
|
+
const marker = await readMarker(destination);
|
|
359
|
+
if (marker?.skillId === entry.skillId &&
|
|
360
|
+
marker.versionId === entry.versionId &&
|
|
361
|
+
marker.contentHash === entry.contentHash) {
|
|
362
|
+
await rm(destination, { recursive: true, force: true });
|
|
363
|
+
}
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
const canonical = this.projectionDirectory(entry.runtimeDirectory);
|
|
367
|
+
const projection = {
|
|
368
|
+
skillId: entry.skillId,
|
|
369
|
+
versionId: entry.versionId,
|
|
370
|
+
contentHash: entry.contentHash,
|
|
371
|
+
};
|
|
372
|
+
await removeCompatibilityProjection(destination, canonical, projection);
|
|
373
|
+
}
|
|
374
|
+
async reuseCurrentProjection(entry) {
|
|
375
|
+
const destination = this.projectionDirectory(entry.runtimeDirectory);
|
|
376
|
+
const marker = await readMarker(destination);
|
|
377
|
+
if (marker?.skillId !== entry.skillId ||
|
|
378
|
+
marker.versionId !== entry.versionId ||
|
|
379
|
+
marker.contentHash !== entry.contentHash ||
|
|
380
|
+
!(await packageMatches(destination, entry.contentHash))) {
|
|
381
|
+
return null;
|
|
382
|
+
}
|
|
383
|
+
await this.ensureCompatibilityProjection(entry, destination);
|
|
384
|
+
return entry.contentHash;
|
|
385
|
+
}
|
|
386
|
+
async adoptLegacyProjection(entry) {
|
|
387
|
+
if (this.storageNamespace)
|
|
388
|
+
return;
|
|
389
|
+
const destination = this.projectionDirectory(entry.runtimeDirectory);
|
|
390
|
+
if (await pathExists(destination))
|
|
391
|
+
return;
|
|
392
|
+
const manifest = await readLegacyManifest(this.legacyManifestPath);
|
|
393
|
+
const legacy = manifest?.skills[entry.slug];
|
|
394
|
+
if (!legacy)
|
|
395
|
+
return;
|
|
396
|
+
const source = join(this.managedSkillsDirectory, entry.slug);
|
|
397
|
+
if (!(await legacyFileMatches(source, legacy.hash)) ||
|
|
398
|
+
!(await packageMatches(source, entry.contentHash))) {
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
await rename(source, destination);
|
|
402
|
+
try {
|
|
403
|
+
await writeFile(join(destination, ".alan-managed.json"), `${JSON.stringify(markerFor(entry), null, 2)}\n`, { encoding: "utf8", flag: "wx", mode: 0o600 });
|
|
404
|
+
}
|
|
405
|
+
catch (error) {
|
|
406
|
+
await rename(destination, source).catch(() => undefined);
|
|
407
|
+
throw error;
|
|
408
|
+
}
|
|
409
|
+
await removeExactLegacySkill(join(this.compatibilitySkillsDirectory, entry.slug), legacy.hash);
|
|
410
|
+
}
|
|
411
|
+
async retireLegacySyncManifest() {
|
|
412
|
+
if (this.storageNamespace)
|
|
413
|
+
return;
|
|
414
|
+
const manifest = await readLegacyManifest(this.legacyManifestPath);
|
|
415
|
+
if (!manifest)
|
|
416
|
+
return;
|
|
417
|
+
for (const [command, entry] of Object.entries(manifest.skills)) {
|
|
418
|
+
await removeExactLegacySkill(join(this.managedSkillsDirectory, command), entry.hash);
|
|
419
|
+
await removeExactLegacySkill(join(this.compatibilitySkillsDirectory, command), entry.hash);
|
|
420
|
+
}
|
|
421
|
+
await rm(this.legacyManifestPath, { force: true });
|
|
422
|
+
}
|
|
423
|
+
async ensureCached(entry) {
|
|
424
|
+
const cacheDirectory = join(this.skillsStateDirectory, "cache", "sha256", entry.contentHash.slice("sha256:".length));
|
|
425
|
+
if (await packageMatches(cacheDirectory, entry.contentHash))
|
|
426
|
+
return cacheDirectory;
|
|
427
|
+
await rm(cacheDirectory, { recursive: true, force: true });
|
|
428
|
+
const bytes = await this.downloadBundle(entry);
|
|
429
|
+
if (bytes.byteLength !== entry.compressedBytes) {
|
|
430
|
+
throw new Error(`Downloaded Skill bundle length ${bytes.byteLength} does not match ${entry.compressedBytes}`);
|
|
431
|
+
}
|
|
432
|
+
const pendingDirectory = join(this.skillsStateDirectory, "tmp", `cache-${process.pid}-${randomBytes(8).toString("hex")}`);
|
|
433
|
+
try {
|
|
434
|
+
await extractSkillBundle(bytes, pendingDirectory, {
|
|
435
|
+
expectedArchiveHash: entry.archiveHash,
|
|
436
|
+
expectedContentHash: entry.contentHash,
|
|
437
|
+
});
|
|
438
|
+
try {
|
|
439
|
+
await rename(pendingDirectory, cacheDirectory);
|
|
440
|
+
}
|
|
441
|
+
catch (error) {
|
|
442
|
+
if (!(await packageMatches(cacheDirectory, entry.contentHash)))
|
|
443
|
+
throw error;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
finally {
|
|
447
|
+
await rm(pendingDirectory, { recursive: true, force: true });
|
|
448
|
+
}
|
|
449
|
+
return cacheDirectory;
|
|
450
|
+
}
|
|
451
|
+
async project(entry, cacheDirectory) {
|
|
452
|
+
const destination = this.projectionDirectory(entry.runtimeDirectory);
|
|
453
|
+
const existing = await readMarker(destination);
|
|
454
|
+
if (existing?.skillId === entry.skillId &&
|
|
455
|
+
existing.versionId === entry.versionId &&
|
|
456
|
+
existing.contentHash === entry.contentHash &&
|
|
457
|
+
(await packageMatches(destination, entry.contentHash))) {
|
|
458
|
+
await this.ensureCompatibilityProjection(entry, destination);
|
|
459
|
+
return entry.contentHash;
|
|
460
|
+
}
|
|
461
|
+
const suffix = `${process.pid}-${randomBytes(8).toString("hex")}`;
|
|
462
|
+
const pending = join(this.managedSkillsDirectory, `.pending-${suffix}`);
|
|
463
|
+
const backup = join(this.managedSkillsDirectory, `.backup-${suffix}`);
|
|
464
|
+
let movedExisting = false;
|
|
465
|
+
let installedPending = false;
|
|
466
|
+
let completed = false;
|
|
467
|
+
try {
|
|
468
|
+
await cp(cacheDirectory, pending, { recursive: true, errorOnExist: true, force: false });
|
|
469
|
+
await writeFile(join(pending, ".alan-managed.json"), `${JSON.stringify(markerFor(entry), null, 2)}\n`, { encoding: "utf8", flag: "wx", mode: 0o600 });
|
|
470
|
+
if (!(await packageMatches(pending, entry.contentHash))) {
|
|
471
|
+
throw new Error("Pending managed Skill projection failed content verification");
|
|
472
|
+
}
|
|
473
|
+
if (await pathExists(destination)) {
|
|
474
|
+
await rename(destination, backup);
|
|
475
|
+
movedExisting = true;
|
|
476
|
+
}
|
|
477
|
+
try {
|
|
478
|
+
await rename(pending, destination);
|
|
479
|
+
installedPending = true;
|
|
480
|
+
}
|
|
481
|
+
catch (error) {
|
|
482
|
+
if (movedExisting)
|
|
483
|
+
await rename(backup, destination);
|
|
484
|
+
throw error;
|
|
485
|
+
}
|
|
486
|
+
const inspected = await inspectSkillPackage(destination, { expectedName: null });
|
|
487
|
+
if (inspected.contentHash !== entry.contentHash) {
|
|
488
|
+
throw new Error("Managed Skill projection does not match its expected content hash");
|
|
489
|
+
}
|
|
490
|
+
await this.ensureCompatibilityProjection(entry, destination);
|
|
491
|
+
completed = true;
|
|
492
|
+
await rm(backup, { recursive: true, force: true });
|
|
493
|
+
return inspected.contentHash;
|
|
494
|
+
}
|
|
495
|
+
catch (error) {
|
|
496
|
+
if (!completed && installedPending) {
|
|
497
|
+
await rm(destination, { recursive: true, force: true });
|
|
498
|
+
if (movedExisting && (await pathExists(backup)))
|
|
499
|
+
await rename(backup, destination);
|
|
500
|
+
}
|
|
501
|
+
throw error;
|
|
502
|
+
}
|
|
503
|
+
finally {
|
|
504
|
+
await rm(pending, { recursive: true, force: true });
|
|
505
|
+
if (completed || !movedExisting) {
|
|
506
|
+
await rm(backup, { recursive: true, force: true });
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
async requireReplaceable(entry) {
|
|
511
|
+
const destination = this.projectionDirectory(entry.runtimeDirectory);
|
|
512
|
+
if (!(await pathExists(destination)))
|
|
513
|
+
return;
|
|
514
|
+
const marker = await readMarker(destination);
|
|
515
|
+
if (!marker)
|
|
516
|
+
throw unmanagedPathConflict(entry.runtimeDirectory);
|
|
517
|
+
if (marker.skillId === entry.skillId &&
|
|
518
|
+
marker.versionId === entry.versionId &&
|
|
519
|
+
marker.contentHash === entry.contentHash &&
|
|
520
|
+
(await packageMatches(destination, entry.contentHash))) {
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
const recorded = this.store.projections()[entry.runtimeDirectory];
|
|
524
|
+
if (!recorded || !markerMatchesProjection(marker, recorded)) {
|
|
525
|
+
throw unmanagedPathConflict(entry.runtimeDirectory);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
async removeNoLongerDesired(desired) {
|
|
529
|
+
const failures = [];
|
|
530
|
+
if (!this.store.inspect().canRemoveManagedFiles)
|
|
531
|
+
return failures;
|
|
532
|
+
for (const [runtimeDirectory, recorded] of Object.entries(this.store.projections())) {
|
|
533
|
+
if (desired[runtimeDirectory])
|
|
534
|
+
continue;
|
|
535
|
+
const destination = this.projectionDirectory(runtimeDirectory);
|
|
536
|
+
const compatibility = join(this.compatibilitySkillsDirectory, this.projectionDirectoryName(runtimeDirectory));
|
|
537
|
+
const marker = await readMarker(destination);
|
|
538
|
+
if (!(await pathExists(destination)))
|
|
539
|
+
continue;
|
|
540
|
+
if (marker && markerMatchesProjection(marker, recorded)) {
|
|
541
|
+
if (!(await removeCompatibilityProjection(compatibility, destination, recorded))) {
|
|
542
|
+
failures.push({
|
|
543
|
+
skillId: recorded.skillId,
|
|
544
|
+
versionId: recorded.versionId,
|
|
545
|
+
contentHash: recorded.contentHash,
|
|
546
|
+
state: "conflict",
|
|
547
|
+
errorCode: "COMPATIBILITY_PATH_CONFLICT",
|
|
548
|
+
errorMessage: `Refusing to remove an unowned compatibility path: ${runtimeDirectory}`,
|
|
549
|
+
});
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
552
|
+
await rm(destination, { recursive: true, force: true });
|
|
553
|
+
}
|
|
554
|
+
else {
|
|
555
|
+
failures.push({
|
|
556
|
+
skillId: recorded.skillId,
|
|
557
|
+
versionId: recorded.versionId,
|
|
558
|
+
contentHash: recorded.contentHash,
|
|
559
|
+
state: "conflict",
|
|
560
|
+
errorCode: "MANAGED_MARKER_MISMATCH",
|
|
561
|
+
errorMessage: `Refusing to remove modified or unowned Skill directory: ${runtimeDirectory}`,
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
return failures;
|
|
566
|
+
}
|
|
567
|
+
async ensureCompatibilityProjection(entry, canonicalDirectory) {
|
|
568
|
+
await mkdir(this.compatibilitySkillsDirectory, { recursive: true, mode: 0o700 });
|
|
569
|
+
const destination = join(this.compatibilitySkillsDirectory, this.projectionDirectoryName(entry.runtimeDirectory));
|
|
570
|
+
if (await pathExists(destination)) {
|
|
571
|
+
if (await compatibilityProjectionMatches(destination, canonicalDirectory, entry))
|
|
572
|
+
return;
|
|
573
|
+
throw unmanagedCompatibilityConflict(entry.runtimeDirectory);
|
|
574
|
+
}
|
|
575
|
+
try {
|
|
576
|
+
await symlink(canonicalDirectory, destination, "dir");
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
catch (error) {
|
|
580
|
+
if (!isSymlinkUnsupported(error))
|
|
581
|
+
throw error;
|
|
582
|
+
}
|
|
583
|
+
const pending = `${destination}.pending-${process.pid}-${randomBytes(6).toString("hex")}`;
|
|
584
|
+
try {
|
|
585
|
+
await cp(canonicalDirectory, pending, { recursive: true, errorOnExist: true, force: false });
|
|
586
|
+
await writeFile(join(pending, ".alan-compatibility.json"), `${JSON.stringify({ ...markerFor(entry), canonicalDirectory }, null, 2)}\n`, { encoding: "utf8", flag: "wx", mode: 0o600 });
|
|
587
|
+
await rename(pending, destination);
|
|
588
|
+
}
|
|
589
|
+
finally {
|
|
590
|
+
await rm(pending, { recursive: true, force: true });
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
async runExclusively(work) {
|
|
594
|
+
const previous = this.reconcileTail;
|
|
595
|
+
let release;
|
|
596
|
+
this.reconcileTail = new Promise((resolve) => {
|
|
597
|
+
release = resolve;
|
|
598
|
+
});
|
|
599
|
+
await previous;
|
|
600
|
+
try {
|
|
601
|
+
return await work();
|
|
602
|
+
}
|
|
603
|
+
finally {
|
|
604
|
+
release();
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
projectionDirectory(runtimeDirectory) {
|
|
608
|
+
return join(this.managedSkillsDirectory, this.projectionDirectoryName(runtimeDirectory));
|
|
609
|
+
}
|
|
610
|
+
projectionDirectoryName(runtimeDirectory) {
|
|
611
|
+
requireSafeRuntimeDirectory(runtimeDirectory);
|
|
612
|
+
return this.storageNamespace
|
|
613
|
+
? `${runtimeDirectory}--alan-${this.storageNamespace}`
|
|
614
|
+
: runtimeDirectory;
|
|
615
|
+
}
|
|
616
|
+
async withMachineLock(work) {
|
|
617
|
+
await mkdir(this.skillsStateDirectory, { recursive: true, mode: 0o700 });
|
|
618
|
+
const lockDirectory = join(this.skillsStateDirectory, "manager.lock");
|
|
619
|
+
const deadline = Date.now() + 30_000;
|
|
620
|
+
while (true) {
|
|
621
|
+
try {
|
|
622
|
+
await mkdir(lockDirectory, { mode: 0o700 });
|
|
623
|
+
try {
|
|
624
|
+
await writeFile(join(lockDirectory, "owner.json"), `${JSON.stringify({ pid: process.pid, acquiredAt: new Date().toISOString() })}\n`, { encoding: "utf8", flag: "wx", mode: 0o600 });
|
|
625
|
+
}
|
|
626
|
+
catch (error) {
|
|
627
|
+
await rm(lockDirectory, { recursive: true, force: true });
|
|
628
|
+
throw error;
|
|
629
|
+
}
|
|
630
|
+
break;
|
|
631
|
+
}
|
|
632
|
+
catch (error) {
|
|
633
|
+
if (!isAlreadyPresent(error))
|
|
634
|
+
throw error;
|
|
635
|
+
const ageMs = await stat(lockDirectory)
|
|
636
|
+
.then((metadata) => Date.now() - metadata.mtimeMs)
|
|
637
|
+
.catch(() => 0);
|
|
638
|
+
if (ageMs > 15 * 60_000) {
|
|
639
|
+
await rm(lockDirectory, { recursive: true, force: true });
|
|
640
|
+
continue;
|
|
641
|
+
}
|
|
642
|
+
if (Date.now() >= deadline) {
|
|
643
|
+
throw Object.assign(new Error("Another Skill synchronization is still running"), {
|
|
644
|
+
code: "SKILL_MANAGER_BUSY",
|
|
645
|
+
});
|
|
646
|
+
}
|
|
647
|
+
await new Promise((resolveDelay) => setTimeout(resolveDelay, 50));
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
try {
|
|
651
|
+
return await work();
|
|
652
|
+
}
|
|
653
|
+
finally {
|
|
654
|
+
await rm(lockDirectory, { recursive: true, force: true });
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
async function downloadBundleWithFetch(entry) {
|
|
659
|
+
if (entry.compressedBytes > SKILL_PACKAGE_LIMITS.maxArchiveBytes) {
|
|
660
|
+
throw new Error("Desired Skill bundle exceeds the compressed size limit");
|
|
661
|
+
}
|
|
662
|
+
const response = await fetch(entry.downloadUrl, { redirect: "error" });
|
|
663
|
+
if (!response.ok)
|
|
664
|
+
throw new Error(`Skill bundle download failed with HTTP ${response.status}`);
|
|
665
|
+
return Buffer.from(await response.arrayBuffer());
|
|
666
|
+
}
|
|
667
|
+
async function packageMatches(directory, expectedHash) {
|
|
668
|
+
try {
|
|
669
|
+
return ((await inspectSkillPackage(directory, { expectedName: null })).contentHash === expectedHash);
|
|
670
|
+
}
|
|
671
|
+
catch {
|
|
672
|
+
return false;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
async function readMarker(directory) {
|
|
676
|
+
try {
|
|
677
|
+
const value = JSON.parse(await readFile(join(directory, ".alan-managed.json"), "utf8"));
|
|
678
|
+
if (typeof value !== "object" ||
|
|
679
|
+
value === null ||
|
|
680
|
+
!("protocolVersion" in value) ||
|
|
681
|
+
value.protocolVersion !== SKILLS_PROTOCOL_VERSION ||
|
|
682
|
+
!("skillId" in value) ||
|
|
683
|
+
typeof value.skillId !== "string" ||
|
|
684
|
+
!("versionId" in value) ||
|
|
685
|
+
typeof value.versionId !== "string" ||
|
|
686
|
+
!("contentHash" in value) ||
|
|
687
|
+
typeof value.contentHash !== "string" ||
|
|
688
|
+
!/^sha256:[a-f0-9]{64}$/.test(value.contentHash)) {
|
|
689
|
+
return null;
|
|
690
|
+
}
|
|
691
|
+
return value;
|
|
692
|
+
}
|
|
693
|
+
catch {
|
|
694
|
+
return null;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
async function compatibilityProjectionMatches(destination, canonicalDirectory, entry) {
|
|
698
|
+
const metadata = await lstat(destination);
|
|
699
|
+
if (metadata.isSymbolicLink()) {
|
|
700
|
+
const target = await readlink(destination);
|
|
701
|
+
return resolve(dirname(destination), target) === resolve(canonicalDirectory);
|
|
702
|
+
}
|
|
703
|
+
if (!metadata.isDirectory())
|
|
704
|
+
return false;
|
|
705
|
+
const marker = await readCompatibilityMarker(destination);
|
|
706
|
+
return (marker?.canonicalDirectory === canonicalDirectory &&
|
|
707
|
+
marker.skillId === entry.skillId &&
|
|
708
|
+
marker.versionId === entry.versionId &&
|
|
709
|
+
marker.contentHash === entry.contentHash &&
|
|
710
|
+
(await packageMatches(destination, entry.contentHash)));
|
|
711
|
+
}
|
|
712
|
+
async function removeCompatibilityProjection(destination, canonicalDirectory, projection) {
|
|
713
|
+
if (!(await pathExists(destination)))
|
|
714
|
+
return true;
|
|
715
|
+
const metadata = await lstat(destination);
|
|
716
|
+
if (metadata.isSymbolicLink()) {
|
|
717
|
+
const target = await readlink(destination);
|
|
718
|
+
if (resolve(dirname(destination), target) !== resolve(canonicalDirectory))
|
|
719
|
+
return false;
|
|
720
|
+
await rm(destination, { force: true });
|
|
721
|
+
return true;
|
|
722
|
+
}
|
|
723
|
+
const marker = await readCompatibilityMarker(destination);
|
|
724
|
+
if (!marker || !markerMatchesProjection(marker, projection))
|
|
725
|
+
return false;
|
|
726
|
+
await rm(destination, { recursive: true, force: true });
|
|
727
|
+
return true;
|
|
728
|
+
}
|
|
729
|
+
async function readCompatibilityMarker(directory) {
|
|
730
|
+
try {
|
|
731
|
+
const value = JSON.parse(await readFile(join(directory, ".alan-compatibility.json"), "utf8"));
|
|
732
|
+
if (value.protocolVersion !== SKILLS_PROTOCOL_VERSION ||
|
|
733
|
+
typeof value.skillId !== "string" ||
|
|
734
|
+
typeof value.versionId !== "string" ||
|
|
735
|
+
!/^sha256:[a-f0-9]{64}$/.test(value.contentHash) ||
|
|
736
|
+
typeof value.canonicalDirectory !== "string") {
|
|
737
|
+
return null;
|
|
738
|
+
}
|
|
739
|
+
return value;
|
|
740
|
+
}
|
|
741
|
+
catch {
|
|
742
|
+
return null;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
function markerFor(entry) {
|
|
746
|
+
return {
|
|
747
|
+
protocolVersion: SKILLS_PROTOCOL_VERSION,
|
|
748
|
+
skillId: entry.skillId,
|
|
749
|
+
versionId: entry.versionId,
|
|
750
|
+
contentHash: entry.contentHash,
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
async function readLegacyManifest(path) {
|
|
754
|
+
try {
|
|
755
|
+
const value = JSON.parse(await readFile(path, "utf8"));
|
|
756
|
+
if (!value || typeof value !== "object" || !("skills" in value))
|
|
757
|
+
return null;
|
|
758
|
+
const skillsValue = value.skills;
|
|
759
|
+
if (!skillsValue || typeof skillsValue !== "object" || Array.isArray(skillsValue))
|
|
760
|
+
return null;
|
|
761
|
+
const entries = {};
|
|
762
|
+
for (const [command, raw] of Object.entries(skillsValue)) {
|
|
763
|
+
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(command) ||
|
|
764
|
+
!raw ||
|
|
765
|
+
typeof raw !== "object" ||
|
|
766
|
+
!("hash" in raw) ||
|
|
767
|
+
typeof raw.hash !== "string" ||
|
|
768
|
+
!/^[a-f0-9]{16}$/.test(raw.hash)) {
|
|
769
|
+
return null;
|
|
770
|
+
}
|
|
771
|
+
entries[command] = { hash: raw.hash };
|
|
772
|
+
}
|
|
773
|
+
return { skills: entries };
|
|
774
|
+
}
|
|
775
|
+
catch {
|
|
776
|
+
return null;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
async function legacyFileMatches(directory, expectedHash) {
|
|
780
|
+
try {
|
|
781
|
+
const metadata = await lstat(directory);
|
|
782
|
+
if (!metadata.isDirectory() || metadata.isSymbolicLink())
|
|
783
|
+
return false;
|
|
784
|
+
const content = await readFile(join(directory, "SKILL.md"));
|
|
785
|
+
return createHash("sha256").update(content).digest("hex").slice(0, 16) === expectedHash;
|
|
786
|
+
}
|
|
787
|
+
catch {
|
|
788
|
+
return false;
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
async function removeExactLegacySkill(directory, expectedHash) {
|
|
792
|
+
if (!(await legacyFileMatches(directory, expectedHash)))
|
|
793
|
+
return;
|
|
794
|
+
await rm(join(directory, "SKILL.md"), { force: true });
|
|
795
|
+
const remaining = await readdir(directory);
|
|
796
|
+
if (remaining.length === 0)
|
|
797
|
+
await rm(directory, { recursive: true, force: true });
|
|
798
|
+
}
|
|
799
|
+
function markerMatchesProjection(marker, projection) {
|
|
800
|
+
return (marker.skillId === projection.skillId &&
|
|
801
|
+
marker.versionId === projection.versionId &&
|
|
802
|
+
marker.contentHash === projection.contentHash);
|
|
803
|
+
}
|
|
804
|
+
function resolveStorageNamespace(endpointProfile, profileStorageIdentity) {
|
|
805
|
+
if (!endpointProfile)
|
|
806
|
+
return null;
|
|
807
|
+
if (endpointProfile === "production" || endpointProfile === "staging") {
|
|
808
|
+
return endpointProfile;
|
|
809
|
+
}
|
|
810
|
+
const identity = profileStorageIdentity?.trim();
|
|
811
|
+
if (!identity)
|
|
812
|
+
return endpointProfile;
|
|
813
|
+
const identityHash = createHash("sha256").update(identity).digest("hex").slice(0, 12);
|
|
814
|
+
return `${endpointProfile}-${identityHash}`;
|
|
815
|
+
}
|
|
816
|
+
function requireSafeRuntimeDirectory(value) {
|
|
817
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/.test(value) || value === "." || value === "..") {
|
|
818
|
+
throw new Error(`Unsafe managed Skill directory: ${value}`);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
function requirePortableSkillName(value) {
|
|
822
|
+
if (!/^(?!-)(?!.*--)[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value) || value.length > 64) {
|
|
823
|
+
throw Object.assign(new Error("Local Skill names use lowercase letters, numbers, and single hyphens"), { code: "INVALID_SKILL_NAME" });
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
function rewriteSkillMarkdownName(markdown, name) {
|
|
827
|
+
const lineEnding = markdown.includes("\r\n") ? "\r\n" : "\n";
|
|
828
|
+
const lines = markdown.split(/\r?\n/);
|
|
829
|
+
if (lines[0]?.trim() !== "---") {
|
|
830
|
+
throw Object.assign(new Error("The local Skill has invalid SKILL.md frontmatter"), {
|
|
831
|
+
code: "INVALID_FRONTMATTER",
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
const end = lines.findIndex((line, index) => index > 0 && line.trim() === "---");
|
|
835
|
+
const nameIndex = lines.findIndex((line, index) => index > 0 && index < end && /^name\s*:/.test(line));
|
|
836
|
+
if (end < 0 || nameIndex < 0) {
|
|
837
|
+
throw Object.assign(new Error("The local Skill has invalid SKILL.md frontmatter"), {
|
|
838
|
+
code: "INVALID_FRONTMATTER",
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
lines[nameIndex] = `name: ${name}`;
|
|
842
|
+
return lines.join(lineEnding);
|
|
843
|
+
}
|
|
844
|
+
function sameConflict(left, right) {
|
|
845
|
+
return (left.kind === right.kind &&
|
|
846
|
+
left.runtimeDirectory === right.runtimeDirectory &&
|
|
847
|
+
left.observedHash === right.observedHash &&
|
|
848
|
+
left.observedName === right.observedName);
|
|
849
|
+
}
|
|
850
|
+
function resolutionFromReconcile(input, result) {
|
|
851
|
+
const resolved = result.skills.find((candidate) => candidate.skillId === input.skillId && candidate.versionId === input.versionId);
|
|
852
|
+
if (resolved?.state === "applied") {
|
|
853
|
+
return {
|
|
854
|
+
commandId: input.commandId,
|
|
855
|
+
skillId: input.skillId,
|
|
856
|
+
versionId: input.versionId,
|
|
857
|
+
state: "applied",
|
|
858
|
+
};
|
|
859
|
+
}
|
|
860
|
+
return resolutionFailure(input, "failed", resolved?.errorCode ?? "SKILL_RECONCILE_FAILED", resolved?.errorMessage ?? "The Skill could not be installed after resolving the conflict");
|
|
861
|
+
}
|
|
862
|
+
function resolutionFailure(input, state, errorCodeValue, errorMessage) {
|
|
863
|
+
return {
|
|
864
|
+
commandId: input.commandId,
|
|
865
|
+
skillId: input.skillId,
|
|
866
|
+
versionId: input.versionId,
|
|
867
|
+
state,
|
|
868
|
+
errorCode: errorCodeValue,
|
|
869
|
+
errorMessage,
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
function localRasterMediaType(path) {
|
|
873
|
+
const lower = path.toLowerCase();
|
|
874
|
+
if (lower.endsWith(".gif"))
|
|
875
|
+
return "image/gif";
|
|
876
|
+
if (lower.endsWith(".jpeg") || lower.endsWith(".jpg"))
|
|
877
|
+
return "image/jpeg";
|
|
878
|
+
if (lower.endsWith(".png"))
|
|
879
|
+
return "image/png";
|
|
880
|
+
if (lower.endsWith(".webp"))
|
|
881
|
+
return "image/webp";
|
|
882
|
+
return null;
|
|
883
|
+
}
|
|
884
|
+
function localTextMediaType(path) {
|
|
885
|
+
return path.toLowerCase().endsWith(".md")
|
|
886
|
+
? "text/markdown; charset=utf-8"
|
|
887
|
+
: "text/plain; charset=utf-8";
|
|
888
|
+
}
|
|
889
|
+
async function pathExists(path) {
|
|
890
|
+
try {
|
|
891
|
+
await lstat(path);
|
|
892
|
+
return true;
|
|
893
|
+
}
|
|
894
|
+
catch (error) {
|
|
895
|
+
if (isMissingPath(error))
|
|
896
|
+
return false;
|
|
897
|
+
throw error;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
function unmanagedPathConflict(runtimeDirectory) {
|
|
901
|
+
return Object.assign(new Error(`Managed Skill destination is occupied by unowned files: ${runtimeDirectory}`), { code: "UNMANAGED_PATH_CONFLICT" });
|
|
902
|
+
}
|
|
903
|
+
function unmanagedCompatibilityConflict(runtimeDirectory) {
|
|
904
|
+
return Object.assign(new Error(`Claude compatibility destination is occupied by unowned files: ${runtimeDirectory}`), { code: "COMPATIBILITY_PATH_CONFLICT" });
|
|
905
|
+
}
|
|
906
|
+
function isUnmanagedConflict(error) {
|
|
907
|
+
return ["UNMANAGED_PATH_CONFLICT", "COMPATIBILITY_PATH_CONFLICT"].includes(errorCode(error));
|
|
908
|
+
}
|
|
909
|
+
function errorCode(error) {
|
|
910
|
+
if (typeof error === "object" && error !== null && "code" in error) {
|
|
911
|
+
const code = error.code;
|
|
912
|
+
if (typeof code === "string")
|
|
913
|
+
return code;
|
|
914
|
+
}
|
|
915
|
+
return "SKILL_RECONCILE_FAILED";
|
|
916
|
+
}
|
|
917
|
+
function isMissingPath(error) {
|
|
918
|
+
return (typeof error === "object" &&
|
|
919
|
+
error !== null &&
|
|
920
|
+
"code" in error &&
|
|
921
|
+
error.code === "ENOENT");
|
|
922
|
+
}
|
|
923
|
+
function isAlreadyPresent(error) {
|
|
924
|
+
return (typeof error === "object" &&
|
|
925
|
+
error !== null &&
|
|
926
|
+
"code" in error &&
|
|
927
|
+
error.code === "EEXIST");
|
|
928
|
+
}
|
|
929
|
+
function isSymlinkUnsupported(error) {
|
|
930
|
+
if (typeof error !== "object" || error === null || !("code" in error))
|
|
931
|
+
return false;
|
|
932
|
+
return ["EACCES", "ENOSYS", "EPERM"].includes(String(error.code));
|
|
933
|
+
}
|
|
934
|
+
//# sourceMappingURL=runtime-skill-manager.js.map
|