@openacp/cli 2026.327.1 → 2026.327.3
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/{adapter-Z435XYBQ.js → adapter-LC2QSDAS.js} +4 -5
- package/dist/{adapter-PQGHVG4K.js → adapter-Y55NXX6I.js} +2 -2
- package/dist/{api-server-5VEESFOT.js → api-server-7G3ZUZRM.js} +2 -2
- package/dist/{api-server-2I7B3MXR.js → api-server-CAYNPUF2.js} +2 -2
- package/dist/{chunk-5YW56UJK.js → chunk-2YCW3QDV.js} +21 -5
- package/dist/chunk-2YCW3QDV.js.map +1 -0
- package/dist/{chunk-366FOUJG.js → chunk-36YQ44D7.js} +2 -2
- package/dist/{chunk-UB2QB6DE.js → chunk-3ASUU6WW.js} +2 -2
- package/dist/{chunk-ZPTM4NGK.js → chunk-4GMLGCF2.js} +2 -2
- package/dist/{chunk-CFM4GJ74.js → chunk-HUWOFP2H.js} +7 -11
- package/dist/chunk-HUWOFP2H.js.map +1 -0
- package/dist/{chunk-P4SNGQNI.js → chunk-KMMEFXIE.js} +2 -2
- package/dist/{chunk-FDLQ5M6W.js → chunk-LP45RCA4.js} +568 -23
- package/dist/chunk-LP45RCA4.js.map +1 -0
- package/dist/{chunk-L7YNNBI5.js → chunk-QAQDGPB4.js} +1 -75
- package/dist/chunk-QAQDGPB4.js.map +1 -0
- package/dist/{chunk-V2M243KZ.js → chunk-TRXBJEZ5.js} +55 -53
- package/dist/chunk-TRXBJEZ5.js.map +1 -0
- package/dist/{chunk-7KGWYNWE.js → chunk-UMT7RU77.js} +45 -118
- package/dist/chunk-UMT7RU77.js.map +1 -0
- package/dist/{chunk-QUXTZU36.js → chunk-XIBG7LSL.js} +137 -3
- package/dist/chunk-XIBG7LSL.js.map +1 -0
- package/dist/cli.js +24 -17
- package/dist/cli.js.map +1 -1
- package/dist/{config-editor-2GYL2SSZ.js → config-editor-3IKBPZA7.js} +2 -2
- package/dist/{core-plugins-I6UPXQBL.js → core-plugins-ROU4GPLT.js} +6 -7
- package/dist/{dev-loader-RDC5E2CW.js → dev-loader-DRU3R7ZM.js} +7 -18
- package/dist/dev-loader-DRU3R7ZM.js.map +1 -0
- package/dist/{doctor-H72BZOPA.js → doctor-QZQAP46W.js} +2 -2
- package/dist/index.d.ts +115 -5
- package/dist/index.js +45 -18
- package/dist/index.js.map +1 -1
- package/dist/{integrate-APK4OEQF.js → integrate-G6CVXTGT.js} +2 -3
- package/dist/integrate-G6CVXTGT.js.map +1 -0
- package/dist/{main-EJBK65NS.js → main-UVTZ46WP.js} +20 -147
- package/dist/main-UVTZ46WP.js.map +1 -0
- package/dist/{plugin-create-LCXXNDK6.js → plugin-create-5HQRF2ID.js} +19 -2
- package/dist/plugin-create-5HQRF2ID.js.map +1 -0
- package/dist/plugin-installer-GQ2P3Q3E.js +23 -0
- package/dist/plugin-installer-GQ2P3Q3E.js.map +1 -0
- package/dist/{post-upgrade-2MG3VUDV.js → post-upgrade-3ADZRMYJ.js} +2 -2
- package/dist/{setup-N7KT56O7.js → setup-EYAFK2WI.js} +77 -50
- package/dist/setup-EYAFK2WI.js.map +1 -0
- package/dist/{slack-KH7E3VBS.js → slack-37ZWBDUI.js} +2 -2
- package/dist/{telegram-QWMJU3A6.js → telegram-2ZCCCZIY.js} +2 -2
- package/dist/{tunnel-M47I7H4B.js → tunnel-45HA72MB.js} +2 -2
- package/dist/{tunnel-service-WADYHREX.js → tunnel-service-QJPUYEKU.js} +11 -3
- package/dist/tunnel-service-QJPUYEKU.js.map +1 -0
- package/package.json +1 -2
- package/dist/action-detect-QPA775HB.js +0 -16
- package/dist/adapter-IZNL6AK2.js +0 -2394
- package/dist/adapter-IZNL6AK2.js.map +0 -1
- package/dist/admin-GBPZFFAU.js +0 -23
- package/dist/agents-BWU4MRRD.js +0 -15
- package/dist/chunk-4KGLKKQK.js +0 -298
- package/dist/chunk-4KGLKKQK.js.map +0 -1
- package/dist/chunk-5RO42TWV.js +0 -150
- package/dist/chunk-5RO42TWV.js.map +0 -1
- package/dist/chunk-5YW56UJK.js.map +0 -1
- package/dist/chunk-5ZOFBTOR.js +0 -553
- package/dist/chunk-5ZOFBTOR.js.map +0 -1
- package/dist/chunk-6RXVEXF3.js +0 -23
- package/dist/chunk-6RXVEXF3.js.map +0 -1
- package/dist/chunk-7KGWYNWE.js.map +0 -1
- package/dist/chunk-CFM4GJ74.js.map +0 -1
- package/dist/chunk-FDLQ5M6W.js.map +0 -1
- package/dist/chunk-GJOY37U7.js +0 -265
- package/dist/chunk-GJOY37U7.js.map +0 -1
- package/dist/chunk-HVBNCPAY.js +0 -71
- package/dist/chunk-HVBNCPAY.js.map +0 -1
- package/dist/chunk-I3CGU5W7.js +0 -134
- package/dist/chunk-I3CGU5W7.js.map +0 -1
- package/dist/chunk-L7YNNBI5.js.map +0 -1
- package/dist/chunk-MTSDOSXS.js +0 -219
- package/dist/chunk-MTSDOSXS.js.map +0 -1
- package/dist/chunk-NAM4ERUW.js +0 -203
- package/dist/chunk-NAM4ERUW.js.map +0 -1
- package/dist/chunk-O5RG4YZY.js +0 -122
- package/dist/chunk-O5RG4YZY.js.map +0 -1
- package/dist/chunk-QUXTZU36.js.map +0 -1
- package/dist/chunk-V2M243KZ.js.map +0 -1
- package/dist/chunk-VO3A2NI4.js +0 -145
- package/dist/chunk-VO3A2NI4.js.map +0 -1
- package/dist/dev-loader-RDC5E2CW.js.map +0 -1
- package/dist/discord-DXDTGVGS.js +0 -8
- package/dist/doctor-H72BZOPA.js.map +0 -1
- package/dist/doctor-RF6BHMCC.js +0 -15
- package/dist/doctor-RF6BHMCC.js.map +0 -1
- package/dist/integrate-APK4OEQF.js.map +0 -1
- package/dist/main-EJBK65NS.js.map +0 -1
- package/dist/new-session-HFO5GHSZ.js +0 -17
- package/dist/new-session-HFO5GHSZ.js.map +0 -1
- package/dist/plugin-create-LCXXNDK6.js.map +0 -1
- package/dist/session-KZFA6Z26.js +0 -20
- package/dist/session-KZFA6Z26.js.map +0 -1
- package/dist/settings-MFYM7CZO.js +0 -14
- package/dist/settings-MFYM7CZO.js.map +0 -1
- package/dist/setup-N7KT56O7.js.map +0 -1
- package/dist/slack-KH7E3VBS.js.map +0 -1
- package/dist/telegram-QWMJU3A6.js.map +0 -1
- package/dist/tunnel-M47I7H4B.js.map +0 -1
- package/dist/tunnel-service-WADYHREX.js.map +0 -1
- package/dist/validators-6CLEZUBD.js +0 -8
- package/dist/validators-6CLEZUBD.js.map +0 -1
- /package/dist/{action-detect-QPA775HB.js.map → adapter-LC2QSDAS.js.map} +0 -0
- /package/dist/{adapter-PQGHVG4K.js.map → adapter-Y55NXX6I.js.map} +0 -0
- /package/dist/{adapter-Z435XYBQ.js.map → api-server-7G3ZUZRM.js.map} +0 -0
- /package/dist/{admin-GBPZFFAU.js.map → api-server-CAYNPUF2.js.map} +0 -0
- /package/dist/{chunk-366FOUJG.js.map → chunk-36YQ44D7.js.map} +0 -0
- /package/dist/{chunk-UB2QB6DE.js.map → chunk-3ASUU6WW.js.map} +0 -0
- /package/dist/{chunk-ZPTM4NGK.js.map → chunk-4GMLGCF2.js.map} +0 -0
- /package/dist/{chunk-P4SNGQNI.js.map → chunk-KMMEFXIE.js.map} +0 -0
- /package/dist/{agents-BWU4MRRD.js.map → config-editor-3IKBPZA7.js.map} +0 -0
- /package/dist/{api-server-2I7B3MXR.js.map → core-plugins-ROU4GPLT.js.map} +0 -0
- /package/dist/{api-server-5VEESFOT.js.map → doctor-QZQAP46W.js.map} +0 -0
- /package/dist/{post-upgrade-2MG3VUDV.js.map → post-upgrade-3ADZRMYJ.js.map} +0 -0
- /package/dist/{config-editor-2GYL2SSZ.js.map → slack-37ZWBDUI.js.map} +0 -0
- /package/dist/{core-plugins-I6UPXQBL.js.map → telegram-2ZCCCZIY.js.map} +0 -0
- /package/dist/{discord-DXDTGVGS.js.map → tunnel-45HA72MB.js.map} +0 -0
package/dist/session-KZFA6Z26.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
executeCancelSession,
|
|
3
|
-
handleCancel,
|
|
4
|
-
handleCleanupButton,
|
|
5
|
-
handleHandoff,
|
|
6
|
-
handleSessions,
|
|
7
|
-
handleStatus
|
|
8
|
-
} from "./chunk-GJOY37U7.js";
|
|
9
|
-
import "./chunk-O5RG4YZY.js";
|
|
10
|
-
import "./chunk-XMMAGAT4.js";
|
|
11
|
-
import "./chunk-VUNV25KB.js";
|
|
12
|
-
export {
|
|
13
|
-
executeCancelSession,
|
|
14
|
-
handleCancel,
|
|
15
|
-
handleCleanupButton,
|
|
16
|
-
handleHandoff,
|
|
17
|
-
handleSessions,
|
|
18
|
-
handleStatus
|
|
19
|
-
};
|
|
20
|
-
//# sourceMappingURL=session-KZFA6Z26.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
handleSettings,
|
|
3
|
-
handleSettingsButton,
|
|
4
|
-
showSettingsInfo
|
|
5
|
-
} from "./chunk-4KGLKKQK.js";
|
|
6
|
-
import "./chunk-ODUM3D6X.js";
|
|
7
|
-
import "./chunk-XMMAGAT4.js";
|
|
8
|
-
import "./chunk-VUNV25KB.js";
|
|
9
|
-
export {
|
|
10
|
-
handleSettings,
|
|
11
|
-
handleSettingsButton,
|
|
12
|
-
showSettingsInfo
|
|
13
|
-
};
|
|
14
|
-
//# sourceMappingURL=settings-MFYM7CZO.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/setup/wizard.ts","../../src/core/setup/types.ts","../../src/core/setup/helpers.ts","../../src/core/setup/setup-agents.ts","../../src/core/setup/setup-workspace.ts","../../src/core/setup/setup-run-mode.ts","../../src/core/setup/setup-integrations.ts","../../src/core/setup/setup-channels.ts"],"sourcesContent":["import * as clack from \"@clack/prompts\";\nimport type { Config, ConfigManager } from \"../config/config.js\";\nimport type { OnboardSection } from \"./types.js\";\nimport { ONBOARD_SECTION_OPTIONS } from \"./types.js\";\nimport { guardCancel, ok, fail, printStartBanner, summarizeConfig } from \"./helpers.js\";\nimport { setupAgents } from \"./setup-agents.js\";\nimport { setupWorkspace } from \"./setup-workspace.js\";\nimport { setupRunMode } from \"./setup-run-mode.js\";\nimport { setupIntegrations } from \"./setup-integrations.js\";\nimport { configureChannels } from \"./setup-channels.js\";\nimport type { SettingsManager } from \"../plugin/settings-manager.js\";\nimport type { PluginRegistry } from \"../plugin/plugin-registry.js\";\n\n// ─── First-run setup ───\n\nexport async function runSetup(\n configManager: ConfigManager,\n opts?: { skipRunMode?: boolean; settingsManager?: SettingsManager; pluginRegistry?: PluginRegistry },\n): Promise<boolean> {\n await printStartBanner();\n clack.intro(\"Let's set up OpenACP\");\n\n const { settingsManager, pluginRegistry } = opts ?? {};\n\n try {\n const channelChoice = guardCancel(\n await clack.select({\n message: 'Which messaging platform do you want to use?',\n options: [\n { label: 'Telegram', value: 'telegram' },\n { label: 'Discord', value: 'discord' },\n { label: 'Both', value: 'both' },\n ],\n }),\n );\n\n // Calculate total steps dynamically: channel(s) + workspace + run mode\n const channelSteps = channelChoice === 'both' ? 2 : 1;\n const runModeSteps = opts?.skipRunMode ? 0 : 1;\n const totalSteps = channelSteps + 1 + runModeSteps; // + workspace + optional run mode\n\n let currentStep = 0;\n\n if (channelChoice === 'telegram' || channelChoice === 'both') {\n currentStep++;\n if (settingsManager && pluginRegistry) {\n // Delegate to Telegram plugin's install() via InstallContext\n const { createInstallContext } = await import('../plugin/install-context.js');\n const telegramPlugin = (await import('../../plugins/telegram/index.js')).default;\n const ctx = createInstallContext({\n pluginName: telegramPlugin.name,\n settingsManager,\n basePath: settingsManager.getBasePath(),\n });\n await telegramPlugin.install!(ctx);\n pluginRegistry.register(telegramPlugin.name, {\n version: telegramPlugin.version,\n source: 'builtin',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(telegramPlugin.name),\n description: telegramPlugin.description,\n });\n } else {\n // Plugin system not available — inform user\n console.log(fail('Plugin system not initialized. Cannot set up Telegram.'));\n return false;\n }\n }\n if (channelChoice === 'discord' || channelChoice === 'both') {\n currentStep++;\n if (settingsManager && pluginRegistry) {\n // Delegate to Discord plugin's install() via InstallContext\n const { createInstallContext } = await import('../plugin/install-context.js');\n const discordPlugin = (await import('../../plugins/discord/index.js')).default;\n const ctx = createInstallContext({\n pluginName: discordPlugin.name,\n settingsManager,\n basePath: settingsManager.getBasePath(),\n });\n await discordPlugin.install!(ctx);\n pluginRegistry.register(discordPlugin.name, {\n version: discordPlugin.version,\n source: 'builtin',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(discordPlugin.name),\n description: discordPlugin.description,\n });\n } else {\n // Plugin system not available — inform user\n console.log(fail('Plugin system not initialized. Cannot set up Discord.'));\n return false;\n }\n }\n\n const { defaultAgent } = await setupAgents();\n\n // Offer Claude CLI integration\n await setupIntegrations();\n\n currentStep++;\n const workspace = await setupWorkspace({ stepNum: currentStep, totalSteps });\n\n let runMode: 'foreground' | 'daemon' = 'foreground';\n let autoStart = false;\n if (!opts?.skipRunMode) {\n currentStep++;\n const result = await setupRunMode({ stepNum: currentStep, totalSteps });\n runMode = result.runMode;\n autoStart = result.autoStart;\n }\n\n const security = {\n allowedUserIds: [] as string[],\n maxConcurrentSessions: 20,\n sessionTimeoutMinutes: 60,\n };\n\n const config: Config = {\n channels: {},\n agents: {},\n defaultAgent,\n workspace,\n security,\n logging: {\n level: \"info\",\n logDir: \"~/.openacp/logs\",\n maxFileSize: \"10m\",\n maxFiles: 7,\n sessionLogRetentionDays: 30,\n },\n runMode,\n autoStart,\n api: {\n port: 21420,\n host: '127.0.0.1',\n },\n sessionStore: { ttlDays: 30 },\n tunnel: {\n enabled: true,\n port: 3100,\n provider: \"cloudflare\",\n options: {},\n maxUserTunnels: 5,\n storeTtlMinutes: 60,\n auth: { enabled: false },\n },\n usage: {\n enabled: true,\n warningThreshold: 0.8,\n currency: \"USD\",\n retentionDays: 90,\n },\n integrations: {},\n speech: {\n stt: { provider: null, providers: {} },\n tts: { provider: null, providers: {} },\n },\n };\n\n try {\n await configManager.writeNew(config);\n } catch (writeErr) {\n console.log(\n fail(`Could not save config: ${(writeErr as Error).message}`),\n );\n return false;\n }\n\n // Auto-register remaining built-in plugins in the registry\n if (settingsManager && pluginRegistry) {\n await registerBuiltinPlugins(settingsManager, pluginRegistry);\n await pluginRegistry.save();\n }\n\n clack.outro(`Config saved to ${configManager.getConfigPath()}`);\n\n if (!opts?.skipRunMode) {\n console.log(ok(\"Starting OpenACP...\"));\n console.log(\"\");\n }\n\n return true;\n } catch (err) {\n if ((err as Error).name === \"ExitPromptError\") {\n clack.cancel(\"Setup cancelled.\");\n return false;\n }\n throw err;\n }\n}\n\n/**\n * Register all built-in plugins that haven't been registered yet.\n * Called after first-run setup to populate the registry with defaults.\n */\nasync function registerBuiltinPlugins(\n settingsManager: SettingsManager,\n pluginRegistry: PluginRegistry,\n): Promise<void> {\n const builtinPlugins = [\n { name: '@openacp/security', version: '1.0.0', description: 'User access control and session limits' },\n { name: '@openacp/file-service', version: '1.0.0', description: 'File storage and management' },\n { name: '@openacp/context', version: '1.0.0', description: 'Conversation context management' },\n { name: '@openacp/usage', version: '1.0.0', description: 'Token usage tracking and budget enforcement' },\n { name: '@openacp/speech', version: '1.0.0', description: 'Text-to-speech and speech-to-text' },\n { name: '@openacp/notifications', version: '1.0.0', description: 'Cross-session notification routing' },\n { name: '@openacp/tunnel', version: '1.0.0', description: 'Expose local services via tunnel' },\n { name: '@openacp/api-server', version: '1.0.0', description: 'REST API + SSE streaming server' },\n ];\n\n for (const p of builtinPlugins) {\n if (!pluginRegistry.get(p.name)) {\n pluginRegistry.register(p.name, {\n version: p.version,\n source: 'builtin',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(p.name),\n description: p.description,\n });\n }\n }\n}\n\n// ─── Reconfigure (section-based, for existing config) ───\n\ntype ReconfigureSection = OnboardSection | \"__continue\";\n\nasync function selectSection(hasSelection: boolean): Promise<ReconfigureSection> {\n return guardCancel(\n await clack.select({\n message: \"Select sections to configure\",\n options: [\n ...ONBOARD_SECTION_OPTIONS,\n {\n value: \"__continue\" as const,\n label: \"Continue\",\n hint: hasSelection ? \"Done\" : \"Skip for now\",\n },\n ],\n initialValue: ONBOARD_SECTION_OPTIONS[0].value,\n }),\n ) as ReconfigureSection;\n}\n\nexport async function runReconfigure(configManager: ConfigManager): Promise<void> {\n await printStartBanner();\n clack.intro(\"OpenACP — Reconfigure\");\n\n try {\n await configManager.load();\n let config = configManager.get();\n\n // Show current config summary\n clack.note(summarizeConfig(config), \"Current configuration\");\n\n let ranSection = false;\n\n while (true) {\n const choice = await selectSection(ranSection);\n if (choice === \"__continue\") break;\n ranSection = true;\n\n if (choice === \"channels\") {\n const result = await configureChannels(config);\n if (result.changed) {\n // IMPORTANT: Use writeNew() instead of save() because save() uses deepMerge\n // which cannot delete keys. Channel deletion (delete next.channels.telegram)\n // would be silently ignored by deepMerge. writeNew() overwrites the full config.\n config = { ...config, channels: result.config.channels };\n await configManager.writeNew(config);\n }\n }\n\n if (choice === \"agents\") {\n const { defaultAgent } = await setupAgents();\n await configManager.save({ defaultAgent });\n config = configManager.get();\n }\n\n if (choice === \"workspace\") {\n const { baseDir } = await setupWorkspace({\n existing: config.workspace.baseDir,\n });\n await configManager.save({ workspace: { baseDir } });\n config = configManager.get();\n }\n\n if (choice === \"runMode\") {\n const result = await setupRunMode({\n existing: { runMode: config.runMode, autoStart: config.autoStart },\n });\n await configManager.save({\n runMode: result.runMode,\n autoStart: result.autoStart,\n });\n config = configManager.get();\n }\n\n if (choice === \"integrations\") {\n await setupIntegrations(config);\n }\n }\n\n if (!ranSection) {\n clack.outro(\"No changes made.\");\n return;\n }\n\n clack.outro(`Config saved to ${configManager.getConfigPath()}`);\n } catch (err) {\n if ((err as Error).name === \"ExitPromptError\") {\n clack.cancel(\"Setup cancelled.\");\n return;\n }\n throw err;\n }\n}\n","export type OnboardSection =\n | \"channels\"\n | \"agents\"\n | \"workspace\"\n | \"runMode\"\n | \"integrations\";\n\nexport type ConfiguredChannelAction = \"modify\" | \"disable\" | \"delete\" | \"skip\";\n\nexport type ChannelId = \"telegram\" | \"discord\";\n\nexport type ChannelStatus = {\n id: ChannelId;\n label: string;\n configured: boolean;\n enabled: boolean;\n hint?: string;\n};\n\nexport const ONBOARD_SECTION_OPTIONS: Array<{\n value: OnboardSection;\n label: string;\n hint: string;\n}> = [\n { value: \"channels\", label: \"Channels\", hint: \"Link/update messaging platforms\" },\n { value: \"agents\", label: \"Agents\", hint: \"Install agents, change default\" },\n { value: \"workspace\", label: \"Workspace\", hint: \"Set workspace directory\" },\n { value: \"runMode\", label: \"Run mode\", hint: \"Foreground/daemon, auto-start\" },\n { value: \"integrations\", label: \"Integrations\", hint: \"Claude CLI session transfer\" },\n];\n\nexport const CHANNEL_META: Record<ChannelId, { label: string; method: string }> = {\n telegram: { label: \"Telegram\", method: \"Bot API\" },\n discord: { label: \"Discord\", method: \"Bot API\" },\n};\n\n","import * as clack from \"@clack/prompts\";\nimport type { Config } from \"../config/config.js\";\n\n// --- ANSI colors ---\n\nexport const c = {\n reset: \"\\x1b[0m\",\n bold: \"\\x1b[1m\",\n dim: \"\\x1b[2m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n red: \"\\x1b[31m\",\n cyan: \"\\x1b[36m\",\n white: \"\\x1b[37m\",\n};\n\nexport const ok = (msg: string) =>\n `${c.green}${c.bold}✓${c.reset} ${c.green}${msg}${c.reset}`;\nexport const warn = (msg: string) => `${c.yellow}⚠ ${msg}${c.reset}`;\nexport const fail = (msg: string) => `${c.red}✗ ${msg}${c.reset}`;\nexport const step = (n: number, total: number, title: string) =>\n `\\n${c.cyan}${c.bold}[${n}/${total}]${c.reset} ${c.bold}${title}${c.reset}\\n`;\nexport const dim = (msg: string) => `${c.dim}${msg}${c.reset}`;\n\nexport function guardCancel<T>(value: T | symbol): T {\n if (clack.isCancel(value)) {\n clack.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n return value as T;\n}\n\n// --- Banner ---\n\nfunction applyGradient(text: string): string {\n const colors = [135, 99, 63, 33, 39, 44, 44];\n const lines = text.split(\"\\n\");\n return lines\n .map((line, i) => {\n const colorIdx = Math.min(i, colors.length - 1);\n return `\\x1b[38;5;${colors[colorIdx]}m${line}\\x1b[0m`;\n })\n .join(\"\\n\");\n}\n\nconst BANNER = `\n ██████╗ ██████╗ ███████╗███╗ ██╗ █████╗ ██████╗██████╗\n ██╔═══██╗██╔══██╗██╔════╝████╗ ██║██╔══██╗██╔════╝██╔══██╗\n ██║ ██║██████╔╝█████╗ ██╔██╗ ██║███████║██║ ██████╔╝\n ██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║██╔══██║██║ ██╔═══╝\n ╚██████╔╝██║ ███████╗██║ ╚████║██║ ██║╚██████╗██║\n ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═════╝╚═╝\n`;\n\nexport async function printStartBanner(): Promise<void> {\n let version = \"0.0.0\";\n try {\n const { getCurrentVersion } = await import(\"../../cli/version.js\");\n version = getCurrentVersion();\n } catch {\n // ignore\n }\n console.log(applyGradient(BANNER));\n console.log(`${c.dim} AI coding agents, anywhere. v${version}${c.reset}\\n`);\n}\n\n// --- Config summary ---\n\nexport function summarizeConfig(config: Config): string {\n const lines: string[] = [];\n\n // Channels\n const channelStatuses: string[] = [];\n for (const [id, meta] of Object.entries({\n telegram: \"Telegram\",\n discord: \"Discord\",\n })) {\n const ch = config.channels[id] as { enabled?: boolean } | undefined;\n if (ch?.enabled) {\n channelStatuses.push(`${meta} (enabled)`);\n } else if (ch && Object.keys(ch).length > 1) {\n channelStatuses.push(`${meta} (disabled)`);\n } else {\n channelStatuses.push(`${meta} (not configured)`);\n }\n }\n lines.push(`Channels: ${channelStatuses.join(\", \")}`);\n\n // Default agent\n lines.push(`Default agent: ${config.defaultAgent}`);\n\n // Workspace\n lines.push(`Workspace: ${config.workspace.baseDir}`);\n\n // Run mode\n lines.push(`Run mode: ${config.runMode}${config.autoStart ? \" (auto-start)\" : \"\"}`);\n\n return lines.join(\"\\n\");\n}\n","import { execFileSync } from \"node:child_process\";\nimport * as clack from \"@clack/prompts\";\nimport { commandExists } from \"../agents/agent-dependencies.js\";\nimport { guardCancel, ok, warn, c } from \"./helpers.js\";\n\nconst KNOWN_AGENTS: Array<{ name: string; commands: string[] }> = [\n // claude-agent-acp is bundled as a dependency — no detection needed, but\n // kept here so detectAgents() still returns it for display purposes.\n { name: \"claude\", commands: [\"claude-agent-acp\"] },\n { name: \"codex\", commands: [\"codex\"] },\n];\n\nexport async function detectAgents(): Promise<\n Array<{ name: string; command: string }>\n> {\n const found: Array<{ name: string; command: string }> = [];\n for (const agent of KNOWN_AGENTS) {\n // Find all available commands for this agent (PATH + node_modules/.bin)\n const available: string[] = [];\n for (const cmd of agent.commands) {\n if (commandExists(cmd)) {\n available.push(cmd);\n }\n }\n if (available.length > 0) {\n // Prefer claude-agent-acp over claude/claude-code (priority order)\n found.push({ name: agent.name, command: available[0] });\n }\n }\n return found;\n}\n\nexport async function validateAgentCommand(command: string): Promise<boolean> {\n try {\n execFileSync(\"which\", [command], { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function setupAgents(): Promise<{\n defaultAgent: string;\n}> {\n const { AgentCatalog } = await import(\"../agents/agent-catalog.js\");\n const { muteLogger, unmuteLogger } = await import(\"../utils/log.js\");\n\n muteLogger();\n const catalog = new AgentCatalog();\n catalog.load();\n\n const s = clack.spinner();\n s.start(\"Checking available agents...\");\n await catalog.refreshRegistryIfStale();\n\n // Claude is always pre-installed (bundled dependency)\n if (!catalog.getInstalledAgent(\"claude\")) {\n const claudeRegistry = catalog.findRegistryAgent(\"claude-acp\");\n if (claudeRegistry) {\n await catalog.install(\"claude-acp\");\n } else {\n // Fallback: register bundled claude-agent-acp directly\n const { AgentStore } = await import(\"../agents/agent-store.js\");\n const store = new AgentStore();\n store.load();\n store.addAgent(\"claude\", {\n registryId: \"claude-acp\",\n name: \"Claude Agent\",\n version: \"bundled\",\n distribution: \"npx\",\n command: \"npx\",\n args: [\"@zed-industries/claude-agent-acp\"],\n env: {},\n installedAt: new Date().toISOString(),\n binaryPath: null,\n });\n }\n }\n s.stop(ok(\"Claude Agent ready\"));\n unmuteLogger();\n\n const available = catalog.getAvailable();\n const installed = available.filter((a) => a.installed);\n const installable = available.filter((a) => !a.installed && a.available);\n\n // Offer agent selection — show installed agents as pre-checked + installable agents\n if (installed.length > 0 || installable.length > 0) {\n // Deduplicate by key AND name\n const seen = new Set<string>();\n const options: Array<{ label: string; value: string }> = [];\n\n for (const a of installed) {\n const dedupeKey = `${a.key}::${a.name}`;\n if (seen.has(dedupeKey)) continue;\n seen.add(dedupeKey);\n options.push({\n label: `${a.name} (installed)`,\n value: a.key,\n });\n }\n for (const a of installable) {\n const dedupeKey = `${a.key}::${a.name}`;\n if (seen.has(dedupeKey)) continue;\n seen.add(dedupeKey);\n options.push({\n label: `${a.name} (${a.distribution})`,\n value: a.key,\n });\n }\n\n const installedKeys = installed.map(a => a.key);\n const selected = guardCancel(\n await clack.autocompleteMultiselect({\n message: \"Install additional agents? (type to search, Space to select)\",\n options,\n initialValues: installedKeys,\n required: false,\n }),\n ) as string[];\n\n for (const key of selected) {\n const regAgent = catalog.findRegistryAgent(key);\n if (regAgent) {\n const installSpinner = clack.spinner();\n installSpinner.start(`Installing ${regAgent.name}...`);\n muteLogger();\n const result = await catalog.install(key);\n unmuteLogger();\n if (result.ok) {\n installSpinner.stop(ok(\"done\"));\n } else {\n installSpinner.stop(warn(`skipped: ${result.error}`));\n }\n }\n }\n }\n\n // Choose default agent\n const installedAgents = Object.keys(catalog.getInstalledEntries());\n let defaultAgent = \"claude\";\n\n if (installedAgents.length > 1) {\n defaultAgent = guardCancel(\n await clack.select({\n message: \"Which agent should be the default?\",\n options: installedAgents.map((key) => {\n const agent = catalog.getInstalledAgent(key)!;\n return { label: `${agent.name} (${key})`, value: key };\n }),\n initialValue: \"claude\",\n }),\n ) as string;\n }\n\n console.log(ok(`Default agent: ${c.bold}${defaultAgent}${c.reset}`));\n return { defaultAgent };\n}\n","import * as clack from \"@clack/prompts\";\nimport { guardCancel, step } from \"./helpers.js\";\n\nexport async function setupWorkspace(opts?: {\n existing?: string;\n stepNum?: number;\n totalSteps?: number;\n}): Promise<{ baseDir: string }> {\n const { existing, stepNum, totalSteps } = opts ?? {};\n if (stepNum != null && totalSteps != null) {\n console.log(step(stepNum, totalSteps, \"Workspace\"));\n }\n\n const baseDir = guardCancel(\n await clack.text({\n message: \"Base directory for workspaces:\",\n initialValue: existing ?? \"~/openacp-workspace\",\n validate: (val) =>\n (val ?? \"\").toString().trim().length > 0 ? undefined : \"Path cannot be empty\",\n }),\n ) as string;\n\n return { baseDir: baseDir.trim().replace(/^['\"]|['\"]$/g, \"\") };\n}\n","import * as clack from \"@clack/prompts\";\nimport { expandHome } from \"../config/config.js\";\nimport { guardCancel, ok, warn, dim, step } from \"./helpers.js\";\n\nexport async function setupRunMode(opts?: {\n existing?: { runMode: string; autoStart: boolean };\n stepNum?: number;\n totalSteps?: number;\n}): Promise<{ runMode: 'foreground' | 'daemon'; autoStart: boolean }> {\n const { existing, stepNum, totalSteps } = opts ?? {};\n if (stepNum != null && totalSteps != null) {\n console.log(step(stepNum, totalSteps, 'Run Mode'));\n }\n\n // Don't show daemon option on Windows\n if (process.platform === 'win32') {\n console.log(dim(' (Daemon mode not available on Windows)'));\n return { runMode: 'foreground', autoStart: false };\n }\n\n const initialValue = (existing?.runMode === 'daemon' ? 'daemon' : 'foreground') as 'foreground' | 'daemon';\n\n const mode = guardCancel(\n await clack.select({\n message: 'How would you like to run OpenACP?',\n options: [\n {\n label: 'Background (daemon)',\n value: 'daemon' as const,\n hint: 'Runs silently, auto-starts on boot. Manage with: openacp status | stop | logs',\n },\n {\n label: 'Foreground (terminal)',\n value: 'foreground' as const,\n hint: 'Runs in current terminal session. Start with: openacp',\n },\n ],\n initialValue,\n }),\n );\n\n const wasDaemon = existing?.runMode === 'daemon';\n\n if (mode === 'daemon') {\n const { installAutoStart, isAutoStartSupported } = await import('../../cli/autostart.js');\n const { muteLogger, unmuteLogger } = await import('../utils/log.js');\n const autoStart = isAutoStartSupported();\n if (autoStart) {\n muteLogger();\n const result = installAutoStart(expandHome('~/.openacp/logs'));\n unmuteLogger();\n if (result.success) {\n console.log(ok('Auto-start on boot enabled'));\n } else {\n console.log(warn(`Auto-start failed: ${result.error}`));\n }\n }\n return { runMode: 'daemon', autoStart };\n }\n\n // Switching from daemon → foreground: stop daemon + uninstall autostart\n if (wasDaemon) {\n const { muteLogger, unmuteLogger } = await import('../utils/log.js');\n muteLogger();\n try {\n const { stopDaemon } = await import('../../cli/daemon.js');\n const result = await stopDaemon();\n unmuteLogger();\n if (result.stopped) {\n console.log(ok(`Daemon stopped (was PID ${result.pid})`));\n }\n } catch {\n unmuteLogger();\n // Daemon may not be running\n }\n muteLogger();\n try {\n const { uninstallAutoStart } = await import('../../cli/autostart.js');\n uninstallAutoStart();\n unmuteLogger();\n } catch {\n unmuteLogger();\n // ignore\n }\n }\n\n return { runMode: 'foreground', autoStart: false };\n}\n","import * as clack from \"@clack/prompts\";\nimport type { Config } from \"../config/config.js\";\nimport { guardCancel } from \"./helpers.js\";\n\nexport async function setupIntegrations(config?: Config): Promise<void> {\n const claudeIntegration = (config?.integrations as Record<string, unknown> | undefined)?.claude as { installed?: boolean } | undefined;\n const isInstalled = claudeIntegration?.installed === true;\n\n const installClaude = guardCancel(\n await clack.confirm({\n message: isInstalled\n ? \"Claude CLI integration is installed. Reinstall?\"\n : \"Install session transfer for Claude? (enables /openacp:handoff in your terminal)\",\n initialValue: !isInstalled,\n }),\n );\n\n if (installClaude) {\n try {\n const { getIntegration } = await import(\"../../cli/integrate.js\");\n const integration = getIntegration(\"claude\");\n if (integration) {\n for (const item of integration.items) {\n const result = await item.install();\n for (const log of result.logs) console.log(` ${log}`);\n }\n }\n console.log(\"Claude CLI integration installed.\\n\");\n } catch (err) {\n console.log(`Could not install Claude CLI integration: ${err instanceof Error ? err.message : err}`);\n console.log(\" You can install it later with: openacp integrate claude\\n\");\n }\n }\n}\n","import * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport * as clack from \"@clack/prompts\";\nimport type { Config } from \"../config/config.js\";\nimport type { ConfiguredChannelAction, ChannelId, ChannelStatus } from \"./types.js\";\nimport { CHANNEL_META } from \"./types.js\";\nimport { guardCancel, ok, c } from \"./helpers.js\";\n\nexport function getChannelStatuses(config: Config): ChannelStatus[] {\n const statuses: ChannelStatus[] = [];\n\n for (const [id, meta] of Object.entries(CHANNEL_META) as [ChannelId, typeof CHANNEL_META[ChannelId]][]) {\n const ch = config.channels[id] as Record<string, unknown> | undefined;\n const enabled = ch?.enabled === true;\n const configured = !!ch && Object.keys(ch).length > 1;\n\n let hint: string | undefined;\n if (id === \"telegram\" && ch?.botToken && typeof ch.botToken === \"string\" && ch.botToken !== \"YOUR_BOT_TOKEN_HERE\") {\n hint = `Chat ID: ${ch.chatId}`;\n }\n if (id === \"discord\" && ch?.guildId) {\n hint = `Guild: ${ch.guildId}`;\n }\n\n statuses.push({ id, label: meta.label, configured, enabled, hint });\n }\n\n return statuses;\n}\n\nexport function noteChannelStatus(config: Config): void {\n const statuses = getChannelStatuses(config);\n const lines = statuses.map((s) => {\n const status = s.enabled ? \"enabled\" : s.configured ? \"disabled\" : \"not configured\";\n const hintStr = s.hint ? ` — ${s.hint}` : \"\";\n return ` ${s.label}: ${status}${hintStr}`;\n });\n\n console.log(\"\");\n console.log(`${c.bold} Channel status${c.reset}`);\n for (const line of lines) console.log(line);\n console.log(\"\");\n}\n\nasync function promptConfiguredAction(label: string): Promise<ConfiguredChannelAction> {\n return guardCancel(\n await clack.select({\n message: `${label} already configured. What do you want to do?`,\n options: [\n { value: \"modify\" as const, label: \"Modify settings\" },\n { value: \"disable\" as const, label: \"Disable bot\" },\n { value: \"delete\" as const, label: \"Delete config\" },\n { value: \"skip\" as const, label: \"Skip (leave as-is)\" },\n ],\n initialValue: \"modify\" as const,\n }),\n );\n}\n\nasync function configureViaPlugin(channelId: ChannelId): Promise<void> {\n const pluginMap: Record<ChannelId, { importPath: string; name: string }> = {\n telegram: { importPath: '../../plugins/telegram/index.js', name: '@openacp/telegram' },\n discord: { importPath: '../../plugins/discord/index.js', name: '@openacp/discord' },\n };\n\n const pluginInfo = pluginMap[channelId];\n if (!pluginInfo) return;\n\n const { SettingsManager } = await import('../plugin/settings-manager.js');\n const { createInstallContext } = await import('../plugin/install-context.js');\n const basePath = path.join(os.homedir(), '.openacp', 'plugins');\n const settingsManager = new SettingsManager(basePath);\n\n const pluginModule = await import(pluginInfo.importPath);\n const plugin = pluginModule.default;\n\n if (plugin?.configure) {\n const ctx = createInstallContext({\n pluginName: plugin.name,\n settingsManager,\n basePath,\n });\n await plugin.configure(ctx);\n }\n}\n\nexport async function configureChannels(config: Config): Promise<{ config: Config; changed: boolean }> {\n const next = structuredClone(config);\n let changed = false;\n\n noteChannelStatus(next);\n\n while (true) {\n const statuses = getChannelStatuses(next);\n const options = statuses.map((s) => {\n const status = s.enabled ? \"enabled\" : s.configured ? \"disabled\" : \"not configured\";\n return {\n value: s.id,\n label: `${s.label} (${CHANNEL_META[s.id].method})`,\n hint: status + (s.hint ? ` · ${s.hint}` : \"\"),\n };\n });\n\n const choice = guardCancel(\n await clack.select({\n message: \"Select a channel\",\n options: [\n ...options,\n { value: \"__done__\" as const, label: \"Finished\" },\n ],\n }),\n );\n\n if (choice === \"__done__\") break;\n\n const channelId = choice as ChannelId;\n const meta = CHANNEL_META[channelId];\n const existing = next.channels[channelId] as Record<string, unknown> | undefined;\n const isConfigured = !!existing && Object.keys(existing).length > 1;\n\n if (isConfigured) {\n const action = await promptConfiguredAction(meta.label);\n\n if (action === \"skip\") continue;\n if (action === \"disable\") {\n (next.channels[channelId] as Record<string, unknown>).enabled = false;\n changed = true;\n console.log(ok(`${meta.label} disabled`));\n continue;\n }\n if (action === \"delete\") {\n const confirmed = guardCancel(\n await clack.confirm({\n message: `Delete ${meta.label} config? This cannot be undone.`,\n initialValue: false,\n }),\n );\n if (confirmed) {\n delete next.channels[channelId];\n changed = true;\n console.log(ok(`${meta.label} config deleted`));\n }\n continue;\n }\n // action === \"modify\" — fall through to plugin configure\n }\n\n // Run channel configuration via plugin configure()\n await configureViaPlugin(channelId);\n changed = true;\n }\n\n return { config: next, changed };\n}\n"],"mappings":"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","names":["clack","text","clack","clack","clack","clack","clack"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/plugins/tunnel/tunnel-service.ts","../../src/plugins/tunnel/tunnel-registry.ts","../../src/plugins/tunnel/providers/cloudflare.ts","../../src/plugins/tunnel/providers/ngrok.ts","../../src/plugins/tunnel/providers/bore.ts","../../src/plugins/tunnel/providers/tailscale.ts","../../src/plugins/tunnel/viewer-store.ts","../../src/plugins/tunnel/server.ts","../../src/plugins/tunnel/templates/file-viewer.ts","../../src/plugins/tunnel/templates/diff-viewer.ts"],"sourcesContent":["import { serve } from '@hono/node-server'\nimport type { TunnelConfig } from '../../core/config/config.js'\nimport { createChildLogger } from '../../core/utils/log.js'\nimport { TunnelRegistry, type TunnelEntry } from './tunnel-registry.js'\nimport { ViewerStore } from './viewer-store.js'\nimport { createTunnelServer } from './server.js'\n\nconst log = createChildLogger({ module: 'tunnel' })\n\nexport class TunnelService {\n private registry: TunnelRegistry\n private store: ViewerStore\n private server: ReturnType<typeof serve> | null = null\n private config: TunnelConfig\n private systemPort = 0\n\n constructor(config: TunnelConfig) {\n this.config = config\n this.store = new ViewerStore(config.storeTtlMinutes)\n this.registry = new TunnelRegistry({\n maxUserTunnels: config.maxUserTunnels ?? 5,\n providerOptions: config.options,\n })\n }\n\n async start(): Promise<string> {\n // 1. Start HTTP viewer server — try configured port, then auto-increment\n const authToken = this.config.auth.enabled ? this.config.auth.token : undefined\n const app = createTunnelServer(this.store, authToken)\n\n let actualPort = this.config.port\n const maxRetries = 10\n\n for (let i = 0; i < maxRetries; i++) {\n const port = this.config.port + i\n const server = serve({ fetch: app.fetch, port })\n\n const ok = await new Promise<boolean>((resolve) => {\n server.on('listening', () => resolve(true))\n server.on('error', () => resolve(false))\n })\n\n if (ok) {\n this.server = server\n actualPort = port\n if (i > 0) {\n log.info({ configuredPort: this.config.port, actualPort }, 'Configured port in use, using next available')\n }\n log.info({ port: actualPort }, 'Tunnel HTTP server started')\n break\n }\n\n server.close()\n }\n\n if (!this.server) {\n log.warn({ port: this.config.port }, 'Could not find available port for tunnel HTTP server')\n return `http://localhost:${this.config.port}`\n }\n\n this.systemPort = actualPort\n\n // 2. Register system tunnel (file viewer)\n try {\n await this.registry.add(actualPort, {\n type: 'system',\n provider: this.config.provider,\n label: 'File Viewer',\n })\n } catch (err) {\n log.warn({ err: (err as Error).message }, 'System tunnel failed, running on localhost')\n }\n\n // 3. Restore persisted user tunnels\n await this.registry.restore()\n\n const systemEntry = this.registry.getSystemEntry()\n return systemEntry?.publicUrl || `http://localhost:${actualPort}`\n }\n\n async stop(): Promise<void> {\n await this.registry.shutdown()\n this.registry.flush()\n if (this.server) {\n this.server.close()\n this.server = null\n }\n this.store.destroy()\n log.info('Tunnel service stopped')\n }\n\n // --- User tunnel management ---\n\n async addTunnel(port: number, opts?: { label?: string; sessionId?: string }): Promise<TunnelEntry> {\n return this.registry.add(port, {\n type: 'user',\n provider: this.config.provider,\n label: opts?.label,\n sessionId: opts?.sessionId,\n })\n }\n\n async stopTunnel(port: number): Promise<void> {\n return this.registry.stop(port)\n }\n\n async stopAllUser(): Promise<void> {\n return this.registry.stopAllUser()\n }\n\n async stopBySession(sessionId: string): Promise<TunnelEntry[]> {\n return this.registry.stopBySession(sessionId)\n }\n\n listTunnels(): TunnelEntry[] {\n return this.registry.list(false) // user only\n }\n\n getTunnel(port: number): TunnelEntry | null {\n return this.registry.get(port)\n }\n\n // --- Viewer (system tunnel) ---\n\n getPublicUrl(): string {\n const system = this.registry.getSystemEntry()\n return system?.publicUrl || `http://localhost:${this.systemPort || this.config.port}`\n }\n\n getStore(): ViewerStore {\n return this.store\n }\n\n fileUrl(entryId: string): string {\n return `${this.getPublicUrl()}/view/${entryId}`\n }\n\n diffUrl(entryId: string): string {\n return `${this.getPublicUrl()}/diff/${entryId}`\n }\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\nimport { createChildLogger } from '../../core/utils/log.js'\nimport type { TunnelProvider } from './provider.js'\nimport { CloudflareTunnelProvider } from './providers/cloudflare.js'\nimport { NgrokTunnelProvider } from './providers/ngrok.js'\nimport { BoreTunnelProvider } from './providers/bore.js'\nimport { TailscaleTunnelProvider } from './providers/tailscale.js'\n\nconst log = createChildLogger({ module: 'tunnel-registry' })\n\nexport interface TunnelEntry {\n port: number\n type: 'system' | 'user'\n provider: string\n label?: string\n publicUrl?: string\n sessionId?: string\n status: 'stopped' | 'starting' | 'active' | 'failed'\n createdAt: string\n}\n\ninterface PersistedEntry {\n port: number\n type: 'system' | 'user'\n provider: string\n label?: string\n sessionId?: string\n createdAt: string\n}\n\ninterface LiveEntry {\n entry: TunnelEntry\n process: TunnelProvider | null\n spawnPromise: Promise<string> | null\n}\n\nconst REGISTRY_PATH = path.join(os.homedir(), '.openacp', 'tunnels.json')\n\nexport class TunnelRegistry {\n private entries: Map<number, LiveEntry> = new Map()\n private saveTimeout: ReturnType<typeof setTimeout> | null = null\n private maxUserTunnels: number\n private providerOptions: Record<string, unknown>\n\n constructor(opts: { maxUserTunnels?: number; providerOptions?: Record<string, unknown> } = {}) {\n this.maxUserTunnels = opts.maxUserTunnels ?? 5\n this.providerOptions = opts.providerOptions ?? {}\n }\n\n async add(port: number, opts: {\n type: 'system' | 'user'\n provider: string\n label?: string\n sessionId?: string\n }): Promise<TunnelEntry> {\n // Check if port already registered\n if (this.entries.has(port)) {\n const existing = this.entries.get(port)!\n if (existing.entry.status === 'active' || existing.entry.status === 'starting') {\n throw new Error(`Port ${port} is already tunneled → ${existing.entry.publicUrl || 'starting...'}`)\n }\n // Stopped/failed entry — remove and re-add\n this.entries.delete(port)\n }\n\n // Check max user tunnels\n if (opts.type === 'user') {\n const userCount = this.list(false).filter(e => e.status === 'active' || e.status === 'starting').length\n if (userCount >= this.maxUserTunnels) {\n throw new Error(`Max user tunnels (${this.maxUserTunnels}) reached. Stop a tunnel first.`)\n }\n }\n\n const entry: TunnelEntry = {\n port,\n type: opts.type,\n provider: opts.provider,\n label: opts.label,\n sessionId: opts.sessionId,\n status: 'starting',\n createdAt: new Date().toISOString(),\n }\n\n const provider = this.createProvider(opts.provider)\n const spawnPromise = provider.start(port).then(url => {\n entry.publicUrl = url\n entry.status = 'active'\n log.info({ port, url, label: opts.label }, 'Tunnel active')\n this.scheduleSave()\n return url\n }).catch(err => {\n entry.status = 'failed'\n log.error({ port, err: (err as Error).message }, 'Tunnel failed to start')\n this.scheduleSave()\n throw err\n })\n\n this.entries.set(port, { entry, process: provider, spawnPromise })\n this.scheduleSave()\n\n // Await spawn — caller gets the URL or error\n await spawnPromise\n return entry\n }\n\n async stop(port: number): Promise<void> {\n const live = this.entries.get(port)\n if (!live) return\n\n if (live.entry.type === 'system') {\n throw new Error('Cannot stop system tunnel')\n }\n\n // Wait for spawn to finish if still starting\n if (live.spawnPromise) {\n try { await live.spawnPromise } catch { /* ignore spawn error */ }\n }\n\n if (live.process) {\n await live.process.stop()\n }\n\n this.entries.delete(port)\n this.scheduleSave()\n log.info({ port, label: live.entry.label }, 'Tunnel stopped')\n }\n\n async stopBySession(sessionId: string): Promise<TunnelEntry[]> {\n const stopped: TunnelEntry[] = []\n const toStop = this.getBySession(sessionId)\n for (const entry of toStop) {\n try {\n await this.stop(entry.port)\n stopped.push(entry)\n } catch { /* ignore */ }\n }\n return stopped\n }\n\n async stopAllUser(): Promise<void> {\n const userEntries = this.list(false)\n for (const entry of userEntries) {\n try { await this.stop(entry.port) } catch { /* ignore */ }\n }\n }\n\n async shutdown(): Promise<void> {\n for (const [, live] of this.entries) {\n if (live.spawnPromise) {\n try { await live.spawnPromise } catch { /* ignore */ }\n }\n if (live.process) {\n await live.process.stop()\n }\n }\n this.entries.clear()\n this.scheduleSave()\n }\n\n list(includeSystem = false): TunnelEntry[] {\n const entries = Array.from(this.entries.values()).map(l => l.entry)\n if (includeSystem) return entries\n return entries.filter(e => e.type === 'user')\n }\n\n get(port: number): TunnelEntry | null {\n return this.entries.get(port)?.entry ?? null\n }\n\n getBySession(sessionId: string): TunnelEntry[] {\n return this.list(false).filter(e => e.sessionId === sessionId)\n }\n\n getSystemEntry(): TunnelEntry | null {\n for (const live of this.entries.values()) {\n if (live.entry.type === 'system') return live.entry\n }\n return null\n }\n\n async restore(): Promise<void> {\n if (!fs.existsSync(REGISTRY_PATH)) return\n\n try {\n const raw = JSON.parse(fs.readFileSync(REGISTRY_PATH, 'utf-8')) as PersistedEntry[]\n log.info({ count: raw.length }, 'Restoring tunnels')\n\n // Only restore user tunnels — system tunnel is registered separately by TunnelService.start()\n const userEntries = raw.filter(e => e.type === 'user')\n for (const persisted of userEntries) {\n try {\n await this.add(persisted.port, {\n type: persisted.type,\n provider: persisted.provider,\n label: persisted.label,\n sessionId: persisted.sessionId,\n })\n } catch (err) {\n log.warn({ port: persisted.port, err: (err as Error).message }, 'Failed to restore tunnel')\n }\n }\n } catch (err) {\n log.warn({ err: (err as Error).message }, 'Failed to read tunnels.json')\n }\n }\n\n private createProvider(name: string): TunnelProvider {\n switch (name) {\n case 'cloudflare':\n return new CloudflareTunnelProvider(this.providerOptions)\n case 'ngrok':\n return new NgrokTunnelProvider(this.providerOptions)\n case 'bore':\n return new BoreTunnelProvider(this.providerOptions)\n case 'tailscale':\n return new TailscaleTunnelProvider(this.providerOptions)\n default:\n log.warn({ provider: name }, 'Unknown provider, falling back to cloudflare')\n return new CloudflareTunnelProvider(this.providerOptions)\n }\n }\n\n private scheduleSave(): void {\n if (this.saveTimeout) clearTimeout(this.saveTimeout)\n this.saveTimeout = setTimeout(() => this.save(), 2000)\n }\n\n private save(): void {\n const data: PersistedEntry[] = Array.from(this.entries.values()).map(l => ({\n port: l.entry.port,\n type: l.entry.type,\n provider: l.entry.provider,\n label: l.entry.label,\n sessionId: l.entry.sessionId,\n createdAt: l.entry.createdAt,\n }))\n\n try {\n const dir = path.dirname(REGISTRY_PATH)\n fs.mkdirSync(dir, { recursive: true })\n fs.writeFileSync(REGISTRY_PATH, JSON.stringify(data, null, 2))\n } catch (err) {\n log.error({ err: (err as Error).message }, 'Failed to save tunnels.json')\n }\n }\n\n flush(): void {\n if (this.saveTimeout) {\n clearTimeout(this.saveTimeout)\n this.saveTimeout = null\n }\n this.save()\n }\n}\n","import { spawn, type ChildProcess } from 'node:child_process'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\nimport { createChildLogger } from '../../../core/utils/log.js'\nimport { commandExists } from '../../../core/agents/agent-dependencies.js'\nimport type { TunnelProvider } from '../provider.js'\n\nconst log = createChildLogger({ module: 'cloudflare-tunnel' })\n\nexport class CloudflareTunnelProvider implements TunnelProvider {\n private child: ChildProcess | null = null\n private publicUrl = ''\n private options: Record<string, unknown>\n\n constructor(options: Record<string, unknown> = {}) {\n this.options = options\n }\n\n async start(localPort: number): Promise<string> {\n // Find binary — post-upgrade should have installed it, but fallback to ensureCloudflared() as safety net\n let binaryPath = this.findBinary()\n if (!binaryPath) {\n log.warn('cloudflared not found locally, attempting auto-install as fallback...')\n try {\n const { ensureCloudflared } = await import('./install-cloudflared.js')\n binaryPath = await ensureCloudflared()\n } catch (err) {\n throw new Error(`cloudflared is not installed and auto-install failed: ${(err as Error).message}`)\n }\n }\n\n const args = ['tunnel', '--url', `http://localhost:${localPort}`]\n if (this.options.domain) {\n args.push('--hostname', String(this.options.domain))\n }\n\n return new Promise<string>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.stop()\n reject(new Error('Cloudflare tunnel timed out after 30s'))\n }, 30_000)\n\n try {\n this.child = spawn(binaryPath, args, { stdio: ['ignore', 'pipe', 'pipe'] })\n } catch {\n clearTimeout(timeout)\n reject(new Error(`Failed to start cloudflared at ${binaryPath}`))\n return\n }\n\n const urlPattern = /https:\\/\\/[a-zA-Z0-9-]+\\.trycloudflare\\.com/\n\n const onData = (data: Buffer) => {\n const line = data.toString()\n log.debug(line.trim())\n const match = line.match(urlPattern)\n if (match) {\n clearTimeout(timeout)\n this.publicUrl = match[0]\n log.info({ url: this.publicUrl }, 'Cloudflare tunnel ready')\n resolve(this.publicUrl)\n }\n }\n\n this.child.stdout?.on('data', onData)\n this.child.stderr?.on('data', onData)\n\n this.child.on('error', (err) => {\n clearTimeout(timeout)\n reject(new Error(`cloudflared failed to start: ${err.message}`))\n })\n\n this.child.on('exit', (code) => {\n if (!this.publicUrl) {\n clearTimeout(timeout)\n reject(new Error(`cloudflared exited with code ${code} before establishing tunnel`))\n }\n })\n })\n }\n\n async stop(): Promise<void> {\n if (this.child) {\n this.child.kill('SIGTERM')\n this.child = null\n log.info('Cloudflare tunnel stopped')\n }\n }\n\n getPublicUrl(): string {\n return this.publicUrl\n }\n\n private findBinary(): string | null {\n // 1. Check PATH first (respects user's system install)\n if (commandExists('cloudflared')) return 'cloudflared'\n\n // 2. Check ~/.openacp/bin/ (installed by post-upgrade)\n const binPath = path.join(os.homedir(), '.openacp', 'bin', 'cloudflared')\n if (fs.existsSync(binPath)) return binPath\n\n // 3. Not found\n return null\n }\n}\n","import { spawn, type ChildProcess } from 'node:child_process'\nimport { createChildLogger } from '../../../core/utils/log.js'\nimport type { TunnelProvider } from '../provider.js'\n\nconst log = createChildLogger({ module: 'ngrok-tunnel' })\n\nexport class NgrokTunnelProvider implements TunnelProvider {\n private child: ChildProcess | null = null\n private publicUrl = ''\n private options: Record<string, unknown>\n\n constructor(options: Record<string, unknown> = {}) {\n this.options = options\n }\n\n async start(localPort: number): Promise<string> {\n const args = ['http', String(localPort), '--log', 'stdout', '--log-format', 'json']\n if (this.options.authtoken) {\n args.push('--authtoken', String(this.options.authtoken))\n }\n if (this.options.domain) {\n args.push('--domain', String(this.options.domain))\n }\n if (this.options.region) {\n args.push('--region', String(this.options.region))\n }\n\n return new Promise<string>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.stop()\n reject(new Error('ngrok tunnel timed out after 30s. Is ngrok installed?'))\n }, 30_000)\n\n try {\n this.child = spawn('ngrok', args, { stdio: ['ignore', 'pipe', 'pipe'] })\n } catch {\n clearTimeout(timeout)\n reject(new Error(\n 'Failed to start ngrok. Install it from https://ngrok.com/download'\n ))\n return\n }\n\n const urlPattern = /https:\\/\\/[a-zA-Z0-9-]+\\.ngrok(-free)?\\.app/\n\n const onData = (data: Buffer) => {\n const line = data.toString()\n log.debug(line.trim())\n const match = line.match(urlPattern)\n if (match) {\n clearTimeout(timeout)\n this.publicUrl = match[0]\n log.info({ url: this.publicUrl }, 'ngrok tunnel ready')\n resolve(this.publicUrl)\n }\n }\n\n this.child.stdout?.on('data', onData)\n this.child.stderr?.on('data', onData)\n\n this.child.on('error', (err) => {\n clearTimeout(timeout)\n reject(new Error(\n `ngrok failed to start: ${err.message}. Install it from https://ngrok.com/download`\n ))\n })\n\n this.child.on('exit', (code) => {\n if (!this.publicUrl) {\n clearTimeout(timeout)\n reject(new Error(`ngrok exited with code ${code} before establishing tunnel`))\n }\n })\n })\n }\n\n async stop(): Promise<void> {\n if (this.child) {\n this.child.kill('SIGTERM')\n this.child = null\n log.info('ngrok tunnel stopped')\n }\n }\n\n getPublicUrl(): string {\n return this.publicUrl\n }\n}\n","import { spawn, type ChildProcess } from 'node:child_process'\nimport { createChildLogger } from '../../../core/utils/log.js'\nimport type { TunnelProvider } from '../provider.js'\n\nconst log = createChildLogger({ module: 'bore-tunnel' })\n\nexport class BoreTunnelProvider implements TunnelProvider {\n private child: ChildProcess | null = null\n private publicUrl = ''\n private options: Record<string, unknown>\n\n constructor(options: Record<string, unknown> = {}) {\n this.options = options\n }\n\n async start(localPort: number): Promise<string> {\n const server = String(this.options.server || 'bore.pub')\n const args = ['local', String(localPort), '--to', server]\n if (this.options.port) {\n args.push('--port', String(this.options.port))\n }\n if (this.options.secret) {\n args.push('--secret', String(this.options.secret))\n }\n\n return new Promise<string>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.stop()\n reject(new Error('Bore tunnel timed out after 30s. Is bore installed?'))\n }, 30_000)\n\n try {\n this.child = spawn('bore', args, { stdio: ['ignore', 'pipe', 'pipe'] })\n } catch {\n clearTimeout(timeout)\n reject(new Error(\n 'Failed to start bore. Install it from https://github.com/ekzhang/bore'\n ))\n return\n }\n\n const urlPattern = /listening at ([^\\s]+):(\\d+)/\n\n const onData = (data: Buffer) => {\n const line = data.toString()\n log.debug(line.trim())\n const match = line.match(urlPattern)\n if (match) {\n clearTimeout(timeout)\n this.publicUrl = `http://${match[1]}:${match[2]}`\n log.info({ url: this.publicUrl }, 'Bore tunnel ready')\n resolve(this.publicUrl)\n }\n }\n\n this.child.stdout?.on('data', onData)\n this.child.stderr?.on('data', onData)\n\n this.child.on('error', (err) => {\n clearTimeout(timeout)\n reject(new Error(\n `bore failed to start: ${err.message}. Install it from https://github.com/ekzhang/bore`\n ))\n })\n\n this.child.on('exit', (code) => {\n if (!this.publicUrl) {\n clearTimeout(timeout)\n reject(new Error(`bore exited with code ${code} before establishing tunnel`))\n }\n })\n })\n }\n\n async stop(): Promise<void> {\n if (this.child) {\n this.child.kill('SIGTERM')\n this.child = null\n log.info('Bore tunnel stopped')\n }\n }\n\n getPublicUrl(): string {\n return this.publicUrl\n }\n}\n","import { spawn, execSync, type ChildProcess } from 'node:child_process'\nimport { createChildLogger } from '../../../core/utils/log.js'\nimport type { TunnelProvider } from '../provider.js'\n\nconst log = createChildLogger({ module: 'tailscale-tunnel' })\n\nexport class TailscaleTunnelProvider implements TunnelProvider {\n private child: ChildProcess | null = null\n private publicUrl = ''\n private options: Record<string, unknown>\n\n constructor(options: Record<string, unknown> = {}) {\n this.options = options\n }\n\n async start(localPort: number): Promise<string> {\n let hostname = ''\n try {\n const statusJson = execSync('tailscale status --json', { encoding: 'utf-8' })\n const status = JSON.parse(statusJson)\n hostname = String(status.Self.DNSName).replace(/\\.$/, '')\n log.debug({ hostname }, 'Resolved Tailscale hostname')\n } catch (err) {\n log.warn('Failed to resolve Tailscale hostname via status --json')\n }\n\n const args = ['funnel', String(localPort)]\n if (this.options.bg) {\n args.push('--bg')\n }\n\n return new Promise<string>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.stop()\n reject(new Error('Tailscale funnel timed out after 30s. Is tailscale installed?'))\n }, 30_000)\n\n try {\n this.child = spawn('tailscale', args, { stdio: ['ignore', 'pipe', 'pipe'] })\n } catch {\n clearTimeout(timeout)\n reject(new Error(\n 'Failed to start tailscale. Install it from https://tailscale.com/download'\n ))\n return\n }\n\n const urlPattern = /https:\\/\\/[^\\s]+/\n\n const onData = (data: Buffer) => {\n const line = data.toString()\n log.debug(line.trim())\n const match = line.match(urlPattern)\n if (match) {\n clearTimeout(timeout)\n this.publicUrl = match[0]\n log.info({ url: this.publicUrl }, 'Tailscale funnel ready')\n resolve(this.publicUrl)\n }\n }\n\n this.child.stdout?.on('data', onData)\n this.child.stderr?.on('data', onData)\n\n this.child.on('error', (err) => {\n clearTimeout(timeout)\n reject(new Error(\n `tailscale failed to start: ${err.message}. Install it from https://tailscale.com/download`\n ))\n })\n\n this.child.on('exit', (code) => {\n if (!this.publicUrl) {\n clearTimeout(timeout)\n if (hostname) {\n this.publicUrl = `https://${hostname}`\n log.info({ url: this.publicUrl }, 'Tailscale funnel ready (constructed from hostname)')\n resolve(this.publicUrl)\n } else {\n reject(new Error(`tailscale exited with code ${code} before establishing funnel`))\n }\n }\n })\n })\n }\n\n async stop(): Promise<void> {\n if (this.child) {\n this.child.kill('SIGTERM')\n this.child = null\n log.info('Tailscale funnel stopped')\n }\n }\n\n getPublicUrl(): string {\n return this.publicUrl\n }\n}\n","import * as path from 'node:path'\nimport { nanoid } from 'nanoid'\nimport { createChildLogger } from '../../core/utils/log.js'\n\nconst log = createChildLogger({ module: 'viewer-store' })\n\nconst MAX_CONTENT_SIZE = 1_000_000 // 1MB\n\nconst EXTENSION_LANGUAGE: Record<string, string> = {\n '.ts': 'typescript', '.tsx': 'typescript', '.js': 'javascript', '.jsx': 'javascript',\n '.py': 'python', '.rs': 'rust', '.go': 'go', '.java': 'java', '.kt': 'kotlin',\n '.rb': 'ruby', '.php': 'php', '.c': 'c', '.cpp': 'cpp', '.h': 'c', '.hpp': 'cpp',\n '.cs': 'csharp', '.swift': 'swift', '.sh': 'bash', '.zsh': 'bash', '.bash': 'bash',\n '.json': 'json', '.yaml': 'yaml', '.yml': 'yaml', '.toml': 'toml',\n '.xml': 'xml', '.html': 'html', '.css': 'css', '.scss': 'scss',\n '.sql': 'sql', '.md': 'markdown', '.dockerfile': 'dockerfile',\n '.tf': 'hcl', '.vue': 'xml', '.svelte': 'xml',\n}\n\nexport interface ViewerEntry {\n id: string\n type: 'file' | 'diff'\n filePath?: string\n content: string\n oldContent?: string\n language?: string\n sessionId: string\n workingDirectory: string\n createdAt: number\n expiresAt: number\n}\n\nexport class ViewerStore {\n private entries = new Map<string, ViewerEntry>()\n private cleanupTimer: ReturnType<typeof setInterval>\n private ttlMs: number\n\n constructor(ttlMinutes: number = 60) {\n this.ttlMs = ttlMinutes * 60 * 1000\n this.cleanupTimer = setInterval(() => this.cleanup(), 5 * 60 * 1000)\n }\n\n storeFile(sessionId: string, filePath: string, content: string, workingDirectory: string): string | null {\n if (!this.isPathAllowed(filePath, workingDirectory)) {\n log.warn({ filePath, workingDirectory }, 'Path outside workspace, rejecting')\n return null\n }\n if (content.length > MAX_CONTENT_SIZE) {\n log.debug({ filePath, size: content.length }, 'File too large for viewer')\n return null\n }\n\n const id = nanoid(12)\n const now = Date.now()\n this.entries.set(id, {\n id,\n type: 'file',\n filePath,\n content,\n language: this.detectLanguage(filePath),\n sessionId,\n workingDirectory,\n createdAt: now,\n expiresAt: now + this.ttlMs,\n })\n log.debug({ id, filePath }, 'Stored file for viewing')\n return id\n }\n\n storeDiff(sessionId: string, filePath: string, oldContent: string, newContent: string, workingDirectory: string): string | null {\n if (!this.isPathAllowed(filePath, workingDirectory)) {\n log.warn({ filePath, workingDirectory }, 'Path outside workspace, rejecting')\n return null\n }\n const combined = oldContent.length + newContent.length\n if (combined > MAX_CONTENT_SIZE) {\n log.debug({ filePath, size: combined }, 'Diff content too large for viewer')\n return null\n }\n\n const id = nanoid(12)\n const now = Date.now()\n this.entries.set(id, {\n id,\n type: 'diff',\n filePath,\n content: newContent,\n oldContent,\n language: this.detectLanguage(filePath),\n sessionId,\n workingDirectory,\n createdAt: now,\n expiresAt: now + this.ttlMs,\n })\n log.debug({ id, filePath }, 'Stored diff for viewing')\n return id\n }\n\n get(id: string): ViewerEntry | undefined {\n const entry = this.entries.get(id)\n if (!entry) return undefined\n if (Date.now() > entry.expiresAt) {\n this.entries.delete(id)\n return undefined\n }\n return entry\n }\n\n private cleanup(): void {\n const now = Date.now()\n let removed = 0\n for (const [id, entry] of this.entries) {\n if (now > entry.expiresAt) {\n this.entries.delete(id)\n removed++\n }\n }\n if (removed > 0) {\n log.debug({ removed, remaining: this.entries.size }, 'Cleaned up expired viewer entries')\n }\n }\n\n private isPathAllowed(filePath: string, workingDirectory: string): boolean {\n const resolved = path.resolve(workingDirectory, filePath)\n return resolved.startsWith(path.resolve(workingDirectory))\n }\n\n private detectLanguage(filePath: string): string | undefined {\n const ext = path.extname(filePath).toLowerCase()\n return EXTENSION_LANGUAGE[ext]\n }\n\n destroy(): void {\n clearInterval(this.cleanupTimer)\n this.entries.clear()\n }\n}\n","import { Hono } from 'hono'\nimport type { ViewerStore } from './viewer-store.js'\nimport { renderFileViewer } from './templates/file-viewer.js'\nimport { renderDiffViewer } from './templates/diff-viewer.js'\n\nfunction notFoundPage(): string {\n return `<!DOCTYPE html>\n<html><head><meta charset=\"UTF-8\"><title>Not Found - OpenACP</title>\n<style>body{background:#0d1117;color:#c9d1d9;font-family:sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0}\n.box{text-align:center;padding:40px}.code{font-size:72px;font-weight:bold;color:#484f58}p{margin-top:16px;color:#8b949e}</style>\n</head><body><div class=\"box\"><div class=\"code\">404</div><p>This viewer link has expired or does not exist.</p></div></body></html>`\n}\n\nexport function createTunnelServer(store: ViewerStore, authToken?: string): Hono {\n const app = new Hono()\n\n // Auth middleware\n if (authToken) {\n app.use('*', async (c, next) => {\n if (c.req.path === '/health') return next()\n const bearer = c.req.header('Authorization')?.replace('Bearer ', '')\n const query = c.req.query('token')\n if (bearer !== authToken && query !== authToken) {\n return c.text('Unauthorized', 401)\n }\n return next()\n })\n }\n\n app.get('/health', (c) => c.json({ status: 'ok' }))\n\n app.get('/view/:id', (c) => {\n const entry = store.get(c.req.param('id'))\n if (!entry || entry.type !== 'file') {\n return c.html(notFoundPage(), 404)\n }\n return c.html(renderFileViewer(entry))\n })\n\n app.get('/diff/:id', (c) => {\n const entry = store.get(c.req.param('id'))\n if (!entry || entry.type !== 'diff') {\n return c.html(notFoundPage(), 404)\n }\n return c.html(renderDiffViewer(entry))\n })\n\n app.get('/api/file/:id', (c) => {\n const entry = store.get(c.req.param('id'))\n if (!entry || entry.type !== 'file') {\n return c.json({ error: 'not found' }, 404)\n }\n return c.json({ filePath: entry.filePath, content: entry.content, language: entry.language })\n })\n\n app.get('/api/diff/:id', (c) => {\n const entry = store.get(c.req.param('id'))\n if (!entry || entry.type !== 'diff') {\n return c.json({ error: 'not found' }, 404)\n }\n return c.json({ filePath: entry.filePath, oldContent: entry.oldContent, newContent: entry.content, language: entry.language })\n })\n\n return app\n}\n","import type { ViewerEntry } from '../viewer-store.js'\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n}\n\n// Map our language IDs to Monaco language IDs\nconst MONACO_LANGUAGE: Record<string, string> = {\n typescript: 'typescript', javascript: 'javascript', python: 'python',\n rust: 'rust', go: 'go', java: 'java', kotlin: 'kotlin', ruby: 'ruby',\n php: 'php', c: 'c', cpp: 'cpp', csharp: 'csharp', swift: 'swift',\n bash: 'shell', json: 'json', yaml: 'yaml', toml: 'ini', xml: 'xml',\n html: 'html', css: 'css', scss: 'scss', sql: 'sql', markdown: 'markdown',\n dockerfile: 'dockerfile', hcl: 'hcl', plaintext: 'plaintext',\n}\n\nfunction getMonacoLang(lang?: string): string {\n if (!lang) return 'plaintext'\n return MONACO_LANGUAGE[lang] || 'plaintext'\n}\n\nexport function renderFileViewer(entry: ViewerEntry): string {\n const fileName = entry.filePath || 'untitled'\n const lang = getMonacoLang(entry.language)\n // Escape </script> inside content to prevent premature tag closure\n const safeContent = JSON.stringify(entry.content).replace(/<\\//g, '<\\\\/')\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${escapeHtml(fileName)} - OpenACP</title>\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body { background: #1e1e1e; color: #d4d4d4; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; display: flex; flex-direction: column; height: 100vh; }\n .header { background: #252526; border-bottom: 1px solid #3c3c3c; padding: 8px 16px; display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; z-index: 10; }\n .file-info { display: flex; align-items: center; gap: 8px; font-size: 13px; min-width: 0; }\n .file-icon { font-size: 14px; flex-shrink: 0; }\n .file-path { color: #969696; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .file-name { color: #e0e0e0; font-weight: 500; flex-shrink: 0; }\n .actions { display: flex; gap: 6px; flex-shrink: 0; }\n .btn { background: #3c3c3c; color: #d4d4d4; border: 1px solid #505050; padding: 4px 10px; border-radius: 4px; cursor: pointer; font-size: 12px; transition: background 0.15s; }\n .btn:hover { background: #505050; }\n .btn.active { background: #0e639c; border-color: #1177bb; }\n #editor-container { flex: 1; overflow: hidden; }\n .status-bar { background: #007acc; color: #fff; padding: 2px 16px; font-size: 12px; display: flex; justify-content: space-between; flex-shrink: 0; }\n </style>\n</head>\n<body>\n <div class=\"header\">\n <div class=\"file-info\">\n <span class=\"file-icon\">📄</span>\n ${formatBreadcrumb(fileName)}\n </div>\n <div class=\"actions\">\n ${lang === 'markdown' ? '<button class=\"btn\" onclick=\"togglePreview()\" id=\"btn-preview\">Preview</button>' : ''}\n <button class=\"btn\" onclick=\"toggleWordWrap()\" id=\"btn-wrap\">Wrap</button>\n <button class=\"btn\" onclick=\"toggleMinimap()\" id=\"btn-minimap\">Minimap</button>\n <button class=\"btn\" onclick=\"toggleTheme()\" id=\"btn-theme\">Light</button>\n <button class=\"btn\" onclick=\"copyCode()\">Copy</button>\n </div>\n </div>\n <div id=\"editor-container\"></div>\n <div id=\"preview-wrapper\" style=\"display:none; flex:1; overflow-y:auto;\">\n <div id=\"preview-container\" style=\"padding:24px 48px; max-width:900px; margin:0 auto; width:100%;\"></div>\n </div>\n <div class=\"status-bar\">\n <span>${escapeHtml(entry.language || 'plaintext')} | ${entry.content.split('\\n').length} lines</span>\n <span>OpenACP Viewer (read-only)</span>\n </div>\n\n ${lang === 'markdown' ? '<script src=\"https://cdn.jsdelivr.net/npm/marked@15.0.0/marked.min.js\"></script>' : ''}\n <script src=\"https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs/loader.js\"></script>\n <script>\n const content = ${safeContent};\n const lang = ${JSON.stringify(lang)};\n let editor;\n let isDark = true;\n let wordWrap = false;\n let minimap = true;\n\n require.config({ paths: { vs: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs' } });\n require(['vs/editor/editor.main'], function () {\n editor = monaco.editor.create(document.getElementById('editor-container'), {\n value: content,\n language: lang,\n theme: 'vs-dark',\n readOnly: true,\n automaticLayout: true,\n minimap: { enabled: true },\n scrollBeyondLastLine: false,\n fontSize: 13,\n fontFamily: \"'SF Mono', SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace\",\n lineNumbers: 'on',\n renderLineHighlight: 'all',\n wordWrap: 'off',\n padding: { top: 8 },\n });\n\n // Handle line range from URL hash: #L42 or #L42-L55\n function highlightFromHash() {\n const hash = location.hash.slice(1);\n const match = hash.match(/^L(\\\\d+)(?:-L?(\\\\d+))?$/);\n if (!match) return;\n const startLine = parseInt(match[1], 10);\n const endLine = match[2] ? parseInt(match[2], 10) : startLine;\n editor.revealLineInCenter(startLine);\n editor.setSelection(new monaco.Selection(startLine, 1, endLine + 1, 1));\n }\n highlightFromHash();\n window.addEventListener('hashchange', highlightFromHash);\n });\n\n function toggleTheme() {\n isDark = !isDark;\n monaco.editor.setTheme(isDark ? 'vs-dark' : 'vs');\n document.body.style.background = isDark ? '#1e1e1e' : '#ffffff';\n document.querySelector('.header').style.background = isDark ? '#252526' : '#f3f3f3';\n document.querySelector('.header').style.borderColor = isDark ? '#3c3c3c' : '#e0e0e0';\n document.getElementById('btn-theme').textContent = isDark ? 'Light' : 'Dark';\n }\n\n function toggleWordWrap() {\n wordWrap = !wordWrap;\n editor.updateOptions({ wordWrap: wordWrap ? 'on' : 'off' });\n document.getElementById('btn-wrap').classList.toggle('active', wordWrap);\n }\n\n function toggleMinimap() {\n minimap = !minimap;\n editor.updateOptions({ minimap: { enabled: minimap } });\n document.getElementById('btn-minimap').classList.toggle('active', !minimap);\n }\n\n function copyCode() {\n navigator.clipboard.writeText(content).then(() => {\n const btn = event.target;\n btn.textContent = 'Copied!';\n setTimeout(() => btn.textContent = 'Copy', 2000);\n });\n }\n\n let previewMode = false;\n function togglePreview() {\n previewMode = !previewMode;\n const editorEl = document.getElementById('editor-container');\n const wrapperEl = document.getElementById('preview-wrapper');\n const previewEl = document.getElementById('preview-container');\n const btn = document.getElementById('btn-preview');\n if (previewMode) {\n editorEl.style.display = 'none';\n wrapperEl.style.display = 'block';\n previewEl.innerHTML = typeof marked !== 'undefined' ? marked.parse(content) : content.replace(/\\\\n/g, '<br>');\n previewEl.style.color = isDark ? '#d4d4d4' : '#1e1e1e';\n wrapperEl.style.background = isDark ? '#1e1e1e' : '#ffffff';\n btn.classList.add('active');\n btn.textContent = 'Editor';\n } else {\n editorEl.style.display = 'block';\n wrapperEl.style.display = 'none';\n btn.classList.remove('active');\n btn.textContent = 'Preview';\n }\n }\n </script>\n <style>\n #preview-container { font-size: 15px; line-height: 1.7; }\n #preview-container h1 { font-size: 2em; margin: 0.5em 0 0.3em; border-bottom: 1px solid #3c3c3c; padding-bottom: 0.3em; }\n #preview-container h2 { font-size: 1.5em; margin: 0.5em 0 0.3em; border-bottom: 1px solid #3c3c3c; padding-bottom: 0.2em; }\n #preview-container h3 { font-size: 1.25em; margin: 0.4em 0 0.2em; }\n #preview-container p { margin: 0.5em 0; }\n #preview-container code { background: rgba(128,128,128,0.2); padding: 2px 6px; border-radius: 3px; font-size: 0.9em; }\n #preview-container pre { background: rgba(0,0,0,0.3); padding: 16px; border-radius: 6px; overflow-x: auto; margin: 0.5em 0; }\n #preview-container pre code { background: none; padding: 0; }\n #preview-container blockquote { border-left: 3px solid #505050; padding-left: 16px; margin: 0.5em 0; color: #969696; }\n #preview-container ul, #preview-container ol { padding-left: 24px; margin: 0.5em 0; }\n #preview-container table { border-collapse: collapse; margin: 0.5em 0; width: 100%; }\n #preview-container th, #preview-container td { border: 1px solid #3c3c3c; padding: 6px 12px; text-align: left; }\n #preview-container th { background: rgba(128,128,128,0.15); }\n #preview-container a { color: #3794ff; }\n #preview-container img { max-width: 100%; }\n </style>\n</body>\n</html>`\n}\n\nfunction formatBreadcrumb(filePath: string): string {\n const parts = filePath.split('/')\n if (parts.length <= 1) return `<span class=\"file-name\">${escapeHtml(filePath)}</span>`\n const dir = parts.slice(0, -1).join(' / ')\n const name = parts[parts.length - 1]\n return `<span class=\"file-path\">${escapeHtml(dir)} /</span> <span class=\"file-name\">${escapeHtml(name)}</span>`\n}\n","import { createPatch } from 'diff'\nimport type { ViewerEntry } from '../viewer-store.js'\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n}\n\nconst MONACO_LANGUAGE: Record<string, string> = {\n typescript: 'typescript', javascript: 'javascript', python: 'python',\n rust: 'rust', go: 'go', java: 'java', kotlin: 'kotlin', ruby: 'ruby',\n php: 'php', c: 'c', cpp: 'cpp', csharp: 'csharp', swift: 'swift',\n bash: 'shell', json: 'json', yaml: 'yaml', toml: 'ini', xml: 'xml',\n html: 'html', css: 'css', scss: 'scss', sql: 'sql', markdown: 'markdown',\n dockerfile: 'dockerfile', hcl: 'hcl', plaintext: 'plaintext',\n}\n\nfunction getMonacoLang(lang?: string): string {\n if (!lang) return 'plaintext'\n return MONACO_LANGUAGE[lang] || 'plaintext'\n}\n\nexport function renderDiffViewer(entry: ViewerEntry): string {\n const fileName = entry.filePath || 'untitled'\n const lang = getMonacoLang(entry.language)\n const oldContent = entry.oldContent || ''\n const newContent = entry.content\n\n // Count changes for stats\n const patch = createPatch(fileName, oldContent, newContent, 'before', 'after')\n const adds = (patch.match(/^\\+[^+]/gm) || []).length\n const dels = (patch.match(/^-[^-]/gm) || []).length\n\n // Escape </script> in content\n const safeOld = JSON.stringify(oldContent).replace(/<\\//g, '<\\\\/')\n const safeNew = JSON.stringify(newContent).replace(/<\\//g, '<\\\\/')\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${escapeHtml(fileName)} (diff) - OpenACP</title>\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body { background: #1e1e1e; color: #d4d4d4; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; display: flex; flex-direction: column; height: 100vh; }\n .header { background: #252526; border-bottom: 1px solid #3c3c3c; padding: 8px 16px; display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; z-index: 10; }\n .file-info { display: flex; align-items: center; gap: 8px; font-size: 13px; }\n .file-icon { font-size: 14px; }\n .file-name { color: #e0e0e0; font-weight: 500; }\n .stats { font-size: 12px; margin-left: 12px; }\n .stats .add { color: #4ec9b0; }\n .stats .del { color: #f14c4c; }\n .actions { display: flex; gap: 6px; }\n .btn { background: #3c3c3c; color: #d4d4d4; border: 1px solid #505050; padding: 4px 10px; border-radius: 4px; cursor: pointer; font-size: 12px; transition: background 0.15s; }\n .btn:hover { background: #505050; }\n .btn.active { background: #0e639c; border-color: #1177bb; }\n #editor-container { flex: 1; overflow: hidden; }\n .status-bar { background: #007acc; color: #fff; padding: 2px 16px; font-size: 12px; display: flex; justify-content: space-between; flex-shrink: 0; }\n </style>\n</head>\n<body>\n <div class=\"header\">\n <div class=\"file-info\">\n <span class=\"file-icon\">📝</span>\n <span class=\"file-name\">${escapeHtml(fileName)}</span>\n <span class=\"stats\"><span class=\"add\">+${adds}</span> / <span class=\"del\">-${dels}</span></span>\n </div>\n <div class=\"actions\">\n <button class=\"btn active\" id=\"btn-side\" onclick=\"setView('side')\">Side by Side</button>\n <button class=\"btn\" id=\"btn-inline\" onclick=\"setView('inline')\">Inline</button>\n <button class=\"btn\" onclick=\"toggleTheme()\" id=\"btn-theme\">Light</button>\n </div>\n </div>\n <div id=\"editor-container\"></div>\n <div class=\"status-bar\">\n <span>${escapeHtml(entry.language || 'plaintext')} | <span class=\"add\">+${adds}</span> <span class=\"del\">-${dels}</span></span>\n <span>OpenACP Diff Viewer</span>\n </div>\n\n <script src=\"https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs/loader.js\"></script>\n <script>\n const oldContent = ${safeOld};\n const newContent = ${safeNew};\n const lang = ${JSON.stringify(lang)};\n let diffEditor;\n let isDark = true;\n let renderSideBySide = true;\n\n require.config({ paths: { vs: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs' } });\n require(['vs/editor/editor.main'], function () {\n const originalModel = monaco.editor.createModel(oldContent, lang);\n const modifiedModel = monaco.editor.createModel(newContent, lang);\n\n diffEditor = monaco.editor.createDiffEditor(document.getElementById('editor-container'), {\n theme: 'vs-dark',\n readOnly: true,\n automaticLayout: true,\n renderSideBySide: true,\n scrollBeyondLastLine: false,\n fontSize: 13,\n fontFamily: \"'SF Mono', SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace\",\n padding: { top: 8 },\n enableSplitViewResizing: true,\n renderOverviewRuler: true,\n });\n\n diffEditor.setModel({ original: originalModel, modified: modifiedModel });\n });\n\n function setView(mode) {\n renderSideBySide = mode === 'side';\n diffEditor.updateOptions({ renderSideBySide });\n document.getElementById('btn-side').classList.toggle('active', renderSideBySide);\n document.getElementById('btn-inline').classList.toggle('active', !renderSideBySide);\n }\n\n function toggleTheme() {\n isDark = !isDark;\n monaco.editor.setTheme(isDark ? 'vs-dark' : 'vs');\n document.body.style.background = isDark ? '#1e1e1e' : '#ffffff';\n document.querySelector('.header').style.background = isDark ? '#252526' : '#f3f3f3';\n document.querySelector('.header').style.borderColor = isDark ? '#3c3c3c' : '#e0e0e0';\n document.getElementById('btn-theme').textContent = isDark ? 'Light' : 'Dark';\n }\n </script>\n</body>\n</html>`\n}\n"],"mappings":"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","names":["fs","path","os","resolve","spawn","log","resolve","spawn","spawn","log","resolve","spawn","spawn","log","resolve","spawn","log","path","os","fs","path","log","escapeHtml","MONACO_LANGUAGE","getMonacoLang","log","resolve"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|