@geminixiang/mikan 1.0.0-beta.2 → 1.0.0-beta.4
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 +20 -0
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +3 -1
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/commands/extensions.d.ts.map +1 -1
- package/dist/commands/extensions.js +11 -4
- package/dist/commands/extensions.js.map +1 -1
- package/dist/harness/extensions/loader.d.ts.map +1 -1
- package/dist/harness/extensions/loader.js +8 -0
- package/dist/harness/extensions/loader.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,26 @@ any release.
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [1.0.0-beta.4]
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Show an extension's slug in `/pi-extensions` when it differs from the manifest display name.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- Reject extensions installed directly at a scope root and show an actionable warning to use a named subdirectory.
|
|
21
|
+
|
|
22
|
+
### Tests
|
|
23
|
+
|
|
24
|
+
- Add coverage for scope-root extension mis-install detection and inventory warnings.
|
|
25
|
+
|
|
26
|
+
## [1.0.0-beta.3]
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- Route `/pi-extensions` through Slack and include it in the bundled app manifests.
|
|
31
|
+
|
|
12
32
|
## [1.0.0-beta.2]
|
|
13
33
|
|
|
14
34
|
### Added
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../../src/adapters/slack/bot.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../../src/adapters/slack/bot.ts"],"names":[],"mappings":"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"}
|
|
@@ -947,7 +947,9 @@ export class SlackMessagingBot {
|
|
|
947
947
|
user_name,
|
|
948
948
|
});
|
|
949
949
|
}
|
|
950
|
-
else if (command === "/pi-sandbox" ||
|
|
950
|
+
else if (command === "/pi-sandbox" ||
|
|
951
|
+
command === "/pi-auto-reply" ||
|
|
952
|
+
command === "/pi-extensions") {
|
|
951
953
|
handlerPromise = this.routeSlashModelCommand({
|
|
952
954
|
command,
|
|
953
955
|
text,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bot.js","sourceRoot":"","sources":["../../../src/adapters/slack/bot.ts"],"names":[],"mappings":"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","sourcesContent":["import { SocketModeClient } from \"@slack/socket-mode\";\nimport type { KnownBlock } from \"@slack/types\";\nimport { WebClient } from \"@slack/web-api\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { readFile } from \"fs/promises\";\nimport { basename, join } from \"path\";\nimport type {\n MessagingBot,\n ConversationContext,\n ConversationEvent,\n MessagingEventHandler,\n ConversationMessage,\n ConversationResponder,\n ChatToolResult,\n ConversationKind,\n MessagingInfo,\n} from \"../../adapter.js\";\nimport { resolveConversationSettings } from \"../../config.js\";\nimport type { EventsWatcher } from \"../../events.js\";\nimport * as log from \"../../log.js\";\nimport type { Attachment, ChannelStore } from \"../../store.js\";\nimport type {\n SlackBlockAction,\n SlackBlockActionBody,\n SlackChannel,\n SlackEvent,\n SlackUser,\n} from \"./types.js\";\nimport { PRODUCT_NAME, formatForceStopped, formatNothingRunning } from \"../../platform-messages.js\";\nimport {\n appendBotResponseLog,\n appendChannelLog,\n MessagingEventQueue,\n resolveOnlyScopedStopTarget,\n resolveStopTarget,\n withRetry,\n} from \"../shared.js\";\nimport { processMessageIntake } from \"../intake.js\";\nimport { createSlackAdapters } from \"./context.js\";\nimport {\n hasMaterializedChatSession,\n registerThreadSession,\n} from \"../../sessions/agent-memory-file-manager.js\";\nimport {\n isSlackThreadSessionKey,\n planSlackAdapterSession,\n planSlackEventAnchorRun,\n resolveSlackSessionKey,\n} from \"./session.js\";\nimport { reportUserFacingError } from \"../../observability/sentry.js\";\nimport { renderSlackBlocks } from \"./blocks.js\";\n\nconst SLACK_EVENT_ANCHOR_TEXT = \"Working on it...\";\n\n// Slack WebClient errors carry either `code: \"rate_limited\"` (retry-after) or\n// the legacy `data.error === \"rate_limited\"` / 429 status shape.\nfunction slackIsRateLimited(err: Error): boolean {\n if ((err as { code?: unknown }).code === \"rate_limited\") return true;\n const data = (err as { data?: { error?: string; response?: { status?: number } } }).data;\n return data?.error === \"rate_limited\" || data?.response?.status === 429;\n}\n\nconst slackRetry = <T>(fn: () => Promise<T>): Promise<T> =>\n withRetry(fn, { isRateLimited: slackIsRateLimited });\n\nfunction collectSlackText(value: unknown, parts: string[]): void {\n if (value === null || value === undefined) return;\n if (typeof value === \"string\") {\n const trimmed = value.trim();\n if (trimmed) parts.push(trimmed);\n return;\n }\n if (Array.isArray(value)) {\n for (const item of value) collectSlackText(item, parts);\n return;\n }\n if (typeof value !== \"object\") return;\n\n const obj = value as Record<string, unknown>;\n for (const key of [\"text\", \"fallback\", \"title\", \"value\"] as const) {\n collectSlackText(obj[key], parts);\n }\n collectSlackText(obj.fields, parts);\n collectSlackText(obj.elements, parts);\n collectSlackText(obj.blocks, parts);\n}\n\nfunction buildSlackAppMessageText(event: {\n text?: string;\n blocks?: unknown[];\n attachments?: unknown[];\n}): string {\n const parts: string[] = [];\n collectSlackText(event.text, parts);\n collectSlackText(event.blocks, parts);\n collectSlackText(event.attachments, parts);\n const deduped = parts.filter((part, index) => parts.indexOf(part) === index);\n return deduped.join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Shared mrkdwn truncation helper\n// ---------------------------------------------------------------------------\n\nconst MRKDWN_CONTEXT_TEXT_LIMIT = 3000;\n\n/**\n * Build a Slack context block whose text is capped at the mrkdwn limit.\n * Used for muted diagnostics and ephemeral command responses.\n */\nexport function buildMrkdwnContextBlock(text: string): object {\n const blockText =\n text.length > MRKDWN_CONTEXT_TEXT_LIMIT\n ? text.substring(0, MRKDWN_CONTEXT_TEXT_LIMIT - 20) + \"\\n_(truncated)_\"\n : text;\n return { type: \"context\", elements: [{ type: \"mrkdwn\", text: blockText }] };\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type { SlackChannel, SlackEvent, SlackUser } from \"./types.js\";\n\n// ============================================================================\n// SlackMessagingBot\n// ============================================================================\n\nexport class SlackMessagingBot implements MessagingBot {\n private socketClient: SocketModeClient;\n private webClient: WebClient;\n private handler: MessagingEventHandler;\n private workingDir: string;\n private store: ChannelStore;\n private botUserId: string | null = null;\n private botId: string | null = null;\n private teamId: string | null = null;\n private ownMentionRegex: RegExp | null = null;\n private startupTs: string | null = null; // Messages older than this are just logged, not processed\n\n private users = new Map<string, SlackUser>();\n private channels = new Map<string, SlackChannel>();\n private queues = new Map<string, MessagingEventQueue>();\n private eventsWatcher: EventsWatcher | null = null;\n\n private createContext(event: SlackEvent): ConversationContext {\n return createSlackAdapters(event, this, {\n replyMode:\n resolveConversationSettings(join(this.workingDir, event.conversationId)).slack?.replyMode ??\n \"top-level\",\n });\n }\n\n constructor(\n handler: MessagingEventHandler,\n config: { appToken: string; botToken: string; workingDir: string; store: ChannelStore },\n ) {\n this.handler = handler;\n this.workingDir = config.workingDir;\n this.store = config.store;\n this.socketClient = new SocketModeClient({\n appToken: config.appToken,\n // Default 5s is too tight: brief event-loop stalls (e.g. backfill, sync fs)\n // cause false pong timeouts; 4 in a row makes Slack drop the socket.\n clientPingTimeout: 12_000,\n });\n this.webClient = new WebClient(config.botToken);\n }\n\n setEventsWatcher(watcher: EventsWatcher): void {\n this.eventsWatcher = watcher;\n }\n\n // ==========================================================================\n // Public API\n // ==========================================================================\n\n async start(): Promise<void> {\n const auth = await this.webClient.auth.test();\n this.botUserId = auth.user_id as string;\n this.botId = typeof auth.bot_id === \"string\" ? auth.bot_id : null;\n this.teamId = typeof auth.team_id === \"string\" ? auth.team_id : null;\n\n await Promise.all([this.fetchUsers(), this.fetchChannels()]);\n log.logInfo(`Loaded ${this.channels.size} channels, ${this.users.size} users`);\n\n // Record startup time before opening the socket. Slack may replay older events;\n // those should be logged but not processed. Backfill runs in the background up\n // to this timestamp so startup is not blocked by one history call per channel.\n this.startupTs = (Date.now() / 1000).toFixed(6);\n\n this.setupEventHandlers();\n await this.socketClient.start();\n\n log.logConnected(\"Slack\");\n\n void this.backfillAllChannels(this.startupTs).catch((error) => {\n log.logWarning(\"Slack backfill failed\", String(error));\n });\n }\n\n getUser(userId: string): SlackUser | undefined {\n return this.users.get(userId);\n }\n\n getChannel(channelId: string): SlackChannel | undefined {\n return this.channels.get(channelId);\n }\n\n getAllUsers(): SlackUser[] {\n return Array.from(this.users.values());\n }\n\n getAllChannels(): SlackChannel[] {\n return Array.from(this.channels.values());\n }\n\n private stripOwnMention(text: string | undefined): string {\n const source = text ?? \"\";\n if (!this.botUserId) return source.trim();\n if (!this.ownMentionRegex || !this.ownMentionRegex.source.includes(this.botUserId)) {\n this.ownMentionRegex = new RegExp(`<@${this.botUserId}>`, \"gi\");\n }\n return source.replace(this.ownMentionRegex, \"\").trim();\n }\n\n async postMessage(channel: string, text: string): Promise<string> {\n return slackRetry(async () => {\n const payload = { channel, ...renderSlackBlocks(text) };\n const result = await this.webClient.chat.postMessage(payload);\n return result.ts as string;\n });\n }\n\n async postEphemeral(\n channel: string,\n user: string,\n text: string,\n threadTs?: string,\n ): Promise<void> {\n return slackRetry(async () => {\n await this.webClient.chat.postEphemeral({\n channel,\n user,\n text,\n ...(threadTs ? { thread_ts: threadTs } : {}),\n });\n });\n }\n\n async postEphemeralBlocks(\n channel: string,\n user: string,\n text: string,\n blocks: object[],\n threadTs?: string,\n ): Promise<void> {\n return slackRetry(async () => {\n await this.webClient.chat.postEphemeral({\n channel,\n user,\n text,\n blocks: blocks as KnownBlock[],\n ...(threadTs ? { thread_ts: threadTs } : {}),\n });\n });\n }\n\n async postMessageBlocks(channel: string, text: string, blocks: object[]): Promise<string> {\n return slackRetry(async () => {\n const payload = { channel, text, blocks: blocks as KnownBlock[] };\n const result = await this.webClient.chat.postMessage(payload);\n return result.ts as string;\n });\n }\n\n async postPrivate(conversationId: string, userId: string, text: string): Promise<void> {\n await this.postEphemeral(conversationId, userId, text);\n }\n\n async postPrivateDiagnostic(\n conversationId: string,\n userId: string,\n text: string,\n options?: { style?: \"muted\" | \"error\" },\n ): Promise<void> {\n if (options?.style !== \"muted\") {\n await this.postEphemeral(\n conversationId,\n userId,\n options?.style === \"error\" ? `_${text}_` : text,\n );\n return;\n }\n await this.postEphemeralBlocks(conversationId, userId, text, [buildMrkdwnContextBlock(text)]);\n }\n\n async openDirectMessage(userId: string): Promise<string> {\n return slackRetry(async () => {\n const result = await this.webClient.conversations.open({ users: userId });\n const channelId = result.channel?.id;\n if (!channelId) {\n throw new Error(`Failed to open DM for user ${userId}`);\n }\n return channelId;\n });\n }\n\n async updateMessage(channel: string, ts: string, text: string): Promise<void> {\n return slackRetry(async () => {\n const payload = { channel, ts, ...renderSlackBlocks(text) };\n await this.webClient.chat.update(payload);\n });\n }\n\n async startMessageStream(\n channel: string,\n text: string,\n threadTs?: string,\n recipientUserId?: string,\n ): Promise<string> {\n return slackRetry(async () => {\n const result = await this.webClient.apiCall(\"chat.startStream\", {\n channel,\n markdown_text: text,\n ...(threadTs ? { thread_ts: threadTs } : {}),\n ...(this.teamId ? { recipient_team_id: this.teamId } : {}),\n ...(recipientUserId ? { recipient_user_id: recipientUserId } : {}),\n });\n const ts = (result as { ts?: string }).ts;\n if (!ts) throw new Error(\"Slack chat.startStream did not return ts\");\n return ts;\n });\n }\n\n async appendMessageStream(channel: string, ts: string, text: string): Promise<void> {\n return slackRetry(async () => {\n await this.webClient.apiCall(\"chat.appendStream\", {\n channel,\n ts,\n markdown_text: text,\n });\n });\n }\n\n async stopMessageStream(channel: string, ts: string): Promise<void> {\n return slackRetry(async () => {\n await this.webClient.apiCall(\"chat.stopStream\", { channel, ts });\n });\n }\n\n async deleteMessage(channel: string, ts: string): Promise<void> {\n return slackRetry(async () => {\n await this.webClient.chat.delete({ channel, ts });\n });\n }\n\n // ==========================================================================\n // Slack Assistant API (AI assistant experience)\n // ==========================================================================\n\n /** Set the status for an assistant thread (shows \"thinking\" state) */\n async setAssistantStatus(channel: string, threadTs: string, status: string): Promise<void> {\n return slackRetry(async () => {\n await this.webClient.assistant.threads.setStatus({\n channel_id: channel,\n thread_ts: threadTs,\n status,\n });\n });\n }\n\n async postInThread(channel: string, threadTs: string, text: string): Promise<string> {\n return slackRetry(async () => {\n const payload = { channel, thread_ts: threadTs, ...renderSlackBlocks(text) };\n const result = await this.webClient.chat.postMessage(payload);\n return result.ts as string;\n });\n }\n\n async postInThreadBlocks(\n channel: string,\n threadTs: string,\n text: string,\n blocks: object[],\n ): Promise<string> {\n return slackRetry(async () => {\n const payload = {\n channel,\n thread_ts: threadTs,\n text, // fallback for notifications\n blocks: blocks as KnownBlock[],\n };\n const result = await this.webClient.chat.postMessage(payload);\n return result.ts as string;\n });\n }\n\n async uploadFile(\n channel: string,\n filePath: string,\n title?: string,\n threadTs?: string,\n ): Promise<void> {\n return slackRetry(async () => {\n const fileName = title || basename(filePath);\n const fileContent = readFileSync(filePath);\n await this.webClient.files.uploadV2({\n channel_id: channel,\n file: fileContent,\n filename: fileName,\n title: fileName,\n ...(threadTs ? { thread_ts: threadTs } : {}),\n } as Parameters<typeof this.webClient.files.uploadV2>[0]);\n });\n }\n\n logToFile(channel: string, entry: object): void {\n appendChannelLog(this.workingDir, channel, entry);\n }\n\n logBotResponse(\n channel: string,\n text: string,\n ts: string,\n threadTs?: string,\n slackBlocks?: object[],\n ): void {\n appendBotResponseLog(this.workingDir, channel, text, ts, threadTs, {\n platform: \"slack\",\n ...(slackBlocks ? { slackBlocks } : {}),\n });\n }\n\n getMessagingInfo(): MessagingInfo {\n return {\n name: \"slack\",\n formattingGuide:\n \"## Slack Formatting (mrkdwn, NOT Markdown)\\nBold: *text*, Italic: _text_, Code: `code`, Block: ```code```, Links: <url|text>\\nDo NOT use **double asterisks** or [markdown](links).\",\n channels: this.getAllChannels().map((c) => ({ id: c.id, name: c.name })),\n users: this.getAllUsers().map((u) => ({\n id: u.id,\n userName: u.userName,\n displayName: u.displayName,\n })),\n diagnostics: {\n showUsageSummary: true,\n },\n };\n }\n\n // ==========================================================================\n // Events Integration\n // ==========================================================================\n\n /**\n * Enqueue an event for processing. Always queues (no \"already working\" rejection).\n * Returns true if enqueued, false if queue is full (max 5).\n */\n enqueueEvent(event: ConversationEvent): boolean {\n const conversationId = event.conversationId;\n const queue = this.getQueue(conversationId);\n if (queue.size() >= 5) {\n log.logWarning(\n `Event queue full for ${conversationId}, discarding: ${event.text.substring(0, 50)}`,\n );\n return false;\n }\n log.logInfo(`Enqueueing event for ${conversationId}: ${event.text.substring(0, 50)}`);\n queue.enqueue(async () => {\n let anchorTs: string | undefined;\n if (!event.thread_ts) {\n try {\n anchorTs = await this.postMessage(conversationId, SLACK_EVENT_ANCHOR_TEXT);\n } catch (err) {\n log.logWarning(\n `Failed to post Slack event anchor for ${conversationId}`,\n err instanceof Error ? err.message : String(err),\n );\n reportUserFacingError(err, {\n domain: \"events\",\n surface: \"event_delivery\",\n operation: \"slack_anchor_post\",\n severity: \"error\",\n platform: \"slack\",\n context: {\n conversationId,\n conversationKind: event.conversationKind,\n eventTs: event.ts,\n textLength: event.text.length,\n },\n });\n throw err;\n }\n }\n const eventPlan = planSlackEventAnchorRun(event, anchorTs);\n const eventForRun = eventPlan.event;\n if (eventPlan.initialMessageTs && eventForRun.sessionKey) {\n registerThreadSession({\n conversationDir: join(this.workingDir, conversationId),\n sessionKey: eventForRun.sessionKey,\n });\n }\n\n const runQueueKey = planSlackAdapterSession(eventForRun, {\n initialMessageTs: eventPlan.initialMessageTs,\n }).sessionKey;\n this.getQueue(runQueueKey).enqueue(async () => {\n const slackEvent: SlackEvent = {\n type: eventForRun.type as SlackEvent[\"type\"],\n conversationId,\n conversationKind: eventForRun.conversationKind,\n channel: conversationId,\n ts: eventForRun.ts,\n thread_ts: eventForRun.thread_ts,\n user: eventForRun.user,\n text: eventForRun.text,\n attachments: eventForRun.attachments?.map((attachment) => ({\n original: attachment.name,\n localPath: attachment.localPath,\n })),\n sessionKey: eventForRun.sessionKey,\n };\n const context = createSlackAdapters(slackEvent, this, {\n initialMessageTs: eventPlan.initialMessageTs,\n replyMode:\n resolveConversationSettings(join(this.workingDir, eventForRun.conversationId)).slack\n ?.replyMode ?? \"top-level\",\n });\n return this.handler.handleEvent(eventForRun, this, context);\n });\n });\n return true;\n }\n\n // ==========================================================================\n // Private - Event Handlers\n // ==========================================================================\n\n private getQueue(channelId: string): MessagingEventQueue {\n let queue = this.queues.get(channelId);\n if (!queue) {\n queue = new MessagingEventQueue(\"Slack\");\n this.queues.set(channelId, queue);\n }\n return queue;\n }\n\n private resolveQueueKey(conversationId: string, sessionKey: string): string {\n if (!isSlackThreadSessionKey(sessionKey)) return sessionKey;\n if (this.handler.isRunning(sessionKey)) return sessionKey;\n return this.hasKnownThreadSession(conversationId, sessionKey) ? sessionKey : conversationId;\n }\n\n private hasKnownThreadSession(conversationId: string, sessionKey: string): boolean {\n return hasMaterializedChatSession({\n conversationDir: join(this.workingDir, conversationId),\n sessionKey,\n });\n }\n\n private processSlackMessageIntake(options: {\n event: SlackEvent;\n attachmentsPromise: Promise<Attachment[]>;\n queueKey: string;\n isAutoReplyCandidate: boolean;\n onNotTriggered?: () => void;\n }): void {\n void processMessageIntake({\n eventBase: options.event as unknown as ConversationEvent,\n workingDir: this.workingDir,\n isAutoReplyCandidate: options.isAutoReplyCandidate,\n logEntryBase: {},\n processAttachments: () => options.attachmentsPromise,\n queueKey: options.queueKey,\n enqueue: (queueKey, work) => this.getQueue(queueKey).enqueue(work),\n handler: this.handler,\n bot: this,\n createContext: (event) => this.createContext(event as SlackEvent),\n onNotTriggered: options.onNotTriggered,\n deferAttachmentsUntilRun: true,\n });\n }\n\n private buildHomeView(): { type: \"home\"; blocks: KnownBlock[] } {\n const blocks: object[] = [\n {\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: `*${PRODUCT_NAME}*\\nStart a new task or check on running work.`,\n },\n accessory: {\n type: \"image\",\n image_url: \"https://media1.tenor.com/m/lfDATg4Bhc0AAAAC/happy-cat.gif\",\n alt_text: PRODUCT_NAME,\n },\n },\n ];\n\n // --- Running tasks ---\n const runningSessions = this.handler.getRunningSessions();\n\n blocks.push(\n { type: \"divider\" },\n {\n type: \"header\",\n text: {\n type: \"plain_text\",\n text: `Running Tasks (${runningSessions.length})`,\n emoji: true,\n },\n },\n );\n\n if (runningSessions.length === 0) {\n blocks.push({\n type: \"context\",\n elements: [{ type: \"mrkdwn\", text: \"_No tasks running right now._\" }],\n });\n } else {\n // Threshold for \"stuck\" detection (10 minutes)\n const STUCK_THRESHOLD_MS = 10 * 60 * 1000;\n\n for (const session of runningSessions) {\n const channelId = session.sessionKey.split(\":\")[0];\n const channel = this.channels.get(channelId);\n const channelName = channel ? `#${channel.name}` : channelId;\n const elapsed = Math.floor((Date.now() - session.startedAt) / 60000);\n const elapsedStr = elapsed < 1 ? \"<1 min\" : `${elapsed} min`;\n\n // Check if task might be stuck\n const lastActivity = session.lastActivityAt ? Date.now() - session.lastActivityAt : 0;\n const isStuck = lastActivity > STUCK_THRESHOLD_MS;\n const statusText = isStuck ? \"_stuck_\" : \"_running_\";\n\n // Build status line: channel · status · time · step\n let statusLine = `${statusText} · ${elapsedStr}`;\n if (session.currentTool) {\n statusLine += ` · ${session.currentTool}`;\n }\n if (isStuck && lastActivity > 0) {\n const inactiveMin = Math.floor(lastActivity / 60000);\n statusLine += ` · idle ${inactiveMin}m`;\n }\n\n // Use context block for gray small text (like \"No scheduled jobs.\")\n blocks.push({\n type: \"context\",\n elements: [\n {\n type: \"mrkdwn\",\n text: `*${channelName}* · ${statusLine}`,\n },\n ],\n });\n\n // Add Force Stop button as separate element if stuck\n if (isStuck) {\n blocks.push({\n type: \"context\",\n elements: [\n {\n type: \"mrkdwn\",\n text: \" \",\n },\n {\n type: \"button\",\n text: { type: \"plain_text\", text: \"Force Stop\", emoji: true },\n action_id: `force_stop_${session.sessionKey.replace(/:/g, \"_\")}`,\n style: \"danger\",\n },\n ],\n });\n }\n }\n }\n\n // --- Cron jobs ---\n const periodicEvents = this.eventsWatcher?.getPeriodicEvents() ?? [];\n\n blocks.push(\n { type: \"divider\" },\n {\n type: \"header\",\n text: {\n type: \"plain_text\",\n text: `Scheduled Jobs (${periodicEvents.length})`,\n emoji: true,\n },\n },\n );\n\n if (periodicEvents.length === 0) {\n blocks.push({\n type: \"context\",\n elements: [{ type: \"mrkdwn\", text: \"_No scheduled jobs._\" }],\n });\n } else {\n for (const ev of periodicEvents) {\n const channelLabel =\n ev.platform === \"slack\"\n ? (() => {\n const channel = this.channels.get(ev.conversationId);\n const channelName = channel ? `#${channel.name}` : ev.conversationId;\n return `${ev.platform}:${channelName}`;\n })()\n : `${ev.platform}:${ev.conversationId}`;\n const nextStr = ev.nextRun\n ? new Date(ev.nextRun).toLocaleString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n })\n : \"—\";\n blocks.push({\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: `*${ev.text}*\\n└ \\`${ev.schedule}\\` · ${channelLabel} · Next: ${nextStr}`,\n },\n });\n }\n }\n\n // --- Footer ---\n blocks.push(\n { type: \"divider\" },\n {\n type: \"context\",\n elements: [\n { type: \"mrkdwn\", text: \"💡 @mention in a channel or send a DM to start a new task\" },\n ],\n },\n );\n\n return { type: \"home\", blocks: blocks as KnownBlock[] };\n }\n\n private resolveStopTarget(channelId: string, threadTs?: string): string | null {\n const directTarget = resolveStopTarget({\n handler: this.handler,\n conversationId: channelId,\n sessionKey: resolveSlackSessionKey(channelId, threadTs),\n });\n if (directTarget) return directTarget;\n if (threadTs) return null;\n return resolveOnlyScopedStopTarget(this.handler, channelId);\n }\n\n private isStopText(text: string): boolean {\n const normalized = text.trim().toLowerCase();\n return normalized === \"stop\" || normalized === \"/stop\";\n }\n\n private createCommandAdapters(\n conversationId: string,\n userId: string,\n userName: string | undefined,\n text: string,\n ts: string,\n options: { ephemeralChannelId?: string; threadTs?: string } = {},\n ): ConversationContext {\n const message: ConversationMessage = {\n id: ts,\n sessionKey: conversationId,\n conversationKind: options.ephemeralChannelId ? \"shared\" : \"direct\",\n userId,\n userName,\n text,\n attachments: [],\n };\n\n const respond = async (responseText: string) => {\n if (options.ephemeralChannelId) {\n await this.postEphemeral(\n options.ephemeralChannelId,\n userId,\n responseText,\n options.threadTs,\n );\n return;\n }\n const messageTs = await this.postMessage(conversationId, responseText);\n this.logBotResponse(conversationId, responseText, messageTs);\n };\n\n const respondMuted = async (responseText: string) => {\n const blocks = [buildMrkdwnContextBlock(responseText)];\n if (options.ephemeralChannelId) {\n await this.postEphemeralBlocks(\n options.ephemeralChannelId,\n userId,\n responseText,\n blocks,\n options.threadTs,\n );\n return;\n }\n const messageTs = await this.postMessageBlocks(conversationId, responseText, blocks);\n this.logBotResponse(conversationId, responseText, messageTs);\n };\n\n const responder: ConversationResponder = {\n respond,\n replaceResponse: respond,\n respondDiagnostic: async (\n responseText: string,\n responseOptions?: { style?: \"muted\" | \"error\" },\n ) => {\n if (responseOptions?.style === \"muted\") {\n await respondMuted(responseText);\n return;\n }\n await respond(responseOptions?.style === \"error\" ? `_${responseText}_` : responseText);\n },\n respondToolResult: async (result: ChatToolResult) => {\n const duration = (result.durationMs / 1000).toFixed(1);\n await respond(\n `${result.isError ? \"Error\" : \"Done\"} ${result.toolName} (${duration}s)\\n${result.result}`,\n );\n },\n setTyping: async () => {},\n setWorking: async () => {},\n uploadFile: async (filePath: string, title?: string) => {\n await this.uploadFile(conversationId, filePath, title);\n },\n deleteResponse: async () => {},\n };\n\n return {\n message,\n responder,\n platform: this.getMessagingInfo(),\n };\n }\n\n private buildSlashCommandEvent(\n payload: {\n command: string;\n text?: string;\n channel_id: string;\n user_id: string;\n user_name?: string;\n thread_ts?: string;\n },\n options: { type?: ConversationEvent[\"type\"]; includeText?: boolean; thread?: boolean } = {},\n ): { event: ConversationEvent; context: ConversationContext } {\n const conversationId = payload.channel_id;\n const isDirectMessage = conversationId.startsWith(\"D\");\n const createdAt = new Date();\n const eventTs = (createdAt.getTime() / 1000).toFixed(6);\n const userName = payload.user_name ?? this.getUser(payload.user_id)?.userName;\n const commandSuffix = options.includeText ? payload.text?.trim() : undefined;\n const commandText = commandSuffix ? `${payload.command} ${commandSuffix}` : payload.command;\n const threadTs = options.thread ? payload.thread_ts : undefined;\n const sessionKey = options.thread\n ? resolveSlackSessionKey(conversationId, threadTs)\n : conversationId;\n\n this.logToFile(conversationId, {\n date: createdAt.toISOString(),\n ts: eventTs,\n user: payload.user_id,\n userName,\n text: commandText,\n attachments: [],\n isMessagingBot: false,\n ...(threadTs ? { threadTs } : {}),\n });\n\n const event: ConversationEvent = {\n type: options.type ?? (isDirectMessage ? \"dm\" : \"mention\"),\n conversationId,\n conversationKind: isDirectMessage ? \"direct\" : \"shared\",\n ts: eventTs,\n user: payload.user_id,\n text: commandText,\n attachments: [],\n ...(threadTs ? { thread_ts: threadTs } : {}),\n sessionKey,\n };\n\n const context = this.createCommandAdapters(\n conversationId,\n payload.user_id,\n userName,\n commandText,\n eventTs,\n isDirectMessage ? { threadTs } : { ephemeralChannelId: conversationId, threadTs },\n );\n\n return { event, context };\n }\n\n private async routeSlashLoginCommand(payload: {\n command: string;\n text?: string;\n channel_id: string;\n user_id: string;\n user_name?: string;\n }): Promise<void> {\n const { event, context } = this.buildSlashCommandEvent(payload, {\n type: payload.channel_id.startsWith(\"D\") ? \"dm\" : \"private_command\",\n includeText: true,\n });\n await this.handler.handleEvent(event, this, context);\n }\n\n private async routeSlashNewCommand(payload: {\n command: string;\n channel_id: string;\n user_id: string;\n user_name?: string;\n }): Promise<void> {\n const conversationId = payload.channel_id;\n if (!conversationId.startsWith(\"D\")) {\n await this.postEphemeral(\n conversationId,\n payload.user_id,\n `為了避免誤清除共享上下文,${payload.command} 目前只能在與 ${PRODUCT_NAME} 的私訊中使用。`,\n );\n return;\n }\n\n const createdAt = new Date();\n const eventTs = (createdAt.getTime() / 1000).toFixed(6);\n const userName = payload.user_name ?? this.getUser(payload.user_id)?.userName;\n\n this.logToFile(conversationId, {\n date: createdAt.toISOString(),\n ts: eventTs,\n user: payload.user_id,\n userName,\n text: payload.command,\n attachments: [],\n isMessagingBot: false,\n });\n\n const commandMessagingBot: MessagingBot = {\n start: async () => {},\n postMessage: async (_channel: string, text: string) => this.postMessage(conversationId, text),\n updateMessage: async (channel: string, ts: string, text: string) =>\n this.updateMessage(channel, ts, text),\n enqueueEvent: (event: ConversationEvent) => this.enqueueEvent(event),\n getMessagingInfo: () => this.getMessagingInfo(),\n };\n await this.handler.handleNewCommand(conversationId, conversationId, commandMessagingBot);\n }\n\n private async routeSlashModelCommand(payload: {\n command: string;\n text?: string;\n channel_id: string;\n user_id: string;\n user_name?: string;\n }): Promise<void> {\n const { event, context } = this.buildSlashCommandEvent(payload, { includeText: true });\n await this.handler.handleEvent(event, this, context);\n }\n\n private async routeSlashSessionCommand(payload: {\n command: string;\n channel_id: string;\n user_id: string;\n user_name?: string;\n thread_ts?: string;\n }): Promise<void> {\n const { event, context } = this.buildSlashCommandEvent(payload, { thread: true });\n await this.handler.handleEvent(event, this, context);\n }\n\n private async routeSlashAdminCommand(payload: {\n command: string;\n channel_id: string;\n user_id: string;\n user_name?: string;\n thread_ts?: string;\n }): Promise<void> {\n const { event, context } = this.buildSlashCommandEvent(payload, { thread: true });\n await this.handler.handleEvent(event, this, context);\n }\n\n private setupEventHandlers(): void {\n this.socketClient.on(\"disconnect\", (err: unknown) => {\n log.logWarning(\"Slack socket disconnect\", err ? String(err) : \"\");\n });\n this.socketClient.on(\"error\", (err: unknown) => {\n log.logWarning(\"Slack socket error\", err ? String(err) : \"\");\n });\n this.socketClient.on(\"unable_to_socket_mode_start\", (err: unknown) => {\n log.logWarning(\"Slack socket unable_to_start\", err ? String(err) : \"\");\n });\n\n this.socketClient.on(\"app_mention\", (payload) => this.handleAppMention(payload));\n this.socketClient.on(\"message\", (payload) => this.handleMessageEvent(payload));\n this.socketClient.on(\"slash_commands\", (payload) => void this.handleSlashCommand(payload));\n this.socketClient.on(\"app_home_opened\", (payload) => this.handleAppHomeOpened(payload));\n this.socketClient.on(\"block_actions\", (payload) => void this.handleBlockAction(payload));\n this.socketClient.on(\n \"interactive\",\n (payload) =>\n void this.handleBlockAction(payload as { body: SlackBlockActionBody; ack: () => void }),\n );\n }\n\n private handleAppMention({ event, ack }: { event: unknown; ack: () => void }): void {\n const e = event as {\n text: string;\n channel: string;\n user: string;\n ts: string;\n thread_ts?: string;\n files?: Array<{ name: string; url_private_download?: string; url_private?: string }>;\n };\n\n // Skip DMs (handled by message event)\n if (e.channel.startsWith(\"D\")) {\n ack();\n return;\n }\n\n // Top-level mentions use a persistent channel session.\n // Thread replies get their own isolated session (channelId:thread_ts).\n const sessionKey = resolveSlackSessionKey(e.channel, e.thread_ts);\n\n const mentionText = this.stripOwnMention(e.text);\n const slackEvent: SlackEvent = {\n type: \"mention\",\n conversationId: e.channel,\n conversationKind: \"shared\",\n channel: e.channel,\n ts: e.ts,\n thread_ts: e.thread_ts,\n user: e.user,\n text: mentionText || \"Please respond to the recent conversation context.\",\n files: e.files,\n sessionKey,\n };\n\n const attachmentsPromise = this.logUserMessage(slackEvent);\n\n // Only trigger processing for messages AFTER startup (not replayed old messages)\n if (this.startupTs && e.ts < this.startupTs) {\n log.logInfo(\n `[${e.channel}] Logged old message (pre-startup), not triggering: ${slackEvent.text.substring(0, 30)}`,\n );\n void attachmentsPromise.catch((err) => {\n log.logWarning(\"Failed to log Slack message\", String(err));\n });\n ack();\n return;\n }\n\n // Check for stop command - execute immediately, don't queue!\n if (this.isStopText(slackEvent.text)) {\n const stopTarget = this.resolveStopTarget(e.channel, e.thread_ts);\n if (stopTarget) {\n this.handler.handleStop(stopTarget, e.channel, this);\n } else {\n this.postMessage(e.channel, formatNothingRunning(\"slack\"));\n }\n void attachmentsPromise.catch((err) => {\n log.logWarning(\"Failed to log Slack message\", String(err));\n });\n ack();\n return;\n }\n\n this.processSlackMessageIntake({\n event: slackEvent,\n attachmentsPromise,\n queueKey: this.resolveQueueKey(e.channel, sessionKey),\n isAutoReplyCandidate: false,\n });\n\n ack();\n }\n\n private handleMessageEvent({ event, ack }: { event: unknown; ack: () => void }): void {\n const e = event as {\n text?: string;\n channel: string;\n user?: string;\n ts: string;\n thread_ts?: string;\n channel_type?: string;\n subtype?: string;\n bot_id?: string;\n app_id?: string;\n username?: string;\n bot_profile?: { id?: string; app_id?: string; name?: string; real_name?: string };\n blocks?: unknown[];\n attachments?: unknown[];\n files?: Array<{ name: string; url_private_download?: string; url_private?: string }>;\n };\n\n const hasFiles = !!e.files && e.files.length > 0;\n const hasSlackContent = !!e.text || hasFiles || !!e.blocks?.length || !!e.attachments?.length;\n const isOwnMessagingBotMessage =\n (!!e.user && e.user === this.botUserId) || (!!this.botId && e.bot_id === this.botId);\n if (isOwnMessagingBotMessage) {\n ack();\n return;\n }\n\n const isExternalMessagingBotMessage = !!e.bot_id || e.subtype === \"bot_message\";\n if (isExternalMessagingBotMessage) {\n if (e.subtype !== undefined && e.subtype !== \"bot_message\" && e.subtype !== \"file_share\") {\n ack();\n return;\n }\n if (!hasSlackContent) {\n ack();\n return;\n }\n void this.logExternalMessagingBotMessage(e).catch((err) => {\n log.logWarning(\"Failed to log Slack bot message\", String(err));\n });\n ack();\n return;\n }\n\n if (!e.user) {\n ack();\n return;\n }\n if (e.subtype !== undefined && e.subtype !== \"file_share\") {\n ack();\n return;\n }\n if (!hasSlackContent) {\n ack();\n return;\n }\n\n const isDM = e.channel_type === \"im\";\n const conversationKind: ConversationKind = isDM ? \"direct\" : \"shared\";\n const isMessagingBotMention = e.text?.includes(`<@${this.botUserId}>`);\n\n // Skip channel @mentions - already handled by app_mention event\n if (!isDM && isMessagingBotMention) {\n ack();\n return;\n }\n\n const isThreadReply = !!e.thread_ts;\n const sessionKey = isDM ? resolveSlackSessionKey(e.channel, e.thread_ts) : undefined;\n\n const slackEvent: SlackEvent = {\n type: isDM ? \"dm\" : \"mention\",\n conversationId: e.channel,\n conversationKind,\n channel: e.channel,\n ts: e.ts,\n thread_ts: e.thread_ts,\n user: e.user,\n text: this.stripOwnMention(e.text),\n files: e.files,\n sessionKey,\n };\n\n const attachmentsPromise = this.logUserMessage(slackEvent);\n\n // Only trigger processing for messages AFTER startup (not replayed old messages)\n if (this.startupTs && e.ts < this.startupTs) {\n log.logInfo(\n `[${e.channel}] Skipping old message (pre-startup): ${slackEvent.text.substring(0, 30)}`,\n );\n void attachmentsPromise.catch((err) => {\n log.logWarning(\"Failed to log Slack message\", String(err));\n });\n ack();\n return;\n }\n\n // Stop command for DM only (app_mention handles shared-channel \"@mikan stop\").\n if (isDM && this.isStopText(slackEvent.text)) {\n const stopTarget = this.resolveStopTarget(e.channel, e.thread_ts);\n if (stopTarget) {\n this.handler.handleStop(stopTarget, e.channel, this);\n } else {\n this.postMessage(e.channel, formatNothingRunning(\"slack\"));\n }\n void attachmentsPromise.catch((err) => {\n log.logWarning(\"Failed to log Slack message\", String(err));\n });\n ack();\n return;\n }\n\n const enqueueTriggered = () => {\n const activeSessionKey =\n slackEvent.sessionKey ?? resolveSlackSessionKey(e.channel, e.thread_ts);\n // Auto-reply top-level channel messages start with no sessionKey because\n // they are only candidates until the policy allows them. Once triggered,\n // persist the resolved key on the event; otherwise the runtime fallback\n // treats the message ts as a thread session (`channel:ts`) instead of the\n // persistent top-level channel session.\n slackEvent.sessionKey = activeSessionKey;\n this.processSlackMessageIntake({\n event: slackEvent,\n attachmentsPromise,\n queueKey: this.resolveQueueKey(e.channel, activeSessionKey),\n isAutoReplyCandidate: false,\n });\n };\n\n const logOnly = () => {\n void attachmentsPromise.catch((err) => {\n log.logWarning(\"Failed to log Slack message\", String(err));\n });\n };\n\n if (isDM) {\n enqueueTriggered();\n ack();\n return;\n }\n\n if (isThreadReply) {\n logOnly();\n ack();\n return;\n }\n\n const activeSessionKey = resolveSlackSessionKey(e.channel, e.thread_ts);\n slackEvent.sessionKey = activeSessionKey;\n this.processSlackMessageIntake({\n event: slackEvent,\n attachmentsPromise,\n queueKey: this.resolveQueueKey(e.channel, activeSessionKey),\n isAutoReplyCandidate: true,\n onNotTriggered: logOnly,\n });\n\n ack();\n }\n\n private async handleSlashCommand({\n body,\n ack,\n }: {\n body: unknown;\n ack: () => Promise<void>;\n }): Promise<void> {\n const payload = body as {\n command?: string;\n text?: string;\n channel_id?: string;\n user_id?: string;\n user_name?: string;\n thread_ts?: string;\n };\n\n await ack();\n\n if (!payload.command || !payload.channel_id || !payload.user_id) {\n return;\n }\n\n const { command, text, channel_id, user_id, user_name, thread_ts } = payload;\n\n let handlerPromise: Promise<void> | null = null;\n if (command === \"/pi-login\") {\n handlerPromise = this.routeSlashLoginCommand({\n command,\n text,\n channel_id,\n user_id,\n user_name,\n });\n } else if (command === \"/pi-new\") {\n handlerPromise = this.routeSlashNewCommand({ command, channel_id, user_id, user_name });\n } else if (command === \"/pi-session\") {\n handlerPromise = this.routeSlashSessionCommand({\n command,\n channel_id,\n user_id,\n user_name,\n thread_ts,\n });\n } else if (command === \"/pi-model\") {\n handlerPromise = this.routeSlashModelCommand({\n command,\n text,\n channel_id,\n user_id,\n user_name,\n });\n } else if (command === \"/pi-sandbox\" || command === \"/pi-auto-reply\") {\n handlerPromise = this.routeSlashModelCommand({\n command,\n text,\n channel_id,\n user_id,\n user_name,\n });\n } else if (command === \"/pi-admin\") {\n handlerPromise = this.routeSlashAdminCommand({\n command,\n channel_id,\n user_id,\n user_name,\n thread_ts,\n });\n }\n\n if (!handlerPromise) {\n return;\n }\n\n handlerPromise.catch((err) => {\n log.logWarning(\"Slack slash command error\", err instanceof Error ? err.message : String(err));\n });\n }\n\n private handleAppHomeOpened({ event, ack }: { event: unknown; ack: () => void }): void {\n const e = event as { user: string; tab: string };\n ack();\n if (e.tab !== \"home\") return;\n\n this.webClient.views\n .publish({\n user_id: e.user,\n view: this.buildHomeView(),\n })\n .catch((err) => {\n log.logWarning(`Failed to publish App Home view`, String(err));\n });\n }\n\n private async handleBlockAction({\n body,\n ack,\n }: {\n body: SlackBlockActionBody;\n ack: () => void;\n }): Promise<void> {\n const action = body.actions?.[0];\n if (!action) {\n ack();\n return;\n }\n\n if (!action.action_id?.startsWith(\"force_stop_\")) {\n ack();\n this.handleSlackInteraction(body, action);\n return;\n }\n\n ack();\n const sessionKey = action.action_id.replace(\"force_stop_\", \"\").replace(/_/g, \":\");\n const userId = body.user?.id;\n const channelId = body.container?.channel_id || sessionKey.split(\":\")[0];\n\n log.logInfo(`[Force Stop] User ${userId} requested force stop for ${sessionKey}`);\n\n // Use handler's forceStop method\n this.handler.forceStop(sessionKey);\n\n // Notify in channel\n await this.postMessage(channelId, formatForceStopped(\"slack\", userId ?? \"unknown\"));\n\n // Refresh home tab\n if (userId) {\n this.webClient.views\n .publish({\n user_id: userId,\n view: this.buildHomeView(),\n })\n .catch((err) => {\n log.logWarning(`Failed to refresh App Home view`, String(err));\n });\n }\n }\n\n private handleSlackInteraction(body: SlackBlockActionBody, action: SlackBlockAction): void {\n const container = body.container ?? {};\n const channelId = container.channel_id;\n const userId = body.user?.id;\n if (!channelId || !userId) return;\n\n const selectedOption = action.selected_option;\n const selectedOptions = Array.isArray(action.selected_options)\n ? action.selected_options\n : undefined;\n const selectedText = selectedOption?.text?.text ?? selectedOption?.value;\n const selectedTexts = selectedOptions?.map((option) => option.text?.text ?? option.value);\n const valueText = selectedTexts?.length\n ? selectedTexts.join(\", \")\n : (selectedText ?? action.value ?? action.action_id);\n const text = `[Slack action] ${action.action_id}: ${valueText}`;\n const ts = `action:${Date.now()}`;\n const threadTs = container.thread_ts;\n const sessionKey = resolveSlackSessionKey(channelId, threadTs);\n\n this.logToFile(channelId, {\n date: new Date().toISOString(),\n ts,\n ...(threadTs ? { threadTs } : {}),\n user: userId,\n userName: body.user?.username ?? body.user?.name,\n text,\n attachments: [],\n isMessagingBot: false,\n platform: \"slack\",\n slackInteraction: {\n type: \"block_actions\",\n actionId: action.action_id,\n blockId: action.block_id,\n actionType: action.type,\n value: action.value,\n selectedOption: selectedOption\n ? { text: selectedOption.text?.text, value: selectedOption.value }\n : undefined,\n selectedOptions: selectedOptions?.map((option) => ({\n text: option.text?.text,\n value: option.value,\n })),\n messageTs: container.message_ts,\n },\n });\n\n const event: ConversationEvent = {\n type: \"slack_action\",\n conversationId: channelId,\n conversationKind: channelId.startsWith(\"D\") ? \"direct\" : \"shared\",\n ts,\n user: userId,\n text,\n attachments: [],\n ...(threadTs ? { thread_ts: threadTs } : {}),\n sessionKey,\n };\n\n this.getQueue(this.resolveQueueKey(channelId, sessionKey)).enqueue(async () => {\n const slackEvent: SlackEvent = {\n type: event.conversationKind === \"direct\" ? \"dm\" : \"mention\",\n conversationId: channelId,\n conversationKind: event.conversationKind,\n channel: channelId,\n ts,\n thread_ts: threadTs,\n user: userId,\n text,\n attachments: [],\n sessionKey,\n };\n return this.handler.handleEvent(event, this, this.createContext(slackEvent));\n });\n }\n\n /**\n * Log a user message to log.jsonl after attachments are ready.\n */\n private async logUserMessage(event: SlackEvent): Promise<Attachment[]> {\n const user = this.users.get(event.user);\n let attachments: Attachment[] = [];\n let attachmentError: unknown;\n if (event.files) {\n try {\n attachments = await this.store.processAttachments(event.channel, event.files, event.ts);\n } catch (err) {\n attachmentError = err;\n }\n }\n // Always write the text log, even if attachment processing failed — we want\n // a record of the user message regardless of file-handling errors.\n this.logToFile(event.channel, {\n date: new Date(parseFloat(event.ts) * 1000).toISOString(),\n ts: event.ts,\n threadTs: event.thread_ts,\n user: event.user,\n userName: user?.userName,\n displayName: user?.displayName,\n text: event.text,\n attachments,\n isMessagingBot: false,\n });\n if (attachmentError) throw attachmentError;\n return attachments;\n }\n\n private async logExternalMessagingBotMessage(event: {\n channel: string;\n ts: string;\n thread_ts?: string;\n text?: string;\n subtype?: string;\n bot_id?: string;\n app_id?: string;\n username?: string;\n bot_profile?: { app_id?: string; name?: string; real_name?: string };\n blocks?: unknown[];\n attachments?: unknown[];\n files?: Array<{ name: string; url_private_download?: string; url_private?: string }>;\n }): Promise<Attachment[]> {\n const attachments = event.files\n ? await this.store.processAttachments(event.channel, event.files, event.ts)\n : [];\n const botName =\n event.username ?? event.bot_profile?.name ?? event.bot_profile?.real_name ?? event.bot_id;\n this.logToFile(event.channel, {\n date: new Date(parseFloat(event.ts) * 1000).toISOString(),\n ts: event.ts,\n threadTs: event.thread_ts,\n user: event.bot_id ? `bot:${event.bot_id}` : \"external-bot\",\n userName: botName,\n displayName: botName,\n text: buildSlackAppMessageText(event),\n attachments,\n isMessagingBot: true,\n botId: event.bot_id,\n appId: event.app_id ?? event.bot_profile?.app_id,\n subtype: event.subtype,\n });\n return attachments;\n }\n\n // ==========================================================================\n // Private - Backfill\n // ==========================================================================\n\n private async getExistingTimestamps(channelId: string): Promise<Set<string>> {\n const logPath = join(this.workingDir, channelId, \"log.jsonl\");\n const timestamps = new Set<string>();\n if (!existsSync(logPath)) return timestamps;\n\n const content = await readFile(logPath, \"utf-8\");\n const lines = content.trim().split(\"\\n\").filter(Boolean);\n for (let i = 0; i < lines.length; i++) {\n try {\n const entry = JSON.parse(lines[i]);\n if (entry.ts) timestamps.add(entry.ts);\n } catch (err) {\n log.logWarning(\n `Skipping malformed log entry at ${logPath}:${i + 1}`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n return timestamps;\n }\n\n private async backfillChannel(channelId: string, upperBoundTs?: string): Promise<number> {\n const existingTs = await this.getExistingTimestamps(channelId);\n\n // Find the biggest ts in log.jsonl\n let lastLoggedTs: string | undefined;\n for (const ts of existingTs) {\n if (!lastLoggedTs || parseFloat(ts) > parseFloat(lastLoggedTs)) lastLoggedTs = ts;\n }\n\n type Message = {\n user?: string;\n bot_id?: string;\n app_id?: string;\n username?: string;\n bot_profile?: { app_id?: string; name?: string; real_name?: string };\n blocks?: unknown[];\n attachments?: unknown[];\n text?: string;\n ts?: string;\n thread_ts?: string;\n subtype?: string;\n files?: Array<{ name: string }>;\n };\n const allMessages: Message[] = [];\n\n let cursor: string | undefined;\n let pageCount = 0;\n const maxPages = 3;\n\n do {\n const result = await this.webClient.conversations.history({\n channel: channelId,\n oldest: lastLoggedTs, // Only fetch messages newer than what we have\n latest: upperBoundTs, // Do not race live socket events after startup\n inclusive: false,\n limit: 1000,\n cursor,\n });\n if (result.messages) {\n allMessages.push(...(result.messages as Message[]));\n }\n cursor = result.response_metadata?.next_cursor;\n pageCount++;\n } while (cursor && pageCount < maxPages);\n\n // Filter: include mikan's messages, external app/bot messages, and user messages.\n const relevantMessages = allMessages.filter((msg) => {\n if (!msg.ts || existingTs.has(msg.ts)) return false; // Skip duplicates\n if (msg.user === this.botUserId) return true;\n const isExternalMessagingBotMessage = !!msg.bot_id || msg.subtype === \"bot_message\";\n if (isExternalMessagingBotMessage) {\n if (this.botId && msg.bot_id === this.botId) return false;\n if (\n msg.subtype !== undefined &&\n msg.subtype !== \"bot_message\" &&\n msg.subtype !== \"file_share\"\n ) {\n return false;\n }\n return (\n !!msg.text ||\n !!(msg.files && msg.files.length > 0) ||\n !!msg.blocks?.length ||\n !!msg.attachments?.length\n );\n }\n if (msg.subtype !== undefined && msg.subtype !== \"file_share\") return false;\n if (!msg.user) return false;\n if (!msg.text && (!msg.files || msg.files.length === 0)) return false;\n return true;\n });\n\n // Reverse to chronological order\n relevantMessages.reverse();\n\n // Log each message to log.jsonl\n for (const msg of relevantMessages) {\n const isMikanMessage = msg.user === this.botUserId;\n const isExternalMessagingBotMessage =\n !isMikanMessage && (!!msg.bot_id || msg.subtype === \"bot_message\");\n if (isExternalMessagingBotMessage) {\n await this.logExternalMessagingBotMessage({ ...msg, channel: channelId, ts: msg.ts! });\n continue;\n }\n\n const user = this.users.get(msg.user!);\n const text = this.stripOwnMention(msg.text);\n const attachments = msg.files\n ? await this.store.processAttachments(channelId, msg.files, msg.ts!)\n : [];\n\n this.logToFile(channelId, {\n date: new Date(parseFloat(msg.ts!) * 1000).toISOString(),\n ts: msg.ts!,\n threadTs: msg.thread_ts,\n user: isMikanMessage ? \"bot\" : msg.user!,\n userName: isMikanMessage ? undefined : user?.userName,\n displayName: isMikanMessage ? undefined : user?.displayName,\n text,\n attachments,\n isMessagingBot: isMikanMessage,\n });\n }\n\n return relevantMessages.length;\n }\n\n private async backfillAllChannels(upperBoundTs?: string): Promise<void> {\n const startTime = Date.now();\n\n // Only backfill channels that already have a log.jsonl (mikan has interacted with them before)\n const channelsToBackfill: Array<[string, SlackChannel]> = [];\n for (const [channelId, channel] of this.channels) {\n const logPath = join(this.workingDir, channelId, \"log.jsonl\");\n if (existsSync(logPath)) {\n channelsToBackfill.push([channelId, channel]);\n }\n }\n\n log.logBackfillStart(channelsToBackfill.length);\n\n let totalMessages = 0;\n for (const [channelId, channel] of channelsToBackfill) {\n try {\n const count = await this.backfillChannel(channelId, upperBoundTs);\n if (count > 0) log.logBackfillChannel(channel.name, count);\n totalMessages += count;\n } catch (error) {\n log.logWarning(`Failed to backfill #${channel.name}`, String(error));\n }\n\n // Add delay between channels to avoid hitting Slack rate limits\n if (channelId !== channelsToBackfill[channelsToBackfill.length - 1][0]) {\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n }\n\n const durationMs = Date.now() - startTime;\n log.logBackfillComplete(totalMessages, durationMs);\n }\n\n // ==========================================================================\n // Private - Fetch Users/Channels\n // ==========================================================================\n\n private async fetchUsers(): Promise<void> {\n let cursor: string | undefined;\n do {\n const result = await this.webClient.users.list({ limit: 200, cursor });\n const members = result.members as\n | Array<{ id?: string; name?: string; real_name?: string; deleted?: boolean }>\n | undefined;\n if (members) {\n for (const u of members) {\n if (u.id && u.name && !u.deleted) {\n this.users.set(u.id, {\n id: u.id,\n userName: u.name,\n displayName: u.real_name || u.name,\n });\n }\n }\n }\n cursor = result.response_metadata?.next_cursor;\n } while (cursor);\n }\n\n private async fetchChannels(): Promise<void> {\n // Fetch public/private channels\n let cursor: string | undefined;\n do {\n const result = await this.webClient.conversations.list({\n types: \"public_channel,private_channel\",\n exclude_archived: true,\n limit: 200,\n cursor,\n });\n const channels = result.channels as\n | Array<{ id?: string; name?: string; is_member?: boolean }>\n | undefined;\n if (channels) {\n for (const c of channels) {\n if (c.id && c.name && c.is_member) {\n this.channels.set(c.id, { id: c.id, name: c.name });\n }\n }\n }\n cursor = result.response_metadata?.next_cursor;\n } while (cursor);\n\n // Also fetch DM channels (IMs)\n cursor = undefined;\n do {\n const result = await this.webClient.conversations.list({\n types: \"im\",\n limit: 200,\n cursor,\n });\n const ims = result.channels as Array<{ id?: string; user?: string }> | undefined;\n if (ims) {\n for (const im of ims) {\n if (im.id) {\n // Use user's name as channel name for DMs\n const user = im.user ? this.users.get(im.user) : undefined;\n const name = user ? `DM:${user.userName}` : `DM:${im.id}`;\n this.channels.set(im.id, { id: im.id, name });\n }\n }\n }\n cursor = result.response_metadata?.next_cursor;\n } while (cursor);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"bot.js","sourceRoot":"","sources":["../../../src/adapters/slack/bot.ts"],"names":[],"mappings":"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","sourcesContent":["import { SocketModeClient } from \"@slack/socket-mode\";\nimport type { KnownBlock } from \"@slack/types\";\nimport { WebClient } from \"@slack/web-api\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { readFile } from \"fs/promises\";\nimport { basename, join } from \"path\";\nimport type {\n MessagingBot,\n ConversationContext,\n ConversationEvent,\n MessagingEventHandler,\n ConversationMessage,\n ConversationResponder,\n ChatToolResult,\n ConversationKind,\n MessagingInfo,\n} from \"../../adapter.js\";\nimport { resolveConversationSettings } from \"../../config.js\";\nimport type { EventsWatcher } from \"../../events.js\";\nimport * as log from \"../../log.js\";\nimport type { Attachment, ChannelStore } from \"../../store.js\";\nimport type {\n SlackBlockAction,\n SlackBlockActionBody,\n SlackChannel,\n SlackEvent,\n SlackUser,\n} from \"./types.js\";\nimport { PRODUCT_NAME, formatForceStopped, formatNothingRunning } from \"../../platform-messages.js\";\nimport {\n appendBotResponseLog,\n appendChannelLog,\n MessagingEventQueue,\n resolveOnlyScopedStopTarget,\n resolveStopTarget,\n withRetry,\n} from \"../shared.js\";\nimport { processMessageIntake } from \"../intake.js\";\nimport { createSlackAdapters } from \"./context.js\";\nimport {\n hasMaterializedChatSession,\n registerThreadSession,\n} from \"../../sessions/agent-memory-file-manager.js\";\nimport {\n isSlackThreadSessionKey,\n planSlackAdapterSession,\n planSlackEventAnchorRun,\n resolveSlackSessionKey,\n} from \"./session.js\";\nimport { reportUserFacingError } from \"../../observability/sentry.js\";\nimport { renderSlackBlocks } from \"./blocks.js\";\n\nconst SLACK_EVENT_ANCHOR_TEXT = \"Working on it...\";\n\n// Slack WebClient errors carry either `code: \"rate_limited\"` (retry-after) or\n// the legacy `data.error === \"rate_limited\"` / 429 status shape.\nfunction slackIsRateLimited(err: Error): boolean {\n if ((err as { code?: unknown }).code === \"rate_limited\") return true;\n const data = (err as { data?: { error?: string; response?: { status?: number } } }).data;\n return data?.error === \"rate_limited\" || data?.response?.status === 429;\n}\n\nconst slackRetry = <T>(fn: () => Promise<T>): Promise<T> =>\n withRetry(fn, { isRateLimited: slackIsRateLimited });\n\nfunction collectSlackText(value: unknown, parts: string[]): void {\n if (value === null || value === undefined) return;\n if (typeof value === \"string\") {\n const trimmed = value.trim();\n if (trimmed) parts.push(trimmed);\n return;\n }\n if (Array.isArray(value)) {\n for (const item of value) collectSlackText(item, parts);\n return;\n }\n if (typeof value !== \"object\") return;\n\n const obj = value as Record<string, unknown>;\n for (const key of [\"text\", \"fallback\", \"title\", \"value\"] as const) {\n collectSlackText(obj[key], parts);\n }\n collectSlackText(obj.fields, parts);\n collectSlackText(obj.elements, parts);\n collectSlackText(obj.blocks, parts);\n}\n\nfunction buildSlackAppMessageText(event: {\n text?: string;\n blocks?: unknown[];\n attachments?: unknown[];\n}): string {\n const parts: string[] = [];\n collectSlackText(event.text, parts);\n collectSlackText(event.blocks, parts);\n collectSlackText(event.attachments, parts);\n const deduped = parts.filter((part, index) => parts.indexOf(part) === index);\n return deduped.join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Shared mrkdwn truncation helper\n// ---------------------------------------------------------------------------\n\nconst MRKDWN_CONTEXT_TEXT_LIMIT = 3000;\n\n/**\n * Build a Slack context block whose text is capped at the mrkdwn limit.\n * Used for muted diagnostics and ephemeral command responses.\n */\nexport function buildMrkdwnContextBlock(text: string): object {\n const blockText =\n text.length > MRKDWN_CONTEXT_TEXT_LIMIT\n ? text.substring(0, MRKDWN_CONTEXT_TEXT_LIMIT - 20) + \"\\n_(truncated)_\"\n : text;\n return { type: \"context\", elements: [{ type: \"mrkdwn\", text: blockText }] };\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type { SlackChannel, SlackEvent, SlackUser } from \"./types.js\";\n\n// ============================================================================\n// SlackMessagingBot\n// ============================================================================\n\nexport class SlackMessagingBot implements MessagingBot {\n private socketClient: SocketModeClient;\n private webClient: WebClient;\n private handler: MessagingEventHandler;\n private workingDir: string;\n private store: ChannelStore;\n private botUserId: string | null = null;\n private botId: string | null = null;\n private teamId: string | null = null;\n private ownMentionRegex: RegExp | null = null;\n private startupTs: string | null = null; // Messages older than this are just logged, not processed\n\n private users = new Map<string, SlackUser>();\n private channels = new Map<string, SlackChannel>();\n private queues = new Map<string, MessagingEventQueue>();\n private eventsWatcher: EventsWatcher | null = null;\n\n private createContext(event: SlackEvent): ConversationContext {\n return createSlackAdapters(event, this, {\n replyMode:\n resolveConversationSettings(join(this.workingDir, event.conversationId)).slack?.replyMode ??\n \"top-level\",\n });\n }\n\n constructor(\n handler: MessagingEventHandler,\n config: { appToken: string; botToken: string; workingDir: string; store: ChannelStore },\n ) {\n this.handler = handler;\n this.workingDir = config.workingDir;\n this.store = config.store;\n this.socketClient = new SocketModeClient({\n appToken: config.appToken,\n // Default 5s is too tight: brief event-loop stalls (e.g. backfill, sync fs)\n // cause false pong timeouts; 4 in a row makes Slack drop the socket.\n clientPingTimeout: 12_000,\n });\n this.webClient = new WebClient(config.botToken);\n }\n\n setEventsWatcher(watcher: EventsWatcher): void {\n this.eventsWatcher = watcher;\n }\n\n // ==========================================================================\n // Public API\n // ==========================================================================\n\n async start(): Promise<void> {\n const auth = await this.webClient.auth.test();\n this.botUserId = auth.user_id as string;\n this.botId = typeof auth.bot_id === \"string\" ? auth.bot_id : null;\n this.teamId = typeof auth.team_id === \"string\" ? auth.team_id : null;\n\n await Promise.all([this.fetchUsers(), this.fetchChannels()]);\n log.logInfo(`Loaded ${this.channels.size} channels, ${this.users.size} users`);\n\n // Record startup time before opening the socket. Slack may replay older events;\n // those should be logged but not processed. Backfill runs in the background up\n // to this timestamp so startup is not blocked by one history call per channel.\n this.startupTs = (Date.now() / 1000).toFixed(6);\n\n this.setupEventHandlers();\n await this.socketClient.start();\n\n log.logConnected(\"Slack\");\n\n void this.backfillAllChannels(this.startupTs).catch((error) => {\n log.logWarning(\"Slack backfill failed\", String(error));\n });\n }\n\n getUser(userId: string): SlackUser | undefined {\n return this.users.get(userId);\n }\n\n getChannel(channelId: string): SlackChannel | undefined {\n return this.channels.get(channelId);\n }\n\n getAllUsers(): SlackUser[] {\n return Array.from(this.users.values());\n }\n\n getAllChannels(): SlackChannel[] {\n return Array.from(this.channels.values());\n }\n\n private stripOwnMention(text: string | undefined): string {\n const source = text ?? \"\";\n if (!this.botUserId) return source.trim();\n if (!this.ownMentionRegex || !this.ownMentionRegex.source.includes(this.botUserId)) {\n this.ownMentionRegex = new RegExp(`<@${this.botUserId}>`, \"gi\");\n }\n return source.replace(this.ownMentionRegex, \"\").trim();\n }\n\n async postMessage(channel: string, text: string): Promise<string> {\n return slackRetry(async () => {\n const payload = { channel, ...renderSlackBlocks(text) };\n const result = await this.webClient.chat.postMessage(payload);\n return result.ts as string;\n });\n }\n\n async postEphemeral(\n channel: string,\n user: string,\n text: string,\n threadTs?: string,\n ): Promise<void> {\n return slackRetry(async () => {\n await this.webClient.chat.postEphemeral({\n channel,\n user,\n text,\n ...(threadTs ? { thread_ts: threadTs } : {}),\n });\n });\n }\n\n async postEphemeralBlocks(\n channel: string,\n user: string,\n text: string,\n blocks: object[],\n threadTs?: string,\n ): Promise<void> {\n return slackRetry(async () => {\n await this.webClient.chat.postEphemeral({\n channel,\n user,\n text,\n blocks: blocks as KnownBlock[],\n ...(threadTs ? { thread_ts: threadTs } : {}),\n });\n });\n }\n\n async postMessageBlocks(channel: string, text: string, blocks: object[]): Promise<string> {\n return slackRetry(async () => {\n const payload = { channel, text, blocks: blocks as KnownBlock[] };\n const result = await this.webClient.chat.postMessage(payload);\n return result.ts as string;\n });\n }\n\n async postPrivate(conversationId: string, userId: string, text: string): Promise<void> {\n await this.postEphemeral(conversationId, userId, text);\n }\n\n async postPrivateDiagnostic(\n conversationId: string,\n userId: string,\n text: string,\n options?: { style?: \"muted\" | \"error\" },\n ): Promise<void> {\n if (options?.style !== \"muted\") {\n await this.postEphemeral(\n conversationId,\n userId,\n options?.style === \"error\" ? `_${text}_` : text,\n );\n return;\n }\n await this.postEphemeralBlocks(conversationId, userId, text, [buildMrkdwnContextBlock(text)]);\n }\n\n async openDirectMessage(userId: string): Promise<string> {\n return slackRetry(async () => {\n const result = await this.webClient.conversations.open({ users: userId });\n const channelId = result.channel?.id;\n if (!channelId) {\n throw new Error(`Failed to open DM for user ${userId}`);\n }\n return channelId;\n });\n }\n\n async updateMessage(channel: string, ts: string, text: string): Promise<void> {\n return slackRetry(async () => {\n const payload = { channel, ts, ...renderSlackBlocks(text) };\n await this.webClient.chat.update(payload);\n });\n }\n\n async startMessageStream(\n channel: string,\n text: string,\n threadTs?: string,\n recipientUserId?: string,\n ): Promise<string> {\n return slackRetry(async () => {\n const result = await this.webClient.apiCall(\"chat.startStream\", {\n channel,\n markdown_text: text,\n ...(threadTs ? { thread_ts: threadTs } : {}),\n ...(this.teamId ? { recipient_team_id: this.teamId } : {}),\n ...(recipientUserId ? { recipient_user_id: recipientUserId } : {}),\n });\n const ts = (result as { ts?: string }).ts;\n if (!ts) throw new Error(\"Slack chat.startStream did not return ts\");\n return ts;\n });\n }\n\n async appendMessageStream(channel: string, ts: string, text: string): Promise<void> {\n return slackRetry(async () => {\n await this.webClient.apiCall(\"chat.appendStream\", {\n channel,\n ts,\n markdown_text: text,\n });\n });\n }\n\n async stopMessageStream(channel: string, ts: string): Promise<void> {\n return slackRetry(async () => {\n await this.webClient.apiCall(\"chat.stopStream\", { channel, ts });\n });\n }\n\n async deleteMessage(channel: string, ts: string): Promise<void> {\n return slackRetry(async () => {\n await this.webClient.chat.delete({ channel, ts });\n });\n }\n\n // ==========================================================================\n // Slack Assistant API (AI assistant experience)\n // ==========================================================================\n\n /** Set the status for an assistant thread (shows \"thinking\" state) */\n async setAssistantStatus(channel: string, threadTs: string, status: string): Promise<void> {\n return slackRetry(async () => {\n await this.webClient.assistant.threads.setStatus({\n channel_id: channel,\n thread_ts: threadTs,\n status,\n });\n });\n }\n\n async postInThread(channel: string, threadTs: string, text: string): Promise<string> {\n return slackRetry(async () => {\n const payload = { channel, thread_ts: threadTs, ...renderSlackBlocks(text) };\n const result = await this.webClient.chat.postMessage(payload);\n return result.ts as string;\n });\n }\n\n async postInThreadBlocks(\n channel: string,\n threadTs: string,\n text: string,\n blocks: object[],\n ): Promise<string> {\n return slackRetry(async () => {\n const payload = {\n channel,\n thread_ts: threadTs,\n text, // fallback for notifications\n blocks: blocks as KnownBlock[],\n };\n const result = await this.webClient.chat.postMessage(payload);\n return result.ts as string;\n });\n }\n\n async uploadFile(\n channel: string,\n filePath: string,\n title?: string,\n threadTs?: string,\n ): Promise<void> {\n return slackRetry(async () => {\n const fileName = title || basename(filePath);\n const fileContent = readFileSync(filePath);\n await this.webClient.files.uploadV2({\n channel_id: channel,\n file: fileContent,\n filename: fileName,\n title: fileName,\n ...(threadTs ? { thread_ts: threadTs } : {}),\n } as Parameters<typeof this.webClient.files.uploadV2>[0]);\n });\n }\n\n logToFile(channel: string, entry: object): void {\n appendChannelLog(this.workingDir, channel, entry);\n }\n\n logBotResponse(\n channel: string,\n text: string,\n ts: string,\n threadTs?: string,\n slackBlocks?: object[],\n ): void {\n appendBotResponseLog(this.workingDir, channel, text, ts, threadTs, {\n platform: \"slack\",\n ...(slackBlocks ? { slackBlocks } : {}),\n });\n }\n\n getMessagingInfo(): MessagingInfo {\n return {\n name: \"slack\",\n formattingGuide:\n \"## Slack Formatting (mrkdwn, NOT Markdown)\\nBold: *text*, Italic: _text_, Code: `code`, Block: ```code```, Links: <url|text>\\nDo NOT use **double asterisks** or [markdown](links).\",\n channels: this.getAllChannels().map((c) => ({ id: c.id, name: c.name })),\n users: this.getAllUsers().map((u) => ({\n id: u.id,\n userName: u.userName,\n displayName: u.displayName,\n })),\n diagnostics: {\n showUsageSummary: true,\n },\n };\n }\n\n // ==========================================================================\n // Events Integration\n // ==========================================================================\n\n /**\n * Enqueue an event for processing. Always queues (no \"already working\" rejection).\n * Returns true if enqueued, false if queue is full (max 5).\n */\n enqueueEvent(event: ConversationEvent): boolean {\n const conversationId = event.conversationId;\n const queue = this.getQueue(conversationId);\n if (queue.size() >= 5) {\n log.logWarning(\n `Event queue full for ${conversationId}, discarding: ${event.text.substring(0, 50)}`,\n );\n return false;\n }\n log.logInfo(`Enqueueing event for ${conversationId}: ${event.text.substring(0, 50)}`);\n queue.enqueue(async () => {\n let anchorTs: string | undefined;\n if (!event.thread_ts) {\n try {\n anchorTs = await this.postMessage(conversationId, SLACK_EVENT_ANCHOR_TEXT);\n } catch (err) {\n log.logWarning(\n `Failed to post Slack event anchor for ${conversationId}`,\n err instanceof Error ? err.message : String(err),\n );\n reportUserFacingError(err, {\n domain: \"events\",\n surface: \"event_delivery\",\n operation: \"slack_anchor_post\",\n severity: \"error\",\n platform: \"slack\",\n context: {\n conversationId,\n conversationKind: event.conversationKind,\n eventTs: event.ts,\n textLength: event.text.length,\n },\n });\n throw err;\n }\n }\n const eventPlan = planSlackEventAnchorRun(event, anchorTs);\n const eventForRun = eventPlan.event;\n if (eventPlan.initialMessageTs && eventForRun.sessionKey) {\n registerThreadSession({\n conversationDir: join(this.workingDir, conversationId),\n sessionKey: eventForRun.sessionKey,\n });\n }\n\n const runQueueKey = planSlackAdapterSession(eventForRun, {\n initialMessageTs: eventPlan.initialMessageTs,\n }).sessionKey;\n this.getQueue(runQueueKey).enqueue(async () => {\n const slackEvent: SlackEvent = {\n type: eventForRun.type as SlackEvent[\"type\"],\n conversationId,\n conversationKind: eventForRun.conversationKind,\n channel: conversationId,\n ts: eventForRun.ts,\n thread_ts: eventForRun.thread_ts,\n user: eventForRun.user,\n text: eventForRun.text,\n attachments: eventForRun.attachments?.map((attachment) => ({\n original: attachment.name,\n localPath: attachment.localPath,\n })),\n sessionKey: eventForRun.sessionKey,\n };\n const context = createSlackAdapters(slackEvent, this, {\n initialMessageTs: eventPlan.initialMessageTs,\n replyMode:\n resolveConversationSettings(join(this.workingDir, eventForRun.conversationId)).slack\n ?.replyMode ?? \"top-level\",\n });\n return this.handler.handleEvent(eventForRun, this, context);\n });\n });\n return true;\n }\n\n // ==========================================================================\n // Private - Event Handlers\n // ==========================================================================\n\n private getQueue(channelId: string): MessagingEventQueue {\n let queue = this.queues.get(channelId);\n if (!queue) {\n queue = new MessagingEventQueue(\"Slack\");\n this.queues.set(channelId, queue);\n }\n return queue;\n }\n\n private resolveQueueKey(conversationId: string, sessionKey: string): string {\n if (!isSlackThreadSessionKey(sessionKey)) return sessionKey;\n if (this.handler.isRunning(sessionKey)) return sessionKey;\n return this.hasKnownThreadSession(conversationId, sessionKey) ? sessionKey : conversationId;\n }\n\n private hasKnownThreadSession(conversationId: string, sessionKey: string): boolean {\n return hasMaterializedChatSession({\n conversationDir: join(this.workingDir, conversationId),\n sessionKey,\n });\n }\n\n private processSlackMessageIntake(options: {\n event: SlackEvent;\n attachmentsPromise: Promise<Attachment[]>;\n queueKey: string;\n isAutoReplyCandidate: boolean;\n onNotTriggered?: () => void;\n }): void {\n void processMessageIntake({\n eventBase: options.event as unknown as ConversationEvent,\n workingDir: this.workingDir,\n isAutoReplyCandidate: options.isAutoReplyCandidate,\n logEntryBase: {},\n processAttachments: () => options.attachmentsPromise,\n queueKey: options.queueKey,\n enqueue: (queueKey, work) => this.getQueue(queueKey).enqueue(work),\n handler: this.handler,\n bot: this,\n createContext: (event) => this.createContext(event as SlackEvent),\n onNotTriggered: options.onNotTriggered,\n deferAttachmentsUntilRun: true,\n });\n }\n\n private buildHomeView(): { type: \"home\"; blocks: KnownBlock[] } {\n const blocks: object[] = [\n {\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: `*${PRODUCT_NAME}*\\nStart a new task or check on running work.`,\n },\n accessory: {\n type: \"image\",\n image_url: \"https://media1.tenor.com/m/lfDATg4Bhc0AAAAC/happy-cat.gif\",\n alt_text: PRODUCT_NAME,\n },\n },\n ];\n\n // --- Running tasks ---\n const runningSessions = this.handler.getRunningSessions();\n\n blocks.push(\n { type: \"divider\" },\n {\n type: \"header\",\n text: {\n type: \"plain_text\",\n text: `Running Tasks (${runningSessions.length})`,\n emoji: true,\n },\n },\n );\n\n if (runningSessions.length === 0) {\n blocks.push({\n type: \"context\",\n elements: [{ type: \"mrkdwn\", text: \"_No tasks running right now._\" }],\n });\n } else {\n // Threshold for \"stuck\" detection (10 minutes)\n const STUCK_THRESHOLD_MS = 10 * 60 * 1000;\n\n for (const session of runningSessions) {\n const channelId = session.sessionKey.split(\":\")[0];\n const channel = this.channels.get(channelId);\n const channelName = channel ? `#${channel.name}` : channelId;\n const elapsed = Math.floor((Date.now() - session.startedAt) / 60000);\n const elapsedStr = elapsed < 1 ? \"<1 min\" : `${elapsed} min`;\n\n // Check if task might be stuck\n const lastActivity = session.lastActivityAt ? Date.now() - session.lastActivityAt : 0;\n const isStuck = lastActivity > STUCK_THRESHOLD_MS;\n const statusText = isStuck ? \"_stuck_\" : \"_running_\";\n\n // Build status line: channel · status · time · step\n let statusLine = `${statusText} · ${elapsedStr}`;\n if (session.currentTool) {\n statusLine += ` · ${session.currentTool}`;\n }\n if (isStuck && lastActivity > 0) {\n const inactiveMin = Math.floor(lastActivity / 60000);\n statusLine += ` · idle ${inactiveMin}m`;\n }\n\n // Use context block for gray small text (like \"No scheduled jobs.\")\n blocks.push({\n type: \"context\",\n elements: [\n {\n type: \"mrkdwn\",\n text: `*${channelName}* · ${statusLine}`,\n },\n ],\n });\n\n // Add Force Stop button as separate element if stuck\n if (isStuck) {\n blocks.push({\n type: \"context\",\n elements: [\n {\n type: \"mrkdwn\",\n text: \" \",\n },\n {\n type: \"button\",\n text: { type: \"plain_text\", text: \"Force Stop\", emoji: true },\n action_id: `force_stop_${session.sessionKey.replace(/:/g, \"_\")}`,\n style: \"danger\",\n },\n ],\n });\n }\n }\n }\n\n // --- Cron jobs ---\n const periodicEvents = this.eventsWatcher?.getPeriodicEvents() ?? [];\n\n blocks.push(\n { type: \"divider\" },\n {\n type: \"header\",\n text: {\n type: \"plain_text\",\n text: `Scheduled Jobs (${periodicEvents.length})`,\n emoji: true,\n },\n },\n );\n\n if (periodicEvents.length === 0) {\n blocks.push({\n type: \"context\",\n elements: [{ type: \"mrkdwn\", text: \"_No scheduled jobs._\" }],\n });\n } else {\n for (const ev of periodicEvents) {\n const channelLabel =\n ev.platform === \"slack\"\n ? (() => {\n const channel = this.channels.get(ev.conversationId);\n const channelName = channel ? `#${channel.name}` : ev.conversationId;\n return `${ev.platform}:${channelName}`;\n })()\n : `${ev.platform}:${ev.conversationId}`;\n const nextStr = ev.nextRun\n ? new Date(ev.nextRun).toLocaleString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n })\n : \"—\";\n blocks.push({\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: `*${ev.text}*\\n└ \\`${ev.schedule}\\` · ${channelLabel} · Next: ${nextStr}`,\n },\n });\n }\n }\n\n // --- Footer ---\n blocks.push(\n { type: \"divider\" },\n {\n type: \"context\",\n elements: [\n { type: \"mrkdwn\", text: \"💡 @mention in a channel or send a DM to start a new task\" },\n ],\n },\n );\n\n return { type: \"home\", blocks: blocks as KnownBlock[] };\n }\n\n private resolveStopTarget(channelId: string, threadTs?: string): string | null {\n const directTarget = resolveStopTarget({\n handler: this.handler,\n conversationId: channelId,\n sessionKey: resolveSlackSessionKey(channelId, threadTs),\n });\n if (directTarget) return directTarget;\n if (threadTs) return null;\n return resolveOnlyScopedStopTarget(this.handler, channelId);\n }\n\n private isStopText(text: string): boolean {\n const normalized = text.trim().toLowerCase();\n return normalized === \"stop\" || normalized === \"/stop\";\n }\n\n private createCommandAdapters(\n conversationId: string,\n userId: string,\n userName: string | undefined,\n text: string,\n ts: string,\n options: { ephemeralChannelId?: string; threadTs?: string } = {},\n ): ConversationContext {\n const message: ConversationMessage = {\n id: ts,\n sessionKey: conversationId,\n conversationKind: options.ephemeralChannelId ? \"shared\" : \"direct\",\n userId,\n userName,\n text,\n attachments: [],\n };\n\n const respond = async (responseText: string) => {\n if (options.ephemeralChannelId) {\n await this.postEphemeral(\n options.ephemeralChannelId,\n userId,\n responseText,\n options.threadTs,\n );\n return;\n }\n const messageTs = await this.postMessage(conversationId, responseText);\n this.logBotResponse(conversationId, responseText, messageTs);\n };\n\n const respondMuted = async (responseText: string) => {\n const blocks = [buildMrkdwnContextBlock(responseText)];\n if (options.ephemeralChannelId) {\n await this.postEphemeralBlocks(\n options.ephemeralChannelId,\n userId,\n responseText,\n blocks,\n options.threadTs,\n );\n return;\n }\n const messageTs = await this.postMessageBlocks(conversationId, responseText, blocks);\n this.logBotResponse(conversationId, responseText, messageTs);\n };\n\n const responder: ConversationResponder = {\n respond,\n replaceResponse: respond,\n respondDiagnostic: async (\n responseText: string,\n responseOptions?: { style?: \"muted\" | \"error\" },\n ) => {\n if (responseOptions?.style === \"muted\") {\n await respondMuted(responseText);\n return;\n }\n await respond(responseOptions?.style === \"error\" ? `_${responseText}_` : responseText);\n },\n respondToolResult: async (result: ChatToolResult) => {\n const duration = (result.durationMs / 1000).toFixed(1);\n await respond(\n `${result.isError ? \"Error\" : \"Done\"} ${result.toolName} (${duration}s)\\n${result.result}`,\n );\n },\n setTyping: async () => {},\n setWorking: async () => {},\n uploadFile: async (filePath: string, title?: string) => {\n await this.uploadFile(conversationId, filePath, title);\n },\n deleteResponse: async () => {},\n };\n\n return {\n message,\n responder,\n platform: this.getMessagingInfo(),\n };\n }\n\n private buildSlashCommandEvent(\n payload: {\n command: string;\n text?: string;\n channel_id: string;\n user_id: string;\n user_name?: string;\n thread_ts?: string;\n },\n options: { type?: ConversationEvent[\"type\"]; includeText?: boolean; thread?: boolean } = {},\n ): { event: ConversationEvent; context: ConversationContext } {\n const conversationId = payload.channel_id;\n const isDirectMessage = conversationId.startsWith(\"D\");\n const createdAt = new Date();\n const eventTs = (createdAt.getTime() / 1000).toFixed(6);\n const userName = payload.user_name ?? this.getUser(payload.user_id)?.userName;\n const commandSuffix = options.includeText ? payload.text?.trim() : undefined;\n const commandText = commandSuffix ? `${payload.command} ${commandSuffix}` : payload.command;\n const threadTs = options.thread ? payload.thread_ts : undefined;\n const sessionKey = options.thread\n ? resolveSlackSessionKey(conversationId, threadTs)\n : conversationId;\n\n this.logToFile(conversationId, {\n date: createdAt.toISOString(),\n ts: eventTs,\n user: payload.user_id,\n userName,\n text: commandText,\n attachments: [],\n isMessagingBot: false,\n ...(threadTs ? { threadTs } : {}),\n });\n\n const event: ConversationEvent = {\n type: options.type ?? (isDirectMessage ? \"dm\" : \"mention\"),\n conversationId,\n conversationKind: isDirectMessage ? \"direct\" : \"shared\",\n ts: eventTs,\n user: payload.user_id,\n text: commandText,\n attachments: [],\n ...(threadTs ? { thread_ts: threadTs } : {}),\n sessionKey,\n };\n\n const context = this.createCommandAdapters(\n conversationId,\n payload.user_id,\n userName,\n commandText,\n eventTs,\n isDirectMessage ? { threadTs } : { ephemeralChannelId: conversationId, threadTs },\n );\n\n return { event, context };\n }\n\n private async routeSlashLoginCommand(payload: {\n command: string;\n text?: string;\n channel_id: string;\n user_id: string;\n user_name?: string;\n }): Promise<void> {\n const { event, context } = this.buildSlashCommandEvent(payload, {\n type: payload.channel_id.startsWith(\"D\") ? \"dm\" : \"private_command\",\n includeText: true,\n });\n await this.handler.handleEvent(event, this, context);\n }\n\n private async routeSlashNewCommand(payload: {\n command: string;\n channel_id: string;\n user_id: string;\n user_name?: string;\n }): Promise<void> {\n const conversationId = payload.channel_id;\n if (!conversationId.startsWith(\"D\")) {\n await this.postEphemeral(\n conversationId,\n payload.user_id,\n `為了避免誤清除共享上下文,${payload.command} 目前只能在與 ${PRODUCT_NAME} 的私訊中使用。`,\n );\n return;\n }\n\n const createdAt = new Date();\n const eventTs = (createdAt.getTime() / 1000).toFixed(6);\n const userName = payload.user_name ?? this.getUser(payload.user_id)?.userName;\n\n this.logToFile(conversationId, {\n date: createdAt.toISOString(),\n ts: eventTs,\n user: payload.user_id,\n userName,\n text: payload.command,\n attachments: [],\n isMessagingBot: false,\n });\n\n const commandMessagingBot: MessagingBot = {\n start: async () => {},\n postMessage: async (_channel: string, text: string) => this.postMessage(conversationId, text),\n updateMessage: async (channel: string, ts: string, text: string) =>\n this.updateMessage(channel, ts, text),\n enqueueEvent: (event: ConversationEvent) => this.enqueueEvent(event),\n getMessagingInfo: () => this.getMessagingInfo(),\n };\n await this.handler.handleNewCommand(conversationId, conversationId, commandMessagingBot);\n }\n\n private async routeSlashModelCommand(payload: {\n command: string;\n text?: string;\n channel_id: string;\n user_id: string;\n user_name?: string;\n }): Promise<void> {\n const { event, context } = this.buildSlashCommandEvent(payload, { includeText: true });\n await this.handler.handleEvent(event, this, context);\n }\n\n private async routeSlashSessionCommand(payload: {\n command: string;\n channel_id: string;\n user_id: string;\n user_name?: string;\n thread_ts?: string;\n }): Promise<void> {\n const { event, context } = this.buildSlashCommandEvent(payload, { thread: true });\n await this.handler.handleEvent(event, this, context);\n }\n\n private async routeSlashAdminCommand(payload: {\n command: string;\n channel_id: string;\n user_id: string;\n user_name?: string;\n thread_ts?: string;\n }): Promise<void> {\n const { event, context } = this.buildSlashCommandEvent(payload, { thread: true });\n await this.handler.handleEvent(event, this, context);\n }\n\n private setupEventHandlers(): void {\n this.socketClient.on(\"disconnect\", (err: unknown) => {\n log.logWarning(\"Slack socket disconnect\", err ? String(err) : \"\");\n });\n this.socketClient.on(\"error\", (err: unknown) => {\n log.logWarning(\"Slack socket error\", err ? String(err) : \"\");\n });\n this.socketClient.on(\"unable_to_socket_mode_start\", (err: unknown) => {\n log.logWarning(\"Slack socket unable_to_start\", err ? String(err) : \"\");\n });\n\n this.socketClient.on(\"app_mention\", (payload) => this.handleAppMention(payload));\n this.socketClient.on(\"message\", (payload) => this.handleMessageEvent(payload));\n this.socketClient.on(\"slash_commands\", (payload) => void this.handleSlashCommand(payload));\n this.socketClient.on(\"app_home_opened\", (payload) => this.handleAppHomeOpened(payload));\n this.socketClient.on(\"block_actions\", (payload) => void this.handleBlockAction(payload));\n this.socketClient.on(\n \"interactive\",\n (payload) =>\n void this.handleBlockAction(payload as { body: SlackBlockActionBody; ack: () => void }),\n );\n }\n\n private handleAppMention({ event, ack }: { event: unknown; ack: () => void }): void {\n const e = event as {\n text: string;\n channel: string;\n user: string;\n ts: string;\n thread_ts?: string;\n files?: Array<{ name: string; url_private_download?: string; url_private?: string }>;\n };\n\n // Skip DMs (handled by message event)\n if (e.channel.startsWith(\"D\")) {\n ack();\n return;\n }\n\n // Top-level mentions use a persistent channel session.\n // Thread replies get their own isolated session (channelId:thread_ts).\n const sessionKey = resolveSlackSessionKey(e.channel, e.thread_ts);\n\n const mentionText = this.stripOwnMention(e.text);\n const slackEvent: SlackEvent = {\n type: \"mention\",\n conversationId: e.channel,\n conversationKind: \"shared\",\n channel: e.channel,\n ts: e.ts,\n thread_ts: e.thread_ts,\n user: e.user,\n text: mentionText || \"Please respond to the recent conversation context.\",\n files: e.files,\n sessionKey,\n };\n\n const attachmentsPromise = this.logUserMessage(slackEvent);\n\n // Only trigger processing for messages AFTER startup (not replayed old messages)\n if (this.startupTs && e.ts < this.startupTs) {\n log.logInfo(\n `[${e.channel}] Logged old message (pre-startup), not triggering: ${slackEvent.text.substring(0, 30)}`,\n );\n void attachmentsPromise.catch((err) => {\n log.logWarning(\"Failed to log Slack message\", String(err));\n });\n ack();\n return;\n }\n\n // Check for stop command - execute immediately, don't queue!\n if (this.isStopText(slackEvent.text)) {\n const stopTarget = this.resolveStopTarget(e.channel, e.thread_ts);\n if (stopTarget) {\n this.handler.handleStop(stopTarget, e.channel, this);\n } else {\n this.postMessage(e.channel, formatNothingRunning(\"slack\"));\n }\n void attachmentsPromise.catch((err) => {\n log.logWarning(\"Failed to log Slack message\", String(err));\n });\n ack();\n return;\n }\n\n this.processSlackMessageIntake({\n event: slackEvent,\n attachmentsPromise,\n queueKey: this.resolveQueueKey(e.channel, sessionKey),\n isAutoReplyCandidate: false,\n });\n\n ack();\n }\n\n private handleMessageEvent({ event, ack }: { event: unknown; ack: () => void }): void {\n const e = event as {\n text?: string;\n channel: string;\n user?: string;\n ts: string;\n thread_ts?: string;\n channel_type?: string;\n subtype?: string;\n bot_id?: string;\n app_id?: string;\n username?: string;\n bot_profile?: { id?: string; app_id?: string; name?: string; real_name?: string };\n blocks?: unknown[];\n attachments?: unknown[];\n files?: Array<{ name: string; url_private_download?: string; url_private?: string }>;\n };\n\n const hasFiles = !!e.files && e.files.length > 0;\n const hasSlackContent = !!e.text || hasFiles || !!e.blocks?.length || !!e.attachments?.length;\n const isOwnMessagingBotMessage =\n (!!e.user && e.user === this.botUserId) || (!!this.botId && e.bot_id === this.botId);\n if (isOwnMessagingBotMessage) {\n ack();\n return;\n }\n\n const isExternalMessagingBotMessage = !!e.bot_id || e.subtype === \"bot_message\";\n if (isExternalMessagingBotMessage) {\n if (e.subtype !== undefined && e.subtype !== \"bot_message\" && e.subtype !== \"file_share\") {\n ack();\n return;\n }\n if (!hasSlackContent) {\n ack();\n return;\n }\n void this.logExternalMessagingBotMessage(e).catch((err) => {\n log.logWarning(\"Failed to log Slack bot message\", String(err));\n });\n ack();\n return;\n }\n\n if (!e.user) {\n ack();\n return;\n }\n if (e.subtype !== undefined && e.subtype !== \"file_share\") {\n ack();\n return;\n }\n if (!hasSlackContent) {\n ack();\n return;\n }\n\n const isDM = e.channel_type === \"im\";\n const conversationKind: ConversationKind = isDM ? \"direct\" : \"shared\";\n const isMessagingBotMention = e.text?.includes(`<@${this.botUserId}>`);\n\n // Skip channel @mentions - already handled by app_mention event\n if (!isDM && isMessagingBotMention) {\n ack();\n return;\n }\n\n const isThreadReply = !!e.thread_ts;\n const sessionKey = isDM ? resolveSlackSessionKey(e.channel, e.thread_ts) : undefined;\n\n const slackEvent: SlackEvent = {\n type: isDM ? \"dm\" : \"mention\",\n conversationId: e.channel,\n conversationKind,\n channel: e.channel,\n ts: e.ts,\n thread_ts: e.thread_ts,\n user: e.user,\n text: this.stripOwnMention(e.text),\n files: e.files,\n sessionKey,\n };\n\n const attachmentsPromise = this.logUserMessage(slackEvent);\n\n // Only trigger processing for messages AFTER startup (not replayed old messages)\n if (this.startupTs && e.ts < this.startupTs) {\n log.logInfo(\n `[${e.channel}] Skipping old message (pre-startup): ${slackEvent.text.substring(0, 30)}`,\n );\n void attachmentsPromise.catch((err) => {\n log.logWarning(\"Failed to log Slack message\", String(err));\n });\n ack();\n return;\n }\n\n // Stop command for DM only (app_mention handles shared-channel \"@mikan stop\").\n if (isDM && this.isStopText(slackEvent.text)) {\n const stopTarget = this.resolveStopTarget(e.channel, e.thread_ts);\n if (stopTarget) {\n this.handler.handleStop(stopTarget, e.channel, this);\n } else {\n this.postMessage(e.channel, formatNothingRunning(\"slack\"));\n }\n void attachmentsPromise.catch((err) => {\n log.logWarning(\"Failed to log Slack message\", String(err));\n });\n ack();\n return;\n }\n\n const enqueueTriggered = () => {\n const activeSessionKey =\n slackEvent.sessionKey ?? resolveSlackSessionKey(e.channel, e.thread_ts);\n // Auto-reply top-level channel messages start with no sessionKey because\n // they are only candidates until the policy allows them. Once triggered,\n // persist the resolved key on the event; otherwise the runtime fallback\n // treats the message ts as a thread session (`channel:ts`) instead of the\n // persistent top-level channel session.\n slackEvent.sessionKey = activeSessionKey;\n this.processSlackMessageIntake({\n event: slackEvent,\n attachmentsPromise,\n queueKey: this.resolveQueueKey(e.channel, activeSessionKey),\n isAutoReplyCandidate: false,\n });\n };\n\n const logOnly = () => {\n void attachmentsPromise.catch((err) => {\n log.logWarning(\"Failed to log Slack message\", String(err));\n });\n };\n\n if (isDM) {\n enqueueTriggered();\n ack();\n return;\n }\n\n if (isThreadReply) {\n logOnly();\n ack();\n return;\n }\n\n const activeSessionKey = resolveSlackSessionKey(e.channel, e.thread_ts);\n slackEvent.sessionKey = activeSessionKey;\n this.processSlackMessageIntake({\n event: slackEvent,\n attachmentsPromise,\n queueKey: this.resolveQueueKey(e.channel, activeSessionKey),\n isAutoReplyCandidate: true,\n onNotTriggered: logOnly,\n });\n\n ack();\n }\n\n private async handleSlashCommand({\n body,\n ack,\n }: {\n body: unknown;\n ack: () => Promise<void>;\n }): Promise<void> {\n const payload = body as {\n command?: string;\n text?: string;\n channel_id?: string;\n user_id?: string;\n user_name?: string;\n thread_ts?: string;\n };\n\n await ack();\n\n if (!payload.command || !payload.channel_id || !payload.user_id) {\n return;\n }\n\n const { command, text, channel_id, user_id, user_name, thread_ts } = payload;\n\n let handlerPromise: Promise<void> | null = null;\n if (command === \"/pi-login\") {\n handlerPromise = this.routeSlashLoginCommand({\n command,\n text,\n channel_id,\n user_id,\n user_name,\n });\n } else if (command === \"/pi-new\") {\n handlerPromise = this.routeSlashNewCommand({ command, channel_id, user_id, user_name });\n } else if (command === \"/pi-session\") {\n handlerPromise = this.routeSlashSessionCommand({\n command,\n channel_id,\n user_id,\n user_name,\n thread_ts,\n });\n } else if (command === \"/pi-model\") {\n handlerPromise = this.routeSlashModelCommand({\n command,\n text,\n channel_id,\n user_id,\n user_name,\n });\n } else if (\n command === \"/pi-sandbox\" ||\n command === \"/pi-auto-reply\" ||\n command === \"/pi-extensions\"\n ) {\n handlerPromise = this.routeSlashModelCommand({\n command,\n text,\n channel_id,\n user_id,\n user_name,\n });\n } else if (command === \"/pi-admin\") {\n handlerPromise = this.routeSlashAdminCommand({\n command,\n channel_id,\n user_id,\n user_name,\n thread_ts,\n });\n }\n\n if (!handlerPromise) {\n return;\n }\n\n handlerPromise.catch((err) => {\n log.logWarning(\"Slack slash command error\", err instanceof Error ? err.message : String(err));\n });\n }\n\n private handleAppHomeOpened({ event, ack }: { event: unknown; ack: () => void }): void {\n const e = event as { user: string; tab: string };\n ack();\n if (e.tab !== \"home\") return;\n\n this.webClient.views\n .publish({\n user_id: e.user,\n view: this.buildHomeView(),\n })\n .catch((err) => {\n log.logWarning(`Failed to publish App Home view`, String(err));\n });\n }\n\n private async handleBlockAction({\n body,\n ack,\n }: {\n body: SlackBlockActionBody;\n ack: () => void;\n }): Promise<void> {\n const action = body.actions?.[0];\n if (!action) {\n ack();\n return;\n }\n\n if (!action.action_id?.startsWith(\"force_stop_\")) {\n ack();\n this.handleSlackInteraction(body, action);\n return;\n }\n\n ack();\n const sessionKey = action.action_id.replace(\"force_stop_\", \"\").replace(/_/g, \":\");\n const userId = body.user?.id;\n const channelId = body.container?.channel_id || sessionKey.split(\":\")[0];\n\n log.logInfo(`[Force Stop] User ${userId} requested force stop for ${sessionKey}`);\n\n // Use handler's forceStop method\n this.handler.forceStop(sessionKey);\n\n // Notify in channel\n await this.postMessage(channelId, formatForceStopped(\"slack\", userId ?? \"unknown\"));\n\n // Refresh home tab\n if (userId) {\n this.webClient.views\n .publish({\n user_id: userId,\n view: this.buildHomeView(),\n })\n .catch((err) => {\n log.logWarning(`Failed to refresh App Home view`, String(err));\n });\n }\n }\n\n private handleSlackInteraction(body: SlackBlockActionBody, action: SlackBlockAction): void {\n const container = body.container ?? {};\n const channelId = container.channel_id;\n const userId = body.user?.id;\n if (!channelId || !userId) return;\n\n const selectedOption = action.selected_option;\n const selectedOptions = Array.isArray(action.selected_options)\n ? action.selected_options\n : undefined;\n const selectedText = selectedOption?.text?.text ?? selectedOption?.value;\n const selectedTexts = selectedOptions?.map((option) => option.text?.text ?? option.value);\n const valueText = selectedTexts?.length\n ? selectedTexts.join(\", \")\n : (selectedText ?? action.value ?? action.action_id);\n const text = `[Slack action] ${action.action_id}: ${valueText}`;\n const ts = `action:${Date.now()}`;\n const threadTs = container.thread_ts;\n const sessionKey = resolveSlackSessionKey(channelId, threadTs);\n\n this.logToFile(channelId, {\n date: new Date().toISOString(),\n ts,\n ...(threadTs ? { threadTs } : {}),\n user: userId,\n userName: body.user?.username ?? body.user?.name,\n text,\n attachments: [],\n isMessagingBot: false,\n platform: \"slack\",\n slackInteraction: {\n type: \"block_actions\",\n actionId: action.action_id,\n blockId: action.block_id,\n actionType: action.type,\n value: action.value,\n selectedOption: selectedOption\n ? { text: selectedOption.text?.text, value: selectedOption.value }\n : undefined,\n selectedOptions: selectedOptions?.map((option) => ({\n text: option.text?.text,\n value: option.value,\n })),\n messageTs: container.message_ts,\n },\n });\n\n const event: ConversationEvent = {\n type: \"slack_action\",\n conversationId: channelId,\n conversationKind: channelId.startsWith(\"D\") ? \"direct\" : \"shared\",\n ts,\n user: userId,\n text,\n attachments: [],\n ...(threadTs ? { thread_ts: threadTs } : {}),\n sessionKey,\n };\n\n this.getQueue(this.resolveQueueKey(channelId, sessionKey)).enqueue(async () => {\n const slackEvent: SlackEvent = {\n type: event.conversationKind === \"direct\" ? \"dm\" : \"mention\",\n conversationId: channelId,\n conversationKind: event.conversationKind,\n channel: channelId,\n ts,\n thread_ts: threadTs,\n user: userId,\n text,\n attachments: [],\n sessionKey,\n };\n return this.handler.handleEvent(event, this, this.createContext(slackEvent));\n });\n }\n\n /**\n * Log a user message to log.jsonl after attachments are ready.\n */\n private async logUserMessage(event: SlackEvent): Promise<Attachment[]> {\n const user = this.users.get(event.user);\n let attachments: Attachment[] = [];\n let attachmentError: unknown;\n if (event.files) {\n try {\n attachments = await this.store.processAttachments(event.channel, event.files, event.ts);\n } catch (err) {\n attachmentError = err;\n }\n }\n // Always write the text log, even if attachment processing failed — we want\n // a record of the user message regardless of file-handling errors.\n this.logToFile(event.channel, {\n date: new Date(parseFloat(event.ts) * 1000).toISOString(),\n ts: event.ts,\n threadTs: event.thread_ts,\n user: event.user,\n userName: user?.userName,\n displayName: user?.displayName,\n text: event.text,\n attachments,\n isMessagingBot: false,\n });\n if (attachmentError) throw attachmentError;\n return attachments;\n }\n\n private async logExternalMessagingBotMessage(event: {\n channel: string;\n ts: string;\n thread_ts?: string;\n text?: string;\n subtype?: string;\n bot_id?: string;\n app_id?: string;\n username?: string;\n bot_profile?: { app_id?: string; name?: string; real_name?: string };\n blocks?: unknown[];\n attachments?: unknown[];\n files?: Array<{ name: string; url_private_download?: string; url_private?: string }>;\n }): Promise<Attachment[]> {\n const attachments = event.files\n ? await this.store.processAttachments(event.channel, event.files, event.ts)\n : [];\n const botName =\n event.username ?? event.bot_profile?.name ?? event.bot_profile?.real_name ?? event.bot_id;\n this.logToFile(event.channel, {\n date: new Date(parseFloat(event.ts) * 1000).toISOString(),\n ts: event.ts,\n threadTs: event.thread_ts,\n user: event.bot_id ? `bot:${event.bot_id}` : \"external-bot\",\n userName: botName,\n displayName: botName,\n text: buildSlackAppMessageText(event),\n attachments,\n isMessagingBot: true,\n botId: event.bot_id,\n appId: event.app_id ?? event.bot_profile?.app_id,\n subtype: event.subtype,\n });\n return attachments;\n }\n\n // ==========================================================================\n // Private - Backfill\n // ==========================================================================\n\n private async getExistingTimestamps(channelId: string): Promise<Set<string>> {\n const logPath = join(this.workingDir, channelId, \"log.jsonl\");\n const timestamps = new Set<string>();\n if (!existsSync(logPath)) return timestamps;\n\n const content = await readFile(logPath, \"utf-8\");\n const lines = content.trim().split(\"\\n\").filter(Boolean);\n for (let i = 0; i < lines.length; i++) {\n try {\n const entry = JSON.parse(lines[i]);\n if (entry.ts) timestamps.add(entry.ts);\n } catch (err) {\n log.logWarning(\n `Skipping malformed log entry at ${logPath}:${i + 1}`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n return timestamps;\n }\n\n private async backfillChannel(channelId: string, upperBoundTs?: string): Promise<number> {\n const existingTs = await this.getExistingTimestamps(channelId);\n\n // Find the biggest ts in log.jsonl\n let lastLoggedTs: string | undefined;\n for (const ts of existingTs) {\n if (!lastLoggedTs || parseFloat(ts) > parseFloat(lastLoggedTs)) lastLoggedTs = ts;\n }\n\n type Message = {\n user?: string;\n bot_id?: string;\n app_id?: string;\n username?: string;\n bot_profile?: { app_id?: string; name?: string; real_name?: string };\n blocks?: unknown[];\n attachments?: unknown[];\n text?: string;\n ts?: string;\n thread_ts?: string;\n subtype?: string;\n files?: Array<{ name: string }>;\n };\n const allMessages: Message[] = [];\n\n let cursor: string | undefined;\n let pageCount = 0;\n const maxPages = 3;\n\n do {\n const result = await this.webClient.conversations.history({\n channel: channelId,\n oldest: lastLoggedTs, // Only fetch messages newer than what we have\n latest: upperBoundTs, // Do not race live socket events after startup\n inclusive: false,\n limit: 1000,\n cursor,\n });\n if (result.messages) {\n allMessages.push(...(result.messages as Message[]));\n }\n cursor = result.response_metadata?.next_cursor;\n pageCount++;\n } while (cursor && pageCount < maxPages);\n\n // Filter: include mikan's messages, external app/bot messages, and user messages.\n const relevantMessages = allMessages.filter((msg) => {\n if (!msg.ts || existingTs.has(msg.ts)) return false; // Skip duplicates\n if (msg.user === this.botUserId) return true;\n const isExternalMessagingBotMessage = !!msg.bot_id || msg.subtype === \"bot_message\";\n if (isExternalMessagingBotMessage) {\n if (this.botId && msg.bot_id === this.botId) return false;\n if (\n msg.subtype !== undefined &&\n msg.subtype !== \"bot_message\" &&\n msg.subtype !== \"file_share\"\n ) {\n return false;\n }\n return (\n !!msg.text ||\n !!(msg.files && msg.files.length > 0) ||\n !!msg.blocks?.length ||\n !!msg.attachments?.length\n );\n }\n if (msg.subtype !== undefined && msg.subtype !== \"file_share\") return false;\n if (!msg.user) return false;\n if (!msg.text && (!msg.files || msg.files.length === 0)) return false;\n return true;\n });\n\n // Reverse to chronological order\n relevantMessages.reverse();\n\n // Log each message to log.jsonl\n for (const msg of relevantMessages) {\n const isMikanMessage = msg.user === this.botUserId;\n const isExternalMessagingBotMessage =\n !isMikanMessage && (!!msg.bot_id || msg.subtype === \"bot_message\");\n if (isExternalMessagingBotMessage) {\n await this.logExternalMessagingBotMessage({ ...msg, channel: channelId, ts: msg.ts! });\n continue;\n }\n\n const user = this.users.get(msg.user!);\n const text = this.stripOwnMention(msg.text);\n const attachments = msg.files\n ? await this.store.processAttachments(channelId, msg.files, msg.ts!)\n : [];\n\n this.logToFile(channelId, {\n date: new Date(parseFloat(msg.ts!) * 1000).toISOString(),\n ts: msg.ts!,\n threadTs: msg.thread_ts,\n user: isMikanMessage ? \"bot\" : msg.user!,\n userName: isMikanMessage ? undefined : user?.userName,\n displayName: isMikanMessage ? undefined : user?.displayName,\n text,\n attachments,\n isMessagingBot: isMikanMessage,\n });\n }\n\n return relevantMessages.length;\n }\n\n private async backfillAllChannels(upperBoundTs?: string): Promise<void> {\n const startTime = Date.now();\n\n // Only backfill channels that already have a log.jsonl (mikan has interacted with them before)\n const channelsToBackfill: Array<[string, SlackChannel]> = [];\n for (const [channelId, channel] of this.channels) {\n const logPath = join(this.workingDir, channelId, \"log.jsonl\");\n if (existsSync(logPath)) {\n channelsToBackfill.push([channelId, channel]);\n }\n }\n\n log.logBackfillStart(channelsToBackfill.length);\n\n let totalMessages = 0;\n for (const [channelId, channel] of channelsToBackfill) {\n try {\n const count = await this.backfillChannel(channelId, upperBoundTs);\n if (count > 0) log.logBackfillChannel(channel.name, count);\n totalMessages += count;\n } catch (error) {\n log.logWarning(`Failed to backfill #${channel.name}`, String(error));\n }\n\n // Add delay between channels to avoid hitting Slack rate limits\n if (channelId !== channelsToBackfill[channelsToBackfill.length - 1][0]) {\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n }\n\n const durationMs = Date.now() - startTime;\n log.logBackfillComplete(totalMessages, durationMs);\n }\n\n // ==========================================================================\n // Private - Fetch Users/Channels\n // ==========================================================================\n\n private async fetchUsers(): Promise<void> {\n let cursor: string | undefined;\n do {\n const result = await this.webClient.users.list({ limit: 200, cursor });\n const members = result.members as\n | Array<{ id?: string; name?: string; real_name?: string; deleted?: boolean }>\n | undefined;\n if (members) {\n for (const u of members) {\n if (u.id && u.name && !u.deleted) {\n this.users.set(u.id, {\n id: u.id,\n userName: u.name,\n displayName: u.real_name || u.name,\n });\n }\n }\n }\n cursor = result.response_metadata?.next_cursor;\n } while (cursor);\n }\n\n private async fetchChannels(): Promise<void> {\n // Fetch public/private channels\n let cursor: string | undefined;\n do {\n const result = await this.webClient.conversations.list({\n types: \"public_channel,private_channel\",\n exclude_archived: true,\n limit: 200,\n cursor,\n });\n const channels = result.channels as\n | Array<{ id?: string; name?: string; is_member?: boolean }>\n | undefined;\n if (channels) {\n for (const c of channels) {\n if (c.id && c.name && c.is_member) {\n this.channels.set(c.id, { id: c.id, name: c.name });\n }\n }\n }\n cursor = result.response_metadata?.next_cursor;\n } while (cursor);\n\n // Also fetch DM channels (IMs)\n cursor = undefined;\n do {\n const result = await this.webClient.conversations.list({\n types: \"im\",\n limit: 200,\n cursor,\n });\n const ims = result.channels as Array<{ id?: string; user?: string }> | undefined;\n if (ims) {\n for (const im of ims) {\n if (im.id) {\n // Use user's name as channel name for DMs\n const user = im.user ? this.users.get(im.user) : undefined;\n const name = user ? `DM:${user.userName}` : `DM:${im.id}`;\n this.channels.set(im.id, { id: im.id, name });\n }\n }\n }\n cursor = result.response_metadata?.next_cursor;\n } while (cursor);\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../src/commands/extensions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../src/commands/extensions.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKjE;;;;;;;;GAQG;AACH,qBAAa,wBAAyB,YAAW,cAAc;IACvD,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CA4CzD;CACF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { basename, join } from "node:path";
|
|
2
3
|
import { defaultExtensionDirs, listInstalledExtensions } from "../harness/index.js";
|
|
3
4
|
import { readEnv } from "../utils/env.js";
|
|
4
5
|
import { matchCommand } from "./parse.js";
|
|
@@ -20,7 +21,12 @@ export class ExtensionsCommandHandler {
|
|
|
20
21
|
return false;
|
|
21
22
|
const dirs = defaultExtensionDirs(context.conversationId, readEnv("STATE_DIR"));
|
|
22
23
|
const installed = listInstalledExtensions(dirs);
|
|
23
|
-
|
|
24
|
+
// A root-level index file means an extension's contents were copied into
|
|
25
|
+
// the scope directory itself; the loader skips it (the slug would
|
|
26
|
+
// degenerate to the scope name). Surface that here, not just in logs.
|
|
27
|
+
const misinstalled = dirs.filter((dir) => ["index.mjs", "index.js"].some((file) => existsSync(join(dir, file))));
|
|
28
|
+
const misinstallLines = misinstalled.map((dir) => `⚠️ \`${dir}/index.mjs\` 位於範圍根目錄,已被忽略 — 請移入具名子目錄(如 \`${dir}/my-ext/\`)。`);
|
|
29
|
+
if (installed.length === 0 && misinstallLines.length === 0) {
|
|
24
30
|
await replyDiagnosticWithContext(context.responder, [
|
|
25
31
|
"_Extensions_",
|
|
26
32
|
"沒有安裝任何 extension。",
|
|
@@ -28,11 +34,12 @@ export class ExtensionsCommandHandler {
|
|
|
28
34
|
].join("\n"), { style: "muted" });
|
|
29
35
|
return true;
|
|
30
36
|
}
|
|
31
|
-
const lines = ["_Extensions_"];
|
|
37
|
+
const lines = ["_Extensions_", ...misinstallLines];
|
|
32
38
|
for (const info of installed) {
|
|
33
39
|
const scope = basename(info.dir) === "global" ? "global" : "this conversation";
|
|
34
40
|
const version = info.version ? `@${info.version}` : "";
|
|
35
|
-
|
|
41
|
+
const slug = info.slug !== info.name ? ` (slug: ${info.slug})` : "";
|
|
42
|
+
lines.push(`• *${info.name}*${version} — ${scope}${slug}`);
|
|
36
43
|
if (info.description)
|
|
37
44
|
lines.push(` ${info.description}`);
|
|
38
45
|
if (info.skillNames.length > 0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extensions.js","sourceRoot":"","sources":["../../src/commands/extensions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"extensions.js","sourceRoot":"","sources":["../../src/commands/extensions.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport { defaultExtensionDirs, listInstalledExtensions } from \"../harness/index.js\";\nimport { readEnv } from \"../utils/env.js\";\nimport { matchCommand } from \"./parse.js\";\nimport type { CommandContext, CommandHandler } from \"./types.js\";\nimport { replyDiagnosticWithContext } from \"./utils.js\";\n\nconst EXTENSIONS_COMMANDS = [\"/pi-extensions\", \"/extensions\"] as const;\n\n/**\n * `/pi-extensions` — inventory of extensions installed for this conversation.\n *\n * Discovery-only (nothing is imported or activated): it reports what is on\n * disk under the host-only state dir, for both the `global` scope and this\n * conversation's scope. Doubles as the user-facing answer to \"why can the\n * bot suddenly do X\" and the operator-facing answer to \"what is installed\n * where\".\n */\nexport class ExtensionsCommandHandler implements CommandHandler {\n async tryHandle(context: CommandContext): Promise<boolean> {\n const matched = matchCommand(context.commandText, EXTENSIONS_COMMANDS, { stripMention: true });\n if (!matched) return false;\n\n const dirs = defaultExtensionDirs(context.conversationId, readEnv(\"STATE_DIR\"));\n const installed = listInstalledExtensions(dirs);\n\n // A root-level index file means an extension's contents were copied into\n // the scope directory itself; the loader skips it (the slug would\n // degenerate to the scope name). Surface that here, not just in logs.\n const misinstalled = dirs.filter((dir) =>\n [\"index.mjs\", \"index.js\"].some((file) => existsSync(join(dir, file))),\n );\n const misinstallLines = misinstalled.map(\n (dir) =>\n `⚠️ \\`${dir}/index.mjs\\` 位於範圍根目錄,已被忽略 — 請移入具名子目錄(如 \\`${dir}/my-ext/\\`)。`,\n );\n\n if (installed.length === 0 && misinstallLines.length === 0) {\n await replyDiagnosticWithContext(\n context.responder,\n [\n \"_Extensions_\",\n \"沒有安裝任何 extension。\",\n `安裝位置:\\`${dirs[0]}\\`(所有會話)或 \\`${dirs[1]}\\`(僅此會話)。`,\n ].join(\"\\n\"),\n { style: \"muted\" },\n );\n return true;\n }\n\n const lines = [\"_Extensions_\", ...misinstallLines];\n for (const info of installed) {\n const scope = basename(info.dir) === \"global\" ? \"global\" : \"this conversation\";\n const version = info.version ? `@${info.version}` : \"\";\n const slug = info.slug !== info.name ? ` (slug: ${info.slug})` : \"\";\n lines.push(`• *${info.name}*${version} — ${scope}${slug}`);\n if (info.description) lines.push(` ${info.description}`);\n if (info.skillNames.length > 0) lines.push(` skills: ${info.skillNames.join(\", \")}`);\n }\n lines.push(\"_(安裝/移除後,對話輸入 `/pi-new` 生效)_\");\n\n await replyDiagnosticWithContext(context.responder, lines.join(\"\\n\"), { style: \"muted\" });\n return true;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/harness/extensions/loader.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAa,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,EAAqB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EACV,qBAAqB,EACrB,kBAAkB,EAKlB,eAAe,EAIhB,MAAM,YAAY,CAAC;AAIpB;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,cAAc,EAAE,MAAM,EACtB,QAAQ,GAAE,MAAkC,GAC3C,MAAM,EAAE,CAEV;AAED,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,sBAAsB,EAAE,CAkBhF;AAED,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE;QACP,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAClB,aAAa,EAAE,aAAa,CAAC;KAC9B,CAAC;IACF,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,qBAAqB,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,4EAA4E;IAC5E,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/harness/extensions/loader.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAa,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,EAAqB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EACV,qBAAqB,EACrB,kBAAkB,EAKlB,eAAe,EAIhB,MAAM,YAAY,CAAC;AAIpB;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,cAAc,EAAE,MAAM,EACtB,QAAQ,GAAE,MAAkC,GAC3C,MAAM,EAAE,CAEV;AAED,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,sBAAsB,EAAE,CAkBhF;AAED,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE;QACP,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAClB,aAAa,EAAE,aAAa,CAAC;KAC9B,CAAC;IACF,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,qBAAqB,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,4EAA4E;IAC5E,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AA0CD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAUxD;AAkMD,uEAAuE;AACvE,wBAAsB,cAAc,CAClC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAmD/B"}
|
|
@@ -69,6 +69,14 @@ function discoverExtensionEntrypoints(dir) {
|
|
|
69
69
|
for (const name of readdirSync(dir).toSorted()) {
|
|
70
70
|
if (name.startsWith("."))
|
|
71
71
|
continue;
|
|
72
|
+
if (/^index\.(mjs|js)$/.test(name)) {
|
|
73
|
+
// An index file at the scan root means the extension's contents were
|
|
74
|
+
// copied into the scope directory itself; the slug would degenerate to
|
|
75
|
+
// the scope name (e.g. the conversation id), mis-keying its data dir,
|
|
76
|
+
// secrets, and schedules. Require a named form instead.
|
|
77
|
+
log.logWarning(`Ignoring extension index file at scope root: ${join(dir, name)}`, "install into a named subdirectory (e.g. extensions/<scope>/my-ext/index.mjs)");
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
72
80
|
const fullPath = join(dir, name);
|
|
73
81
|
let stats;
|
|
74
82
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/harness/extensions/loader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Extension discovery and activation.\n *\n * Extension modules execute inside the mikan host process with its full\n * privileges (platform tokens, vault, host filesystem). They must therefore\n * only ever load from host-controlled directories: installing an extension\n * is an administrator action. In particular, extension directories must not\n * live under paths mounted into sandbox containers (workspace and\n * conversation dirs in image mode), or code written from inside the sandbox\n * would be imported into the host process — a sandbox escape.\n * {@link defaultExtensionDirs} returns the canonical host-only locations\n * under mikan's state dir.\n *\n * Directories are scanned in order; all discovered extensions activate.\n * Accepted layouts:\n *\n * - `extensions/<name>.mjs` / `extensions/<name>.js`\n * - `extensions/<name>/index.mjs` / `extensions/<name>/index.js`\n *\n * Modules are imported with a cache-busting query so edited extensions are\n * picked up when a new harness instance is created for a conversation.\n */\nimport { existsSync, mkdirSync, readdirSync, readFileSync, statSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join } from \"path\";\nimport { pathToFileURL } from \"url\";\nimport type { AgentTool, ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport * as log from \"../../log.js\";\nimport { loadSkillsFromDir, type MikanSkill } from \"../skills.js\";\nimport { ExtensionRegistry } from \"./registry.js\";\nimport type {\n ExtensionHostServices,\n ExtensionLoadError,\n ExtensionManifest,\n ExtensionSchedulePayload,\n ExtensionScheduleInfo,\n ExtensionScheduleSpec,\n LoadedExtension,\n MikanExtensionActivate,\n MikanExtensionApi,\n MikanExtensionModule,\n} from \"./types.js\";\n\nconst EXTENSION_FILE_PATTERN = /\\.(mjs|js)$/;\n\n/**\n * Canonical host-only extension directories for a conversation:\n * `<stateDir>/extensions/global` (all conversations) and\n * `<stateDir>/extensions/<conversationId>` (that conversation only).\n * `global` is reserved as a scope name; platform conversation ids never\n * take that value.\n */\nexport function defaultExtensionDirs(\n conversationId: string,\n stateDir: string = join(homedir(), \".mikan\"),\n): string[] {\n return [join(stateDir, \"extensions\", \"global\"), join(stateDir, \"extensions\", conversationId)];\n}\n\n/** Discovery-only view of an installed extension (module is not imported). */\nexport interface InstalledExtensionInfo {\n /** Display name: manifest name, falling back to the slug. */\n name: string;\n slug: string;\n path: string;\n /** Scan directory the extension was found in. */\n dir: string;\n version?: string;\n description?: string;\n /** Names of skills shipped in the extension's skills/ directory. */\n skillNames: string[];\n}\n\n/**\n * List installed extensions without importing or activating them — safe for\n * inventory surfaces (commands, portal). Activation side effects (schedule\n * upserts, tool registration) only happen in {@link loadExtensions}.\n */\nexport function listInstalledExtensions(dirs: string[]): InstalledExtensionInfo[] {\n const infos: InstalledExtensionInfo[] = [];\n for (const dir of dirs) {\n for (const entrypoint of discoverExtensionEntrypoints(dir)) {\n const slug = extensionSlug(entrypoint);\n const manifest = readManifest(entrypoint);\n infos.push({\n name: manifest.name ?? slug,\n slug,\n path: entrypoint,\n dir,\n version: manifest.version,\n description: manifest.description,\n skillNames: loadExtensionSkills(entrypoint, slug).map((skill) => skill.name),\n });\n }\n }\n return infos;\n}\n\nexport interface LoadExtensionsOptions {\n /** Directories to scan for extensions. Missing directories are skipped. */\n dirs: string[];\n context: {\n conversationId: string;\n workspaceDir: string;\n model: Model<Api>;\n thinkingLevel: ThinkingLevel;\n };\n /** Embedder-provided services backing the v2 api surface. */\n services?: ExtensionHostServices;\n}\n\nexport interface LoadExtensionsResult {\n registry: ExtensionRegistry;\n extensions: LoadedExtension[];\n errors: ExtensionLoadError[];\n /** Skills contributed by extensions (inline: bodies ride in the prompt). */\n skills: MikanSkill[];\n}\n\nfunction discoverExtensionEntrypoints(dir: string): string[] {\n if (!existsSync(dir)) return [];\n const entrypoints: string[] = [];\n for (const name of readdirSync(dir).toSorted()) {\n if (name.startsWith(\".\")) continue;\n const fullPath = join(dir, name);\n let stats;\n try {\n stats = statSync(fullPath);\n } catch {\n continue;\n }\n if (stats.isFile() && EXTENSION_FILE_PATTERN.test(name)) {\n entrypoints.push(fullPath);\n continue;\n }\n if (stats.isDirectory()) {\n for (const candidate of [\"index.mjs\", \"index.js\"]) {\n const indexPath = join(fullPath, candidate);\n if (existsSync(indexPath)) {\n entrypoints.push(indexPath);\n break;\n }\n }\n }\n }\n return entrypoints;\n}\n\n/**\n * Filesystem-safe identifier for an extension, derived from its install\n * location (directory name for `<name>/index.mjs`, file basename otherwise).\n * The slug keys the extension's data dir, secrets vault, and schedule\n * ownership — installing the same extension globally and per-conversation\n * shares one slug and therefore one data dir.\n */\nexport function extensionSlug(entrypoint: string): string {\n const base = /^index\\.(mjs|js)$/.test(basename(entrypoint))\n ? basename(dirname(entrypoint))\n : basename(entrypoint).replace(EXTENSION_FILE_PATTERN, \"\");\n const slug = base\n .toLowerCase()\n .replace(/[^a-z0-9_-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 64);\n return slug || \"extension\";\n}\n\n/** Sanitize an extension-chosen schedule name into a filename segment. */\nfunction scheduleNameSegment(name: string): string {\n const segment = name\n .toLowerCase()\n .replace(/[^a-z0-9_-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 64);\n if (!segment) throw new Error(`Invalid schedule name: ${JSON.stringify(name)}`);\n return segment;\n}\n\n/** Read `manifest.json` next to a directory-form extension's entrypoint. */\nfunction readManifest(entrypoint: string): ExtensionManifest {\n if (!/^index\\.(mjs|js)$/.test(basename(entrypoint))) return {};\n const manifestPath = join(dirname(entrypoint), \"manifest.json\");\n if (!existsSync(manifestPath)) return {};\n try {\n const parsed: unknown = JSON.parse(readFileSync(manifestPath, \"utf-8\"));\n if (!parsed || typeof parsed !== \"object\") return {};\n const record = parsed as Record<string, unknown>;\n return {\n name: typeof record.name === \"string\" ? record.name : undefined,\n version: typeof record.version === \"string\" ? record.version : undefined,\n description: typeof record.description === \"string\" ? record.description : undefined,\n };\n } catch (err) {\n log.logWarning(`Ignoring malformed extension manifest: ${manifestPath}`, String(err));\n return {};\n }\n}\n\n/**\n * Skills shipped inside a directory-form extension (`<dir>/skills/`).\n * Marked inline: extension files live under the host-only state dir, which\n * sandbox containers cannot read, so skill bodies must ride in the prompt.\n */\nfunction loadExtensionSkills(entrypoint: string, slug: string): MikanSkill[] {\n if (!/^index\\.(mjs|js)$/.test(basename(entrypoint))) return [];\n const skillsDir = join(dirname(entrypoint), \"skills\");\n if (!existsSync(skillsDir)) return [];\n const result = loadSkillsFromDir({ dir: skillsDir, source: `extension:${slug}` });\n for (const diagnostic of result.diagnostics) {\n log.logWarning(`Extension skill warning (${slug}): ${diagnostic.message}`, diagnostic.path);\n }\n for (const skill of result.skills) skill.inline = true;\n return result.skills;\n}\n\nconst SCHEDULE_FILE_SUFFIX = \".json\";\n\nfunction schedulePrefix(slug: string, conversationId: string): string {\n return `ext.${slug}.${scheduleNameSegment(conversationId)}.`;\n}\n\nfunction payloadFromSpec(\n spec: ExtensionScheduleSpec,\n conversationId: string,\n): ExtensionSchedulePayload {\n if (spec.type === \"periodic\") {\n if (!spec.schedule || !spec.timezone) {\n throw new Error(\"periodic schedule requires schedule and timezone\");\n }\n return {\n type: \"periodic\",\n conversationId,\n text: spec.text,\n schedule: spec.schedule,\n timezone: spec.timezone,\n ...(spec.platform ? { platform: spec.platform } : {}),\n };\n }\n if (!spec.at) throw new Error(\"one-shot schedule requires at\");\n return {\n type: \"one-shot\",\n conversationId,\n text: spec.text,\n at: spec.at,\n ...(spec.platform ? { platform: spec.platform } : {}),\n };\n}\n\nfunction specFromPayload(payload: ExtensionSchedulePayload): ExtensionScheduleSpec {\n if (payload.type === \"periodic\") {\n return {\n type: \"periodic\",\n schedule: payload.schedule ?? \"\",\n timezone: payload.timezone ?? \"\",\n text: payload.text,\n ...(payload.platform ? { platform: payload.platform } : {}),\n };\n }\n return {\n type: \"one-shot\",\n at: payload.at ?? \"\",\n text: payload.text,\n ...(payload.platform ? { platform: payload.platform } : {}),\n };\n}\n\n/** Build the v2 api surface for one extension over the injected services. */\nfunction buildExtensionApi(params: {\n name: string;\n slug: string;\n registry: ExtensionRegistry;\n context: LoadExtensionsOptions[\"context\"];\n services: ExtensionHostServices;\n}): MikanExtensionApi {\n const { name, slug, registry, context, services } = params;\n const stateDir = services.stateDir ?? join(homedir(), \".mikan\");\n const conversationId = context.conversationId;\n\n const requireScheduleStore = () => {\n if (!services.scheduleStore) {\n throw new Error(\"api.schedules is unavailable: this context provides no schedule store\");\n }\n return services.scheduleStore;\n };\n\n return {\n on: (hook, handler) => registry.register(name, hook, handler),\n registerTool: (tool: AgentTool) => registry.registerTool(tool),\n log: (message: string) => log.logInfo(`[extension:${name}] ${message}`),\n context,\n paths: {\n get dataDir(): string {\n const dir = join(stateDir, \"extension-data\", slug);\n mkdirSync(dir, { recursive: true });\n return dir;\n },\n },\n secrets: {\n get: (key: string) => services.resolveSecrets?.(slug)[key],\n list: () => Object.keys(services.resolveSecrets?.(slug) ?? {}),\n },\n schedules: {\n upsert: async (scheduleName, spec) => {\n const store = requireScheduleStore();\n const filename = `${schedulePrefix(slug, conversationId)}${scheduleNameSegment(scheduleName)}${SCHEDULE_FILE_SUFFIX}`;\n await store.write(filename, payloadFromSpec(spec, conversationId));\n },\n delete: async (scheduleName) => {\n const store = requireScheduleStore();\n const filename = `${schedulePrefix(slug, conversationId)}${scheduleNameSegment(scheduleName)}${SCHEDULE_FILE_SUFFIX}`;\n return store.delete(filename);\n },\n list: async () => {\n const store = requireScheduleStore();\n const prefix = schedulePrefix(slug, conversationId);\n const infos: ExtensionScheduleInfo[] = [];\n for (const entry of await store.list()) {\n if (!entry.filename.startsWith(prefix)) continue;\n if (!entry.filename.endsWith(SCHEDULE_FILE_SUFFIX)) continue;\n infos.push({\n name: entry.filename.slice(prefix.length, -SCHEDULE_FILE_SUFFIX.length),\n spec: specFromPayload(entry.payload),\n });\n }\n return infos;\n },\n },\n notify: async (text: string) => {\n if (!services.postMessage) {\n throw new Error(\"api.notify is unavailable: this context provides no platform messaging\");\n }\n await services.postMessage(conversationId, text);\n },\n };\n}\n\nfunction resolveActivate(moduleExports: unknown): MikanExtensionModule | undefined {\n if (!moduleExports || typeof moduleExports !== \"object\") return undefined;\n const candidates: unknown[] = [(moduleExports as { default?: unknown }).default, moduleExports];\n for (const candidate of candidates) {\n if (typeof candidate === \"function\") {\n return { activate: candidate as MikanExtensionActivate };\n }\n if (candidate && typeof candidate === \"object\") {\n const activate = (candidate as { activate?: unknown }).activate;\n if (typeof activate === \"function\") {\n return {\n name:\n typeof (candidate as { name?: unknown }).name === \"string\"\n ? (candidate as { name: string }).name\n : undefined,\n activate: activate as MikanExtensionActivate,\n };\n }\n }\n }\n return undefined;\n}\n\n/** Load and activate all extensions found in the given directories. */\nexport async function loadExtensions(\n options: LoadExtensionsOptions,\n): Promise<LoadExtensionsResult> {\n const registry = new ExtensionRegistry();\n const extensions: LoadedExtension[] = [];\n const errors: ExtensionLoadError[] = [];\n const skills: MikanSkill[] = [];\n const services = options.services ?? {};\n\n for (const dir of options.dirs) {\n for (const entrypoint of discoverExtensionEntrypoints(dir)) {\n try {\n const moduleUrl = `${pathToFileURL(entrypoint).href}?t=${Date.now()}`;\n const moduleExports: unknown = await import(moduleUrl);\n const extension = resolveActivate(moduleExports);\n if (!extension) {\n errors.push({\n path: entrypoint,\n error: \"extension must export an activate function (default or named)\",\n });\n continue;\n }\n const slug = extensionSlug(entrypoint);\n const manifest = readManifest(entrypoint);\n const name = manifest.name ?? extension.name ?? slug;\n const api = buildExtensionApi({\n name,\n slug,\n registry,\n context: options.context,\n services,\n });\n await extension.activate(api);\n const extensionSkills = loadExtensionSkills(entrypoint, slug);\n skills.push(...extensionSkills);\n extensions.push({\n name,\n path: entrypoint,\n slug,\n version: manifest.version,\n description: manifest.description,\n skills: extensionSkills,\n });\n } catch (err) {\n errors.push({\n path: entrypoint,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n }\n\n return { registry, extensions, errors, skills };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/harness/extensions/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAGpC,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAmB,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAclD,MAAM,sBAAsB,GAAG,aAAa,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,cAAsB,EACtB,QAAQ,GAAW,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC;IAE5C,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC;AAChG,CAAC;AAgBD;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAc;IACpD,MAAM,KAAK,GAA6B,EAAE,CAAC;IAC3C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,KAAK,MAAM,UAAU,IAAI,4BAA4B,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3D,MAAM,IAAI,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;YACvC,MAAM,QAAQ,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,IAAI;gBAC3B,IAAI;gBACJ,IAAI,EAAE,UAAU;gBAChB,GAAG;gBACH,OAAO,EAAE,QAAQ,CAAC,OAAO;gBACzB,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,UAAU,EAAE,mBAAmB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;aAC7E,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAuBD,SAAS,4BAA4B,CAAC,GAAW;IAC/C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC/C,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACnC,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,qEAAqE;YACrE,uEAAuE;YACvE,sEAAsE;YACtE,wDAAwD;YACxD,GAAG,CAAC,UAAU,CACZ,gDAAgD,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EACjE,8EAA8E,CAC/E,CAAC;YACF,SAAS;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACjC,IAAI,KAAK,CAAC;QACV,IAAI,CAAC;YACH,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxD,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,KAAK,MAAM,SAAS,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,CAAC;gBAClD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;gBAC5C,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC1B,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBAC5B,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,UAAkB;IAC9C,MAAM,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACzD,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC/B,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,IAAI;SACd,WAAW,EAAE;SACb,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC;SAC7B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChB,OAAO,IAAI,IAAI,WAAW,CAAC;AAC7B,CAAC;AAED,0EAA0E;AAC1E,SAAS,mBAAmB,CAAC,IAAY;IACvC,MAAM,OAAO,GAAG,IAAI;SACjB,WAAW,EAAE;SACb,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC;SAC7B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChB,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,4EAA4E;AAC5E,SAAS,YAAY,CAAC,UAAkB;IACtC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC,CAAC;IAChE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,EAAE,CAAC;IACzC,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;QACxE,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QACrD,MAAM,MAAM,GAAG,MAAiC,CAAC;QACjD,OAAO;YACL,IAAI,EAAE,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;YAC/D,OAAO,EAAE,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;YACxE,WAAW,EAAE,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;SACrF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,UAAU,CAAC,0CAA0C,YAAY,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACtF,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,UAAkB,EAAE,IAAY;IAC3D,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,CAAC;IACtD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,iBAAiB,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,IAAI,EAAE,EAAE,CAAC,CAAC;IAClF,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QAC5C,GAAG,CAAC,UAAU,CAAC,4BAA4B,IAAI,MAAM,UAAU,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IAC9F,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM;QAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;IACvD,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,CAAC;AAED,MAAM,oBAAoB,GAAG,OAAO,CAAC;AAErC,SAAS,cAAc,CAAC,IAAY,EAAE,cAAsB;IAC1D,OAAO,OAAO,IAAI,IAAI,mBAAmB,CAAC,cAAc,CAAC,GAAG,CAAC;AAC/D,CAAC;AAED,SAAS,eAAe,CACtB,IAA2B,EAC3B,cAAsB;IAEtB,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACtE,CAAC;QACD,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,cAAc;YACd,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACtD,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC/D,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,cAAc;QACd,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtD,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,OAAiC;IACxD,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAChC,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE;YAChC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE;YAChC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5D,CAAC;IACJ,CAAC;IACD,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE;QACpB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5D,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,SAAS,iBAAiB,CAAC,MAM1B;IACC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IAC3D,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;IAChE,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAE9C,MAAM,oBAAoB,GAAG,GAAG,EAAE;QAChC,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;QAC3F,CAAC;QACD,OAAO,QAAQ,CAAC,aAAa,CAAC;IAChC,CAAC,CAAC;IAEF,OAAO;QACL,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC;QAC7D,YAAY,EAAE,CAAC,IAAe,EAAE,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC;QAC9D,GAAG,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,IAAI,KAAK,OAAO,EAAE,CAAC;QACvE,OAAO;QACP,KAAK,EAAE;YACL,IAAI,OAAO;gBACT,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC;gBACnD,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpC,OAAO,GAAG,CAAC;YACb,CAAC;SACF;QACD,OAAO,EAAE;YACP,GAAG,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC;YAC1D,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC/D;QACD,SAAS,EAAE;YACT,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE;gBACnC,MAAM,KAAK,GAAG,oBAAoB,EAAE,CAAC;gBACrC,MAAM,QAAQ,GAAG,GAAG,cAAc,CAAC,IAAI,EAAE,cAAc,CAAC,GAAG,mBAAmB,CAAC,YAAY,CAAC,GAAG,oBAAoB,EAAE,CAAC;gBACtH,MAAM,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,eAAe,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;YACrE,CAAC;YACD,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE;gBAC7B,MAAM,KAAK,GAAG,oBAAoB,EAAE,CAAC;gBACrC,MAAM,QAAQ,GAAG,GAAG,cAAc,CAAC,IAAI,EAAE,cAAc,CAAC,GAAG,mBAAmB,CAAC,YAAY,CAAC,GAAG,oBAAoB,EAAE,CAAC;gBACtH,OAAO,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAChC,CAAC;YACD,IAAI,EAAE,KAAK,IAAI,EAAE;gBACf,MAAM,KAAK,GAAG,oBAAoB,EAAE,CAAC;gBACrC,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;gBACpD,MAAM,KAAK,GAA4B,EAAE,CAAC;gBAC1C,KAAK,MAAM,KAAK,IAAI,MAAM,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;oBACvC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC;wBAAE,SAAS;oBACjD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,oBAAoB,CAAC;wBAAE,SAAS;oBAC7D,KAAK,CAAC,IAAI,CAAC;wBACT,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,oBAAoB,CAAC,MAAM,CAAC;wBACvE,IAAI,EAAE,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC;qBACrC,CAAC,CAAC;gBACL,CAAC;gBACD,OAAO,KAAK,CAAC;YACf,CAAC;SACF;QACD,MAAM,EAAE,KAAK,EAAE,IAAY,EAAE,EAAE;YAC7B,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;YAC5F,CAAC;YACD,MAAM,QAAQ,CAAC,WAAW,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QACnD,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,aAAsB;IAC7C,IAAI,CAAC,aAAa,IAAI,OAAO,aAAa,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC1E,MAAM,UAAU,GAAc,CAAE,aAAuC,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAChG,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;YACpC,OAAO,EAAE,QAAQ,EAAE,SAAmC,EAAE,CAAC;QAC3D,CAAC;QACD,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC/C,MAAM,QAAQ,GAAI,SAAoC,CAAC,QAAQ,CAAC;YAChE,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACnC,OAAO;oBACL,IAAI,EACF,OAAQ,SAAgC,CAAC,IAAI,KAAK,QAAQ;wBACxD,CAAC,CAAE,SAA8B,CAAC,IAAI;wBACtC,CAAC,CAAC,SAAS;oBACf,QAAQ,EAAE,QAAkC;iBAC7C,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,uEAAuE;AACvE,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAA8B;IAE9B,MAAM,QAAQ,GAAG,IAAI,iBAAiB,EAAE,CAAC;IACzC,MAAM,UAAU,GAAsB,EAAE,CAAC;IACzC,MAAM,MAAM,GAAyB,EAAE,CAAC;IACxC,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;IAExC,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAC/B,KAAK,MAAM,UAAU,IAAI,4BAA4B,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3D,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,IAAI,MAAM,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBACtE,MAAM,aAAa,GAAY,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;gBACvD,MAAM,SAAS,GAAG,eAAe,CAAC,aAAa,CAAC,CAAC;gBACjD,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,UAAU;wBAChB,KAAK,EAAE,+DAA+D;qBACvE,CAAC,CAAC;oBACH,SAAS;gBACX,CAAC;gBACD,MAAM,IAAI,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;gBACvC,MAAM,QAAQ,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;gBAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,IAAI,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC;gBACrD,MAAM,GAAG,GAAG,iBAAiB,CAAC;oBAC5B,IAAI;oBACJ,IAAI;oBACJ,QAAQ;oBACR,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,QAAQ;iBACT,CAAC,CAAC;gBACH,MAAM,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAC9B,MAAM,eAAe,GAAG,mBAAmB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;gBAC9D,MAAM,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,CAAC;gBAChC,UAAU,CAAC,IAAI,CAAC;oBACd,IAAI;oBACJ,IAAI,EAAE,UAAU;oBAChB,IAAI;oBACJ,OAAO,EAAE,QAAQ,CAAC,OAAO;oBACzB,WAAW,EAAE,QAAQ,CAAC,WAAW;oBACjC,MAAM,EAAE,eAAe;iBACxB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,UAAU;oBAChB,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBACxD,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAClD,CAAC","sourcesContent":["/**\n * Extension discovery and activation.\n *\n * Extension modules execute inside the mikan host process with its full\n * privileges (platform tokens, vault, host filesystem). They must therefore\n * only ever load from host-controlled directories: installing an extension\n * is an administrator action. In particular, extension directories must not\n * live under paths mounted into sandbox containers (workspace and\n * conversation dirs in image mode), or code written from inside the sandbox\n * would be imported into the host process — a sandbox escape.\n * {@link defaultExtensionDirs} returns the canonical host-only locations\n * under mikan's state dir.\n *\n * Directories are scanned in order; all discovered extensions activate.\n * Accepted layouts:\n *\n * - `extensions/<name>.mjs` / `extensions/<name>.js`\n * - `extensions/<name>/index.mjs` / `extensions/<name>/index.js`\n *\n * Modules are imported with a cache-busting query so edited extensions are\n * picked up when a new harness instance is created for a conversation.\n */\nimport { existsSync, mkdirSync, readdirSync, readFileSync, statSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join } from \"path\";\nimport { pathToFileURL } from \"url\";\nimport type { AgentTool, ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport * as log from \"../../log.js\";\nimport { loadSkillsFromDir, type MikanSkill } from \"../skills.js\";\nimport { ExtensionRegistry } from \"./registry.js\";\nimport type {\n ExtensionHostServices,\n ExtensionLoadError,\n ExtensionManifest,\n ExtensionSchedulePayload,\n ExtensionScheduleInfo,\n ExtensionScheduleSpec,\n LoadedExtension,\n MikanExtensionActivate,\n MikanExtensionApi,\n MikanExtensionModule,\n} from \"./types.js\";\n\nconst EXTENSION_FILE_PATTERN = /\\.(mjs|js)$/;\n\n/**\n * Canonical host-only extension directories for a conversation:\n * `<stateDir>/extensions/global` (all conversations) and\n * `<stateDir>/extensions/<conversationId>` (that conversation only).\n * `global` is reserved as a scope name; platform conversation ids never\n * take that value.\n */\nexport function defaultExtensionDirs(\n conversationId: string,\n stateDir: string = join(homedir(), \".mikan\"),\n): string[] {\n return [join(stateDir, \"extensions\", \"global\"), join(stateDir, \"extensions\", conversationId)];\n}\n\n/** Discovery-only view of an installed extension (module is not imported). */\nexport interface InstalledExtensionInfo {\n /** Display name: manifest name, falling back to the slug. */\n name: string;\n slug: string;\n path: string;\n /** Scan directory the extension was found in. */\n dir: string;\n version?: string;\n description?: string;\n /** Names of skills shipped in the extension's skills/ directory. */\n skillNames: string[];\n}\n\n/**\n * List installed extensions without importing or activating them — safe for\n * inventory surfaces (commands, portal). Activation side effects (schedule\n * upserts, tool registration) only happen in {@link loadExtensions}.\n */\nexport function listInstalledExtensions(dirs: string[]): InstalledExtensionInfo[] {\n const infos: InstalledExtensionInfo[] = [];\n for (const dir of dirs) {\n for (const entrypoint of discoverExtensionEntrypoints(dir)) {\n const slug = extensionSlug(entrypoint);\n const manifest = readManifest(entrypoint);\n infos.push({\n name: manifest.name ?? slug,\n slug,\n path: entrypoint,\n dir,\n version: manifest.version,\n description: manifest.description,\n skillNames: loadExtensionSkills(entrypoint, slug).map((skill) => skill.name),\n });\n }\n }\n return infos;\n}\n\nexport interface LoadExtensionsOptions {\n /** Directories to scan for extensions. Missing directories are skipped. */\n dirs: string[];\n context: {\n conversationId: string;\n workspaceDir: string;\n model: Model<Api>;\n thinkingLevel: ThinkingLevel;\n };\n /** Embedder-provided services backing the v2 api surface. */\n services?: ExtensionHostServices;\n}\n\nexport interface LoadExtensionsResult {\n registry: ExtensionRegistry;\n extensions: LoadedExtension[];\n errors: ExtensionLoadError[];\n /** Skills contributed by extensions (inline: bodies ride in the prompt). */\n skills: MikanSkill[];\n}\n\nfunction discoverExtensionEntrypoints(dir: string): string[] {\n if (!existsSync(dir)) return [];\n const entrypoints: string[] = [];\n for (const name of readdirSync(dir).toSorted()) {\n if (name.startsWith(\".\")) continue;\n if (/^index\\.(mjs|js)$/.test(name)) {\n // An index file at the scan root means the extension's contents were\n // copied into the scope directory itself; the slug would degenerate to\n // the scope name (e.g. the conversation id), mis-keying its data dir,\n // secrets, and schedules. Require a named form instead.\n log.logWarning(\n `Ignoring extension index file at scope root: ${join(dir, name)}`,\n \"install into a named subdirectory (e.g. extensions/<scope>/my-ext/index.mjs)\",\n );\n continue;\n }\n const fullPath = join(dir, name);\n let stats;\n try {\n stats = statSync(fullPath);\n } catch {\n continue;\n }\n if (stats.isFile() && EXTENSION_FILE_PATTERN.test(name)) {\n entrypoints.push(fullPath);\n continue;\n }\n if (stats.isDirectory()) {\n for (const candidate of [\"index.mjs\", \"index.js\"]) {\n const indexPath = join(fullPath, candidate);\n if (existsSync(indexPath)) {\n entrypoints.push(indexPath);\n break;\n }\n }\n }\n }\n return entrypoints;\n}\n\n/**\n * Filesystem-safe identifier for an extension, derived from its install\n * location (directory name for `<name>/index.mjs`, file basename otherwise).\n * The slug keys the extension's data dir, secrets vault, and schedule\n * ownership — installing the same extension globally and per-conversation\n * shares one slug and therefore one data dir.\n */\nexport function extensionSlug(entrypoint: string): string {\n const base = /^index\\.(mjs|js)$/.test(basename(entrypoint))\n ? basename(dirname(entrypoint))\n : basename(entrypoint).replace(EXTENSION_FILE_PATTERN, \"\");\n const slug = base\n .toLowerCase()\n .replace(/[^a-z0-9_-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 64);\n return slug || \"extension\";\n}\n\n/** Sanitize an extension-chosen schedule name into a filename segment. */\nfunction scheduleNameSegment(name: string): string {\n const segment = name\n .toLowerCase()\n .replace(/[^a-z0-9_-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 64);\n if (!segment) throw new Error(`Invalid schedule name: ${JSON.stringify(name)}`);\n return segment;\n}\n\n/** Read `manifest.json` next to a directory-form extension's entrypoint. */\nfunction readManifest(entrypoint: string): ExtensionManifest {\n if (!/^index\\.(mjs|js)$/.test(basename(entrypoint))) return {};\n const manifestPath = join(dirname(entrypoint), \"manifest.json\");\n if (!existsSync(manifestPath)) return {};\n try {\n const parsed: unknown = JSON.parse(readFileSync(manifestPath, \"utf-8\"));\n if (!parsed || typeof parsed !== \"object\") return {};\n const record = parsed as Record<string, unknown>;\n return {\n name: typeof record.name === \"string\" ? record.name : undefined,\n version: typeof record.version === \"string\" ? record.version : undefined,\n description: typeof record.description === \"string\" ? record.description : undefined,\n };\n } catch (err) {\n log.logWarning(`Ignoring malformed extension manifest: ${manifestPath}`, String(err));\n return {};\n }\n}\n\n/**\n * Skills shipped inside a directory-form extension (`<dir>/skills/`).\n * Marked inline: extension files live under the host-only state dir, which\n * sandbox containers cannot read, so skill bodies must ride in the prompt.\n */\nfunction loadExtensionSkills(entrypoint: string, slug: string): MikanSkill[] {\n if (!/^index\\.(mjs|js)$/.test(basename(entrypoint))) return [];\n const skillsDir = join(dirname(entrypoint), \"skills\");\n if (!existsSync(skillsDir)) return [];\n const result = loadSkillsFromDir({ dir: skillsDir, source: `extension:${slug}` });\n for (const diagnostic of result.diagnostics) {\n log.logWarning(`Extension skill warning (${slug}): ${diagnostic.message}`, diagnostic.path);\n }\n for (const skill of result.skills) skill.inline = true;\n return result.skills;\n}\n\nconst SCHEDULE_FILE_SUFFIX = \".json\";\n\nfunction schedulePrefix(slug: string, conversationId: string): string {\n return `ext.${slug}.${scheduleNameSegment(conversationId)}.`;\n}\n\nfunction payloadFromSpec(\n spec: ExtensionScheduleSpec,\n conversationId: string,\n): ExtensionSchedulePayload {\n if (spec.type === \"periodic\") {\n if (!spec.schedule || !spec.timezone) {\n throw new Error(\"periodic schedule requires schedule and timezone\");\n }\n return {\n type: \"periodic\",\n conversationId,\n text: spec.text,\n schedule: spec.schedule,\n timezone: spec.timezone,\n ...(spec.platform ? { platform: spec.platform } : {}),\n };\n }\n if (!spec.at) throw new Error(\"one-shot schedule requires at\");\n return {\n type: \"one-shot\",\n conversationId,\n text: spec.text,\n at: spec.at,\n ...(spec.platform ? { platform: spec.platform } : {}),\n };\n}\n\nfunction specFromPayload(payload: ExtensionSchedulePayload): ExtensionScheduleSpec {\n if (payload.type === \"periodic\") {\n return {\n type: \"periodic\",\n schedule: payload.schedule ?? \"\",\n timezone: payload.timezone ?? \"\",\n text: payload.text,\n ...(payload.platform ? { platform: payload.platform } : {}),\n };\n }\n return {\n type: \"one-shot\",\n at: payload.at ?? \"\",\n text: payload.text,\n ...(payload.platform ? { platform: payload.platform } : {}),\n };\n}\n\n/** Build the v2 api surface for one extension over the injected services. */\nfunction buildExtensionApi(params: {\n name: string;\n slug: string;\n registry: ExtensionRegistry;\n context: LoadExtensionsOptions[\"context\"];\n services: ExtensionHostServices;\n}): MikanExtensionApi {\n const { name, slug, registry, context, services } = params;\n const stateDir = services.stateDir ?? join(homedir(), \".mikan\");\n const conversationId = context.conversationId;\n\n const requireScheduleStore = () => {\n if (!services.scheduleStore) {\n throw new Error(\"api.schedules is unavailable: this context provides no schedule store\");\n }\n return services.scheduleStore;\n };\n\n return {\n on: (hook, handler) => registry.register(name, hook, handler),\n registerTool: (tool: AgentTool) => registry.registerTool(tool),\n log: (message: string) => log.logInfo(`[extension:${name}] ${message}`),\n context,\n paths: {\n get dataDir(): string {\n const dir = join(stateDir, \"extension-data\", slug);\n mkdirSync(dir, { recursive: true });\n return dir;\n },\n },\n secrets: {\n get: (key: string) => services.resolveSecrets?.(slug)[key],\n list: () => Object.keys(services.resolveSecrets?.(slug) ?? {}),\n },\n schedules: {\n upsert: async (scheduleName, spec) => {\n const store = requireScheduleStore();\n const filename = `${schedulePrefix(slug, conversationId)}${scheduleNameSegment(scheduleName)}${SCHEDULE_FILE_SUFFIX}`;\n await store.write(filename, payloadFromSpec(spec, conversationId));\n },\n delete: async (scheduleName) => {\n const store = requireScheduleStore();\n const filename = `${schedulePrefix(slug, conversationId)}${scheduleNameSegment(scheduleName)}${SCHEDULE_FILE_SUFFIX}`;\n return store.delete(filename);\n },\n list: async () => {\n const store = requireScheduleStore();\n const prefix = schedulePrefix(slug, conversationId);\n const infos: ExtensionScheduleInfo[] = [];\n for (const entry of await store.list()) {\n if (!entry.filename.startsWith(prefix)) continue;\n if (!entry.filename.endsWith(SCHEDULE_FILE_SUFFIX)) continue;\n infos.push({\n name: entry.filename.slice(prefix.length, -SCHEDULE_FILE_SUFFIX.length),\n spec: specFromPayload(entry.payload),\n });\n }\n return infos;\n },\n },\n notify: async (text: string) => {\n if (!services.postMessage) {\n throw new Error(\"api.notify is unavailable: this context provides no platform messaging\");\n }\n await services.postMessage(conversationId, text);\n },\n };\n}\n\nfunction resolveActivate(moduleExports: unknown): MikanExtensionModule | undefined {\n if (!moduleExports || typeof moduleExports !== \"object\") return undefined;\n const candidates: unknown[] = [(moduleExports as { default?: unknown }).default, moduleExports];\n for (const candidate of candidates) {\n if (typeof candidate === \"function\") {\n return { activate: candidate as MikanExtensionActivate };\n }\n if (candidate && typeof candidate === \"object\") {\n const activate = (candidate as { activate?: unknown }).activate;\n if (typeof activate === \"function\") {\n return {\n name:\n typeof (candidate as { name?: unknown }).name === \"string\"\n ? (candidate as { name: string }).name\n : undefined,\n activate: activate as MikanExtensionActivate,\n };\n }\n }\n }\n return undefined;\n}\n\n/** Load and activate all extensions found in the given directories. */\nexport async function loadExtensions(\n options: LoadExtensionsOptions,\n): Promise<LoadExtensionsResult> {\n const registry = new ExtensionRegistry();\n const extensions: LoadedExtension[] = [];\n const errors: ExtensionLoadError[] = [];\n const skills: MikanSkill[] = [];\n const services = options.services ?? {};\n\n for (const dir of options.dirs) {\n for (const entrypoint of discoverExtensionEntrypoints(dir)) {\n try {\n const moduleUrl = `${pathToFileURL(entrypoint).href}?t=${Date.now()}`;\n const moduleExports: unknown = await import(moduleUrl);\n const extension = resolveActivate(moduleExports);\n if (!extension) {\n errors.push({\n path: entrypoint,\n error: \"extension must export an activate function (default or named)\",\n });\n continue;\n }\n const slug = extensionSlug(entrypoint);\n const manifest = readManifest(entrypoint);\n const name = manifest.name ?? extension.name ?? slug;\n const api = buildExtensionApi({\n name,\n slug,\n registry,\n context: options.context,\n services,\n });\n await extension.activate(api);\n const extensionSkills = loadExtensionSkills(entrypoint, slug);\n skills.push(...extensionSkills);\n extensions.push({\n name,\n path: entrypoint,\n slug,\n version: manifest.version,\n description: manifest.description,\n skills: extensionSkills,\n });\n } catch (err) {\n errors.push({\n path: entrypoint,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n }\n\n return { registry, extensions, errors, skills };\n}\n"]}
|