@bytespell/shella 0.1.6 → 0.1.8
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/bin/cli.js +277 -80
- package/dist/bin/cli.js.map +1 -1
- package/dist/index.js +269 -79
- package/dist/index.js.map +1 -1
- package/dist/public/assets/{_baseUniq-ofDPcIU7.js → _baseUniq-xMBLm_vj.js} +1 -1
- package/{public/assets/arc-CN1QbtAQ.js → dist/public/assets/arc-CCivY36l.js} +1 -1
- package/{public/assets/architectureDiagram-VXUJARFQ-B7xrwB3a.js → dist/public/assets/architectureDiagram-VXUJARFQ-Cx1ftnZs.js} +1 -1
- package/{public/assets/blockDiagram-VD42YOAC-ByLGlNws.js → dist/public/assets/blockDiagram-VD42YOAC-Dd5J4pAa.js} +1 -1
- package/dist/public/assets/{c4Diagram-YG6GDRKO-YpYx4Aj8.js → c4Diagram-YG6GDRKO-C4yoJFk1.js} +1 -1
- package/dist/public/assets/channel-CgkYY8Ci.js +1 -0
- package/dist/public/assets/{chunk-4BX2VUAB-D0zp96k1.js → chunk-4BX2VUAB-CiImuKHD.js} +1 -1
- package/dist/public/assets/{chunk-55IACEB6-C5GJeIrO.js → chunk-55IACEB6-V6l1i-_P.js} +1 -1
- package/{public/assets/chunk-B4BG7PRW-Ci17wd3H.js → dist/public/assets/chunk-B4BG7PRW-DU8Wql9S.js} +1 -1
- package/{public/assets/chunk-DI55MBZ5-B2XMqfQC.js → dist/public/assets/chunk-DI55MBZ5-B_Jw-lhj.js} +1 -1
- package/dist/public/assets/{chunk-FMBD7UC4-Crk5_wey.js → chunk-FMBD7UC4-C1LlA37K.js} +1 -1
- package/dist/public/assets/{chunk-QN33PNHL-DqQoCDuG.js → chunk-QN33PNHL-CcgyTGxJ.js} +1 -1
- package/dist/public/assets/{chunk-QZHKN3VN-DtbXtmmy.js → chunk-QZHKN3VN-C2H0lOPM.js} +1 -1
- package/dist/public/assets/{chunk-TZMSLE5B-Boi_YcuZ.js → chunk-TZMSLE5B-Cp4Dpzkh.js} +1 -1
- package/dist/public/assets/classDiagram-2ON5EDUG-BuYVNwmc.js +1 -0
- package/dist/public/assets/classDiagram-v2-WZHVMYZB-BuYVNwmc.js +1 -0
- package/dist/public/assets/clone-mkrd6lC9.js +1 -0
- package/dist/public/assets/{code-block-IT6T5CEO-BAcnOjsj.js → code-block-IT6T5CEO-DOOuyfxG.js} +1 -1
- package/dist/public/assets/{cose-bilkent-S5V4N54A-DAIcBIuP.js → cose-bilkent-S5V4N54A-DefjjRca.js} +1 -1
- package/dist/public/assets/{dagre-6UL2VRFP-zz51dmH0.js → dagre-6UL2VRFP-hHpxpOKX.js} +1 -1
- package/dist/public/assets/demo.svg +1 -0
- package/dist/public/assets/{diagram-PSM6KHXK-bVpD6rI7.js → diagram-PSM6KHXK-ZgZ2X0Q-.js} +1 -1
- package/dist/public/assets/{diagram-QEK2KX5R-I8YB5Wm0.js → diagram-QEK2KX5R-gCeAqKj1.js} +1 -1
- package/dist/public/assets/{diagram-S2PKOQOG-D1xlOPWJ.js → diagram-S2PKOQOG-9IyVqMFa.js} +1 -1
- package/{public/assets/erDiagram-Q2GNP2WA-DEdjbB3m.js → dist/public/assets/erDiagram-Q2GNP2WA-Dzm33cik.js} +1 -1
- package/{public/assets/flowDiagram-NV44I4VS-BBCU2dfK.js → dist/public/assets/flowDiagram-NV44I4VS-BamNhi0g.js} +1 -1
- package/dist/public/assets/{ganttDiagram-JELNMOA3-B0jnifD_.js → ganttDiagram-JELNMOA3-CrECl9wX.js} +1 -1
- package/dist/public/assets/{gitGraphDiagram-NY62KEGX-BX21wvJS.js → gitGraphDiagram-NY62KEGX-C7_E64uK.js} +1 -1
- package/dist/public/assets/{graph-BE95p5Ca.js → graph-CtTAhETf.js} +1 -1
- package/dist/public/assets/index-Czr2q0NP.css +1 -0
- package/dist/public/assets/index-kEIJA0pC.js +1781 -0
- package/dist/public/assets/{infoDiagram-WHAUD3N6-CrU0UXwW.js → infoDiagram-WHAUD3N6-CLOougXO.js} +1 -1
- package/dist/public/assets/{journeyDiagram-XKPGCS4Q-DzukVB-1.js → journeyDiagram-XKPGCS4Q-g0dISD-I.js} +1 -1
- package/{public/assets/kanban-definition-3W4ZIXB7-CJVLdxxJ.js → dist/public/assets/kanban-definition-3W4ZIXB7-DFIVrLyR.js} +1 -1
- package/dist/public/assets/{layout-CM_3juMX.js → layout-DolajoeL.js} +1 -1
- package/dist/public/assets/{linear-BXRjo7t5.js → linear-B5Hf7uIN.js} +1 -1
- package/dist/public/assets/{mermaid.core-Hp60xAyJ.js → mermaid.core-DqP3HtOk.js} +5 -5
- package/dist/public/assets/{min-oqogeQSX.js → min-UFvm8GLY.js} +1 -1
- package/dist/public/assets/{mindmap-definition-VGOIOE7T-CCgMWgfM.js → mindmap-definition-VGOIOE7T-CnSTRcIt.js} +1 -1
- package/dist/public/assets/{pieDiagram-ADFJNKIX-DAkNkjx-.js → pieDiagram-ADFJNKIX-CuMH9Po8.js} +1 -1
- package/{public/assets/quadrantDiagram-AYHSOK5B-CPEqSA2x.js → dist/public/assets/quadrantDiagram-AYHSOK5B-6i0SX3Xo.js} +1 -1
- package/dist/public/assets/{requirementDiagram-UZGBJVZJ-jOv297_A.js → requirementDiagram-UZGBJVZJ-ChwO2HU-.js} +1 -1
- package/dist/public/assets/{sankeyDiagram-TZEHDZUN-CwvAKmpc.js → sankeyDiagram-TZEHDZUN-DG-8crEL.js} +1 -1
- package/dist/public/assets/{sequenceDiagram-WL72ISMW-D_WZ2ogT.js → sequenceDiagram-WL72ISMW-BQH_OfEp.js} +1 -1
- package/{public/assets/stateDiagram-FKZM4ZOC-tqYMmK3v.js → dist/public/assets/stateDiagram-FKZM4ZOC-CBOkbVQn.js} +1 -1
- package/dist/public/assets/stateDiagram-v2-4FDKWEC3-BqHz04Bh.js +1 -0
- package/{public/assets/timeline-definition-IT6M3QCI-BIqJkdQ0.js → dist/public/assets/timeline-definition-IT6M3QCI-CkNd8y6W.js} +1 -1
- package/dist/public/assets/{treemap-KMMF4GRG-CmJM6xaw.js → treemap-KMMF4GRG-D6z_eudj.js} +1 -1
- package/dist/public/assets/{xychartDiagram-PRI3JC2R-D7-tZ8iR.js → xychartDiagram-PRI3JC2R-B5wk4XRt.js} +1 -1
- package/dist/public/favicon-16.ico +0 -0
- package/dist/public/favicon-32.ico +0 -0
- package/dist/public/favicon-48.ico +0 -0
- package/dist/public/favicon.svg +4 -0
- package/dist/public/index.html +2 -2
- package/dist/public/logo-1024.png +0 -0
- package/dist/public/logo-128.png +0 -0
- package/dist/public/logo-16.png +0 -0
- package/dist/public/logo-256.png +0 -0
- package/dist/public/logo-32.png +0 -0
- package/dist/public/logo-48.png +0 -0
- package/dist/public/logo-512.png +0 -0
- package/dist/public/logo-64.png +0 -0
- package/package.json +6 -2
- package/public/assets/{_baseUniq-ofDPcIU7.js → _baseUniq-xMBLm_vj.js} +1 -1
- package/{dist/public/assets/arc-CN1QbtAQ.js → public/assets/arc-CCivY36l.js} +1 -1
- package/{dist/public/assets/architectureDiagram-VXUJARFQ-B7xrwB3a.js → public/assets/architectureDiagram-VXUJARFQ-Cx1ftnZs.js} +1 -1
- package/{dist/public/assets/blockDiagram-VD42YOAC-ByLGlNws.js → public/assets/blockDiagram-VD42YOAC-Dd5J4pAa.js} +1 -1
- package/public/assets/{c4Diagram-YG6GDRKO-YpYx4Aj8.js → c4Diagram-YG6GDRKO-C4yoJFk1.js} +1 -1
- package/public/assets/channel-CgkYY8Ci.js +1 -0
- package/public/assets/{chunk-4BX2VUAB-D0zp96k1.js → chunk-4BX2VUAB-CiImuKHD.js} +1 -1
- package/public/assets/{chunk-55IACEB6-C5GJeIrO.js → chunk-55IACEB6-V6l1i-_P.js} +1 -1
- package/{dist/public/assets/chunk-B4BG7PRW-Ci17wd3H.js → public/assets/chunk-B4BG7PRW-DU8Wql9S.js} +1 -1
- package/{dist/public/assets/chunk-DI55MBZ5-B2XMqfQC.js → public/assets/chunk-DI55MBZ5-B_Jw-lhj.js} +1 -1
- package/public/assets/{chunk-FMBD7UC4-Crk5_wey.js → chunk-FMBD7UC4-C1LlA37K.js} +1 -1
- package/public/assets/{chunk-QN33PNHL-DqQoCDuG.js → chunk-QN33PNHL-CcgyTGxJ.js} +1 -1
- package/public/assets/{chunk-QZHKN3VN-DtbXtmmy.js → chunk-QZHKN3VN-C2H0lOPM.js} +1 -1
- package/public/assets/{chunk-TZMSLE5B-Boi_YcuZ.js → chunk-TZMSLE5B-Cp4Dpzkh.js} +1 -1
- package/public/assets/classDiagram-2ON5EDUG-BuYVNwmc.js +1 -0
- package/public/assets/classDiagram-v2-WZHVMYZB-BuYVNwmc.js +1 -0
- package/public/assets/clone-mkrd6lC9.js +1 -0
- package/public/assets/{code-block-IT6T5CEO-BAcnOjsj.js → code-block-IT6T5CEO-DOOuyfxG.js} +1 -1
- package/public/assets/{cose-bilkent-S5V4N54A-DAIcBIuP.js → cose-bilkent-S5V4N54A-DefjjRca.js} +1 -1
- package/public/assets/{dagre-6UL2VRFP-zz51dmH0.js → dagre-6UL2VRFP-hHpxpOKX.js} +1 -1
- package/public/assets/demo.svg +1 -0
- package/public/assets/{diagram-PSM6KHXK-bVpD6rI7.js → diagram-PSM6KHXK-ZgZ2X0Q-.js} +1 -1
- package/public/assets/{diagram-QEK2KX5R-I8YB5Wm0.js → diagram-QEK2KX5R-gCeAqKj1.js} +1 -1
- package/public/assets/{diagram-S2PKOQOG-D1xlOPWJ.js → diagram-S2PKOQOG-9IyVqMFa.js} +1 -1
- package/{dist/public/assets/erDiagram-Q2GNP2WA-DEdjbB3m.js → public/assets/erDiagram-Q2GNP2WA-Dzm33cik.js} +1 -1
- package/{dist/public/assets/flowDiagram-NV44I4VS-BBCU2dfK.js → public/assets/flowDiagram-NV44I4VS-BamNhi0g.js} +1 -1
- package/public/assets/{ganttDiagram-JELNMOA3-B0jnifD_.js → ganttDiagram-JELNMOA3-CrECl9wX.js} +1 -1
- package/public/assets/{gitGraphDiagram-NY62KEGX-BX21wvJS.js → gitGraphDiagram-NY62KEGX-C7_E64uK.js} +1 -1
- package/public/assets/{graph-BE95p5Ca.js → graph-CtTAhETf.js} +1 -1
- package/public/assets/index-Czr2q0NP.css +1 -0
- package/public/assets/index-kEIJA0pC.js +1781 -0
- package/public/assets/{infoDiagram-WHAUD3N6-CrU0UXwW.js → infoDiagram-WHAUD3N6-CLOougXO.js} +1 -1
- package/public/assets/{journeyDiagram-XKPGCS4Q-DzukVB-1.js → journeyDiagram-XKPGCS4Q-g0dISD-I.js} +1 -1
- package/{dist/public/assets/kanban-definition-3W4ZIXB7-CJVLdxxJ.js → public/assets/kanban-definition-3W4ZIXB7-DFIVrLyR.js} +1 -1
- package/public/assets/{layout-CM_3juMX.js → layout-DolajoeL.js} +1 -1
- package/public/assets/{linear-BXRjo7t5.js → linear-B5Hf7uIN.js} +1 -1
- package/public/assets/{mermaid.core-Hp60xAyJ.js → mermaid.core-DqP3HtOk.js} +5 -5
- package/public/assets/{min-oqogeQSX.js → min-UFvm8GLY.js} +1 -1
- package/public/assets/{mindmap-definition-VGOIOE7T-CCgMWgfM.js → mindmap-definition-VGOIOE7T-CnSTRcIt.js} +1 -1
- package/public/assets/{pieDiagram-ADFJNKIX-DAkNkjx-.js → pieDiagram-ADFJNKIX-CuMH9Po8.js} +1 -1
- package/{dist/public/assets/quadrantDiagram-AYHSOK5B-CPEqSA2x.js → public/assets/quadrantDiagram-AYHSOK5B-6i0SX3Xo.js} +1 -1
- package/public/assets/{requirementDiagram-UZGBJVZJ-jOv297_A.js → requirementDiagram-UZGBJVZJ-ChwO2HU-.js} +1 -1
- package/public/assets/{sankeyDiagram-TZEHDZUN-CwvAKmpc.js → sankeyDiagram-TZEHDZUN-DG-8crEL.js} +1 -1
- package/public/assets/{sequenceDiagram-WL72ISMW-D_WZ2ogT.js → sequenceDiagram-WL72ISMW-BQH_OfEp.js} +1 -1
- package/{dist/public/assets/stateDiagram-FKZM4ZOC-tqYMmK3v.js → public/assets/stateDiagram-FKZM4ZOC-CBOkbVQn.js} +1 -1
- package/public/assets/stateDiagram-v2-4FDKWEC3-BqHz04Bh.js +1 -0
- package/{dist/public/assets/timeline-definition-IT6M3QCI-BIqJkdQ0.js → public/assets/timeline-definition-IT6M3QCI-CkNd8y6W.js} +1 -1
- package/public/assets/{treemap-KMMF4GRG-CmJM6xaw.js → treemap-KMMF4GRG-D6z_eudj.js} +1 -1
- package/public/assets/{xychartDiagram-PRI3JC2R-D7-tZ8iR.js → xychartDiagram-PRI3JC2R-B5wk4XRt.js} +1 -1
- package/public/favicon-16.ico +0 -0
- package/public/favicon-32.ico +0 -0
- package/public/favicon-48.ico +0 -0
- package/public/favicon.svg +4 -0
- package/public/index.html +2 -2
- package/public/logo-1024.png +0 -0
- package/public/logo-128.png +0 -0
- package/public/logo-16.png +0 -0
- package/public/logo-256.png +0 -0
- package/public/logo-32.png +0 -0
- package/public/logo-48.png +0 -0
- package/public/logo-512.png +0 -0
- package/public/logo-64.png +0 -0
- package/dist/public/assets/channel-BtuRdvAy.js +0 -1
- package/dist/public/assets/classDiagram-2ON5EDUG-CDjYhjfv.js +0 -1
- package/dist/public/assets/classDiagram-v2-WZHVMYZB-CDjYhjfv.js +0 -1
- package/dist/public/assets/clone-C8pGQ3Xy.js +0 -1
- package/dist/public/assets/index-CA2Ed_I8.css +0 -1
- package/dist/public/assets/index-CbxztLlk.js +0 -1701
- package/dist/public/assets/stateDiagram-v2-4FDKWEC3-BF0ecSBs.js +0 -1
- package/public/assets/channel-BtuRdvAy.js +0 -1
- package/public/assets/classDiagram-2ON5EDUG-CDjYhjfv.js +0 -1
- package/public/assets/classDiagram-v2-WZHVMYZB-CDjYhjfv.js +0 -1
- package/public/assets/clone-C8pGQ3Xy.js +0 -1
- package/public/assets/index-CA2Ed_I8.css +0 -1
- package/public/assets/index-CbxztLlk.js +0 -1701
- package/public/assets/stateDiagram-v2-4FDKWEC3-BF0ecSBs.js +0 -1
package/dist/bin/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../bin/cli.ts","../../src/index.ts","../../src/db/index.ts","../../src/lib/paths.ts","../../src/db/schema.ts","../../src/amuxBridge.ts","../../src/trpc/trpc.ts","../../src/trpc/windows.ts","../../client/lib/layout.ts","../../src/trpc/layout.ts","../../src/trpc/agents.ts","../../src/trpc/files.ts","../../src/trpc/router.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Shella CLI - Self-hosted AI coding agents\n *\n * Usage:\n * npx @bytespell/shella Start in current directory\n * npx @bytespell/shella --port 3070 Custom port\n */\n\nimport { program } from 'commander';\nimport { networkInterfaces } from 'os';\nimport { spawn } from 'child_process';\nimport * as p from '@clack/prompts';\nimport { createShellaServer } from '../src/index.js';\n\nconst VERSION = '0.1.0';\n\n// Brand color (indigo) for terminal output\nconst BRAND = '\\x1b[38;2;99;102;241m'; // rgb(99, 102, 241)\nconst RESET = '\\x1b[0m';\nconst DIM = '\\x1b[2m';\nconst brand = (text: string) => `${BRAND}${text}${RESET}`;\nconst dim = (text: string) => `${DIM}${text}${RESET}`;\n\nfunction getLanIp(): string {\n const interfaces = networkInterfaces();\n for (const [name, addrs] of Object.entries(interfaces)) {\n if (/^(lo|docker|veth|br-|virbr)/.test(name)) continue;\n for (const addr of addrs || []) {\n if (addr.family === 'IPv4' && !addr.internal) {\n return addr.address;\n }\n }\n }\n return 'localhost';\n}\n\ninterface StartOptions {\n port: string;\n open: boolean;\n verbose: boolean;\n}\n\nasync function startCommand(options: StartOptions) {\n const port = parseInt(options.port, 10);\n const verbose = options.verbose;\n\n const s = verbose ? null : p.spinner();\n const log = (msg: string) => verbose && console.log(msg);\n\n if (!verbose) {\n p.intro(`${brand('shella')} ${dim(`v${VERSION}`)}`);\n } else {\n log(`${brand('shella')} ${dim(`v${VERSION}`)}`);\n }\n\n if (s) s.start('Starting server...');\n else log('Starting server...');\n\n const shella = createShellaServer({\n port,\n onReady: (url) => {\n if (s) s.stop('Ready');\n\n const lanIp = getLanIp();\n const lanUrl = `http://${lanIp}:${port}`;\n\n if (verbose) {\n log(`\\n${brand(lanUrl)}`);\n log(dim('access from any device'));\n log(`\\n${dim('press ctrl+c to stop')}\\n`);\n } else {\n p.log.success(`${brand(lanUrl)}`);\n p.log.message(dim('access from any device'));\n p.outro(dim('press ctrl+c to stop'));\n }\n\n // Open browser if requested\n if (options.open) {\n const openCommand =\n process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';\n spawn(openCommand, [url], { stdio: 'ignore', detached: true }).unref();\n }\n },\n });\n\n await shella.start();\n\n // Graceful shutdown\n const shutdown = async () => {\n console.log('');\n console.log(dim('stopping...'));\n await shella.stop();\n console.log(`${brand('shella')} ${dim('stopped')}`);\n process.exit(0);\n };\n\n process.on('SIGTERM', shutdown);\n process.on('SIGINT', shutdown);\n}\n\nprogram\n .name('shella')\n .description(`${brand('shella')} - Self-hosted AI coding agents. Access from your phone.`)\n .version(VERSION)\n .option('-p, --port <port>', 'Server port', '3067')\n .option('--no-open', \"Don't open browser automatically\")\n .option('-v, --verbose', 'Show detailed logs', false)\n .action(startCommand);\n\nprogram.parse();\n","/**\n * Shella Server - Full product combining Amux + UI\n *\n * Creates a server that:\n * 1. Initializes Shella's database (windows, panes, ui_state)\n * 2. Creates an amux bridge for session/agent operations\n * 3. Serves the bundled UI static files\n * 4. Mounts Shella's tRPC API at /trpc (which proxies to amux internally)\n * 5. Handles WebSocket connections for subscriptions\n */\n\nimport express from 'express';\nimport { createServer } from 'http';\nimport { WebSocketServer } from 'ws';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport { createExpressMiddleware } from '@trpc/server/adapters/express';\nimport { applyWSSHandler } from '@trpc/server/adapters/ws';\nimport { agentManager } from '@bytespell/amux/agents/manager';\n\n// Import to trigger amux database initialization\nimport '@bytespell/amux/db';\n\n// Import to trigger shella database initialization\nimport './db/index.js';\n\nimport { createAmuxBridge } from './amuxBridge.js';\nimport { shellaRouter, initializeRouters } from './trpc/router.js';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport interface ShellaServerOptions {\n port?: number;\n onReady?: (url: string) => void;\n}\n\nexport interface ShellaServer {\n start: () => Promise<void>;\n stop: () => Promise<void>;\n}\n\nexport function createShellaServer(options: ShellaServerOptions = {}): ShellaServer {\n const port = options.port ?? 3067;\n\n // Initialize amux bridge\n const amuxBridge = createAmuxBridge();\n\n // Initialize routers with the bridge\n initializeRouters(amuxBridge);\n\n // Create main express app\n const app = express();\n app.use(express.json());\n\n // Serve static UI files first\n const publicPath = path.join(__dirname, '..', 'public');\n app.use(express.static(publicPath));\n\n // tRPC HTTP endpoint\n app.use('/trpc', createExpressMiddleware({ router: shellaRouter }));\n\n // Health check\n app.get('/health', (_req, res) => res.json({ status: 'ok' }));\n\n // SPA fallback - serve index.html for all non-API routes\n // Express 5 requires named parameter for wildcards\n app.get('/{*splat}', (_req, res) => {\n res.sendFile(path.join(publicPath, 'index.html'));\n });\n\n // Create HTTP server\n const server = createServer(app);\n\n // WebSocket for subscriptions\n const wss = new WebSocketServer({ server, path: '/trpc' });\n applyWSSHandler({ wss, router: shellaRouter });\n\n return {\n start: () => {\n return new Promise((resolve) => {\n server.listen(port, () => {\n const url = `http://localhost:${port}`;\n console.log(`[shella] Running on ${url}`);\n options.onReady?.(url);\n resolve();\n });\n });\n },\n\n stop: async () => {\n console.log('[shella] Shutting down...');\n wss.close();\n await agentManager.stopAll();\n server.close();\n },\n };\n}\n\n// Re-export router type for UI\nexport { shellaRouter, type ShellaRouter } from './trpc/router.js';\n","import Database from 'better-sqlite3';\nimport { drizzle } from 'drizzle-orm/better-sqlite3';\nimport { getShellaDbPath, ensureDir, getDataDir } from '../lib/paths.js';\nimport * as schema from './schema.js';\n\nensureDir(getDataDir());\n\nconst sqlite = new Database(getShellaDbPath());\nsqlite.pragma('journal_mode = WAL');\nsqlite.pragma('foreign_keys = ON');\n\nexport const db = drizzle(sqlite, { schema });\n\n// Create tables if they don't exist\nsqlite.exec(`\n CREATE TABLE IF NOT EXISTS windows (\n id TEXT PRIMARY KEY,\n title TEXT NOT NULL,\n has_custom_title INTEGER NOT NULL DEFAULT 0,\n layout TEXT NOT NULL,\n active_pane_id TEXT NOT NULL,\n created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000),\n last_accessed_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)\n );\n\n CREATE TABLE IF NOT EXISTS panes (\n id TEXT PRIMARY KEY,\n window_id TEXT NOT NULL REFERENCES windows(id) ON DELETE CASCADE,\n session_id TEXT NOT NULL,\n created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)\n );\n\n CREATE TABLE IF NOT EXISTS ui_state (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n`);\n\nexport { schema };\n","import path from 'path';\nimport os from 'os';\nimport fs from 'fs';\n\n/**\n * Get the data directory following XDG Base Directory spec\n * Shared with amux in the same directory.\n */\nexport function getDataDir(): string {\n const home = os.homedir();\n\n let dataDir: string;\n\n switch (process.platform) {\n case 'darwin':\n dataDir = path.join(home, 'Library', 'Application Support', 'shella');\n break;\n case 'win32':\n dataDir = path.join(process.env.APPDATA || path.join(home, 'AppData', 'Roaming'), 'shella');\n break;\n default:\n // Linux and others - follow XDG spec\n dataDir = path.join(process.env.XDG_DATA_HOME || path.join(home, '.local', 'share'), 'shella');\n }\n\n return dataDir;\n}\n\n/**\n * Check if running in mock mode\n */\nexport function isMockMode(): boolean {\n return process.env.SHELLA_MOCK_MODE === 'true';\n}\n\n/**\n * Get the path to Shella's database file (UI state: windows, panes, layouts)\n * This is separate from amux's database (sessions, events, agent configs)\n */\nexport function getShellaDbPath(): string {\n const filename = isMockMode() ? 'shella-ui.mock.db' : 'shella-ui.db';\n return path.join(getDataDir(), filename);\n}\n\n/**\n * Ensure a directory exists, creating it if necessary\n */\nexport function ensureDir(dir: string): void {\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n}\n","import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';\nimport { sql } from 'drizzle-orm';\nimport type { LayoutNode } from '../../client/lib/layout.js';\n\n/**\n * Windows - top-level UI containers with layout trees.\n * Each window contains one or more panes arranged in a layout.\n */\nexport const windows = sqliteTable('windows', {\n id: text('id').primaryKey(),\n title: text('title').notNull(),\n hasCustomTitle: integer('has_custom_title', { mode: 'boolean' }).notNull().default(false),\n /** JSON-serialized LayoutNode tree */\n layout: text('layout', { mode: 'json' }).$type<LayoutNode>().notNull(),\n activePaneId: text('active_pane_id').notNull(),\n createdAt: integer('created_at', { mode: 'timestamp_ms' })\n .notNull()\n .default(sql`(unixepoch() * 1000)`),\n lastAccessedAt: integer('last_accessed_at', { mode: 'timestamp_ms' })\n .notNull()\n .default(sql`(unixepoch() * 1000)`),\n});\n\n/**\n * Panes - individual agent session containers within a window.\n * Each pane references an amux session (cross-database reference).\n */\nexport const panes = sqliteTable('panes', {\n id: text('id').primaryKey(),\n windowId: text('window_id')\n .notNull()\n .references(() => windows.id, { onDelete: 'cascade' }),\n /** References amux session ID (cross-database) */\n sessionId: text('session_id').notNull(),\n createdAt: integer('created_at', { mode: 'timestamp_ms' })\n .notNull()\n .default(sql`(unixepoch() * 1000)`),\n});\n\n/**\n * UI state - key/value store for UI preferences.\n * Examples: active_window_id, theme, sidebar_collapsed\n */\nexport const uiState = sqliteTable('ui_state', {\n key: text('key').primaryKey(),\n value: text('value').notNull(),\n});\n\n// Type exports\nexport type Window = typeof windows.$inferSelect;\nexport type NewWindow = typeof windows.$inferInsert;\nexport type Pane = typeof panes.$inferSelect;\nexport type NewPane = typeof panes.$inferInsert;\nexport type UiState = typeof uiState.$inferSelect;\n","/**\n * Bridge between Shella and Amux.\n *\n * Since Shella embeds Amux (same process), this bridge directly calls\n * Amux's internal functions rather than going through tRPC.\n */\n\nimport { randomUUID } from 'crypto';\nimport { eq, inArray } from 'drizzle-orm';\nimport { db, schema } from '@bytespell/amux/db';\nimport { agentManager } from '@bytespell/amux/agents/manager';\nimport { clearEventsForSession } from '@bytespell/amux/agents/eventStore';\nimport { listFilesForAutocomplete, type FileEntry } from '@bytespell/amux/trpc/files';\nimport type { WindowUpdate } from '@bytespell/amux/types';\n\nconst { sessions, agentConfigs, appState } = schema;\n\n// Types that match Amux's internal types\nexport interface AmuxSession {\n id: string;\n directory: string;\n agentConfigId: string;\n acpSessionId: string | null;\n title: string | null;\n model: string | null;\n mode: string | null;\n createdAt: Date;\n}\n\nexport interface AmuxAgentConfig {\n id: string;\n name: string;\n command: string;\n args: string[] | null;\n env: Record<string, string> | null;\n createdAt: Date;\n}\n\nexport interface AmuxAgentSession {\n acpSessionId: string;\n replayEvents: any[];\n models?: Array<{ modelId: string; name: string }>;\n modes?: Array<{ id: string; name: string; description?: string }>;\n}\n\nexport interface AmuxBridge {\n // Session operations\n getSessions(ids: string[]): Promise<AmuxSession[]>;\n getSession(id: string): Promise<AmuxSession | null>;\n createSession(params: { id?: string; directory: string; agentConfigId?: string }): Promise<AmuxSession>;\n deleteSession(id: string): Promise<void>;\n\n // Agent config operations\n getAgentConfigs(): Promise<AmuxAgentConfig[]>;\n\n // Agent operations (start/stop/prompt/etc)\n startAgent(sessionId: string): Promise<AmuxAgentSession>;\n stopAgent(sessionId: string): Promise<void>;\n prompt(sessionId: string, message: string): Promise<void>;\n cancel(sessionId: string): Promise<void>;\n setMode(sessionId: string, modeId: string): Promise<void>;\n setModel(sessionId: string, modelId: string): Promise<void>;\n respondPermission(sessionId: string, requestId: string, optionId: string): void;\n switchAgent(sessionId: string, agentConfigId: string): Promise<void>;\n\n // Subscriptions\n subscribeToSession(sessionId: string, callback: (update: WindowUpdate) => void): () => void;\n\n // File operations\n listFilesForAutocomplete(sessionId: string, partialPath: string, limit: number): Promise<FileEntry[]>;\n}\n\n/**\n * Create an AmuxBridge from the embedded Amux instance.\n * This connects to Amux running in the same process.\n */\nexport function createAmuxBridge(): AmuxBridge {\n return {\n async getSessions(ids: string[]): Promise<AmuxSession[]> {\n if (ids.length === 0) return [];\n return db.select().from(sessions).where(inArray(sessions.id, ids)).all();\n },\n\n async getSession(id: string): Promise<AmuxSession | null> {\n return db.select().from(sessions).where(eq(sessions.id, id)).get() ?? null;\n },\n\n async createSession(params: { id?: string; directory: string; agentConfigId?: string }): Promise<AmuxSession> {\n // Get agent config\n let configId = params.agentConfigId;\n if (!configId) {\n const lastUsedRow = db.select().from(appState).where(eq(appState.key, 'last_used_agent_config_id')).get();\n if (lastUsedRow?.value) {\n const config = db.select().from(agentConfigs).where(eq(agentConfigs.id, lastUsedRow.value)).get();\n if (config) configId = config.id;\n }\n if (!configId) {\n const firstConfig = db.select().from(agentConfigs).get();\n if (!firstConfig) {\n throw new Error('No agent configs available');\n }\n configId = firstConfig.id;\n }\n } else {\n // Save as last used\n db.insert(appState)\n .values({ key: 'last_used_agent_config_id', value: configId })\n .onConflictDoUpdate({ target: appState.key, set: { value: configId } })\n .run();\n }\n\n // Use client-provided ID if available (for optimistic updates)\n const id = params.id ?? randomUUID();\n const now = new Date();\n db.insert(sessions).values({\n id,\n directory: params.directory,\n agentConfigId: configId,\n acpSessionId: null,\n model: null,\n mode: null,\n createdAt: now,\n }).run();\n\n return db.select().from(sessions).where(eq(sessions.id, id)).get()!;\n },\n\n async deleteSession(id: string): Promise<void> {\n await agentManager.stopForSession(id);\n clearEventsForSession(id);\n db.delete(sessions).where(eq(sessions.id, id)).run();\n },\n\n async getAgentConfigs(): Promise<AmuxAgentConfig[]> {\n return db.select().from(agentConfigs).all();\n },\n\n async startAgent(sessionId: string): Promise<AmuxAgentSession> {\n return agentManager.startForSession(sessionId);\n },\n\n async stopAgent(sessionId: string): Promise<void> {\n await agentManager.stopForSession(sessionId);\n },\n\n async prompt(sessionId: string, message: string): Promise<void> {\n await agentManager.prompt(sessionId, message);\n },\n\n async cancel(sessionId: string): Promise<void> {\n await agentManager.cancel(sessionId);\n },\n\n async setMode(sessionId: string, modeId: string): Promise<void> {\n await agentManager.setMode(sessionId, modeId);\n },\n\n async setModel(sessionId: string, modelId: string): Promise<void> {\n await agentManager.setModel(sessionId, modelId);\n },\n\n respondPermission(sessionId: string, requestId: string, optionId: string): void {\n agentManager.respondPermission(sessionId, requestId, optionId);\n },\n\n async switchAgent(sessionId: string, agentConfigId: string): Promise<void> {\n // Stop old agent\n await agentManager.stopForSession(sessionId);\n // Clear events\n clearEventsForSession(sessionId);\n // Update session\n db.update(sessions)\n .set({\n agentConfigId,\n acpSessionId: null,\n model: null,\n mode: null,\n })\n .where(eq(sessions.id, sessionId))\n .run();\n // Save as last used\n db.insert(appState)\n .values({ key: 'last_used_agent_config_id', value: agentConfigId })\n .onConflictDoUpdate({ target: appState.key, set: { value: agentConfigId } })\n .run();\n },\n\n subscribeToSession(sessionId: string, callback: (update: WindowUpdate) => void): () => void {\n const handler = (event: { sessionId: string; update: WindowUpdate }) => {\n if (event.sessionId === sessionId) {\n callback(event.update);\n }\n };\n agentManager.on('update', handler);\n return () => agentManager.off('update', handler);\n },\n\n async listFilesForAutocomplete(sessionId: string, partialPath: string, limit: number): Promise<FileEntry[]> {\n const session = db.select().from(sessions).where(eq(sessions.id, sessionId)).get();\n if (!session) throw new Error(`Session ${sessionId} not found`);\n return listFilesForAutocomplete(session.directory, partialPath, limit);\n },\n };\n}\n","import { initTRPC } from '@trpc/server';\n\nconst t = initTRPC.create();\n\nexport const router = t.router;\nexport const publicProcedure = t.procedure;\n","import { z } from 'zod';\nimport { randomUUID } from 'crypto';\nimport { eq } from 'drizzle-orm';\nimport { router, publicProcedure } from './trpc.js';\nimport { db } from '../db/index.js';\nimport { windows, panes, uiState } from '../db/schema.js';\nimport { createLeaf, type LayoutNode } from '../../client/lib/layout.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\n// AmuxBridge is injected at server startup\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\nfunction generateTitle(existingCount: number, directory: string): string {\n // Use directory name as title, or generic \"Window N\"\n const dirName = directory.split('/').pop();\n if (dirName && dirName !== '~' && dirName !== '') {\n return dirName;\n }\n return `Window ${existingCount + 1}`;\n}\n\nexport const windowsRouter = router({\n /**\n * List all windows with their panes and sessions.\n */\n list: publicProcedure.query(async () => {\n const allWindows = db.select().from(windows).orderBy(windows.createdAt).all();\n const allPanes = db.select().from(panes).all();\n const activeRow = db.select().from(uiState).where(eq(uiState.key, 'active_window_id')).get();\n\n // Get all unique session IDs\n const sessionIds = [...new Set(allPanes.map(p => p.sessionId))];\n\n // Fetch sessions from amux\n const sessionsData = await amux.getSessions(sessionIds);\n const sessionMap = new Map(sessionsData.map(s => [s.id, s]));\n\n // Get agent configs from amux\n const agentConfigs = await amux.getAgentConfigs();\n\n return {\n windows: allWindows.map(w => ({\n ...w,\n panes: allPanes\n .filter(p => p.windowId === w.id)\n .map(p => ({\n ...p,\n session: sessionMap.get(p.sessionId) ?? null,\n })),\n })),\n activeWindowId: activeRow?.value ?? allWindows[allWindows.length - 1]?.id ?? null,\n agentConfigs,\n };\n }),\n\n /**\n * Get a single window by ID.\n */\n get: publicProcedure\n .input(z.object({ id: z.string() }))\n .query(async ({ input }) => {\n const window = db.select().from(windows).where(eq(windows.id, input.id)).get();\n if (!window) {\n throw new Error(`Window ${input.id} not found`);\n }\n const windowPanes = db.select().from(panes).where(eq(panes.windowId, input.id)).all();\n\n // Fetch sessions\n const sessionIds = windowPanes.map(p => p.sessionId);\n const sessionsData = await amux.getSessions(sessionIds);\n const sessionMap = new Map(sessionsData.map(s => [s.id, s]));\n\n return {\n ...window,\n panes: windowPanes.map(p => ({\n ...p,\n session: sessionMap.get(p.sessionId) ?? null,\n })),\n };\n }),\n\n /**\n * Create a new window with a single pane.\n */\n create: publicProcedure\n .input(z.object({\n id: z.string().optional(),\n title: z.string().optional(),\n directory: z.string().optional(),\n agentConfigId: z.string().optional(),\n }))\n .mutation(async ({ input }) => {\n const directory = input.directory ?? process.cwd();\n\n // 1. Create session in amux\n const session = await amux.createSession({\n directory,\n agentConfigId: input.agentConfigId,\n });\n\n // 2. Create window + pane in shella\n const windowId = input.id ?? randomUUID();\n const paneId = randomUUID();\n const existingCount = db.select().from(windows).all().length;\n const layout: LayoutNode = createLeaf(paneId);\n\n db.insert(windows).values({\n id: windowId,\n title: input.title || generateTitle(existingCount, directory),\n hasCustomTitle: !!input.title, // Only true if title is non-empty string\n layout,\n activePaneId: paneId,\n }).run();\n\n db.insert(panes).values({\n id: paneId,\n windowId,\n sessionId: session.id,\n }).run();\n\n // 3. Set as active window\n db.insert(uiState)\n .values({ key: 'active_window_id', value: windowId })\n .onConflictDoUpdate({ target: uiState.key, set: { value: windowId } })\n .run();\n\n // Fetch the full window with panes for the response\n const newWindow = db.select().from(windows).where(eq(windows.id, windowId)).get()!;\n const newPanes = db.select().from(panes).where(eq(panes.windowId, windowId)).all();\n\n return {\n ...newWindow,\n panes: newPanes.map(p => ({\n ...p,\n session: p.sessionId === session.id ? session : null,\n })),\n };\n }),\n\n /**\n * Update a window (title, etc).\n */\n update: publicProcedure\n .input(z.object({\n id: z.string(),\n title: z.string().optional(),\n }))\n .mutation(async ({ input }) => {\n const updates: Record<string, unknown> = {};\n if (input.title !== undefined) {\n updates.title = input.title;\n updates.hasCustomTitle = true;\n }\n updates.lastAccessedAt = new Date();\n\n db.update(windows)\n .set(updates)\n .where(eq(windows.id, input.id))\n .run();\n\n return db.select().from(windows).where(eq(windows.id, input.id)).get()!;\n }),\n\n /**\n * Delete a window and all its panes/sessions.\n */\n delete: publicProcedure\n .input(z.object({ id: z.string() }))\n .mutation(async ({ input }) => {\n // Get all panes for this window\n const windowPanes = db.select().from(panes).where(eq(panes.windowId, input.id)).all();\n\n // Delete sessions in amux\n for (const pane of windowPanes) {\n await amux.deleteSession(pane.sessionId);\n }\n\n // Delete window (cascades to panes)\n db.delete(windows).where(eq(windows.id, input.id)).run();\n\n // Update active window if needed\n const activeRow = db.select().from(uiState).where(eq(uiState.key, 'active_window_id')).get();\n if (activeRow?.value === input.id) {\n const remaining = db.select().from(windows).orderBy(windows.createdAt).all();\n const newActiveId = remaining[remaining.length - 1]?.id ?? null;\n if (newActiveId) {\n db.update(uiState)\n .set({ value: newActiveId })\n .where(eq(uiState.key, 'active_window_id'))\n .run();\n } else {\n db.delete(uiState).where(eq(uiState.key, 'active_window_id')).run();\n }\n }\n\n return { ok: true };\n }),\n\n /**\n * Set the active window.\n */\n setActive: publicProcedure\n .input(z.object({ id: z.string() }))\n .mutation(async ({ input }) => {\n db.insert(uiState)\n .values({ key: 'active_window_id', value: input.id })\n .onConflictDoUpdate({ target: uiState.key, set: { value: input.id } })\n .run();\n\n // Update last accessed\n db.update(windows)\n .set({ lastAccessedAt: new Date() })\n .where(eq(windows.id, input.id))\n .run();\n\n return { ok: true };\n }),\n});\n","/**\n * Layout types for tmux-like pane splitting.\n *\n * Layout is a binary tree where:\n * - Leaf nodes are panes (contain a paneId)\n * - Branch nodes split space horizontally or vertically\n */\n\nexport type SplitDirection = 'horizontal' | 'vertical';\n\nexport interface LayoutLeaf {\n type: 'leaf';\n paneId: string;\n}\n\nexport interface LayoutBranch {\n type: 'branch';\n direction: SplitDirection;\n /** Percentage of space for first child (0-100) */\n ratio: number;\n first: LayoutNode;\n second: LayoutNode;\n}\n\nexport type LayoutNode = LayoutLeaf | LayoutBranch;\n\n/**\n * Create a leaf node for a pane.\n */\nexport function createLeaf(paneId: string): LayoutLeaf {\n return { type: 'leaf', paneId };\n}\n\n/**\n * Create a branch node splitting two children.\n */\nexport function createBranch(\n direction: SplitDirection,\n first: LayoutNode,\n second: LayoutNode,\n ratio = 50\n): LayoutBranch {\n return { type: 'branch', direction, ratio, first, second };\n}\n\n/**\n * Find all pane IDs in a layout tree.\n */\nexport function getAllPaneIds(node: LayoutNode): string[] {\n if (node.type === 'leaf') {\n return [node.paneId];\n }\n return [...getAllPaneIds(node.first), ...getAllPaneIds(node.second)];\n}\n\n/**\n * Find a pane in the layout and return its path.\n * Returns null if not found.\n */\nexport function findPanePath(\n node: LayoutNode,\n paneId: string,\n path: ('first' | 'second')[] = []\n): ('first' | 'second')[] | null {\n if (node.type === 'leaf') {\n return node.paneId === paneId ? path : null;\n }\n const firstPath = findPanePath(node.first, paneId, [...path, 'first']);\n if (firstPath) return firstPath;\n return findPanePath(node.second, paneId, [...path, 'second']);\n}\n\n/**\n * Replace a pane in the layout with a new node.\n */\nexport function replacePaneWithNode(\n root: LayoutNode,\n paneId: string,\n newNode: LayoutNode\n): LayoutNode {\n if (root.type === 'leaf') {\n return root.paneId === paneId ? newNode : root;\n }\n return {\n ...root,\n first: replacePaneWithNode(root.first, paneId, newNode),\n second: replacePaneWithNode(root.second, paneId, newNode),\n };\n}\n\n/**\n * Split a pane, creating a new branch with the original and new pane.\n */\nexport function splitPane(\n root: LayoutNode,\n paneId: string,\n newPaneId: string,\n direction: SplitDirection\n): LayoutNode {\n const originalLeaf = createLeaf(paneId);\n const newLeaf = createLeaf(newPaneId);\n const branch = createBranch(direction, originalLeaf, newLeaf);\n return replacePaneWithNode(root, paneId, branch);\n}\n\n/**\n * Remove a pane from the layout.\n * Returns the modified layout, or null if removing the only pane.\n */\nexport function removePane(root: LayoutNode, paneId: string): LayoutNode | null {\n if (root.type === 'leaf') {\n return root.paneId === paneId ? null : root;\n }\n\n // Check if either child is the pane to remove\n if (root.first.type === 'leaf' && root.first.paneId === paneId) {\n return root.second;\n }\n if (root.second.type === 'leaf' && root.second.paneId === paneId) {\n return root.first;\n }\n\n // Recursively remove from children\n const newFirst = removePane(root.first, paneId);\n const newSecond = removePane(root.second, paneId);\n\n // If a child was removed entirely, return the other\n if (newFirst === null) return newSecond;\n if (newSecond === null) return newFirst;\n\n // If either child changed, return updated branch\n if (newFirst !== root.first || newSecond !== root.second) {\n return { ...root, first: newFirst, second: newSecond };\n }\n\n return root;\n}\n\n/**\n * Update the split ratio at a specific path.\n */\nexport function updateRatio(\n root: LayoutNode,\n path: ('first' | 'second')[],\n newRatio: number\n): LayoutNode {\n if (path.length === 0) {\n if (root.type === 'branch') {\n return { ...root, ratio: Math.max(10, Math.min(90, newRatio)) };\n }\n return root;\n }\n\n if (root.type === 'leaf') return root;\n\n const [next, ...rest] = path;\n if (next === 'first') {\n return { ...root, first: updateRatio(root.first, rest, newRatio) };\n } else {\n return { ...root, second: updateRatio(root.second, rest, newRatio) };\n }\n}\n\n/**\n * Get the sibling pane ID when navigating in a direction.\n * Returns null if there's no sibling in that direction.\n */\nexport function getAdjacentPane(\n root: LayoutNode,\n currentPaneId: string,\n direction: 'left' | 'right' | 'up' | 'down'\n): string | null {\n const path = findPanePath(root, currentPaneId);\n if (!path) return null;\n\n // Navigate up the tree to find a branch going the right direction\n let node = root;\n const pathNodes: { node: LayoutBranch; childSide: 'first' | 'second' }[] = [];\n\n for (const step of path) {\n if (node.type === 'branch') {\n pathNodes.push({ node, childSide: step });\n node = step === 'first' ? node.first : node.second;\n }\n }\n\n // Find the closest branch that allows movement in the desired direction\n for (let i = pathNodes.length - 1; i >= 0; i--) {\n const { node: branch, childSide } = pathNodes[i];\n const isHorizontal = branch.direction === 'horizontal';\n const isVertical = branch.direction === 'vertical';\n\n // Check if this branch allows movement in the desired direction\n const canMove =\n (direction === 'left' && isHorizontal && childSide === 'second') ||\n (direction === 'right' && isHorizontal && childSide === 'first') ||\n (direction === 'up' && isVertical && childSide === 'second') ||\n (direction === 'down' && isVertical && childSide === 'first');\n\n if (canMove) {\n // Get the other child and find the closest pane in it\n const otherChild = childSide === 'first' ? branch.second : branch.first;\n return getFirstPaneInDirection(otherChild, direction);\n }\n }\n\n return null;\n}\n\n/**\n * Get the first pane when entering a subtree from a direction.\n */\nfunction getFirstPaneInDirection(\n node: LayoutNode,\n fromDirection: 'left' | 'right' | 'up' | 'down'\n): string {\n if (node.type === 'leaf') {\n return node.paneId;\n }\n\n // When entering from left, prefer the leftmost pane (first in horizontal split)\n // When entering from right, prefer the rightmost pane (second in horizontal split)\n // Similar for up/down with vertical splits\n const isHorizontal = node.direction === 'horizontal';\n\n if (fromDirection === 'left' || fromDirection === 'up') {\n // Coming from left/up, go to the first (left/top) child\n const targetChild = isHorizontal\n ? (fromDirection === 'left' ? node.first : node.first)\n : (fromDirection === 'up' ? node.first : node.first);\n return getFirstPaneInDirection(targetChild, fromDirection);\n } else {\n // Coming from right/down, go to the second (right/bottom) child\n const targetChild = isHorizontal\n ? (fromDirection === 'right' ? node.second : node.second)\n : (fromDirection === 'down' ? node.second : node.second);\n return getFirstPaneInDirection(targetChild, fromDirection);\n }\n}\n","import { z } from 'zod';\nimport { randomUUID } from 'crypto';\nimport { eq } from 'drizzle-orm';\nimport { router, publicProcedure } from './trpc.js';\nimport { db } from '../db/index.js';\nimport { windows, panes } from '../db/schema.js';\nimport {\n splitPane,\n removePane,\n getAllPaneIds,\n getAdjacentPane,\n updateRatio,\n type LayoutNode,\n type SplitDirection,\n} from '../../client/lib/layout.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\nexport const layoutRouter = router({\n /**\n * Split a pane horizontally or vertically.\n * Creates a new session in amux and a new pane in shella.\n */\n split: publicProcedure\n .input(z.object({\n windowId: z.string(),\n paneId: z.string(),\n direction: z.enum(['horizontal', 'vertical']),\n // Client can provide IDs for optimistic updates\n newPaneId: z.string().optional(),\n newSessionId: z.string().optional(),\n }))\n .mutation(async ({ input }) => {\n // 1. Get source pane and its session\n const sourcePane = db.select().from(panes).where(eq(panes.id, input.paneId)).get();\n if (!sourcePane) {\n throw new Error(`Pane ${input.paneId} not found`);\n }\n\n const sourceSession = await amux.getSession(sourcePane.sessionId);\n if (!sourceSession) {\n throw new Error(`Session ${sourcePane.sessionId} not found`);\n }\n\n // 2. Create new session in amux (inherits directory and agent config)\n // Use client-provided ID if available for optimistic updates\n const newSession = await amux.createSession({\n id: input.newSessionId,\n directory: sourceSession.directory,\n agentConfigId: sourceSession.agentConfigId,\n });\n\n // 3. Create new pane (use client-provided ID if available)\n const newPaneId = input.newPaneId ?? randomUUID();\n db.insert(panes).values({\n id: newPaneId,\n windowId: input.windowId,\n sessionId: newSession.id,\n }).run();\n\n // 4. Update window layout\n const window = db.select().from(windows).where(eq(windows.id, input.windowId)).get();\n if (!window) {\n throw new Error(`Window ${input.windowId} not found`);\n }\n\n const currentLayout = window.layout as LayoutNode;\n const newLayout = splitPane(currentLayout, input.paneId, newPaneId, input.direction as SplitDirection);\n\n db.update(windows)\n .set({\n layout: newLayout,\n activePaneId: newPaneId,\n lastAccessedAt: new Date(),\n })\n .where(eq(windows.id, input.windowId))\n .run();\n\n // 5. Start agent for new pane\n await amux.startAgent(newSession.id);\n\n const now = new Date();\n return {\n newPaneId,\n newSessionId: newSession.id,\n layout: newLayout,\n // Match exact shape from windows.list: { ...pane, session }\n newPane: {\n id: newPaneId,\n windowId: input.windowId,\n sessionId: newSession.id,\n createdAt: now.toISOString(),\n session: {\n id: newSession.id,\n directory: newSession.directory,\n agentConfigId: newSession.agentConfigId,\n model: newSession.model,\n mode: newSession.mode,\n createdAt: newSession.createdAt.toISOString(),\n acpSessionId: newSession.acpSessionId,\n },\n },\n };\n }),\n\n /**\n * Close a pane. If it's the last pane, close the window.\n */\n closePane: publicProcedure\n .input(z.object({\n windowId: z.string(),\n paneId: z.string(),\n }))\n .mutation(async ({ input }) => {\n const window = db.select().from(windows).where(eq(windows.id, input.windowId)).get();\n if (!window) {\n throw new Error(`Window ${input.windowId} not found`);\n }\n\n const pane = db.select().from(panes).where(eq(panes.id, input.paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${input.paneId} not found`);\n }\n\n const currentLayout = window.layout as LayoutNode;\n const allPaneIds = getAllPaneIds(currentLayout);\n\n // Check if this is the last pane\n if (allPaneIds.length === 1) {\n // Delete session in amux\n await amux.deleteSession(pane.sessionId);\n // Delete window (cascades to pane)\n db.delete(windows).where(eq(windows.id, input.windowId)).run();\n return { windowClosed: true, layout: null, activePaneId: null };\n }\n\n // Delete session in amux\n await amux.deleteSession(pane.sessionId);\n // Delete pane\n db.delete(panes).where(eq(panes.id, input.paneId)).run();\n\n // Update layout\n const newLayout = removePane(currentLayout, input.paneId);\n if (!newLayout) {\n throw new Error('Failed to remove pane from layout');\n }\n\n // Determine new active pane\n const newActivePaneId = window.activePaneId === input.paneId\n ? getAllPaneIds(newLayout)[0]\n : window.activePaneId;\n\n db.update(windows)\n .set({\n layout: newLayout,\n activePaneId: newActivePaneId,\n lastAccessedAt: new Date(),\n })\n .where(eq(windows.id, input.windowId))\n .run();\n\n return {\n windowClosed: false,\n layout: newLayout,\n activePaneId: newActivePaneId,\n };\n }),\n\n /**\n * Set the active pane within a window.\n */\n setActivePane: publicProcedure\n .input(z.object({\n windowId: z.string(),\n paneId: z.string(),\n }))\n .mutation(async ({ input }) => {\n db.update(windows)\n .set({\n activePaneId: input.paneId,\n lastAccessedAt: new Date(),\n })\n .where(eq(windows.id, input.windowId))\n .run();\n\n return { ok: true };\n }),\n\n /**\n * Navigate to an adjacent pane.\n */\n navigate: publicProcedure\n .input(z.object({\n windowId: z.string(),\n currentPaneId: z.string(),\n direction: z.enum(['left', 'right', 'up', 'down']),\n }))\n .mutation(async ({ input }) => {\n const window = db.select().from(windows).where(eq(windows.id, input.windowId)).get();\n if (!window) {\n throw new Error(`Window ${input.windowId} not found`);\n }\n\n const currentLayout = window.layout as LayoutNode;\n const adjacentPaneId = getAdjacentPane(currentLayout, input.currentPaneId, input.direction);\n\n if (adjacentPaneId) {\n db.update(windows)\n .set({\n activePaneId: adjacentPaneId,\n lastAccessedAt: new Date(),\n })\n .where(eq(windows.id, input.windowId))\n .run();\n\n return { newActivePaneId: adjacentPaneId };\n }\n\n return { newActivePaneId: null };\n }),\n\n /**\n * Update the split ratio at a specific position.\n */\n setRatio: publicProcedure\n .input(z.object({\n windowId: z.string(),\n path: z.array(z.enum(['first', 'second'])),\n ratio: z.number().min(10).max(90),\n }))\n .mutation(async ({ input }) => {\n const window = db.select().from(windows).where(eq(windows.id, input.windowId)).get();\n if (!window) {\n throw new Error(`Window ${input.windowId} not found`);\n }\n\n const currentLayout = window.layout as LayoutNode;\n const newLayout = updateRatio(currentLayout, input.path, input.ratio);\n\n db.update(windows)\n .set({ layout: newLayout })\n .where(eq(windows.id, input.windowId))\n .run();\n\n return { layout: newLayout };\n }),\n});\n","import { z } from 'zod';\nimport { eq } from 'drizzle-orm';\nimport { observable } from '@trpc/server/observable';\nimport { router, publicProcedure } from './trpc.js';\nimport { db } from '../db/index.js';\nimport { panes } from '../db/schema.js';\nimport type { WindowUpdate } from '@bytespell/amux/types';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\nconst paneInput = z.object({\n paneId: z.string(),\n});\n\n// Helper to get sessionId from paneId\nfunction getSessionIdForPane(paneId: string): string {\n const pane = db.select().from(panes).where(eq(panes.id, paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${paneId} not found`);\n }\n return pane.sessionId;\n}\n\nexport const agentsRouter = router({\n /**\n * Start agent for a pane.\n */\n start: publicProcedure\n .input(paneInput)\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n return amux.startAgent(sessionId);\n }),\n\n /**\n * Stop agent for a pane.\n */\n stop: publicProcedure\n .input(paneInput)\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n await amux.stopAgent(sessionId);\n return { ok: true };\n }),\n\n /**\n * Send a prompt to a pane's agent.\n */\n prompt: publicProcedure\n .input(z.object({\n paneId: z.string(),\n message: z.string(),\n }))\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n await amux.prompt(sessionId, input.message);\n return { ok: true };\n }),\n\n /**\n * Cancel the current prompt.\n */\n cancel: publicProcedure\n .input(paneInput)\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n await amux.cancel(sessionId);\n return { ok: true };\n }),\n\n /**\n * Set agent mode.\n */\n setMode: publicProcedure\n .input(z.object({\n paneId: z.string(),\n modeId: z.string(),\n }))\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n await amux.setMode(sessionId, input.modeId);\n return { ok: true };\n }),\n\n /**\n * Set agent model.\n */\n setModel: publicProcedure\n .input(z.object({\n paneId: z.string(),\n modelId: z.string(),\n }))\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n await amux.setModel(sessionId, input.modelId);\n return { ok: true };\n }),\n\n /**\n * Respond to a permission request.\n */\n respondPermission: publicProcedure\n .input(z.object({\n paneId: z.string(),\n requestId: z.string(),\n optionId: z.string(),\n }))\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n amux.respondPermission(sessionId, input.requestId, input.optionId);\n return { ok: true };\n }),\n\n /**\n * Switch to a different agent.\n */\n switchAgent: publicProcedure\n .input(z.object({\n paneId: z.string(),\n agentConfigId: z.string(),\n }))\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n await amux.switchAgent(sessionId, input.agentConfigId);\n return { ok: true };\n }),\n\n /**\n * Subscribe to updates for a pane's agent session.\n */\n subscribe: publicProcedure\n .input(paneInput)\n .subscription(({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n return observable<WindowUpdate>((emit) => {\n return amux.subscribeToSession(sessionId, (update) => {\n emit.next(update);\n });\n });\n }),\n});\n","import { z } from 'zod';\nimport { eq } from 'drizzle-orm';\nimport { router, publicProcedure } from './trpc.js';\nimport { db } from '../db/index.js';\nimport { panes } from '../db/schema.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\n// Helper to get sessionId from paneId\nfunction getSessionIdForPane(paneId: string): string {\n const pane = db.select().from(panes).where(eq(panes.id, paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${paneId} not found`);\n }\n return pane.sessionId;\n}\n\nexport const filesRouter = router({\n /**\n * List files/directories matching a partial path for autocomplete.\n * Returns files in the session's working directory.\n */\n listForAutocomplete: publicProcedure\n .input(z.object({\n paneId: z.string(),\n partialPath: z.string(),\n limit: z.number().default(20),\n }))\n .query(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n return amux.listFilesForAutocomplete(sessionId, input.partialPath, input.limit);\n }),\n});\n","import { router } from './trpc.js';\nimport { windowsRouter, setAmuxBridge as setWindowsAmux } from './windows.js';\nimport { layoutRouter, setAmuxBridge as setLayoutAmux } from './layout.js';\nimport { agentsRouter, setAmuxBridge as setAgentsAmux } from './agents.js';\nimport { filesRouter, setAmuxBridge as setFilesAmux } from './files.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\n/**\n * Initialize all routers with the amux bridge.\n * Must be called before any routes are used.\n */\nexport function initializeRouters(amux: AmuxBridge) {\n setWindowsAmux(amux);\n setLayoutAmux(amux);\n setAgentsAmux(amux);\n setFilesAmux(amux);\n}\n\n/**\n * Shella's tRPC router.\n *\n * Provides UI-layer endpoints:\n * - windows: Window CRUD (with panes)\n * - layout: Split, close, navigate panes\n * - agents: Proxy to amux for agent operations\n */\nexport const shellaRouter = router({\n windows: windowsRouter,\n layout: layoutRouter,\n agents: agentsRouter,\n files: filesRouter,\n});\n\nexport type ShellaRouter = typeof shellaRouter;\n"],"mappings":"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","names":["path","agentManager","db","randomUUID","eq","path","eq","p","agentConfigs","randomUUID","z","randomUUID","eq","amux","setAmuxBridge","z","eq","randomUUID","z","eq","amux","setAmuxBridge","z","eq","z","eq","amux","setAmuxBridge","getSessionIdForPane","eq","z","amux","setAmuxBridge","path","agentManager","text","log"]}
|
|
1
|
+
{"version":3,"sources":["../../bin/cli.ts","../../src/index.ts","../../src/db/index.ts","../../src/lib/paths.ts","../../src/db/schema.ts","../../src/amuxBridge.ts","../../src/trpc/trpc.ts","../../src/trpc/windows.ts","../../client/lib/layout.ts","../../src/trpc/layout.ts","../../src/trpc/agents.ts","../../src/trpc/files.ts","../../src/trpc/terminals.ts","../../src/trpc/router.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Shella CLI - Self-hosted AI coding agents\n *\n * Usage:\n * npx @bytespell/shella Start in current directory\n * npx @bytespell/shella --port 3070 Custom port\n */\n\nimport { program } from 'commander';\nimport { networkInterfaces } from 'os';\nimport { spawn } from 'child_process';\nimport * as p from '@clack/prompts';\nimport { createShellaServer } from '../src/index.js';\n\nconst VERSION = '0.1.0';\n\n// Brand color (indigo) for terminal output\nconst BRAND = '\\x1b[38;2;99;102;241m'; // rgb(99, 102, 241)\nconst RESET = '\\x1b[0m';\nconst DIM = '\\x1b[2m';\nconst brand = (text: string) => `${BRAND}${text}${RESET}`;\nconst dim = (text: string) => `${DIM}${text}${RESET}`;\n\nfunction getLanIp(): string {\n const interfaces = networkInterfaces();\n for (const [name, addrs] of Object.entries(interfaces)) {\n if (/^(lo|docker|veth|br-|virbr)/.test(name)) continue;\n for (const addr of addrs || []) {\n if (addr.family === 'IPv4' && !addr.internal) {\n return addr.address;\n }\n }\n }\n return 'localhost';\n}\n\ninterface StartOptions {\n port: string;\n open: boolean;\n verbose: boolean;\n}\n\nasync function startCommand(options: StartOptions) {\n const port = parseInt(options.port, 10);\n const verbose = options.verbose;\n\n const s = verbose ? null : p.spinner();\n const log = (msg: string) => verbose && console.log(msg);\n\n if (!verbose) {\n p.intro(`${brand('shella')} ${dim(`v${VERSION}`)}`);\n } else {\n log(`${brand('shella')} ${dim(`v${VERSION}`)}`);\n }\n\n if (s) s.start('Starting server...');\n else log('Starting server...');\n\n const shella = createShellaServer({\n port,\n verbose,\n onReady: (url) => {\n if (s) s.stop('Ready');\n\n const lanIp = getLanIp();\n const lanUrl = `http://${lanIp}:${port}`;\n\n if (verbose) {\n log(`\\n${brand(lanUrl)}`);\n log(dim('access from any device'));\n log(`\\n${dim('press ctrl+c to stop')}\\n`);\n } else {\n p.log.success(`${brand(lanUrl)}`);\n p.log.message(dim('access from any device'));\n p.outro(dim('press ctrl+c to stop'));\n }\n\n // Open browser if requested\n if (options.open) {\n const openCommand =\n process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';\n spawn(openCommand, [url], { stdio: 'ignore', detached: true }).unref();\n }\n },\n });\n\n try {\n await shella.start();\n } catch (err) {\n if (s) s.stop('Failed');\n p.log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n\n // Graceful shutdown\n const shutdown = async () => {\n console.log('');\n console.log(dim('stopping...'));\n await shella.stop();\n console.log(`${brand('shella')} ${dim('stopped')}`);\n process.exit(0);\n };\n\n process.on('SIGTERM', shutdown);\n process.on('SIGINT', shutdown);\n}\n\nprogram\n .name('shella')\n .description(`${brand('shella')} - Self-hosted AI coding agents. Access from your phone.`)\n .version(VERSION)\n .option('-p, --port <port>', 'Server port', '3067')\n .option('--no-open', \"Don't open browser automatically\")\n .option('-v, --verbose', 'Show detailed logs', false)\n .action(startCommand);\n\nprogram.parse();\n","/**\n * Shella Server - Full product combining Amux + UI\n *\n * Creates a server that:\n * 1. Initializes Shella's database (windows, panes, ui_state)\n * 2. Creates an amux bridge for session/agent operations\n * 3. Serves the bundled UI static files\n * 4. Mounts Shella's tRPC API at /trpc (which proxies to amux internally)\n * 5. Handles WebSocket connections for subscriptions\n */\n\nimport express from 'express';\nimport { createServer } from 'http';\nimport { WebSocketServer } from 'ws';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport { createExpressMiddleware } from '@trpc/server/adapters/express';\nimport { applyWSSHandler } from '@trpc/server/adapters/ws';\nimport { agentManager } from '@bytespell/amux/agents/manager';\nimport { setVerbose, debug } from '@bytespell/amux/lib/logger';\n\n// Import to trigger amux database initialization\nimport '@bytespell/amux/db';\n\n// Import to trigger shella database initialization\nimport './db/index.js';\n\nimport { createAmuxBridge } from './amuxBridge.js';\nimport { shellaRouter, initializeRouters } from './trpc/router.js';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport interface ShellaServerOptions {\n port?: number;\n verbose?: boolean;\n onReady?: (url: string) => void;\n}\n\nexport interface ShellaServer {\n start: () => Promise<void>;\n stop: () => Promise<void>;\n}\n\nexport function createShellaServer(options: ShellaServerOptions = {}): ShellaServer {\n const port = options.port ?? 3067;\n\n // Configure verbose logging\n if (options.verbose) {\n setVerbose(true);\n }\n\n // Initialize amux bridge\n const amuxBridge = createAmuxBridge();\n\n // Initialize routers with the bridge\n initializeRouters(amuxBridge);\n\n // Create main express app\n const app = express();\n app.use(express.json());\n\n // Serve static UI files first\n const publicPath = path.join(__dirname, '..', 'public');\n app.use(express.static(publicPath));\n\n // tRPC HTTP endpoint\n app.use('/trpc', createExpressMiddleware({ router: shellaRouter }));\n\n // Health check\n app.get('/health', (_req, res) => res.json({ status: 'ok' }));\n\n // SPA fallback - serve index.html for all non-API routes\n // Express 5 requires named parameter for wildcards\n app.get('/{*splat}', (_req, res) => {\n res.sendFile(path.join(publicPath, 'index.html'));\n });\n\n // Create HTTP server\n const server = createServer(app);\n\n // WebSocket for subscriptions\n const wss = new WebSocketServer({ server, path: '/trpc' });\n applyWSSHandler({ wss, router: shellaRouter });\n\n return {\n start: () => {\n return new Promise((resolve, reject) => {\n server.once('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n reject(new Error(`Port ${port} is already in use. Kill the other process or use a different port.`));\n } else {\n reject(err);\n }\n });\n\n server.listen(port, () => {\n const url = `http://localhost:${port}`;\n debug('shella', `Running on ${url}`);\n options.onReady?.(url);\n resolve();\n });\n });\n },\n\n stop: async () => {\n debug('shella', 'Shutting down...');\n wss.close();\n await agentManager.stopAll();\n server.close();\n },\n };\n}\n\n// Re-export router type for UI\nexport { shellaRouter, type ShellaRouter } from './trpc/router.js';\n","import Database from 'better-sqlite3';\nimport { drizzle } from 'drizzle-orm/better-sqlite3';\nimport { getShellaDbPath, ensureDir, getDataDir } from '../lib/paths.js';\nimport * as schema from './schema.js';\n\nensureDir(getDataDir());\n\nconst sqlite = new Database(getShellaDbPath());\nsqlite.pragma('journal_mode = WAL');\nsqlite.pragma('foreign_keys = ON');\n\nexport const db = drizzle(sqlite, { schema });\n\n// Create tables if they don't exist\nsqlite.exec(`\n CREATE TABLE IF NOT EXISTS windows (\n id TEXT PRIMARY KEY,\n title TEXT NOT NULL,\n has_custom_title INTEGER NOT NULL DEFAULT 0,\n layout TEXT NOT NULL,\n active_pane_id TEXT NOT NULL,\n created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000),\n last_accessed_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)\n );\n\n CREATE TABLE IF NOT EXISTS panes (\n id TEXT PRIMARY KEY,\n window_id TEXT NOT NULL REFERENCES windows(id) ON DELETE CASCADE,\n content TEXT,\n created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)\n );\n\n CREATE TABLE IF NOT EXISTS ui_state (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n`);\n\n// Migration: Convert session_id column to content JSON column\n// This migrates from the old schema where panes had session_id to the new\n// schema where panes have a content JSON object with type discrimination\ntry {\n const tableInfo = sqlite.prepare('PRAGMA table_info(panes)').all() as Array<{\n name: string;\n notnull: number;\n }>;\n const hasSessionId = tableInfo.some((col) => col.name === 'session_id');\n const hasContent = tableInfo.some((col) => col.name === 'content');\n\n if (hasSessionId && !hasContent) {\n // Old schema with session_id, need to migrate to content\n sqlite.exec(`\n -- Disable foreign keys temporarily\n PRAGMA foreign_keys = OFF;\n\n -- Create new table with content column\n CREATE TABLE panes_new (\n id TEXT PRIMARY KEY,\n window_id TEXT NOT NULL REFERENCES windows(id) ON DELETE CASCADE,\n content TEXT,\n created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)\n );\n\n -- Copy data, converting session_id to content JSON\n INSERT INTO panes_new (id, window_id, content, created_at)\n SELECT\n id,\n window_id,\n CASE\n WHEN session_id IS NOT NULL THEN json_object('type', 'session', 'sessionId', session_id)\n ELSE NULL\n END,\n created_at\n FROM panes;\n\n -- Drop old table and rename new\n DROP TABLE panes;\n ALTER TABLE panes_new RENAME TO panes;\n\n -- Re-enable foreign keys\n PRAGMA foreign_keys = ON;\n `);\n console.log('[shella-db] Migrated panes from session_id to content column');\n }\n} catch {\n // Migration not needed or already done\n}\n\nexport { schema };\n","import path from 'path';\nimport os from 'os';\nimport fs from 'fs';\n\n/**\n * Get the data directory following XDG Base Directory spec\n * Shared with amux in the same directory.\n */\nexport function getDataDir(): string {\n const home = os.homedir();\n\n let dataDir: string;\n\n switch (process.platform) {\n case 'darwin':\n dataDir = path.join(home, 'Library', 'Application Support', 'shella');\n break;\n case 'win32':\n dataDir = path.join(process.env.APPDATA || path.join(home, 'AppData', 'Roaming'), 'shella');\n break;\n default:\n // Linux and others - follow XDG spec\n dataDir = path.join(process.env.XDG_DATA_HOME || path.join(home, '.local', 'share'), 'shella');\n }\n\n return dataDir;\n}\n\n/**\n * Check if running in mock mode\n */\nexport function isMockMode(): boolean {\n return process.env.SHELLA_MOCK_MODE === 'true';\n}\n\n/**\n * Get the path to Shella's database file (UI state: windows, panes, layouts)\n * This is separate from amux's database (sessions, events, agent configs)\n */\nexport function getShellaDbPath(): string {\n const filename = isMockMode() ? 'shella-ui.mock.db' : 'shella-ui.db';\n return path.join(getDataDir(), filename);\n}\n\n/**\n * Ensure a directory exists, creating it if necessary\n */\nexport function ensureDir(dir: string): void {\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n}\n","import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';\nimport { sql } from 'drizzle-orm';\nimport type { LayoutNode } from '../../client/lib/layout.js';\n\n/**\n * Windows - top-level UI containers with layout trees.\n * Each window contains one or more panes arranged in a layout.\n */\nexport const windows = sqliteTable('windows', {\n id: text('id').primaryKey(),\n title: text('title').notNull(),\n hasCustomTitle: integer('has_custom_title', { mode: 'boolean' }).notNull().default(false),\n /** JSON-serialized LayoutNode tree */\n layout: text('layout', { mode: 'json' }).$type<LayoutNode>().notNull(),\n activePaneId: text('active_pane_id').notNull(),\n createdAt: integer('created_at', { mode: 'timestamp_ms' })\n .notNull()\n .default(sql`(unixepoch() * 1000)`),\n lastAccessedAt: integer('last_accessed_at', { mode: 'timestamp_ms' })\n .notNull()\n .default(sql`(unixepoch() * 1000)`),\n});\n\n/**\n * Pane content types - tagged union for what a pane displays.\n * - session: References an amux session (agent or shell)\n * - browser: Embeds a URL in an iframe\n */\nexport type PaneContent =\n | { type: 'session'; sessionId: string }\n | { type: 'browser'; url: string };\n\n/**\n * Panes - individual content containers within a window.\n * Each pane has a content type that determines what it displays.\n */\nexport const panes = sqliteTable('panes', {\n id: text('id').primaryKey(),\n windowId: text('window_id')\n .notNull()\n .references(() => windows.id, { onDelete: 'cascade' }),\n /** Content configuration. Null when pane type not yet selected. */\n content: text('content', { mode: 'json' }).$type<PaneContent>(),\n createdAt: integer('created_at', { mode: 'timestamp_ms' })\n .notNull()\n .default(sql`(unixepoch() * 1000)`),\n});\n\n/**\n * UI state - key/value store for UI preferences.\n * Examples: active_window_id, theme, sidebar_collapsed\n */\nexport const uiState = sqliteTable('ui_state', {\n key: text('key').primaryKey(),\n value: text('value').notNull(),\n});\n\n// Type exports\nexport type Window = typeof windows.$inferSelect;\nexport type NewWindow = typeof windows.$inferInsert;\nexport type Pane = typeof panes.$inferSelect;\nexport type NewPane = typeof panes.$inferInsert;\nexport type UiState = typeof uiState.$inferSelect;\n","/**\n * Bridge between Shella and Amux.\n *\n * Since Shella embeds Amux (same process), this bridge directly calls\n * Amux's internal functions rather than going through tRPC.\n */\n\nimport { randomUUID } from 'crypto';\nimport { eq, inArray } from 'drizzle-orm';\nimport { db, schema } from '@bytespell/amux/db';\nimport { agentManager } from '@bytespell/amux/agents/manager';\nimport { clearEventsForSession } from '@bytespell/amux/agents/eventStore';\nimport { listFilesForAutocomplete, type FileEntry } from '@bytespell/amux/trpc/files';\nimport type { WindowUpdate } from '@bytespell/amux/types';\n\nconst { sessions, agentConfigs, appState } = schema;\n\n// Types that match Amux's internal types\nexport interface AmuxSession {\n id: string;\n directory: string;\n agentConfigId: string;\n acpSessionId: string | null;\n title: string | null;\n model: string | null;\n mode: string | null;\n createdAt: Date;\n}\n\nexport interface AmuxAgentConfig {\n id: string;\n name: string;\n command: string;\n args: string[] | null;\n env: Record<string, string> | null;\n createdAt: Date;\n}\n\nexport interface AmuxAgentSession {\n acpSessionId: string;\n replayEvents: any[];\n scrollback?: string;\n models?: Array<{ modelId: string; name: string }>;\n modes?: Array<{ id: string; name: string; description?: string }>;\n}\n\nexport interface AmuxBridge {\n // Session operations\n getSessions(ids: string[]): Promise<AmuxSession[]>;\n getSession(id: string): Promise<AmuxSession | null>;\n createSession(params: { id?: string; directory: string; agentConfigId?: string }): Promise<AmuxSession>;\n deleteSession(id: string): Promise<void>;\n\n // Agent config operations\n getAgentConfigs(): Promise<AmuxAgentConfig[]>;\n\n // Agent operations (start/stop/prompt/etc)\n startAgent(sessionId: string): Promise<AmuxAgentSession>;\n stopAgent(sessionId: string): Promise<void>;\n prompt(sessionId: string, message: string): Promise<void>;\n cancel(sessionId: string): Promise<void>;\n setMode(sessionId: string, modeId: string): Promise<void>;\n setModel(sessionId: string, modelId: string): Promise<void>;\n respondPermission(sessionId: string, requestId: string, optionId: string): void;\n\n // Subscriptions\n subscribeToSession(sessionId: string, callback: (update: WindowUpdate) => void): () => void;\n\n // File operations\n listFilesForAutocomplete(sessionId: string, partialPath: string, limit: number): Promise<FileEntry[]>;\n\n // Terminal operations (ShellBackend)\n terminalWrite(sessionId: string, data: string): void;\n terminalResize(sessionId: string, cols: number, rows: number): void;\n getTerminalScrollback(sessionId: string): string | undefined;\n isTerminalSession(sessionId: string): boolean;\n\n // Session updates\n updateSessionTitle(sessionId: string, title: string): void;\n}\n\n/**\n * Create an AmuxBridge from the embedded Amux instance.\n * This connects to Amux running in the same process.\n */\nexport function createAmuxBridge(): AmuxBridge {\n return {\n async getSessions(ids: string[]): Promise<AmuxSession[]> {\n if (ids.length === 0) return [];\n return db.select().from(sessions).where(inArray(sessions.id, ids)).all();\n },\n\n async getSession(id: string): Promise<AmuxSession | null> {\n return db.select().from(sessions).where(eq(sessions.id, id)).get() ?? null;\n },\n\n async createSession(params: { id?: string; directory: string; agentConfigId?: string }): Promise<AmuxSession> {\n // Get agent config\n let configId = params.agentConfigId;\n if (!configId) {\n const lastUsedRow = db.select().from(appState).where(eq(appState.key, 'last_used_agent_config_id')).get();\n if (lastUsedRow?.value) {\n const config = db.select().from(agentConfigs).where(eq(agentConfigs.id, lastUsedRow.value)).get();\n if (config) configId = config.id;\n }\n if (!configId) {\n const firstConfig = db.select().from(agentConfigs).get();\n if (!firstConfig) {\n throw new Error('No agent configs available');\n }\n configId = firstConfig.id;\n }\n } else {\n // Save as last used\n db.insert(appState)\n .values({ key: 'last_used_agent_config_id', value: configId })\n .onConflictDoUpdate({ target: appState.key, set: { value: configId } })\n .run();\n }\n\n // Use client-provided ID if available (for optimistic updates)\n const id = params.id ?? randomUUID();\n const now = new Date();\n\n // For PTY sessions (terminals), default title to directory name\n const config = db.select().from(agentConfigs).where(eq(agentConfigs.id, configId)).get();\n const initialTitle = config?.streamType === 'pty'\n ? params.directory.split('/').pop() || null\n : null;\n\n db.insert(sessions).values({\n id,\n directory: params.directory,\n agentConfigId: configId,\n acpSessionId: null,\n title: initialTitle,\n model: null,\n mode: null,\n createdAt: now,\n }).run();\n\n return db.select().from(sessions).where(eq(sessions.id, id)).get()!;\n },\n\n async deleteSession(id: string): Promise<void> {\n await agentManager.stopForSession(id);\n clearEventsForSession(id);\n db.delete(sessions).where(eq(sessions.id, id)).run();\n },\n\n async getAgentConfigs(): Promise<AmuxAgentConfig[]> {\n return db.select().from(agentConfigs).all();\n },\n\n async startAgent(sessionId: string): Promise<AmuxAgentSession> {\n return agentManager.startForSession(sessionId);\n },\n\n async stopAgent(sessionId: string): Promise<void> {\n await agentManager.stopForSession(sessionId);\n },\n\n async prompt(sessionId: string, message: string): Promise<void> {\n await agentManager.prompt(sessionId, message);\n },\n\n async cancel(sessionId: string): Promise<void> {\n await agentManager.cancel(sessionId);\n },\n\n async setMode(sessionId: string, modeId: string): Promise<void> {\n await agentManager.setMode(sessionId, modeId);\n },\n\n async setModel(sessionId: string, modelId: string): Promise<void> {\n await agentManager.setModel(sessionId, modelId);\n },\n\n respondPermission(sessionId: string, requestId: string, optionId: string): void {\n agentManager.respondPermission(sessionId, requestId, optionId);\n },\n\n subscribeToSession(sessionId: string, callback: (update: WindowUpdate) => void): () => void {\n const handler = (event: { sessionId: string; update: WindowUpdate }) => {\n if (event.sessionId === sessionId) {\n callback(event.update);\n }\n };\n agentManager.on('update', handler);\n return () => agentManager.off('update', handler);\n },\n\n async listFilesForAutocomplete(sessionId: string, partialPath: string, limit: number): Promise<FileEntry[]> {\n const session = db.select().from(sessions).where(eq(sessions.id, sessionId)).get();\n if (!session) throw new Error(`Session ${sessionId} not found`);\n return listFilesForAutocomplete(session.directory, partialPath, limit);\n },\n\n // Terminal operations\n terminalWrite(sessionId: string, data: string): void {\n agentManager.terminalWrite(sessionId, data);\n },\n\n terminalResize(sessionId: string, cols: number, rows: number): void {\n agentManager.terminalResize(sessionId, cols, rows);\n },\n\n getTerminalScrollback(sessionId: string): string | undefined {\n return agentManager.getTerminalScrollback(sessionId);\n },\n\n isTerminalSession(sessionId: string): boolean {\n return agentManager.isTerminalSession(sessionId);\n },\n\n updateSessionTitle(sessionId: string, title: string): void {\n db.update(sessions)\n .set({ title })\n .where(eq(sessions.id, sessionId))\n .run();\n },\n };\n}\n","import { initTRPC } from '@trpc/server';\n\nconst t = initTRPC.create();\n\nexport const router = t.router;\nexport const publicProcedure = t.procedure;\n","import { z } from 'zod';\nimport { randomUUID } from 'crypto';\nimport { eq } from 'drizzle-orm';\nimport { router, publicProcedure } from './trpc.js';\nimport { db } from '../db/index.js';\nimport { windows, panes, uiState } from '../db/schema.js';\nimport { createLeaf, type LayoutNode } from '../../client/lib/layout.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\n// AmuxBridge is injected at server startup\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\nfunction generateTitle(existingCount: number, directory: string): string {\n // Use directory name as title, or generic \"Window N\"\n const dirName = directory.split('/').pop();\n if (dirName && dirName !== '~' && dirName !== '') {\n return dirName;\n }\n return `Window ${existingCount + 1}`;\n}\n\nexport const windowsRouter = router({\n /**\n * List all windows with their panes and sessions.\n */\n list: publicProcedure.query(async () => {\n const allWindows = db.select().from(windows).orderBy(windows.createdAt).all();\n const allPanes = db.select().from(panes).all();\n const activeRow = db.select().from(uiState).where(eq(uiState.key, 'active_window_id')).get();\n\n // Get all unique session IDs from session-type panes\n const sessionIds = [...new Set(\n allPanes\n .map(p => p.content?.type === 'session' ? p.content.sessionId : null)\n .filter((id): id is string => id !== null)\n )];\n\n // Fetch sessions from amux\n const sessionsData = await amux.getSessions(sessionIds);\n const sessionMap = new Map(sessionsData.map(s => [s.id, s]));\n\n // Get agent configs from amux\n const agentConfigs = await amux.getAgentConfigs();\n\n return {\n windows: allWindows.map(w => ({\n ...w,\n panes: allPanes\n .filter(p => p.windowId === w.id)\n .map(p => ({\n ...p,\n // Enrich session-type content with full session data\n session: p.content?.type === 'session'\n ? sessionMap.get(p.content.sessionId) ?? null\n : null,\n })),\n })),\n activeWindowId: activeRow?.value ?? allWindows[allWindows.length - 1]?.id ?? null,\n agentConfigs,\n };\n }),\n\n /**\n * Get a single window by ID.\n */\n get: publicProcedure\n .input(z.object({ id: z.string() }))\n .query(async ({ input }) => {\n const window = db.select().from(windows).where(eq(windows.id, input.id)).get();\n if (!window) {\n throw new Error(`Window ${input.id} not found`);\n }\n const windowPanes = db.select().from(panes).where(eq(panes.windowId, input.id)).all();\n\n // Fetch sessions for session-type panes\n const sessionIds = windowPanes\n .map(p => p.content?.type === 'session' ? p.content.sessionId : null)\n .filter((id): id is string => id !== null);\n const sessionsData = await amux.getSessions(sessionIds);\n const sessionMap = new Map(sessionsData.map(s => [s.id, s]));\n\n return {\n ...window,\n panes: windowPanes.map(p => ({\n ...p,\n session: p.content?.type === 'session'\n ? sessionMap.get(p.content.sessionId) ?? null\n : null,\n })),\n };\n }),\n\n /**\n * Create a new window with a single pane.\n * If agentConfigId is not provided, pane is created with no content (shows picker).\n */\n create: publicProcedure\n .input(z.object({\n id: z.string().optional(),\n title: z.string().optional(),\n directory: z.string().optional(),\n agentConfigId: z.string().optional(),\n }))\n .mutation(async ({ input }) => {\n const directory = input.directory ?? process.cwd();\n\n // 1. Only create session if agentConfigId is provided\n let session = null;\n if (input.agentConfigId) {\n session = await amux.createSession({\n directory,\n agentConfigId: input.agentConfigId,\n });\n }\n\n // 2. Create window + pane in shella\n const windowId = input.id ?? randomUUID();\n const paneId = randomUUID();\n const existingCount = db.select().from(windows).all().length;\n const layout: LayoutNode = createLeaf(paneId);\n\n db.insert(windows).values({\n id: windowId,\n title: input.title || generateTitle(existingCount, directory),\n hasCustomTitle: !!input.title,\n layout,\n activePaneId: paneId,\n }).run();\n\n db.insert(panes).values({\n id: paneId,\n windowId,\n content: session ? { type: 'session', sessionId: session.id } : null,\n }).run();\n\n // 3. Set as active window\n db.insert(uiState)\n .values({ key: 'active_window_id', value: windowId })\n .onConflictDoUpdate({ target: uiState.key, set: { value: windowId } })\n .run();\n\n // Fetch the full window with panes for the response\n const newWindow = db.select().from(windows).where(eq(windows.id, windowId)).get()!;\n const newPanes = db.select().from(panes).where(eq(panes.windowId, windowId)).all();\n\n return {\n ...newWindow,\n panes: newPanes.map(p => ({\n ...p,\n session: session && p.content?.type === 'session' && p.content.sessionId === session.id\n ? session\n : null,\n })),\n };\n }),\n\n /**\n * Update a window (title, etc).\n */\n update: publicProcedure\n .input(z.object({\n id: z.string(),\n title: z.string().optional(),\n }))\n .mutation(async ({ input }) => {\n const updates: Record<string, unknown> = {};\n if (input.title !== undefined) {\n updates.title = input.title;\n updates.hasCustomTitle = true;\n }\n updates.lastAccessedAt = new Date();\n\n db.update(windows)\n .set(updates)\n .where(eq(windows.id, input.id))\n .run();\n\n return db.select().from(windows).where(eq(windows.id, input.id)).get()!;\n }),\n\n /**\n * Delete a window and all its panes/sessions.\n */\n delete: publicProcedure\n .input(z.object({ id: z.string() }))\n .mutation(async ({ input }) => {\n // Get all panes for this window\n const windowPanes = db.select().from(panes).where(eq(panes.windowId, input.id)).all();\n\n // Delete sessions in amux (only for session-type panes)\n for (const pane of windowPanes) {\n if (pane.content?.type === 'session') {\n await amux.deleteSession(pane.content.sessionId);\n }\n }\n\n // Delete window (cascades to panes)\n db.delete(windows).where(eq(windows.id, input.id)).run();\n\n // Update active window if needed\n const activeRow = db.select().from(uiState).where(eq(uiState.key, 'active_window_id')).get();\n if (activeRow?.value === input.id) {\n const remaining = db.select().from(windows).orderBy(windows.createdAt).all();\n const newActiveId = remaining[remaining.length - 1]?.id ?? null;\n if (newActiveId) {\n db.update(uiState)\n .set({ value: newActiveId })\n .where(eq(uiState.key, 'active_window_id'))\n .run();\n } else {\n db.delete(uiState).where(eq(uiState.key, 'active_window_id')).run();\n }\n }\n\n return { ok: true };\n }),\n\n /**\n * Set the active window.\n */\n setActive: publicProcedure\n .input(z.object({ id: z.string() }))\n .mutation(async ({ input }) => {\n db.insert(uiState)\n .values({ key: 'active_window_id', value: input.id })\n .onConflictDoUpdate({ target: uiState.key, set: { value: input.id } })\n .run();\n\n // Update last accessed\n db.update(windows)\n .set({ lastAccessedAt: new Date() })\n .where(eq(windows.id, input.id))\n .run();\n\n return { ok: true };\n }),\n});\n","/**\n * Layout types for tmux-like pane splitting.\n *\n * Layout is a binary tree where:\n * - Leaf nodes are panes (contain a paneId)\n * - Branch nodes split space horizontally or vertically\n */\n\nexport type SplitDirection = 'horizontal' | 'vertical';\n\nexport interface LayoutLeaf {\n type: 'leaf';\n paneId: string;\n}\n\nexport interface LayoutBranch {\n type: 'branch';\n direction: SplitDirection;\n /** Percentage of space for first child (0-100) */\n ratio: number;\n first: LayoutNode;\n second: LayoutNode;\n}\n\nexport type LayoutNode = LayoutLeaf | LayoutBranch;\n\n/**\n * Create a leaf node for a pane.\n */\nexport function createLeaf(paneId: string): LayoutLeaf {\n return { type: 'leaf', paneId };\n}\n\n/**\n * Create a branch node splitting two children.\n */\nexport function createBranch(\n direction: SplitDirection,\n first: LayoutNode,\n second: LayoutNode,\n ratio = 50\n): LayoutBranch {\n return { type: 'branch', direction, ratio, first, second };\n}\n\n/**\n * Find all pane IDs in a layout tree.\n */\nexport function getAllPaneIds(node: LayoutNode): string[] {\n if (node.type === 'leaf') {\n return [node.paneId];\n }\n return [...getAllPaneIds(node.first), ...getAllPaneIds(node.second)];\n}\n\n/**\n * Find a pane in the layout and return its path.\n * Returns null if not found.\n */\nexport function findPanePath(\n node: LayoutNode,\n paneId: string,\n path: ('first' | 'second')[] = []\n): ('first' | 'second')[] | null {\n if (node.type === 'leaf') {\n return node.paneId === paneId ? path : null;\n }\n const firstPath = findPanePath(node.first, paneId, [...path, 'first']);\n if (firstPath) return firstPath;\n return findPanePath(node.second, paneId, [...path, 'second']);\n}\n\n/**\n * Replace a pane in the layout with a new node.\n */\nexport function replacePaneWithNode(\n root: LayoutNode,\n paneId: string,\n newNode: LayoutNode\n): LayoutNode {\n if (root.type === 'leaf') {\n return root.paneId === paneId ? newNode : root;\n }\n return {\n ...root,\n first: replacePaneWithNode(root.first, paneId, newNode),\n second: replacePaneWithNode(root.second, paneId, newNode),\n };\n}\n\n/**\n * Split a pane, creating a new branch with the original and new pane.\n */\nexport function splitPane(\n root: LayoutNode,\n paneId: string,\n newPaneId: string,\n direction: SplitDirection\n): LayoutNode {\n const originalLeaf = createLeaf(paneId);\n const newLeaf = createLeaf(newPaneId);\n const branch = createBranch(direction, originalLeaf, newLeaf);\n return replacePaneWithNode(root, paneId, branch);\n}\n\n/**\n * Remove a pane from the layout.\n * Returns the modified layout, or null if removing the only pane.\n */\nexport function removePane(root: LayoutNode, paneId: string): LayoutNode | null {\n if (root.type === 'leaf') {\n return root.paneId === paneId ? null : root;\n }\n\n // Check if either child is the pane to remove\n if (root.first.type === 'leaf' && root.first.paneId === paneId) {\n return root.second;\n }\n if (root.second.type === 'leaf' && root.second.paneId === paneId) {\n return root.first;\n }\n\n // Recursively remove from children\n const newFirst = removePane(root.first, paneId);\n const newSecond = removePane(root.second, paneId);\n\n // If a child was removed entirely, return the other\n if (newFirst === null) return newSecond;\n if (newSecond === null) return newFirst;\n\n // If either child changed, return updated branch\n if (newFirst !== root.first || newSecond !== root.second) {\n return { ...root, first: newFirst, second: newSecond };\n }\n\n return root;\n}\n\n/**\n * Update the split ratio at a specific path.\n */\nexport function updateRatio(\n root: LayoutNode,\n path: ('first' | 'second')[],\n newRatio: number\n): LayoutNode {\n if (path.length === 0) {\n if (root.type === 'branch') {\n return { ...root, ratio: Math.max(10, Math.min(90, newRatio)) };\n }\n return root;\n }\n\n if (root.type === 'leaf') return root;\n\n const [next, ...rest] = path;\n if (next === 'first') {\n return { ...root, first: updateRatio(root.first, rest, newRatio) };\n } else {\n return { ...root, second: updateRatio(root.second, rest, newRatio) };\n }\n}\n\n/**\n * Get the sibling pane ID when navigating in a direction.\n * Returns null if there's no sibling in that direction.\n */\nexport function getAdjacentPane(\n root: LayoutNode,\n currentPaneId: string,\n direction: 'left' | 'right' | 'up' | 'down'\n): string | null {\n const path = findPanePath(root, currentPaneId);\n if (!path) return null;\n\n // Navigate up the tree to find a branch going the right direction\n let node = root;\n const pathNodes: { node: LayoutBranch; childSide: 'first' | 'second' }[] = [];\n\n for (const step of path) {\n if (node.type === 'branch') {\n pathNodes.push({ node, childSide: step });\n node = step === 'first' ? node.first : node.second;\n }\n }\n\n // Find the closest branch that allows movement in the desired direction\n for (let i = pathNodes.length - 1; i >= 0; i--) {\n const { node: branch, childSide } = pathNodes[i];\n const isHorizontal = branch.direction === 'horizontal';\n const isVertical = branch.direction === 'vertical';\n\n // Check if this branch allows movement in the desired direction\n const canMove =\n (direction === 'left' && isHorizontal && childSide === 'second') ||\n (direction === 'right' && isHorizontal && childSide === 'first') ||\n (direction === 'up' && isVertical && childSide === 'second') ||\n (direction === 'down' && isVertical && childSide === 'first');\n\n if (canMove) {\n // Get the other child and find the closest pane in it\n const otherChild = childSide === 'first' ? branch.second : branch.first;\n return getFirstPaneInDirection(otherChild, direction);\n }\n }\n\n return null;\n}\n\n/**\n * Get the first pane when entering a subtree from a direction.\n */\nfunction getFirstPaneInDirection(\n node: LayoutNode,\n fromDirection: 'left' | 'right' | 'up' | 'down'\n): string {\n if (node.type === 'leaf') {\n return node.paneId;\n }\n\n // When entering from left, prefer the leftmost pane (first in horizontal split)\n // When entering from right, prefer the rightmost pane (second in horizontal split)\n // Similar for up/down with vertical splits\n const isHorizontal = node.direction === 'horizontal';\n\n if (fromDirection === 'left' || fromDirection === 'up') {\n // Coming from left/up, go to the first (left/top) child\n const targetChild = isHorizontal\n ? (fromDirection === 'left' ? node.first : node.first)\n : (fromDirection === 'up' ? node.first : node.first);\n return getFirstPaneInDirection(targetChild, fromDirection);\n } else {\n // Coming from right/down, go to the second (right/bottom) child\n const targetChild = isHorizontal\n ? (fromDirection === 'right' ? node.second : node.second)\n : (fromDirection === 'down' ? node.second : node.second);\n return getFirstPaneInDirection(targetChild, fromDirection);\n }\n}\n","import { z } from 'zod';\nimport { randomUUID } from 'crypto';\nimport { eq } from 'drizzle-orm';\nimport { router, publicProcedure } from './trpc.js';\nimport { db } from '../db/index.js';\nimport { windows, panes } from '../db/schema.js';\nimport {\n splitPane,\n removePane,\n getAllPaneIds,\n getAdjacentPane,\n updateRatio,\n type LayoutNode,\n type SplitDirection,\n} from '../../client/lib/layout.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\nexport const layoutRouter = router({\n /**\n * Split a pane horizontally or vertically.\n * If source pane has a session, clones it. Otherwise creates empty pane.\n */\n split: publicProcedure\n .input(z.object({\n windowId: z.string(),\n paneId: z.string(),\n direction: z.enum(['horizontal', 'vertical']),\n // Client can provide IDs for optimistic updates\n newPaneId: z.string().optional(),\n newSessionId: z.string().optional(),\n }))\n .mutation(async ({ input }) => {\n // 1. Get source pane\n const sourcePane = db.select().from(panes).where(eq(panes.id, input.paneId)).get();\n if (!sourcePane) {\n throw new Error(`Pane ${input.paneId} not found`);\n }\n\n // 2. Get window for layout update\n const window = db.select().from(windows).where(eq(windows.id, input.windowId)).get();\n if (!window) {\n throw new Error(`Window ${input.windowId} not found`);\n }\n\n // 3. New pane always starts empty (shows PaneTypePicker)\n const newContent = null;\n\n // 4. Create new pane\n const newPaneId = input.newPaneId ?? randomUUID();\n db.insert(panes).values({\n id: newPaneId,\n windowId: input.windowId,\n content: newContent,\n }).run();\n\n // 5. Update window layout\n const currentLayout = window.layout as LayoutNode;\n const newLayout = splitPane(currentLayout, input.paneId, newPaneId, input.direction as SplitDirection);\n\n db.update(windows)\n .set({\n layout: newLayout,\n activePaneId: newPaneId,\n lastAccessedAt: new Date(),\n })\n .where(eq(windows.id, input.windowId))\n .run();\n\n const now = new Date();\n return {\n newPaneId,\n newSessionId: null,\n layout: newLayout,\n newPane: {\n id: newPaneId,\n windowId: input.windowId,\n content: newContent,\n createdAt: now.toISOString(),\n session: null,\n },\n };\n }),\n\n /**\n * Close a pane. If it's the last pane, close the window.\n */\n closePane: publicProcedure\n .input(z.object({\n windowId: z.string(),\n paneId: z.string(),\n }))\n .mutation(async ({ input }) => {\n const window = db.select().from(windows).where(eq(windows.id, input.windowId)).get();\n if (!window) {\n throw new Error(`Window ${input.windowId} not found`);\n }\n\n const pane = db.select().from(panes).where(eq(panes.id, input.paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${input.paneId} not found`);\n }\n\n const currentLayout = window.layout as LayoutNode;\n const allPaneIds = getAllPaneIds(currentLayout);\n\n // Check if this is the last pane\n if (allPaneIds.length === 1) {\n // Delete session in amux if this is a session-type pane\n if (pane.content?.type === 'session') {\n await amux.deleteSession(pane.content.sessionId);\n }\n // Delete window (cascades to pane)\n db.delete(windows).where(eq(windows.id, input.windowId)).run();\n return { windowClosed: true, layout: null, activePaneId: null };\n }\n\n // Delete session in amux if this is a session-type pane\n if (pane.content?.type === 'session') {\n await amux.deleteSession(pane.content.sessionId);\n }\n // Delete pane\n db.delete(panes).where(eq(panes.id, input.paneId)).run();\n\n // Update layout\n const newLayout = removePane(currentLayout, input.paneId);\n if (!newLayout) {\n throw new Error('Failed to remove pane from layout');\n }\n\n // Determine new active pane\n const newActivePaneId = window.activePaneId === input.paneId\n ? getAllPaneIds(newLayout)[0]\n : window.activePaneId;\n\n db.update(windows)\n .set({\n layout: newLayout,\n activePaneId: newActivePaneId,\n lastAccessedAt: new Date(),\n })\n .where(eq(windows.id, input.windowId))\n .run();\n\n return {\n windowClosed: false,\n layout: newLayout,\n activePaneId: newActivePaneId,\n };\n }),\n\n /**\n * Set the active pane within a window.\n */\n setActivePane: publicProcedure\n .input(z.object({\n windowId: z.string(),\n paneId: z.string(),\n }))\n .mutation(async ({ input }) => {\n db.update(windows)\n .set({\n activePaneId: input.paneId,\n lastAccessedAt: new Date(),\n })\n .where(eq(windows.id, input.windowId))\n .run();\n\n return { ok: true };\n }),\n\n /**\n * Navigate to an adjacent pane.\n */\n navigate: publicProcedure\n .input(z.object({\n windowId: z.string(),\n currentPaneId: z.string(),\n direction: z.enum(['left', 'right', 'up', 'down']),\n }))\n .mutation(async ({ input }) => {\n const window = db.select().from(windows).where(eq(windows.id, input.windowId)).get();\n if (!window) {\n throw new Error(`Window ${input.windowId} not found`);\n }\n\n const currentLayout = window.layout as LayoutNode;\n const adjacentPaneId = getAdjacentPane(currentLayout, input.currentPaneId, input.direction);\n\n if (adjacentPaneId) {\n db.update(windows)\n .set({\n activePaneId: adjacentPaneId,\n lastAccessedAt: new Date(),\n })\n .where(eq(windows.id, input.windowId))\n .run();\n\n return { newActivePaneId: adjacentPaneId };\n }\n\n return { newActivePaneId: null };\n }),\n\n /**\n * Update the split ratio at a specific position.\n */\n setRatio: publicProcedure\n .input(z.object({\n windowId: z.string(),\n path: z.array(z.enum(['first', 'second'])),\n ratio: z.number().min(10).max(90),\n }))\n .mutation(async ({ input }) => {\n const window = db.select().from(windows).where(eq(windows.id, input.windowId)).get();\n if (!window) {\n throw new Error(`Window ${input.windowId} not found`);\n }\n\n const currentLayout = window.layout as LayoutNode;\n const newLayout = updateRatio(currentLayout, input.path, input.ratio);\n\n db.update(windows)\n .set({ layout: newLayout })\n .where(eq(windows.id, input.windowId))\n .run();\n\n return { layout: newLayout };\n }),\n\n /**\n * Set the session for an empty pane (used when user picks agent/shell type).\n * Creates a session in amux and updates the pane.\n */\n setSession: publicProcedure\n .input(z.object({\n paneId: z.string(),\n agentConfigId: z.string(),\n directory: z.string().optional(),\n }))\n .mutation(async ({ input }) => {\n const pane = db.select().from(panes).where(eq(panes.id, input.paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${input.paneId} not found`);\n }\n\n if (pane.content) {\n throw new Error(`Pane ${input.paneId} already has content`);\n }\n\n // Create session in amux\n const session = await amux.createSession({\n directory: input.directory ?? process.cwd(),\n agentConfigId: input.agentConfigId,\n });\n\n // Update pane with session content\n db.update(panes)\n .set({ content: { type: 'session', sessionId: session.id } })\n .where(eq(panes.id, input.paneId))\n .run();\n\n // Start the agent\n await amux.startAgent(session.id);\n\n return {\n sessionId: session.id,\n content: { type: 'session' as const, sessionId: session.id },\n session: {\n id: session.id,\n directory: session.directory,\n agentConfigId: session.agentConfigId,\n model: session.model,\n mode: session.mode,\n createdAt: session.createdAt.toISOString(),\n acpSessionId: session.acpSessionId,\n },\n };\n }),\n\n /**\n * Set browser content for an empty pane.\n */\n setBrowserContent: publicProcedure\n .input(z.object({\n paneId: z.string(),\n url: z.string().url(),\n }))\n .mutation(async ({ input }) => {\n const pane = db.select().from(panes).where(eq(panes.id, input.paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${input.paneId} not found`);\n }\n\n if (pane.content) {\n throw new Error(`Pane ${input.paneId} already has content`);\n }\n\n const content = { type: 'browser' as const, url: input.url };\n\n db.update(panes)\n .set({ content })\n .where(eq(panes.id, input.paneId))\n .run();\n\n return { content };\n }),\n\n /**\n * Update the URL of an existing browser pane.\n */\n updateBrowserUrl: publicProcedure\n .input(z.object({\n paneId: z.string(),\n url: z.string().url(),\n }))\n .mutation(async ({ input }) => {\n const pane = db.select().from(panes).where(eq(panes.id, input.paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${input.paneId} not found`);\n }\n\n if (pane.content?.type !== 'browser') {\n throw new Error(`Pane ${input.paneId} is not a browser pane`);\n }\n\n const content = { type: 'browser' as const, url: input.url };\n\n db.update(panes)\n .set({ content })\n .where(eq(panes.id, input.paneId))\n .run();\n\n return { content };\n }),\n});\n","import { z } from 'zod';\nimport { eq } from 'drizzle-orm';\nimport { observable } from '@trpc/server/observable';\nimport { router, publicProcedure } from './trpc.js';\nimport { db } from '../db/index.js';\nimport { panes } from '../db/schema.js';\nimport type { WindowUpdate } from '@bytespell/amux/types';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\nconst paneInput = z.object({\n paneId: z.string(),\n});\n\n// Helper to get sessionId from paneId (for session-type panes only)\nfunction getSessionIdForPane(paneId: string): string {\n const pane = db.select().from(panes).where(eq(panes.id, paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${paneId} not found`);\n }\n if (pane.content?.type !== 'session') {\n throw new Error(`Pane ${paneId} is not a session pane`);\n }\n return pane.content.sessionId;\n}\n\nexport const agentsRouter = router({\n /**\n * Start agent for a pane.\n */\n start: publicProcedure\n .input(paneInput)\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n return amux.startAgent(sessionId);\n }),\n\n /**\n * Stop agent for a pane.\n */\n stop: publicProcedure\n .input(paneInput)\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n await amux.stopAgent(sessionId);\n return { ok: true };\n }),\n\n /**\n * Send a prompt to a pane's agent.\n */\n prompt: publicProcedure\n .input(z.object({\n paneId: z.string(),\n message: z.string(),\n }))\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n await amux.prompt(sessionId, input.message);\n return { ok: true };\n }),\n\n /**\n * Cancel the current prompt.\n */\n cancel: publicProcedure\n .input(paneInput)\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n await amux.cancel(sessionId);\n return { ok: true };\n }),\n\n /**\n * Set agent mode.\n */\n setMode: publicProcedure\n .input(z.object({\n paneId: z.string(),\n modeId: z.string(),\n }))\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n await amux.setMode(sessionId, input.modeId);\n return { ok: true };\n }),\n\n /**\n * Set agent model.\n */\n setModel: publicProcedure\n .input(z.object({\n paneId: z.string(),\n modelId: z.string(),\n }))\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n await amux.setModel(sessionId, input.modelId);\n return { ok: true };\n }),\n\n /**\n * Respond to a permission request.\n */\n respondPermission: publicProcedure\n .input(z.object({\n paneId: z.string(),\n requestId: z.string(),\n optionId: z.string(),\n }))\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n amux.respondPermission(sessionId, input.requestId, input.optionId);\n return { ok: true };\n }),\n\n /**\n * Subscribe to updates for a pane's agent session.\n */\n subscribe: publicProcedure\n .input(paneInput)\n .subscription(({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n return observable<WindowUpdate>((emit) => {\n return amux.subscribeToSession(sessionId, (update) => {\n emit.next(update);\n });\n });\n }),\n});\n","import { z } from 'zod';\nimport { eq } from 'drizzle-orm';\nimport { router, publicProcedure } from './trpc.js';\nimport { db } from '../db/index.js';\nimport { panes } from '../db/schema.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\n// Helper to get sessionId from paneId (for session-type panes only)\nfunction getSessionIdForPane(paneId: string): string {\n const pane = db.select().from(panes).where(eq(panes.id, paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${paneId} not found`);\n }\n if (pane.content?.type !== 'session') {\n throw new Error(`Pane ${paneId} is not a session pane`);\n }\n return pane.content.sessionId;\n}\n\nexport const filesRouter = router({\n /**\n * List files/directories matching a partial path for autocomplete.\n * Returns files in the session's working directory.\n */\n listForAutocomplete: publicProcedure\n .input(z.object({\n paneId: z.string(),\n partialPath: z.string(),\n limit: z.number().default(20),\n }))\n .query(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n return amux.listFilesForAutocomplete(sessionId, input.partialPath, input.limit);\n }),\n});\n","import { z } from 'zod';\nimport { eq } from 'drizzle-orm';\nimport { router, publicProcedure } from './trpc.js';\nimport { db } from '../db/index.js';\nimport { panes } from '../db/schema.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\nconst paneInput = z.object({\n paneId: z.string(),\n});\n\n// Helper to get sessionId from paneId (for session-type panes only)\nfunction getSessionIdForPane(paneId: string): string {\n const pane = db.select().from(panes).where(eq(panes.id, paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${paneId} not found`);\n }\n if (pane.content?.type !== 'session') {\n throw new Error(`Pane ${paneId} is not a session pane`);\n }\n return pane.content.sessionId;\n}\n\n/**\n * Terminal-specific tRPC router.\n *\n * These endpoints are for interactive terminal panes (ShellBackend).\n * Regular agent panes use the agents router instead.\n */\nexport const terminalsRouter = router({\n /**\n * Write raw input to terminal (keystrokes from client).\n */\n write: publicProcedure\n .input(\n z.object({\n paneId: z.string(),\n data: z.string(),\n })\n )\n .mutation(({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n amux.terminalWrite(sessionId, input.data);\n return { ok: true };\n }),\n\n /**\n * Resize terminal dimensions.\n */\n resize: publicProcedure\n .input(\n z.object({\n paneId: z.string(),\n cols: z.number().int().positive(),\n rows: z.number().int().positive(),\n })\n )\n .mutation(({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n amux.terminalResize(sessionId, input.cols, input.rows);\n return { ok: true };\n }),\n\n /**\n * Check if a pane is a terminal session.\n */\n isTerminal: publicProcedure.input(paneInput).query(({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n return { isTerminal: amux.isTerminalSession(sessionId) };\n }),\n\n /**\n * Set terminal title (from OSC escape sequence).\n */\n setTitle: publicProcedure\n .input(z.object({\n paneId: z.string(),\n title: z.string(),\n }))\n .mutation(({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n amux.updateSessionTitle(sessionId, input.title);\n return { ok: true };\n }),\n});\n","import { router } from './trpc.js';\nimport { windowsRouter, setAmuxBridge as setWindowsAmux } from './windows.js';\nimport { layoutRouter, setAmuxBridge as setLayoutAmux } from './layout.js';\nimport { agentsRouter, setAmuxBridge as setAgentsAmux } from './agents.js';\nimport { filesRouter, setAmuxBridge as setFilesAmux } from './files.js';\nimport { terminalsRouter, setAmuxBridge as setTerminalsAmux } from './terminals.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\n/**\n * Initialize all routers with the amux bridge.\n * Must be called before any routes are used.\n */\nexport function initializeRouters(amux: AmuxBridge) {\n setWindowsAmux(amux);\n setLayoutAmux(amux);\n setAgentsAmux(amux);\n setFilesAmux(amux);\n setTerminalsAmux(amux);\n}\n\n/**\n * Shella's tRPC router.\n *\n * Provides UI-layer endpoints:\n * - windows: Window CRUD (with panes)\n * - layout: Split, close, navigate panes\n * - agents: Proxy to amux for agent operations\n * - terminals: Terminal-specific operations (ShellBackend)\n */\nexport const shellaRouter = router({\n windows: windowsRouter,\n layout: layoutRouter,\n agents: agentsRouter,\n files: filesRouter,\n terminals: terminalsRouter,\n});\n\nexport type ShellaRouter = typeof shellaRouter;\n"],"mappings":"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","names":["path","agentManager","db","config","randomUUID","eq","path","eq","p","agentConfigs","randomUUID","z","randomUUID","eq","amux","setAmuxBridge","z","eq","randomUUID","z","eq","amux","setAmuxBridge","z","eq","z","eq","amux","setAmuxBridge","getSessionIdForPane","eq","z","z","eq","amux","setAmuxBridge","paneInput","z","getSessionIdForPane","eq","amux","setAmuxBridge","path","agentManager","text","log"]}
|