@geminixiang/mikan 1.0.0-beta.45 → 1.0.0-beta.47
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 +47 -0
- package/README.md +12 -19
- 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/discord/bot.d.ts +6 -1
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +168 -144
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/discord/context.d.ts +2 -8
- package/dist/adapters/discord/context.d.ts.map +1 -1
- package/dist/adapters/discord/context.js +1 -1
- package/dist/adapters/discord/context.js.map +1 -1
- package/dist/adapters/discord/format.d.ts.map +1 -1
- package/dist/adapters/discord/format.js +2 -4
- package/dist/adapters/discord/format.js.map +1 -1
- package/dist/adapters/github/bot.d.ts +6 -1
- package/dist/adapters/github/bot.d.ts.map +1 -1
- package/dist/adapters/github/bot.js +57 -25
- package/dist/adapters/github/bot.js.map +1 -1
- package/dist/adapters/github/context.d.ts +2 -9
- package/dist/adapters/github/context.d.ts.map +1 -1
- package/dist/adapters/github/context.js.map +1 -1
- package/dist/adapters/github/github-ops.d.ts +4 -17
- package/dist/adapters/github/github-ops.d.ts.map +1 -1
- package/dist/adapters/github/github-ops.js +17 -86
- package/dist/adapters/github/github-ops.js.map +1 -1
- package/dist/adapters/github/tool-pack.d.ts.map +1 -1
- package/dist/adapters/github/tool-pack.js +0 -1
- package/dist/adapters/github/tool-pack.js.map +1 -1
- package/dist/adapters/github/tools/checks.d.ts +0 -1
- package/dist/adapters/github/tools/checks.d.ts.map +1 -1
- package/dist/adapters/github/tools/checks.js +3 -22
- package/dist/adapters/github/tools/checks.js.map +1 -1
- package/dist/adapters/github/types.d.ts +0 -33
- package/dist/adapters/github/types.d.ts.map +1 -1
- package/dist/adapters/github/types.js.map +1 -1
- package/dist/adapters/progressive-renderer.d.ts.map +1 -1
- package/dist/adapters/progressive-renderer.js +311 -318
- package/dist/adapters/progressive-renderer.js.map +1 -1
- package/dist/adapters/shared.d.ts +12 -1
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/shared.js +44 -1
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/slack/blocks.d.ts.map +1 -1
- package/dist/adapters/slack/blocks.js +1 -4
- package/dist/adapters/slack/blocks.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +15 -0
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +233 -206
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/context.d.ts +2 -8
- package/dist/adapters/slack/context.d.ts.map +1 -1
- package/dist/adapters/slack/context.js +1 -1
- 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 +135 -123
- package/dist/adapters/slack/response-lifecycle.js.map +1 -1
- package/dist/adapters/slack/stream-limits.d.ts +1 -1
- package/dist/adapters/slack/stream-limits.js +1 -1
- package/dist/adapters/slack/stream-limits.js.map +1 -1
- package/dist/adapters/slack/types.d.ts +4 -0
- package/dist/adapters/slack/types.d.ts.map +1 -1
- package/dist/adapters/slack/types.js.map +1 -1
- package/dist/adapters/telegram/bot.d.ts +3 -0
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +23 -7
- package/dist/adapters/telegram/bot.js.map +1 -1
- package/dist/adapters/telegram/context.d.ts +2 -8
- package/dist/adapters/telegram/context.d.ts.map +1 -1
- package/dist/adapters/telegram/context.js +1 -2
- package/dist/adapters/telegram/context.js.map +1 -1
- package/dist/adapters/types.d.ts +11 -5
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/agent/catalog.d.ts +6 -18
- package/dist/agent/catalog.d.ts.map +1 -1
- package/dist/agent/catalog.js +24 -156
- package/dist/agent/catalog.js.map +1 -1
- package/dist/agent/execution.d.ts +0 -7
- package/dist/agent/execution.d.ts.map +1 -1
- package/dist/agent/execution.js +23 -21
- package/dist/agent/execution.js.map +1 -1
- package/dist/agent/presenter.d.ts +7 -9
- package/dist/agent/presenter.d.ts.map +1 -1
- package/dist/agent/presenter.js +355 -357
- package/dist/agent/presenter.js.map +1 -1
- package/dist/agent/prompt.d.ts +5 -12
- package/dist/agent/prompt.d.ts.map +1 -1
- package/dist/agent/prompt.js +56 -81
- package/dist/agent/prompt.js.map +1 -1
- package/dist/agent/runner.d.ts +0 -7
- package/dist/agent/runner.d.ts.map +1 -1
- package/dist/agent/runner.js +335 -318
- package/dist/agent/runner.js.map +1 -1
- package/dist/agent/types.d.ts +21 -17
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js +0 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/cli/boot.d.ts.map +1 -1
- package/dist/cli/boot.js +7 -10
- package/dist/cli/boot.js.map +1 -1
- package/dist/cli/onboard.d.ts +10 -0
- package/dist/cli/onboard.d.ts.map +1 -0
- package/dist/cli/onboard.js +237 -0
- package/dist/cli/onboard.js.map +1 -0
- package/dist/cli/types.d.ts +8 -3
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/cli/types.js.map +1 -1
- package/dist/commands/auto-reply.d.ts.map +1 -1
- package/dist/commands/auto-reply.js +5 -12
- package/dist/commands/auto-reply.js.map +1 -1
- package/dist/commands/manifest.d.ts.map +1 -1
- package/dist/commands/manifest.js +9 -16
- package/dist/commands/manifest.js.map +1 -1
- package/dist/commands/new.d.ts.map +1 -1
- package/dist/commands/new.js +15 -10
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/registry.d.ts.map +1 -1
- package/dist/commands/registry.js +0 -2
- package/dist/commands/registry.js.map +1 -1
- package/dist/commands/sandbox.d.ts.map +1 -1
- package/dist/commands/sandbox.js +89 -70
- package/dist/commands/sandbox.js.map +1 -1
- package/dist/commands/session-view.js +9 -2
- package/dist/commands/session-view.js.map +1 -1
- package/dist/commands/types.d.ts +4 -3
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/config.d.ts +13 -17
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +39 -37
- package/dist/config.js.map +1 -1
- package/dist/dream/index.d.ts +20 -0
- package/dist/dream/index.d.ts.map +1 -0
- package/dist/dream/index.js +253 -0
- package/dist/dream/index.js.map +1 -0
- package/dist/dream/types.d.ts +30 -0
- package/dist/dream/types.d.ts.map +1 -0
- package/dist/dream/types.js.map +1 -0
- package/dist/env-manifest.d.ts.map +1 -1
- package/dist/env-manifest.js +12 -27
- package/dist/env-manifest.js.map +1 -1
- package/dist/execution-resolver.d.ts +9 -2
- package/dist/execution-resolver.d.ts.map +1 -1
- package/dist/execution-resolver.js +26 -27
- package/dist/execution-resolver.js.map +1 -1
- package/dist/harness/event-format.d.ts +1 -2
- package/dist/harness/event-format.d.ts.map +1 -1
- package/dist/harness/event-format.js +9 -15
- package/dist/harness/event-format.js.map +1 -1
- package/dist/harness/index.d.ts +1 -7
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +0 -4
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/models.d.ts.map +1 -1
- package/dist/harness/models.js +15 -35
- package/dist/harness/models.js.map +1 -1
- package/dist/harness/runner.d.ts +7 -16
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +13 -131
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session-store.d.ts +1 -1
- package/dist/harness/session-store.d.ts.map +1 -1
- package/dist/harness/session-store.js +1 -1
- package/dist/harness/session-store.js.map +1 -1
- package/dist/harness/subagent-runner.d.ts +2 -2
- package/dist/harness/subagent-runner.d.ts.map +1 -1
- package/dist/harness/subagent-runner.js +157 -162
- package/dist/harness/subagent-runner.js.map +1 -1
- package/dist/harness/types.d.ts +1 -13
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/index.d.ts +3 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -5
- package/dist/index.js.map +1 -1
- package/dist/main.js +103 -222
- package/dist/main.js.map +1 -1
- package/dist/mcp/catalog.d.ts +5 -0
- package/dist/mcp/catalog.d.ts.map +1 -0
- package/dist/mcp/catalog.js +156 -0
- package/dist/mcp/catalog.js.map +1 -0
- package/dist/mcp/loader.d.ts +3 -2
- package/dist/mcp/loader.d.ts.map +1 -1
- package/dist/mcp/loader.js +54 -23
- package/dist/mcp/loader.js.map +1 -1
- package/dist/mcp/open-connector.d.ts +14 -0
- package/dist/mcp/open-connector.d.ts.map +1 -0
- package/dist/mcp/open-connector.js +203 -0
- package/dist/mcp/open-connector.js.map +1 -0
- package/dist/mcp/types.d.ts +28 -0
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/mcp/types.js.map +1 -1
- package/dist/office/index.d.ts +136 -8
- package/dist/office/index.d.ts.map +1 -1
- package/dist/office/index.js +1050 -9
- package/dist/office/index.js.map +1 -1
- package/dist/office/types.d.ts +19 -1
- package/dist/office/types.d.ts.map +1 -1
- package/dist/office/types.js.map +1 -1
- package/dist/packages/index.d.ts +168 -5
- package/dist/packages/index.d.ts.map +1 -1
- package/dist/packages/index.js +720 -5
- package/dist/packages/index.js.map +1 -1
- package/dist/packages/types.d.ts +1 -5
- package/dist/packages/types.d.ts.map +1 -1
- package/dist/packages/types.js.map +1 -1
- package/dist/process-lifecycle.d.ts +19 -0
- package/dist/process-lifecycle.d.ts.map +1 -0
- package/dist/process-lifecycle.js +60 -0
- package/dist/process-lifecycle.js.map +1 -0
- package/dist/provisioner.d.ts +2 -9
- package/dist/provisioner.d.ts.map +1 -1
- package/dist/provisioner.js +3 -12
- package/dist/provisioner.js.map +1 -1
- package/dist/runtime/conversation-runtime.d.ts.map +1 -1
- package/dist/runtime/conversation-runtime.js +124 -380
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/session-lifecycle.d.ts +34 -18
- package/dist/runtime/session-lifecycle.d.ts.map +1 -1
- package/dist/runtime/session-lifecycle.js +179 -46
- package/dist/runtime/session-lifecycle.js.map +1 -1
- package/dist/runtime/types.d.ts +8 -26
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/cloudflare.d.ts.map +1 -1
- package/dist/sandbox/cloudflare.js +2 -3
- package/dist/sandbox/cloudflare.js.map +1 -1
- package/dist/sandbox/container.d.ts +0 -1
- package/dist/sandbox/container.d.ts.map +1 -1
- package/dist/sandbox/container.js +2 -3
- package/dist/sandbox/container.js.map +1 -1
- package/dist/sandbox/host.d.ts.map +1 -1
- package/dist/sandbox/host.js +4 -2
- package/dist/sandbox/host.js.map +1 -1
- package/dist/sandbox/identity.d.ts +10 -19
- package/dist/sandbox/identity.d.ts.map +1 -1
- package/dist/sandbox/identity.js +8 -8
- package/dist/sandbox/identity.js.map +1 -1
- package/dist/sandbox/index.d.ts +7 -10
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +45 -16
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/types.d.ts +13 -45
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/sandbox/types.js.map +1 -1
- package/dist/sandbox/utils.d.ts +5 -0
- package/dist/sandbox/utils.d.ts.map +1 -1
- package/dist/sandbox/utils.js +10 -0
- package/dist/sandbox/utils.js.map +1 -1
- package/dist/sessions/chat-history-sync.d.ts +1 -3
- package/dist/sessions/chat-history-sync.d.ts.map +1 -1
- package/dist/sessions/chat-history-sync.js +58 -11
- package/dist/sessions/chat-history-sync.js.map +1 -1
- package/dist/sessions/migrate-v3.d.ts +2 -5
- package/dist/sessions/migrate-v3.d.ts.map +1 -1
- package/dist/sessions/migrate-v3.js +17 -1
- package/dist/sessions/migrate-v3.js.map +1 -1
- package/dist/sessions/store.d.ts +5 -6
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +62 -2
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/types.d.ts +9 -0
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js.map +1 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +2 -10
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/read.js +2 -2
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/sandbox.d.ts.map +1 -1
- package/dist/tools/sandbox.js +2 -3
- package/dist/tools/sandbox.js.map +1 -1
- package/dist/tools/subagent.d.ts +1 -1
- package/dist/tools/subagent.js.map +1 -1
- package/dist/types.d.ts +54 -130
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/vault/index.d.ts +9 -2
- package/dist/vault/index.d.ts.map +1 -1
- package/dist/vault/index.js +29 -5
- package/dist/vault/index.js.map +1 -1
- package/dist/web/admin/portal.d.ts +12 -1
- package/dist/web/admin/portal.d.ts.map +1 -1
- package/dist/web/admin/portal.js +437 -422
- package/dist/web/admin/portal.js.map +1 -1
- package/dist/web/admin/types.d.ts +2 -2
- package/dist/web/admin/types.d.ts.map +1 -1
- package/dist/web/admin/types.js.map +1 -1
- package/dist/web/login/portal.d.ts +7 -1
- package/dist/web/login/portal.d.ts.map +1 -1
- package/dist/web/login/portal.js +143 -78
- package/dist/web/login/portal.js.map +1 -1
- package/dist/web/portal-shell.d.ts +1 -0
- package/dist/web/portal-shell.d.ts.map +1 -1
- package/dist/web/portal-shell.js +12 -1
- package/dist/web/portal-shell.js.map +1 -1
- package/dist/web/server.d.ts +3 -3
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js.map +1 -1
- package/dist/web/session-view/portal.d.ts +8 -1
- package/dist/web/session-view/portal.d.ts.map +1 -1
- package/dist/web/session-view/portal.js +609 -132
- package/dist/web/session-view/portal.js.map +1 -1
- package/dist/web/session-view/types.d.ts +8 -0
- package/dist/web/session-view/types.d.ts.map +1 -1
- package/dist/web/session-view/types.js.map +1 -1
- package/dist/workspace-projection/index.d.ts +14 -2
- package/dist/workspace-projection/index.d.ts.map +1 -1
- package/dist/workspace-projection/index.js +102 -14
- package/dist/workspace-projection/index.js.map +1 -1
- package/dist/workspace-projection/types.d.ts +14 -1
- package/dist/workspace-projection/types.d.ts.map +1 -1
- package/dist/workspace-projection/types.js.map +1 -1
- package/package.json +3 -5
- package/dist/adapters/github/cloudbuild.d.ts +0 -19
- package/dist/adapters/github/cloudbuild.d.ts.map +0 -1
- package/dist/adapters/github/cloudbuild.js +0 -71
- package/dist/adapters/github/cloudbuild.js.map +0 -1
- package/dist/adapters/github/gcp-auth.d.ts +0 -28
- package/dist/adapters/github/gcp-auth.d.ts.map +0 -1
- package/dist/adapters/github/gcp-auth.js +0 -196
- package/dist/adapters/github/gcp-auth.js.map +0 -1
- package/dist/agent/index.d.ts +0 -9
- package/dist/agent/index.d.ts.map +0 -1
- package/dist/agent/index.js +0 -8
- package/dist/agent/index.js.map +0 -1
- package/dist/cli/ext-dev.d.ts +0 -2
- package/dist/cli/ext-dev.d.ts.map +0 -1
- package/dist/cli/ext-dev.js +0 -188
- package/dist/cli/ext-dev.js.map +0 -1
- package/dist/cli/ext.d.ts +0 -2
- package/dist/cli/ext.d.ts.map +0 -1
- package/dist/cli/ext.js +0 -324
- package/dist/cli/ext.js.map +0 -1
- package/dist/commands/extensions.d.ts +0 -26
- package/dist/commands/extensions.d.ts.map +0 -1
- package/dist/commands/extensions.js +0 -103
- package/dist/commands/extensions.js.map +0 -1
- package/dist/extension-schedules.d.ts +0 -31
- package/dist/extension-schedules.d.ts.map +0 -1
- package/dist/extension-schedules.js +0 -229
- package/dist/extension-schedules.js.map +0 -1
- package/dist/harness/auth.d.ts +0 -17
- package/dist/harness/auth.d.ts.map +0 -1
- package/dist/harness/auth.js +0 -92
- package/dist/harness/auth.js.map +0 -1
- package/dist/harness/extensions/loader.d.ts +0 -40
- package/dist/harness/extensions/loader.d.ts.map +0 -1
- package/dist/harness/extensions/loader.js +0 -723
- package/dist/harness/extensions/loader.js.map +0 -1
- package/dist/harness/extensions/registry.d.ts +0 -155
- package/dist/harness/extensions/registry.d.ts.map +0 -1
- package/dist/harness/extensions/registry.js +0 -420
- package/dist/harness/extensions/registry.js.map +0 -1
- package/dist/harness/extensions/types.d.ts +0 -665
- package/dist/harness/extensions/types.d.ts.map +0 -1
- package/dist/harness/extensions/types.js.map +0 -1
- package/dist/office/address.d.ts +0 -31
- package/dist/office/address.d.ts.map +0 -1
- package/dist/office/address.js +0 -113
- package/dist/office/address.js.map +0 -1
- package/dist/office/layout.d.ts +0 -27
- package/dist/office/layout.d.ts.map +0 -1
- package/dist/office/layout.js +0 -97
- package/dist/office/layout.js.map +0 -1
- package/dist/office/migration.d.ts +0 -44
- package/dist/office/migration.d.ts.map +0 -1
- package/dist/office/migration.js +0 -255
- package/dist/office/migration.js.map +0 -1
- package/dist/office/registry.d.ts +0 -75
- package/dist/office/registry.d.ts.map +0 -1
- package/dist/office/registry.js +0 -646
- package/dist/office/registry.js.map +0 -1
- package/dist/packages/admin.d.ts +0 -17
- package/dist/packages/admin.d.ts.map +0 -1
- package/dist/packages/admin.js +0 -98
- package/dist/packages/admin.js.map +0 -1
- package/dist/packages/inspect.d.ts +0 -11
- package/dist/packages/inspect.d.ts.map +0 -1
- package/dist/packages/inspect.js +0 -98
- package/dist/packages/inspect.js.map +0 -1
- package/dist/packages/materialize.d.ts +0 -40
- package/dist/packages/materialize.d.ts.map +0 -1
- package/dist/packages/materialize.js +0 -297
- package/dist/packages/materialize.js.map +0 -1
- package/dist/packages/resolve.d.ts +0 -25
- package/dist/packages/resolve.d.ts.map +0 -1
- package/dist/packages/resolve.js +0 -208
- package/dist/packages/resolve.js.map +0 -1
- package/dist/packages/source.d.ts +0 -39
- package/dist/packages/source.d.ts.map +0 -1
- package/dist/packages/source.js +0 -189
- package/dist/packages/source.js.map +0 -1
- package/dist/sandbox/errors.d.ts +0 -6
- package/dist/sandbox/errors.d.ts.map +0 -1
- package/dist/sandbox/errors.js +0 -11
- package/dist/sandbox/errors.js.map +0 -1
- package/dist/sandbox/firecracker.d.ts +0 -18
- package/dist/sandbox/firecracker.d.ts.map +0 -1
- package/dist/sandbox/firecracker.js +0 -223
- package/dist/sandbox/firecracker.js.map +0 -1
- package/dist/sandbox/gondolin.d.ts +0 -57
- package/dist/sandbox/gondolin.d.ts.map +0 -1
- package/dist/sandbox/gondolin.js +0 -764
- package/dist/sandbox/gondolin.js.map +0 -1
- package/dist/sandbox/image.d.ts +0 -3
- package/dist/sandbox/image.d.ts.map +0 -1
- package/dist/sandbox/image.js +0 -29
- package/dist/sandbox/image.js.map +0 -1
- package/dist/sessions/conversation-log.d.ts +0 -9
- package/dist/sessions/conversation-log.d.ts.map +0 -1
- package/dist/sessions/conversation-log.js +0 -50
- package/dist/sessions/conversation-log.js.map +0 -1
- package/dist/sessions/rotation.d.ts +0 -2
- package/dist/sessions/rotation.d.ts.map +0 -1
- package/dist/sessions/rotation.js +0 -41
- package/dist/sessions/rotation.js.map +0 -1
- package/dist/vault/disabled.d.ts +0 -9
- package/dist/vault/disabled.d.ts.map +0 -1
- package/dist/vault/disabled.js +0 -25
- package/dist/vault/disabled.js.map +0 -1
- package/dist/web/admin/store.d.ts +0 -13
- package/dist/web/admin/store.d.ts.map +0 -1
- package/dist/web/admin/store.js +0 -14
- package/dist/web/admin/store.js.map +0 -1
- package/dist/web/login/store.d.ts +0 -8
- package/dist/web/login/store.d.ts.map +0 -1
- package/dist/web/login/store.js +0 -15
- package/dist/web/login/store.js.map +0 -1
- package/dist/web/session-view/service.d.ts +0 -6
- package/dist/web/session-view/service.d.ts.map +0 -1
- package/dist/web/session-view/service.js +0 -517
- package/dist/web/session-view/service.js.map +0 -1
- package/dist/web/session-view/store.d.ts +0 -8
- package/dist/web/session-view/store.d.ts.map +0 -1
- package/dist/web/session-view/store.js +0 -15
- package/dist/web/session-view/store.js.map +0 -1
- /package/dist/{harness/extensions → dream}/types.js +0 -0
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Host-authoritative store + scheduler for extension callback schedules.
|
|
3
|
-
*
|
|
4
|
-
* `api.schedules` callback specs fire trusted host-side handlers, so unlike
|
|
5
|
-
* the agent-writable workspace event bus (`events/`, watched by
|
|
6
|
-
* EventsWatcher), these schedules persist under the host-only state dir:
|
|
7
|
-
* `<stateDir>/conversations/<officeKey>/extension-schedules/<slug>.<name>.json`.
|
|
8
|
-
* A sandboxed agent can neither create nor edit them — the file is written
|
|
9
|
-
* exclusively by extension code running in the mikan process.
|
|
10
|
-
*
|
|
11
|
-
* One process-wide scheduler arms every schedule with croner (periodic cron
|
|
12
|
-
* or a one-shot ISO date), survives restarts via a boot scan, and dispatches
|
|
13
|
-
* fires to the conversation runtime, which materializes the conversation's
|
|
14
|
-
* harness and runs the registered `onCallback` handler — no agent run, no
|
|
15
|
-
* model call.
|
|
16
|
-
*/
|
|
17
|
-
import { Cron } from "croner";
|
|
18
|
-
import { existsSync, readdirSync, readFileSync, rmSync } from "node:fs";
|
|
19
|
-
import { readFile } from "node:fs/promises";
|
|
20
|
-
import { join } from "node:path";
|
|
21
|
-
import { Type } from "@sinclair/typebox";
|
|
22
|
-
import { isValidIsoTimestampWithOffset } from "./harness/event-format.js";
|
|
23
|
-
import * as log from "./log.js";
|
|
24
|
-
import { officeStateDir } from "./office/index.js";
|
|
25
|
-
import { atomicWritePrivateFile, ensureDirExists, parseJsonSchemaValue, } from "./utils/file-guards.js";
|
|
26
|
-
const SCHEDULES_DIRNAME = "extension-schedules";
|
|
27
|
-
/** On-disk record: the fire payload plus the schedule's timing fields. */
|
|
28
|
-
const CallbackScheduleFileSchema = Type.Object({
|
|
29
|
-
platform: Type.String(),
|
|
30
|
-
conversationId: Type.String(),
|
|
31
|
-
slug: Type.String(),
|
|
32
|
-
name: Type.String(),
|
|
33
|
-
type: Type.Union([Type.Literal("periodic"), Type.Literal("one-shot")]),
|
|
34
|
-
schedule: Type.Optional(Type.String()),
|
|
35
|
-
timezone: Type.Optional(Type.String()),
|
|
36
|
-
at: Type.Optional(Type.String()),
|
|
37
|
-
callback: Type.String(),
|
|
38
|
-
args: Type.Optional(Type.Unknown()),
|
|
39
|
-
});
|
|
40
|
-
function specFromRecord(record) {
|
|
41
|
-
const action = {
|
|
42
|
-
callback: record.callback,
|
|
43
|
-
...(record.args !== undefined ? { args: record.args } : {}),
|
|
44
|
-
};
|
|
45
|
-
return record.type === "periodic"
|
|
46
|
-
? {
|
|
47
|
-
type: "periodic",
|
|
48
|
-
schedule: record.schedule ?? "",
|
|
49
|
-
timezone: record.timezone ?? "",
|
|
50
|
-
...action,
|
|
51
|
-
}
|
|
52
|
-
: { type: "one-shot", at: record.at ?? "", ...action };
|
|
53
|
-
}
|
|
54
|
-
export class ExtensionCallbackScheduler {
|
|
55
|
-
constructor(options) {
|
|
56
|
-
this.options = options;
|
|
57
|
-
/** Armed croner instances keyed by schedule file path. */
|
|
58
|
-
this.crons = new Map();
|
|
59
|
-
}
|
|
60
|
-
/** Arm every persisted schedule. Call once after the runtime is ready. */
|
|
61
|
-
start() {
|
|
62
|
-
const conversationsDir = join(this.options.stateDir, "conversations");
|
|
63
|
-
if (!existsSync(conversationsDir))
|
|
64
|
-
return;
|
|
65
|
-
let armed = 0;
|
|
66
|
-
for (const officeDir of readdirSync(conversationsDir)) {
|
|
67
|
-
const schedulesDir = join(conversationsDir, officeDir, SCHEDULES_DIRNAME);
|
|
68
|
-
if (!existsSync(schedulesDir))
|
|
69
|
-
continue;
|
|
70
|
-
for (const filename of readdirSync(schedulesDir)) {
|
|
71
|
-
if (!filename.endsWith(".json"))
|
|
72
|
-
continue;
|
|
73
|
-
if (this.armFromDisk(join(schedulesDir, filename)))
|
|
74
|
-
armed++;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
if (armed > 0)
|
|
78
|
-
log.logInfo(`Extension callback schedules armed: ${armed}`);
|
|
79
|
-
}
|
|
80
|
-
/** Disarm everything (shutdown). Persisted files re-arm on next start. */
|
|
81
|
-
stop() {
|
|
82
|
-
for (const cron of this.crons.values())
|
|
83
|
-
cron.stop();
|
|
84
|
-
this.crons.clear();
|
|
85
|
-
}
|
|
86
|
-
async upsert(address, slug, name, spec) {
|
|
87
|
-
if (spec.type === "one-shot") {
|
|
88
|
-
if (!isValidIsoTimestampWithOffset(spec.at)) {
|
|
89
|
-
throw new Error("`at` must be a valid ISO 8601 timestamp with UTC offset");
|
|
90
|
-
}
|
|
91
|
-
if (new Date(spec.at).getTime() <= Date.now()) {
|
|
92
|
-
throw new Error("`at` must be in the future");
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
const record = {
|
|
96
|
-
platform: address.platform,
|
|
97
|
-
conversationId: address.conversationId,
|
|
98
|
-
slug,
|
|
99
|
-
name,
|
|
100
|
-
type: spec.type,
|
|
101
|
-
...(spec.type === "periodic" ? { schedule: spec.schedule, timezone: spec.timezone } : {}),
|
|
102
|
-
...(spec.type === "one-shot" ? { at: spec.at } : {}),
|
|
103
|
-
callback: spec.callback,
|
|
104
|
-
// Round-tripped through JSON so what fires later is exactly what
|
|
105
|
-
// persisting kept (functions and other non-JSON values never survive).
|
|
106
|
-
...(spec.args !== undefined
|
|
107
|
-
? { args: JSON.parse(JSON.stringify(spec.args)) }
|
|
108
|
-
: {}),
|
|
109
|
-
};
|
|
110
|
-
const filePath = this.filePath(address, slug, name);
|
|
111
|
-
// Validate by arming first: an invalid cron pattern or timezone throws
|
|
112
|
-
// here, before anything is persisted or replaced.
|
|
113
|
-
this.arm(filePath, record);
|
|
114
|
-
ensureDirExists(join(officeStateDir(this.options.stateDir, address), SCHEDULES_DIRNAME));
|
|
115
|
-
atomicWritePrivateFile(filePath, JSON.stringify(record, null, 2));
|
|
116
|
-
}
|
|
117
|
-
async delete(address, slug, name) {
|
|
118
|
-
const filePath = this.filePath(address, slug, name);
|
|
119
|
-
this.disarm(filePath);
|
|
120
|
-
if (!existsSync(filePath))
|
|
121
|
-
return false;
|
|
122
|
-
rmSync(filePath, { force: true });
|
|
123
|
-
return true;
|
|
124
|
-
}
|
|
125
|
-
async list(address, slug) {
|
|
126
|
-
const schedulesDir = join(officeStateDir(this.options.stateDir, address), SCHEDULES_DIRNAME);
|
|
127
|
-
if (!existsSync(schedulesDir))
|
|
128
|
-
return [];
|
|
129
|
-
const prefix = `${slug}.`;
|
|
130
|
-
const infos = [];
|
|
131
|
-
for (const filename of readdirSync(schedulesDir).toSorted()) {
|
|
132
|
-
if (!filename.startsWith(prefix) || !filename.endsWith(".json"))
|
|
133
|
-
continue;
|
|
134
|
-
const record = await this.readRecord(join(schedulesDir, filename));
|
|
135
|
-
if (record && record.slug === slug) {
|
|
136
|
-
infos.push({ name: record.name, spec: specFromRecord(record) });
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
return infos;
|
|
140
|
-
}
|
|
141
|
-
filePath(address, slug, name) {
|
|
142
|
-
return join(officeStateDir(this.options.stateDir, address), SCHEDULES_DIRNAME, `${slug}.${name}.json`);
|
|
143
|
-
}
|
|
144
|
-
async readRecord(filePath) {
|
|
145
|
-
try {
|
|
146
|
-
const content = await readFile(filePath, "utf-8");
|
|
147
|
-
return parseJsonSchemaValue(content, CallbackScheduleFileSchema, (detail) => `Malformed extension schedule ${filePath}: ${detail}`);
|
|
148
|
-
}
|
|
149
|
-
catch (err) {
|
|
150
|
-
log.logWarning(`Skipping unreadable extension schedule: ${filePath}`, err instanceof Error ? err.message : String(err));
|
|
151
|
-
return undefined;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
armFromDisk(filePath) {
|
|
155
|
-
try {
|
|
156
|
-
const record = parseJsonSchemaValue(readFileSync(filePath, "utf-8"), CallbackScheduleFileSchema, (detail) => `Malformed extension schedule ${filePath}: ${detail}`);
|
|
157
|
-
this.arm(filePath, record);
|
|
158
|
-
return this.crons.has(filePath);
|
|
159
|
-
}
|
|
160
|
-
catch (err) {
|
|
161
|
-
// Never delete on parse failure: a code bug must not destroy schedules.
|
|
162
|
-
log.logWarning(`Skipping invalid extension schedule: ${filePath}`, err instanceof Error ? err.message : String(err));
|
|
163
|
-
return false;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Replace the armed cron for one schedule file. Throws on an invalid cron
|
|
168
|
-
* pattern or timezone BEFORE touching the existing arm, so a failed upsert
|
|
169
|
-
* leaves the previous schedule running.
|
|
170
|
-
*/
|
|
171
|
-
arm(filePath, record) {
|
|
172
|
-
const fire = () => void this.fire(filePath, record);
|
|
173
|
-
let cron;
|
|
174
|
-
if (record.type === "periodic") {
|
|
175
|
-
if (!record.schedule || !record.timezone) {
|
|
176
|
-
throw new Error("`schedule` and `timezone` are required for periodic schedules");
|
|
177
|
-
}
|
|
178
|
-
cron = new Cron(record.schedule, { timezone: record.timezone }, fire);
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
if (!record.at)
|
|
182
|
-
throw new Error("`at` is required for one-shot schedules");
|
|
183
|
-
const at = new Date(record.at);
|
|
184
|
-
if (at.getTime() <= Date.now()) {
|
|
185
|
-
// Fired while we were down (or was written in the past): drop it,
|
|
186
|
-
// mirroring the event watcher's stale one-shot handling. Only the
|
|
187
|
-
// boot scan reaches here — upsert rejects past timestamps.
|
|
188
|
-
log.logInfo(`Extension schedule in the past, deleting: ${filePath}`);
|
|
189
|
-
rmSync(filePath, { force: true });
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
cron = new Cron(at, fire);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
this.disarm(filePath);
|
|
196
|
-
if (cron)
|
|
197
|
-
this.crons.set(filePath, cron);
|
|
198
|
-
}
|
|
199
|
-
disarm(filePath) {
|
|
200
|
-
const cron = this.crons.get(filePath);
|
|
201
|
-
if (cron) {
|
|
202
|
-
cron.stop();
|
|
203
|
-
this.crons.delete(filePath);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
async fire(filePath, record) {
|
|
207
|
-
if (record.type === "one-shot") {
|
|
208
|
-
this.disarm(filePath);
|
|
209
|
-
rmSync(filePath, { force: true });
|
|
210
|
-
}
|
|
211
|
-
try {
|
|
212
|
-
const consumed = await this.options.dispatch({
|
|
213
|
-
platform: record.platform,
|
|
214
|
-
conversationId: record.conversationId,
|
|
215
|
-
slug: record.slug,
|
|
216
|
-
scheduleName: record.name,
|
|
217
|
-
callback: record.callback,
|
|
218
|
-
...(record.args !== undefined ? { args: record.args } : {}),
|
|
219
|
-
});
|
|
220
|
-
if (!consumed) {
|
|
221
|
-
log.logWarning(`Extension schedule callback has no registered handler: ${record.slug}.${record.name} → ${record.callback}`, filePath);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
catch (err) {
|
|
225
|
-
log.logWarning(`Extension schedule dispatch failed: ${record.slug}.${record.name}`, err instanceof Error ? err.message : String(err));
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
//# sourceMappingURL=extension-schedules.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extension-schedules.js","sourceRoot":"","sources":["../src/extension-schedules.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Host-authoritative store + scheduler for extension callback schedules.\n *\n * `api.schedules` callback specs fire trusted host-side handlers, so unlike\n * the agent-writable workspace event bus (`events/`, watched by\n * EventsWatcher), these schedules persist under the host-only state dir:\n * `<stateDir>/conversations/<officeKey>/extension-schedules/<slug>.<name>.json`.\n * A sandboxed agent can neither create nor edit them — the file is written\n * exclusively by extension code running in the mikan process.\n *\n * One process-wide scheduler arms every schedule with croner (periodic cron\n * or a one-shot ISO date), survives restarts via a boot scan, and dispatches\n * fires to the conversation runtime, which materializes the conversation's\n * harness and runs the registered `onCallback` handler — no agent run, no\n * model call.\n */\nimport { Cron } from \"croner\";\nimport { existsSync, readdirSync, readFileSync, rmSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { Type, type Static } from \"@sinclair/typebox\";\nimport { isValidIsoTimestampWithOffset } from \"./harness/event-format.js\";\nimport type {\n ExtensionCallbackScheduleSpec,\n ExtensionScheduleCallbackFire,\n ExtensionScheduleEngine,\n ExtensionScheduleInfo,\n} from \"./harness/index.js\";\nimport * as log from \"./log.js\";\nimport { officeStateDir } from \"./office/index.js\";\nimport type { OfficeAddress } from \"./types.js\";\nimport {\n atomicWritePrivateFile,\n ensureDirExists,\n parseJsonSchemaValue,\n} from \"./utils/file-guards.js\";\n\nconst SCHEDULES_DIRNAME = \"extension-schedules\";\n\n/** On-disk record: the fire payload plus the schedule's timing fields. */\nconst CallbackScheduleFileSchema = Type.Object({\n platform: Type.String(),\n conversationId: Type.String(),\n slug: Type.String(),\n name: Type.String(),\n type: Type.Union([Type.Literal(\"periodic\"), Type.Literal(\"one-shot\")]),\n schedule: Type.Optional(Type.String()),\n timezone: Type.Optional(Type.String()),\n at: Type.Optional(Type.String()),\n callback: Type.String(),\n args: Type.Optional(Type.Unknown()),\n});\n\ntype CallbackScheduleRecord = Static<typeof CallbackScheduleFileSchema>;\n\nfunction specFromRecord(record: CallbackScheduleRecord): ExtensionCallbackScheduleSpec {\n const action = {\n callback: record.callback,\n ...(record.args !== undefined ? { args: record.args } : {}),\n };\n return record.type === \"periodic\"\n ? {\n type: \"periodic\",\n schedule: record.schedule ?? \"\",\n timezone: record.timezone ?? \"\",\n ...action,\n }\n : { type: \"one-shot\", at: record.at ?? \"\", ...action };\n}\n\nexport class ExtensionCallbackScheduler implements ExtensionScheduleEngine {\n /** Armed croner instances keyed by schedule file path. */\n private crons = new Map<string, Cron>();\n\n constructor(\n private options: {\n stateDir: string;\n /** Resolves false when no handler is registered for the fire. */\n dispatch: (fire: ExtensionScheduleCallbackFire) => Promise<boolean>;\n },\n ) {}\n\n /** Arm every persisted schedule. Call once after the runtime is ready. */\n start(): void {\n const conversationsDir = join(this.options.stateDir, \"conversations\");\n if (!existsSync(conversationsDir)) return;\n let armed = 0;\n for (const officeDir of readdirSync(conversationsDir)) {\n const schedulesDir = join(conversationsDir, officeDir, SCHEDULES_DIRNAME);\n if (!existsSync(schedulesDir)) continue;\n for (const filename of readdirSync(schedulesDir)) {\n if (!filename.endsWith(\".json\")) continue;\n if (this.armFromDisk(join(schedulesDir, filename))) armed++;\n }\n }\n if (armed > 0) log.logInfo(`Extension callback schedules armed: ${armed}`);\n }\n\n /** Disarm everything (shutdown). Persisted files re-arm on next start. */\n stop(): void {\n for (const cron of this.crons.values()) cron.stop();\n this.crons.clear();\n }\n\n async upsert(\n address: OfficeAddress,\n slug: string,\n name: string,\n spec: ExtensionCallbackScheduleSpec,\n ): Promise<void> {\n if (spec.type === \"one-shot\") {\n if (!isValidIsoTimestampWithOffset(spec.at)) {\n throw new Error(\"`at` must be a valid ISO 8601 timestamp with UTC offset\");\n }\n if (new Date(spec.at).getTime() <= Date.now()) {\n throw new Error(\"`at` must be in the future\");\n }\n }\n const record: CallbackScheduleRecord = {\n platform: address.platform,\n conversationId: address.conversationId,\n slug,\n name,\n type: spec.type,\n ...(spec.type === \"periodic\" ? { schedule: spec.schedule, timezone: spec.timezone } : {}),\n ...(spec.type === \"one-shot\" ? { at: spec.at } : {}),\n callback: spec.callback,\n // Round-tripped through JSON so what fires later is exactly what\n // persisting kept (functions and other non-JSON values never survive).\n ...(spec.args !== undefined\n ? { args: JSON.parse(JSON.stringify(spec.args)) as unknown }\n : {}),\n };\n const filePath = this.filePath(address, slug, name);\n // Validate by arming first: an invalid cron pattern or timezone throws\n // here, before anything is persisted or replaced.\n this.arm(filePath, record);\n ensureDirExists(join(officeStateDir(this.options.stateDir, address), SCHEDULES_DIRNAME));\n atomicWritePrivateFile(filePath, JSON.stringify(record, null, 2));\n }\n\n async delete(address: OfficeAddress, slug: string, name: string): Promise<boolean> {\n const filePath = this.filePath(address, slug, name);\n this.disarm(filePath);\n if (!existsSync(filePath)) return false;\n rmSync(filePath, { force: true });\n return true;\n }\n\n async list(address: OfficeAddress, slug: string): Promise<ExtensionScheduleInfo[]> {\n const schedulesDir = join(officeStateDir(this.options.stateDir, address), SCHEDULES_DIRNAME);\n if (!existsSync(schedulesDir)) return [];\n const prefix = `${slug}.`;\n const infos: ExtensionScheduleInfo[] = [];\n for (const filename of readdirSync(schedulesDir).toSorted()) {\n if (!filename.startsWith(prefix) || !filename.endsWith(\".json\")) continue;\n const record = await this.readRecord(join(schedulesDir, filename));\n if (record && record.slug === slug) {\n infos.push({ name: record.name, spec: specFromRecord(record) });\n }\n }\n return infos;\n }\n\n private filePath(address: OfficeAddress, slug: string, name: string): string {\n return join(\n officeStateDir(this.options.stateDir, address),\n SCHEDULES_DIRNAME,\n `${slug}.${name}.json`,\n );\n }\n\n private async readRecord(filePath: string): Promise<CallbackScheduleRecord | undefined> {\n try {\n const content = await readFile(filePath, \"utf-8\");\n return parseJsonSchemaValue(\n content,\n CallbackScheduleFileSchema,\n (detail) => `Malformed extension schedule ${filePath}: ${detail}`,\n );\n } catch (err) {\n log.logWarning(\n `Skipping unreadable extension schedule: ${filePath}`,\n err instanceof Error ? err.message : String(err),\n );\n return undefined;\n }\n }\n\n private armFromDisk(filePath: string): boolean {\n try {\n const record = parseJsonSchemaValue(\n readFileSync(filePath, \"utf-8\"),\n CallbackScheduleFileSchema,\n (detail) => `Malformed extension schedule ${filePath}: ${detail}`,\n );\n this.arm(filePath, record);\n return this.crons.has(filePath);\n } catch (err) {\n // Never delete on parse failure: a code bug must not destroy schedules.\n log.logWarning(\n `Skipping invalid extension schedule: ${filePath}`,\n err instanceof Error ? err.message : String(err),\n );\n return false;\n }\n }\n\n /**\n * Replace the armed cron for one schedule file. Throws on an invalid cron\n * pattern or timezone BEFORE touching the existing arm, so a failed upsert\n * leaves the previous schedule running.\n */\n private arm(filePath: string, record: CallbackScheduleRecord): void {\n const fire = () => void this.fire(filePath, record);\n let cron: Cron | undefined;\n if (record.type === \"periodic\") {\n if (!record.schedule || !record.timezone) {\n throw new Error(\"`schedule` and `timezone` are required for periodic schedules\");\n }\n cron = new Cron(record.schedule, { timezone: record.timezone }, fire);\n } else {\n if (!record.at) throw new Error(\"`at` is required for one-shot schedules\");\n const at = new Date(record.at);\n if (at.getTime() <= Date.now()) {\n // Fired while we were down (or was written in the past): drop it,\n // mirroring the event watcher's stale one-shot handling. Only the\n // boot scan reaches here — upsert rejects past timestamps.\n log.logInfo(`Extension schedule in the past, deleting: ${filePath}`);\n rmSync(filePath, { force: true });\n } else {\n cron = new Cron(at, fire);\n }\n }\n this.disarm(filePath);\n if (cron) this.crons.set(filePath, cron);\n }\n\n private disarm(filePath: string): void {\n const cron = this.crons.get(filePath);\n if (cron) {\n cron.stop();\n this.crons.delete(filePath);\n }\n }\n\n private async fire(filePath: string, record: CallbackScheduleRecord): Promise<void> {\n if (record.type === \"one-shot\") {\n this.disarm(filePath);\n rmSync(filePath, { force: true });\n }\n try {\n const consumed = await this.options.dispatch({\n platform: record.platform,\n conversationId: record.conversationId,\n slug: record.slug,\n scheduleName: record.name,\n callback: record.callback,\n ...(record.args !== undefined ? { args: record.args } : {}),\n });\n if (!consumed) {\n log.logWarning(\n `Extension schedule callback has no registered handler: ${record.slug}.${record.name} → ${record.callback}`,\n filePath,\n );\n }\n } catch (err) {\n log.logWarning(\n `Extension schedule dispatch failed: ${record.slug}.${record.name}`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n}\n"]}
|
package/dist/harness/auth.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { Credential, CredentialInfo, CredentialStore } from "@earendil-works/pi-ai";
|
|
2
|
-
/** Default location of mikan's credential file. */
|
|
3
|
-
export declare function defaultAuthPath(): string;
|
|
4
|
-
export declare class FileCredentialStore implements CredentialStore {
|
|
5
|
-
private readonly authPath;
|
|
6
|
-
private chain;
|
|
7
|
-
constructor(authPath?: string);
|
|
8
|
-
private load;
|
|
9
|
-
private save;
|
|
10
|
-
/** Serialize read-modify-write cycles so concurrent refreshes cannot clobber each other. */
|
|
11
|
-
private enqueue;
|
|
12
|
-
read(providerId: string): Promise<Credential | undefined>;
|
|
13
|
-
list(): Promise<readonly CredentialInfo[]>;
|
|
14
|
-
modify(providerId: string, fn: (current: Credential | undefined) => Promise<Credential | undefined>): Promise<Credential | undefined>;
|
|
15
|
-
delete(providerId: string): Promise<void>;
|
|
16
|
-
}
|
|
17
|
-
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/harness/auth.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAIzF,mDAAmD;AACnD,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAQD,qBAAa,mBAAoB,YAAW,eAAe;IACzD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,KAAK,CAAqB;IAElC,YAAY,QAAQ,GAAE,MAA0B,EAE/C;IAED,OAAO,CAAC,IAAI;IAmBZ,OAAO,CAAC,IAAI;IAKZ,4FAA4F;IAC5F,OAAO,CAAC,OAAO;IASf,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAExD;IAED,IAAI,IAAI,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAOzC;IAED,MAAM,CACJ,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,KAAK,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,GACvE,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CASjC;IAED,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOxC;CACF"}
|
package/dist/harness/auth.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* File-backed credential store for the mikan harness.
|
|
3
|
-
*
|
|
4
|
-
* Implements pi-ai's `CredentialStore` over mikan's `auth.json`
|
|
5
|
-
* (`~/.mikan/auth.json` by default). The file maps provider ids to
|
|
6
|
-
* type-tagged credentials — the same shape pi-ai documents for auth.json.
|
|
7
|
-
*
|
|
8
|
-
* Writes are atomic (temp file + rename, mode 0600) and serialized per
|
|
9
|
-
* provider within the process. mikan runs as a single process, so no
|
|
10
|
-
* cross-process file lock is taken.
|
|
11
|
-
*/
|
|
12
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
13
|
-
import { mkdirSync } from "node:fs";
|
|
14
|
-
import { homedir } from "node:os";
|
|
15
|
-
import { dirname, join } from "node:path";
|
|
16
|
-
import { atomicWritePrivateFile } from "../utils/file-guards.js";
|
|
17
|
-
import * as log from "../log.js";
|
|
18
|
-
/** Default location of mikan's credential file. */
|
|
19
|
-
export function defaultAuthPath() {
|
|
20
|
-
return join(homedir(), ".mikan", "auth.json");
|
|
21
|
-
}
|
|
22
|
-
function isCredential(value) {
|
|
23
|
-
if (!value || typeof value !== "object")
|
|
24
|
-
return false;
|
|
25
|
-
const type = value.type;
|
|
26
|
-
return type === "api_key" || type === "oauth";
|
|
27
|
-
}
|
|
28
|
-
export class FileCredentialStore {
|
|
29
|
-
constructor(authPath = defaultAuthPath()) {
|
|
30
|
-
this.chain = Promise.resolve();
|
|
31
|
-
this.authPath = authPath;
|
|
32
|
-
}
|
|
33
|
-
load() {
|
|
34
|
-
if (!existsSync(this.authPath))
|
|
35
|
-
return {};
|
|
36
|
-
try {
|
|
37
|
-
const parsed = JSON.parse(readFileSync(this.authPath, "utf-8"));
|
|
38
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
39
|
-
return {};
|
|
40
|
-
const data = {};
|
|
41
|
-
for (const [provider, credential] of Object.entries(parsed)) {
|
|
42
|
-
if (isCredential(credential))
|
|
43
|
-
data[provider] = credential;
|
|
44
|
-
}
|
|
45
|
-
return data;
|
|
46
|
-
}
|
|
47
|
-
catch (err) {
|
|
48
|
-
log.logWarning(`Failed to read credentials from ${this.authPath}`, err instanceof Error ? err.message : String(err));
|
|
49
|
-
return {};
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
save(data) {
|
|
53
|
-
mkdirSync(dirname(this.authPath), { recursive: true });
|
|
54
|
-
atomicWritePrivateFile(this.authPath, `${JSON.stringify(data, null, 2)}\n`);
|
|
55
|
-
}
|
|
56
|
-
/** Serialize read-modify-write cycles so concurrent refreshes cannot clobber each other. */
|
|
57
|
-
enqueue(task) {
|
|
58
|
-
const result = this.chain.then(task);
|
|
59
|
-
this.chain = result.then(() => undefined, () => undefined);
|
|
60
|
-
return result;
|
|
61
|
-
}
|
|
62
|
-
read(providerId) {
|
|
63
|
-
return this.enqueue(async () => this.load()[providerId]);
|
|
64
|
-
}
|
|
65
|
-
list() {
|
|
66
|
-
return this.enqueue(async () => Object.entries(this.load()).map(([providerId, credential]) => ({
|
|
67
|
-
providerId,
|
|
68
|
-
type: credential.type,
|
|
69
|
-
})));
|
|
70
|
-
}
|
|
71
|
-
modify(providerId, fn) {
|
|
72
|
-
return this.enqueue(async () => {
|
|
73
|
-
const data = this.load();
|
|
74
|
-
const next = await fn(data[providerId]);
|
|
75
|
-
if (next === undefined)
|
|
76
|
-
return data[providerId];
|
|
77
|
-
data[providerId] = next;
|
|
78
|
-
this.save(data);
|
|
79
|
-
return next;
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
delete(providerId) {
|
|
83
|
-
return this.enqueue(async () => {
|
|
84
|
-
const data = this.load();
|
|
85
|
-
if (!(providerId in data))
|
|
86
|
-
return;
|
|
87
|
-
delete data[providerId];
|
|
88
|
-
this.save(data);
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
//# sourceMappingURL=auth.js.map
|
package/dist/harness/auth.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/harness/auth.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * File-backed credential store for the mikan harness.\n *\n * Implements pi-ai's `CredentialStore` over mikan's `auth.json`\n * (`~/.mikan/auth.json` by default). The file maps provider ids to\n * type-tagged credentials — the same shape pi-ai documents for auth.json.\n *\n * Writes are atomic (temp file + rename, mode 0600) and serialized per\n * provider within the process. mikan runs as a single process, so no\n * cross-process file lock is taken.\n */\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { mkdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport type { Credential, CredentialInfo, CredentialStore } from \"@earendil-works/pi-ai\";\nimport { atomicWritePrivateFile } from \"../utils/file-guards.js\";\nimport * as log from \"../log.js\";\n\n/** Default location of mikan's credential file. */\nexport function defaultAuthPath(): string {\n return join(homedir(), \".mikan\", \"auth.json\");\n}\n\nfunction isCredential(value: unknown): value is Credential {\n if (!value || typeof value !== \"object\") return false;\n const type = (value as { type?: unknown }).type;\n return type === \"api_key\" || type === \"oauth\";\n}\n\nexport class FileCredentialStore implements CredentialStore {\n private readonly authPath: string;\n private chain = Promise.resolve();\n\n constructor(authPath: string = defaultAuthPath()) {\n this.authPath = authPath;\n }\n\n private load(): Record<string, Credential> {\n if (!existsSync(this.authPath)) return {};\n try {\n const parsed: unknown = JSON.parse(readFileSync(this.authPath, \"utf-8\"));\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) return {};\n const data: Record<string, Credential> = {};\n for (const [provider, credential] of Object.entries(parsed)) {\n if (isCredential(credential)) data[provider] = credential;\n }\n return data;\n } catch (err) {\n log.logWarning(\n `Failed to read credentials from ${this.authPath}`,\n err instanceof Error ? err.message : String(err),\n );\n return {};\n }\n }\n\n private save(data: Record<string, Credential>): void {\n mkdirSync(dirname(this.authPath), { recursive: true });\n atomicWritePrivateFile(this.authPath, `${JSON.stringify(data, null, 2)}\\n`);\n }\n\n /** Serialize read-modify-write cycles so concurrent refreshes cannot clobber each other. */\n private enqueue<T>(task: () => Promise<T>): Promise<T> {\n const result = this.chain.then(task);\n this.chain = result.then(\n () => undefined,\n () => undefined,\n );\n return result;\n }\n\n read(providerId: string): Promise<Credential | undefined> {\n return this.enqueue(async () => this.load()[providerId]);\n }\n\n list(): Promise<readonly CredentialInfo[]> {\n return this.enqueue(async () =>\n Object.entries(this.load()).map(([providerId, credential]) => ({\n providerId,\n type: credential.type,\n })),\n );\n }\n\n modify(\n providerId: string,\n fn: (current: Credential | undefined) => Promise<Credential | undefined>,\n ): Promise<Credential | undefined> {\n return this.enqueue(async () => {\n const data = this.load();\n const next = await fn(data[providerId]);\n if (next === undefined) return data[providerId];\n data[providerId] = next;\n this.save(data);\n return next;\n });\n }\n\n delete(providerId: string): Promise<void> {\n return this.enqueue(async () => {\n const data = this.load();\n if (!(providerId in data)) return;\n delete data[providerId];\n this.save(data);\n });\n }\n}\n"]}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { OfficeAddress } from "../../types.js";
|
|
2
|
-
import type { ExtensionValidation, InstalledExtensionInfo, LoadExtensionsOptions, LoadExtensionsResult } from "./types.js";
|
|
3
|
-
export type { ExtensionValidation, InstalledExtensionInfo, LoadExtensionsOptions, LoadExtensionsResult, } from "./types.js";
|
|
4
|
-
/**
|
|
5
|
-
* Canonical host-only extension code directories for a conversation, in load
|
|
6
|
-
* order: `<stateDir>/global/extensions` (all conversations) then
|
|
7
|
-
* `<stateDir>/conversations/<office key>/extensions` (that conversation
|
|
8
|
-
* only). `global` and `conversations` are the two sibling scopes; see
|
|
9
|
-
* `LAYOUT.md`.
|
|
10
|
-
*/
|
|
11
|
-
export declare function defaultExtensionDirs(address: OfficeAddress, stateDir?: string): string[];
|
|
12
|
-
/**
|
|
13
|
-
* List installed extensions without importing or activating them — safe for
|
|
14
|
-
* inventory surfaces (commands, portal). Activation side effects (schedule
|
|
15
|
-
* upserts, tool registration) only happen in {@link loadExtensions}.
|
|
16
|
-
*/
|
|
17
|
-
export declare function listInstalledExtensions(dirs: string[]): InstalledExtensionInfo[];
|
|
18
|
-
/**
|
|
19
|
-
* Filesystem-safe identifier for an extension, derived from its root (the
|
|
20
|
-
* install directory, or the file path for a bare-file extension). The slug
|
|
21
|
-
* keys the extension's data dir, secrets vault, and schedule ownership —
|
|
22
|
-
* installing the same extension globally and per-conversation shares one
|
|
23
|
-
* slug and therefore one shared data dir. This is the only slug derivation:
|
|
24
|
-
* a second one keyed off a different input (e.g. the entrypoint, which for
|
|
25
|
-
* package.json-form extensions can live under dist/) would silently split an
|
|
26
|
-
* extension's identity.
|
|
27
|
-
*/
|
|
28
|
-
export declare function extensionSlug(rootDir: string): string;
|
|
29
|
-
/** Load and activate all extensions found in the given directories. */
|
|
30
|
-
export declare function loadExtensions(options: LoadExtensionsOptions): Promise<LoadExtensionsResult>;
|
|
31
|
-
/**
|
|
32
|
-
* Validate an extension source path (a directory or a single file) WITHOUT
|
|
33
|
-
* activating it: resolves the entrypoint (package.json `mikan.extensions`,
|
|
34
|
-
* index file, or the file itself), imports it, and checks it exports an
|
|
35
|
-
* `activate` function. Used by `mikan ext install` as a preflight and by
|
|
36
|
-
* `mikan ext validate`. Importing runs top-level module code but not
|
|
37
|
-
* `activate`, so there are no schedule/tool side effects.
|
|
38
|
-
*/
|
|
39
|
-
export declare function validateExtension(sourcePath: string): Promise<ExtensionValidation>;
|
|
40
|
-
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/harness/extensions/loader.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAWV,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EAKrB,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAiBpB;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,aAAa,EACtB,QAAQ,GAAE,MAAkC,GAC3C,MAAM,EAAE,CAKV;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,sBAAsB,EAAE,CAmBhF;AAkJD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIrD;AA4WD,uEAAuE;AACvE,wBAAsB,cAAc,CAClC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CA6E/B;AA2DD;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAuDxF"}
|