@geminixiang/mikan 1.0.0-beta.61 → 1.0.0-beta.63
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 +38 -0
- package/README.md +16 -14
- package/dist/adapters/commands/sandbox.d.ts.map +1 -1
- package/dist/adapters/commands/sandbox.js +30 -53
- package/dist/adapters/commands/sandbox.js.map +1 -1
- package/dist/adapters/commands/types.d.ts +3 -3
- package/dist/adapters/commands/types.d.ts.map +1 -1
- package/dist/adapters/commands/types.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +15 -3
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +50 -14
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/web/admin/portal.d.ts +1 -1
- package/dist/adapters/web/admin/portal.d.ts.map +1 -1
- package/dist/adapters/web/admin/portal.js +61 -146
- package/dist/adapters/web/admin/portal.js.map +1 -1
- package/dist/adapters/web/admin/types.d.ts +6 -3
- package/dist/adapters/web/admin/types.d.ts.map +1 -1
- package/dist/adapters/web/admin/types.js.map +1 -1
- package/dist/adapters/web/server.d.ts +3 -0
- package/dist/adapters/web/server.d.ts.map +1 -1
- package/dist/adapters/web/server.js +4 -6
- package/dist/adapters/web/server.js.map +1 -1
- package/dist/cli/boot.js +1 -1
- package/dist/cli/boot.js.map +1 -1
- package/dist/cli/office.d.ts.map +1 -1
- package/dist/cli/office.js +66 -0
- package/dist/cli/office.js.map +1 -1
- package/dist/config.d.ts +13 -10
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +35 -54
- package/dist/config.js.map +1 -1
- package/dist/env-manifest.js +3 -3
- package/dist/env-manifest.js.map +1 -1
- package/dist/events/index.d.ts +56 -34
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +114 -23
- package/dist/events/index.js.map +1 -1
- package/dist/events/scheduler.d.ts +34 -0
- package/dist/events/scheduler.d.ts.map +1 -0
- package/dist/events/scheduler.js +231 -0
- package/dist/events/scheduler.js.map +1 -0
- package/dist/harness/execution-resolver.d.ts.map +1 -1
- package/dist/harness/execution-resolver.js +1 -1
- package/dist/harness/execution-resolver.js.map +1 -1
- package/dist/harness/mcp.d.ts.map +1 -1
- package/dist/harness/mcp.js +1 -3
- package/dist/harness/mcp.js.map +1 -1
- package/dist/harness/open-connector.d.ts +21 -10
- package/dist/harness/open-connector.d.ts.map +1 -1
- package/dist/harness/open-connector.js +109 -135
- package/dist/harness/open-connector.js.map +1 -1
- package/dist/harness/prompt.d.ts.map +1 -1
- package/dist/harness/prompt.js +19 -23
- package/dist/harness/prompt.js.map +1 -1
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +26 -11
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/tools/event.d.ts +1 -1
- package/dist/harness/tools/event.d.ts.map +1 -1
- package/dist/harness/tools/event.js +19 -22
- package/dist/harness/tools/event.js.map +1 -1
- package/dist/harness/tools/index.d.ts +2 -1
- package/dist/harness/tools/index.d.ts.map +1 -1
- package/dist/harness/tools/index.js +2 -3
- package/dist/harness/tools/index.js.map +1 -1
- package/dist/main.js +17 -9
- package/dist/main.js.map +1 -1
- package/dist/office/index.d.ts +3 -2
- package/dist/office/index.d.ts.map +1 -1
- package/dist/office/index.js +3 -3
- package/dist/office/index.js.map +1 -1
- package/dist/office/projection.d.ts +19 -2
- package/dist/office/projection.d.ts.map +1 -1
- package/dist/office/projection.js +73 -100
- package/dist/office/projection.js.map +1 -1
- package/dist/office/types.d.ts +13 -10
- package/dist/office/types.d.ts.map +1 -1
- package/dist/office/types.js.map +1 -1
- package/dist/runtime/conversation-runtime.js +1 -0
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/types.d.ts +4 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/index.d.ts +9 -1
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +16 -12
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/provisioner.d.ts +8 -0
- package/dist/sandbox/provisioner.d.ts.map +1 -1
- package/dist/sandbox/provisioner.js +36 -0
- package/dist/sandbox/provisioner.js.map +1 -1
- package/dist/settings-mutation.d.ts +5 -29
- package/dist/settings-mutation.d.ts.map +1 -1
- package/dist/settings-mutation.js +7 -13
- package/dist/settings-mutation.js.map +1 -1
- package/dist/types.d.ts +11 -27
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -1
- package/dist/events/watcher.d.ts +0 -43
- package/dist/events/watcher.d.ts.map +0 -1
- package/dist/events/watcher.js +0 -395
- package/dist/events/watcher.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MessagingBot, OfficeAddress, PlatformName, RunningSession } from "../../../adapter.js";
|
|
2
|
-
import type { Workspace } from "../../../office/index.js";
|
|
2
|
+
import type { Office, Workspace } from "../../../office/index.js";
|
|
3
3
|
import type { LinkTokenStoreLike } from "../../commands/types.js";
|
|
4
4
|
import type { SandboxConfig } from "../../../sandbox/index.js";
|
|
5
5
|
import type { EventStore } from "../../../events/index.js";
|
|
@@ -22,8 +22,8 @@ export interface AdminServices {
|
|
|
22
22
|
adminTokenStore: InMemoryAdminTokenStore;
|
|
23
23
|
portalBaseUrl?: string;
|
|
24
24
|
workspace?: Workspace;
|
|
25
|
-
/**
|
|
26
|
-
eventStore?: EventStore;
|
|
25
|
+
/** Office-confined event store factory; Admin never reads event files directly. */
|
|
26
|
+
eventStore?: (office: Office) => EventStore;
|
|
27
27
|
sandbox?: SandboxConfig;
|
|
28
28
|
runtime?: AdminRuntimeBridge;
|
|
29
29
|
botsByPlatform?: Partial<Record<PlatformName, MessagingBot>>;
|
|
@@ -33,6 +33,9 @@ export interface EventSummary {
|
|
|
33
33
|
size: number;
|
|
34
34
|
mtimeMs: number;
|
|
35
35
|
type: string | null;
|
|
36
|
+
/** Owning office, from the store — authoritative even when the payload is unparseable. */
|
|
37
|
+
officePlatform: string;
|
|
38
|
+
officeConversationId: string;
|
|
36
39
|
platform: string | null;
|
|
37
40
|
conversationId: string | null;
|
|
38
41
|
text: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/adapters/web/admin/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,cAAc,EACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/adapters/web/admin/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,cAAc,EACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,IAAI,cAAc,EAAE,CAAC;IACvC,uBAAuB,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1F,8BAA8B,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC;IAChE,uBAAuB,IAAI;QAAE,IAAI,EAAE,aAAa,EAAE,CAAA;KAAE,CAAC;CACtD;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,kBAAkB,CAAC;IACnC,qBAAqB,CAAC,EAAE,6BAA6B,CAAC;IACtD,eAAe,EAAE,uBAAuB,CAAC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,mFAAmF;IACnF,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,UAAU,CAAC;IAC5C,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,0FAA0F;IAC1F,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,QAAQ,EAAE,YAAY,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oFAAoF;IACpF,cAAc,EAAE,MAAM,CAAC;CACxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/adapters/web/admin/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n MessagingBot,\n OfficeAddress,\n PlatformName,\n RunningSession,\n} from \"../../../adapter.js\";\nimport type { Workspace } from \"../../../office/index.js\";\nimport type { LinkTokenStoreLike } from \"../../commands/types.js\";\nimport type { SandboxConfig } from \"../../../sandbox/index.js\";\nimport type { EventStore } from \"../../../events/index.js\";\nimport type { VaultManager } from \"../../../vault/index.js\";\nimport type { InMemorySessionViewTokenStore } from \"../session-view/portal.js\";\nimport type { TokenRecord } from \"../types.js\";\nimport type { InMemoryAdminTokenStore } from \"./portal.js\";\n\nexport interface AdminRuntimeBridge {\n getRunningSessions(): RunningSession[];\n switchConversationModel(address: OfficeAddress, provider: string, model: string): boolean;\n refreshConversationEnvironment(address: OfficeAddress): boolean;\n refreshAllConversations(): { busy: OfficeAddress[] };\n}\n\nexport interface AdminServices {\n vaultManager: VaultManager;\n linkTokenStore: LinkTokenStoreLike;\n sessionViewTokenStore?: InMemorySessionViewTokenStore;\n adminTokenStore: InMemoryAdminTokenStore;\n portalBaseUrl?: string;\n workspace?: Workspace;\n /**
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/adapters/web/admin/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n MessagingBot,\n OfficeAddress,\n PlatformName,\n RunningSession,\n} from \"../../../adapter.js\";\nimport type { Office, Workspace } from \"../../../office/index.js\";\nimport type { LinkTokenStoreLike } from \"../../commands/types.js\";\nimport type { SandboxConfig } from \"../../../sandbox/index.js\";\nimport type { EventStore } from \"../../../events/index.js\";\nimport type { VaultManager } from \"../../../vault/index.js\";\nimport type { InMemorySessionViewTokenStore } from \"../session-view/portal.js\";\nimport type { TokenRecord } from \"../types.js\";\nimport type { InMemoryAdminTokenStore } from \"./portal.js\";\n\nexport interface AdminRuntimeBridge {\n getRunningSessions(): RunningSession[];\n switchConversationModel(address: OfficeAddress, provider: string, model: string): boolean;\n refreshConversationEnvironment(address: OfficeAddress): boolean;\n refreshAllConversations(): { busy: OfficeAddress[] };\n}\n\nexport interface AdminServices {\n vaultManager: VaultManager;\n linkTokenStore: LinkTokenStoreLike;\n sessionViewTokenStore?: InMemorySessionViewTokenStore;\n adminTokenStore: InMemoryAdminTokenStore;\n portalBaseUrl?: string;\n workspace?: Workspace;\n /** Office-confined event store factory; Admin never reads event files directly. */\n eventStore?: (office: Office) => EventStore;\n sandbox?: SandboxConfig;\n runtime?: AdminRuntimeBridge;\n botsByPlatform?: Partial<Record<PlatformName, MessagingBot>>;\n}\n\nexport interface EventSummary {\n name: string;\n size: number;\n mtimeMs: number;\n type: string | null;\n /** Owning office, from the store — authoritative even when the payload is unparseable. */\n officePlatform: string;\n officeConversationId: string;\n platform: string | null;\n conversationId: string | null;\n text: string | null;\n at: string | null;\n schedule: string | null;\n timezone: string | null;\n}\n\nexport interface AdminToken extends TokenRecord {\n platform: PlatformName;\n platformUserId: string;\n platformUserName?: string;\n /** The conversation where /admin was invoked. Default scope for the 3 sub-pages. */\n conversationId: string;\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Server } from "node:http";
|
|
2
2
|
import type { MessagingBot, PlatformName } from "../../adapter.js";
|
|
3
3
|
import type { SandboxConfig } from "../../sandbox/index.js";
|
|
4
|
+
import { type EventScheduleSink } from "../../events/index.js";
|
|
4
5
|
import type { VaultManager } from "../../vault/index.js";
|
|
5
6
|
import { type AdminRuntimeBridge } from "./admin/portal.js";
|
|
6
7
|
import type { InMemoryAdminTokenStore } from "./admin/portal.js";
|
|
@@ -23,6 +24,8 @@ interface StartWebServerOptions {
|
|
|
23
24
|
runtime?: AdminRuntimeBridge;
|
|
24
25
|
sandbox?: SandboxConfig;
|
|
25
26
|
botsByPlatform?: Partial<Record<PlatformName, MessagingBot>>;
|
|
27
|
+
/** Scheduler notified by Admin event deletes; resolved lazily (starts after bots). */
|
|
28
|
+
eventScheduler?: () => EventScheduleSink | undefined;
|
|
26
29
|
};
|
|
27
30
|
githubWebhook?: GithubWebhookOptions;
|
|
28
31
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/adapters/web/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AACjG,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/adapters/web/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AACjG,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACjF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAGjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAEL,KAAK,6BAA6B,EACnC,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,KAAK,EAAU,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAA8B,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE7F,UAAU,qBAAqB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,sBAAsB,CAAC;IACvC,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,QAAQ,CAAC;IACjB,qBAAqB,CAAC,EAAE,6BAA6B,CAAC;IACtD,sBAAsB,CAAC,EAAE,6BAA6B,CAAC;IACvD,YAAY,CAAC,EAAE;QACb,eAAe,EAAE,uBAAuB,CAAC;QACzC,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,OAAO,CAAC,EAAE,kBAAkB,CAAC;QAC7B,OAAO,CAAC,EAAE,aAAa,CAAC;QACxB,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;QAC7D,sFAAsF;QACtF,cAAc,CAAC,EAAE,MAAM,iBAAiB,GAAG,SAAS,CAAC;KACtD,CAAC;IACF,aAAa,CAAC,EAAE,oBAAoB,CAAC;CACtC;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,CA0FrE"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createServer } from "node:http";
|
|
2
2
|
import { resolveLinkBaseUrl } from "../../config.js";
|
|
3
3
|
import * as log from "../../log.js";
|
|
4
|
-
import {
|
|
4
|
+
import { OfficeEventStore } from "../../events/index.js";
|
|
5
5
|
import { handleAdminRequest } from "./admin/portal.js";
|
|
6
6
|
import { createLoginRequestHandler } from "./login/portal.js";
|
|
7
7
|
import { requestBaseUrl } from "./portal-shell.js";
|
|
@@ -9,11 +9,9 @@ import { handleSessionViewRequest, } from "./session-view/portal.js";
|
|
|
9
9
|
import { handleGithubWebhookRequest } from "../github/webhook.js";
|
|
10
10
|
export function startWebServer(options) {
|
|
11
11
|
const loginHandler = createLoginRequestHandler(options.linkTokenStore, options.vaultManager, options.notify);
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
const adminEventStore = options.adminOptions?.
|
|
15
|
-
? HostEventStore.fromWorkspaceDir(options.adminOptions.workspace.root)
|
|
16
|
-
: undefined;
|
|
12
|
+
// The admin portal consumes office-confined event stores instead of
|
|
13
|
+
// re-parsing event files off disk.
|
|
14
|
+
const adminEventStore = (office) => new OfficeEventStore(office, options.adminOptions?.eventScheduler?.());
|
|
17
15
|
const server = createServer(async (req, res) => {
|
|
18
16
|
try {
|
|
19
17
|
const url = new URL(req.url ?? "/", requestBaseUrl(req));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/adapters/web/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA0D,MAAM,WAAW,CAAC;AAEjG,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AAEpC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/adapters/web/server.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport type { MessagingBot, PlatformName } from \"../../adapter.js\";\nimport { resolveLinkBaseUrl } from \"../../config.js\";\nimport * as log from \"../../log.js\";\nimport type { SandboxConfig } from \"../../sandbox/index.js\";\nimport { OfficeEventStore, type EventScheduleSink } from \"../../events/index.js\";\nimport type { VaultManager } from \"../../vault/index.js\";\nimport { handleAdminRequest, type AdminRuntimeBridge } from \"./admin/portal.js\";\nimport type { InMemoryAdminTokenStore } from \"./admin/portal.js\";\nimport { createLoginRequestHandler } from \"./login/portal.js\";\nimport { requestBaseUrl } from \"./portal-shell.js\";\nimport type { InMemoryLinkTokenStore } from \"./login/portal.js\";\nimport type { NotifyFn } from \"./login/types.js\";\nimport {\n handleSessionViewRequest,\n type SessionViewInteractiveOptions,\n} from \"./session-view/portal.js\";\nimport type { InMemorySessionViewTokenStore } from \"./session-view/portal.js\";\nimport type { Office, Workspace } from \"../../office/types.js\";\nimport { handleGithubWebhookRequest, type GithubWebhookOptions } from \"../github/webhook.js\";\n\ninterface StartWebServerOptions {\n port: number;\n linkTokenStore: InMemoryLinkTokenStore;\n vaultManager: VaultManager;\n notify: NotifyFn;\n sessionViewTokenStore?: InMemorySessionViewTokenStore;\n sessionViewInteractive?: SessionViewInteractiveOptions;\n adminOptions?: {\n adminTokenStore: InMemoryAdminTokenStore;\n workspace?: Workspace;\n runtime?: AdminRuntimeBridge;\n sandbox?: SandboxConfig;\n botsByPlatform?: Partial<Record<PlatformName, MessagingBot>>;\n /** Scheduler notified by Admin event deletes; resolved lazily (starts after bots). */\n eventScheduler?: () => EventScheduleSink | undefined;\n };\n githubWebhook?: GithubWebhookOptions;\n}\n\nexport function startWebServer(options: StartWebServerOptions): Server {\n const loginHandler = createLoginRequestHandler(\n options.linkTokenStore,\n options.vaultManager,\n options.notify,\n );\n\n // The admin portal consumes office-confined event stores instead of\n // re-parsing event files off disk.\n const adminEventStore = (office: Office) =>\n new OfficeEventStore(office, options.adminOptions?.eventScheduler?.());\n\n const server = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n try {\n const url = new URL(req.url ?? \"/\", requestBaseUrl(req));\n\n if (req.method === \"GET\" && url.pathname === \"/health\") {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n\n if (\n options.githubWebhook &&\n (await handleGithubWebhookRequest(req, res, url, options.githubWebhook))\n ) {\n return;\n }\n\n const adminOptions = options.adminOptions;\n if (\n adminOptions?.adminTokenStore &&\n (await handleAdminRequest(req, res, url, {\n vaultManager: options.vaultManager,\n linkTokenStore: options.linkTokenStore,\n sessionViewTokenStore: options.sessionViewTokenStore,\n adminTokenStore: adminOptions.adminTokenStore,\n portalBaseUrl: resolveLinkBaseUrl() ?? undefined,\n workspace: adminOptions.workspace,\n eventStore: adminEventStore,\n runtime: adminOptions.runtime,\n sandbox: adminOptions.sandbox,\n botsByPlatform: adminOptions.botsByPlatform,\n }))\n ) {\n return;\n }\n\n if (\n await handleSessionViewRequest(\n req,\n res,\n url,\n options.sessionViewTokenStore,\n options.sessionViewInteractive,\n )\n ) {\n return;\n }\n\n if (loginHandler(req, res, url)) return;\n\n res.writeHead(404);\n res.end();\n } catch (err) {\n log.logWarning(\"Web server request error\", err instanceof Error ? err.message : String(err));\n if (!res.headersSent) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n }\n res.end(JSON.stringify({ error: \"Internal server error\" }));\n }\n });\n\n const bindHost = resolveLinkBaseUrl() ? undefined : \"127.0.0.1\";\n server.listen(options.port, bindHost, () => {\n log.logInfo(`Web server listening on ${bindHost ?? \"0.0.0.0\"}:${options.port}`);\n if (!resolveLinkBaseUrl()) {\n log.logWarning(\n \"MIKAN_LINK_URL is not set — bound to 127.0.0.1 and OAuth redirect_uri will be \" +\n \"derived from request headers (Host / X-Forwarded-*). Set \" +\n \"MIKAN_LINK_URL=https://your-host.example.com for production.\",\n );\n }\n });\n\n server.on(\"error\", (err) => {\n log.logWarning(\"Web server error\", err.message);\n });\n\n return server;\n}\n"]}
|
package/dist/cli/boot.js
CHANGED
|
@@ -78,7 +78,7 @@ export function helpText() {
|
|
|
78
78
|
return (bootCommand().helpInformation() +
|
|
79
79
|
`
|
|
80
80
|
Commands:
|
|
81
|
-
mikan office <list|claim>
|
|
81
|
+
mikan office <list|claim|migrate-openconnector|migrate-events> Inspect offices, claim legacy directories, migrate legacy state.
|
|
82
82
|
mikan sessions migrate Migrate legacy sessions (stop the daemon first).
|
|
83
83
|
mikan env Show environment-variable inventory.
|
|
84
84
|
mikan onboard Interactive first-run setup.
|
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,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAI/F,MAAM,WAAW,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAU,CAAC;AAW3D,SAAS,WAAW;IAClB,OAAO,UAAU,CAAC,OAAO,CAAC;SACvB,WAAW,CAAC,kCAAkC,CAAC;SAC/C,UAAU,CAAC,KAAK,CAAC;SACjB,QAAQ,CAAC,wBAAwB,EAAE,sDAAsD,CAAC;SAC1F,MAAM,CAAC,mBAAmB,EAAE,qCAAqC,EAAE,aAAa,CAAC;SACjF,MAAM,CACL,kBAAkB,EAClB,iEAAiE,EACjE,aAAa,CACd;SACA,MAAM,CAAC,sBAAsB,EAAE,2CAA2C,EAAE,aAAa,CAAC;SAC1F,MAAM,CAAC,WAAW,EAAE,mDAAmD,CAAC;SACxE,MAAM,CAAC,eAAe,EAAE,eAAe,CAAC;SACxC,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC;SAC7B,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAI,GAAa,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAiC,CAAC;IAC9D,4EAA4E;IAC5E,+CAA+C;IAC/C,MAAM,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;IAC3C,MAAM,aAAa,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACnF,MAAM,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;IACzC,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IACnC,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,EAAE,EAAE,YAAY,CAAC;QACnF,QAAQ;QACR,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC;QAChF,kBAAkB,EAAE,aAAa,KAAK,SAAS;QAC/C,OAAO,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,UAAU,CAAC;QAClF,eAAe;KAChB,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,IAAc;IACpC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;IACnC,OAAO;QACL,IAAI;QACJ,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,QAAQ;QACR,UAAU,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC;QACvC,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;KAC1B,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,OAAoB,EAAE,YAAqB;IAC3D,IAAI,OAAO,CAAC,IAAI;QAAE,OAAO,MAAM,CAAC;IAChC,IAAI,OAAO,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IACtC,IAAI,YAAY,IAAI,OAAO,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IACtD,IAAI,OAAO,CAAC,QAAQ;QAAE,OAAO,UAAU,CAAC;IACxC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,OAAO,CACL,WAAW,EAAE,CAAC,eAAe,EAAE;QAC/B;;;;;;;;EAQF,eAAe,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;sCACQ,CACnC,CAAC;AACJ,CAAC","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: `office`, `sessions`, `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 { BootPlan } from \"./types.js\";\nimport { cliCommand, defaultStateDir, nonEmptyValue, resolveStateDir } from \"./arg-grammar.js\";\n\nexport type { BootPlan } from \"./types.js\";\n\nconst SUBCOMMANDS = [\"office\", \"sessions\", \"env\"] as const;\n\ninterface BootOptions {\n stateDir?: string;\n sandbox?: string;\n download?: string;\n help?: boolean;\n version?: boolean;\n onboard?: boolean;\n}\n\nfunction bootCommand() {\n return cliCommand(\"mikan\")\n .description(\"Multi-platform chat agent daemon\")\n .helpOption(false)\n .argument(\"[working-directory...]\", \"Workspace directory (default: <state-dir>/workspace)\")\n .option(\"--state-dir <dir>\", \"State directory (default: ~/.mikan)\", nonEmptyValue)\n .option(\n \"--sandbox <spec>\",\n \"host | container:<name> | image:<image[:tag]> | cloudflare:<id>\",\n nonEmptyValue,\n )\n .option(\"--download <channel>\", \"Dump a Slack channel's history, then exit\", nonEmptyValue)\n .option(\"--onboard\", \"Interactive first-run setup (also: mikan onboard)\")\n .option(\"-v, --version\", \"Print version\")\n .option(\"-V\", \"Print version\")\n .option(\"-h, --help\", \"Show help\");\n}\n\nexport function resolveBoot(args: string[] = process.argv.slice(2)): BootPlan {\n const routed = subcommandPlan(args);\n if (routed) return routed;\n\n const command = bootCommand();\n command.parse(args, { from: \"user\" });\n const options = command.opts<BootOptions & { V?: boolean }>();\n // `onboard` counts as a subcommand only in first position; anywhere else it\n // is an ordinary working-directory positional.\n const onboardFirst = args[0] === \"onboard\";\n const workingDirArg = (onboardFirst ? command.args.slice(1) : command.args).at(-1);\n const downloadChannel = options.download;\n const sandboxArg = options.sandbox;\n const stateDir = resolveStateDir(args);\n return {\n mode: bootMode({ ...options, version: options.version || options.V }, onboardFirst),\n stateDir,\n workingDir: workingDirArg ? resolve(workingDirArg) : join(stateDir, \"workspace\"),\n workingDirExplicit: workingDirArg !== undefined,\n sandbox: sandboxArg === undefined ? { type: \"host\" } : parseSandboxArg(sandboxArg),\n downloadChannel,\n };\n}\n\nfunction subcommandPlan(args: string[]): BootPlan | undefined {\n const mode = SUBCOMMANDS.find((name) => name === args[0]);\n if (!mode) return undefined;\n const stateDir = defaultStateDir();\n return {\n mode,\n ...(mode === \"office\" ? { officeArgs: args.slice(1) } : {}),\n ...(mode === \"sessions\" ? { sessionsArgs: args.slice(1) } : {}),\n stateDir,\n workingDir: join(stateDir, \"workspace\"),\n workingDirExplicit: false,\n sandbox: { type: \"host\" },\n };\n}\n\nfunction bootMode(options: BootOptions, onboardFirst: boolean): BootPlan[\"mode\"] {\n if (options.help) return \"help\";\n if (options.version) return \"version\";\n if (onboardFirst || options.onboard) return \"onboard\";\n if (options.download) return \"download\";\n return \"run\";\n}\n\nexport function helpText(): string {\n return (\n bootCommand().helpInformation() +\n `\nCommands:\n mikan office <list|claim>
|
|
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: `office`, `sessions`, `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 { BootPlan } from \"./types.js\";\nimport { cliCommand, defaultStateDir, nonEmptyValue, resolveStateDir } from \"./arg-grammar.js\";\n\nexport type { BootPlan } from \"./types.js\";\n\nconst SUBCOMMANDS = [\"office\", \"sessions\", \"env\"] as const;\n\ninterface BootOptions {\n stateDir?: string;\n sandbox?: string;\n download?: string;\n help?: boolean;\n version?: boolean;\n onboard?: boolean;\n}\n\nfunction bootCommand() {\n return cliCommand(\"mikan\")\n .description(\"Multi-platform chat agent daemon\")\n .helpOption(false)\n .argument(\"[working-directory...]\", \"Workspace directory (default: <state-dir>/workspace)\")\n .option(\"--state-dir <dir>\", \"State directory (default: ~/.mikan)\", nonEmptyValue)\n .option(\n \"--sandbox <spec>\",\n \"host | container:<name> | image:<image[:tag]> | cloudflare:<id>\",\n nonEmptyValue,\n )\n .option(\"--download <channel>\", \"Dump a Slack channel's history, then exit\", nonEmptyValue)\n .option(\"--onboard\", \"Interactive first-run setup (also: mikan onboard)\")\n .option(\"-v, --version\", \"Print version\")\n .option(\"-V\", \"Print version\")\n .option(\"-h, --help\", \"Show help\");\n}\n\nexport function resolveBoot(args: string[] = process.argv.slice(2)): BootPlan {\n const routed = subcommandPlan(args);\n if (routed) return routed;\n\n const command = bootCommand();\n command.parse(args, { from: \"user\" });\n const options = command.opts<BootOptions & { V?: boolean }>();\n // `onboard` counts as a subcommand only in first position; anywhere else it\n // is an ordinary working-directory positional.\n const onboardFirst = args[0] === \"onboard\";\n const workingDirArg = (onboardFirst ? command.args.slice(1) : command.args).at(-1);\n const downloadChannel = options.download;\n const sandboxArg = options.sandbox;\n const stateDir = resolveStateDir(args);\n return {\n mode: bootMode({ ...options, version: options.version || options.V }, onboardFirst),\n stateDir,\n workingDir: workingDirArg ? resolve(workingDirArg) : join(stateDir, \"workspace\"),\n workingDirExplicit: workingDirArg !== undefined,\n sandbox: sandboxArg === undefined ? { type: \"host\" } : parseSandboxArg(sandboxArg),\n downloadChannel,\n };\n}\n\nfunction subcommandPlan(args: string[]): BootPlan | undefined {\n const mode = SUBCOMMANDS.find((name) => name === args[0]);\n if (!mode) return undefined;\n const stateDir = defaultStateDir();\n return {\n mode,\n ...(mode === \"office\" ? { officeArgs: args.slice(1) } : {}),\n ...(mode === \"sessions\" ? { sessionsArgs: args.slice(1) } : {}),\n stateDir,\n workingDir: join(stateDir, \"workspace\"),\n workingDirExplicit: false,\n sandbox: { type: \"host\" },\n };\n}\n\nfunction bootMode(options: BootOptions, onboardFirst: boolean): BootPlan[\"mode\"] {\n if (options.help) return \"help\";\n if (options.version) return \"version\";\n if (onboardFirst || options.onboard) return \"onboard\";\n if (options.download) return \"download\";\n return \"run\";\n}\n\nexport function helpText(): string {\n return (\n bootCommand().helpInformation() +\n `\nCommands:\n mikan office <list|claim|migrate-openconnector|migrate-events> Inspect offices, claim legacy directories, migrate legacy state.\n mikan sessions migrate Migrate legacy sessions (stop the daemon first).\n mikan env Show environment-variable inventory.\n mikan onboard Interactive first-run setup.\n\nEnvironment (platform tokens select which chat adapters start):\n${envSummaryLines().join(\"\\n\")}\nRun mikan env for the full inventory.`\n );\n}\n"]}
|
package/dist/cli/office.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"office.d.ts","sourceRoot":"","sources":["../../src/cli/office.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"office.d.ts","sourceRoot":"","sources":["../../src/cli/office.ts"],"names":[],"mappings":"AA+BA,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAqDvD"}
|
package/dist/cli/office.js
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
*
|
|
4
4
|
* mikan office list [--state-dir <dir>] [--workspace <dir>]
|
|
5
5
|
* mikan office claim <conversationId> <platform> [--state-dir <dir>] [--workspace <dir>]
|
|
6
|
+
* mikan office migrate-openconnector [--state-dir <dir>] [--workspace <dir>]
|
|
7
|
+
* mikan office migrate-events [--state-dir <dir>] [--workspace <dir>]
|
|
8
|
+
*
|
|
9
|
+
* `migrate-events` moves legacy `<workspace>/events/*.json` records into the
|
|
10
|
+
* owning office's host-only state (`conversations/<key>/events/`). Records
|
|
11
|
+
* without an attributable, registered owner stay put and are reported. Run it
|
|
12
|
+
* with the daemon stopped.
|
|
13
|
+
*
|
|
14
|
+
* `migrate-openconnector` converts legacy per-office
|
|
15
|
+
* `open-connector-runtime-token.json` files into ordinary conversation
|
|
16
|
+
* `mcpServers` entries for the current `OPENCONNECTOR_ENDPOINT`. Run it with
|
|
17
|
+
* the daemon stopped.
|
|
6
18
|
*
|
|
7
19
|
* `claim` records which platform owns a legacy raw-id conversation directory
|
|
8
20
|
* when several platforms are enabled and boot cannot infer ownership. The
|
|
@@ -12,6 +24,10 @@
|
|
|
12
24
|
import { join, resolve } from "node:path";
|
|
13
25
|
import { assertPlatformName, OfficeRegistry } from "../office/index.js";
|
|
14
26
|
import { cliCommand, commandExitCode, nonEmptyValue, resolveStateDir } from "./arg-grammar.js";
|
|
27
|
+
import { readEnv } from "../env-manifest.js";
|
|
28
|
+
import { migrateLegacyOpenConnectorTokens } from "../harness/open-connector.js";
|
|
29
|
+
import { migrateLegacyWorkspaceEvents } from "../events/index.js";
|
|
30
|
+
import { createWorkspace } from "../office/index.js";
|
|
15
31
|
export function runOfficeCommand(argv) {
|
|
16
32
|
const command = cliCommand("mikan office")
|
|
17
33
|
.description("Inspect conversation offices and claim legacy directories")
|
|
@@ -35,6 +51,22 @@ export function runOfficeCommand(argv) {
|
|
|
35
51
|
platform,
|
|
36
52
|
]);
|
|
37
53
|
});
|
|
54
|
+
command
|
|
55
|
+
.command("migrate-openconnector")
|
|
56
|
+
.description("Convert legacy OpenConnector token files into MCP settings (stop the daemon first)")
|
|
57
|
+
.action(() => {
|
|
58
|
+
const stateDir = resolveStateDir(argv);
|
|
59
|
+
const { workspace } = command.opts();
|
|
60
|
+
result = migrateOpenConnector(stateDir, workspace ? resolve(workspace) : join(stateDir, "workspace"));
|
|
61
|
+
});
|
|
62
|
+
command
|
|
63
|
+
.command("migrate-events")
|
|
64
|
+
.description("Move legacy workspace event files into office state (stop the daemon first)")
|
|
65
|
+
.action(() => {
|
|
66
|
+
const stateDir = resolveStateDir(argv);
|
|
67
|
+
const { workspace } = command.opts();
|
|
68
|
+
result = migrateEvents(stateDir, workspace ? resolve(workspace) : join(stateDir, "workspace"));
|
|
69
|
+
});
|
|
38
70
|
try {
|
|
39
71
|
command.parse(argv, { from: "user" });
|
|
40
72
|
return result;
|
|
@@ -60,6 +92,40 @@ function listOffices(stateDir) {
|
|
|
60
92
|
}
|
|
61
93
|
return 0;
|
|
62
94
|
}
|
|
95
|
+
function migrateEvents(stateDir, workspaceRoot) {
|
|
96
|
+
try {
|
|
97
|
+
const report = migrateLegacyWorkspaceEvents(createWorkspace({ root: workspaceRoot, stateDir }));
|
|
98
|
+
console.log(`Migrated ${report.migrated.length} event file(s) into office state.`);
|
|
99
|
+
for (const entry of report.migrated)
|
|
100
|
+
console.log(` ${entry.filename} -> ${entry.key}`);
|
|
101
|
+
for (const entry of report.skipped)
|
|
102
|
+
console.log(` skipped ${entry.filename}: ${entry.reason}`);
|
|
103
|
+
return 0;
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
107
|
+
return 1;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function migrateOpenConnector(stateDir, workspaceRoot) {
|
|
111
|
+
const endpoint = readEnv("OPENCONNECTOR_ENDPOINT");
|
|
112
|
+
if (!endpoint) {
|
|
113
|
+
console.error("OPENCONNECTOR_ENDPOINT is not set; nothing to migrate to.");
|
|
114
|
+
return 1;
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
const report = migrateLegacyOpenConnectorTokens(stateDir, endpoint, workspaceRoot);
|
|
118
|
+
console.log(`Migrated ${report.migrated.length} office token file(s) into settings.json.`);
|
|
119
|
+
for (const entry of report.skipped) {
|
|
120
|
+
console.log(` skipped ${entry.key}: ${entry.reason}`);
|
|
121
|
+
}
|
|
122
|
+
return 0;
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
126
|
+
return 1;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
63
129
|
function claimOffice(stateDir, workspaceRoot, rest) {
|
|
64
130
|
const [rawConversationId, platform] = rest;
|
|
65
131
|
if (!rawConversationId || !platform)
|
package/dist/cli/office.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"office.js","sourceRoot":"","sources":["../../src/cli/office.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `mikan office` — inspect and claim conversation offices from the CLI.\n *\n * mikan office list [--state-dir <dir>] [--workspace <dir>]\n * mikan office claim <conversationId> <platform> [--state-dir <dir>] [--workspace <dir>]\n *\n * `claim` records which platform owns a legacy raw-id conversation directory\n * when several platforms are enabled and boot cannot infer ownership. The\n * daemon performs the actual move on its next start. Run it with the daemon\n * stopped so the directory is not moving under a live runtime.\n */\nimport { join, resolve } from \"node:path\";\nimport { assertPlatformName, OfficeRegistry } from \"../office/index.js\";\nimport { cliCommand, commandExitCode, nonEmptyValue, resolveStateDir } from \"./arg-grammar.js\";\n\nexport function runOfficeCommand(argv: string[]): number {\n const command = cliCommand(\"mikan office\")\n .description(\"Inspect conversation offices and claim legacy directories\")\n .option(\"--state-dir <dir>\", \"State directory\", nonEmptyValue)\n .option(\"--workspace <dir>\", \"Workspace directory\", nonEmptyValue);\n let result = 1;\n command\n .command(\"list\")\n .description(\"List registered offices\")\n .action(() => {\n result = listOffices(resolveStateDir(argv));\n });\n command\n .command(\"claim <conversationId> <platform>\")\n .description(\"Claim a legacy directory (stop the daemon first)\")\n .action((conversationId: string, platform: string) => {\n const stateDir = resolveStateDir(argv);\n const { workspace } = command.opts<{ workspace?: string }>();\n result = claimOffice(stateDir, workspace ? resolve(workspace) : join(stateDir, \"workspace\"), [\n conversationId,\n platform,\n ]);\n });\n try {\n command.parse(argv, { from: \"user\" });\n return result;\n } catch (error) {\n return commandExitCode(error, command);\n }\n}\n\nfunction listOffices(stateDir: string): number {\n const state = new OfficeRegistry(stateDir).getState();\n console.log(`Enabled platforms: ${state.enabledPlatforms.join(\", \") || \"(none)\"}`);\n console.log(`Offices (${state.offices.length}):`);\n for (const office of state.offices) {\n console.log(` ${office.platform} ${office.conversationId}`);\n }\n const pending = state.migrations.filter((record) => record.status !== \"committed\");\n if (pending.length > 0) {\n console.log(`Pending migrations (${pending.length}):`);\n for (const record of pending) {\n const error = record.error ? ` (${record.error})` : \"\";\n console.log(` ${record.status} ${record.rawConversationId}${error}`);\n }\n }\n return 0;\n}\n\nfunction claimOffice(stateDir: string, workspaceRoot: string, rest: string[]): number {\n const [rawConversationId, platform] = rest;\n if (!rawConversationId || !platform) return 1;\n try {\n const record = new OfficeRegistry(stateDir).prepareLegacyMigration({\n rawConversationId,\n sourceDir: join(workspaceRoot, rawConversationId),\n workspaceRoot,\n ownerPlatform: assertPlatformName(platform),\n });\n console.log(\n `Claimed ${record.rawConversationId} for ${record.ownerPlatform}; ` +\n \"the daemon migrates the directory on its next start.\",\n );\n return 0;\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n return 1;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"office.js","sourceRoot":"","sources":["../../src/cli/office.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `mikan office` — inspect and claim conversation offices from the CLI.\n *\n * mikan office list [--state-dir <dir>] [--workspace <dir>]\n * mikan office claim <conversationId> <platform> [--state-dir <dir>] [--workspace <dir>]\n * mikan office migrate-openconnector [--state-dir <dir>] [--workspace <dir>]\n * mikan office migrate-events [--state-dir <dir>] [--workspace <dir>]\n *\n * `migrate-events` moves legacy `<workspace>/events/*.json` records into the\n * owning office's host-only state (`conversations/<key>/events/`). Records\n * without an attributable, registered owner stay put and are reported. Run it\n * with the daemon stopped.\n *\n * `migrate-openconnector` converts legacy per-office\n * `open-connector-runtime-token.json` files into ordinary conversation\n * `mcpServers` entries for the current `OPENCONNECTOR_ENDPOINT`. Run it with\n * the daemon stopped.\n *\n * `claim` records which platform owns a legacy raw-id conversation directory\n * when several platforms are enabled and boot cannot infer ownership. The\n * daemon performs the actual move on its next start. Run it with the daemon\n * stopped so the directory is not moving under a live runtime.\n */\nimport { join, resolve } from \"node:path\";\nimport { assertPlatformName, OfficeRegistry } from \"../office/index.js\";\nimport { cliCommand, commandExitCode, nonEmptyValue, resolveStateDir } from \"./arg-grammar.js\";\nimport { readEnv } from \"../env-manifest.js\";\nimport { migrateLegacyOpenConnectorTokens } from \"../harness/open-connector.js\";\nimport { migrateLegacyWorkspaceEvents } from \"../events/index.js\";\nimport { createWorkspace } from \"../office/index.js\";\n\nexport function runOfficeCommand(argv: string[]): number {\n const command = cliCommand(\"mikan office\")\n .description(\"Inspect conversation offices and claim legacy directories\")\n .option(\"--state-dir <dir>\", \"State directory\", nonEmptyValue)\n .option(\"--workspace <dir>\", \"Workspace directory\", nonEmptyValue);\n let result = 1;\n command\n .command(\"list\")\n .description(\"List registered offices\")\n .action(() => {\n result = listOffices(resolveStateDir(argv));\n });\n command\n .command(\"claim <conversationId> <platform>\")\n .description(\"Claim a legacy directory (stop the daemon first)\")\n .action((conversationId: string, platform: string) => {\n const stateDir = resolveStateDir(argv);\n const { workspace } = command.opts<{ workspace?: string }>();\n result = claimOffice(stateDir, workspace ? resolve(workspace) : join(stateDir, \"workspace\"), [\n conversationId,\n platform,\n ]);\n });\n command\n .command(\"migrate-openconnector\")\n .description(\n \"Convert legacy OpenConnector token files into MCP settings (stop the daemon first)\",\n )\n .action(() => {\n const stateDir = resolveStateDir(argv);\n const { workspace } = command.opts<{ workspace?: string }>();\n result = migrateOpenConnector(\n stateDir,\n workspace ? resolve(workspace) : join(stateDir, \"workspace\"),\n );\n });\n command\n .command(\"migrate-events\")\n .description(\"Move legacy workspace event files into office state (stop the daemon first)\")\n .action(() => {\n const stateDir = resolveStateDir(argv);\n const { workspace } = command.opts<{ workspace?: string }>();\n result = migrateEvents(\n stateDir,\n workspace ? resolve(workspace) : join(stateDir, \"workspace\"),\n );\n });\n try {\n command.parse(argv, { from: \"user\" });\n return result;\n } catch (error) {\n return commandExitCode(error, command);\n }\n}\n\nfunction listOffices(stateDir: string): number {\n const state = new OfficeRegistry(stateDir).getState();\n console.log(`Enabled platforms: ${state.enabledPlatforms.join(\", \") || \"(none)\"}`);\n console.log(`Offices (${state.offices.length}):`);\n for (const office of state.offices) {\n console.log(` ${office.platform} ${office.conversationId}`);\n }\n const pending = state.migrations.filter((record) => record.status !== \"committed\");\n if (pending.length > 0) {\n console.log(`Pending migrations (${pending.length}):`);\n for (const record of pending) {\n const error = record.error ? ` (${record.error})` : \"\";\n console.log(` ${record.status} ${record.rawConversationId}${error}`);\n }\n }\n return 0;\n}\n\nfunction migrateEvents(stateDir: string, workspaceRoot: string): number {\n try {\n const report = migrateLegacyWorkspaceEvents(createWorkspace({ root: workspaceRoot, stateDir }));\n console.log(`Migrated ${report.migrated.length} event file(s) into office state.`);\n for (const entry of report.migrated) console.log(` ${entry.filename} -> ${entry.key}`);\n for (const entry of report.skipped) console.log(` skipped ${entry.filename}: ${entry.reason}`);\n return 0;\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n return 1;\n }\n}\n\nfunction migrateOpenConnector(stateDir: string, workspaceRoot: string): number {\n const endpoint = readEnv(\"OPENCONNECTOR_ENDPOINT\");\n if (!endpoint) {\n console.error(\"OPENCONNECTOR_ENDPOINT is not set; nothing to migrate to.\");\n return 1;\n }\n try {\n const report = migrateLegacyOpenConnectorTokens(stateDir, endpoint, workspaceRoot);\n console.log(`Migrated ${report.migrated.length} office token file(s) into settings.json.`);\n for (const entry of report.skipped) {\n console.log(` skipped ${entry.key}: ${entry.reason}`);\n }\n return 0;\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n return 1;\n }\n}\n\nfunction claimOffice(stateDir: string, workspaceRoot: string, rest: string[]): number {\n const [rawConversationId, platform] = rest;\n if (!rawConversationId || !platform) return 1;\n try {\n const record = new OfficeRegistry(stateDir).prepareLegacyMigration({\n rawConversationId,\n sourceDir: join(workspaceRoot, rawConversationId),\n workspaceRoot,\n ownerPlatform: assertPlatformName(platform),\n });\n console.log(\n `Claimed ${record.rawConversationId} for ${record.ownerPlatform}; ` +\n \"the daemon migrates the directory on its next start.\",\n );\n return 0;\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n return 1;\n }\n}\n"]}
|
package/dist/config.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ export declare class MissingGlobalSettingsError extends Error {
|
|
|
2
2
|
readonly settingsPath: string;
|
|
3
3
|
constructor(settingsPath: string);
|
|
4
4
|
}
|
|
5
|
-
export type { AgentConfig, SandboxSettings
|
|
6
|
-
import type { AgentConfig
|
|
5
|
+
export type { AgentConfig, SandboxSettings } from "./types.js";
|
|
6
|
+
import type { AgentConfig } from "./types.js";
|
|
7
7
|
import type { McpServerConfig } from "./harness/types.js";
|
|
8
8
|
import type { OnboardLlmChoice } from "./types.js";
|
|
9
9
|
import type { Office } from "./office/index.js";
|
|
@@ -65,13 +65,16 @@ export declare function loadScopeMcpServers(office: Office): {
|
|
|
65
65
|
conversation: Record<string, McpServerConfig>;
|
|
66
66
|
};
|
|
67
67
|
/**
|
|
68
|
-
* The conversation's own
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
* (see resolveEffectiveWorkspace), preserving today's read-write behavior for
|
|
72
|
-
* every office that predates this setting.
|
|
68
|
+
* The conversation's own visibility override, or null when it follows the
|
|
69
|
+
* platform. Only "private" can be stored: an operator may narrow a public
|
|
70
|
+
* channel, never widen a private one (see ADR 0008).
|
|
73
71
|
*/
|
|
74
|
-
export declare function
|
|
75
|
-
export declare function
|
|
76
|
-
|
|
72
|
+
export declare function loadOfficeVisibilityOverride(office: Office): "private" | null;
|
|
73
|
+
export declare function setOfficeVisibilityOverride(office: Office, visibility: "private" | null): void;
|
|
74
|
+
/**
|
|
75
|
+
* Legacy door-policy override kept readable only so the observation period
|
|
76
|
+
* can report which offices still declare `full`; it no longer changes the
|
|
77
|
+
* projection (ADR 0008).
|
|
78
|
+
*/
|
|
79
|
+
export declare function loadLegacyFullOverride(office: Office): boolean;
|
|
77
80
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAUA,qBAAa,0BAA2B,SAAQ,KAAK;aACvB,YAAY,EAAE,MAAM;IAAhD,YAA4B,YAAY,EAAE,MAAM,EAG/C;CACF;AAED,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAUA,qBAAa,0BAA2B,SAAQ,KAAK;aACvB,YAAY,EAAE,MAAM;IAAhD,YAA4B,YAAY,EAAE,MAAM,EAG/C;CACF;AAED,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,YAAY,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AA6OhD,wBAAgB,kBAAkB,IAAI,WAAW,CAEhD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA6B/D;AAiBD,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEzE;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAcpF;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAiBvE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAInE;AAED;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,IAAI,CAWN;AAOD,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAGrD;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAkBzF;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAIvD;AAiFD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAEtE;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAE5F;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG;IACnD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACxC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC/C,CAKA;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAE7E;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI,CAa9F;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAG9D"}
|
package/dist/config.js
CHANGED
|
@@ -29,11 +29,8 @@ const ONBOARD_SETTINGS = {
|
|
|
29
29
|
cpus: "2",
|
|
30
30
|
memory: "4g",
|
|
31
31
|
},
|
|
32
|
-
//
|
|
33
|
-
//
|
|
34
|
-
// workspace memory, private channels read it without writing, DMs stay
|
|
35
|
-
// isolated — see workspace-projection platformDerivedWorkspace).
|
|
36
|
-
// Deployments that predate this keep their explicit isolated setting.
|
|
32
|
+
// Office visibility is not a setting here: it follows the platform
|
|
33
|
+
// conversation type (see office/projection resolveOfficeVisibility).
|
|
37
34
|
defaultSharedVault: "",
|
|
38
35
|
},
|
|
39
36
|
};
|
|
@@ -57,6 +54,14 @@ const SettingsFileSchema = Type.Object({
|
|
|
57
54
|
slack: Type.Optional(Type.Object({
|
|
58
55
|
replyMode: Type.Optional(Type.Union([Type.Literal("top-level"), Type.Literal("thread")])),
|
|
59
56
|
})),
|
|
57
|
+
/**
|
|
58
|
+
* Conversation-only office policy. `visibility: "private"` marks a
|
|
59
|
+
* platform-public conversation as private; nothing can widen visibility
|
|
60
|
+
* beyond what the platform grants, so "public" is never stored here.
|
|
61
|
+
*/
|
|
62
|
+
office: Type.Optional(Type.Object({
|
|
63
|
+
visibility: Type.Optional(Type.Literal("private")),
|
|
64
|
+
})),
|
|
60
65
|
sandbox: Type.Optional(Type.Object({
|
|
61
66
|
cpus: Type.Optional(Type.String()),
|
|
62
67
|
memory: Type.Optional(Type.String()),
|
|
@@ -81,8 +86,9 @@ const SettingsFileSchema = Type.Object({
|
|
|
81
86
|
/**
|
|
82
87
|
* MCP servers, keyed by name. Merged per key across scopes: a conversation
|
|
83
88
|
* entry overrides (or, with `disabled: true`, turns off) the same-name
|
|
84
|
-
* global entry; other global entries stay available.
|
|
85
|
-
*
|
|
89
|
+
* global entry; other global entries stay available. `open-connector` is an
|
|
90
|
+
* ordinary entry that the host fills in from `OPENCONNECTOR_ENDPOINT` when
|
|
91
|
+
* neither scope declares it (see `src/harness/open-connector.ts`).
|
|
86
92
|
*/
|
|
87
93
|
mcpServers: Type.Optional(Type.Record(Type.String(), Type.Object({
|
|
88
94
|
command: Type.Optional(Type.String()),
|
|
@@ -280,8 +286,7 @@ export function resolveConversationSettings(office) {
|
|
|
280
286
|
const globalConfig = loadRawGlobalSettings();
|
|
281
287
|
const conversationConfig = normalizeSettingsConfig(loadSettingsFile(conversationSettingsPath(office)) ?? {});
|
|
282
288
|
// MCP servers merge per key: a conversation redefines or disables individual
|
|
283
|
-
// servers without losing the rest of the global set.
|
|
284
|
-
// removes the reserved open-connector entry before loading servers.
|
|
289
|
+
// servers without losing the rest of the global set.
|
|
285
290
|
const mcpServers = { ...globalConfig.mcpServers, ...conversationConfig.mcpServers };
|
|
286
291
|
// The sandbox group merges at the leaf level (see mergeSandboxSettings):
|
|
287
292
|
// a conversation that only sets sandbox.memory keeps the global sandbox.cpus.
|
|
@@ -369,6 +374,7 @@ function compactSettingsConfig(config) {
|
|
|
369
374
|
...(hasDefinedValue(config.sentry) ? { sentry: config.sentry } : {}),
|
|
370
375
|
...(hasDefinedValue(config.sandbox) ? { sandbox: config.sandbox } : {}),
|
|
371
376
|
...(hasDefinedValue(config.slack) ? { slack: config.slack } : {}),
|
|
377
|
+
...(hasDefinedValue(config.office) ? { office: config.office } : {}),
|
|
372
378
|
// An empty map means "all servers removed".
|
|
373
379
|
...(config.mcpServers !== undefined ? { mcpServers: config.mcpServers } : {}),
|
|
374
380
|
};
|
|
@@ -394,6 +400,9 @@ function patchSettingsConfig(existing, config) {
|
|
|
394
400
|
...existing.slack,
|
|
395
401
|
...config.slack,
|
|
396
402
|
},
|
|
403
|
+
// Office visibility has its own writer (setOfficeVisibilityOverride); the
|
|
404
|
+
// generic patch must not drop it.
|
|
405
|
+
...(existing.office !== undefined ? { office: existing.office } : {}),
|
|
397
406
|
// The portal edits the full MCP map, and
|
|
398
407
|
// a merge would make removing a server impossible.
|
|
399
408
|
...(config.mcpServers !== undefined ? { mcpServers: config.mcpServers } : {}),
|
|
@@ -437,55 +446,27 @@ export function loadScopeMcpServers(office) {
|
|
|
437
446
|
};
|
|
438
447
|
}
|
|
439
448
|
/**
|
|
440
|
-
* The conversation's own
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
* (see resolveEffectiveWorkspace), preserving today's read-write behavior for
|
|
444
|
-
* every office that predates this setting.
|
|
449
|
+
* The conversation's own visibility override, or null when it follows the
|
|
450
|
+
* platform. Only "private" can be stored: an operator may narrow a public
|
|
451
|
+
* channel, never widen a private one (see ADR 0008).
|
|
445
452
|
*/
|
|
446
|
-
export function
|
|
447
|
-
|
|
448
|
-
const sandbox = file?.sandbox;
|
|
449
|
-
if (sandbox?.workspace?.doorPolicy === "isolated")
|
|
450
|
-
return { doorPolicy: "isolated" };
|
|
451
|
-
if (sandbox?.workspace?.doorPolicy === "trusted") {
|
|
452
|
-
if (sandbox.workspace.layout === "full")
|
|
453
|
-
return { doorPolicy: "trusted", layout: "full" };
|
|
454
|
-
return {
|
|
455
|
-
doorPolicy: "trusted",
|
|
456
|
-
layout: "shared-support",
|
|
457
|
-
...(sandbox.workspace.visibility ? { visibility: sandbox.workspace.visibility } : {}),
|
|
458
|
-
};
|
|
459
|
-
}
|
|
460
|
-
if (sandbox?.image?.workspaceMount === "full")
|
|
461
|
-
return { doorPolicy: "trusted", layout: "full" };
|
|
462
|
-
if (sandbox?.image?.workspaceMount === "private") {
|
|
463
|
-
return { doorPolicy: "trusted", layout: "shared-support" };
|
|
464
|
-
}
|
|
465
|
-
return null;
|
|
453
|
+
export function loadOfficeVisibilityOverride(office) {
|
|
454
|
+
return loadSettingsFile(conversationSettingsPath(office))?.office?.visibility ?? null;
|
|
466
455
|
}
|
|
467
|
-
export function
|
|
468
|
-
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
|
|
456
|
+
export function setOfficeVisibilityOverride(office, visibility) {
|
|
457
|
+
const settingsPath = conversationSettingsPath(office);
|
|
458
|
+
const existing = loadSettingsFileForUpdate(settingsPath, {});
|
|
459
|
+
const { office: _previous, ...rest } = existing;
|
|
460
|
+
ensureDirExists(dirname(settingsPath));
|
|
461
|
+
atomicWritePrivateFile(settingsPath, JSON.stringify(compactSettingsConfig({ ...rest, ...(visibility ? { office: { visibility } } : {}) }), null, 2));
|
|
472
462
|
}
|
|
473
463
|
/**
|
|
474
|
-
*
|
|
475
|
-
*
|
|
476
|
-
*
|
|
477
|
-
* sets or removes the `workspace` group.
|
|
464
|
+
* Legacy door-policy override kept readable only so the observation period
|
|
465
|
+
* can report which offices still declare `full`; it no longer changes the
|
|
466
|
+
* projection (ADR 0008).
|
|
478
467
|
*/
|
|
479
|
-
function
|
|
480
|
-
const
|
|
481
|
-
|
|
482
|
-
const { workspace: _previous, image: _image, ...sandboxRest } = existing.sandbox ?? {};
|
|
483
|
-
const sandbox = {
|
|
484
|
-
...sandboxRest,
|
|
485
|
-
...(hasDefinedValue(image) ? { image } : {}),
|
|
486
|
-
...(choice ? { workspace: choice } : {}),
|
|
487
|
-
};
|
|
488
|
-
ensureDirExists(dirname(settingsPath));
|
|
489
|
-
atomicWritePrivateFile(settingsPath, JSON.stringify(compactSettingsConfig({ ...existing, sandbox }), null, 2));
|
|
468
|
+
export function loadLegacyFullOverride(office) {
|
|
469
|
+
const sandbox = loadSettingsFile(conversationSettingsPath(office))?.sandbox;
|
|
470
|
+
return sandbox?.workspace?.layout === "full" || sandbox?.image?.workspaceMount === "full";
|
|
490
471
|
}
|
|
491
472
|
//# sourceMappingURL=config.js.map
|