@geminixiang/mikan 1.0.0-beta.2 → 1.0.0-beta.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +388 -0
- package/README.md +49 -16
- package/dist/adapter.d.ts +1 -1
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js.map +1 -1
- package/dist/adapters/buffered-responder.d.ts +60 -0
- package/dist/adapters/buffered-responder.d.ts.map +1 -0
- package/dist/adapters/buffered-responder.js +201 -0
- package/dist/adapters/buffered-responder.js.map +1 -0
- package/dist/adapters/discord/bot.d.ts +1 -0
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +36 -67
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/discord/context.d.ts.map +1 -1
- package/dist/adapters/discord/context.js +44 -204
- package/dist/adapters/discord/context.js.map +1 -1
- package/dist/adapters/github/bot.d.ts +86 -0
- package/dist/adapters/github/bot.d.ts.map +1 -0
- package/dist/adapters/github/bot.js +640 -0
- package/dist/adapters/github/bot.js.map +1 -0
- package/dist/adapters/github/client.d.ts +122 -0
- package/dist/adapters/github/client.d.ts.map +1 -0
- package/dist/adapters/github/client.js +314 -0
- package/dist/adapters/github/client.js.map +1 -0
- package/dist/adapters/github/cloudbuild.d.ts +24 -0
- package/dist/adapters/github/cloudbuild.d.ts.map +1 -0
- package/dist/adapters/github/cloudbuild.js +71 -0
- package/dist/adapters/github/cloudbuild.js.map +1 -0
- package/dist/adapters/github/context.d.ts +9 -0
- package/dist/adapters/github/context.d.ts.map +1 -0
- package/dist/adapters/github/context.js +103 -0
- package/dist/adapters/github/context.js.map +1 -0
- package/dist/adapters/github/gcp-auth.d.ts +31 -0
- package/dist/adapters/github/gcp-auth.d.ts.map +1 -0
- package/dist/adapters/github/gcp-auth.js +196 -0
- package/dist/adapters/github/gcp-auth.js.map +1 -0
- package/dist/adapters/github/github-ops.d.ts +90 -0
- package/dist/adapters/github/github-ops.d.ts.map +1 -0
- package/dist/adapters/github/github-ops.js +405 -0
- package/dist/adapters/github/github-ops.js.map +1 -0
- package/dist/adapters/github/ids.d.ts +34 -0
- package/dist/adapters/github/ids.d.ts.map +1 -0
- package/dist/adapters/github/ids.js +53 -0
- package/dist/adapters/github/ids.js.map +1 -0
- package/dist/adapters/github/repo.d.ts +32 -0
- package/dist/adapters/github/repo.d.ts.map +1 -0
- package/dist/adapters/github/repo.js +141 -0
- package/dist/adapters/github/repo.js.map +1 -0
- package/dist/adapters/github/tool-pack.d.ts +14 -0
- package/dist/adapters/github/tool-pack.d.ts.map +1 -0
- package/dist/adapters/github/tool-pack.js +56 -0
- package/dist/adapters/github/tool-pack.js.map +1 -0
- package/dist/adapters/github/tools/checks.d.ts +24 -0
- package/dist/adapters/github/tools/checks.d.ts.map +1 -0
- package/dist/adapters/github/tools/checks.js +105 -0
- package/dist/adapters/github/tools/checks.js.map +1 -0
- package/dist/adapters/github/tools/issue.d.ts +22 -0
- package/dist/adapters/github/tools/issue.d.ts.map +1 -0
- package/dist/adapters/github/tools/issue.js +48 -0
- package/dist/adapters/github/tools/issue.js.map +1 -0
- package/dist/adapters/github/tools/pr.d.ts +22 -0
- package/dist/adapters/github/tools/pr.d.ts.map +1 -0
- package/dist/adapters/github/tools/pr.js +48 -0
- package/dist/adapters/github/tools/pr.js.map +1 -0
- package/dist/adapters/github/tools/read.d.ts +22 -0
- package/dist/adapters/github/tools/read.d.ts.map +1 -0
- package/dist/adapters/github/tools/read.js +141 -0
- package/dist/adapters/github/tools/read.js.map +1 -0
- package/dist/adapters/github/tools/review-reply.d.ts +19 -0
- package/dist/adapters/github/tools/review-reply.d.ts.map +1 -0
- package/dist/adapters/github/tools/review-reply.js +38 -0
- package/dist/adapters/github/tools/review-reply.js.map +1 -0
- package/dist/adapters/github/tools/sync.d.ts +17 -0
- package/dist/adapters/github/tools/sync.d.ts.map +1 -0
- package/dist/adapters/github/tools/sync.js +34 -0
- package/dist/adapters/github/tools/sync.js.map +1 -0
- package/dist/adapters/github/types.d.ts +350 -0
- package/dist/adapters/github/types.d.ts.map +1 -0
- package/dist/adapters/github/types.js +2 -0
- package/dist/adapters/github/types.js.map +1 -0
- package/dist/adapters/intake.d.ts +16 -5
- package/dist/adapters/intake.d.ts.map +1 -1
- package/dist/adapters/intake.js +79 -22
- package/dist/adapters/intake.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +8 -6
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +82 -134
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/context.d.ts.map +1 -1
- package/dist/adapters/slack/context.js +3 -14
- package/dist/adapters/slack/context.js.map +1 -1
- package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
- package/dist/adapters/slack/response-lifecycle.js +14 -17
- package/dist/adapters/slack/response-lifecycle.js.map +1 -1
- package/dist/adapters/slack/session.d.ts.map +1 -1
- package/dist/adapters/slack/session.js +5 -8
- package/dist/adapters/slack/session.js.map +1 -1
- package/dist/adapters/streaming.d.ts +4 -0
- package/dist/adapters/streaming.d.ts.map +1 -1
- package/dist/adapters/streaming.js +11 -0
- package/dist/adapters/streaming.js.map +1 -1
- package/dist/adapters/telegram/bot.d.ts +1 -2
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +27 -62
- package/dist/adapters/telegram/bot.js.map +1 -1
- package/dist/adapters/telegram/context.d.ts.map +1 -1
- package/dist/adapters/telegram/context.js +37 -174
- package/dist/adapters/telegram/context.js.map +1 -1
- package/dist/adapters/types.d.ts +28 -2
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/agent.d.ts +37 -14
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +359 -229
- package/dist/agent.js.map +1 -1
- package/dist/cli/arg-grammar.d.ts +25 -0
- package/dist/cli/arg-grammar.d.ts.map +1 -0
- package/dist/cli/arg-grammar.js +59 -0
- package/dist/cli/arg-grammar.js.map +1 -0
- package/dist/cli/boot.d.ts +16 -0
- package/dist/cli/boot.d.ts.map +1 -0
- package/dist/cli/boot.js +119 -0
- package/dist/cli/boot.js.map +1 -0
- package/dist/cli/download.d.ts.map +1 -0
- package/dist/cli/download.js.map +1 -0
- package/dist/cli/ext-git.d.ts +22 -0
- package/dist/cli/ext-git.d.ts.map +1 -0
- package/dist/cli/ext-git.js +76 -0
- package/dist/cli/ext-git.js.map +1 -0
- package/dist/cli/ext.d.ts +2 -0
- package/dist/cli/ext.d.ts.map +1 -0
- package/dist/cli/ext.js +215 -0
- package/dist/cli/ext.js.map +1 -0
- package/dist/commands/admin.d.ts.map +1 -1
- package/dist/commands/admin.js +2 -1
- package/dist/commands/admin.js.map +1 -1
- package/dist/commands/auto-reply.d.ts.map +1 -1
- package/dist/commands/auto-reply.js +2 -6
- package/dist/commands/auto-reply.js.map +1 -1
- package/dist/commands/extensions.d.ts.map +1 -1
- package/dist/commands/extensions.js +18 -8
- package/dist/commands/extensions.js.map +1 -1
- package/dist/commands/login.d.ts +2 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +35 -3
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/manifest.d.ts +72 -0
- package/dist/commands/manifest.d.ts.map +1 -0
- package/dist/commands/manifest.js +121 -0
- package/dist/commands/manifest.js.map +1 -0
- package/dist/commands/model.d.ts.map +1 -1
- package/dist/commands/model.js +11 -9
- package/dist/commands/model.js.map +1 -1
- package/dist/commands/new.d.ts.map +1 -1
- package/dist/commands/new.js +2 -1
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/sandbox.d.ts.map +1 -1
- package/dist/commands/sandbox.js +23 -17
- package/dist/commands/sandbox.js.map +1 -1
- package/dist/commands/text.d.ts +2 -0
- package/dist/commands/text.d.ts.map +1 -0
- package/dist/commands/text.js +16 -0
- package/dist/commands/text.js.map +1 -0
- package/dist/commands/types.d.ts +14 -1
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/config.d.ts +1 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +98 -95
- package/dist/config.js.map +1 -1
- package/dist/env-manifest.d.ts +35 -0
- package/dist/env-manifest.d.ts.map +1 -0
- package/dist/env-manifest.js +225 -0
- package/dist/env-manifest.js.map +1 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +9 -73
- package/dist/events.js.map +1 -1
- package/dist/execution-resolver.d.ts +4 -2
- package/dist/execution-resolver.d.ts.map +1 -1
- package/dist/execution-resolver.js +54 -41
- package/dist/execution-resolver.js.map +1 -1
- package/dist/harness/event-format.d.ts +66 -0
- package/dist/harness/event-format.d.ts.map +1 -0
- package/dist/harness/event-format.js +112 -0
- package/dist/harness/event-format.js.map +1 -0
- package/dist/harness/extensions/loader.d.ts +44 -11
- package/dist/harness/extensions/loader.d.ts.map +1 -1
- package/dist/harness/extensions/loader.js +273 -84
- package/dist/harness/extensions/loader.js.map +1 -1
- package/dist/harness/extensions/registry.d.ts +48 -1
- package/dist/harness/extensions/registry.d.ts.map +1 -1
- package/dist/harness/extensions/registry.js +146 -0
- package/dist/harness/extensions/registry.js.map +1 -1
- package/dist/harness/extensions/types.d.ts +165 -22
- package/dist/harness/extensions/types.d.ts.map +1 -1
- package/dist/harness/extensions/types.js.map +1 -1
- package/dist/harness/index.d.ts +6 -5
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +3 -2
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/models.d.ts +5 -0
- package/dist/harness/models.d.ts.map +1 -1
- package/dist/harness/models.js +10 -0
- package/dist/harness/models.js.map +1 -1
- package/dist/harness/runner.d.ts +37 -2
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +107 -23
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session-store.d.ts +4 -1
- package/dist/harness/session-store.d.ts.map +1 -1
- package/dist/harness/session-store.js +11 -2
- package/dist/harness/session-store.js.map +1 -1
- package/dist/harness/subagent-runner.d.ts +34 -0
- package/dist/harness/subagent-runner.d.ts.map +1 -0
- package/dist/harness/subagent-runner.js +339 -0
- package/dist/harness/subagent-runner.js.map +1 -0
- package/dist/harness/types.d.ts +53 -0
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/main.js +260 -109
- package/dist/main.js.map +1 -1
- package/dist/observability/instrument.js +6 -4
- package/dist/observability/instrument.js.map +1 -1
- package/dist/observability/sentry.d.ts.map +1 -1
- package/dist/observability/sentry.js +3 -2
- package/dist/observability/sentry.js.map +1 -1
- package/dist/provisioner.d.ts.map +1 -1
- package/dist/provisioner.js +2 -5
- package/dist/provisioner.js.map +1 -1
- package/dist/runtime/conversation-runtime.d.ts +1 -1
- package/dist/runtime/conversation-runtime.d.ts.map +1 -1
- package/dist/runtime/conversation-runtime.js +276 -43
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/types.d.ts +36 -5
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/cloudflare.d.ts +3 -0
- package/dist/sandbox/cloudflare.d.ts.map +1 -1
- package/dist/sandbox/cloudflare.js +10 -0
- package/dist/sandbox/cloudflare.js.map +1 -1
- package/dist/sandbox/container.d.ts +4 -0
- package/dist/sandbox/container.d.ts.map +1 -1
- package/dist/sandbox/container.js +11 -2
- package/dist/sandbox/container.js.map +1 -1
- package/dist/sandbox/firecracker.d.ts +3 -0
- package/dist/sandbox/firecracker.d.ts.map +1 -1
- package/dist/sandbox/firecracker.js +10 -1
- package/dist/sandbox/firecracker.js.map +1 -1
- package/dist/sandbox/gondolin-bootstrap.d.ts +26 -0
- package/dist/sandbox/gondolin-bootstrap.d.ts.map +1 -0
- package/dist/sandbox/gondolin-bootstrap.js +27 -0
- package/dist/sandbox/gondolin-bootstrap.js.map +1 -0
- package/dist/sandbox/gondolin-contract.d.ts +125 -0
- package/dist/sandbox/gondolin-contract.d.ts.map +1 -0
- package/dist/sandbox/gondolin-contract.js +155 -0
- package/dist/sandbox/gondolin-contract.js.map +1 -0
- package/dist/sandbox/gondolin-fleet.d.ts +104 -0
- package/dist/sandbox/gondolin-fleet.d.ts.map +1 -0
- package/dist/sandbox/gondolin-fleet.js +330 -0
- package/dist/sandbox/gondolin-fleet.js.map +1 -0
- package/dist/sandbox/gondolin-gateway.d.ts +86 -0
- package/dist/sandbox/gondolin-gateway.d.ts.map +1 -0
- package/dist/sandbox/gondolin-gateway.js +407 -0
- package/dist/sandbox/gondolin-gateway.js.map +1 -0
- package/dist/sandbox/gondolin-inventory.d.ts +75 -0
- package/dist/sandbox/gondolin-inventory.d.ts.map +1 -0
- package/dist/sandbox/gondolin-inventory.js +257 -0
- package/dist/sandbox/gondolin-inventory.js.map +1 -0
- package/dist/sandbox/gondolin-join.d.ts +62 -0
- package/dist/sandbox/gondolin-join.d.ts.map +1 -0
- package/dist/sandbox/gondolin-join.js +261 -0
- package/dist/sandbox/gondolin-join.js.map +1 -0
- package/dist/sandbox/gondolin-nfs-advisory.d.ts +15 -0
- package/dist/sandbox/gondolin-nfs-advisory.d.ts.map +1 -0
- package/dist/sandbox/gondolin-nfs-advisory.js +60 -0
- package/dist/sandbox/gondolin-nfs-advisory.js.map +1 -0
- package/dist/sandbox/gondolin-placement.d.ts +30 -0
- package/dist/sandbox/gondolin-placement.d.ts.map +1 -0
- package/dist/sandbox/gondolin-placement.js +77 -0
- package/dist/sandbox/gondolin-placement.js.map +1 -0
- package/dist/sandbox/gondolin-recovery.d.ts +33 -0
- package/dist/sandbox/gondolin-recovery.d.ts.map +1 -0
- package/dist/sandbox/gondolin-recovery.js +39 -0
- package/dist/sandbox/gondolin-recovery.js.map +1 -0
- package/dist/sandbox/gondolin-remote.d.ts +70 -0
- package/dist/sandbox/gondolin-remote.d.ts.map +1 -0
- package/dist/sandbox/gondolin-remote.js +325 -0
- package/dist/sandbox/gondolin-remote.js.map +1 -0
- package/dist/sandbox/gondolin-worker-client.d.ts +135 -0
- package/dist/sandbox/gondolin-worker-client.d.ts.map +1 -0
- package/dist/sandbox/gondolin-worker-client.js +323 -0
- package/dist/sandbox/gondolin-worker-client.js.map +1 -0
- package/dist/sandbox/gondolin-worker-main.d.ts +2 -0
- package/dist/sandbox/gondolin-worker-main.d.ts.map +1 -0
- package/dist/sandbox/gondolin-worker-main.js +22 -0
- package/dist/sandbox/gondolin-worker-main.js.map +1 -0
- package/dist/sandbox/gondolin-worker.d.ts +17 -0
- package/dist/sandbox/gondolin-worker.d.ts.map +1 -0
- package/dist/sandbox/gondolin-worker.js +201 -0
- package/dist/sandbox/gondolin-worker.js.map +1 -0
- package/dist/sandbox/gondolin.d.ts +53 -0
- package/dist/sandbox/gondolin.d.ts.map +1 -0
- package/dist/sandbox/gondolin.js +429 -0
- package/dist/sandbox/gondolin.js.map +1 -0
- package/dist/sandbox/host.d.ts +3 -0
- package/dist/sandbox/host.d.ts.map +1 -1
- package/dist/sandbox/host.js +14 -0
- package/dist/sandbox/host.js.map +1 -1
- package/dist/sandbox/identity.d.ts +21 -0
- package/dist/sandbox/identity.d.ts.map +1 -0
- package/dist/sandbox/identity.js +36 -0
- package/dist/sandbox/identity.js.map +1 -0
- package/dist/sandbox/index.d.ts +13 -4
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +19 -3
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/types.d.ts +31 -1
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/sandbox/types.js.map +1 -1
- package/dist/sandbox/utils.d.ts +12 -0
- package/dist/sandbox/utils.d.ts.map +1 -1
- package/dist/sandbox/utils.js +38 -0
- package/dist/sandbox/utils.js.map +1 -1
- package/dist/sessions/chat-history-sync.d.ts +32 -0
- package/dist/sessions/chat-history-sync.d.ts.map +1 -0
- package/dist/sessions/{agent-memory-file-manager.js → chat-history-sync.js} +40 -113
- package/dist/sessions/chat-history-sync.js.map +1 -0
- package/dist/sessions/conversation-log.d.ts +13 -0
- package/dist/sessions/conversation-log.d.ts.map +1 -0
- package/dist/sessions/conversation-log.js +47 -0
- package/dist/sessions/conversation-log.js.map +1 -0
- package/dist/sessions/history-line.d.ts +20 -0
- package/dist/sessions/history-line.d.ts.map +1 -0
- package/dist/sessions/history-line.js +24 -0
- package/dist/sessions/history-line.js.map +1 -0
- package/dist/sessions/policy.d.ts.map +1 -1
- package/dist/sessions/policy.js +5 -3
- package/dist/sessions/policy.js.map +1 -1
- package/dist/sessions/rotation.d.ts +2 -0
- package/dist/sessions/rotation.d.ts.map +1 -0
- package/dist/sessions/rotation.js +39 -0
- package/dist/sessions/rotation.js.map +1 -0
- package/dist/sessions/session-key.d.ts +31 -0
- package/dist/sessions/session-key.d.ts.map +1 -0
- package/dist/sessions/session-key.js +44 -0
- package/dist/sessions/session-key.js.map +1 -0
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +6 -12
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/types.d.ts +2 -2
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js.map +1 -1
- package/dist/settings-mutation.d.ts +23 -0
- package/dist/settings-mutation.d.ts.map +1 -0
- package/dist/settings-mutation.js +42 -0
- package/dist/settings-mutation.js.map +1 -0
- package/dist/tools/bash.d.ts +3 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +24 -17
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +9 -12
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/event.d.ts +1 -1
- package/dist/tools/event.d.ts.map +1 -1
- package/dist/tools/event.js +53 -43
- package/dist/tools/event.js.map +1 -1
- package/dist/tools/generate-image.d.ts +17 -0
- package/dist/tools/generate-image.d.ts.map +1 -0
- package/dist/tools/generate-image.js +63 -0
- package/dist/tools/generate-image.js.map +1 -0
- package/dist/tools/host-fn-tool.d.ts +21 -0
- package/dist/tools/host-fn-tool.d.ts.map +1 -0
- package/dist/tools/host-fn-tool.js +32 -0
- package/dist/tools/host-fn-tool.js.map +1 -0
- package/dist/tools/index.d.ts +17 -2
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +28 -3
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/react.d.ts +15 -0
- package/dist/tools/react.d.ts.map +1 -0
- package/dist/tools/react.js +29 -0
- package/dist/tools/react.js.map +1 -0
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +7 -26
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/sandbox.d.ts +2 -2
- package/dist/tools/sandbox.d.ts.map +1 -1
- package/dist/tools/sandbox.js +13 -9
- package/dist/tools/sandbox.js.map +1 -1
- package/dist/tools/subagent-slots.d.ts +28 -0
- package/dist/tools/subagent-slots.d.ts.map +1 -0
- package/dist/tools/subagent-slots.js +57 -0
- package/dist/tools/subagent-slots.js.map +1 -0
- package/dist/tools/subagent.d.ts +74 -0
- package/dist/tools/subagent.d.ts.map +1 -0
- package/dist/tools/subagent.js +335 -0
- package/dist/tools/subagent.js.map +1 -0
- package/dist/tools/types.d.ts +40 -6
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js.map +1 -1
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.js +1 -8
- package/dist/tools/write.js.map +1 -1
- package/dist/trigger.d.ts.map +1 -1
- package/dist/trigger.js +1 -2
- package/dist/trigger.js.map +1 -1
- package/dist/types.d.ts +144 -31
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/date.d.ts +1 -1
- package/dist/utils/date.js +1 -1
- package/dist/utils/date.js.map +1 -1
- package/dist/vault/disabled.d.ts +9 -0
- package/dist/vault/disabled.d.ts.map +1 -0
- package/dist/vault/disabled.js +22 -0
- package/dist/vault/disabled.js.map +1 -0
- package/dist/vault/index.d.ts +0 -2
- package/dist/vault/index.d.ts.map +1 -1
- package/dist/vault/index.js +1 -32
- package/dist/vault/index.js.map +1 -1
- package/dist/vault/injection.d.ts +20 -0
- package/dist/vault/injection.d.ts.map +1 -0
- package/dist/vault/injection.js +27 -0
- package/dist/vault/injection.js.map +1 -0
- package/dist/vault/policy.d.ts +20 -0
- package/dist/vault/policy.d.ts.map +1 -0
- package/dist/vault/policy.js +20 -0
- package/dist/vault/policy.js.map +1 -0
- package/dist/vault/types.d.ts +0 -2
- package/dist/vault/types.d.ts.map +1 -1
- package/dist/vault/types.js.map +1 -1
- package/dist/web/admin/portal.d.ts +27 -0
- package/dist/web/admin/portal.d.ts.map +1 -1
- package/dist/web/admin/portal.js +117 -154
- package/dist/web/admin/portal.js.map +1 -1
- package/dist/web/admin/types.d.ts +6 -0
- package/dist/web/admin/types.d.ts.map +1 -1
- package/dist/web/admin/types.js.map +1 -1
- package/dist/web/agent-events/portal.d.ts.map +1 -1
- package/dist/web/agent-events/portal.js +2 -1
- package/dist/web/agent-events/portal.js.map +1 -1
- package/dist/web/login/oauth.d.ts +2 -3
- package/dist/web/login/oauth.d.ts.map +1 -1
- package/dist/web/login/oauth.js +0 -31
- package/dist/web/login/oauth.js.map +1 -1
- package/dist/web/login/portal.js +1 -1
- package/dist/web/login/portal.js.map +1 -1
- package/dist/web/login/types.d.ts +0 -11
- package/dist/web/login/types.d.ts.map +1 -1
- package/dist/web/login/types.js.map +1 -1
- package/dist/web/portal-shell.d.ts +4 -0
- package/dist/web/portal-shell.d.ts.map +1 -0
- package/dist/{portal-shell.js → web/portal-shell.js} +2 -2
- package/dist/web/portal-shell.js.map +1 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +7 -0
- package/dist/web/server.js.map +1 -1
- package/dist/web/session-view/command.d.ts.map +1 -1
- package/dist/web/session-view/command.js +4 -1
- package/dist/web/session-view/command.js.map +1 -1
- package/dist/web/session-view/portal.d.ts.map +1 -1
- package/dist/web/session-view/portal.js +4 -3
- package/dist/web/session-view/portal.js.map +1 -1
- package/dist/web/session-view/service.d.ts.map +1 -1
- package/dist/web/session-view/service.js +2 -1
- package/dist/web/session-view/service.js.map +1 -1
- package/dist/web/session-view/types.d.ts +2 -1
- package/dist/web/session-view/types.d.ts.map +1 -1
- package/dist/web/session-view/types.js.map +1 -1
- package/package.json +7 -4
- package/dist/download.d.ts.map +0 -1
- package/dist/download.js.map +0 -1
- package/dist/model-registry.d.ts +0 -4
- package/dist/model-registry.d.ts.map +0 -1
- package/dist/model-registry.js +0 -7
- package/dist/model-registry.js.map +0 -1
- package/dist/portal-shell.d.ts +0 -4
- package/dist/portal-shell.d.ts.map +0 -1
- package/dist/portal-shell.js.map +0 -1
- package/dist/runtime/agent-run-controller.d.ts +0 -31
- package/dist/runtime/agent-run-controller.d.ts.map +0 -1
- package/dist/runtime/agent-run-controller.js +0 -195
- package/dist/runtime/agent-run-controller.js.map +0 -1
- package/dist/sessions/agent-memory-file-manager.d.ts +0 -19
- package/dist/sessions/agent-memory-file-manager.d.ts.map +0 -1
- package/dist/sessions/agent-memory-file-manager.js.map +0 -1
- package/dist/vault/routing.d.ts +0 -3
- package/dist/vault/routing.d.ts.map +0 -1
- package/dist/vault/routing.js +0 -13
- package/dist/vault/routing.js.map +0 -1
- /package/dist/{download.d.ts → cli/download.d.ts} +0 -0
- /package/dist/{download.js → cli/download.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-format.js","sourceRoot":"","sources":["../../src/harness/event-format.ts"],"names":[],"mappings":"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","sourcesContent":["import { Type, type Static } from \"@sinclair/typebox\";\nimport { parseJsonSchemaValue } from \"../utils/file-guards.js\";\n\n/**\n * Single home for the scheduled-event file format (`events/*.json`, the\n * workspace scheduling bus). Every reader and writer — the EventsWatcher\n * scheduler, the agent `event` tool, and the extension schedule API — must go\n * through this module: one schema, one payload union, one parser, one\n * builder. Per-type field rules (`at` for one-shot, `schedule` + `timezone`\n * for periodic) live here and nowhere else.\n */\n\nexport type EventConversationKind = \"direct\" | \"shared\";\n\nexport type EventType = \"immediate\" | \"one-shot\" | \"periodic\";\n\n/** Typebox union for the `type` field, shared by the file schema and the event tool's parameters. */\nexport const EventTypeSchema = Type.Union([\n Type.Literal(\"immediate\"),\n Type.Literal(\"one-shot\"),\n Type.Literal(\"periodic\"),\n]);\n\ninterface EventPayloadBase {\n /** Target platform; may be omitted when only one platform is running. */\n platform?: string;\n conversationId: string;\n conversationKind?: EventConversationKind;\n userId?: string;\n /** Self-contained task text; event runs do not inherit conversation history. */\n text: string;\n}\n\nexport interface ImmediateEventPayload extends EventPayloadBase {\n type: \"immediate\";\n}\n\nexport interface OneShotEventPayload extends EventPayloadBase {\n type: \"one-shot\";\n /** ISO 8601 timestamp with offset. */\n at: string;\n}\n\nexport interface PeriodicEventPayload extends EventPayloadBase {\n type: \"periodic\";\n /** Cron expression (croner syntax). */\n schedule: string;\n /** IANA timezone, e.g. \"Asia/Taipei\". */\n timezone: string;\n}\n\n/**\n * Wire shape of one event file. Platform defaulting and conversation-kind\n * inference happen at read time (EventsWatcher), so both stay optional here.\n */\nexport type EventFilePayload = ImmediateEventPayload | OneShotEventPayload | PeriodicEventPayload;\n\n/**\n * Lenient file-reading schema: every field optional so shape problems surface\n * as the specific missing-field messages below rather than typebox noise.\n * `channelId` is the legacy alias for `conversationId`.\n */\nconst EventFileSchema = Type.Object({\n type: Type.Optional(EventTypeSchema),\n platform: Type.Optional(Type.String()),\n conversationId: Type.Optional(Type.String()),\n channelId: Type.Optional(Type.String()),\n conversationKind: Type.Optional(Type.Union([Type.Literal(\"direct\"), Type.Literal(\"shared\")])),\n userId: Type.Optional(Type.String()),\n text: Type.Optional(Type.String()),\n at: Type.Optional(Type.String()),\n schedule: Type.Optional(Type.String()),\n timezone: Type.Optional(Type.String()),\n});\n\ntype EventFileData = Static<typeof EventFileSchema>;\n\n/**\n * Resolve an event file's conversation id, honoring the legacy `channelId`\n * alias. Alias knowledge is private to the format module: consumers always\n * see `conversationId` on parsed payloads.\n */\nfunction resolveEventConversationId(data: {\n conversationId?: unknown;\n channelId?: unknown;\n}): string | undefined {\n if (typeof data.conversationId === \"string\") return data.conversationId;\n if (typeof data.channelId === \"string\") return data.channelId;\n return undefined;\n}\n\n/**\n * Parse and validate one event file's content into the canonical payload.\n * `filename` appears in error messages. Throws on malformed JSON, wrong\n * field types, and missing required fields (common and per-type).\n */\nexport function parseEventPayload(content: string, filename: string): EventFilePayload {\n const data: EventFileData = parseJsonSchemaValue(content, EventFileSchema, (detail) =>\n detail === \"unexpected JSON shape\"\n ? `Expected top-level JSON object in ${filename}`\n : `Malformed event file ${filename}: ${detail}`,\n );\n const conversationId = resolveEventConversationId(data);\n const { type, text } = data;\n\n if (!type || !conversationId || !text) {\n throw new Error(`Missing required fields (type, conversationId, text) in ${filename}`);\n }\n\n const base = {\n ...(data.platform !== undefined ? { platform: data.platform } : {}),\n conversationId,\n ...(data.conversationKind !== undefined ? { conversationKind: data.conversationKind } : {}),\n ...(data.userId !== undefined ? { userId: data.userId } : {}),\n text,\n };\n\n switch (type) {\n case \"immediate\":\n return { type, ...base };\n\n case \"one-shot\":\n if (typeof data.at !== \"string\" || data.at.length === 0) {\n throw new Error(`Missing 'at' field for one-shot event in ${filename}`);\n }\n return { type, ...base, at: data.at };\n\n case \"periodic\":\n if (typeof data.schedule !== \"string\" || data.schedule.length === 0) {\n throw new Error(`Missing 'schedule' field for periodic event in ${filename}`);\n }\n if (typeof data.timezone !== \"string\" || data.timezone.length === 0) {\n throw new Error(`Missing 'timezone' field for periodic event in ${filename}`);\n }\n return { type, ...base, schedule: data.schedule, timezone: data.timezone };\n }\n}\n\nexport interface EventPayloadInput {\n type: EventType;\n platform?: string;\n conversationId: string;\n conversationKind?: EventConversationKind;\n userId?: string;\n text: string;\n at?: string;\n schedule?: string;\n timezone?: string;\n}\n\n/**\n * Validate and assemble a new event payload for writing. Owns the per-type\n * field rules; write-side *policy* beyond the format (e.g. the event tool's\n * requirement that `at` lies in the future) stays with the writer.\n */\nexport function buildEventPayload(input: EventPayloadInput): EventFilePayload {\n const base = {\n ...(input.platform !== undefined ? { platform: input.platform } : {}),\n conversationId: input.conversationId,\n ...(input.conversationKind !== undefined ? { conversationKind: input.conversationKind } : {}),\n ...(input.userId !== undefined ? { userId: input.userId } : {}),\n text: input.text,\n };\n\n switch (input.type) {\n case \"immediate\":\n return { type: \"immediate\", ...base };\n\n case \"one-shot\": {\n if (!input.at) {\n throw new Error(\"`at` is required for one-shot events\");\n }\n if (Number.isNaN(new Date(input.at).getTime())) {\n throw new Error(\"`at` must be a valid ISO 8601 timestamp with UTC offset\");\n }\n return { type: \"one-shot\", ...base, at: input.at };\n }\n\n case \"periodic\":\n if (!input.schedule) {\n throw new Error(\"`schedule` is required for periodic events\");\n }\n if (!input.timezone) {\n throw new Error(\"`timezone` is required for periodic events\");\n }\n return { type: \"periodic\", ...base, schedule: input.schedule, timezone: input.timezone };\n }\n}\n"]}
|
|
@@ -4,11 +4,11 @@ import { type MikanSkill } from "../skills.js";
|
|
|
4
4
|
import { ExtensionRegistry } from "./registry.js";
|
|
5
5
|
import type { ExtensionHostServices, ExtensionLoadError, LoadedExtension } from "./types.js";
|
|
6
6
|
/**
|
|
7
|
-
* Canonical host-only extension directories for a conversation
|
|
8
|
-
* `<stateDir>/extensions
|
|
9
|
-
* `<stateDir>/
|
|
10
|
-
* `global`
|
|
11
|
-
*
|
|
7
|
+
* Canonical host-only extension code directories for a conversation, in load
|
|
8
|
+
* order: `<stateDir>/global/extensions` (all conversations) then
|
|
9
|
+
* `<stateDir>/conversations/<conversationId>/extensions` (that conversation
|
|
10
|
+
* only). `global` and `conversations` are the two sibling scopes; see
|
|
11
|
+
* `LAYOUT.md`. Conversation ids are used verbatim (see LAYOUT.md § Casing).
|
|
12
12
|
*/
|
|
13
13
|
export declare function defaultExtensionDirs(conversationId: string, stateDir?: string): string[];
|
|
14
14
|
/** Discovery-only view of an installed extension (module is not imported). */
|
|
@@ -48,15 +48,48 @@ export interface LoadExtensionsResult {
|
|
|
48
48
|
errors: ExtensionLoadError[];
|
|
49
49
|
/** Skills contributed by extensions (inline: bodies ride in the prompt). */
|
|
50
50
|
skills: MikanSkill[];
|
|
51
|
+
/**
|
|
52
|
+
* Run extension disposers (from `api.onDispose` and `activate` return
|
|
53
|
+
* values). Call when the harness instance owning these extensions is
|
|
54
|
+
* discarded. Idempotent; disposer errors are logged, never thrown.
|
|
55
|
+
*/
|
|
56
|
+
dispose(): Promise<void>;
|
|
51
57
|
}
|
|
52
58
|
/**
|
|
53
|
-
* Filesystem-safe identifier for an extension, derived from its
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
59
|
+
* Filesystem-safe identifier for an extension, derived from its root (the
|
|
60
|
+
* install directory, or the file path for a bare-file extension). The slug
|
|
61
|
+
* keys the extension's data dir, secrets vault, and schedule ownership —
|
|
62
|
+
* installing the same extension globally and per-conversation shares one
|
|
63
|
+
* slug and therefore one shared data dir. This is the only slug derivation:
|
|
64
|
+
* a second one keyed off a different input (e.g. the entrypoint, which for
|
|
65
|
+
* package.json-form extensions can live under dist/) would silently split an
|
|
66
|
+
* extension's identity.
|
|
58
67
|
*/
|
|
59
|
-
export declare function extensionSlug(
|
|
68
|
+
export declare function extensionSlug(rootDir: string): string;
|
|
60
69
|
/** Load and activate all extensions found in the given directories. */
|
|
61
70
|
export declare function loadExtensions(options: LoadExtensionsOptions): Promise<LoadExtensionsResult>;
|
|
71
|
+
export interface ExtensionValidation {
|
|
72
|
+
ok: boolean;
|
|
73
|
+
/** Slug the extension would install as (from the source dir/file name). */
|
|
74
|
+
slug: string;
|
|
75
|
+
/** Display name (manifest name, else slug). */
|
|
76
|
+
name: string;
|
|
77
|
+
version?: string;
|
|
78
|
+
description?: string;
|
|
79
|
+
/** Resolved entrypoint that would be imported. */
|
|
80
|
+
entrypoint?: string;
|
|
81
|
+
/** Skill names shipped alongside the extension. */
|
|
82
|
+
skillNames: string[];
|
|
83
|
+
errors: string[];
|
|
84
|
+
warnings: string[];
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Validate an extension source path (a directory or a single file) WITHOUT
|
|
88
|
+
* activating it: resolves the entrypoint (package.json `mikan.extensions`,
|
|
89
|
+
* index file, or the file itself), imports it, and checks it exports an
|
|
90
|
+
* `activate` function. Used by `mikan ext install` as a preflight and by
|
|
91
|
+
* `mikan ext validate`. Importing runs top-level module code but not
|
|
92
|
+
* `activate`, so there are no schedule/tool side effects.
|
|
93
|
+
*/
|
|
94
|
+
export declare function validateExtension(sourcePath: string): Promise<ExtensionValidation>;
|
|
62
95
|
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/harness/extensions/loader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/harness/extensions/loader.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAa,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,EAAqB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAGV,qBAAqB,EACrB,kBAAkB,EAKlB,eAAe,EAIhB,MAAM,YAAY,CAAC;AAiBpB;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,cAAc,EAAE,MAAM,EACtB,QAAQ,GAAE,MAAkC,GAC3C,MAAM,EAAE,CAKV;AAED,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,sBAAsB,EAAE,CAkBhF;AAED,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE;QACP,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAClB,aAAa,EAAE,aAAa,CAAC;KAC9B,CAAC;IACF,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,qBAAqB,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,4EAA4E;IAC5E,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB;;;;OAIG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AA2HD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIrD;AAmPD,uEAAuE;AACvE,wBAAsB,cAAc,CAClC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAmD/B;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAsDxF"}
|
|
@@ -12,31 +12,49 @@
|
|
|
12
12
|
* under mikan's state dir.
|
|
13
13
|
*
|
|
14
14
|
* Directories are scanned in order; all discovered extensions activate.
|
|
15
|
-
* Accepted layouts:
|
|
15
|
+
* Accepted layouts (entrypoint may be .mjs/.js/.ts/.mts — loaded via jiti):
|
|
16
16
|
*
|
|
17
|
-
* - `extensions/<name
|
|
18
|
-
* - `extensions/<name>/index
|
|
17
|
+
* - `extensions/<name>.<ext>` (bare file)
|
|
18
|
+
* - `extensions/<name>/index.<ext>` (directory + index)
|
|
19
|
+
* - `extensions/<name>/package.json` (mikan.extensions entrypoint;
|
|
20
|
+
* may carry npm dependencies in node_modules)
|
|
19
21
|
*
|
|
20
|
-
* Modules are imported with a cache
|
|
21
|
-
* picked up when a new harness instance is created
|
|
22
|
+
* Modules are imported with a fresh jiti instance (no cache) so edited
|
|
23
|
+
* extensions are picked up when a new harness instance is created.
|
|
22
24
|
*/
|
|
23
25
|
import { existsSync, mkdirSync, readdirSync, readFileSync, statSync } from "fs";
|
|
24
26
|
import { homedir } from "os";
|
|
25
|
-
import { basename,
|
|
26
|
-
import {
|
|
27
|
+
import { basename, join } from "path";
|
|
28
|
+
import { createJiti } from "jiti";
|
|
27
29
|
import * as log from "../../log.js";
|
|
30
|
+
import { buildEventPayload } from "../event-format.js";
|
|
28
31
|
import { loadSkillsFromDir } from "../skills.js";
|
|
29
32
|
import { ExtensionRegistry } from "./registry.js";
|
|
30
|
-
const EXTENSION_FILE_PATTERN = /\.(mjs|js)$/;
|
|
33
|
+
const EXTENSION_FILE_PATTERN = /\.(mjs|js|ts|mts)$/;
|
|
34
|
+
const INDEX_FILE_PATTERN = /^index\.(mjs|js|ts|mts)$/;
|
|
35
|
+
const INDEX_CANDIDATES = ["index.mjs", "index.js", "index.ts", "index.mts"];
|
|
31
36
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
|
|
37
|
+
* Import an extension entrypoint through jiti so it can be TypeScript and can
|
|
38
|
+
* use node_modules dependencies, transparently compiling on the fly. A fresh
|
|
39
|
+
* jiti instance with caching disabled is used per load so edited extensions
|
|
40
|
+
* are picked up when a new harness instance is created for a conversation.
|
|
41
|
+
*/
|
|
42
|
+
async function importExtensionModule(entrypoint) {
|
|
43
|
+
const jiti = createJiti(import.meta.url, { moduleCache: false, fsCache: false });
|
|
44
|
+
return jiti.import(entrypoint);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Canonical host-only extension code directories for a conversation, in load
|
|
48
|
+
* order: `<stateDir>/global/extensions` (all conversations) then
|
|
49
|
+
* `<stateDir>/conversations/<conversationId>/extensions` (that conversation
|
|
50
|
+
* only). `global` and `conversations` are the two sibling scopes; see
|
|
51
|
+
* `LAYOUT.md`. Conversation ids are used verbatim (see LAYOUT.md § Casing).
|
|
37
52
|
*/
|
|
38
53
|
export function defaultExtensionDirs(conversationId, stateDir = join(homedir(), ".mikan")) {
|
|
39
|
-
return [
|
|
54
|
+
return [
|
|
55
|
+
join(stateDir, "global", "extensions"),
|
|
56
|
+
join(stateDir, "conversations", conversationId, "extensions"),
|
|
57
|
+
];
|
|
40
58
|
}
|
|
41
59
|
/**
|
|
42
60
|
* List installed extensions without importing or activating them — safe for
|
|
@@ -46,9 +64,9 @@ export function defaultExtensionDirs(conversationId, stateDir = join(homedir(),
|
|
|
46
64
|
export function listInstalledExtensions(dirs) {
|
|
47
65
|
const infos = [];
|
|
48
66
|
for (const dir of dirs) {
|
|
49
|
-
for (const entrypoint of discoverExtensionEntrypoints(dir)) {
|
|
50
|
-
const slug = extensionSlug(
|
|
51
|
-
const manifest = readManifest(
|
|
67
|
+
for (const { entrypoint, rootDir } of discoverExtensionEntrypoints(dir)) {
|
|
68
|
+
const slug = extensionSlug(rootDir);
|
|
69
|
+
const manifest = readManifest(rootDir);
|
|
52
70
|
infos.push({
|
|
53
71
|
name: manifest.name ?? slug,
|
|
54
72
|
slug,
|
|
@@ -56,7 +74,7 @@ export function listInstalledExtensions(dirs) {
|
|
|
56
74
|
dir,
|
|
57
75
|
version: manifest.version,
|
|
58
76
|
description: manifest.description,
|
|
59
|
-
skillNames: loadExtensionSkills(
|
|
77
|
+
skillNames: loadExtensionSkills(rootDir, slug).map((skill) => skill.name),
|
|
60
78
|
});
|
|
61
79
|
}
|
|
62
80
|
}
|
|
@@ -65,10 +83,18 @@ export function listInstalledExtensions(dirs) {
|
|
|
65
83
|
function discoverExtensionEntrypoints(dir) {
|
|
66
84
|
if (!existsSync(dir))
|
|
67
85
|
return [];
|
|
68
|
-
const
|
|
86
|
+
const found = [];
|
|
69
87
|
for (const name of readdirSync(dir).toSorted()) {
|
|
70
88
|
if (name.startsWith("."))
|
|
71
89
|
continue;
|
|
90
|
+
if (INDEX_FILE_PATTERN.test(name)) {
|
|
91
|
+
// An index file at the scan root means the extension's contents were
|
|
92
|
+
// copied into the scope directory itself; the slug would degenerate to
|
|
93
|
+
// the scope name (e.g. the conversation id), mis-keying its data dir,
|
|
94
|
+
// secrets, and schedules. Require a named form instead.
|
|
95
|
+
log.logWarning(`Ignoring extension index file at scope root: ${join(dir, name)}`, "install into a named subdirectory (e.g. extensions/<scope>/my-ext/index.mjs)");
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
72
98
|
const fullPath = join(dir, name);
|
|
73
99
|
let stats;
|
|
74
100
|
try {
|
|
@@ -78,55 +104,126 @@ function discoverExtensionEntrypoints(dir) {
|
|
|
78
104
|
continue;
|
|
79
105
|
}
|
|
80
106
|
if (stats.isFile() && EXTENSION_FILE_PATTERN.test(name)) {
|
|
81
|
-
|
|
107
|
+
// Bare-file form: the file is both entrypoint and (its own) root.
|
|
108
|
+
found.push({ entrypoint: fullPath, rootDir: fullPath });
|
|
82
109
|
continue;
|
|
83
110
|
}
|
|
84
111
|
if (stats.isDirectory()) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
entrypoints.push(indexPath);
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
112
|
+
const entrypoint = resolveDirectoryEntrypoint(fullPath);
|
|
113
|
+
if (entrypoint)
|
|
114
|
+
found.push({ entrypoint, rootDir: fullPath });
|
|
92
115
|
}
|
|
93
116
|
}
|
|
94
|
-
return
|
|
117
|
+
return found;
|
|
95
118
|
}
|
|
96
119
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
120
|
+
* Resolve a directory-form extension's entrypoint. A `package.json` with a
|
|
121
|
+
* `mikan.extensions` array (first entry, relative to the dir) wins — this is
|
|
122
|
+
* how an extension declares a TypeScript entry and pulls in npm dependencies.
|
|
123
|
+
* Otherwise fall back to an `index.{mjs,js,ts,mts}` file. Returns undefined
|
|
124
|
+
* when neither is present.
|
|
102
125
|
*/
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
126
|
+
function resolveDirectoryEntrypoint(dir) {
|
|
127
|
+
const declared = readMikanManifestEntrypoints(dir)[0];
|
|
128
|
+
if (declared) {
|
|
129
|
+
const resolved = join(dir, declared);
|
|
130
|
+
if (existsSync(resolved))
|
|
131
|
+
return resolved;
|
|
132
|
+
log.logWarning(`Extension package.json declares a missing entrypoint: ${resolved}`, "falling back to an index file");
|
|
133
|
+
}
|
|
134
|
+
for (const candidate of INDEX_CANDIDATES) {
|
|
135
|
+
const indexPath = join(dir, candidate);
|
|
136
|
+
if (existsSync(indexPath))
|
|
137
|
+
return indexPath;
|
|
138
|
+
}
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
/** Read and shape a directory's package.json; undefined when absent/malformed. */
|
|
142
|
+
function readPackageJson(dir) {
|
|
143
|
+
const packageJsonPath = join(dir, "package.json");
|
|
144
|
+
if (!existsSync(packageJsonPath))
|
|
145
|
+
return undefined;
|
|
146
|
+
try {
|
|
147
|
+
const parsed = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
148
|
+
if (!parsed || typeof parsed !== "object")
|
|
149
|
+
return undefined;
|
|
150
|
+
const record = parsed;
|
|
151
|
+
const mikanRaw = record.mikan;
|
|
152
|
+
return {
|
|
153
|
+
name: typeof record.name === "string" ? record.name : undefined,
|
|
154
|
+
version: typeof record.version === "string" ? record.version : undefined,
|
|
155
|
+
description: typeof record.description === "string" ? record.description : undefined,
|
|
156
|
+
mikan: {
|
|
157
|
+
extensions: Array.isArray(mikanRaw?.extensions)
|
|
158
|
+
? mikanRaw.extensions.filter((entry) => typeof entry === "string")
|
|
159
|
+
: undefined,
|
|
160
|
+
displayName: typeof mikanRaw?.displayName === "string" ? mikanRaw.displayName : undefined,
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
log.logWarning(`Ignoring malformed package.json: ${packageJsonPath}`, String(err));
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/** Read the `mikan.extensions` entrypoint list from a directory's package.json. */
|
|
170
|
+
function readMikanManifestEntrypoints(dir) {
|
|
171
|
+
return readPackageJson(dir)?.mikan?.extensions ?? [];
|
|
172
|
+
}
|
|
173
|
+
/** The one filesystem-safe segment sanitizer for extension identity and schedule names. */
|
|
174
|
+
function sanitizeSegment(value) {
|
|
175
|
+
return value
|
|
108
176
|
.toLowerCase()
|
|
109
177
|
.replace(/[^a-z0-9_-]+/g, "-")
|
|
110
178
|
.replace(/^-+|-+$/g, "")
|
|
111
179
|
.slice(0, 64);
|
|
112
|
-
|
|
180
|
+
}
|
|
181
|
+
function sanitizeSlug(base) {
|
|
182
|
+
return sanitizeSegment(base) || "extension";
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Filesystem-safe identifier for an extension, derived from its root (the
|
|
186
|
+
* install directory, or the file path for a bare-file extension). The slug
|
|
187
|
+
* keys the extension's data dir, secrets vault, and schedule ownership —
|
|
188
|
+
* installing the same extension globally and per-conversation shares one
|
|
189
|
+
* slug and therefore one shared data dir. This is the only slug derivation:
|
|
190
|
+
* a second one keyed off a different input (e.g. the entrypoint, which for
|
|
191
|
+
* package.json-form extensions can live under dist/) would silently split an
|
|
192
|
+
* extension's identity.
|
|
193
|
+
*/
|
|
194
|
+
export function extensionSlug(rootDir) {
|
|
195
|
+
return EXTENSION_FILE_PATTERN.test(basename(rootDir))
|
|
196
|
+
? sanitizeSlug(basename(rootDir).replace(EXTENSION_FILE_PATTERN, ""))
|
|
197
|
+
: sanitizeSlug(basename(rootDir));
|
|
113
198
|
}
|
|
114
199
|
/** Sanitize an extension-chosen schedule name into a filename segment. */
|
|
115
200
|
function scheduleNameSegment(name) {
|
|
116
|
-
const segment = name
|
|
117
|
-
.toLowerCase()
|
|
118
|
-
.replace(/[^a-z0-9_-]+/g, "-")
|
|
119
|
-
.replace(/^-+|-+$/g, "")
|
|
120
|
-
.slice(0, 64);
|
|
201
|
+
const segment = sanitizeSegment(name);
|
|
121
202
|
if (!segment)
|
|
122
203
|
throw new Error(`Invalid schedule name: ${JSON.stringify(name)}`);
|
|
123
204
|
return segment;
|
|
124
205
|
}
|
|
125
|
-
/**
|
|
126
|
-
|
|
127
|
-
|
|
206
|
+
/**
|
|
207
|
+
* Read display metadata (name/version/description) for a directory-form
|
|
208
|
+
* extension. `package.json` is the primary source — its standard `name`,
|
|
209
|
+
* `version`, `description`, plus an optional `mikan.displayName` that
|
|
210
|
+
* overrides the npm name for the user-facing label (npm names are
|
|
211
|
+
* lowercase/scoped; display names can be arbitrary). A `manifest.json` is a
|
|
212
|
+
* fallback for extensions that ship no package.json.
|
|
213
|
+
*/
|
|
214
|
+
function readManifest(rootDir) {
|
|
215
|
+
// Bare-file extensions (rootDir is a *.mjs/.ts file) have no manifest.
|
|
216
|
+
if (EXTENSION_FILE_PATTERN.test(basename(rootDir)))
|
|
128
217
|
return {};
|
|
129
|
-
const
|
|
218
|
+
const pkg = readPackageJson(rootDir);
|
|
219
|
+
if (pkg && (pkg.mikan?.displayName ?? pkg.name ?? pkg.version ?? pkg.description)) {
|
|
220
|
+
return {
|
|
221
|
+
name: pkg.mikan?.displayName ?? pkg.name,
|
|
222
|
+
version: pkg.version,
|
|
223
|
+
description: pkg.description,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
const manifestPath = join(rootDir, "manifest.json");
|
|
130
227
|
if (!existsSync(manifestPath))
|
|
131
228
|
return {};
|
|
132
229
|
try {
|
|
@@ -150,10 +247,11 @@ function readManifest(entrypoint) {
|
|
|
150
247
|
* Marked inline: extension files live under the host-only state dir, which
|
|
151
248
|
* sandbox containers cannot read, so skill bodies must ride in the prompt.
|
|
152
249
|
*/
|
|
153
|
-
function loadExtensionSkills(
|
|
154
|
-
|
|
250
|
+
function loadExtensionSkills(rootDir, slug) {
|
|
251
|
+
// Bare-file extensions (rootDir is a *.mjs/.ts file) ship no skills.
|
|
252
|
+
if (EXTENSION_FILE_PATTERN.test(basename(rootDir)))
|
|
155
253
|
return [];
|
|
156
|
-
const skillsDir = join(
|
|
254
|
+
const skillsDir = join(rootDir, "skills");
|
|
157
255
|
if (!existsSync(skillsDir))
|
|
158
256
|
return [];
|
|
159
257
|
const result = loadSkillsFromDir({ dir: skillsDir, source: `extension:${slug}` });
|
|
@@ -169,42 +267,34 @@ function schedulePrefix(slug, conversationId) {
|
|
|
169
267
|
return `ext.${slug}.${scheduleNameSegment(conversationId)}.`;
|
|
170
268
|
}
|
|
171
269
|
function payloadFromSpec(spec, conversationId) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
return {
|
|
177
|
-
type: "periodic",
|
|
178
|
-
conversationId,
|
|
179
|
-
text: spec.text,
|
|
180
|
-
schedule: spec.schedule,
|
|
181
|
-
timezone: spec.timezone,
|
|
182
|
-
...(spec.platform ? { platform: spec.platform } : {}),
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
if (!spec.at)
|
|
186
|
-
throw new Error("one-shot schedule requires at");
|
|
187
|
-
return {
|
|
188
|
-
type: "one-shot",
|
|
270
|
+
// Per-type validation (schedule/timezone for periodic, at for one-shot)
|
|
271
|
+
// is owned by the event-format builder.
|
|
272
|
+
return buildEventPayload({
|
|
273
|
+
type: spec.type,
|
|
189
274
|
conversationId,
|
|
190
275
|
text: spec.text,
|
|
191
|
-
at: spec.at,
|
|
192
276
|
...(spec.platform ? { platform: spec.platform } : {}),
|
|
193
|
-
|
|
277
|
+
...(spec.type === "periodic"
|
|
278
|
+
? { schedule: spec.schedule, timezone: spec.timezone }
|
|
279
|
+
: { at: spec.at }),
|
|
280
|
+
});
|
|
194
281
|
}
|
|
195
282
|
function specFromPayload(payload) {
|
|
196
283
|
if (payload.type === "periodic") {
|
|
197
284
|
return {
|
|
198
285
|
type: "periodic",
|
|
199
|
-
schedule: payload.schedule
|
|
200
|
-
timezone: payload.timezone
|
|
286
|
+
schedule: payload.schedule,
|
|
287
|
+
timezone: payload.timezone,
|
|
201
288
|
text: payload.text,
|
|
202
289
|
...(payload.platform ? { platform: payload.platform } : {}),
|
|
203
290
|
};
|
|
204
291
|
}
|
|
292
|
+
// `immediate` payloads never appear under the schedules namespace (they
|
|
293
|
+
// live under "extrun."); tolerate them as an empty one-shot rather than
|
|
294
|
+
// widening the spec union.
|
|
205
295
|
return {
|
|
206
296
|
type: "one-shot",
|
|
207
|
-
at: payload.at
|
|
297
|
+
at: payload.type === "one-shot" ? payload.at : "",
|
|
208
298
|
text: payload.text,
|
|
209
299
|
...(payload.platform ? { platform: payload.platform } : {}),
|
|
210
300
|
};
|
|
@@ -223,11 +313,21 @@ function buildExtensionApi(params) {
|
|
|
223
313
|
return {
|
|
224
314
|
on: (hook, handler) => registry.register(name, hook, handler),
|
|
225
315
|
registerTool: (tool) => registry.registerTool(tool),
|
|
316
|
+
registerCommand: (command) => registry.registerCommand(name, command),
|
|
317
|
+
onDispose: (disposer) => registry.registerDisposer(name, disposer),
|
|
226
318
|
log: (message) => log.logInfo(`[extension:${name}] ${message}`),
|
|
227
319
|
context,
|
|
228
320
|
paths: {
|
|
229
321
|
get dataDir() {
|
|
230
|
-
|
|
322
|
+
// This conversation's own data, co-located with the conversation's
|
|
323
|
+
// other host-only assets; removed when the conversation is deleted.
|
|
324
|
+
const dir = join(stateDir, "conversations", conversationId, "extension-data", slug);
|
|
325
|
+
mkdirSync(dir, { recursive: true });
|
|
326
|
+
return dir;
|
|
327
|
+
},
|
|
328
|
+
get sharedDataDir() {
|
|
329
|
+
// Cross-conversation data under the sibling `global` scope.
|
|
330
|
+
const dir = join(stateDir, "global", "extension-data", slug);
|
|
231
331
|
mkdirSync(dir, { recursive: true });
|
|
232
332
|
return dir;
|
|
233
333
|
},
|
|
@@ -264,14 +364,44 @@ function buildExtensionApi(params) {
|
|
|
264
364
|
return infos;
|
|
265
365
|
},
|
|
266
366
|
},
|
|
267
|
-
|
|
367
|
+
subagent: {
|
|
368
|
+
run: async (request) => {
|
|
369
|
+
if (!services.runSubagent) {
|
|
370
|
+
throw new Error("api.subagent is unavailable: this context provides no subagent runner");
|
|
371
|
+
}
|
|
372
|
+
return services.runSubagent(request, registry.getContributedTools());
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
notify: async (text, options) => {
|
|
268
376
|
if (!services.postMessage) {
|
|
269
377
|
throw new Error("api.notify is unavailable: this context provides no platform messaging");
|
|
270
378
|
}
|
|
271
|
-
await services.postMessage(conversationId, text);
|
|
379
|
+
await services.postMessage(options?.conversationId ?? conversationId, text);
|
|
380
|
+
},
|
|
381
|
+
react: async (messageTs, emoji) => {
|
|
382
|
+
if (!services.addReaction) {
|
|
383
|
+
throw new Error("api.react is unavailable: this context provides no reaction support");
|
|
384
|
+
}
|
|
385
|
+
await services.addReaction(conversationId, messageTs, emoji);
|
|
386
|
+
},
|
|
387
|
+
uploadFile: async (filePath, title) => {
|
|
388
|
+
if (!services.uploadFile) {
|
|
389
|
+
throw new Error("api.uploadFile is unavailable: this context provides no file uploads");
|
|
390
|
+
}
|
|
391
|
+
await services.uploadFile(conversationId, filePath, title);
|
|
392
|
+
},
|
|
393
|
+
triggerRun: async (text) => {
|
|
394
|
+
const store = requireScheduleStore();
|
|
395
|
+
// Distinct "extrun." namespace: run files must never surface in
|
|
396
|
+
// api.schedules.list(), whose ownership filter is the "ext." prefix.
|
|
397
|
+
// The embedder's watcher fires and deletes the file immediately.
|
|
398
|
+
const filename = `extrun.${slug}.${scheduleNameSegment(conversationId)}.${Date.now()}-${runCounter++}${SCHEDULE_FILE_SUFFIX}`;
|
|
399
|
+
await store.write(filename, { type: "immediate", conversationId, text });
|
|
272
400
|
},
|
|
273
401
|
};
|
|
274
402
|
}
|
|
403
|
+
/** Monotonic suffix so rapid triggerRun calls in one process never collide. */
|
|
404
|
+
let runCounter = 0;
|
|
275
405
|
function resolveActivate(moduleExports) {
|
|
276
406
|
if (!moduleExports || typeof moduleExports !== "object")
|
|
277
407
|
return undefined;
|
|
@@ -302,10 +432,9 @@ export async function loadExtensions(options) {
|
|
|
302
432
|
const skills = [];
|
|
303
433
|
const services = options.services ?? {};
|
|
304
434
|
for (const dir of options.dirs) {
|
|
305
|
-
for (const entrypoint of discoverExtensionEntrypoints(dir)) {
|
|
435
|
+
for (const { entrypoint, rootDir } of discoverExtensionEntrypoints(dir)) {
|
|
306
436
|
try {
|
|
307
|
-
const
|
|
308
|
-
const moduleExports = await import(moduleUrl);
|
|
437
|
+
const moduleExports = await importExtensionModule(entrypoint);
|
|
309
438
|
const extension = resolveActivate(moduleExports);
|
|
310
439
|
if (!extension) {
|
|
311
440
|
errors.push({
|
|
@@ -314,8 +443,8 @@ export async function loadExtensions(options) {
|
|
|
314
443
|
});
|
|
315
444
|
continue;
|
|
316
445
|
}
|
|
317
|
-
const slug = extensionSlug(
|
|
318
|
-
const manifest = readManifest(
|
|
446
|
+
const slug = extensionSlug(rootDir);
|
|
447
|
+
const manifest = readManifest(rootDir);
|
|
319
448
|
const name = manifest.name ?? extension.name ?? slug;
|
|
320
449
|
const api = buildExtensionApi({
|
|
321
450
|
name,
|
|
@@ -324,8 +453,10 @@ export async function loadExtensions(options) {
|
|
|
324
453
|
context: options.context,
|
|
325
454
|
services,
|
|
326
455
|
});
|
|
327
|
-
await extension.activate(api);
|
|
328
|
-
|
|
456
|
+
const disposer = await extension.activate(api);
|
|
457
|
+
if (typeof disposer === "function")
|
|
458
|
+
registry.registerDisposer(name, disposer);
|
|
459
|
+
const extensionSkills = loadExtensionSkills(rootDir, slug);
|
|
329
460
|
skills.push(...extensionSkills);
|
|
330
461
|
extensions.push({
|
|
331
462
|
name,
|
|
@@ -344,6 +475,64 @@ export async function loadExtensions(options) {
|
|
|
344
475
|
}
|
|
345
476
|
}
|
|
346
477
|
}
|
|
347
|
-
return { registry, extensions, errors, skills };
|
|
478
|
+
return { registry, extensions, errors, skills, dispose: () => registry.dispose() };
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Validate an extension source path (a directory or a single file) WITHOUT
|
|
482
|
+
* activating it: resolves the entrypoint (package.json `mikan.extensions`,
|
|
483
|
+
* index file, or the file itself), imports it, and checks it exports an
|
|
484
|
+
* `activate` function. Used by `mikan ext install` as a preflight and by
|
|
485
|
+
* `mikan ext validate`. Importing runs top-level module code but not
|
|
486
|
+
* `activate`, so there are no schedule/tool side effects.
|
|
487
|
+
*/
|
|
488
|
+
export async function validateExtension(sourcePath) {
|
|
489
|
+
const errors = [];
|
|
490
|
+
const warnings = [];
|
|
491
|
+
const rootDir = sourcePath.replace(/[/\\]+$/, "");
|
|
492
|
+
const base = basename(rootDir);
|
|
493
|
+
if (INDEX_FILE_PATTERN.test(base)) {
|
|
494
|
+
warnings.push("Entry is a bare index file; install into a named directory so the slug is stable.");
|
|
495
|
+
}
|
|
496
|
+
let entrypoint;
|
|
497
|
+
if (!existsSync(rootDir)) {
|
|
498
|
+
errors.push(`Path does not exist: ${rootDir}`);
|
|
499
|
+
}
|
|
500
|
+
else if (statSync(rootDir).isDirectory()) {
|
|
501
|
+
entrypoint = resolveDirectoryEntrypoint(rootDir);
|
|
502
|
+
if (!entrypoint) {
|
|
503
|
+
errors.push("No entrypoint found: expected package.json with a mikan.extensions entry, or an index.{mjs,js,ts,mts}.");
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
else if (EXTENSION_FILE_PATTERN.test(base)) {
|
|
507
|
+
entrypoint = rootDir;
|
|
508
|
+
}
|
|
509
|
+
else {
|
|
510
|
+
errors.push(`Not an extension file (expected .mjs/.js/.ts/.mts): ${rootDir}`);
|
|
511
|
+
}
|
|
512
|
+
const slug = extensionSlug(rootDir);
|
|
513
|
+
const manifest = readManifest(rootDir);
|
|
514
|
+
const skillNames = loadExtensionSkills(rootDir, slug).map((skill) => skill.name);
|
|
515
|
+
if (entrypoint) {
|
|
516
|
+
try {
|
|
517
|
+
const moduleExports = await importExtensionModule(entrypoint);
|
|
518
|
+
if (!resolveActivate(moduleExports)) {
|
|
519
|
+
errors.push("Module does not export an activate function (default or named).");
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
catch (err) {
|
|
523
|
+
errors.push(`Failed to import: ${err instanceof Error ? err.message : String(err)}`);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
return {
|
|
527
|
+
ok: errors.length === 0,
|
|
528
|
+
slug,
|
|
529
|
+
name: manifest.name ?? slug,
|
|
530
|
+
version: manifest.version,
|
|
531
|
+
description: manifest.description,
|
|
532
|
+
entrypoint,
|
|
533
|
+
skillNames,
|
|
534
|
+
errors,
|
|
535
|
+
warnings,
|
|
536
|
+
};
|
|
348
537
|
}
|
|
349
538
|
//# sourceMappingURL=loader.js.map
|