@geminixiang/mikan 1.0.0-beta.39 → 1.0.0-beta.40
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 +21 -0
- package/README.md +50 -23
- 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 +2 -1
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +3 -3
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/discord/context.d.ts +2 -1
- 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/github/bot.d.ts +2 -1
- package/dist/adapters/github/bot.d.ts.map +1 -1
- package/dist/adapters/github/bot.js +11 -7
- package/dist/adapters/github/bot.js.map +1 -1
- package/dist/adapters/github/client.js +2 -2
- package/dist/adapters/github/client.js.map +1 -1
- package/dist/adapters/github/context.d.ts +4 -2
- package/dist/adapters/github/context.d.ts.map +1 -1
- package/dist/adapters/github/context.js +2 -2
- package/dist/adapters/github/context.js.map +1 -1
- package/dist/adapters/github/gcp-auth.js +2 -2
- package/dist/adapters/github/gcp-auth.js.map +1 -1
- package/dist/adapters/github/github-ops.d.ts +3 -2
- package/dist/adapters/github/github-ops.d.ts.map +1 -1
- package/dist/adapters/github/github-ops.js +1 -1
- package/dist/adapters/github/github-ops.js.map +1 -1
- package/dist/adapters/github/ids.d.ts.map +1 -1
- package/dist/adapters/github/ids.js +7 -3
- package/dist/adapters/github/ids.js.map +1 -1
- package/dist/adapters/github/repo.js +3 -3
- package/dist/adapters/github/repo.js.map +1 -1
- package/dist/adapters/github/types.d.ts +2 -1
- package/dist/adapters/github/types.d.ts.map +1 -1
- package/dist/adapters/github/types.js.map +1 -1
- package/dist/adapters/progressive-renderer.js +1 -1
- package/dist/adapters/progressive-renderer.js.map +1 -1
- package/dist/adapters/shared.js +4 -4
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/slack/blocks.d.ts.map +1 -1
- package/dist/adapters/slack/blocks.js +3 -1
- package/dist/adapters/slack/blocks.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +12 -2
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +70 -9
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/context.d.ts +2 -1
- package/dist/adapters/slack/context.d.ts.map +1 -1
- package/dist/adapters/slack/context.js +1 -0
- 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 +4 -4
- 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 +2 -3
- package/dist/adapters/slack/session.js.map +1 -1
- package/dist/adapters/slack/tools/attach.js +1 -1
- package/dist/adapters/slack/tools/attach.js.map +1 -1
- package/dist/adapters/telegram/bot.d.ts +2 -1
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +6 -6
- package/dist/adapters/telegram/bot.js.map +1 -1
- package/dist/adapters/telegram/context.d.ts +2 -1
- package/dist/adapters/telegram/context.d.ts.map +1 -1
- package/dist/adapters/telegram/context.js.map +1 -1
- package/dist/adapters/telegram/html.d.ts.map +1 -1
- package/dist/adapters/telegram/html.js +10 -7
- package/dist/adapters/telegram/html.js.map +1 -1
- package/dist/adapters/types.d.ts +4 -2
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/agent-events.d.ts +3 -2
- package/dist/agent-events.d.ts.map +1 -1
- package/dist/agent-events.js +19 -1
- package/dist/agent-events.js.map +1 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +34 -9
- package/dist/agent.js.map +1 -1
- package/dist/cli/arg-grammar.d.ts.map +1 -1
- package/dist/cli/arg-grammar.js +5 -3
- package/dist/cli/arg-grammar.js.map +1 -1
- package/dist/cli/boot.d.ts.map +1 -1
- package/dist/cli/boot.js +5 -3
- package/dist/cli/boot.js.map +1 -1
- package/dist/cli/download.d.ts.map +1 -1
- package/dist/cli/download.js +2 -0
- package/dist/cli/download.js.map +1 -1
- package/dist/cli/ext-dev.d.ts.map +1 -1
- package/dist/cli/ext-dev.js +4 -1
- package/dist/cli/ext-dev.js.map +1 -1
- package/dist/cli/ext.d.ts.map +1 -1
- package/dist/cli/ext.js +123 -23
- package/dist/cli/ext.js.map +1 -1
- package/dist/cli/office.d.ts.map +1 -1
- package/dist/cli/office.js +2 -0
- package/dist/cli/office.js.map +1 -1
- package/dist/cli/types.d.ts +0 -6
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/cli/types.js.map +1 -1
- package/dist/commands/admin.js +1 -1
- package/dist/commands/admin.js.map +1 -1
- package/dist/commands/auto-reply.js +2 -2
- package/dist/commands/auto-reply.js.map +1 -1
- package/dist/commands/extensions.js +1 -1
- package/dist/commands/extensions.js.map +1 -1
- package/dist/commands/login.js +1 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/manifest.d.ts +7 -0
- package/dist/commands/manifest.d.ts.map +1 -1
- package/dist/commands/manifest.js +28 -0
- package/dist/commands/manifest.js.map +1 -1
- package/dist/commands/model.d.ts.map +1 -1
- package/dist/commands/model.js +4 -1
- package/dist/commands/model.js.map +1 -1
- package/dist/commands/new.js +1 -1
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/sandbox.js +3 -3
- package/dist/commands/sandbox.js.map +1 -1
- package/dist/commands/session-view.d.ts.map +1 -1
- package/dist/commands/session-view.js +5 -2
- package/dist/commands/session-view.js.map +1 -1
- package/dist/commands/types.d.ts +1 -1
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/config.js +4 -4
- package/dist/config.js.map +1 -1
- package/dist/env-manifest.d.ts +2 -0
- package/dist/env-manifest.d.ts.map +1 -1
- package/dist/env-manifest.js +11 -1
- package/dist/env-manifest.js.map +1 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +7 -6
- package/dist/events.js.map +1 -1
- package/dist/execution-resolver.d.ts.map +1 -1
- package/dist/execution-resolver.js +3 -2
- package/dist/execution-resolver.js.map +1 -1
- package/dist/extension-schedules.d.ts +31 -0
- package/dist/extension-schedules.d.ts.map +1 -0
- package/dist/extension-schedules.js +229 -0
- package/dist/extension-schedules.js.map +1 -0
- package/dist/harness/auth.js +5 -5
- package/dist/harness/auth.js.map +1 -1
- package/dist/harness/event-format.d.ts +2 -0
- package/dist/harness/event-format.d.ts.map +1 -1
- package/dist/harness/event-format.js +2 -1
- package/dist/harness/event-format.js.map +1 -1
- package/dist/harness/extensions/loader.d.ts +2 -2
- package/dist/harness/extensions/loader.d.ts.map +1 -1
- package/dist/harness/extensions/loader.js +135 -33
- package/dist/harness/extensions/loader.js.map +1 -1
- package/dist/harness/extensions/registry.d.ts +33 -1
- package/dist/harness/extensions/registry.d.ts.map +1 -1
- package/dist/harness/extensions/registry.js +79 -2
- package/dist/harness/extensions/registry.js.map +1 -1
- package/dist/harness/extensions/types.d.ts +165 -21
- 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 +2 -2
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +1 -1
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/models.d.ts.map +1 -1
- package/dist/harness/models.js +36 -24
- package/dist/harness/models.js.map +1 -1
- package/dist/harness/runner.js +2 -2
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session-store.d.ts.map +1 -1
- package/dist/harness/session-store.js +9 -7
- package/dist/harness/session-store.js.map +1 -1
- package/dist/harness/skills.js +3 -3
- package/dist/harness/skills.js.map +1 -1
- package/dist/harness/subagent-profiles.js +2 -2
- package/dist/harness/subagent-profiles.js.map +1 -1
- package/dist/harness/subagent-runner.js +3 -3
- package/dist/harness/subagent-runner.js.map +1 -1
- package/dist/index.d.ts +8 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/main.js +58 -9
- package/dist/main.js.map +1 -1
- package/dist/observability/instrument.js +1 -1
- package/dist/observability/instrument.js.map +1 -1
- package/dist/observability/sentry.js +1 -1
- package/dist/observability/sentry.js.map +1 -1
- package/dist/office/index.d.ts +1 -1
- package/dist/office/index.d.ts.map +1 -1
- package/dist/office/index.js +1 -1
- package/dist/office/index.js.map +1 -1
- package/dist/office/layout.d.ts +7 -0
- package/dist/office/layout.d.ts.map +1 -1
- package/dist/office/layout.js +10 -1
- package/dist/office/layout.js.map +1 -1
- package/dist/office/registry.d.ts.map +1 -1
- package/dist/office/registry.js +7 -5
- package/dist/office/registry.js.map +1 -1
- package/dist/packages/materialize.js +10 -3
- package/dist/packages/materialize.js.map +1 -1
- package/dist/packages/source.d.ts +6 -0
- package/dist/packages/source.d.ts.map +1 -1
- package/dist/packages/source.js +14 -2
- package/dist/packages/source.js.map +1 -1
- package/dist/packages/types.d.ts +5 -3
- package/dist/packages/types.d.ts.map +1 -1
- package/dist/packages/types.js.map +1 -1
- package/dist/provisioner.js +5 -5
- package/dist/provisioner.js.map +1 -1
- package/dist/runtime/conversation-runtime.d.ts.map +1 -1
- package/dist/runtime/conversation-runtime.js +44 -2
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/types.d.ts +10 -2
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/cloudflare.js +1 -1
- package/dist/sandbox/cloudflare.js.map +1 -1
- package/dist/sandbox/container.js +1 -2
- package/dist/sandbox/container.js.map +1 -1
- package/dist/sandbox/firecracker.js +1 -1
- package/dist/sandbox/firecracker.js.map +1 -1
- package/dist/sandbox/gondolin.d.ts.map +1 -1
- package/dist/sandbox/gondolin.js +1 -2
- package/dist/sandbox/gondolin.js.map +1 -1
- package/dist/sandbox/host.d.ts.map +1 -1
- package/dist/sandbox/host.js +4 -5
- package/dist/sandbox/host.js.map +1 -1
- package/dist/sandbox/index.js +1 -1
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/utils.d.ts +2 -0
- package/dist/sandbox/utils.d.ts.map +1 -1
- package/dist/sandbox/utils.js +30 -1
- package/dist/sandbox/utils.js.map +1 -1
- package/dist/sessions/chat-history-sync.d.ts.map +1 -1
- package/dist/sessions/chat-history-sync.js +9 -8
- package/dist/sessions/chat-history-sync.js.map +1 -1
- package/dist/sessions/conversation-log.d.ts.map +1 -1
- package/dist/sessions/conversation-log.js +5 -2
- package/dist/sessions/conversation-log.js.map +1 -1
- package/dist/sessions/history-line.d.ts +9 -0
- package/dist/sessions/history-line.d.ts.map +1 -1
- package/dist/sessions/history-line.js +22 -1
- package/dist/sessions/history-line.js.map +1 -1
- package/dist/sessions/session-key.d.ts +5 -12
- package/dist/sessions/session-key.d.ts.map +1 -1
- package/dist/sessions/session-key.js +23 -0
- package/dist/sessions/session-key.js.map +1 -1
- package/dist/sessions/store.d.ts +2 -6
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +16 -16
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/types.d.ts +2 -1
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js.map +1 -1
- package/dist/tools/bash.js +1 -1
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +4 -1
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/event.js +1 -1
- package/dist/tools/event.js.map +1 -1
- package/dist/tools/generate-image.js +3 -3
- package/dist/tools/generate-image.js.map +1 -1
- package/dist/tools/read.js +4 -4
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/subagent.d.ts.map +1 -1
- package/dist/tools/subagent.js +9 -2
- package/dist/tools/subagent.js.map +1 -1
- package/dist/tools/types.d.ts +0 -26
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js.map +1 -1
- package/dist/trigger.d.ts +2 -1
- package/dist/trigger.d.ts.map +1 -1
- package/dist/trigger.js.map +1 -1
- package/dist/types.d.ts +108 -16
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -2
- package/dist/types.js.map +1 -1
- package/dist/utils/file-guards.d.ts +9 -0
- package/dist/utils/file-guards.d.ts.map +1 -1
- package/dist/utils/file-guards.js +44 -1
- package/dist/utils/file-guards.js.map +1 -1
- package/dist/vault/disabled.d.ts.map +1 -1
- package/dist/vault/disabled.js +3 -0
- package/dist/vault/disabled.js.map +1 -1
- package/dist/vault/index.d.ts +29 -0
- package/dist/vault/index.d.ts.map +1 -1
- package/dist/vault/index.js +68 -4
- package/dist/vault/index.js.map +1 -1
- package/dist/vault/types.d.ts +2 -0
- package/dist/vault/types.d.ts.map +1 -1
- package/dist/vault/types.js.map +1 -1
- package/dist/web/admin/portal.d.ts +1 -1
- package/dist/web/admin/portal.d.ts.map +1 -1
- package/dist/web/admin/portal.js +194 -22
- package/dist/web/admin/portal.js.map +1 -1
- package/dist/web/admin/provider-models.js +1 -1
- package/dist/web/admin/provider-models.js.map +1 -1
- package/dist/web/login/oauth.js +1 -1
- package/dist/web/login/oauth.js.map +1 -1
- package/dist/web/login/portal.d.ts +1 -1
- package/dist/web/login/portal.d.ts.map +1 -1
- package/dist/web/login/portal.js +13 -36
- package/dist/web/login/portal.js.map +1 -1
- package/dist/web/portal-shell.d.ts +17 -0
- package/dist/web/portal-shell.d.ts.map +1 -1
- package/dist/web/portal-shell.js +66 -1
- package/dist/web/portal-shell.js.map +1 -1
- package/dist/web/server.d.ts +3 -2
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +3 -3
- package/dist/web/server.js.map +1 -1
- package/dist/web/session-view/portal.d.ts +1 -1
- package/dist/web/session-view/portal.d.ts.map +1 -1
- package/dist/web/session-view/portal.js +10 -12
- 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 +11 -6
- package/dist/web/session-view/service.js.map +1 -1
- package/dist/web/session-view/types.d.ts +0 -4
- package/dist/web/session-view/types.d.ts.map +1 -1
- package/dist/web/session-view/types.js.map +1 -1
- package/dist/web/token-store.js +1 -1
- package/dist/web/token-store.js.map +1 -1
- package/package.json +8 -17
- package/dist/cli/ext-git.d.ts +0 -17
- package/dist/cli/ext-git.d.ts.map +0 -1
- package/dist/cli/ext-git.js +0 -107
- package/dist/cli/ext-git.js.map +0 -1
- package/dist/commands/parse.d.ts +0 -7
- package/dist/commands/parse.d.ts.map +0 -1
- package/dist/commands/parse.js +0 -14
- package/dist/commands/parse.js.map +0 -1
- package/dist/commands/text.d.ts +0 -2
- package/dist/commands/text.d.ts.map +0 -1
- package/dist/commands/text.js +0 -16
- package/dist/commands/text.js.map +0 -1
- package/dist/harness/extensions/blockkit.d.ts +0 -19
- package/dist/harness/extensions/blockkit.d.ts.map +0 -1
- package/dist/harness/extensions/blockkit.js +0 -42
- package/dist/harness/extensions/blockkit.js.map +0 -1
- package/dist/sandbox/path-context.d.ts +0 -3
- package/dist/sandbox/path-context.d.ts.map +0 -1
- package/dist/sandbox/path-context.js +0 -30
- package/dist/sandbox/path-context.js.map +0 -1
- package/dist/sessions/metadata.d.ts +0 -3
- package/dist/sessions/metadata.d.ts.map +0 -1
- package/dist/sessions/metadata.js +0 -11
- package/dist/sessions/metadata.js.map +0 -1
- package/dist/sessions/policy.d.ts +0 -6
- package/dist/sessions/policy.d.ts.map +0 -1
- package/dist/sessions/policy.js +0 -25
- package/dist/sessions/policy.js.map +0 -1
- package/dist/tools/truncate.d.ts +0 -33
- package/dist/tools/truncate.d.ts.map +0 -1
- package/dist/tools/truncate.js +0 -184
- package/dist/tools/truncate.js.map +0 -1
- package/dist/utils/date.d.ts +0 -10
- package/dist/utils/date.d.ts.map +0 -1
- package/dist/utils/date.js +0 -23
- package/dist/utils/date.js.map +0 -1
- package/dist/utils/env.d.ts +0 -3
- package/dist/utils/env.d.ts.map +0 -1
- package/dist/utils/env.js +0 -12
- package/dist/utils/env.js.map +0 -1
- package/dist/utils/fs-atomic.d.ts +0 -10
- package/dist/utils/fs-atomic.d.ts.map +0 -1
- package/dist/utils/fs-atomic.js +0 -45
- package/dist/utils/fs-atomic.js.map +0 -1
- package/dist/utils/html.d.ts +0 -2
- package/dist/utils/html.d.ts.map +0 -1
- package/dist/utils/html.js +0 -4
- package/dist/utils/html.js.map +0 -1
- package/dist/utils/http-body.d.ts +0 -10
- package/dist/utils/http-body.d.ts.map +0 -1
- package/dist/utils/http-body.js +0 -34
- package/dist/utils/http-body.js.map +0 -1
- package/dist/vault/injection.d.ts +0 -12
- package/dist/vault/injection.d.ts.map +0 -1
- package/dist/vault/injection.js +0 -30
- package/dist/vault/injection.js.map +0 -1
- package/dist/vault/policy.d.ts +0 -20
- package/dist/vault/policy.d.ts.map +0 -1
- package/dist/vault/policy.js +0 -20
- package/dist/vault/policy.js.map +0 -1
- package/dist/web/agent-events/portal.d.ts +0 -3
- package/dist/web/agent-events/portal.d.ts.map +0 -1
- package/dist/web/agent-events/portal.js +0 -19
- package/dist/web/agent-events/portal.js.map +0 -1
- package/dist/web/request.d.ts +0 -3
- package/dist/web/request.d.ts.map +0 -1
- package/dist/web/request.js +0 -13
- package/dist/web/request.js.map +0 -1
- package/dist/web/session-view/command.d.ts +0 -4
- package/dist/web/session-view/command.d.ts.map +0 -1
- package/dist/web/session-view/command.js +0 -10
- package/dist/web/session-view/command.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"arg-grammar.d.ts","sourceRoot":"","sources":["../../src/cli/arg-grammar.ts"],"names":[],"mappings":"AAaA,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EAAE,EACd,CAAC,EAAE,MAAM,EACT,IAAI,EAAE,MAAM,GACX;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"arg-grammar.d.ts","sourceRoot":"","sources":["../../src/cli/arg-grammar.ts"],"names":[],"mappings":"AAaA,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EAAE,EACd,CAAC,EAAE,MAAM,EACT,IAAI,EAAE,MAAM,GACX;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAMlD;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,IAAI,GAAE,MAAM,EAA0B,EACtC,QAAQ,GAAE,MAAM,GAAG,SAAgC,GAClD,MAAM,CAYR;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}
|
package/dist/cli/arg-grammar.js
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
* state dir, and an early `--state-dir` probe for import-time consumers
|
|
8
8
|
* (Sentry instrumentation) that must not load the boot path.
|
|
9
9
|
*/
|
|
10
|
-
import { homedir } from "os";
|
|
11
|
-
import { join, resolve } from "path";
|
|
12
|
-
import { readEnv } from "../
|
|
10
|
+
import { homedir } from "node:os";
|
|
11
|
+
import { join, resolve } from "node:path";
|
|
12
|
+
import { readEnv } from "../env-manifest.js";
|
|
13
13
|
export function defaultStateDir() {
|
|
14
14
|
return join(homedir(), ".mikan");
|
|
15
15
|
}
|
|
@@ -20,6 +20,8 @@ export function defaultStateDir() {
|
|
|
20
20
|
*/
|
|
21
21
|
export function takeValueFlag(args, i, name) {
|
|
22
22
|
const arg = args[i];
|
|
23
|
+
if (arg === undefined)
|
|
24
|
+
return undefined;
|
|
23
25
|
if (arg === name)
|
|
24
26
|
return { value: args[i + 1] ?? "", lastIndex: i + 1 };
|
|
25
27
|
if (arg.startsWith(name + "="))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"arg-grammar.js","sourceRoot":"","sources":["../../src/cli/arg-grammar.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"arg-grammar.js","sourceRoot":"","sources":["../../src/cli/arg-grammar.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,MAAM,UAAU,eAAe;IAC7B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAc,EACd,CAAS,EACT,IAAY;IAEZ,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxC,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IACxE,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,GAAG,GAAG,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IAC3F,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAI,GAAa,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EACtC,QAAQ,GAAuB,OAAO,CAAC,WAAW,CAAC;IAEnD,IAAI,SAA6B,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;QACpD,IAAI,KAAK,EAAE,CAAC;YACV,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC;YACxB,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;QACtB,CAAC;IACH,CAAC;IACD,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC;IACvD,IAAI,QAAQ;QAAE,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvC,OAAO,eAAe,EAAE,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,eAAe,CAAC,EAAE,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["/**\n * Shared pieces of the CLI flag grammar.\n *\n * `resolveBoot` (cli/boot.ts) is the daemon's only full argv parser. This\n * module holds what other scanners must agree with it on: the value-flag\n * spelling (`--flag value` / `--flag=value`) via `takeValueFlag`, the default\n * state dir, and an early `--state-dir` probe for import-time consumers\n * (Sentry instrumentation) that must not load the boot path.\n */\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { readEnv } from \"../env-manifest.js\";\n\nexport function defaultStateDir(): string {\n return join(homedir(), \".mikan\");\n}\n\n/**\n * Match `args[i]` against a value flag, accepting both `--name value` and\n * `--name=value`. Returns the raw value and the index of the last argv slot\n * consumed, or undefined when `args[i]` is not this flag.\n */\nexport function takeValueFlag(\n args: string[],\n i: number,\n name: string,\n): { value: string; lastIndex: number } | undefined {\n const arg = args[i];\n if (arg === undefined) return undefined;\n if (arg === name) return { value: args[i + 1] ?? \"\", lastIndex: i + 1 };\n if (arg.startsWith(name + \"=\")) return { value: arg.slice(name.length + 1), lastIndex: i };\n return undefined;\n}\n\n/**\n * Effective state dir — the ONE place its precedence is decided:\n * `--state-dir` flag (last occurrence wins) > STATE_DIR / MIKAN_STATE_DIR\n * env > `~/.mikan`. Boot writes the resolved value back into the env\n * (setEnvAliases) purely as a compatibility channel for code that runs\n * without access to the boot plan — see `effectiveStateDir`.\n */\nexport function resolveStateDir(\n args: string[] = process.argv.slice(2),\n envValue: string | undefined = readEnv(\"STATE_DIR\"),\n): string {\n let flagValue: string | undefined;\n for (let i = 0; i < args.length; i++) {\n const taken = takeValueFlag(args, i, \"--state-dir\");\n if (taken) {\n flagValue = taken.value;\n i = taken.lastIndex;\n }\n }\n if (flagValue !== undefined) return resolve(flagValue);\n if (envValue) return resolve(envValue);\n return defaultStateDir();\n}\n\n/**\n * State dir for post-boot readers: the env channel (which boot populated\n * from the resolved plan) with the shared default. Never re-reads argv —\n * by the time this runs, any `--state-dir` flag is already folded in.\n */\nexport function effectiveStateDir(): string {\n return resolveStateDir([]);\n}\n"]}
|
package/dist/cli/boot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../../src/cli/boot.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,wBAAgB,WAAW,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,QAAQ,
|
|
1
|
+
{"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../../src/cli/boot.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,wBAAgB,WAAW,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,QAAQ,CAgE5E;AAED,wBAAgB,QAAQ,IAAI,MAAM,CAgCjC"}
|
package/dist/cli/boot.js
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* the grammar that actually drives the daemon is testable without spawning a
|
|
5
5
|
* process; main.ts just executes the plan.
|
|
6
6
|
*
|
|
7
|
-
* Modes, highest priority first: `ext` (own
|
|
8
|
-
* `help`, `version`, `onboard`, `download`, `run`.
|
|
7
|
+
* Modes, highest priority first: `ext`, `office`, `env` (own grammars, never
|
|
8
|
+
* flag-parsed here), `help`, `version`, `onboard`, `download`, `run`.
|
|
9
9
|
*/
|
|
10
|
-
import { join, resolve } from "path";
|
|
10
|
+
import { join, resolve } from "node:path";
|
|
11
11
|
import { envSummaryLines } from "../env-manifest.js";
|
|
12
12
|
import { parseSandboxArg } from "../sandbox/index.js";
|
|
13
13
|
import { defaultStateDir, resolveStateDir, takeValueFlag } from "./arg-grammar.js";
|
|
@@ -31,6 +31,8 @@ export function resolveBoot(args = process.argv.slice(2)) {
|
|
|
31
31
|
let onboard = false;
|
|
32
32
|
for (let i = 0; i < args.length; i++) {
|
|
33
33
|
const arg = args[i];
|
|
34
|
+
if (arg === undefined)
|
|
35
|
+
continue;
|
|
34
36
|
let taken;
|
|
35
37
|
if (arg === "--help" || arg === "-h") {
|
|
36
38
|
help = true;
|
package/dist/cli/boot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boot.js","sourceRoot":"","sources":["../../src/cli/boot.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"boot.js","sourceRoot":"","sources":["../../src/cli/boot.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Boot resolution for the `mikan` binary: argv → a BootPlan saying which mode\n * to run and with what configuration. Pure — no side effects, no exits — so\n * the grammar that actually drives the daemon is testable without spawning a\n * process; main.ts just executes the plan.\n *\n * Modes, highest priority first: `ext`, `office`, `env` (own grammars, never\n * flag-parsed here), `help`, `version`, `onboard`, `download`, `run`.\n */\nimport { join, resolve } from \"node:path\";\nimport { envSummaryLines } from \"../env-manifest.js\";\nimport { parseSandboxArg } from \"../sandbox/index.js\";\nimport type { SandboxConfig } from \"../sandbox/types.js\";\nimport type { BootPlan } from \"./types.js\";\nimport { defaultStateDir, resolveStateDir, takeValueFlag } from \"./arg-grammar.js\";\n\nexport type { BootPlan } from \"./types.js\";\n\nexport function resolveBoot(args: string[] = process.argv.slice(2)): BootPlan {\n if (args[0] === \"ext\" || args[0] === \"office\" || args[0] === \"env\") {\n return {\n mode: args[0],\n ...(args[0] === \"ext\" ? { extArgs: args.slice(1) } : {}),\n ...(args[0] === \"office\" ? { officeArgs: args.slice(1) } : {}),\n stateDir: defaultStateDir(),\n workingDir: join(defaultStateDir(), \"workspace\"),\n workingDirExplicit: false,\n sandbox: { type: \"host\" },\n };\n }\n\n let sandbox: SandboxConfig = { type: \"host\" };\n let workingDirArg: string | undefined;\n let downloadChannel: string | undefined;\n let help = false;\n let version = false;\n let onboard = false;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === undefined) continue;\n let taken;\n if (arg === \"--help\" || arg === \"-h\") {\n help = true;\n } else if (arg === \"--version\" || arg === \"-v\" || arg === \"-V\") {\n version = true;\n } else if (arg === \"--onboard\") {\n onboard = true;\n } else if ((taken = takeValueFlag(args, i, \"--sandbox\"))) {\n sandbox = parseSandboxArg(taken.value);\n i = taken.lastIndex;\n } else if ((taken = takeValueFlag(args, i, \"--state-dir\"))) {\n // Consumed here so its value never reads as the positional working\n // dir; the value itself is resolved by resolveStateDir below.\n i = taken.lastIndex;\n } else if ((taken = takeValueFlag(args, i, \"--download\"))) {\n downloadChannel = taken.value;\n i = taken.lastIndex;\n } else if (!arg.startsWith(\"-\")) {\n workingDirArg = arg;\n } else {\n throw new Error(`Unknown flag: ${arg}. Run \\`mikan --help\\` for usage.`);\n }\n }\n\n const stateDir = resolveStateDir(args);\n return {\n mode: help\n ? \"help\"\n : version\n ? \"version\"\n : onboard\n ? \"onboard\"\n : downloadChannel\n ? \"download\"\n : \"run\",\n stateDir,\n workingDir: workingDirArg ? resolve(workingDirArg) : join(stateDir, \"workspace\"),\n workingDirExplicit: workingDirArg !== undefined,\n sandbox,\n downloadChannel,\n };\n}\n\nexport function helpText(): string {\n return `mikan — multi-platform chat agent daemon\n\nUsage:\n mikan [options] [working-directory]\n Start the daemon. The working directory defaults to <state-dir>/workspace.\n mikan ext <install|validate|list|remove> …\n Manage extensions (run \\`mikan ext\\` for details).\n mikan office <list|claim> …\n Inspect conversation offices and claim legacy directories for a platform.\n mikan env\n Show the full environment-variable inventory and what is currently set.\n\nOptions:\n --state-dir <dir> State directory (settings.json, vaults, extensions).\n Default: ~/.mikan\n --sandbox <spec> Execution sandbox. One of:\n host\n container:<existing-container-name>\n image:<image[:tag]>\n gondolin:default\n firecracker:<vm-id>:<host-path>[:<ssh-user>[:<ssh-port>]]\n cloudflare:<sandbox-id>\n Default: host\n --onboard Create <state-dir>/settings.json from a template, then exit.\n --download <channel> Dump a Slack channel's history (Slack only), then exit.\n --version, -v Print the version.\n --help, -h Show this help.\n\nEnvironment (platform tokens select which chat adapters start):\n${envSummaryLines().join(\"\\n\")}\nRun \\`mikan env\\` for the full inventory.`;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/cli/download.ts"],"names":[],"mappings":"AA6BA,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/cli/download.ts"],"names":[],"mappings":"AA6BA,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwFxF"}
|
package/dist/cli/download.js
CHANGED
|
@@ -52,6 +52,8 @@ export async function downloadChannel(channelId, botToken) {
|
|
|
52
52
|
console.error(`Fetching ${threadsToFetch.length} threads...`);
|
|
53
53
|
for (let i = 0; i < threadsToFetch.length; i++) {
|
|
54
54
|
const parent = threadsToFetch[i];
|
|
55
|
+
if (parent === undefined)
|
|
56
|
+
continue;
|
|
55
57
|
console.error(` Thread ${i + 1}/${threadsToFetch.length} (${parent.reply_count} replies)...`);
|
|
56
58
|
const replies = [];
|
|
57
59
|
let threadCursor;
|
package/dist/cli/download.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/cli/download.ts"],"names":[],"mappings":"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","sourcesContent":["import { LogLevel, WebClient } from \"@slack/web-api\";\n\ninterface Message {\n ts: string;\n user?: string;\n text?: string;\n thread_ts?: string;\n reply_count?: number;\n files?: Array<{ name: string; url_private?: string }>;\n}\n\nfunction formatTs(ts: string): string {\n const date = new Date(parseFloat(ts) * 1000);\n return date\n .toISOString()\n .replace(\"T\", \" \")\n .replace(/\\.\\d+Z$/, \"\");\n}\n\nfunction formatMessage(ts: string, user: string, text: string, indent = \"\"): string {\n const prefix = `[${formatTs(ts)}] ${user}: `;\n const lines = text.split(\"\\n\");\n const firstLine = `${indent}${prefix}${lines[0]}`;\n if (lines.length === 1) return firstLine;\n // All continuation lines get same indent as content start\n const contentIndent = indent + \" \".repeat(prefix.length);\n return [firstLine, ...lines.slice(1).map((l) => contentIndent + l)].join(\"\\n\");\n}\n\nexport async function downloadChannel(channelId: string, botToken: string): Promise<void> {\n const client = new WebClient(botToken, { logLevel: LogLevel.ERROR });\n\n console.error(`Fetching channel info for ${channelId}...`);\n\n // Get channel info\n let channelName = channelId;\n try {\n const info = await client.conversations.info({ channel: channelId });\n channelName = typeof info.channel?.name === \"string\" ? info.channel.name : channelId;\n } catch {\n // DM channels don't have names, that's fine\n }\n\n console.error(`Downloading history for #${channelName} (${channelId})...`);\n\n // Fetch all messages\n const messages: Message[] = [];\n let cursor: string | undefined;\n\n do {\n const response = await client.conversations.history({\n channel: channelId,\n limit: 200,\n cursor,\n });\n\n if (response.messages) {\n messages.push(...(response.messages as Message[]));\n }\n\n cursor = response.response_metadata?.next_cursor;\n console.error(` Fetched ${messages.length} messages...`);\n } while (cursor);\n\n // Reverse to chronological order\n messages.reverse();\n\n // Build map of thread replies\n const threadReplies = new Map<string, Message[]>();\n const threadsToFetch = messages.filter((m) => m.reply_count && m.reply_count > 0);\n\n console.error(`Fetching ${threadsToFetch.length} threads...`);\n\n for (let i = 0; i < threadsToFetch.length; i++) {\n const parent = threadsToFetch[i];\n console.error(` Thread ${i + 1}/${threadsToFetch.length} (${parent.reply_count} replies)...`);\n\n const replies: Message[] = [];\n let threadCursor: string | undefined;\n\n do {\n const response = await client.conversations.replies({\n channel: channelId,\n ts: parent.ts,\n limit: 200,\n cursor: threadCursor,\n });\n\n if (response.messages) {\n // Skip the first message (it's the parent)\n replies.push(...(response.messages as Message[]).slice(1));\n }\n\n threadCursor = response.response_metadata?.next_cursor;\n } while (threadCursor);\n\n threadReplies.set(parent.ts, replies);\n }\n\n // Output messages with thread replies interleaved\n let totalReplies = 0;\n for (const msg of messages) {\n // Output the message\n console.log(formatMessage(msg.ts, msg.user || \"unknown\", msg.text || \"\"));\n\n // Output thread replies right after parent (indented)\n const replies = threadReplies.get(msg.ts);\n if (replies) {\n for (const reply of replies) {\n console.log(formatMessage(reply.ts, reply.user || \"unknown\", reply.text || \"\", \" \"));\n totalReplies++;\n }\n }\n }\n\n console.error(`Done! ${messages.length} messages, ${totalReplies} thread replies`);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/cli/download.ts"],"names":[],"mappings":"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","sourcesContent":["import { LogLevel, WebClient } from \"@slack/web-api\";\n\ninterface Message {\n ts: string;\n user?: string;\n text?: string;\n thread_ts?: string;\n reply_count?: number;\n files?: Array<{ name: string; url_private?: string }>;\n}\n\nfunction formatTs(ts: string): string {\n const date = new Date(parseFloat(ts) * 1000);\n return date\n .toISOString()\n .replace(\"T\", \" \")\n .replace(/\\.\\d+Z$/, \"\");\n}\n\nfunction formatMessage(ts: string, user: string, text: string, indent = \"\"): string {\n const prefix = `[${formatTs(ts)}] ${user}: `;\n const lines = text.split(\"\\n\");\n const firstLine = `${indent}${prefix}${lines[0]}`;\n if (lines.length === 1) return firstLine;\n // All continuation lines get same indent as content start\n const contentIndent = indent + \" \".repeat(prefix.length);\n return [firstLine, ...lines.slice(1).map((l) => contentIndent + l)].join(\"\\n\");\n}\n\nexport async function downloadChannel(channelId: string, botToken: string): Promise<void> {\n const client = new WebClient(botToken, { logLevel: LogLevel.ERROR });\n\n console.error(`Fetching channel info for ${channelId}...`);\n\n // Get channel info\n let channelName = channelId;\n try {\n const info = await client.conversations.info({ channel: channelId });\n channelName = typeof info.channel?.name === \"string\" ? info.channel.name : channelId;\n } catch {\n // DM channels don't have names, that's fine\n }\n\n console.error(`Downloading history for #${channelName} (${channelId})...`);\n\n // Fetch all messages\n const messages: Message[] = [];\n let cursor: string | undefined;\n\n do {\n const response = await client.conversations.history({\n channel: channelId,\n limit: 200,\n cursor,\n });\n\n if (response.messages) {\n messages.push(...(response.messages as Message[]));\n }\n\n cursor = response.response_metadata?.next_cursor;\n console.error(` Fetched ${messages.length} messages...`);\n } while (cursor);\n\n // Reverse to chronological order\n messages.reverse();\n\n // Build map of thread replies\n const threadReplies = new Map<string, Message[]>();\n const threadsToFetch = messages.filter((m) => m.reply_count && m.reply_count > 0);\n\n console.error(`Fetching ${threadsToFetch.length} threads...`);\n\n for (let i = 0; i < threadsToFetch.length; i++) {\n const parent = threadsToFetch[i];\n if (parent === undefined) continue;\n console.error(` Thread ${i + 1}/${threadsToFetch.length} (${parent.reply_count} replies)...`);\n\n const replies: Message[] = [];\n let threadCursor: string | undefined;\n\n do {\n const response = await client.conversations.replies({\n channel: channelId,\n ts: parent.ts,\n limit: 200,\n cursor: threadCursor,\n });\n\n if (response.messages) {\n // Skip the first message (it's the parent)\n replies.push(...(response.messages as Message[]).slice(1));\n }\n\n threadCursor = response.response_metadata?.next_cursor;\n } while (threadCursor);\n\n threadReplies.set(parent.ts, replies);\n }\n\n // Output messages with thread replies interleaved\n let totalReplies = 0;\n for (const msg of messages) {\n // Output the message\n console.log(formatMessage(msg.ts, msg.user || \"unknown\", msg.text || \"\"));\n\n // Output thread replies right after parent (indented)\n const replies = threadReplies.get(msg.ts);\n if (replies) {\n for (const reply of replies) {\n console.log(formatMessage(reply.ts, reply.user || \"unknown\", reply.text || \"\", \" \"));\n totalReplies++;\n }\n }\n }\n\n console.error(`Done! ${messages.length} messages, ${totalReplies} thread replies`);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ext-dev.d.ts","sourceRoot":"","sources":["../../src/cli/ext-dev.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ext-dev.d.ts","sourceRoot":"","sources":["../../src/cli/ext-dev.ts"],"names":[],"mappings":"AA2DA,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAyDtE"}
|
package/dist/cli/ext-dev.js
CHANGED
|
@@ -50,6 +50,9 @@ export async function runExtDevCommand(argv) {
|
|
|
50
50
|
let workspaceDir;
|
|
51
51
|
const positional = [];
|
|
52
52
|
for (let i = 0; i < argv.length; i++) {
|
|
53
|
+
const arg = argv[i];
|
|
54
|
+
if (arg === undefined)
|
|
55
|
+
continue;
|
|
53
56
|
let taken;
|
|
54
57
|
if ((taken = takeValueFlag(argv, i, "--workspace"))) {
|
|
55
58
|
workspaceDir = taken.value;
|
|
@@ -59,7 +62,7 @@ export async function runExtDevCommand(argv) {
|
|
|
59
62
|
i = taken.lastIndex; // already folded in by resolveStateDir
|
|
60
63
|
}
|
|
61
64
|
else
|
|
62
|
-
positional.push(
|
|
65
|
+
positional.push(arg);
|
|
63
66
|
}
|
|
64
67
|
const target = positional[0];
|
|
65
68
|
if (!target) {
|
package/dist/cli/ext-dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ext-dev.js","sourceRoot":"","sources":["../../src/cli/ext-dev.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,yBAAyB,GAK1B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1E,MAAM,KAAK,GAAG;;;;;;;+BAOiB,CAAC;AAEhC;;;GAGG;AACH,SAAS,iBAAiB,CAAC,MAAc;IACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,WAAW,CAAC;IACxF,OAAO,WAAW,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACpF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAc;IACnD,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,YAAgC,CAAC;IACrC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,KAAK,CAAC;QACV,IAAI,CAAC,KAAK,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC;YACpD,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC;YAC3B,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;QACtB,CAAC;aAAM,IAAI,CAAC,KAAK,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC;YAC3D,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,uCAAuC;QAC9D,CAAC;;YAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,6EAA6E;IAC7E,gEAAgE;IAChE,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,WAAW,CACxB,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAC7E,CAAC;QACF,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YACpE,OAAO,CAAC,KAAK,CAAC,oBAAoB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YACjD,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,cAAc,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,WAAW,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAEtF,0EAA0E;IAC1E,uEAAuE;IACvE,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,QAAQ,CAAC;IACvC,MAAM,SAAS,GAAG,eAAe,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;IACjF,SAAS,CAAC,MAAM,EAAE,CAAC;IACnB,0BAA0B,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAE9D,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,mBAAmB,cAAc,EAAE,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,mBAAmB,UAAU,EAAE,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC;IAE9E,OAAO,UAAU,CAAC,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,KAAK,CAAC,IAAY;IACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,UAAU,CAAC,OAGnB;IACC,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAE9C,MAAM,QAAQ,GAAkB;QAC9B,IAAI,EAAE,SAAS;QACf,eAAe,EAAE,sBAAsB;QACvC,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;QACxD,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;KAClE,CAAC;IAEF,MAAM,OAAO,GAAG,yBAAyB,CAAC;QACxC,SAAS;QACT,wEAAwE;QACxE,qEAAqE;QACrE,wEAAwE;QACxE,2CAA2C;QAC3C,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;KAC1B,CAAC,CAAC;IAEH,MAAM,GAAG,GAAiB;QACxB,KAAK,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACrB,WAAW,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,EAAE;YAC3C,KAAK,CAAC,IAAI,CAAC,CAAC;YACZ,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QACzB,CAAC;QACD,aAAa,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;QAChE,YAAY,EAAE,GAAG,EAAE,CAAC,KAAK;QACzB,gBAAgB,EAAE,GAAG,EAAE,CAAC,QAAQ;KACjC,CAAC;IAEF,MAAM,SAAS,GAA0B;QACvC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;QACpC,eAAe,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;QAC5C,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;QACrD,iBAAiB,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,MAAM,CAAC,QAAQ,GAAG,CAAC;QACpE,SAAS,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACzB,UAAU,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAC1B,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,QAAQ,EAAE,CAAC;QAC7D,cAAc,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;KAC/B,CAAC;IAEF,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,UAAU,GAAG,KAAK,EAAE,IAAY,EAAiB,EAAE;QACvD,MAAM,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,uBAAuB,CAAC;YACpC,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,SAAS;YACf,cAAc;YACd,gBAAgB,EAAE,QAAQ;YAC1B,EAAE;YACF,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,IAAI;YACV,UAAU,EAAE,cAAc;SAC3B,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,yBAAyB,CAAC;YACxC,QAAQ,EAAE,OAAO;YACjB,cAAc;YACd,EAAE,EAAE,EAAE;YACN,UAAU,EAAE,cAAc;YAC1B,gBAAgB,EAAE,QAAQ;YAC1B,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,WAAW;YACrB,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;QACH,MAAM,OAAO,GAAwB;YACnC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,OAAO;YACP,SAAS;YACT,QAAQ;SACT,CAAC;QACF,MAAM,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC,CAAC;IAEF,OAAO,IAAI,OAAO,CAAS,CAAC,WAAW,EAAE,EAAE;QACzC,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3F,EAAE,CAAC,MAAM,EAAE,CAAC;QACZ,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACrB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC;YACrC,KAAK,UAAU,CAAC,IAAI,CAAC;iBAClB,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;iBACtF,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YAClB,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * `mikan ext dev <path>` — develop an extension without a Slack workspace.\n *\n * mikan ext dev ./my-extension\n * > add a poll for lunch\n * [agent reply]\n * > /pi-new # picks up your edits\n *\n * The alternative this exists to avoid is asking every extension author to\n * install mikan into a real Slack workspace, create an app, and deploy before\n * they can see whether their `activate()` even runs.\n *\n * It is a stdin/stdout conversation on the same runtime production uses — same\n * package resolution, same loader, same commands — with the platform swapped\n * for the terminal and the sandbox set to `host`. That equivalence is the\n * point: an extension that works here works in a channel, because nothing\n * about how it is found or activated differs.\n *\n * The working copy is registered as a conversation-scoped local package, which\n * is by-reference rather than copied, so the edit → `/pi-new` → test loop needs\n * no reinstall step.\n */\nimport { createInterface } from \"node:readline\";\nimport { existsSync, statSync } from \"node:fs\";\nimport { basename, resolve as resolvePath } from \"node:path\";\nimport { join } from \"node:path\";\nimport {\n createConversationEvent,\n createConversationMessage,\n createConversationRuntime,\n type ConversationContext,\n type ConversationResponder,\n type MessagingBot,\n type MessagingInfo,\n} from \"../index.js\";\nimport { updateConversationSettings } from \"../config.js\";\nimport { formatSource, parseSource } from \"../packages/index.js\";\nimport { resolveStateDir, takeValueFlag } from \"./arg-grammar.js\";\nimport { createOfficeAddress, createWorkspace } from \"../office/index.js\";\n\nconst USAGE = `Usage:\n mikan ext dev <path|source> [--workspace <dir>] [--state-dir <dir>]\n\n <path> a working copy of an extension (or a package directory)\n --workspace where conversation state is written (default: ./.mikan-ext-dev)\n\n Type a message to run the agent against your extension. /pi-new reloads it\n after an edit; Ctrl-D exits.`;\n\n/**\n * One dev conversation per extension, so two extensions can be developed side\n * by side without overwriting each other's settings or session history.\n */\nfunction devConversationId(source: string): string {\n const name = basename(source.replace(/[#@].*$/, \"\").replace(/\\/+$/, \"\")) || \"extension\";\n return `ext-dev-${name.toLowerCase().replace(/[^a-z0-9_-]+/g, \"-\")}`.slice(0, 64);\n}\n\nexport async function runExtDevCommand(argv: string[]): Promise<number> {\n const stateDir = resolveStateDir(argv);\n let workspaceDir: string | undefined;\n const positional: string[] = [];\n for (let i = 0; i < argv.length; i++) {\n let taken;\n if ((taken = takeValueFlag(argv, i, \"--workspace\"))) {\n workspaceDir = taken.value;\n i = taken.lastIndex;\n } else if ((taken = takeValueFlag(argv, i, \"--state-dir\"))) {\n i = taken.lastIndex; // already folded in by resolveStateDir\n } else positional.push(argv[i]);\n }\n\n const target = positional[0];\n if (!target) {\n console.error(USAGE);\n return 1;\n }\n\n // A local working copy is the common case; resolve it to an absolute path so\n // the stored package source does not depend on the shell's cwd.\n let source: string;\n try {\n const parsed = parseSource(\n existsSync(target) && !target.startsWith(\".\") ? resolvePath(target) : target,\n );\n source = formatSource(parsed);\n if (parsed.type === \"local\" && !statSync(parsed.path).isDirectory()) {\n console.error(`Not a directory: ${parsed.path}`);\n return 1;\n }\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n return 1;\n }\n\n const conversationId = devConversationId(target);\n const workingDir = resolvePath(workspaceDir ?? join(process.cwd(), \".mikan-ext-dev\"));\n\n // Declaring the working copy as this conversation's package is what makes\n // the dev loop use the real resolution path rather than a bespoke one.\n process.env.MIKAN_STATE_DIR = stateDir;\n const workspace = createWorkspace({ root: workingDir, stateDir });\n const devOffice = workspace.office(createOfficeAddress(\"slack\", conversationId));\n devOffice.ensure();\n updateConversationSettings(devOffice, { packages: [source] });\n\n console.log(`mikan ext dev — ${source}`);\n console.log(` conversation: ${conversationId}`);\n console.log(` workspace: ${workingDir}`);\n console.log(` state dir: ${stateDir}`);\n console.log(\"Type a message. /pi-new reloads after an edit. Ctrl-D exits.\\n\");\n\n return runDevLoop({ conversationId, workspace });\n}\n\nfunction write(text: string): void {\n process.stdout.write(`${text}\\n`);\n}\n\nfunction runDevLoop(options: {\n conversationId: string;\n workspace: import(\"../office/types.js\").Workspace;\n}): Promise<number> {\n const { conversationId, workspace } = options;\n\n const platform: MessagingInfo = {\n name: \"ext-dev\",\n formattingGuide: \"Reply in plain text.\",\n channels: [{ id: conversationId, name: conversationId }],\n users: [{ id: \"dev\", userName: \"dev\", displayName: \"Developer\" }],\n };\n\n const runtime = createConversationRuntime({\n workspace,\n // The host executor keeps the loop dependency-free: no Docker, no image\n // pull, no VM. An extension's own tools and hooks do not observe the\n // difference, and the ones that shell out see the developer's machine —\n // which is what they want while iterating.\n sandbox: { type: \"host\" },\n });\n\n const bot: MessagingBot = {\n start: async () => {},\n postMessage: async (_conversationId, text) => {\n write(text);\n return `${Date.now()}`;\n },\n updateMessage: async (_conversationId, _ts, text) => write(text),\n enqueueEvent: () => false,\n getMessagingInfo: () => platform,\n };\n\n const responder: ConversationResponder = {\n respond: async (text) => write(text),\n replaceResponse: async (text) => write(text),\n respondDiagnostic: async (text) => write(`· ${text}`),\n respondToolResult: async (result) => write(`· [${result.toolName}]`),\n setTyping: async () => {},\n setWorking: async () => {},\n uploadFile: async (filePath) => write(`· [file] ${filePath}`),\n deleteResponse: async () => {},\n };\n\n let counter = 0;\n const handleLine = async (line: string): Promise<void> => {\n const ts = `${++counter}`;\n const event = createConversationEvent({\n platform: \"slack\",\n type: \"message\",\n conversationId,\n conversationKind: \"direct\",\n ts,\n user: \"dev\",\n text: line,\n sessionKey: conversationId,\n });\n const message = createConversationMessage({\n platform: \"slack\",\n conversationId,\n id: ts,\n sessionKey: conversationId,\n conversationKind: \"direct\",\n userId: \"dev\",\n userName: \"Developer\",\n text: line,\n });\n const context: ConversationContext = {\n address: event.address,\n message,\n responder,\n platform,\n };\n await runtime.handleEvent(event, bot, context);\n };\n\n return new Promise<number>((resolveLoop) => {\n const rl = createInterface({ input: process.stdin, output: process.stdout, prompt: \"> \" });\n rl.prompt();\n rl.on(\"line\", (line) => {\n if (!line.trim()) return rl.prompt();\n void handleLine(line)\n .catch((err: unknown) => write(`· error: ${err instanceof Error ? err.message : err}`))\n .finally(() => rl.prompt());\n });\n rl.on(\"close\", () => {\n void runtime.shutdown().then(() => resolveLoop(0));\n });\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ext-dev.js","sourceRoot":"","sources":["../../src/cli/ext-dev.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `mikan ext dev <path>` — develop an extension without a Slack workspace.\n *\n * mikan ext dev ./my-extension\n * > add a poll for lunch\n * [agent reply]\n * > /pi-new # picks up your edits\n *\n * The alternative this exists to avoid is asking every extension author to\n * install mikan into a real Slack workspace, create an app, and deploy before\n * they can see whether their `activate()` even runs.\n *\n * It is a stdin/stdout conversation on the same runtime production uses — same\n * package resolution, same loader, same commands — with the platform swapped\n * for the terminal and the sandbox set to `host`. That equivalence is the\n * point: an extension that works here works in a channel, because nothing\n * about how it is found or activated differs.\n *\n * The working copy is registered as a conversation-scoped local package, which\n * is by-reference rather than copied, so the edit → `/pi-new` → test loop needs\n * no reinstall step.\n */\nimport { createInterface } from \"node:readline\";\nimport { existsSync, statSync } from \"node:fs\";\nimport { basename, resolve as resolvePath } from \"node:path\";\nimport { join } from \"node:path\";\nimport {\n createConversationEvent,\n createConversationMessage,\n createConversationRuntime,\n type ConversationContext,\n type ConversationResponder,\n type MessagingBot,\n type MessagingInfo,\n} from \"../index.js\";\nimport { updateConversationSettings } from \"../config.js\";\nimport { formatSource, parseSource } from \"../packages/index.js\";\nimport { resolveStateDir, takeValueFlag } from \"./arg-grammar.js\";\nimport { createOfficeAddress, createWorkspace } from \"../office/index.js\";\nimport type { Workspace } from \"../office/types.js\";\n\nconst USAGE = `Usage:\n mikan ext dev <path|source> [--workspace <dir>] [--state-dir <dir>]\n\n <path> a working copy of an extension (or a package directory)\n --workspace where conversation state is written (default: ./.mikan-ext-dev)\n\n Type a message to run the agent against your extension. /pi-new reloads it\n after an edit; Ctrl-D exits.`;\n\n/**\n * One dev conversation per extension, so two extensions can be developed side\n * by side without overwriting each other's settings or session history.\n */\nfunction devConversationId(source: string): string {\n const name = basename(source.replace(/[#@].*$/, \"\").replace(/\\/+$/, \"\")) || \"extension\";\n return `ext-dev-${name.toLowerCase().replace(/[^a-z0-9_-]+/g, \"-\")}`.slice(0, 64);\n}\n\nexport async function runExtDevCommand(argv: string[]): Promise<number> {\n const stateDir = resolveStateDir(argv);\n let workspaceDir: string | undefined;\n const positional: string[] = [];\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === undefined) continue;\n let taken;\n if ((taken = takeValueFlag(argv, i, \"--workspace\"))) {\n workspaceDir = taken.value;\n i = taken.lastIndex;\n } else if ((taken = takeValueFlag(argv, i, \"--state-dir\"))) {\n i = taken.lastIndex; // already folded in by resolveStateDir\n } else positional.push(arg);\n }\n\n const target = positional[0];\n if (!target) {\n console.error(USAGE);\n return 1;\n }\n\n // A local working copy is the common case; resolve it to an absolute path so\n // the stored package source does not depend on the shell's cwd.\n let source: string;\n try {\n const parsed = parseSource(\n existsSync(target) && !target.startsWith(\".\") ? resolvePath(target) : target,\n );\n source = formatSource(parsed);\n if (parsed.type === \"local\" && !statSync(parsed.path).isDirectory()) {\n console.error(`Not a directory: ${parsed.path}`);\n return 1;\n }\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n return 1;\n }\n\n const conversationId = devConversationId(target);\n const workingDir = resolvePath(workspaceDir ?? join(process.cwd(), \".mikan-ext-dev\"));\n\n // Declaring the working copy as this conversation's package is what makes\n // the dev loop use the real resolution path rather than a bespoke one.\n process.env.MIKAN_STATE_DIR = stateDir;\n const workspace = createWorkspace({ root: workingDir, stateDir });\n const devOffice = workspace.office(createOfficeAddress(\"slack\", conversationId));\n devOffice.ensure();\n updateConversationSettings(devOffice, { packages: [source] });\n\n console.log(`mikan ext dev — ${source}`);\n console.log(` conversation: ${conversationId}`);\n console.log(` workspace: ${workingDir}`);\n console.log(` state dir: ${stateDir}`);\n console.log(\"Type a message. /pi-new reloads after an edit. Ctrl-D exits.\\n\");\n\n return runDevLoop({ conversationId, workspace });\n}\n\nfunction write(text: string): void {\n process.stdout.write(`${text}\\n`);\n}\n\nfunction runDevLoop(options: { conversationId: string; workspace: Workspace }): Promise<number> {\n const { conversationId, workspace } = options;\n\n const platform: MessagingInfo = {\n name: \"ext-dev\",\n formattingGuide: \"Reply in plain text.\",\n channels: [{ id: conversationId, name: conversationId }],\n users: [{ id: \"dev\", userName: \"dev\", displayName: \"Developer\" }],\n };\n\n const runtime = createConversationRuntime({\n workspace,\n // The host executor keeps the loop dependency-free: no Docker, no image\n // pull, no VM. An extension's own tools and hooks do not observe the\n // difference, and the ones that shell out see the developer's machine —\n // which is what they want while iterating.\n sandbox: { type: \"host\" },\n });\n\n const bot: MessagingBot = {\n start: async () => {},\n postMessage: async (_conversationId, text) => {\n write(text);\n return `${Date.now()}`;\n },\n updateMessage: async (_conversationId, _ts, text) => write(text),\n enqueueEvent: () => false,\n getMessagingInfo: () => platform,\n };\n\n const responder: ConversationResponder = {\n respond: async (text) => write(text),\n replaceResponse: async (text) => write(text),\n respondDiagnostic: async (text) => write(`· ${text}`),\n respondToolResult: async (result) => write(`· [${result.toolName}]`),\n setTyping: async () => {},\n setWorking: async () => {},\n uploadFile: async (filePath) => write(`· [file] ${filePath}`),\n deleteResponse: async () => {},\n };\n\n let counter = 0;\n const handleLine = async (line: string): Promise<void> => {\n const ts = `${++counter}`;\n const event = createConversationEvent({\n platform: \"slack\",\n type: \"message\",\n conversationId,\n conversationKind: \"direct\",\n ts,\n user: \"dev\",\n text: line,\n sessionKey: conversationId,\n });\n const message = createConversationMessage({\n platform: \"slack\",\n conversationId,\n id: ts,\n sessionKey: conversationId,\n conversationKind: \"direct\",\n userId: \"dev\",\n userName: \"Developer\",\n text: line,\n });\n const context: ConversationContext = {\n address: event.address,\n message,\n responder,\n platform,\n };\n await runtime.handleEvent(event, bot, context);\n };\n\n return new Promise<number>((resolveLoop) => {\n const rl = createInterface({ input: process.stdin, output: process.stdout, prompt: \"> \" });\n rl.prompt();\n rl.on(\"line\", (line) => {\n if (!line.trim()) return rl.prompt();\n void handleLine(line)\n .catch((err: unknown) => write(`· error: ${err instanceof Error ? err.message : err}`))\n .finally(() => rl.prompt());\n });\n rl.on(\"close\", () => {\n void runtime.shutdown().then(() => resolveLoop(0));\n });\n });\n}\n"]}
|
package/dist/cli/ext.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ext.d.ts","sourceRoot":"","sources":["../../src/cli/ext.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ext.d.ts","sourceRoot":"","sources":["../../src/cli/ext.ts"],"names":[],"mappings":"AA4GA,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBnE"}
|
package/dist/cli/ext.js
CHANGED
|
@@ -11,12 +11,13 @@
|
|
|
11
11
|
* existing extension updates it (data is preserved). Extensions install into the
|
|
12
12
|
* host-only state dir (never the workspace); see src/harness/extensions/LAYOUT.md.
|
|
13
13
|
*/
|
|
14
|
-
import { cpSync, existsSync, mkdirSync, rmSync } from "node:fs";
|
|
14
|
+
import { cpSync, existsSync, mkdirSync, readdirSync, rmSync } from "node:fs";
|
|
15
15
|
import { basename, join, resolve } from "node:path";
|
|
16
16
|
import { defaultExtensionDirs, listInstalledExtensions, validateExtension, } from "../harness/index.js";
|
|
17
17
|
import { resolveStateDir, takeValueFlag } from "./arg-grammar.js";
|
|
18
18
|
import { runExtDevCommand } from "./ext-dev.js";
|
|
19
|
-
import {
|
|
19
|
+
import { materializeSource } from "../packages/materialize.js";
|
|
20
|
+
import { isGitSourceString } from "../packages/source.js";
|
|
20
21
|
import { officeStateDir } from "../office/index.js";
|
|
21
22
|
import { resolveOwnedOfficeAddress } from "../office/index.js";
|
|
22
23
|
function parseExtArgs(argv) {
|
|
@@ -24,24 +25,42 @@ function parseExtArgs(argv) {
|
|
|
24
25
|
const stateDir = resolveStateDir(argv);
|
|
25
26
|
let scope;
|
|
26
27
|
let conversationId;
|
|
28
|
+
let workspaceDir;
|
|
29
|
+
let purge = false;
|
|
27
30
|
const positional = [];
|
|
28
31
|
for (let i = 0; i < argv.length; i++) {
|
|
29
32
|
const arg = argv[i];
|
|
33
|
+
if (arg === undefined)
|
|
34
|
+
continue;
|
|
30
35
|
let taken;
|
|
31
36
|
if (arg === "--global")
|
|
32
37
|
scope = "global";
|
|
38
|
+
else if (arg === "--purge")
|
|
39
|
+
purge = true;
|
|
33
40
|
else if ((taken = takeValueFlag(argv, i, "--conversation"))) {
|
|
34
41
|
scope = "conversation";
|
|
35
42
|
conversationId = taken.value || undefined;
|
|
36
43
|
i = taken.lastIndex;
|
|
37
44
|
}
|
|
45
|
+
else if ((taken = takeValueFlag(argv, i, "--workspace"))) {
|
|
46
|
+
workspaceDir = taken.value ? resolve(taken.value) : undefined;
|
|
47
|
+
i = taken.lastIndex;
|
|
48
|
+
}
|
|
38
49
|
else if ((taken = takeValueFlag(argv, i, "--state-dir"))) {
|
|
39
50
|
i = taken.lastIndex; // value already folded in by resolveStateDir
|
|
40
51
|
}
|
|
41
52
|
else
|
|
42
53
|
positional.push(arg);
|
|
43
54
|
}
|
|
44
|
-
return {
|
|
55
|
+
return {
|
|
56
|
+
action: positional[0] ?? "",
|
|
57
|
+
target: positional[1],
|
|
58
|
+
stateDir,
|
|
59
|
+
scope,
|
|
60
|
+
conversationId,
|
|
61
|
+
workspaceDir,
|
|
62
|
+
purge,
|
|
63
|
+
};
|
|
45
64
|
}
|
|
46
65
|
/** Directory that extension CODE for the chosen scope lives in. */
|
|
47
66
|
function scopeExtensionsDir(args) {
|
|
@@ -49,7 +68,11 @@ function scopeExtensionsDir(args) {
|
|
|
49
68
|
return join(args.stateDir, "global", "extensions");
|
|
50
69
|
if (args.scope === "conversation" && args.conversationId) {
|
|
51
70
|
// defaultExtensionDirs returns [global, conversation]; take the conversation one.
|
|
52
|
-
|
|
71
|
+
const conversationDir = defaultExtensionDirs(resolveOwnedOfficeAddress(args.conversationId, args.stateDir), args.stateDir)[1];
|
|
72
|
+
if (conversationDir === undefined) {
|
|
73
|
+
throw new Error("defaultExtensionDirs returned no conversation directory");
|
|
74
|
+
}
|
|
75
|
+
return conversationDir;
|
|
53
76
|
}
|
|
54
77
|
throw new Error("Specify a scope: --global or --conversation <id>");
|
|
55
78
|
}
|
|
@@ -58,13 +81,14 @@ const USAGE = `Usage:
|
|
|
58
81
|
Run an extension in a local stdin/stdout conversation — no Slack, no
|
|
59
82
|
install. Edit, send /pi-new, test again.
|
|
60
83
|
mikan ext install <source> (--global | --conversation <id>) [--state-dir <dir>]
|
|
61
|
-
<source>: a local path, or a git URL / github:owner/repo with optional #subpath
|
|
84
|
+
<source>: a local path, or a git URL / github:owner/repo with optional @ref and #subpath
|
|
62
85
|
e.g. github:geminixiang/mikan#deploy/examples/extensions/agent-pm
|
|
63
86
|
Reinstalling over an existing extension updates it (data preserved).
|
|
64
87
|
mikan ext validate <path>
|
|
65
88
|
mikan ext list [--conversation <id>] [--state-dir <dir>]
|
|
66
|
-
mikan ext remove <slug> (--global | --conversation <id>) [--state-dir <dir>]
|
|
67
|
-
|
|
89
|
+
mikan ext remove <slug> (--global | --conversation <id>) [--purge] [--workspace <dir>] [--state-dir <dir>]
|
|
90
|
+
Removes the extension's code. --purge also sweeps its schedules, secrets
|
|
91
|
+
vault, and data dirs; add --workspace to sweep its event files too.`;
|
|
68
92
|
export async function runExtCommand(argv) {
|
|
69
93
|
const args = parseExtArgs(argv);
|
|
70
94
|
switch (args.action) {
|
|
@@ -106,31 +130,30 @@ async function installAction(args) {
|
|
|
106
130
|
console.error(err instanceof Error ? err.message : String(err));
|
|
107
131
|
return 1;
|
|
108
132
|
}
|
|
109
|
-
// Resolve the source: a git
|
|
110
|
-
//
|
|
111
|
-
|
|
133
|
+
// Resolve the source: a git source materializes through the packages layer
|
|
134
|
+
// (cached clone under the scope's git/ dir, @ref supported); a local path is
|
|
135
|
+
// used directly. `refresh` re-fetches so reinstall always picks up updates.
|
|
112
136
|
let source;
|
|
113
|
-
|
|
114
|
-
if (gitSpec) {
|
|
137
|
+
if (isGitSourceString(args.target)) {
|
|
115
138
|
try {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
139
|
+
source = materializeSource(args.target, {
|
|
140
|
+
scope: args.scope,
|
|
141
|
+
address: args.scope === "conversation"
|
|
142
|
+
? resolveOwnedOfficeAddress(args.conversationId, args.stateDir)
|
|
143
|
+
: undefined,
|
|
144
|
+
stateDir: args.stateDir,
|
|
145
|
+
mode: "refresh",
|
|
146
|
+
}).dir;
|
|
119
147
|
}
|
|
120
148
|
catch (err) {
|
|
121
|
-
console.error(`Failed to fetch ${
|
|
149
|
+
console.error(`Failed to fetch ${args.target}: ${err instanceof Error ? err.message : err}`);
|
|
122
150
|
return 1;
|
|
123
151
|
}
|
|
124
152
|
}
|
|
125
153
|
else {
|
|
126
154
|
source = resolve(args.target);
|
|
127
155
|
}
|
|
128
|
-
|
|
129
|
-
return await installResolved(args, source, destDir);
|
|
130
|
-
}
|
|
131
|
-
finally {
|
|
132
|
-
cleanup();
|
|
133
|
-
}
|
|
156
|
+
return await installResolved(args, source, destDir);
|
|
134
157
|
}
|
|
135
158
|
async function installResolved(args, source, destDir) {
|
|
136
159
|
const result = await validateExtension(source);
|
|
@@ -178,9 +201,47 @@ function listAction(args) {
|
|
|
178
201
|
console.log(` ${info.description}`);
|
|
179
202
|
if (info.skillNames.length > 0)
|
|
180
203
|
console.log(` skills: ${info.skillNames.join(", ")}`);
|
|
204
|
+
if (info.secrets.length > 0) {
|
|
205
|
+
const keys = info.secrets.map((s) => `${s.key}${s.required ? " (required)" : ""}`);
|
|
206
|
+
console.log(` secrets: ${keys.join(", ")}`);
|
|
207
|
+
}
|
|
181
208
|
}
|
|
182
209
|
return 0;
|
|
183
210
|
}
|
|
211
|
+
/** Files in `dir` (non-recursive) whose names satisfy `matches`; [] when absent. */
|
|
212
|
+
function matchingFiles(dir, matches) {
|
|
213
|
+
if (!existsSync(dir))
|
|
214
|
+
return [];
|
|
215
|
+
return readdirSync(dir)
|
|
216
|
+
.filter(matches)
|
|
217
|
+
.map((filename) => join(dir, filename));
|
|
218
|
+
}
|
|
219
|
+
function findExtensionResidue(slug, stateDir, workspaceDir) {
|
|
220
|
+
const callbackScheduleFiles = [];
|
|
221
|
+
const dataDirs = [];
|
|
222
|
+
const conversationsDir = join(stateDir, "conversations");
|
|
223
|
+
const officeDirs = existsSync(conversationsDir) ? readdirSync(conversationsDir) : [];
|
|
224
|
+
for (const officeDir of officeDirs) {
|
|
225
|
+
callbackScheduleFiles.push(...matchingFiles(join(conversationsDir, officeDir, "extension-schedules"), (filename) => filename.startsWith(`${slug}.`) && filename.endsWith(".json")));
|
|
226
|
+
const dataDir = join(conversationsDir, officeDir, "extension-data", slug);
|
|
227
|
+
if (existsSync(dataDir))
|
|
228
|
+
dataDirs.push(dataDir);
|
|
229
|
+
}
|
|
230
|
+
const globalDataDir = join(stateDir, "global", "extension-data", slug);
|
|
231
|
+
if (existsSync(globalDataDir))
|
|
232
|
+
dataDirs.push(globalDataDir);
|
|
233
|
+
const eventFiles = workspaceDir
|
|
234
|
+
? matchingFiles(join(workspaceDir, "events"), (filename) => (filename.startsWith(`ext.${slug}.`) || filename.startsWith(`extrun.${slug}.`)) &&
|
|
235
|
+
filename.endsWith(".json"))
|
|
236
|
+
: [];
|
|
237
|
+
const vaultDir = join(stateDir, "vaults", "extensions", slug);
|
|
238
|
+
return {
|
|
239
|
+
callbackScheduleFiles,
|
|
240
|
+
...(existsSync(vaultDir) ? { vaultDir } : {}),
|
|
241
|
+
dataDirs,
|
|
242
|
+
eventFiles,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
184
245
|
function removeAction(args) {
|
|
185
246
|
if (!args.target) {
|
|
186
247
|
console.error("ext remove: missing <slug>");
|
|
@@ -205,7 +266,42 @@ function removeAction(args) {
|
|
|
205
266
|
const parent = resolve(match.path, "..");
|
|
206
267
|
const removeTarget = parent === resolve(destDir) ? match.path : parent;
|
|
207
268
|
rmSync(removeTarget, { recursive: true, force: true });
|
|
208
|
-
console.log(`Removed ${match.name} (slug: ${match.slug})
|
|
269
|
+
console.log(`Removed ${match.name} (slug: ${match.slug}).`);
|
|
270
|
+
// Never sweep implicitly: the same slug may still be active through another
|
|
271
|
+
// scope or a PACKAGES declaration this command cannot see. --purge is the
|
|
272
|
+
// admin's statement that nothing else owns it.
|
|
273
|
+
const residue = findExtensionResidue(match.slug, args.stateDir, args.workspaceDir);
|
|
274
|
+
if (args.purge) {
|
|
275
|
+
for (const file of [...residue.callbackScheduleFiles, ...residue.eventFiles]) {
|
|
276
|
+
rmSync(file, { force: true });
|
|
277
|
+
}
|
|
278
|
+
for (const dataDir of residue.dataDirs)
|
|
279
|
+
rmSync(dataDir, { recursive: true, force: true });
|
|
280
|
+
if (residue.vaultDir)
|
|
281
|
+
rmSync(residue.vaultDir, { recursive: true, force: true });
|
|
282
|
+
console.log(`Purged: ${residue.callbackScheduleFiles.length} schedule file(s), ` +
|
|
283
|
+
`${residue.eventFiles.length} event file(s), ${residue.dataDirs.length} data dir(s)` +
|
|
284
|
+
`${residue.vaultDir ? ", secrets vault" : ""}.`);
|
|
285
|
+
if (!args.workspaceDir) {
|
|
286
|
+
console.log("Note: events-bus files were not swept — pass --workspace <dir> to include them.");
|
|
287
|
+
}
|
|
288
|
+
if (residue.callbackScheduleFiles.length > 0) {
|
|
289
|
+
console.log("A running daemon keeps deleted schedules armed until restart.");
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
const leftovers = [
|
|
294
|
+
residue.callbackScheduleFiles.length > 0
|
|
295
|
+
? `${residue.callbackScheduleFiles.length} schedule file(s)`
|
|
296
|
+
: undefined,
|
|
297
|
+
residue.vaultDir ? "secrets vault" : undefined,
|
|
298
|
+
residue.dataDirs.length > 0 ? `${residue.dataDirs.length} data dir(s)` : undefined,
|
|
299
|
+
residue.eventFiles.length > 0 ? `${residue.eventFiles.length} event file(s)` : undefined,
|
|
300
|
+
].filter(Boolean);
|
|
301
|
+
if (leftovers.length > 0) {
|
|
302
|
+
console.log(`Left in place: ${leftovers.join(", ")}. Re-run with --purge to sweep.`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
209
305
|
console.log("Run /pi-new in the conversation to apply.");
|
|
210
306
|
return 0;
|
|
211
307
|
}
|
|
@@ -215,6 +311,10 @@ function printValidation(result) {
|
|
|
215
311
|
console.log(` entrypoint: ${result.entrypoint}`);
|
|
216
312
|
if (result.skillNames.length > 0)
|
|
217
313
|
console.log(` skills: ${result.skillNames.join(", ")}`);
|
|
314
|
+
if (result.secrets.length > 0) {
|
|
315
|
+
const keys = result.secrets.map((s) => `${s.key}${s.required ? " (required)" : ""}`);
|
|
316
|
+
console.log(` secrets: ${keys.join(", ")}`);
|
|
317
|
+
}
|
|
218
318
|
for (const warning of result.warnings)
|
|
219
319
|
console.log(` warning: ${warning}`);
|
|
220
320
|
for (const error of result.errors)
|