@openacp/cli 0.5.0 → 0.5.1
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/README.md +1 -1
- package/dist/{agent-catalog-4IAJ7HEG.js → agent-catalog-LAAVBVLY.js} +3 -3
- package/dist/agent-dependencies-FCLRGMZM.js +23 -0
- package/dist/{agent-registry-B5YAMA4T.js → agent-registry-KZANAFXQ.js} +2 -2
- package/dist/{chunk-S3DRLJPM.js → chunk-5MH66WUY.js} +6 -4
- package/dist/chunk-5MH66WUY.js.map +1 -0
- package/dist/{chunk-LAFKARV3.js → chunk-776VAU3T.js} +2 -2
- package/dist/chunk-GUHCS6X7.js +282 -0
- package/dist/chunk-GUHCS6X7.js.map +1 -0
- package/dist/{chunk-UG6X672R.js → chunk-IURZ4QHG.js} +3 -2
- package/dist/chunk-IURZ4QHG.js.map +1 -0
- package/dist/{chunk-FWN3UIRT.js → chunk-PHC67OP4.js} +114 -29
- package/dist/chunk-PHC67OP4.js.map +1 -0
- package/dist/{chunk-D73LCTPF.js → chunk-QODDJ4PH.js} +19 -10
- package/dist/chunk-QODDJ4PH.js.map +1 -0
- package/dist/cli.js +269 -65
- package/dist/cli.js.map +1 -1
- package/dist/{config-editor-5L7AJ5AF.js → config-editor-RGV6VKPZ.js} +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +15 -15
- package/dist/integrate-X7LI6MUO.js +257 -0
- package/dist/integrate-X7LI6MUO.js.map +1 -0
- package/dist/{main-37GLOJ7G.js → main-DSQBCJHR.js} +10 -10
- package/dist/{menu-6RCPBVGQ.js → menu-J5YVH665.js} +2 -2
- package/dist/{setup-QAS3QW3M.js → setup-3A3XDGCM.js} +3 -3
- package/dist/setup-3A3XDGCM.js.map +1 -0
- package/dist/suggest-RST5VOHB.js +36 -0
- package/dist/suggest-RST5VOHB.js.map +1 -0
- package/package.json +2 -1
- package/dist/chunk-D73LCTPF.js.map +0 -1
- package/dist/chunk-FWN3UIRT.js.map +0 -1
- package/dist/chunk-S3DRLJPM.js.map +0 -1
- package/dist/chunk-UG6X672R.js.map +0 -1
- package/dist/chunk-XJJ7LPXP.js +0 -85
- package/dist/chunk-XJJ7LPXP.js.map +0 -1
- package/dist/integrate-WUPLRJD3.js +0 -145
- package/dist/integrate-WUPLRJD3.js.map +0 -1
- /package/dist/{agent-catalog-4IAJ7HEG.js.map → agent-catalog-LAAVBVLY.js.map} +0 -0
- /package/dist/{agent-registry-B5YAMA4T.js.map → agent-dependencies-FCLRGMZM.js.map} +0 -0
- /package/dist/{config-editor-5L7AJ5AF.js.map → agent-registry-KZANAFXQ.js.map} +0 -0
- /package/dist/{chunk-LAFKARV3.js.map → chunk-776VAU3T.js.map} +0 -0
- /package/dist/{menu-6RCPBVGQ.js.map → config-editor-RGV6VKPZ.js.map} +0 -0
- /package/dist/{main-37GLOJ7G.js.map → main-DSQBCJHR.js.map} +0 -0
- /package/dist/{setup-QAS3QW3M.js.map → menu-J5YVH665.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/agent-catalog.ts","../../src/core/agent-installer.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport { AgentStore } from \"./agent-store.js\";\nimport { installAgent, uninstallAgent, resolveDistribution } from \"./agent-installer.js\";\nimport { getAgentAlias, checkDependencies } from \"./agent-dependencies.js\";\nimport type {\n AgentDefinition,\n RegistryAgent,\n AgentListItem,\n AvailabilityResult,\n InstallProgress,\n InstallResult,\n InstalledAgent,\n} from \"./types.js\";\nimport { createChildLogger } from \"./log.js\";\n\nconst log = createChildLogger({ module: \"agent-catalog\" });\n\nconst REGISTRY_URL = \"https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json\";\nconst CACHE_PATH = path.join(os.homedir(), \".openacp\", \"registry-cache.json\");\nconst DEFAULT_TTL_HOURS = 24;\n\ninterface RegistryCache {\n fetchedAt: string;\n ttlHours: number;\n data: { agents: RegistryAgent[] };\n}\n\nexport class AgentCatalog {\n private store: AgentStore;\n private registryAgents: RegistryAgent[] = [];\n\n constructor(store?: AgentStore) {\n this.store = store ?? new AgentStore();\n }\n\n load(): void {\n this.store.load();\n this.loadRegistryFromCacheOrSnapshot();\n }\n\n // --- Registry ---\n\n async fetchRegistry(): Promise<void> {\n try {\n log.info(\"Fetching agent registry from CDN...\");\n const response = await fetch(REGISTRY_URL);\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n const data = await response.json() as { agents: RegistryAgent[] };\n this.registryAgents = data.agents ?? [];\n\n const cache: RegistryCache = {\n fetchedAt: new Date().toISOString(),\n ttlHours: DEFAULT_TTL_HOURS,\n data,\n };\n fs.mkdirSync(path.dirname(CACHE_PATH), { recursive: true });\n fs.writeFileSync(CACHE_PATH, JSON.stringify(cache, null, 2));\n log.info({ count: this.registryAgents.length }, \"Registry updated\");\n } catch (err) {\n log.warn({ err }, \"Failed to fetch registry, using cached data\");\n }\n }\n\n async refreshRegistryIfStale(): Promise<void> {\n if (this.isCacheStale()) {\n await this.fetchRegistry();\n }\n }\n\n getRegistryAgents(): RegistryAgent[] {\n return this.registryAgents;\n }\n\n getRegistryAgent(registryId: string): RegistryAgent | undefined {\n return this.registryAgents.find((a) => a.id === registryId);\n }\n\n findRegistryAgent(keyOrId: string): RegistryAgent | undefined {\n const byId = this.registryAgents.find((a) => a.id === keyOrId);\n if (byId) return byId;\n return this.registryAgents.find((a) => getAgentAlias(a.id) === keyOrId);\n }\n\n // --- Installed ---\n\n getInstalled(): InstalledAgent[] {\n return Object.values(this.store.getInstalled());\n }\n\n getInstalledEntries(): Record<string, InstalledAgent> {\n return this.store.getInstalled();\n }\n\n getInstalledAgent(key: string): InstalledAgent | undefined {\n return this.store.getAgent(key);\n }\n\n // --- Discovery ---\n\n getAvailable(): AgentListItem[] {\n const installed = this.store.getInstalled();\n const items: AgentListItem[] = [];\n const seenKeys = new Set<string>();\n\n for (const [key, agent] of Object.entries(installed)) {\n seenKeys.add(key);\n const availability = agent.registryId\n ? checkDependencies(agent.registryId)\n : { available: true };\n const registryEntry = agent.registryId\n ? this.registryAgents.find((a) => a.id === agent.registryId)\n : undefined;\n items.push({\n key,\n registryId: agent.registryId ?? key,\n name: agent.name,\n version: agent.version,\n description: registryEntry?.description,\n distribution: agent.distribution,\n installed: true,\n available: availability.available,\n missingDeps: availability.missing?.map((m) => m.label),\n });\n }\n\n for (const agent of this.registryAgents) {\n const alias = getAgentAlias(agent.id);\n if (seenKeys.has(alias)) continue;\n seenKeys.add(alias);\n\n const dist = resolveDistribution(agent);\n const availability = checkDependencies(agent.id);\n\n items.push({\n key: alias,\n registryId: agent.id,\n name: agent.name,\n version: agent.version,\n description: agent.description,\n distribution: dist?.type ?? \"binary\",\n installed: false,\n available: dist !== null && availability.available,\n missingDeps: availability.missing?.map((m) => m.label),\n });\n }\n\n return items;\n }\n\n checkAvailability(keyOrId: string): AvailabilityResult {\n const agent = this.findRegistryAgent(keyOrId);\n if (!agent) return { available: false, reason: \"Not found in the agent registry.\" };\n\n const dist = resolveDistribution(agent);\n if (!dist) {\n return { available: false, reason: `Not available for your system. Check ${agent.website ?? agent.repository ?? \"their website\"} for other options.` };\n }\n\n return checkDependencies(agent.id);\n }\n\n // --- Install/Uninstall ---\n\n async install(keyOrId: string, progress?: InstallProgress, force?: boolean): Promise<InstallResult> {\n const agent = this.findRegistryAgent(keyOrId);\n if (!agent) {\n const msg = `\"${keyOrId}\" was not found in the agent registry. Run \"openacp agents\" to see what's available.`;\n await progress?.onError(msg);\n return { ok: false, agentKey: keyOrId, error: msg };\n }\n\n const agentKey = getAgentAlias(agent.id);\n if (this.store.hasAgent(agentKey) && !force) {\n const existing = this.store.getAgent(agentKey)!;\n const msg = `${agent.name} is already installed (v${existing.version}). Use --force to reinstall.`;\n await progress?.onError(msg);\n return { ok: false, agentKey, error: msg };\n }\n\n return installAgent(agent, this.store, progress);\n }\n\n async uninstall(key: string): Promise<{ ok: boolean; error?: string }> {\n if (!this.store.hasAgent(key)) {\n return { ok: false, error: `\"${key}\" is not installed.` };\n }\n await uninstallAgent(key, this.store);\n return { ok: true };\n }\n\n // --- Resolution (for AgentManager) ---\n\n resolve(key: string): AgentDefinition | undefined {\n const agent = this.store.getAgent(key);\n if (!agent) return undefined;\n return {\n name: key,\n command: agent.command,\n args: agent.args,\n workingDirectory: agent.workingDirectory,\n env: agent.env,\n };\n }\n\n // --- Internal ---\n\n private isCacheStale(): boolean {\n if (!fs.existsSync(CACHE_PATH)) return true;\n try {\n const raw = JSON.parse(fs.readFileSync(CACHE_PATH, \"utf-8\") as string) as RegistryCache;\n const fetchedAt = new Date(raw.fetchedAt).getTime();\n const ttlMs = (raw.ttlHours ?? DEFAULT_TTL_HOURS) * 60 * 60 * 1000;\n return Date.now() - fetchedAt > ttlMs;\n } catch {\n return true;\n }\n }\n\n private loadRegistryFromCacheOrSnapshot(): void {\n // Try cache first\n if (fs.existsSync(CACHE_PATH)) {\n try {\n const raw = JSON.parse(fs.readFileSync(CACHE_PATH, \"utf-8\") as string) as RegistryCache;\n if (raw.data?.agents) {\n this.registryAgents = raw.data.agents;\n log.debug({ count: this.registryAgents.length }, \"Loaded registry from cache\");\n return;\n }\n } catch {\n log.warn(\"Failed to load registry cache\");\n }\n }\n\n // Fallback: bundled snapshot\n try {\n // Try multiple paths for tsc and tsup builds\n const candidates = [\n path.join(import.meta.dirname, \"data\", \"registry-snapshot.json\"),\n path.join(import.meta.dirname, \"..\", \"data\", \"registry-snapshot.json\"),\n path.join(import.meta.dirname, \"..\", \"..\", \"data\", \"registry-snapshot.json\"),\n ];\n\n for (const candidate of candidates) {\n if (fs.existsSync(candidate)) {\n const raw = JSON.parse(fs.readFileSync(candidate, \"utf-8\") as string);\n this.registryAgents = raw.agents ?? [];\n log.debug({ count: this.registryAgents.length }, \"Loaded registry from bundled snapshot\");\n return;\n }\n }\n\n log.warn(\"No registry data available (no cache, no snapshot)\");\n } catch {\n log.warn(\"Failed to load bundled registry snapshot\");\n }\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport { createChildLogger } from \"./log.js\";\nimport type { InstalledAgent, RegistryAgent, InstallProgress, InstallResult } from \"./types.js\";\nimport { getAgentAlias, checkDependencies, checkRuntimeAvailable } from \"./agent-dependencies.js\";\nimport { AgentStore } from \"./agent-store.js\";\n\nconst log = createChildLogger({ module: \"agent-installer\" });\n\nconst AGENTS_DIR = path.join(os.homedir(), \".openacp\", \"agents\");\n\nconst ARCH_MAP: Record<string, string> = {\n arm64: \"aarch64\",\n x64: \"x86_64\",\n};\n\nconst PLATFORM_MAP: Record<string, string> = {\n darwin: \"darwin\",\n linux: \"linux\",\n win32: \"windows\",\n};\n\nexport function getPlatformKey(): string {\n const platform = PLATFORM_MAP[process.platform] ?? process.platform;\n const arch = ARCH_MAP[process.arch] ?? process.arch;\n return `${platform}-${arch}`;\n}\n\nexport type ResolvedDistribution =\n | { type: \"npx\"; package: string; args: string[]; env?: Record<string, string> }\n | { type: \"uvx\"; package: string; args: string[]; env?: Record<string, string> }\n | { type: \"binary\"; archive: string; cmd: string; args: string[]; env?: Record<string, string> };\n\nexport function resolveDistribution(agent: RegistryAgent): ResolvedDistribution | null {\n const dist = agent.distribution;\n\n if (dist.npx) {\n return { type: \"npx\", package: dist.npx.package, args: dist.npx.args ?? [], env: dist.npx.env };\n }\n if (dist.uvx) {\n return { type: \"uvx\", package: dist.uvx.package, args: dist.uvx.args ?? [], env: dist.uvx.env };\n }\n if (dist.binary) {\n const platformKey = getPlatformKey();\n const target = dist.binary[platformKey];\n if (!target) return null;\n return { type: \"binary\", archive: target.archive, cmd: target.cmd, args: target.args ?? [], env: target.env };\n }\n return null;\n}\n\nexport function buildInstalledAgent(\n registryId: string,\n name: string,\n version: string,\n dist: ResolvedDistribution,\n binaryPath?: string,\n): InstalledAgent {\n if (dist.type === \"npx\") {\n return {\n registryId, name, version, distribution: \"npx\",\n command: \"npx\", args: [dist.package, ...dist.args],\n env: dist.env ?? {}, installedAt: new Date().toISOString(), binaryPath: null,\n };\n }\n if (dist.type === \"uvx\") {\n return {\n registryId, name, version, distribution: \"uvx\",\n command: \"uvx\", args: [dist.package, ...dist.args],\n env: dist.env ?? {}, installedAt: new Date().toISOString(), binaryPath: null,\n };\n }\n // binary\n const absCmd = path.resolve(binaryPath!, dist.cmd);\n return {\n registryId, name, version, distribution: \"binary\",\n command: absCmd, args: dist.args,\n env: dist.env ?? {}, installedAt: new Date().toISOString(), binaryPath: binaryPath!,\n };\n}\n\nexport async function installAgent(\n agent: RegistryAgent,\n store: AgentStore,\n progress?: InstallProgress,\n): Promise<InstallResult> {\n const agentKey = getAgentAlias(agent.id);\n await progress?.onStart(agent.id, agent.name);\n\n // 1. Check dependencies\n await progress?.onStep(\"Checking requirements...\");\n const depResult = checkDependencies(agent.id);\n if (!depResult.available) {\n const hints = depResult.missing!.map((m) => ` ${m.label}: ${m.installHint}`).join(\"\\n\");\n const msg = `${agent.name} needs some tools installed first:\\n${hints}`;\n await progress?.onError(msg);\n return { ok: false, agentKey, error: msg };\n }\n\n // 2. Resolve distribution\n const dist = resolveDistribution(agent);\n if (!dist) {\n const platformKey = getPlatformKey();\n const msg = `${agent.name} is not available for your system (${platformKey}). Check their website for other install options.`;\n await progress?.onError(msg);\n return { ok: false, agentKey, error: msg };\n }\n\n // 3. Check runtime\n if (dist.type === \"uvx\" && !checkRuntimeAvailable(\"uvx\")) {\n const msg = `${agent.name} requires Python's uvx tool.\\nInstall it with: pip install uv`;\n await progress?.onError(msg, \"pip install uv\");\n return { ok: false, agentKey, error: msg, hint: \"pip install uv\" };\n }\n\n // 4. Install based on type\n let binaryPath: string | undefined;\n\n if (dist.type === \"binary\") {\n try {\n binaryPath = await downloadAndExtract(agent.id, dist.archive, progress);\n } catch (err) {\n const msg = `Failed to download ${agent.name}. Please try again or install manually.`;\n await progress?.onError(msg);\n return { ok: false, agentKey, error: msg };\n }\n } else {\n await progress?.onStep(\"Setting up... (will download on first use)\");\n }\n\n // 5. Save to store\n const installed = buildInstalledAgent(agent.id, agent.name, agent.version, dist, binaryPath);\n store.addAgent(agentKey, installed);\n\n await progress?.onSuccess(agent.name);\n return { ok: true, agentKey };\n}\n\nasync function downloadAndExtract(\n agentId: string,\n archiveUrl: string,\n progress?: InstallProgress,\n): Promise<string> {\n const destDir = path.join(AGENTS_DIR, agentId);\n fs.mkdirSync(destDir, { recursive: true });\n\n await progress?.onStep(\"Downloading...\");\n log.info({ agentId, url: archiveUrl }, \"Downloading agent binary\");\n\n const response = await fetch(archiveUrl);\n if (!response.ok) {\n throw new Error(`Download failed: ${response.status} ${response.statusText}`);\n }\n\n const contentLength = Number(response.headers.get(\"content-length\") || 0);\n const buffer = await readResponseWithProgress(response, contentLength, progress);\n\n await progress?.onStep(\"Extracting...\");\n\n if (archiveUrl.endsWith(\".zip\")) {\n await extractZip(buffer, destDir);\n } else {\n await extractTarGz(buffer, destDir);\n }\n\n await progress?.onStep(\"Ready!\");\n return destDir;\n}\n\nasync function readResponseWithProgress(\n response: Response,\n contentLength: number,\n progress?: InstallProgress,\n): Promise<Buffer> {\n if (!response.body || contentLength === 0) {\n const arrayBuffer = await response.arrayBuffer();\n return Buffer.from(arrayBuffer);\n }\n\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let received = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n received += value.length;\n if (contentLength > 0) {\n await progress?.onDownloadProgress(Math.round((received / contentLength) * 100));\n }\n }\n\n return Buffer.concat(chunks);\n}\n\nfunction validateExtractedPaths(destDir: string): void {\n const realDest = fs.realpathSync(destDir);\n const entries = fs.readdirSync(destDir, { recursive: true, withFileTypes: true });\n for (const entry of entries) {\n const parentPath = (entry as unknown as { parentPath?: string; path?: string }).parentPath ?? (entry as unknown as { path: string }).path;\n const fullPath = path.join(parentPath, entry.name);\n let realPath: string;\n try {\n realPath = fs.realpathSync(fullPath);\n } catch {\n // Broken symlink — check where it points\n const linkTarget = fs.readlinkSync(fullPath);\n realPath = path.resolve(path.dirname(fullPath), linkTarget);\n }\n if (!realPath.startsWith(realDest + path.sep) && realPath !== realDest) {\n fs.rmSync(destDir, { recursive: true, force: true });\n throw new Error(`Archive contains unsafe path: ${entry.name}`);\n }\n }\n}\n\nasync function extractTarGz(buffer: Buffer, destDir: string): Promise<void> {\n const { execFileSync } = await import(\"node:child_process\");\n const tmpFile = path.join(destDir, \"_archive.tar.gz\");\n fs.writeFileSync(tmpFile, buffer);\n try {\n execFileSync(\"tar\", [\"xzf\", tmpFile, \"-C\", destDir], { stdio: \"pipe\" });\n } finally {\n fs.unlinkSync(tmpFile);\n }\n validateExtractedPaths(destDir);\n}\n\nasync function extractZip(buffer: Buffer, destDir: string): Promise<void> {\n const { execFileSync } = await import(\"node:child_process\");\n const tmpFile = path.join(destDir, \"_archive.zip\");\n fs.writeFileSync(tmpFile, buffer);\n try {\n execFileSync(\"unzip\", [\"-o\", tmpFile, \"-d\", destDir], { stdio: \"pipe\" });\n } finally {\n fs.unlinkSync(tmpFile);\n }\n validateExtractedPaths(destDir);\n}\n\nexport async function uninstallAgent(\n agentKey: string,\n store: AgentStore,\n): Promise<void> {\n const agent = store.getAgent(agentKey);\n if (!agent) return;\n\n if (agent.binaryPath && fs.existsSync(agent.binaryPath)) {\n fs.rmSync(agent.binaryPath, { recursive: true, force: true });\n log.info({ agentKey, binaryPath: agent.binaryPath }, \"Deleted agent binary\");\n }\n\n store.removeAgent(agentKey);\n}\n"],"mappings":"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","names":["fs","path","os","log"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/adapters/telegram/commands/menu.ts"],"sourcesContent":["import type { Context } from \"grammy\";\nimport { InlineKeyboard } from \"grammy\";\nimport type { AgentCommand } from \"../../../core/index.js\";\nimport type { CommandsAssistantContext } from \"../types.js\";\n\nexport function buildMenuKeyboard(): InlineKeyboard {\n return new InlineKeyboard()\n .text(\"🆕 New Session\", \"m:new\")\n .text(\"📋 Sessions\", \"m:topics\")\n .row()\n .text(\"📊 Status\", \"m:status\")\n .text(\"🤖 Agents\", \"m:agents\")\n .row()\n .text(\"⚙️ Settings\", \"m:settings\")\n .text(\"🔗 Integrate\", \"m:integrate\")\n .row()\n .text(\"🔄 Restart\", \"m:restart\")\n .text(\"⬆️ Update\", \"m:update\")\n .row()\n .text(\"❓ Help\", \"m:help\")\n .text(\"🩺 Doctor\", \"m:doctor\");\n}\n\nexport async function handleMenu(ctx: Context): Promise<void> {\n await ctx.reply(`<b>OpenACP Menu</b>\\nChoose an action:`, {\n parse_mode: \"HTML\",\n reply_markup: buildMenuKeyboard(),\n });\n}\n\nexport async function handleHelp(ctx: Context): Promise<void> {\n await ctx.reply(\n `📖 <b>OpenACP Help</b>\\n\\n` +\n `🚀 <b>Getting Started</b>\\n` +\n `Tap 🆕 New Session to start coding with AI.\\n` +\n `Each session gets its own topic — chat there to work with the agent.\\n\\n` +\n `💡 <b>Common Tasks</b>\\n` +\n `/new [agent] [workspace] — Create new session\\n` +\n `/cancel — Cancel session (in session topic)\\n` +\n `/status — Show session or system status\\n` +\n `/sessions — List all sessions\\n` +\n `/agents — List available agents\\n\\n` +\n `⚙️ <b>System</b>\\n` +\n `/restart — Restart OpenACP\\n` +\n `/update — Update to latest version\\n` +\n `/integrate — Manage agent integrations\\n` +\n `/menu — Show action menu\\n\\n` +\n `🔒 <b>Session Options</b>\\n` +\n `/enable_dangerous — Auto-approve permissions\\n` +\n `/disable_dangerous — Restore permission prompts\\n` +\n `/handoff — Continue session in terminal\\n` +\n `/clear — Clear assistant history\\n\\n` +\n `💬 Need help? Just ask me in this topic!`,\n { parse_mode: \"HTML\" },\n );\n}\n\nexport async function handleClear(ctx: Context, assistant?: CommandsAssistantContext): Promise<void> {\n if (!assistant) {\n await ctx.reply(\"⚠️ Assistant is not available.\", { parse_mode: \"HTML\" });\n return;\n }\n\n const threadId = ctx.message?.message_thread_id;\n if (threadId !== assistant.topicId) {\n await ctx.reply(\"ℹ️ /clear only works in the Assistant topic.\", { parse_mode: \"HTML\" });\n return;\n }\n\n await ctx.reply(\"🔄 Clearing assistant history...\", { parse_mode: \"HTML\" });\n\n try {\n await assistant.respawn();\n await ctx.reply(\"✅ Assistant history cleared.\", { parse_mode: \"HTML\" });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await ctx.reply(`❌ Failed to clear: <code>${message}</code>`, { parse_mode: \"HTML\" });\n }\n}\n\nconst TELEGRAM_MSG_LIMIT = 4096;\n\n/**\n * Build plain-text skill command messages. Each command is on its own line\n * wrapped in <code> for tap-to-copy. If the list exceeds Telegram's message\n * limit, it is split into multiple messages (cut at line boundaries).\n */\nexport function buildSkillMessages(commands: AgentCommand[]): string[] {\n const sorted = [...commands].sort((a, b) => a.name.localeCompare(b.name));\n const header = \"🛠 <b>Available Skills</b>\\n\";\n const lines = sorted.map((c) => `<code>/${c.name}</code>`);\n\n const messages: string[] = [];\n let current = header;\n\n for (const line of lines) {\n const candidate = current + \"\\n\" + line;\n if (candidate.length > TELEGRAM_MSG_LIMIT) {\n messages.push(current);\n current = line;\n } else {\n current = candidate;\n }\n }\n if (current) messages.push(current);\n return messages;\n}\n"],"mappings":";AACA,SAAS,sBAAsB;AAIxB,SAAS,oBAAoC;AAClD,SAAO,IAAI,eAAe,EACvB,KAAK,yBAAkB,OAAO,EAC9B,KAAK,sBAAe,UAAU,EAC9B,IAAI,EACJ,KAAK,oBAAa,UAAU,EAC5B,KAAK,oBAAa,UAAU,EAC5B,IAAI,EACJ,KAAK,yBAAe,YAAY,EAChC,KAAK,uBAAgB,aAAa,EAClC,IAAI,EACJ,KAAK,qBAAc,WAAW,EAC9B,KAAK,uBAAa,UAAU,EAC5B,IAAI,EACJ,KAAK,eAAU,QAAQ,EACvB,KAAK,oBAAa,UAAU;AACjC;AAEA,eAAsB,WAAW,KAA6B;AAC5D,QAAM,IAAI,MAAM;AAAA,oBAA0C;AAAA,IACxD,YAAY;AAAA,IACZ,cAAc,kBAAkB;AAAA,EAClC,CAAC;AACH;AAEA,eAAsB,WAAW,KAA6B;AAC5D,QAAM,IAAI;AAAA,IACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAqBA,EAAE,YAAY,OAAO;AAAA,EACvB;AACF;AAEA,eAAsB,YAAY,KAAc,WAAqD;AACnG,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,4CAAkC,EAAE,YAAY,OAAO,CAAC;AACxE;AAAA,EACF;AAEA,QAAM,WAAW,IAAI,SAAS;AAC9B,MAAI,aAAa,UAAU,SAAS;AAClC,UAAM,IAAI,MAAM,0DAAgD,EAAE,YAAY,OAAO,CAAC;AACtF;AAAA,EACF;AAEA,QAAM,IAAI,MAAM,2CAAoC,EAAE,YAAY,OAAO,CAAC;AAE1E,MAAI;AACF,UAAM,UAAU,QAAQ;AACxB,UAAM,IAAI,MAAM,qCAAgC,EAAE,YAAY,OAAO,CAAC;AAAA,EACxE,SAAS,KAAK;AACZ,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,UAAM,IAAI,MAAM,iCAA4B,OAAO,WAAW,EAAE,YAAY,OAAO,CAAC;AAAA,EACtF;AACF;AAEA,IAAM,qBAAqB;AAOpB,SAAS,mBAAmB,UAAoC;AACrE,QAAM,SAAS,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AACxE,QAAM,SAAS;AACf,QAAM,QAAQ,OAAO,IAAI,CAAC,MAAM,UAAU,EAAE,IAAI,SAAS;AAEzD,QAAM,WAAqB,CAAC;AAC5B,MAAI,UAAU;AAEd,aAAW,QAAQ,OAAO;AACxB,UAAM,YAAY,UAAU,OAAO;AACnC,QAAI,UAAU,SAAS,oBAAoB;AACzC,eAAS,KAAK,OAAO;AACrB,gBAAU;AAAA,IACZ,OAAO;AACL,gBAAU;AAAA,IACZ;AAAA,EACF;AACA,MAAI,QAAS,UAAS,KAAK,OAAO;AAClC,SAAO;AACT;","names":[]}
|
package/dist/chunk-XJJ7LPXP.js
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
// src/core/agent-dependencies.ts
|
|
2
|
-
import { execFileSync } from "child_process";
|
|
3
|
-
import * as fs from "fs";
|
|
4
|
-
import * as path from "path";
|
|
5
|
-
var AGENT_DEPENDENCIES = {
|
|
6
|
-
"claude-acp": [
|
|
7
|
-
{
|
|
8
|
-
command: "claude",
|
|
9
|
-
label: "Claude CLI",
|
|
10
|
-
installHint: "npm install -g @anthropic-ai/claude-code"
|
|
11
|
-
}
|
|
12
|
-
],
|
|
13
|
-
"codex-acp": [
|
|
14
|
-
{
|
|
15
|
-
command: "codex",
|
|
16
|
-
label: "Codex CLI",
|
|
17
|
-
installHint: "npm install -g @openai/codex"
|
|
18
|
-
}
|
|
19
|
-
]
|
|
20
|
-
};
|
|
21
|
-
var AGENT_CAPABILITIES = {
|
|
22
|
-
claude: {
|
|
23
|
-
supportsResume: true,
|
|
24
|
-
resumeCommand: (sid) => `claude --resume ${sid}`
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
var REGISTRY_AGENT_ALIASES = {
|
|
28
|
-
"claude-acp": "claude",
|
|
29
|
-
"codex-acp": "codex",
|
|
30
|
-
"gemini": "gemini",
|
|
31
|
-
"cursor": "cursor",
|
|
32
|
-
"github-copilot-cli": "copilot",
|
|
33
|
-
"cline": "cline",
|
|
34
|
-
"goose": "goose",
|
|
35
|
-
"kilo": "kilo",
|
|
36
|
-
"qwen-code": "qwen"
|
|
37
|
-
};
|
|
38
|
-
function getAgentAlias(registryId) {
|
|
39
|
-
return REGISTRY_AGENT_ALIASES[registryId] ?? registryId;
|
|
40
|
-
}
|
|
41
|
-
function getAgentDependencies(registryId) {
|
|
42
|
-
return AGENT_DEPENDENCIES[registryId] ?? [];
|
|
43
|
-
}
|
|
44
|
-
function getAgentCapabilities(agentName) {
|
|
45
|
-
return AGENT_CAPABILITIES[agentName] ?? { supportsResume: false };
|
|
46
|
-
}
|
|
47
|
-
function commandExists(cmd) {
|
|
48
|
-
try {
|
|
49
|
-
execFileSync("which", [cmd], { stdio: "pipe" });
|
|
50
|
-
return true;
|
|
51
|
-
} catch {
|
|
52
|
-
}
|
|
53
|
-
let dir = process.cwd();
|
|
54
|
-
while (true) {
|
|
55
|
-
const binPath = path.join(dir, "node_modules", ".bin", cmd);
|
|
56
|
-
if (fs.existsSync(binPath)) return true;
|
|
57
|
-
const parent = path.dirname(dir);
|
|
58
|
-
if (parent === dir) break;
|
|
59
|
-
dir = parent;
|
|
60
|
-
}
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
function checkDependencies(registryId) {
|
|
64
|
-
const deps = getAgentDependencies(registryId);
|
|
65
|
-
if (deps.length === 0) return { available: true };
|
|
66
|
-
const missing = deps.filter((d) => !commandExists(d.command));
|
|
67
|
-
if (missing.length === 0) return { available: true };
|
|
68
|
-
return {
|
|
69
|
-
available: false,
|
|
70
|
-
reason: `Requires: ${missing.map((m) => m.label).join(", ")}`,
|
|
71
|
-
missing: missing.map((m) => ({ label: m.label, installHint: m.installHint }))
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
function checkRuntimeAvailable(runtime) {
|
|
75
|
-
return commandExists(runtime);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export {
|
|
79
|
-
getAgentAlias,
|
|
80
|
-
getAgentCapabilities,
|
|
81
|
-
commandExists,
|
|
82
|
-
checkDependencies,
|
|
83
|
-
checkRuntimeAvailable
|
|
84
|
-
};
|
|
85
|
-
//# sourceMappingURL=chunk-XJJ7LPXP.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/agent-dependencies.ts"],"sourcesContent":["import { execFileSync } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { AvailabilityResult } from \"./types.js\";\n\nexport interface AgentDependency {\n command: string;\n label: string;\n installHint: string;\n}\n\nexport interface AgentCapability {\n supportsResume: boolean;\n resumeCommand?: (sessionId: string) => string;\n}\n\nconst AGENT_DEPENDENCIES: Record<string, AgentDependency[]> = {\n \"claude-acp\": [\n {\n command: \"claude\",\n label: \"Claude CLI\",\n installHint: \"npm install -g @anthropic-ai/claude-code\",\n },\n ],\n \"codex-acp\": [\n {\n command: \"codex\",\n label: \"Codex CLI\",\n installHint: \"npm install -g @openai/codex\",\n },\n ],\n};\n\nconst AGENT_CAPABILITIES: Record<string, AgentCapability> = {\n claude: {\n supportsResume: true,\n resumeCommand: (sid) => `claude --resume ${sid}`,\n },\n};\n\nexport const REGISTRY_AGENT_ALIASES: Record<string, string> = {\n \"claude-acp\": \"claude\",\n \"codex-acp\": \"codex\",\n \"gemini\": \"gemini\",\n \"cursor\": \"cursor\",\n \"github-copilot-cli\": \"copilot\",\n \"cline\": \"cline\",\n \"goose\": \"goose\",\n \"kilo\": \"kilo\",\n \"qwen-code\": \"qwen\",\n};\n\nexport function getAgentAlias(registryId: string): string {\n return REGISTRY_AGENT_ALIASES[registryId] ?? registryId;\n}\n\nexport function getAgentDependencies(registryId: string): AgentDependency[] {\n return AGENT_DEPENDENCIES[registryId] ?? [];\n}\n\nexport function getAgentCapabilities(agentName: string): AgentCapability {\n return AGENT_CAPABILITIES[agentName] ?? { supportsResume: false };\n}\n\nexport function commandExists(cmd: string): boolean {\n try {\n execFileSync(\"which\", [cmd], { stdio: \"pipe\" });\n return true;\n } catch {\n // not in PATH\n }\n // Check node_modules/.bin (walks up from cwd)\n let dir = process.cwd();\n while (true) {\n const binPath = path.join(dir, \"node_modules\", \".bin\", cmd);\n if (fs.existsSync(binPath)) return true;\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return false;\n}\n\nexport function checkDependencies(registryId: string): AvailabilityResult {\n const deps = getAgentDependencies(registryId);\n if (deps.length === 0) return { available: true };\n\n const missing = deps.filter((d) => !commandExists(d.command));\n if (missing.length === 0) return { available: true };\n\n return {\n available: false,\n reason: `Requires: ${missing.map((m) => m.label).join(\", \")}`,\n missing: missing.map((m) => ({ label: m.label, installHint: m.installHint })),\n };\n}\n\nexport function checkRuntimeAvailable(runtime: \"npx\" | \"uvx\"): boolean {\n return commandExists(runtime);\n}\n"],"mappings":";AAAA,SAAS,oBAAoB;AAC7B,YAAY,QAAQ;AACpB,YAAY,UAAU;AActB,IAAM,qBAAwD;AAAA,EAC5D,cAAc;AAAA,IACZ;AAAA,MACE,SAAS;AAAA,MACT,OAAO;AAAA,MACP,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,aAAa;AAAA,IACX;AAAA,MACE,SAAS;AAAA,MACT,OAAO;AAAA,MACP,aAAa;AAAA,IACf;AAAA,EACF;AACF;AAEA,IAAM,qBAAsD;AAAA,EAC1D,QAAQ;AAAA,IACN,gBAAgB;AAAA,IAChB,eAAe,CAAC,QAAQ,mBAAmB,GAAG;AAAA,EAChD;AACF;AAEO,IAAM,yBAAiD;AAAA,EAC5D,cAAc;AAAA,EACd,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,sBAAsB;AAAA,EACtB,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,aAAa;AACf;AAEO,SAAS,cAAc,YAA4B;AACxD,SAAO,uBAAuB,UAAU,KAAK;AAC/C;AAEO,SAAS,qBAAqB,YAAuC;AAC1E,SAAO,mBAAmB,UAAU,KAAK,CAAC;AAC5C;AAEO,SAAS,qBAAqB,WAAoC;AACvE,SAAO,mBAAmB,SAAS,KAAK,EAAE,gBAAgB,MAAM;AAClE;AAEO,SAAS,cAAc,KAAsB;AAClD,MAAI;AACF,iBAAa,SAAS,CAAC,GAAG,GAAG,EAAE,OAAO,OAAO,CAAC;AAC9C,WAAO;AAAA,EACT,QAAQ;AAAA,EAER;AAEA,MAAI,MAAM,QAAQ,IAAI;AACtB,SAAO,MAAM;AACX,UAAM,UAAe,UAAK,KAAK,gBAAgB,QAAQ,GAAG;AAC1D,QAAO,cAAW,OAAO,EAAG,QAAO;AACnC,UAAM,SAAc,aAAQ,GAAG;AAC/B,QAAI,WAAW,IAAK;AACpB,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAEO,SAAS,kBAAkB,YAAwC;AACxE,QAAM,OAAO,qBAAqB,UAAU;AAC5C,MAAI,KAAK,WAAW,EAAG,QAAO,EAAE,WAAW,KAAK;AAEhD,QAAM,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC;AAC5D,MAAI,QAAQ,WAAW,EAAG,QAAO,EAAE,WAAW,KAAK;AAEnD,SAAO;AAAA,IACL,WAAW;AAAA,IACX,QAAQ,aAAa,QAAQ,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;AAAA,IAC3D,SAAS,QAAQ,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,aAAa,EAAE,YAAY,EAAE;AAAA,EAC9E;AACF;AAEO,SAAS,sBAAsB,SAAiC;AACrE,SAAO,cAAc,OAAO;AAC9B;","names":[]}
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
// src/cli/integrate.ts
|
|
2
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, chmodSync } from "fs";
|
|
3
|
-
import { join } from "path";
|
|
4
|
-
import { homedir } from "os";
|
|
5
|
-
var CLAUDE_DIR = join(homedir(), ".claude");
|
|
6
|
-
var HOOKS_DIR = join(CLAUDE_DIR, "hooks");
|
|
7
|
-
var COMMANDS_DIR = join(CLAUDE_DIR, "commands");
|
|
8
|
-
var SETTINGS_FILE = join(CLAUDE_DIR, "settings.json");
|
|
9
|
-
var INJECT_HOOK_FILE = join(HOOKS_DIR, "openacp-inject-session.sh");
|
|
10
|
-
var HANDOFF_SCRIPT_FILE = join(HOOKS_DIR, "openacp-handoff.sh");
|
|
11
|
-
var HANDOFF_COMMAND_FILE = join(COMMANDS_DIR, "openacp:handoff.md");
|
|
12
|
-
var INJECT_HOOK_CONTENT = `#!/bin/bash
|
|
13
|
-
INPUT=$(cat)
|
|
14
|
-
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id')
|
|
15
|
-
CWD=$(echo "$INPUT" | jq -r '.cwd')
|
|
16
|
-
|
|
17
|
-
echo "CLAUDE_SESSION_ID: $SESSION_ID"
|
|
18
|
-
echo "CLAUDE_WORKING_DIR: $CWD"
|
|
19
|
-
|
|
20
|
-
exit 0
|
|
21
|
-
`;
|
|
22
|
-
var HANDOFF_SCRIPT_CONTENT = `#!/bin/bash
|
|
23
|
-
SESSION_ID=$1
|
|
24
|
-
CWD=$2
|
|
25
|
-
|
|
26
|
-
if [ -z "$SESSION_ID" ]; then
|
|
27
|
-
echo "Usage: openacp-handoff.sh <session_id> [cwd]"
|
|
28
|
-
exit 1
|
|
29
|
-
fi
|
|
30
|
-
|
|
31
|
-
openacp adopt claude "$SESSION_ID" \${CWD:+--cwd "$CWD"}
|
|
32
|
-
`;
|
|
33
|
-
var HANDOFF_COMMAND_CONTENT = `---
|
|
34
|
-
description: Transfer current session to OpenACP (Telegram)
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
Look at the context injected at the start of this message to find
|
|
38
|
-
CLAUDE_SESSION_ID and CLAUDE_WORKING_DIR, then run:
|
|
39
|
-
|
|
40
|
-
bash ~/.claude/hooks/openacp-handoff.sh <CLAUDE_SESSION_ID> <CLAUDE_WORKING_DIR>
|
|
41
|
-
`;
|
|
42
|
-
var HOOK_MARKER = "openacp-inject-session.sh";
|
|
43
|
-
function mergeClaudeSettings() {
|
|
44
|
-
let settings = {};
|
|
45
|
-
if (existsSync(SETTINGS_FILE)) {
|
|
46
|
-
const raw = readFileSync(SETTINGS_FILE, "utf-8");
|
|
47
|
-
writeFileSync(`${SETTINGS_FILE}.bak`, raw);
|
|
48
|
-
settings = JSON.parse(raw);
|
|
49
|
-
}
|
|
50
|
-
const hooks = settings.hooks ?? {};
|
|
51
|
-
settings.hooks = hooks;
|
|
52
|
-
const userPromptSubmit = hooks.UserPromptSubmit ?? [];
|
|
53
|
-
hooks.UserPromptSubmit = userPromptSubmit;
|
|
54
|
-
const alreadyInstalled = userPromptSubmit.some(
|
|
55
|
-
(group) => group.hooks?.some((h) => h.command?.includes(HOOK_MARKER))
|
|
56
|
-
);
|
|
57
|
-
if (!alreadyInstalled) {
|
|
58
|
-
userPromptSubmit.push({
|
|
59
|
-
hooks: [
|
|
60
|
-
{
|
|
61
|
-
type: "command",
|
|
62
|
-
command: INJECT_HOOK_FILE
|
|
63
|
-
}
|
|
64
|
-
]
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2) + "\n");
|
|
68
|
-
}
|
|
69
|
-
function removeClaudeSettings() {
|
|
70
|
-
if (!existsSync(SETTINGS_FILE)) return;
|
|
71
|
-
const raw = readFileSync(SETTINGS_FILE, "utf-8");
|
|
72
|
-
const settings = JSON.parse(raw);
|
|
73
|
-
const hooks = settings.hooks;
|
|
74
|
-
if (!hooks?.UserPromptSubmit) return;
|
|
75
|
-
hooks.UserPromptSubmit = hooks.UserPromptSubmit.filter(
|
|
76
|
-
(group) => !group.hooks?.some((h) => h.command?.includes("openacp-"))
|
|
77
|
-
);
|
|
78
|
-
if (hooks.UserPromptSubmit.length === 0) {
|
|
79
|
-
delete hooks.UserPromptSubmit;
|
|
80
|
-
}
|
|
81
|
-
writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2) + "\n");
|
|
82
|
-
}
|
|
83
|
-
var claudeHandoffItem = {
|
|
84
|
-
id: "handoff",
|
|
85
|
-
name: "Handoff",
|
|
86
|
-
description: "Transfer sessions between terminal and Telegram",
|
|
87
|
-
isInstalled() {
|
|
88
|
-
return existsSync(INJECT_HOOK_FILE) && existsSync(HANDOFF_SCRIPT_FILE) && existsSync(HANDOFF_COMMAND_FILE);
|
|
89
|
-
},
|
|
90
|
-
async install() {
|
|
91
|
-
const logs = [];
|
|
92
|
-
try {
|
|
93
|
-
mkdirSync(HOOKS_DIR, { recursive: true });
|
|
94
|
-
mkdirSync(COMMANDS_DIR, { recursive: true });
|
|
95
|
-
writeFileSync(INJECT_HOOK_FILE, INJECT_HOOK_CONTENT);
|
|
96
|
-
chmodSync(INJECT_HOOK_FILE, 493);
|
|
97
|
-
logs.push(`Created ${INJECT_HOOK_FILE}`);
|
|
98
|
-
writeFileSync(HANDOFF_SCRIPT_FILE, HANDOFF_SCRIPT_CONTENT);
|
|
99
|
-
chmodSync(HANDOFF_SCRIPT_FILE, 493);
|
|
100
|
-
logs.push(`Created ${HANDOFF_SCRIPT_FILE}`);
|
|
101
|
-
writeFileSync(HANDOFF_COMMAND_FILE, HANDOFF_COMMAND_CONTENT);
|
|
102
|
-
logs.push(`Created ${HANDOFF_COMMAND_FILE}`);
|
|
103
|
-
mergeClaudeSettings();
|
|
104
|
-
logs.push(`Updated ${SETTINGS_FILE}`);
|
|
105
|
-
return { success: true, logs };
|
|
106
|
-
} catch (err) {
|
|
107
|
-
logs.push(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
108
|
-
return { success: false, logs };
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
async uninstall() {
|
|
112
|
-
const logs = [];
|
|
113
|
-
try {
|
|
114
|
-
for (const file of [INJECT_HOOK_FILE, HANDOFF_SCRIPT_FILE, HANDOFF_COMMAND_FILE]) {
|
|
115
|
-
if (existsSync(file)) {
|
|
116
|
-
unlinkSync(file);
|
|
117
|
-
logs.push(`Removed ${file}`);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
removeClaudeSettings();
|
|
121
|
-
logs.push(`Updated ${SETTINGS_FILE}`);
|
|
122
|
-
return { success: true, logs };
|
|
123
|
-
} catch (err) {
|
|
124
|
-
logs.push(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
125
|
-
return { success: false, logs };
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
var claudeIntegration = {
|
|
130
|
-
items: [claudeHandoffItem]
|
|
131
|
-
};
|
|
132
|
-
var integrations = {
|
|
133
|
-
claude: claudeIntegration
|
|
134
|
-
};
|
|
135
|
-
function getIntegration(agentName) {
|
|
136
|
-
return integrations[agentName];
|
|
137
|
-
}
|
|
138
|
-
function listIntegrations() {
|
|
139
|
-
return Object.keys(integrations);
|
|
140
|
-
}
|
|
141
|
-
export {
|
|
142
|
-
getIntegration,
|
|
143
|
-
listIntegrations
|
|
144
|
-
};
|
|
145
|
-
//# sourceMappingURL=integrate-WUPLRJD3.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/integrate.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, chmodSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport interface IntegrationResult {\n success: boolean;\n logs: string[];\n}\n\nexport interface IntegrationItem {\n id: string;\n name: string;\n description: string;\n isInstalled(): boolean;\n install(): Promise<IntegrationResult>;\n uninstall(): Promise<IntegrationResult>;\n}\n\nexport interface AgentIntegration {\n items: IntegrationItem[];\n}\n\n// --- Claude integration ---\n\nconst CLAUDE_DIR = join(homedir(), \".claude\");\nconst HOOKS_DIR = join(CLAUDE_DIR, \"hooks\");\nconst COMMANDS_DIR = join(CLAUDE_DIR, \"commands\");\nconst SETTINGS_FILE = join(CLAUDE_DIR, \"settings.json\");\n\nconst INJECT_HOOK_FILE = join(HOOKS_DIR, \"openacp-inject-session.sh\");\nconst HANDOFF_SCRIPT_FILE = join(HOOKS_DIR, \"openacp-handoff.sh\");\nconst HANDOFF_COMMAND_FILE = join(COMMANDS_DIR, \"openacp:handoff.md\");\n\nconst INJECT_HOOK_CONTENT = `#!/bin/bash\nINPUT=$(cat)\nSESSION_ID=$(echo \"$INPUT\" | jq -r '.session_id')\nCWD=$(echo \"$INPUT\" | jq -r '.cwd')\n\necho \"CLAUDE_SESSION_ID: $SESSION_ID\"\necho \"CLAUDE_WORKING_DIR: $CWD\"\n\nexit 0\n`;\n\nconst HANDOFF_SCRIPT_CONTENT = `#!/bin/bash\nSESSION_ID=$1\nCWD=$2\n\nif [ -z \"$SESSION_ID\" ]; then\n echo \"Usage: openacp-handoff.sh <session_id> [cwd]\"\n exit 1\nfi\n\nopenacp adopt claude \"$SESSION_ID\" \\${CWD:+--cwd \"$CWD\"}\n`;\n\nconst HANDOFF_COMMAND_CONTENT = `---\ndescription: Transfer current session to OpenACP (Telegram)\n---\n\nLook at the context injected at the start of this message to find\nCLAUDE_SESSION_ID and CLAUDE_WORKING_DIR, then run:\n\nbash ~/.claude/hooks/openacp-handoff.sh <CLAUDE_SESSION_ID> <CLAUDE_WORKING_DIR>\n`;\n\nconst HOOK_MARKER = \"openacp-inject-session.sh\";\n\nfunction mergeClaudeSettings(): void {\n let settings: Record<string, unknown> = {};\n\n if (existsSync(SETTINGS_FILE)) {\n const raw = readFileSync(SETTINGS_FILE, \"utf-8\");\n writeFileSync(`${SETTINGS_FILE}.bak`, raw);\n settings = JSON.parse(raw);\n }\n\n const hooks = (settings.hooks ?? {}) as Record<string, unknown[]>;\n settings.hooks = hooks;\n\n const userPromptSubmit = (hooks.UserPromptSubmit ?? []) as Array<{ hooks?: Array<{ type?: string; command?: string }> }>;\n hooks.UserPromptSubmit = userPromptSubmit;\n\n const alreadyInstalled = userPromptSubmit.some((group) =>\n group.hooks?.some((h) => h.command?.includes(HOOK_MARKER)),\n );\n\n if (!alreadyInstalled) {\n userPromptSubmit.push({\n hooks: [\n {\n type: \"command\",\n command: INJECT_HOOK_FILE,\n },\n ],\n });\n }\n\n writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2) + \"\\n\");\n}\n\nfunction removeClaudeSettings(): void {\n if (!existsSync(SETTINGS_FILE)) return;\n\n const raw = readFileSync(SETTINGS_FILE, \"utf-8\");\n const settings = JSON.parse(raw);\n\n const hooks = settings.hooks as Record<string, unknown[]> | undefined;\n if (!hooks?.UserPromptSubmit) return;\n\n hooks.UserPromptSubmit = (hooks.UserPromptSubmit as Array<{ hooks?: Array<{ command?: string }> }>).filter(\n (group) => !group.hooks?.some((h) => h.command?.includes(\"openacp-\")),\n );\n\n if (hooks.UserPromptSubmit.length === 0) {\n delete hooks.UserPromptSubmit;\n }\n\n writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2) + \"\\n\");\n}\n\nconst claudeHandoffItem: IntegrationItem = {\n id: \"handoff\",\n name: \"Handoff\",\n description: \"Transfer sessions between terminal and Telegram\",\n\n isInstalled(): boolean {\n return (\n existsSync(INJECT_HOOK_FILE) &&\n existsSync(HANDOFF_SCRIPT_FILE) &&\n existsSync(HANDOFF_COMMAND_FILE)\n );\n },\n\n async install(): Promise<IntegrationResult> {\n const logs: string[] = [];\n try {\n mkdirSync(HOOKS_DIR, { recursive: true });\n mkdirSync(COMMANDS_DIR, { recursive: true });\n\n writeFileSync(INJECT_HOOK_FILE, INJECT_HOOK_CONTENT);\n chmodSync(INJECT_HOOK_FILE, 0o755);\n logs.push(`Created ${INJECT_HOOK_FILE}`);\n\n writeFileSync(HANDOFF_SCRIPT_FILE, HANDOFF_SCRIPT_CONTENT);\n chmodSync(HANDOFF_SCRIPT_FILE, 0o755);\n logs.push(`Created ${HANDOFF_SCRIPT_FILE}`);\n\n writeFileSync(HANDOFF_COMMAND_FILE, HANDOFF_COMMAND_CONTENT);\n logs.push(`Created ${HANDOFF_COMMAND_FILE}`);\n\n mergeClaudeSettings();\n logs.push(`Updated ${SETTINGS_FILE}`);\n\n return { success: true, logs };\n } catch (err) {\n logs.push(`Error: ${err instanceof Error ? err.message : String(err)}`);\n return { success: false, logs };\n }\n },\n\n async uninstall(): Promise<IntegrationResult> {\n const logs: string[] = [];\n try {\n for (const file of [INJECT_HOOK_FILE, HANDOFF_SCRIPT_FILE, HANDOFF_COMMAND_FILE]) {\n if (existsSync(file)) {\n unlinkSync(file);\n logs.push(`Removed ${file}`);\n }\n }\n\n removeClaudeSettings();\n logs.push(`Updated ${SETTINGS_FILE}`);\n\n return { success: true, logs };\n } catch (err) {\n logs.push(`Error: ${err instanceof Error ? err.message : String(err)}`);\n return { success: false, logs };\n }\n },\n};\n\nconst claudeIntegration: AgentIntegration = {\n items: [claudeHandoffItem],\n};\n\n// --- Registry ---\n\nconst integrations: Record<string, AgentIntegration> = {\n claude: claudeIntegration,\n};\n\nexport function getIntegration(agentName: string): AgentIntegration | undefined {\n return integrations[agentName];\n}\n\nexport function listIntegrations(): string[] {\n return Object.keys(integrations);\n}\n"],"mappings":"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","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|