@openacp/cli 2026.330.2 → 2026.331.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 +17 -0
- package/dist/adapter-ELG3VRZ3.js +14 -0
- package/dist/{agent-catalog-SZQQERV7.js → agent-catalog-UYD26QDK.js} +3 -3
- package/dist/{api-client-XTLRRFPX.js → api-client-PEMHYL5U.js} +2 -2
- package/dist/{api-server-JLBDKCU4.js → api-server-DATG2KBR.js} +3 -3
- package/dist/api-server-L5Z7XACW.js +7 -0
- package/dist/chunk-23SRIVG4.js +50 -0
- package/dist/chunk-23SRIVG4.js.map +1 -0
- package/dist/{chunk-YIGBJFJL.js → chunk-7GXEMMEV.js} +15 -15
- package/dist/{chunk-QWVHCTCA.js → chunk-7U6IZIJP.js} +37 -23
- package/dist/chunk-7U6IZIJP.js.map +1 -0
- package/dist/{chunk-FCTC7KDT.js → chunk-7YIKTRSM.js} +14 -10
- package/dist/chunk-7YIKTRSM.js.map +1 -0
- package/dist/{chunk-MITTQMGZ.js → chunk-BYCJQPMN.js} +5 -5
- package/dist/chunk-BYCJQPMN.js.map +1 -0
- package/dist/{chunk-5ZNBNIK3.js → chunk-EWVXSTQK.js} +193 -53
- package/dist/chunk-EWVXSTQK.js.map +1 -0
- package/dist/{chunk-UWH7KIAA.js → chunk-FPKQYCQS.js} +88 -13
- package/dist/chunk-FPKQYCQS.js.map +1 -0
- package/dist/{chunk-GEOXPGCO.js → chunk-K6UY5M75.js} +12 -9
- package/dist/chunk-K6UY5M75.js.map +1 -0
- package/dist/{chunk-KDU3ZEWT.js → chunk-KGAQW6F4.js} +12 -3
- package/dist/chunk-KGAQW6F4.js.map +1 -0
- package/dist/{chunk-7RKPIM3E.js → chunk-LRV56K2M.js} +205 -16
- package/dist/chunk-LRV56K2M.js.map +1 -0
- package/dist/{chunk-V2YZWYXT.js → chunk-MDJHCCFS.js} +18 -17
- package/dist/chunk-MDJHCCFS.js.map +1 -0
- package/dist/chunk-NHD5XDD2.js +686 -0
- package/dist/chunk-NHD5XDD2.js.map +1 -0
- package/dist/{chunk-APS6UEFU.js → chunk-NJX75BLK.js} +1 -1
- package/dist/chunk-NJX75BLK.js.map +1 -0
- package/dist/{chunk-5HKQCYOI.js → chunk-NOEAJNTK.js} +14 -3
- package/dist/chunk-NOEAJNTK.js.map +1 -0
- package/dist/chunk-ON7HB5O7.js +58 -0
- package/dist/chunk-ON7HB5O7.js.map +1 -0
- package/dist/{chunk-5OCGO27U.js → chunk-OSBZXY2W.js} +2 -1
- package/dist/chunk-OSBZXY2W.js.map +1 -0
- package/dist/{chunk-PA6MNBG4.js → chunk-P3HHJANC.js} +32 -13
- package/dist/chunk-P3HHJANC.js.map +1 -0
- package/dist/{chunk-BTJHGSLM.js → chunk-R2YLDQLI.js} +9 -10
- package/dist/chunk-R2YLDQLI.js.map +1 -0
- package/dist/{chunk-CFUJGWOP.js → chunk-SSLVNCEA.js} +27 -3
- package/dist/chunk-SSLVNCEA.js.map +1 -0
- package/dist/{chunk-MPGEHTGE.js → chunk-TGP34LQN.js} +9 -7
- package/dist/chunk-TGP34LQN.js.map +1 -0
- package/dist/{chunk-TMVTSWVH.js → chunk-VUSCVRJL.js} +2 -1
- package/dist/chunk-VUSCVRJL.js.map +1 -0
- package/dist/chunk-XRJUS6FE.js +53 -0
- package/dist/chunk-XRJUS6FE.js.map +1 -0
- package/dist/{chunk-W4LK6WJP.js → chunk-YZCKSNRN.js} +24 -17
- package/dist/chunk-YZCKSNRN.js.map +1 -0
- package/dist/{chunk-3NAFXVQM.js → chunk-ZIRH6QWW.js} +7 -5
- package/dist/chunk-ZIRH6QWW.js.map +1 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.js +334 -140
- package/dist/cli.js.map +1 -1
- package/dist/config-X4UP7H6R.js +13 -0
- package/dist/config-editor-7BENRVG5.js +11 -0
- package/dist/{config-registry-ZXAIJNYB.js → config-registry-M3FFWEVM.js} +3 -2
- package/dist/context-FVGCU5TI.js +9 -0
- package/dist/core-plugins-JSY2I44L.js +25 -0
- package/dist/{daemon-XFEMMJSZ.js → daemon-UOSRDEXW.js} +8 -3
- package/dist/doctor-6DLACBR4.js +10 -0
- package/dist/{file-service-HHB3JQIO.js → file-service-FQQYME7M.js} +2 -2
- package/dist/index.d.ts +265 -32
- package/dist/index.js +44 -33
- package/dist/index.js.map +1 -1
- package/dist/{install-cloudflared-JRJ4BSOM.js → install-cloudflared-LNS5L5FR.js} +5 -4
- package/dist/install-cloudflared-LNS5L5FR.js.map +1 -0
- package/dist/{install-context-EHYV5WRY.js → install-context-KZO5FR4D.js} +4 -3
- package/dist/install-context-KZO5FR4D.js.map +1 -0
- package/dist/{install-jq-ISTGT263.js → install-jq-SN4IA5K4.js} +3 -3
- package/dist/instance-context-FLCE7VZ4.js +13 -0
- package/dist/instance-registry-SW5FWKHO.js +7 -0
- package/dist/{main-L2M4NTJY.js → main-D7M2AKRM.js} +91 -48
- package/dist/main-D7M2AKRM.js.map +1 -0
- package/dist/{plugin-create-EHL76ZZG.js → plugin-create-HFKS23JY.js} +4 -2
- package/dist/{plugin-create-EHL76ZZG.js.map → plugin-create-HFKS23JY.js.map} +1 -1
- package/dist/{post-upgrade-Y26S2ZQ7.js → post-upgrade-F4YPMTUT.js} +6 -6
- package/dist/{security-2BA265LN.js → security-O4XGN2CM.js} +2 -2
- package/dist/{setup-E6BNEYCS.js → setup-44WLBIOT.js} +209 -22
- package/dist/setup-44WLBIOT.js.map +1 -0
- package/dist/{speech-SG62JYIF.js → speech-GHTSWDAN.js} +2 -2
- package/dist/telegram-D7ASLVEB.js +7 -0
- package/dist/telegram-D7ASLVEB.js.map +1 -0
- package/dist/tunnel-ALJDPFDQ.js +10 -0
- package/dist/tunnel-ALJDPFDQ.js.map +1 -0
- package/dist/{tunnel-service-ZMO4THKE.js → tunnel-service-TBAHDXMF.js} +41 -547
- package/dist/tunnel-service-TBAHDXMF.js.map +1 -0
- package/package.json +1 -1
- package/dist/adapter-4U6MC5ZS.js +0 -13
- package/dist/api-server-5VNYFWJE.js +0 -7
- package/dist/chunk-3NAFXVQM.js.map +0 -1
- package/dist/chunk-4WXALZA3.js +0 -45
- package/dist/chunk-4WXALZA3.js.map +0 -1
- package/dist/chunk-5HKQCYOI.js.map +0 -1
- package/dist/chunk-5OCGO27U.js.map +0 -1
- package/dist/chunk-5ZNBNIK3.js.map +0 -1
- package/dist/chunk-7RKPIM3E.js.map +0 -1
- package/dist/chunk-APS6UEFU.js.map +0 -1
- package/dist/chunk-BTJHGSLM.js.map +0 -1
- package/dist/chunk-CFUJGWOP.js.map +0 -1
- package/dist/chunk-FCTC7KDT.js.map +0 -1
- package/dist/chunk-GEOXPGCO.js.map +0 -1
- package/dist/chunk-KDU3ZEWT.js.map +0 -1
- package/dist/chunk-MITTQMGZ.js.map +0 -1
- package/dist/chunk-MPGEHTGE.js.map +0 -1
- package/dist/chunk-PA6MNBG4.js.map +0 -1
- package/dist/chunk-QWVHCTCA.js.map +0 -1
- package/dist/chunk-TMVTSWVH.js.map +0 -1
- package/dist/chunk-UWH7KIAA.js.map +0 -1
- package/dist/chunk-V2YZWYXT.js.map +0 -1
- package/dist/chunk-W4LK6WJP.js.map +0 -1
- package/dist/config-KN6NKKPF.js +0 -20
- package/dist/config-editor-76RVZS4B.js +0 -10
- package/dist/context-NXXW62NJ.js +0 -9
- package/dist/core-plugins-OCHKGCIZ.js +0 -22
- package/dist/doctor-AV6AUO22.js +0 -9
- package/dist/install-cloudflared-JRJ4BSOM.js.map +0 -1
- package/dist/install-context-EHYV5WRY.js.map +0 -1
- package/dist/main-L2M4NTJY.js.map +0 -1
- package/dist/setup-E6BNEYCS.js.map +0 -1
- package/dist/telegram-EAVRDNFU.js +0 -7
- package/dist/tunnel-HWJ27WDH.js +0 -7
- package/dist/tunnel-service-ZMO4THKE.js.map +0 -1
- /package/dist/{adapter-4U6MC5ZS.js.map → adapter-ELG3VRZ3.js.map} +0 -0
- /package/dist/{agent-catalog-SZQQERV7.js.map → agent-catalog-UYD26QDK.js.map} +0 -0
- /package/dist/{api-client-XTLRRFPX.js.map → api-client-PEMHYL5U.js.map} +0 -0
- /package/dist/{api-server-5VNYFWJE.js.map → api-server-DATG2KBR.js.map} +0 -0
- /package/dist/{api-server-JLBDKCU4.js.map → api-server-L5Z7XACW.js.map} +0 -0
- /package/dist/{chunk-YIGBJFJL.js.map → chunk-7GXEMMEV.js.map} +0 -0
- /package/dist/{config-KN6NKKPF.js.map → config-X4UP7H6R.js.map} +0 -0
- /package/dist/{config-editor-76RVZS4B.js.map → config-editor-7BENRVG5.js.map} +0 -0
- /package/dist/{config-registry-ZXAIJNYB.js.map → config-registry-M3FFWEVM.js.map} +0 -0
- /package/dist/{context-NXXW62NJ.js.map → context-FVGCU5TI.js.map} +0 -0
- /package/dist/{core-plugins-OCHKGCIZ.js.map → core-plugins-JSY2I44L.js.map} +0 -0
- /package/dist/{daemon-XFEMMJSZ.js.map → daemon-UOSRDEXW.js.map} +0 -0
- /package/dist/{doctor-AV6AUO22.js.map → doctor-6DLACBR4.js.map} +0 -0
- /package/dist/{file-service-HHB3JQIO.js.map → file-service-FQQYME7M.js.map} +0 -0
- /package/dist/{install-jq-ISTGT263.js.map → install-jq-SN4IA5K4.js.map} +0 -0
- /package/dist/{security-2BA265LN.js.map → instance-context-FLCE7VZ4.js.map} +0 -0
- /package/dist/{speech-SG62JYIF.js.map → instance-registry-SW5FWKHO.js.map} +0 -0
- /package/dist/{post-upgrade-Y26S2ZQ7.js.map → post-upgrade-F4YPMTUT.js.map} +0 -0
- /package/dist/{telegram-EAVRDNFU.js.map → security-O4XGN2CM.js.map} +0 -0
- /package/dist/{tunnel-HWJ27WDH.js.map → speech-GHTSWDAN.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/plugins/tunnel/tunnel-service.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","../../src/plugins/tunnel/templates/output-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 private startError: string | undefined\n\n constructor(config: TunnelConfig, registryPath?: string) {\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 registryPath,\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 result = await new Promise<{ ok: boolean; code?: string }>((resolve) => {\n server.on('listening', () => resolve({ ok: true }))\n server.on('error', (err: NodeJS.ErrnoException) => resolve({ ok: false, code: err.code }))\n })\n\n if (result.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 // EACCES = permission denied — retrying other ports won't help\n if (result.code === 'EACCES') {\n log.error({ port }, 'Permission denied binding to port (try a port > 1024)')\n break\n }\n }\n\n if (!this.server) {\n log.error({ port: this.config.port }, 'Failed to start tunnel HTTP server — no available port')\n this.startError = `HTTP server failed to bind (tried ports ${this.config.port}-${this.config.port + maxRetries - 1})`\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 this.startError = (err as Error).message\n log.warn({ err: this.startError }, '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 getStartError(): string | undefined {\n return this.startError\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 outputUrl(entryId: string): string {\n return `${this.getPublicUrl()}/output/${entryId}`\n }\n}\n","import * as fs from 'node:fs'\nimport * 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' | 'output'\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 storeOutput(sessionId: string, label: string, output: string): string | null {\n if (output.length > MAX_CONTENT_SIZE) {\n log.debug({ label, size: output.length }, 'Output too large for viewer')\n return null\n }\n const id = nanoid(12)\n const now = Date.now()\n this.entries.set(id, {\n id,\n type: 'output',\n filePath: label,\n content: output,\n language: 'text',\n sessionId,\n workingDirectory: '',\n createdAt: now,\n expiresAt: now + this.ttlMs,\n })\n log.debug({ id, label }, 'Stored output 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 caseInsensitive = process.platform === 'darwin' || process.platform === 'win32'\n\n // Resolve paths, using realpathSync when possible for symlink/case canonicalization\n let resolved: string\n let workspace: string\n try { resolved = fs.realpathSync(path.resolve(workingDirectory, filePath)) }\n catch { resolved = path.resolve(workingDirectory, filePath) }\n try { workspace = fs.realpathSync(path.resolve(workingDirectory)) }\n catch { workspace = path.resolve(workingDirectory) }\n\n // macOS/Windows have case-insensitive filesystems — always compare lowercase\n if (caseInsensitive) {\n const rLower = resolved.toLowerCase()\n const wLower = workspace.toLowerCase()\n return rLower.startsWith(wLower + path.sep) || rLower === wLower\n }\n return resolved.startsWith(workspace + path.sep) || resolved === workspace\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'\nimport { renderOutputViewer } from './templates/output-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('/output/:id', (c) => {\n const entry = store.get(c.req.param('id'))\n if (!entry || entry.type !== 'output') {\n return c.html(notFoundPage(), 404)\n }\n return c.html(renderOutputViewer(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","import type { ViewerEntry } from '../viewer-store.js'\n\nexport function renderOutputViewer(entry: ViewerEntry): string {\n const label = entry.filePath ?? 'Output'\n const lines = entry.content.split('\\n')\n const lineNumbers = lines\n .map((line, i) => {\n const num = String(i + 1).padStart(String(lines.length).length, ' ')\n return `<span class=\"line-num\">${num}</span><span class=\"line-content\">${escapeHtml(line)}</span>`\n })\n .join('\\n')\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(label)} — OpenACP</title>\n<style>\n body { background: #0d1117; color: #c9d1d9; font-family: 'JetBrains Mono', 'Fira Code', monospace; font-size: 13px; margin: 0; padding: 0; }\n header { background: #161b22; border-bottom: 1px solid #30363d; padding: 12px 20px; position: sticky; top: 0; z-index: 10; }\n header h1 { margin: 0; font-size: 14px; color: #e6edf3; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .content { padding: 16px 20px; }\n pre { margin: 0; line-height: 1.6; white-space: pre; overflow-x: auto; }\n .line-num { color: #484f58; user-select: none; margin-right: 16px; display: inline-block; min-width: 3ch; text-align: right; }\n .line-content { color: #c9d1d9; }\n</style>\n</head>\n<body>\n<header><h1>📋 ${escapeHtml(label)}</h1></header>\n<div class=\"content\"><pre>${lineNumbers}</pre></div>\n</body>\n</html>`\n}\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n}\n"],"mappings":"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","names":["escapeHtml","MONACO_LANGUAGE","getMonacoLang","escapeHtml","log","resolve"]}
|
package/package.json
CHANGED
package/dist/adapter-4U6MC5ZS.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
TelegramAdapter
|
|
3
|
-
} from "./chunk-5ZNBNIK3.js";
|
|
4
|
-
import "./chunk-AFKX424Q.js";
|
|
5
|
-
import "./chunk-GEOXPGCO.js";
|
|
6
|
-
import "./chunk-APS6UEFU.js";
|
|
7
|
-
import "./chunk-5HKQCYOI.js";
|
|
8
|
-
import "./chunk-W4LK6WJP.js";
|
|
9
|
-
import "./chunk-R6KZYF7D.js";
|
|
10
|
-
export {
|
|
11
|
-
TelegramAdapter
|
|
12
|
-
};
|
|
13
|
-
//# sourceMappingURL=adapter-4U6MC5ZS.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/plugins/file-service/index.ts"],"sourcesContent":["import type { OpenACPPlugin, InstallContext } from '../../core/plugin/types.js'\nimport { FileService } from './file-service.js'\nimport path from 'node:path'\nimport os from 'node:os'\n\nfunction createFileServicePlugin(): OpenACPPlugin {\n return {\n name: '@openacp/file-service',\n version: '1.0.0',\n description: 'File storage and management for session attachments',\n essential: false,\n permissions: ['services:register'],\n\n async install(ctx: InstallContext) {\n const { settings, legacyConfig, terminal } = ctx\n\n // Migrate from legacy config if present\n if (legacyConfig) {\n const filesCfg = legacyConfig.files as Record<string, unknown> | undefined\n if (filesCfg) {\n await settings.setAll({\n baseDir: filesCfg.baseDir ?? path.join(os.homedir(), '.openacp', 'files'),\n })\n terminal.log.success('File service settings migrated from legacy config')\n return\n }\n }\n\n // Save defaults\n await settings.setAll({\n baseDir: path.join(os.homedir(), '.openacp', 'files'),\n })\n terminal.log.success('File service defaults saved')\n },\n\n async configure(ctx: InstallContext) {\n const { terminal, settings } = ctx\n const current = await settings.getAll()\n\n const val = await terminal.text({\n message: 'File storage directory:',\n defaultValue: (current.baseDir as string) ?? path.join(os.homedir(), '.openacp', 'files'),\n })\n await settings.set('baseDir', val.trim())\n terminal.log.success('File storage directory updated')\n },\n\n async uninstall(ctx: InstallContext, opts: { purge: boolean }) {\n if (opts.purge) {\n await ctx.settings.clear()\n ctx.terminal.log.success('File service settings cleared')\n }\n },\n\n async setup(ctx) {\n const config = ctx.pluginConfig as Record<string, unknown>\n const baseDir = (config.baseDir as string) ?? path.join(os.homedir(), '.openacp', 'files')\n const retentionDays = (config.retentionDays as number) ?? 30\n const service = new FileService(baseDir)\n ctx.registerService('file-service', service)\n // Cleanup old session files in background (fire-and-forget)\n service.cleanupOldFiles(retentionDays).then((count) => {\n if (count > 0) ctx.log.info(`Cleaned up ${count} old session files`)\n }).catch(() => {})\n ctx.log.info('File service ready')\n },\n }\n}\n\nexport default createFileServicePlugin()\n"],"mappings":";;;;;AAEA,OAAO,UAAU;AACjB,OAAO,QAAQ;AAEf,SAAS,0BAAyC;AAChD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,IACb,WAAW;AAAA,IACX,aAAa,CAAC,mBAAmB;AAAA,IAEjC,MAAM,QAAQ,KAAqB;AACjC,YAAM,EAAE,UAAU,cAAc,SAAS,IAAI;AAG7C,UAAI,cAAc;AAChB,cAAM,WAAW,aAAa;AAC9B,YAAI,UAAU;AACZ,gBAAM,SAAS,OAAO;AAAA,YACpB,SAAS,SAAS,WAAW,KAAK,KAAK,GAAG,QAAQ,GAAG,YAAY,OAAO;AAAA,UAC1E,CAAC;AACD,mBAAS,IAAI,QAAQ,mDAAmD;AACxE;AAAA,QACF;AAAA,MACF;AAGA,YAAM,SAAS,OAAO;AAAA,QACpB,SAAS,KAAK,KAAK,GAAG,QAAQ,GAAG,YAAY,OAAO;AAAA,MACtD,CAAC;AACD,eAAS,IAAI,QAAQ,6BAA6B;AAAA,IACpD;AAAA,IAEA,MAAM,UAAU,KAAqB;AACnC,YAAM,EAAE,UAAU,SAAS,IAAI;AAC/B,YAAM,UAAU,MAAM,SAAS,OAAO;AAEtC,YAAM,MAAM,MAAM,SAAS,KAAK;AAAA,QAC9B,SAAS;AAAA,QACT,cAAe,QAAQ,WAAsB,KAAK,KAAK,GAAG,QAAQ,GAAG,YAAY,OAAO;AAAA,MAC1F,CAAC;AACD,YAAM,SAAS,IAAI,WAAW,IAAI,KAAK,CAAC;AACxC,eAAS,IAAI,QAAQ,gCAAgC;AAAA,IACvD;AAAA,IAEA,MAAM,UAAU,KAAqB,MAA0B;AAC7D,UAAI,KAAK,OAAO;AACd,cAAM,IAAI,SAAS,MAAM;AACzB,YAAI,SAAS,IAAI,QAAQ,+BAA+B;AAAA,MAC1D;AAAA,IACF;AAAA,IAEA,MAAM,MAAM,KAAK;AACf,YAAM,SAAS,IAAI;AACnB,YAAM,UAAW,OAAO,WAAsB,KAAK,KAAK,GAAG,QAAQ,GAAG,YAAY,OAAO;AACzF,YAAM,gBAAiB,OAAO,iBAA4B;AAC1D,YAAM,UAAU,IAAI,YAAY,OAAO;AACvC,UAAI,gBAAgB,gBAAgB,OAAO;AAE3C,cAAQ,gBAAgB,aAAa,EAAE,KAAK,CAAC,UAAU;AACrD,YAAI,QAAQ,EAAG,KAAI,IAAI,KAAK,cAAc,KAAK,oBAAoB;AAAA,MACrE,CAAC,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACjB,UAAI,IAAI,KAAK,oBAAoB;AAAA,IACnC;AAAA,EACF;AACF;AAEA,IAAO,uBAAQ,wBAAwB;","names":[]}
|
package/dist/chunk-4WXALZA3.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
// src/cli/api-client.ts
|
|
2
|
-
import * as fs from "fs";
|
|
3
|
-
import * as path from "path";
|
|
4
|
-
import * as os from "os";
|
|
5
|
-
var DEFAULT_PORT_FILE = path.join(os.homedir(), ".openacp", "api.port");
|
|
6
|
-
var DEFAULT_SECRET_FILE = path.join(os.homedir(), ".openacp", "api-secret");
|
|
7
|
-
function readApiPort(portFilePath = DEFAULT_PORT_FILE) {
|
|
8
|
-
try {
|
|
9
|
-
const content = fs.readFileSync(portFilePath, "utf-8").trim();
|
|
10
|
-
const port = parseInt(content, 10);
|
|
11
|
-
return isNaN(port) ? null : port;
|
|
12
|
-
} catch {
|
|
13
|
-
return null;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
function readApiSecret(secretFilePath = DEFAULT_SECRET_FILE) {
|
|
17
|
-
try {
|
|
18
|
-
const content = fs.readFileSync(secretFilePath, "utf-8").trim();
|
|
19
|
-
return content || null;
|
|
20
|
-
} catch {
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
function removeStalePortFile(portFilePath = DEFAULT_PORT_FILE) {
|
|
25
|
-
try {
|
|
26
|
-
fs.unlinkSync(portFilePath);
|
|
27
|
-
} catch {
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
async function apiCall(port, urlPath, options) {
|
|
31
|
-
const secret = readApiSecret();
|
|
32
|
-
const headers = new Headers(options?.headers);
|
|
33
|
-
if (secret) {
|
|
34
|
-
headers.set("Authorization", `Bearer ${secret}`);
|
|
35
|
-
}
|
|
36
|
-
return fetch(`http://127.0.0.1:${port}${urlPath}`, { ...options, headers });
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export {
|
|
40
|
-
readApiPort,
|
|
41
|
-
readApiSecret,
|
|
42
|
-
removeStalePortFile,
|
|
43
|
-
apiCall
|
|
44
|
-
};
|
|
45
|
-
//# sourceMappingURL=chunk-4WXALZA3.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/api-client.ts"],"sourcesContent":["import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\n\nconst DEFAULT_PORT_FILE = path.join(os.homedir(), '.openacp', 'api.port')\nconst DEFAULT_SECRET_FILE = path.join(os.homedir(), '.openacp', 'api-secret')\n\nexport function readApiPort(portFilePath: string = DEFAULT_PORT_FILE): number | null {\n try {\n const content = fs.readFileSync(portFilePath, 'utf-8').trim()\n const port = parseInt(content, 10)\n return isNaN(port) ? null : port\n } catch {\n return null\n }\n}\n\nexport function readApiSecret(secretFilePath: string = DEFAULT_SECRET_FILE): string | null {\n try {\n const content = fs.readFileSync(secretFilePath, 'utf-8').trim()\n return content || null\n } catch {\n return null\n }\n}\n\nexport function removeStalePortFile(portFilePath: string = DEFAULT_PORT_FILE): void {\n try {\n fs.unlinkSync(portFilePath)\n } catch {\n // ignore\n }\n}\n\nexport async function apiCall(\n port: number,\n urlPath: string,\n options?: RequestInit,\n): Promise<Response> {\n const secret = readApiSecret()\n const headers = new Headers(options?.headers)\n if (secret) {\n headers.set('Authorization', `Bearer ${secret}`)\n }\n return fetch(`http://127.0.0.1:${port}${urlPath}`, { ...options, headers })\n}\n"],"mappings":";AAAA,YAAY,QAAQ;AACpB,YAAY,UAAU;AACtB,YAAY,QAAQ;AAEpB,IAAM,oBAAyB,UAAQ,WAAQ,GAAG,YAAY,UAAU;AACxE,IAAM,sBAA2B,UAAQ,WAAQ,GAAG,YAAY,YAAY;AAErE,SAAS,YAAY,eAAuB,mBAAkC;AACnF,MAAI;AACF,UAAM,UAAa,gBAAa,cAAc,OAAO,EAAE,KAAK;AAC5D,UAAM,OAAO,SAAS,SAAS,EAAE;AACjC,WAAO,MAAM,IAAI,IAAI,OAAO;AAAA,EAC9B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,cAAc,iBAAyB,qBAAoC;AACzF,MAAI;AACF,UAAM,UAAa,gBAAa,gBAAgB,OAAO,EAAE,KAAK;AAC9D,WAAO,WAAW;AAAA,EACpB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,oBAAoB,eAAuB,mBAAyB;AAClF,MAAI;AACF,IAAG,cAAW,YAAY;AAAA,EAC5B,QAAQ;AAAA,EAER;AACF;AAEA,eAAsB,QACpB,MACA,SACA,SACmB;AACnB,QAAM,SAAS,cAAc;AAC7B,QAAM,UAAU,IAAI,QAAQ,SAAS,OAAO;AAC5C,MAAI,QAAQ;AACV,YAAQ,IAAI,iBAAiB,UAAU,MAAM,EAAE;AAAA,EACjD;AACA,SAAO,MAAM,oBAAoB,IAAI,GAAG,OAAO,IAAI,EAAE,GAAG,SAAS,QAAQ,CAAC;AAC5E;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/config/config-registry.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport type { Config } from \"./config.js\";\n\nexport interface ConfigFieldDef {\n path: string;\n displayName: string;\n group: string;\n type: \"toggle\" | \"select\" | \"number\" | \"string\";\n options?: string[] | ((config: Config) => string[]);\n scope: \"safe\" | \"sensitive\";\n hotReload: boolean;\n}\n\nexport const CONFIG_REGISTRY: ConfigFieldDef[] = [\n {\n path: \"defaultAgent\",\n displayName: \"Default Agent\",\n group: \"agent\",\n type: \"select\",\n options: (config) => {\n try {\n const agentsPath = path.join(os.homedir(), \".openacp\", \"agents.json\");\n if (fs.existsSync(agentsPath)) {\n const data = JSON.parse(fs.readFileSync(agentsPath, \"utf-8\"));\n return Object.keys(data.installed ?? {});\n }\n } catch {\n /* fallback */\n }\n return Object.keys(config.agents ?? {});\n },\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"channels.telegram.displayVerbosity\",\n displayName: \"Telegram Verbosity\",\n group: \"display\",\n type: \"select\",\n options: [\"low\", \"medium\", \"high\"],\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"channels.discord.displayVerbosity\",\n displayName: \"Discord Verbosity\",\n group: \"display\",\n type: \"select\",\n options: [\"low\", \"medium\", \"high\"],\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"logging.level\",\n displayName: \"Log Level\",\n group: \"logging\",\n type: \"select\",\n options: [\"silent\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"],\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"tunnel.enabled\",\n displayName: \"Tunnel\",\n group: \"tunnel\",\n type: \"toggle\",\n scope: \"safe\",\n hotReload: false,\n },\n {\n path: \"security.maxConcurrentSessions\",\n displayName: \"Max Concurrent Sessions\",\n group: \"security\",\n type: \"number\",\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"security.sessionTimeoutMinutes\",\n displayName: \"Session Timeout (min)\",\n group: \"security\",\n type: \"number\",\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"workspace.baseDir\",\n displayName: \"Workspace Directory\",\n group: \"workspace\",\n type: \"string\",\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"sessionStore.ttlDays\",\n displayName: \"Session Store TTL (days)\",\n group: \"storage\",\n type: \"number\",\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"speech.stt.provider\",\n displayName: \"Speech to Text\",\n group: \"speech\",\n type: \"select\",\n options: [\"groq\"],\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"speech.stt.apiKey\",\n displayName: \"STT API Key\",\n group: \"speech\",\n type: \"string\",\n scope: \"sensitive\",\n hotReload: true,\n },\n];\n\nexport function getFieldDef(path: string): ConfigFieldDef | undefined {\n return CONFIG_REGISTRY.find((f) => f.path === path);\n}\n\nexport function getSafeFields(): ConfigFieldDef[] {\n return CONFIG_REGISTRY.filter((f) => f.scope === \"safe\");\n}\n\nexport function isHotReloadable(path: string): boolean {\n const def = getFieldDef(path);\n return def?.hotReload ?? false;\n}\n\nexport function resolveOptions(\n def: ConfigFieldDef,\n config: Config,\n): string[] | undefined {\n if (!def.options) return undefined;\n return typeof def.options === \"function\" ? def.options(config) : def.options;\n}\n\nexport function getConfigValue(config: Config, path: string): unknown {\n const parts = path.split(\".\");\n let current: unknown = config;\n for (const part of parts) {\n if (current && typeof current === \"object\" && part in current) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n return current;\n}\n"],"mappings":"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","names":["path"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/plugins/security/index.ts"],"sourcesContent":["import type { OpenACPPlugin, InstallContext, MiddlewarePayloadMap } from '../../core/plugin/types.js'\nimport { SecurityGuard } from './security-guard.js'\nimport type { IncomingMessage } from '../../core/types.js'\n\n// Structural type for the core fields SecurityGuard needs, avoiding\n// a direct dependency on OpenACPCore's full interface.\ninterface SecurityCoreAccess {\n configManager: ConstructorParameters<typeof SecurityGuard>[0]\n sessionManager: ConstructorParameters<typeof SecurityGuard>[1]\n}\n\n// Factory function pattern (closure for state)\nfunction createSecurityPlugin(): OpenACPPlugin {\n return {\n name: '@openacp/security',\n version: '1.0.0',\n description: 'User access control and session limits',\n essential: false,\n permissions: ['services:register', 'middleware:register', 'kernel:access', 'commands:register'],\n\n async install(ctx: InstallContext) {\n const { settings, legacyConfig, terminal } = ctx\n\n // Migrate from legacy config if present\n if (legacyConfig) {\n const securityCfg = legacyConfig.security as Record<string, unknown> | undefined\n if (securityCfg) {\n await settings.setAll({\n allowedUserIds: securityCfg.allowedUserIds ?? [],\n maxConcurrentSessions: securityCfg.maxConcurrentSessions ?? 20,\n sessionTimeoutMinutes: securityCfg.sessionTimeoutMinutes ?? 60,\n })\n terminal.log.success('Security settings migrated from legacy config')\n return\n }\n }\n\n // Save defaults (no interactive prompts needed)\n await settings.setAll({\n allowedUserIds: [],\n maxConcurrentSessions: 20,\n sessionTimeoutMinutes: 60,\n })\n terminal.log.success('Security defaults saved')\n },\n\n async configure(ctx: InstallContext) {\n const { terminal, settings } = ctx\n const current = await settings.getAll()\n\n const choice = await terminal.select({\n message: 'What to configure?',\n options: [\n { value: 'allowedUsers', label: 'Edit allowed user IDs' },\n { value: 'maxSessions', label: `Max concurrent sessions (current: ${current.maxConcurrentSessions ?? 20})` },\n { value: 'timeout', label: `Session timeout minutes (current: ${current.sessionTimeoutMinutes ?? 60})` },\n { value: 'done', label: 'Done' },\n ],\n })\n\n if (choice === 'allowedUsers') {\n const currentIds = (current.allowedUserIds as string[]) ?? []\n const val = await terminal.text({\n message: 'Allowed user IDs (comma-separated, empty = allow all):',\n defaultValue: currentIds.join(', '),\n })\n const ids = val.split(',').map((s) => s.trim()).filter(Boolean)\n await settings.set('allowedUserIds', ids)\n terminal.log.success('Allowed user IDs updated')\n } else if (choice === 'maxSessions') {\n const val = await terminal.text({\n message: 'Max concurrent sessions:',\n defaultValue: String(current.maxConcurrentSessions ?? 20),\n validate: (v) => {\n const n = Number(v.trim())\n if (isNaN(n) || n < 1) return 'Must be a positive number'\n return undefined\n },\n })\n await settings.set('maxConcurrentSessions', Number(val.trim()))\n terminal.log.success('Max sessions updated')\n } else if (choice === 'timeout') {\n const val = await terminal.text({\n message: 'Session timeout (minutes):',\n defaultValue: String(current.sessionTimeoutMinutes ?? 60),\n validate: (v) => {\n const n = Number(v.trim())\n if (isNaN(n) || n < 1) return 'Must be a positive number'\n return undefined\n },\n })\n await settings.set('sessionTimeoutMinutes', Number(val.trim()))\n terminal.log.success('Session timeout updated')\n }\n },\n\n async uninstall(ctx: InstallContext, opts: { purge: boolean }) {\n if (opts.purge) {\n await ctx.settings.clear()\n ctx.terminal.log.success('Security settings cleared')\n }\n },\n\n async setup(ctx) {\n const core = ctx.core as SecurityCoreAccess\n const guard = new SecurityGuard(core.configManager, core.sessionManager)\n\n // Register middleware for message:incoming — block unauthorized users\n ctx.registerMiddleware('message:incoming', {\n handler: async (payload: MiddlewarePayloadMap['message:incoming'], next) => {\n const access = guard.checkAccess(payload as unknown as IncomingMessage)\n if (!access.allowed) {\n ctx.log.info(`Access denied: ${access.reason}`)\n return null // block\n }\n return next()\n }\n })\n\n // Register SecurityGuard as the service directly\n ctx.registerService('security', guard)\n\n ctx.registerCommand({\n name: 'dangerous',\n description: 'Toggle dangerous mode (auto-approve all permissions)',\n usage: 'on|off',\n category: 'plugin',\n handler: async (args) => {\n const mode = args.raw.trim().toLowerCase()\n if (mode === 'on') return { type: 'text', text: 'Dangerous mode enabled — all permissions will be auto-approved.' }\n if (mode === 'off') return { type: 'text', text: 'Dangerous mode disabled — permissions require manual approval.' }\n return { type: 'menu', title: 'Dangerous Mode', options: [\n { label: 'Enable', command: '/dangerous on' },\n { label: 'Disable', command: '/dangerous off' },\n ]}\n },\n })\n\n ctx.log.info('Security service ready')\n },\n }\n}\n\nexport default createSecurityPlugin()\n"],"mappings":"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","names":[]}
|