@openacp/cli 0.6.1 → 0.6.2
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/dist/{admin-IKPS5PFC.js → admin-IVQTC72V.js} +2 -2
- package/dist/{agent-catalog-T5ECPEDA.js → agent-catalog-IVU2KANH.js} +2 -2
- package/dist/{agents-55NX3DHM.js → agents-SXIY4IEF.js} +2 -2
- package/dist/{chunk-UB7XUO7C.js → chunk-2OFIWTYD.js} +3 -3
- package/dist/{chunk-H7ZMPBZC.js → chunk-3KGRVAEV.js} +1 -1
- package/dist/chunk-3KGRVAEV.js.map +1 -0
- package/dist/{chunk-2KJC3ILH.js → chunk-7WQH4SOY.js} +4 -4
- package/dist/{chunk-2KJC3ILH.js.map → chunk-7WQH4SOY.js.map} +1 -1
- package/dist/{chunk-J6X5SW6O.js → chunk-CKOK7JW6.js} +3 -2
- package/dist/{chunk-J6X5SW6O.js.map → chunk-CKOK7JW6.js.map} +1 -1
- package/dist/{chunk-4LFDEW22.js → chunk-EWYNCHUH.js} +33 -20
- package/dist/chunk-EWYNCHUH.js.map +1 -0
- package/dist/{chunk-4TR5Y3MP.js → chunk-F3AICYO4.js} +39 -1
- package/dist/chunk-F3AICYO4.js.map +1 -0
- package/dist/{chunk-GINCOFNW.js → chunk-FF4C3ZE4.js} +2 -2
- package/dist/chunk-FF4C3ZE4.js.map +1 -0
- package/dist/{chunk-LGQYTK55.js → chunk-FMWSVLRM.js} +31 -2
- package/dist/chunk-FMWSVLRM.js.map +1 -0
- package/dist/{chunk-THBR6OXH.js → chunk-HSGUPJU5.js} +1 -1
- package/dist/chunk-HSGUPJU5.js.map +1 -0
- package/dist/{chunk-R3UJUOXI.js → chunk-IFTYEG5J.js} +1805 -1003
- package/dist/chunk-IFTYEG5J.js.map +1 -0
- package/dist/{chunk-7G5QKLLF.js → chunk-IUIMBEBX.js} +1 -1
- package/dist/chunk-IUIMBEBX.js.map +1 -0
- package/dist/{chunk-TOZQ3JFN.js → chunk-KO5RL7MZ.js} +2 -2
- package/dist/{chunk-AKIU4JBF.js → chunk-ONENT7JQ.js} +2 -2
- package/dist/chunk-ONENT7JQ.js.map +1 -0
- package/dist/{chunk-IMILOCR5.js → chunk-TMCQZAXN.js} +2 -2
- package/dist/chunk-TMCQZAXN.js.map +1 -0
- package/dist/{chunk-T22OLSET.js → chunk-TTDSLV35.js} +1 -1
- package/dist/chunk-TTDSLV35.js.map +1 -0
- package/dist/{chunk-ZCHNAM3B.js → chunk-WQZ4RXH7.js} +2 -2
- package/dist/cli.js +41 -36
- package/dist/cli.js.map +1 -1
- package/dist/{config-AK2W3E67.js → config-4YSJ4NCI.js} +2 -2
- package/dist/{config-editor-VIA7A72X.js → config-editor-TOZUBMO7.js} +4 -4
- package/dist/{config-registry-QQOJ2GQP.js → config-registry-7I6GGDOY.js} +2 -2
- package/dist/{daemon-G27YZUWB.js → daemon-I6XMRQ6P.js} +3 -3
- package/dist/{discord-2DKRH45T.js → discord-7B5NWW5Z.js} +154 -156
- package/dist/discord-7B5NWW5Z.js.map +1 -0
- package/dist/{doctor-CHCYUTV5.js → doctor-FR5GASOQ.js} +4 -4
- package/dist/doctor-UOH7YCT2.js +9 -0
- package/dist/index.d.ts +176 -90
- package/dist/index.js +20 -10
- package/dist/{integrate-VOUYBPPZ.js → integrate-QTK4PPYQ.js} +15 -6
- package/dist/integrate-QTK4PPYQ.js.map +1 -0
- package/dist/{main-56SPFYW4.js → main-46BVXFWI.js} +19 -18
- package/dist/main-46BVXFWI.js.map +1 -0
- package/dist/{new-session-DRRP2J7E.js → new-session-BVNE6S3A.js} +3 -3
- package/dist/{session-FVFLBREJ.js → session-ZMAM67AA.js} +2 -2
- package/dist/{settings-LPOLJ6SA.js → settings-LQ57CFY4.js} +2 -2
- package/dist/{setup-IPWJCIJM.js → setup-DZXZTQRD.js} +3 -3
- package/dist/{tunnel-service-U6V4HQOO.js → tunnel-service-O5EKGFLO.js} +19 -1
- package/dist/tunnel-service-O5EKGFLO.js.map +1 -0
- package/package.json +2 -1
- package/dist/chunk-4LFDEW22.js.map +0 -1
- package/dist/chunk-4TR5Y3MP.js.map +0 -1
- package/dist/chunk-7G5QKLLF.js.map +0 -1
- package/dist/chunk-AKIU4JBF.js.map +0 -1
- package/dist/chunk-GINCOFNW.js.map +0 -1
- package/dist/chunk-H7ZMPBZC.js.map +0 -1
- package/dist/chunk-IMILOCR5.js.map +0 -1
- package/dist/chunk-LGQYTK55.js.map +0 -1
- package/dist/chunk-R3UJUOXI.js.map +0 -1
- package/dist/chunk-T22OLSET.js.map +0 -1
- package/dist/chunk-THBR6OXH.js.map +0 -1
- package/dist/discord-2DKRH45T.js.map +0 -1
- package/dist/doctor-AN6AZ3PF.js +0 -9
- package/dist/integrate-VOUYBPPZ.js.map +0 -1
- package/dist/main-56SPFYW4.js.map +0 -1
- package/dist/tunnel-service-U6V4HQOO.js.map +0 -1
- /package/dist/{admin-IKPS5PFC.js.map → admin-IVQTC72V.js.map} +0 -0
- /package/dist/{agent-catalog-T5ECPEDA.js.map → agent-catalog-IVU2KANH.js.map} +0 -0
- /package/dist/{agents-55NX3DHM.js.map → agents-SXIY4IEF.js.map} +0 -0
- /package/dist/{chunk-UB7XUO7C.js.map → chunk-2OFIWTYD.js.map} +0 -0
- /package/dist/{chunk-TOZQ3JFN.js.map → chunk-KO5RL7MZ.js.map} +0 -0
- /package/dist/{chunk-ZCHNAM3B.js.map → chunk-WQZ4RXH7.js.map} +0 -0
- /package/dist/{config-AK2W3E67.js.map → config-4YSJ4NCI.js.map} +0 -0
- /package/dist/{config-editor-VIA7A72X.js.map → config-editor-TOZUBMO7.js.map} +0 -0
- /package/dist/{config-registry-QQOJ2GQP.js.map → config-registry-7I6GGDOY.js.map} +0 -0
- /package/dist/{daemon-G27YZUWB.js.map → daemon-I6XMRQ6P.js.map} +0 -0
- /package/dist/{doctor-AN6AZ3PF.js.map → doctor-FR5GASOQ.js.map} +0 -0
- /package/dist/{doctor-CHCYUTV5.js.map → doctor-UOH7YCT2.js.map} +0 -0
- /package/dist/{new-session-DRRP2J7E.js.map → new-session-BVNE6S3A.js.map} +0 -0
- /package/dist/{session-FVFLBREJ.js.map → session-ZMAM67AA.js.map} +0 -0
- /package/dist/{settings-LPOLJ6SA.js.map → settings-LQ57CFY4.js.map} +0 -0
- /package/dist/{setup-IPWJCIJM.js.map → setup-DZXZTQRD.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/discord/commands/admin.ts"],"sourcesContent":["import {\n ActionRowBuilder,\n ButtonBuilder,\n ButtonStyle,\n} from 'discord.js'\nimport type { ChatInputCommandInteraction, ButtonInteraction } from 'discord.js'\nimport { log } from '../../../core/log.js'\nimport type { DiscordAdapter } from '../adapter.js'\n\nexport function buildDangerousModeKeyboard(\n sessionId: string,\n isDangerous: boolean,\n): ActionRowBuilder<ButtonBuilder> {\n return new ActionRowBuilder<ButtonBuilder>().addComponents(\n new ButtonBuilder()\n .setCustomId(`d:${sessionId}`)\n .setLabel(isDangerous ? '🔐 Disable Dangerous Mode' : '☠️ Enable Dangerous Mode')\n .setStyle(isDangerous ? ButtonStyle.Secondary : ButtonStyle.Danger),\n )\n}\n\nexport async function handleDangerous(\n interaction: ChatInputCommandInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n await interaction.deferReply({ ephemeral: true })\n\n const channelId = interaction.channelId\n const session = adapter.core.sessionManager.getSessionByThread('discord', channelId)\n\n if (session) {\n session.dangerousMode = !session.dangerousMode\n adapter.core.sessionManager.patchRecord(session.id, { dangerousMode: session.dangerousMode }).catch(() => {})\n log.info({ sessionId: session.id, dangerousMode: session.dangerousMode }, '[discord-admin] Dangerous mode toggled via command')\n\n const msg = session.dangerousMode\n ? '☠️ **Dangerous mode enabled** — All permission requests will be auto-approved.'\n : '🔐 **Dangerous mode disabled** — Permission requests will be shown normally.'\n await interaction.editReply(msg)\n return\n }\n\n // Session not in memory — update store directly\n const record = adapter.core.sessionManager.getRecordByThread('discord', channelId)\n if (!record || record.status === 'cancelled' || record.status === 'error') {\n await interaction.editReply('⚠️ No active session in this channel.')\n return\n }\n\n const newDangerousMode = !(record.dangerousMode ?? false)\n adapter.core.sessionManager.patchRecord(record.sessionId, { dangerousMode: newDangerousMode }).catch(() => {})\n log.info({ sessionId: record.sessionId, dangerousMode: newDangerousMode }, '[discord-admin] Dangerous mode toggled via command (store-only)')\n\n const msg = newDangerousMode\n ? '☠️ **Dangerous mode enabled** — All permission requests will be auto-approved.'\n : '🔐 **Dangerous mode disabled** — Permission requests will be shown normally.'\n await interaction.editReply(msg)\n}\n\nexport async function handleDangerousButton(\n interaction: ButtonInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n const sessionId = interaction.customId.slice(2) // strip 'd:'\n const session = adapter.core.sessionManager.getSession(sessionId)\n\n // Session live in memory — toggle directly\n if (session) {\n session.dangerousMode = !session.dangerousMode\n adapter.core.sessionManager.patchRecord(sessionId, { dangerousMode: session.dangerousMode }).catch(() => {})\n log.info({ sessionId, dangerousMode: session.dangerousMode }, '[discord-admin] Dangerous mode toggled via button')\n\n const toastText = session.dangerousMode\n ? '☠️ Dangerous mode enabled — permissions auto-approved'\n : '🔐 Dangerous mode disabled — permissions shown normally'\n\n try {\n await interaction.update({\n components: [buildDangerousModeKeyboard(sessionId, session.dangerousMode)],\n })\n } catch { /* ignore */ }\n\n try { await interaction.followUp({ content: toastText, ephemeral: true }) } catch { /* ignore */ }\n return\n }\n\n // Session not in memory — toggle in store\n const record = adapter.core.sessionManager.getSessionRecord(sessionId)\n if (!record || record.status === 'cancelled' || record.status === 'error') {\n await interaction.reply({ content: '⚠️ Session not found or already ended.', ephemeral: true })\n return\n }\n\n const newDangerousMode = !(record.dangerousMode ?? false)\n adapter.core.sessionManager.patchRecord(sessionId, { dangerousMode: newDangerousMode }).catch(() => {})\n log.info({ sessionId, dangerousMode: newDangerousMode }, '[discord-admin] Dangerous mode toggled via button (store-only)')\n\n const toastText = newDangerousMode\n ? '☠️ Dangerous mode enabled — permissions auto-approved'\n : '🔐 Dangerous mode disabled — permissions shown normally'\n\n try {\n await interaction.update({\n components: [buildDangerousModeKeyboard(sessionId, newDangerousMode)],\n })\n } catch { /* ignore */ }\n\n try { await interaction.followUp({ content: toastText, ephemeral: true }) } catch { /* ignore */ }\n}\n\nexport async function handleRestart(\n interaction: ChatInputCommandInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n await interaction.deferReply({ ephemeral: true })\n\n if (!adapter.core.requestRestart) {\n await interaction.editReply('⚠️ Restart is not available (no restart handler registered).')\n return\n }\n\n await interaction.editReply('🔄 **Restarting OpenACP...**\\nRebuilding and restarting. Be back shortly.')\n await new Promise((r) => setTimeout(r, 500))\n await adapter.core.requestRestart()\n}\n\nexport async function handleUpdate(\n interaction: ChatInputCommandInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n await interaction.deferReply({ ephemeral: true })\n // Stub: not implemented yet\n await interaction.editReply('⚠️ Update via Discord is not implemented yet. Run `npm install -g @openacp/cli@latest` in your terminal, then use `/restart`.')\n}\n"],"mappings":"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","names":["msg","toastText"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
expandHome
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-EWYNCHUH.js";
|
|
4
4
|
|
|
5
5
|
// src/core/daemon.ts
|
|
6
6
|
import { spawn } from "child_process";
|
|
@@ -169,4 +169,4 @@ export {
|
|
|
169
169
|
clearRunning,
|
|
170
170
|
shouldAutoStart
|
|
171
171
|
};
|
|
172
|
-
//# sourceMappingURL=chunk-
|
|
172
|
+
//# sourceMappingURL=chunk-KO5RL7MZ.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-SM3G6UAX.js";
|
|
5
5
|
import {
|
|
6
6
|
buildDangerousModeKeyboard
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-IUIMBEBX.js";
|
|
8
8
|
import {
|
|
9
9
|
log
|
|
10
10
|
} from "./chunk-ESOPMQAY.js";
|
|
@@ -142,4 +142,4 @@ export {
|
|
|
142
142
|
executeNewSession,
|
|
143
143
|
handleNewSessionButton
|
|
144
144
|
};
|
|
145
|
-
//# sourceMappingURL=chunk-
|
|
145
|
+
//# sourceMappingURL=chunk-ONENT7JQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/discord/commands/new-session.ts"],"sourcesContent":["import {\n ActionRowBuilder,\n ButtonBuilder,\n ButtonStyle,\n} from 'discord.js'\nimport type { ChatInputCommandInteraction, ButtonInteraction } from 'discord.js'\nimport { log } from '../../../core/log.js'\nimport { buildDangerousModeKeyboard } from './admin.js'\nimport { createSessionThread, deleteSessionThread } from '../forums.js'\nimport type { DiscordAdapter } from '../adapter.js'\n\nexport async function handleNew(\n interaction: ChatInputCommandInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n await interaction.deferReply({ ephemeral: true })\n\n const agentName = interaction.options.getString('agent') ?? undefined\n const workspace = interaction.options.getString('workspace') ?? undefined\n\n if (agentName) {\n await executeNewSession(interaction, adapter, agentName, workspace)\n return\n }\n\n // No agent specified — show agent picker\n const installedEntries = adapter.core.agentCatalog.getInstalledEntries()\n const agentKeys = Object.keys(installedEntries)\n const config = adapter.core.configManager.get()\n\n if (agentKeys.length === 0) {\n await interaction.editReply('❌ No agents installed. Use `/install` to install an agent first.')\n return\n }\n\n if (agentKeys.length === 1) {\n await executeNewSession(interaction, adapter, config.defaultAgent, workspace)\n return\n }\n\n // Multiple agents — show picker buttons\n const row = new ActionRowBuilder<ButtonBuilder>()\n for (const key of agentKeys) {\n const agent = installedEntries[key]!\n const label = key === config.defaultAgent ? `${agent.name} (default)` : agent.name\n row.addComponents(\n new ButtonBuilder()\n .setCustomId(`m:new:agent:${key}`)\n .setLabel(label)\n .setStyle(ButtonStyle.Primary),\n )\n }\n\n await interaction.editReply({\n content: '🤖 **Choose an agent:**',\n components: [row],\n })\n}\n\nexport async function handleNewChat(\n interaction: ChatInputCommandInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n await interaction.deferReply({ ephemeral: true })\n\n // Get current thread to inherit config from\n const channelId = interaction.channelId\n const currentSession = adapter.core.sessionManager.getSessionByThread('discord', channelId)\n\n let agentName: string | undefined\n let workspace: string | undefined\n\n if (currentSession) {\n agentName = currentSession.agentName\n workspace = currentSession.workingDirectory\n } else {\n const record = adapter.core.sessionManager.getRecordByThread('discord', channelId)\n if (!record || record.status === 'cancelled' || record.status === 'error') {\n await interaction.editReply('No active session in this channel. Use `/new` to start one.')\n return\n }\n agentName = record.agentName\n workspace = record.workingDir\n }\n\n await executeNewSession(interaction, adapter, agentName, workspace)\n}\n\nexport async function executeNewSession(\n interaction: ChatInputCommandInteraction | ButtonInteraction,\n adapter: DiscordAdapter,\n agentName?: string,\n workspace?: string,\n): Promise<void> {\n const config = adapter.core.configManager.get()\n const resolvedAgent = agentName || config.defaultAgent\n\n log.info({ agentName: resolvedAgent, workspace }, '[discord-new-session] Creating session')\n\n const forumChannel = adapter.getForumChannel()\n if (!forumChannel) {\n const msg = '❌ Forum channel not configured. Please run setup first.'\n if (interaction.deferred || interaction.replied) {\n await interaction.editReply(msg)\n } else {\n await (interaction as ChatInputCommandInteraction).reply({ content: msg, ephemeral: true })\n }\n return\n }\n\n let thread: import('discord.js').ThreadChannel | undefined\n\n try {\n // Create forum thread BEFORE creating session to avoid race condition\n thread = await createSessionThread(forumChannel, `🔄 ${resolvedAgent} — New Session`)\n\n // Create session via core\n const session = await adapter.core.handleNewSession('discord', resolvedAgent, workspace)\n session.threadId = thread.id\n\n // Patch platform record with Discord thread ID\n await adapter.core.sessionManager.patchRecord(session.id, {\n platform: { threadId: thread.id },\n })\n\n // Send welcome message in the new thread\n const dangerousRow = buildDangerousModeKeyboard(session.id, false)\n await thread.send({\n content:\n `✅ **Session started**\\n` +\n `**Agent:** ${session.agentName}\\n` +\n `**Workspace:** \\`${session.workingDirectory}\\`\\n\\n` +\n `This is your coding session — chat here to work with the agent.`,\n components: [dangerousRow],\n })\n\n // Reply to the interaction with a link to the thread\n const replyMsg = `✅ Session created → [Open thread](https://discord.com/channels/${adapter.getGuildId()}/${thread.id})`\n if (interaction.deferred || interaction.replied) {\n await interaction.editReply(replyMsg)\n } else {\n await (interaction as ChatInputCommandInteraction).reply({ content: replyMsg, ephemeral: true })\n }\n\n // Warm up model cache in background\n session.warmup().catch((err: unknown) => log.error({ err }, '[discord-new-session] Warm-up error'))\n } catch (err) {\n log.error({ err }, '[discord-new-session] Session creation failed')\n\n // Clean up orphaned thread on failure (archive+lock instead of permanent delete)\n if (thread) {\n try { await deleteSessionThread(adapter.getGuild(), thread.id) } catch { /* ignore */ }\n }\n\n const errMsg = `❌ ${err instanceof Error ? err.message : String(err)}`\n try {\n if (interaction.deferred || interaction.replied) {\n await interaction.editReply(errMsg)\n } else {\n await (interaction as ChatInputCommandInteraction).reply({ content: errMsg, ephemeral: true })\n }\n } catch { /* ignore */ }\n }\n}\n\nexport async function handleNewSessionButton(\n interaction: ButtonInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n const { customId } = interaction\n\n if (customId.startsWith('m:new:agent:')) {\n const agentKey = customId.replace('m:new:agent:', '')\n try { await interaction.deferUpdate() } catch { /* ignore */ }\n await executeNewSession(interaction, adapter, agentKey, undefined)\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PLUGINS_DIR
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-EWYNCHUH.js";
|
|
4
4
|
import {
|
|
5
5
|
createChildLogger
|
|
6
6
|
} from "./chunk-ESOPMQAY.js";
|
|
@@ -60,4 +60,4 @@ export {
|
|
|
60
60
|
listPlugins,
|
|
61
61
|
loadAdapterFactory
|
|
62
62
|
};
|
|
63
|
-
//# sourceMappingURL=chunk-
|
|
63
|
+
//# sourceMappingURL=chunk-TMCQZAXN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/plugin-manager.ts"],"sourcesContent":["import { execSync } from 'node:child_process'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { createRequire } from 'node:module'\nimport { PLUGINS_DIR } from './config.js'\nimport { createChildLogger } from './log.js'\nconst log = createChildLogger({ module: 'plugin-manager' })\nimport type { ChannelAdapter, ChannelConfig } from './channel.js'\nimport type { OpenACPCore } from './core.js'\n\nexport interface AdapterFactory {\n name: string\n createAdapter(core: OpenACPCore, config: ChannelConfig): ChannelAdapter\n}\n\nfunction ensurePluginsDir(): void {\n fs.mkdirSync(PLUGINS_DIR, { recursive: true })\n const pkgPath = path.join(PLUGINS_DIR, 'package.json')\n if (!fs.existsSync(pkgPath)) {\n fs.writeFileSync(pkgPath, JSON.stringify({ name: 'openacp-plugins', private: true, dependencies: {} }, null, 2))\n }\n}\n\nexport function installPlugin(packageName: string): void {\n ensurePluginsDir()\n log.info({ packageName }, 'Installing plugin')\n execSync(`npm install ${packageName} --prefix \"${PLUGINS_DIR}\"`, { stdio: 'inherit' })\n log.info({ packageName }, 'Plugin installed successfully')\n}\n\nexport function uninstallPlugin(packageName: string): void {\n ensurePluginsDir()\n log.info({ packageName }, 'Uninstalling plugin')\n execSync(`npm uninstall ${packageName} --prefix \"${PLUGINS_DIR}\"`, { stdio: 'inherit' })\n log.info({ packageName }, 'Plugin uninstalled')\n}\n\nexport function listPlugins(): Record<string, string> {\n const pkgPath = path.join(PLUGINS_DIR, 'package.json')\n if (!fs.existsSync(pkgPath)) return {}\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))\n return pkg.dependencies || {}\n}\n\nexport async function loadAdapterFactory(packageName: string): Promise<AdapterFactory | null> {\n try {\n const require = createRequire(path.join(PLUGINS_DIR, 'package.json'))\n const resolved = require.resolve(packageName)\n const mod = await import(resolved)\n\n // Plugin must export `adapterFactory` or default export conforming to AdapterFactory\n const factory: AdapterFactory | undefined = mod.adapterFactory || mod.default\n if (!factory || typeof factory.createAdapter !== 'function') {\n log.error({ packageName }, 'Plugin does not export a valid AdapterFactory (needs .createAdapter())')\n return null\n }\n return factory\n } catch (err) {\n log.error({ packageName, err }, 'Failed to load plugin')\n log.error({ packageName }, 'Run: npx openacp install <packageName>')\n return null\n }\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,gBAAgB;AACzB,YAAY,QAAQ;AACpB,YAAY,UAAU;AACtB,SAAS,qBAAqB;AAG9B,IAAM,MAAM,kBAAkB,EAAE,QAAQ,iBAAiB,CAAC;AAS1D,SAAS,mBAAyB;AAChC,EAAG,aAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAC7C,QAAM,UAAe,UAAK,aAAa,cAAc;AACrD,MAAI,CAAI,cAAW,OAAO,GAAG;AAC3B,IAAG,iBAAc,SAAS,KAAK,UAAU,EAAE,MAAM,mBAAmB,SAAS,MAAM,cAAc,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC;AAAA,EACjH;AACF;AAEO,SAAS,cAAc,aAA2B;AACvD,mBAAiB;AACjB,MAAI,KAAK,EAAE,YAAY,GAAG,mBAAmB;AAC7C,WAAS,eAAe,WAAW,cAAc,WAAW,KAAK,EAAE,OAAO,UAAU,CAAC;AACrF,MAAI,KAAK,EAAE,YAAY,GAAG,+BAA+B;AAC3D;AAEO,SAAS,gBAAgB,aAA2B;AACzD,mBAAiB;AACjB,MAAI,KAAK,EAAE,YAAY,GAAG,qBAAqB;AAC/C,WAAS,iBAAiB,WAAW,cAAc,WAAW,KAAK,EAAE,OAAO,UAAU,CAAC;AACvF,MAAI,KAAK,EAAE,YAAY,GAAG,oBAAoB;AAChD;AAEO,SAAS,cAAsC;AACpD,QAAM,UAAe,UAAK,aAAa,cAAc;AACrD,MAAI,CAAI,cAAW,OAAO,EAAG,QAAO,CAAC;AACrC,QAAM,MAAM,KAAK,MAAS,gBAAa,SAAS,OAAO,CAAC;AACxD,SAAO,IAAI,gBAAgB,CAAC;AAC9B;AAEA,eAAsB,mBAAmB,aAAqD;AAC5F,MAAI;AACF,UAAMA,WAAU,cAAmB,UAAK,aAAa,cAAc,CAAC;AACpE,UAAM,WAAWA,SAAQ,QAAQ,WAAW;AAC5C,UAAM,MAAM,MAAM,OAAO;AAGzB,UAAM,UAAsC,IAAI,kBAAkB,IAAI;AACtE,QAAI,CAAC,WAAW,OAAO,QAAQ,kBAAkB,YAAY;AAC3D,UAAI,MAAM,EAAE,YAAY,GAAG,wEAAwE;AACnG,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,QAAI,MAAM,EAAE,aAAa,IAAI,GAAG,uBAAuB;AACvD,QAAI,MAAM,EAAE,YAAY,GAAG,wCAAwC;AACnE,WAAO;AAAA,EACT;AACF;","names":["require"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/discord/commands/session.ts"],"sourcesContent":["import {\n ActionRowBuilder,\n ButtonBuilder,\n ButtonStyle,\n} from 'discord.js'\nimport type { ChatInputCommandInteraction, ButtonInteraction } from 'discord.js'\nimport type { Session } from '../../../core/session.js'\nimport { log } from '../../../core/log.js'\nimport { deleteSessionThread } from '../forums.js'\nimport type { DiscordAdapter } from '../adapter.js'\n\nconst STATUS_EMOJI: Record<string, string> = {\n active: '🟢',\n initializing: '🟡',\n finished: '✅',\n error: '❌',\n cancelled: '⛔',\n}\n\nconst STATUS_ORDER: Record<string, number> = {\n active: 0,\n initializing: 1,\n error: 2,\n finished: 3,\n cancelled: 4,\n}\n\nexport async function handleCancel(\n interaction: ChatInputCommandInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n await interaction.deferReply({ ephemeral: true })\n\n const channelId = interaction.channelId\n const session = adapter.core.sessionManager.getSessionByThread('discord', channelId)\n\n if (session) {\n log.info({ sessionId: session.id }, '[discord-session] Cancel command')\n await session.abortPrompt()\n await interaction.editReply('⛔ Session cancelled.')\n return\n }\n\n // Fallback: cancel from store when session not in memory\n const record = adapter.core.sessionManager.getRecordByThread('discord', channelId)\n if (record && record.status !== 'cancelled' && record.status !== 'error') {\n log.info({ sessionId: record.sessionId }, '[discord-session] Cancel command (from store)')\n await adapter.core.sessionManager.cancelSession(record.sessionId)\n await interaction.editReply('⛔ Session cancelled.')\n return\n }\n\n await interaction.editReply('No active session in this channel.')\n}\n\nexport async function handleStatus(\n interaction: ChatInputCommandInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n await interaction.deferReply({ ephemeral: true })\n\n const channelId = interaction.channelId\n const session = adapter.core.sessionManager.getSessionByThread('discord', channelId)\n\n if (session) {\n await interaction.editReply(\n `**Session:** ${session.name || session.id}\\n` +\n `**Agent:** ${session.agentName}\\n` +\n `**Status:** ${session.status}\\n` +\n `**Workspace:** \\`${session.workingDirectory}\\`\\n` +\n `**Queue:** ${session.queueDepth} pending`,\n )\n return\n }\n\n // Try stored record\n const record = adapter.core.sessionManager.getRecordByThread('discord', channelId)\n if (record) {\n await interaction.editReply(\n `**Session:** ${record.name || record.sessionId}\\n` +\n `**Agent:** ${record.agentName}\\n` +\n `**Status:** ${record.status} (not loaded)\\n` +\n `**Workspace:** \\`${record.workingDir}\\``,\n )\n return\n }\n\n // Global status\n const sessions = adapter.core.sessionManager.listSessions('discord')\n const active = sessions.filter(\n (s: Session) => s.status === 'active' || s.status === 'initializing',\n )\n await interaction.editReply(\n `**OpenACP Status**\\n` +\n `Active sessions: ${active.length}\\n` +\n `Total sessions: ${sessions.length}`,\n )\n}\n\nexport async function handleSessions(\n interaction: ChatInputCommandInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n await interaction.deferReply({ ephemeral: true })\n\n try {\n const allRecords = adapter.core.sessionManager.listRecords()\n\n // Only show sessions that have a Discord thread\n const records = allRecords.filter((r: any) => {\n const platform = r.platform as { topicId?: string | number }\n return !!platform?.topicId\n })\n const headlessCount = allRecords.length - records.length\n\n if (records.length === 0) {\n const extra = headlessCount > 0 ? ` (${headlessCount} headless hidden)` : ''\n await interaction.editReply(`No sessions found.${extra}`)\n return\n }\n\n records.sort(\n (a: any, b: any) => (STATUS_ORDER[a.status] ?? 5) - (STATUS_ORDER[b.status] ?? 5),\n )\n\n const MAX_DISPLAY = 25\n const displayed = records.slice(0, MAX_DISPLAY)\n\n const lines = displayed.map((r: any) => {\n const emoji = STATUS_EMOJI[r.status] || '⚪'\n const name = r.name?.trim() || `${r.agentName} session`\n return `${emoji} **${name}** \\`[${r.status}]\\``\n })\n\n const header =\n `**Sessions: ${records.length}**` +\n (headlessCount > 0 ? ` (${headlessCount} headless hidden)` : '')\n const truncated =\n records.length > MAX_DISPLAY\n ? `\\n\\n*...and ${records.length - MAX_DISPLAY} more*`\n : ''\n\n // Cleanup buttons\n const finishedCount = allRecords.filter((r: any) => r.status === 'finished').length\n const errorCount = allRecords.filter(\n (r: any) => r.status === 'error' || r.status === 'cancelled',\n ).length\n\n const rows: ActionRowBuilder<ButtonBuilder>[] = []\n\n if (finishedCount + errorCount > 0) {\n const cleanupRow = new ActionRowBuilder<ButtonBuilder>()\n if (finishedCount > 0) {\n cleanupRow.addComponents(\n new ButtonBuilder()\n .setCustomId('m:cleanup:finished')\n .setLabel(`Cleanup finished (${finishedCount})`)\n .setStyle(ButtonStyle.Secondary),\n )\n }\n if (errorCount > 0) {\n cleanupRow.addComponents(\n new ButtonBuilder()\n .setCustomId('m:cleanup:errors')\n .setLabel(`Cleanup errors (${errorCount})`)\n .setStyle(ButtonStyle.Secondary),\n )\n }\n rows.push(cleanupRow)\n\n const cleanupAllRow = new ActionRowBuilder<ButtonBuilder>()\n cleanupAllRow.addComponents(\n new ButtonBuilder()\n .setCustomId('m:cleanup:all')\n .setLabel(`Cleanup all non-active (${finishedCount + errorCount})`)\n .setStyle(ButtonStyle.Secondary),\n )\n rows.push(cleanupAllRow)\n }\n\n await interaction.editReply({\n content: `${header}\\n\\n${lines.join('\\n')}${truncated}`,\n components: rows,\n })\n } catch (err) {\n log.error({ err }, '[discord-session] handleSessions error')\n await interaction.editReply('❌ Failed to list sessions.').catch(() => {})\n }\n}\n\nexport async function handleHandoff(\n interaction: ChatInputCommandInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n await interaction.deferReply({ ephemeral: true })\n\n const channelId = interaction.channelId\n const session = adapter.core.sessionManager.getSessionByThread('discord', channelId)\n\n if (!session) {\n const record = adapter.core.sessionManager.getRecordByThread('discord', channelId)\n if (!record) {\n await interaction.editReply('No session found in this channel.')\n return\n }\n const cmd = `openacp agents run ${record.agentName} --resume ${record.agentSessionId} -- --continue`\n await interaction.editReply(\n `**Resume in terminal:**\\n\\`\\`\\`\\n${cmd}\\n\\`\\`\\`\\n\\n*Run this from your project directory:* \\`${record.workingDir}\\``,\n )\n return\n }\n\n const cmd = `openacp agents run ${session.agentName} --resume ${session.agentSessionId} -- --continue`\n await interaction.editReply(\n `**Resume in terminal:**\\n\\`\\`\\`\\n${cmd}\\n\\`\\`\\`\\n\\n*Run this from your project directory:* \\`${session.workingDirectory}\\``,\n )\n}\n\nexport async function executeCancelSession(\n interaction: ButtonInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n const sessions: Session[] = adapter.core.sessionManager\n .listSessions('discord')\n .filter((s: Session) => s.status === 'active')\n .sort((a: Session, b: Session) => b.createdAt.getTime() - a.createdAt.getTime())\n\n const session = sessions[0]\n if (!session) {\n await interaction.reply({ content: 'No active sessions to cancel.', ephemeral: true })\n return\n }\n\n await session.abortPrompt()\n await interaction.reply({ content: `⛔ Cancelled session: **${session.name || session.id}**`, ephemeral: true })\n}\n\nexport async function handleCleanupButton(\n interaction: ButtonInteraction,\n adapter: DiscordAdapter,\n): Promise<void> {\n const { customId } = interaction\n\n switch (customId) {\n case 'm:cleanup:all':\n await interaction.deferReply({ ephemeral: true })\n await runCleanup(interaction, adapter, ['finished', 'error', 'cancelled'])\n break\n\n case 'm:cleanup:finished':\n await interaction.deferReply({ ephemeral: true })\n await runCleanup(interaction, adapter, ['finished'])\n break\n\n case 'm:cleanup:errors':\n await interaction.deferReply({ ephemeral: true })\n await runCleanup(interaction, adapter, ['error', 'cancelled'])\n break\n\n case 'm:cleanup:confirm':\n await interaction.deferReply({ ephemeral: true })\n await runCleanup(interaction, adapter, ['finished', 'error', 'cancelled', 'active', 'initializing'])\n break\n\n case 'm:cleanup:cancel':\n try { await interaction.update({ components: [] }) } catch { /* ignore */ }\n break\n\n default:\n // Unknown cleanup variant — ignore\n try { await interaction.reply({ content: 'Unknown cleanup action.', ephemeral: true }) } catch { /* ignore */ }\n }\n}\n\nasync function runCleanup(\n interaction: ButtonInteraction,\n adapter: DiscordAdapter,\n statuses: string[],\n): Promise<void> {\n const allRecords = adapter.core.sessionManager.listRecords()\n const cleanable = allRecords.filter((r: any) => statuses.includes(r.status))\n\n if (cleanable.length === 0) {\n await interaction.editReply('Nothing to clean up.')\n return\n }\n\n let deleted = 0\n let failed = 0\n\n for (const record of cleanable) {\n try {\n // Cancel active sessions first\n if (record.status === 'active' || record.status === 'initializing') {\n try {\n await adapter.core.sessionManager.cancelSession(record.sessionId)\n } catch (err) {\n log.warn({ err, sessionId: record.sessionId }, '[discord-session] Failed to cancel session during cleanup')\n }\n }\n\n const platform = record.platform as { topicId?: string | number; threadId?: string } | undefined\n const threadId = platform?.threadId ?? (platform?.topicId != null ? String(platform.topicId) : undefined)\n if (threadId) {\n try {\n await deleteSessionThread(adapter.getGuild(), threadId)\n } catch (err) {\n log.warn({ err, sessionId: record.sessionId, threadId }, '[discord-session] Failed to delete thread during cleanup')\n }\n }\n await adapter.core.sessionManager.removeRecord(record.sessionId)\n deleted++\n } catch (err) {\n log.error({ err, sessionId: record.sessionId }, '[discord-session] Failed to cleanup session')\n failed++\n }\n }\n\n await interaction.editReply(\n `🗑 Cleaned up **${deleted}** sessions${failed > 0 ? ` (${failed} failed)` : ''}.`,\n )\n}\n"],"mappings":"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","names":["cmd"]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
ConfigSchema,
|
|
4
4
|
applyMigrations,
|
|
5
5
|
expandHome
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-EWYNCHUH.js";
|
|
7
7
|
|
|
8
8
|
// src/core/doctor/index.ts
|
|
9
9
|
import * as fs8 from "fs";
|
|
@@ -721,4 +721,4 @@ var DoctorEngine = class {
|
|
|
721
721
|
export {
|
|
722
722
|
DoctorEngine
|
|
723
723
|
};
|
|
724
|
-
//# sourceMappingURL=chunk-
|
|
724
|
+
//# sourceMappingURL=chunk-WQZ4RXH7.js.map
|
package/dist/cli.js
CHANGED
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
installPlugin,
|
|
4
4
|
listPlugins,
|
|
5
5
|
uninstallPlugin
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-TMCQZAXN.js";
|
|
7
|
+
import "./chunk-EWYNCHUH.js";
|
|
8
8
|
import "./chunk-ESOPMQAY.js";
|
|
9
9
|
import {
|
|
10
10
|
apiCall,
|
|
@@ -497,7 +497,8 @@ Shows the version of the currently running daemon process.
|
|
|
497
497
|
const res = await apiCall(port, `/api/topics/${encodeURIComponent(sessionId)}${query}`, { method: "DELETE" });
|
|
498
498
|
const data = await res.json();
|
|
499
499
|
if (res.status === 409) {
|
|
500
|
-
|
|
500
|
+
const session = data.session;
|
|
501
|
+
console.error(`Session "${sessionId}" is active (${session?.status}). Use --force to delete.`);
|
|
501
502
|
process.exit(1);
|
|
502
503
|
}
|
|
503
504
|
if (!res.ok) {
|
|
@@ -771,8 +772,8 @@ Requires an existing config \u2014 run 'openacp' first to set up.
|
|
|
771
772
|
return;
|
|
772
773
|
}
|
|
773
774
|
await checkAndPromptUpdate();
|
|
774
|
-
const { startDaemon, getPidPath } = await import("./daemon-
|
|
775
|
-
const { ConfigManager } = await import("./config-
|
|
775
|
+
const { startDaemon, getPidPath } = await import("./daemon-I6XMRQ6P.js");
|
|
776
|
+
const { ConfigManager } = await import("./config-4YSJ4NCI.js");
|
|
776
777
|
const cm = new ConfigManager();
|
|
777
778
|
if (await cm.exists()) {
|
|
778
779
|
await cm.load();
|
|
@@ -800,7 +801,7 @@ Sends a stop signal to the running OpenACP daemon process.
|
|
|
800
801
|
`);
|
|
801
802
|
return;
|
|
802
803
|
}
|
|
803
|
-
const { stopDaemon } = await import("./daemon-
|
|
804
|
+
const { stopDaemon } = await import("./daemon-I6XMRQ6P.js");
|
|
804
805
|
const result = await stopDaemon();
|
|
805
806
|
if (result.stopped) {
|
|
806
807
|
console.log(`OpenACP daemon stopped (was PID ${result.pid})`);
|
|
@@ -821,7 +822,7 @@ Shows whether the OpenACP daemon is running and its PID.
|
|
|
821
822
|
`);
|
|
822
823
|
return;
|
|
823
824
|
}
|
|
824
|
-
const { getStatus } = await import("./daemon-
|
|
825
|
+
const { getStatus } = await import("./daemon-I6XMRQ6P.js");
|
|
825
826
|
const status = getStatus();
|
|
826
827
|
if (status.running) {
|
|
827
828
|
console.log(`OpenACP is running (PID ${status.pid})`);
|
|
@@ -845,7 +846,7 @@ Log file location is configured in config (default: ~/.openacp/logs/).
|
|
|
845
846
|
return;
|
|
846
847
|
}
|
|
847
848
|
const { spawn } = await import("child_process");
|
|
848
|
-
const { ConfigManager, expandHome } = await import("./config-
|
|
849
|
+
const { ConfigManager, expandHome } = await import("./config-4YSJ4NCI.js");
|
|
849
850
|
const pathMod = await import("path");
|
|
850
851
|
const cm = new ConfigManager();
|
|
851
852
|
let logDir = "~/.openacp/logs";
|
|
@@ -915,7 +916,7 @@ the API for live updates. When stopped, edits config file directly.
|
|
|
915
916
|
console.error("Usage: openacp config set <path> <value>");
|
|
916
917
|
process.exit(1);
|
|
917
918
|
}
|
|
918
|
-
const { ConfigSchema } = await import("./config-
|
|
919
|
+
const { ConfigSchema } = await import("./config-4YSJ4NCI.js");
|
|
919
920
|
const topLevelKey = configPath.split(".")[0];
|
|
920
921
|
const validConfigKeys = Object.keys(ConfigSchema.shape);
|
|
921
922
|
if (!validConfigKeys.includes(topLevelKey)) {
|
|
@@ -947,7 +948,7 @@ the API for live updates. When stopped, edits config file directly.
|
|
|
947
948
|
console.log("Note: restart required for this change to take effect.");
|
|
948
949
|
}
|
|
949
950
|
} else {
|
|
950
|
-
const { ConfigManager: ConfigManager2 } = await import("./config-
|
|
951
|
+
const { ConfigManager: ConfigManager2 } = await import("./config-4YSJ4NCI.js");
|
|
951
952
|
const cm2 = new ConfigManager2();
|
|
952
953
|
if (!await cm2.exists()) {
|
|
953
954
|
console.error('No config found. Run "openacp" first to set up.');
|
|
@@ -960,8 +961,8 @@ the API for live updates. When stopped, edits config file directly.
|
|
|
960
961
|
}
|
|
961
962
|
return;
|
|
962
963
|
}
|
|
963
|
-
const { runConfigEditor } = await import("./config-editor-
|
|
964
|
-
const { ConfigManager } = await import("./config-
|
|
964
|
+
const { runConfigEditor } = await import("./config-editor-TOZUBMO7.js");
|
|
965
|
+
const { ConfigManager } = await import("./config-4YSJ4NCI.js");
|
|
965
966
|
const cm = new ConfigManager();
|
|
966
967
|
if (!await cm.exists()) {
|
|
967
968
|
console.error('No config found. Run "openacp" first to set up.');
|
|
@@ -1000,7 +1001,7 @@ start fresh with the setup wizard. The daemon must be stopped first.
|
|
|
1000
1001
|
`);
|
|
1001
1002
|
return;
|
|
1002
1003
|
}
|
|
1003
|
-
const { getStatus } = await import("./daemon-
|
|
1004
|
+
const { getStatus } = await import("./daemon-I6XMRQ6P.js");
|
|
1004
1005
|
const status = getStatus();
|
|
1005
1006
|
if (status.running) {
|
|
1006
1007
|
console.error("OpenACP is running. Stop it first: openacp stop");
|
|
@@ -1062,34 +1063,38 @@ async function cmdAdopt(args2) {
|
|
|
1062
1063
|
\x1B[1mopenacp adopt\x1B[0m \u2014 Adopt an external agent session
|
|
1063
1064
|
|
|
1064
1065
|
\x1B[1mUsage:\x1B[0m
|
|
1065
|
-
openacp adopt <agent> <session_id> [--cwd <path>]
|
|
1066
|
+
openacp adopt <agent> <session_id> [--cwd <path>] [--channel <name>]
|
|
1066
1067
|
|
|
1067
1068
|
\x1B[1mArguments:\x1B[0m
|
|
1068
1069
|
<agent> Agent name (e.g. claude)
|
|
1069
1070
|
<session_id> External session ID to adopt
|
|
1070
1071
|
|
|
1071
1072
|
\x1B[1mOptions:\x1B[0m
|
|
1072
|
-
--cwd <path>
|
|
1073
|
-
|
|
1073
|
+
--cwd <path> Working directory for the session (default: current dir)
|
|
1074
|
+
--channel <name> Target channel adapter (e.g. telegram, discord). Default: first registered
|
|
1075
|
+
-h, --help Show this help message
|
|
1074
1076
|
|
|
1075
1077
|
Transfers an existing agent session into OpenACP so it appears
|
|
1076
|
-
as a
|
|
1078
|
+
as a messaging thread. Requires a running daemon.
|
|
1077
1079
|
|
|
1078
1080
|
\x1B[1mExamples:\x1B[0m
|
|
1079
1081
|
openacp adopt claude abc123-def456
|
|
1080
1082
|
openacp adopt claude abc123 --cwd /path/to/project
|
|
1083
|
+
openacp adopt claude abc123 --channel discord
|
|
1081
1084
|
`);
|
|
1082
1085
|
return;
|
|
1083
1086
|
}
|
|
1084
1087
|
const agent = args2[1];
|
|
1085
1088
|
const sessionId = args2[2];
|
|
1086
1089
|
if (!agent || !sessionId) {
|
|
1087
|
-
console.log("Usage: openacp adopt <agent> <session_id> [--cwd <path>]");
|
|
1090
|
+
console.log("Usage: openacp adopt <agent> <session_id> [--cwd <path>] [--channel <name>]");
|
|
1088
1091
|
console.log("Example: openacp adopt claude abc123-def456 --cwd /path/to/project");
|
|
1089
1092
|
process.exit(1);
|
|
1090
1093
|
}
|
|
1091
1094
|
const cwdIdx = args2.indexOf("--cwd");
|
|
1092
1095
|
const cwd = cwdIdx !== -1 && args2[cwdIdx + 1] ? args2[cwdIdx + 1] : process.cwd();
|
|
1096
|
+
const channelIdx = args2.indexOf("--channel");
|
|
1097
|
+
const channel = channelIdx !== -1 && args2[channelIdx + 1] ? args2[channelIdx + 1] : void 0;
|
|
1093
1098
|
const port = readApiPort();
|
|
1094
1099
|
if (!port) {
|
|
1095
1100
|
console.log("OpenACP is not running. Start it with: openacp start");
|
|
@@ -1100,7 +1105,7 @@ as a Telegram topic. Requires a running daemon.
|
|
|
1100
1105
|
const res = await apiCall2(port, "/api/sessions/adopt", {
|
|
1101
1106
|
method: "POST",
|
|
1102
1107
|
headers: { "Content-Type": "application/json" },
|
|
1103
|
-
body: JSON.stringify({ agent, agentSessionId: sessionId, cwd })
|
|
1108
|
+
body: JSON.stringify({ agent, agentSessionId: sessionId, cwd, channel })
|
|
1104
1109
|
});
|
|
1105
1110
|
const data = await res.json();
|
|
1106
1111
|
if (data.ok) {
|
|
@@ -1137,7 +1142,7 @@ async function cmdIntegrate(args2) {
|
|
|
1137
1142
|
-h, --help Show this help message
|
|
1138
1143
|
|
|
1139
1144
|
Integrations enable features like session handoff from an agent
|
|
1140
|
-
to OpenACP (Telegram). For example, the Claude integration adds
|
|
1145
|
+
to OpenACP (Telegram/Discord). For example, the Claude integration adds
|
|
1141
1146
|
a "Handoff" slash command to Claude Code.
|
|
1142
1147
|
|
|
1143
1148
|
\x1B[1mExamples:\x1B[0m
|
|
@@ -1146,7 +1151,7 @@ a "Handoff" slash command to Claude Code.
|
|
|
1146
1151
|
`);
|
|
1147
1152
|
return;
|
|
1148
1153
|
}
|
|
1149
|
-
const { getIntegration, listIntegrations } = await import("./integrate-
|
|
1154
|
+
const { getIntegration, listIntegrations } = await import("./integrate-QTK4PPYQ.js");
|
|
1150
1155
|
const agent = args2[1];
|
|
1151
1156
|
const uninstall = args2.includes("--uninstall");
|
|
1152
1157
|
if (!agent) {
|
|
@@ -1220,7 +1225,7 @@ Fixable issues can be auto-repaired when not using --dry-run.
|
|
|
1220
1225
|
process.exit(1);
|
|
1221
1226
|
}
|
|
1222
1227
|
const dryRun = args2.includes("--dry-run");
|
|
1223
|
-
const { DoctorEngine } = await import("./doctor-
|
|
1228
|
+
const { DoctorEngine } = await import("./doctor-UOH7YCT2.js");
|
|
1224
1229
|
const engine = new DoctorEngine({ dryRun });
|
|
1225
1230
|
console.log("\n\u{1FA7A} OpenACP Doctor\n");
|
|
1226
1231
|
const report = await engine.runAll();
|
|
@@ -1408,7 +1413,7 @@ Run 'openacp agents' to see available agents.`);
|
|
|
1408
1413
|
}
|
|
1409
1414
|
}
|
|
1410
1415
|
async function agentsList() {
|
|
1411
|
-
const { AgentCatalog } = await import("./agent-catalog-
|
|
1416
|
+
const { AgentCatalog } = await import("./agent-catalog-IVU2KANH.js");
|
|
1412
1417
|
const catalog = new AgentCatalog();
|
|
1413
1418
|
catalog.load();
|
|
1414
1419
|
await catalog.refreshRegistryIfStale();
|
|
@@ -1471,7 +1476,7 @@ Run 'openacp agents' to see available agents.
|
|
|
1471
1476
|
`);
|
|
1472
1477
|
return;
|
|
1473
1478
|
}
|
|
1474
|
-
const { AgentCatalog } = await import("./agent-catalog-
|
|
1479
|
+
const { AgentCatalog } = await import("./agent-catalog-IVU2KANH.js");
|
|
1475
1480
|
const catalog = new AgentCatalog();
|
|
1476
1481
|
catalog.load();
|
|
1477
1482
|
await catalog.refreshRegistryIfStale();
|
|
@@ -1516,7 +1521,7 @@ Run 'openacp agents' to see available agents.
|
|
|
1516
1521
|
const { getAgentCapabilities } = await import("./agent-dependencies-QY5QSULV.js");
|
|
1517
1522
|
const caps = getAgentCapabilities(result.agentKey);
|
|
1518
1523
|
if (caps.integration) {
|
|
1519
|
-
const { installIntegration } = await import("./integrate-
|
|
1524
|
+
const { installIntegration } = await import("./integrate-QTK4PPYQ.js");
|
|
1520
1525
|
const intResult = await installIntegration(result.agentKey, caps.integration);
|
|
1521
1526
|
if (intResult.success) {
|
|
1522
1527
|
console.log(` \x1B[32m\u2713\x1B[0m Handoff integration installed for ${result.agentKey}`);
|
|
@@ -1550,7 +1555,7 @@ async function agentsUninstall(name, help = false) {
|
|
|
1550
1555
|
`);
|
|
1551
1556
|
return;
|
|
1552
1557
|
}
|
|
1553
|
-
const { AgentCatalog } = await import("./agent-catalog-
|
|
1558
|
+
const { AgentCatalog } = await import("./agent-catalog-IVU2KANH.js");
|
|
1554
1559
|
const catalog = new AgentCatalog();
|
|
1555
1560
|
catalog.load();
|
|
1556
1561
|
const result = await catalog.uninstall(name);
|
|
@@ -1558,7 +1563,7 @@ async function agentsUninstall(name, help = false) {
|
|
|
1558
1563
|
const { getAgentCapabilities } = await import("./agent-dependencies-QY5QSULV.js");
|
|
1559
1564
|
const caps = getAgentCapabilities(name);
|
|
1560
1565
|
if (caps.integration) {
|
|
1561
|
-
const { uninstallIntegration } = await import("./integrate-
|
|
1566
|
+
const { uninstallIntegration } = await import("./integrate-QTK4PPYQ.js");
|
|
1562
1567
|
await uninstallIntegration(name, caps.integration);
|
|
1563
1568
|
console.log(` \x1B[32m\u2713\x1B[0m Handoff integration removed for ${name}`);
|
|
1564
1569
|
}
|
|
@@ -1578,7 +1583,7 @@ async function agentsUninstall(name, help = false) {
|
|
|
1578
1583
|
}
|
|
1579
1584
|
}
|
|
1580
1585
|
async function agentsRefresh() {
|
|
1581
|
-
const { AgentCatalog } = await import("./agent-catalog-
|
|
1586
|
+
const { AgentCatalog } = await import("./agent-catalog-IVU2KANH.js");
|
|
1582
1587
|
const catalog = new AgentCatalog();
|
|
1583
1588
|
catalog.load();
|
|
1584
1589
|
console.log("\n Updating agent list...");
|
|
@@ -1605,7 +1610,7 @@ whether the agent is installed or available from the registry.
|
|
|
1605
1610
|
`);
|
|
1606
1611
|
return;
|
|
1607
1612
|
}
|
|
1608
|
-
const { AgentCatalog } = await import("./agent-catalog-
|
|
1613
|
+
const { AgentCatalog } = await import("./agent-catalog-IVU2KANH.js");
|
|
1609
1614
|
const catalog = new AgentCatalog();
|
|
1610
1615
|
catalog.load();
|
|
1611
1616
|
const { getAgentSetup } = await import("./agent-dependencies-QY5QSULV.js");
|
|
@@ -1686,7 +1691,7 @@ ACP-specific flags are automatically stripped.
|
|
|
1686
1691
|
`);
|
|
1687
1692
|
return;
|
|
1688
1693
|
}
|
|
1689
|
-
const { AgentCatalog } = await import("./agent-catalog-
|
|
1694
|
+
const { AgentCatalog } = await import("./agent-catalog-IVU2KANH.js");
|
|
1690
1695
|
const catalog = new AgentCatalog();
|
|
1691
1696
|
catalog.load();
|
|
1692
1697
|
const installed = catalog.getInstalledAgent(nameOrId);
|
|
@@ -1762,17 +1767,17 @@ async function cmdDefault(command2) {
|
|
|
1762
1767
|
process.exit(1);
|
|
1763
1768
|
}
|
|
1764
1769
|
await checkAndPromptUpdate();
|
|
1765
|
-
const { ConfigManager } = await import("./config-
|
|
1770
|
+
const { ConfigManager } = await import("./config-4YSJ4NCI.js");
|
|
1766
1771
|
const cm = new ConfigManager();
|
|
1767
1772
|
if (!await cm.exists()) {
|
|
1768
|
-
const { runSetup } = await import("./setup-
|
|
1773
|
+
const { runSetup } = await import("./setup-DZXZTQRD.js");
|
|
1769
1774
|
const shouldStart = await runSetup(cm);
|
|
1770
1775
|
if (!shouldStart) process.exit(0);
|
|
1771
1776
|
}
|
|
1772
1777
|
await cm.load();
|
|
1773
1778
|
const config = cm.get();
|
|
1774
1779
|
if (!forceForeground && config.runMode === "daemon") {
|
|
1775
|
-
const { startDaemon, getPidPath } = await import("./daemon-
|
|
1780
|
+
const { startDaemon, getPidPath } = await import("./daemon-I6XMRQ6P.js");
|
|
1776
1781
|
const result = startDaemon(getPidPath(), config.logging.logDir);
|
|
1777
1782
|
if ("error" in result) {
|
|
1778
1783
|
console.error(result.error);
|
|
@@ -1781,9 +1786,9 @@ async function cmdDefault(command2) {
|
|
|
1781
1786
|
console.log(`OpenACP daemon started (PID ${result.pid})`);
|
|
1782
1787
|
return;
|
|
1783
1788
|
}
|
|
1784
|
-
const { markRunning } = await import("./daemon-
|
|
1789
|
+
const { markRunning } = await import("./daemon-I6XMRQ6P.js");
|
|
1785
1790
|
markRunning();
|
|
1786
|
-
const { startServer } = await import("./main-
|
|
1791
|
+
const { startServer } = await import("./main-46BVXFWI.js");
|
|
1787
1792
|
await startServer();
|
|
1788
1793
|
}
|
|
1789
1794
|
|
|
@@ -1813,7 +1818,7 @@ var commands = {
|
|
|
1813
1818
|
"agents": () => cmdAgents(args),
|
|
1814
1819
|
"tunnel": () => cmdTunnel(args),
|
|
1815
1820
|
"--daemon-child": async () => {
|
|
1816
|
-
const { startServer } = await import("./main-
|
|
1821
|
+
const { startServer } = await import("./main-46BVXFWI.js");
|
|
1817
1822
|
await startServer();
|
|
1818
1823
|
}
|
|
1819
1824
|
};
|