@canaryai/cli 0.2.12 → 0.2.14

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.
Files changed (73) hide show
  1. package/dist/{chunk-CEW4BDXD.js → chunk-4A4G5KTC.js} +14 -6
  2. package/dist/chunk-4A4G5KTC.js.map +1 -0
  3. package/dist/{chunk-MSMC6UXW.js → chunk-6IAPGYZQ.js} +1016 -245
  4. package/dist/chunk-6IAPGYZQ.js.map +1 -0
  5. package/dist/{chunk-PWWQGYFG.js → chunk-ACRIE2YR.js} +5 -2
  6. package/dist/chunk-ACRIE2YR.js.map +1 -0
  7. package/dist/{chunk-ERSNYLMZ.js → chunk-BOS2YLKH.js} +12 -8
  8. package/dist/chunk-BOS2YLKH.js.map +1 -0
  9. package/dist/{chunk-A44B2PEA.js → chunk-SYPQF57S.js} +40 -8
  10. package/dist/chunk-SYPQF57S.js.map +1 -0
  11. package/dist/{chunk-Q7WFBG5C.js → chunk-ZQF72UTG.js} +19 -5
  12. package/dist/chunk-ZQF72UTG.js.map +1 -0
  13. package/dist/{debug-workflow-53ULOFJC.js → debug-workflow-DIQZDFMN.js} +10 -12
  14. package/dist/debug-workflow-DIQZDFMN.js.map +1 -0
  15. package/dist/{docs-BEE3LOCO.js → docs-CSVSGIGW.js} +63 -15
  16. package/dist/docs-CSVSGIGW.js.map +1 -0
  17. package/dist/{feature-flag-CYTDV4ZB.js → feature-flag-BIPFVVNC.js} +3 -3
  18. package/dist/index.d.ts +2 -2
  19. package/dist/index.js +36 -30
  20. package/dist/index.js.map +1 -1
  21. package/dist/{init-M6I3MG3D.js → init-BTDX5N6P.js} +4 -4
  22. package/dist/{issues-NLM72HLU.js → issues-EWVB52CA.js} +37 -18
  23. package/dist/issues-EWVB52CA.js.map +1 -0
  24. package/dist/{knobs-O35GAU5M.js → knobs-VYABZESR.js} +3 -3
  25. package/dist/{list-4K4EIGAT.js → list-RCPYLS36.js} +3 -3
  26. package/dist/list-RCPYLS36.js.map +1 -0
  27. package/dist/{local-NHXXPHZ3.js → local-ZPVM4BXX.js} +6 -6
  28. package/dist/{local-browser-VAZORCO3.js → local-browser-WV4IH2DU.js} +4 -4
  29. package/dist/{login-ZLP64YQP.js → login-W4GXV3VA.js} +4 -4
  30. package/dist/{mcp-ZF5G5DCB.js → mcp-YER5GQG7.js} +7 -10
  31. package/dist/mcp-YER5GQG7.js.map +1 -0
  32. package/dist/{psql-2YPIRMDY.js → psql-XO5BB5L5.js} +2 -2
  33. package/dist/{record-V6QKFFH3.js → record-KRS2PHMW.js} +7 -7
  34. package/dist/record-KRS2PHMW.js.map +1 -0
  35. package/dist/{redis-A7GWM23E.js → redis-CQTBPZ6F.js} +2 -2
  36. package/dist/{release-7TI7EIGD.js → release-DW7RPQSQ.js} +2 -2
  37. package/dist/runner/preload.js +1 -1
  38. package/dist/{session-UGNJXRUW.js → session-CLWAVJ2K.js} +33 -12
  39. package/dist/{session-UGNJXRUW.js.map → session-CLWAVJ2K.js.map} +1 -1
  40. package/dist/{skill-ORWAPBDW.js → skill-2TXI3IKP.js} +1 -1
  41. package/dist/skill-2TXI3IKP.js.map +1 -0
  42. package/dist/{src-4VIDSK4A.js → src-WLOHOI6P.js} +8 -2
  43. package/dist/{start-E532F3BU.js → start-CNNQUP5I.js} +4 -4
  44. package/dist/test.js +1 -1
  45. package/dist/test.js.map +1 -1
  46. package/dist/{workflow-HXIUXRFI.js → workflow-XXL4H5R4.js} +23 -11
  47. package/dist/workflow-XXL4H5R4.js.map +1 -0
  48. package/package.json +1 -2
  49. package/dist/chunk-A44B2PEA.js.map +0 -1
  50. package/dist/chunk-CEW4BDXD.js.map +0 -1
  51. package/dist/chunk-ERSNYLMZ.js.map +0 -1
  52. package/dist/chunk-MSMC6UXW.js.map +0 -1
  53. package/dist/chunk-PWWQGYFG.js.map +0 -1
  54. package/dist/chunk-Q7WFBG5C.js.map +0 -1
  55. package/dist/debug-workflow-53ULOFJC.js.map +0 -1
  56. package/dist/docs-BEE3LOCO.js.map +0 -1
  57. package/dist/issues-NLM72HLU.js.map +0 -1
  58. package/dist/list-4K4EIGAT.js.map +0 -1
  59. package/dist/mcp-ZF5G5DCB.js.map +0 -1
  60. package/dist/record-V6QKFFH3.js.map +0 -1
  61. package/dist/skill-ORWAPBDW.js.map +0 -1
  62. package/dist/workflow-HXIUXRFI.js.map +0 -1
  63. /package/dist/{feature-flag-CYTDV4ZB.js.map → feature-flag-BIPFVVNC.js.map} +0 -0
  64. /package/dist/{init-M6I3MG3D.js.map → init-BTDX5N6P.js.map} +0 -0
  65. /package/dist/{knobs-O35GAU5M.js.map → knobs-VYABZESR.js.map} +0 -0
  66. /package/dist/{local-NHXXPHZ3.js.map → local-ZPVM4BXX.js.map} +0 -0
  67. /package/dist/{local-browser-VAZORCO3.js.map → local-browser-WV4IH2DU.js.map} +0 -0
  68. /package/dist/{login-ZLP64YQP.js.map → login-W4GXV3VA.js.map} +0 -0
  69. /package/dist/{psql-2YPIRMDY.js.map → psql-XO5BB5L5.js.map} +0 -0
  70. /package/dist/{redis-A7GWM23E.js.map → redis-CQTBPZ6F.js.map} +0 -0
  71. /package/dist/{release-7TI7EIGD.js.map → release-DW7RPQSQ.js.map} +0 -0
  72. /package/dist/{src-4VIDSK4A.js.map → src-WLOHOI6P.js.map} +0 -0
  73. /package/dist/{start-E532F3BU.js.map → start-CNNQUP5I.js.map} +0 -0
@@ -75,6 +75,7 @@ async function spawnDaemon() {
75
75
  const match = output.match(/DAEMON_READY:(\d+)/);
76
76
  if (match) {
77
77
  clearTimeout(timeout);
78
+ child.stdout.destroy();
78
79
  resolve(parseInt(match[1], 10));
79
80
  }
80
81
  });
@@ -137,11 +138,20 @@ async function swapSessionContext(sessionId, params) {
137
138
  }
138
139
  async function getSessionStorageState(sessionId) {
139
140
  const port = await ensureDaemon();
140
- return daemonFetch(port, "GET", `/sessions/${sessionId}/storage-state`);
141
+ return daemonFetch(
142
+ port,
143
+ "GET",
144
+ `/sessions/${sessionId}/storage-state`
145
+ );
141
146
  }
142
147
  async function callTool(sessionId, toolName, args) {
143
148
  const port = await ensureDaemon();
144
- return daemonFetch(port, "POST", `/sessions/${sessionId}/tools/${toolName}`, args);
149
+ return daemonFetch(
150
+ port,
151
+ "POST",
152
+ `/sessions/${sessionId}/tools/${toolName}`,
153
+ args
154
+ );
145
155
  }
146
156
  async function resolveTargetSession(sessionIdOrName) {
147
157
  const result = await listSessions();
@@ -153,9 +163,7 @@ async function resolveTargetSession(sessionIdOrName) {
153
163
  throw new Error("No active sessions. Start one with: canary session start");
154
164
  }
155
165
  if (sessionIdOrName) {
156
- const match = sessions.find(
157
- (s) => s.id === sessionIdOrName || s.name === sessionIdOrName
158
- );
166
+ const match = sessions.find((s) => s.id === sessionIdOrName || s.name === sessionIdOrName);
159
167
  if (!match) {
160
168
  throw new Error(
161
169
  `Session "${sessionIdOrName}" not found. Active sessions: ${sessions.map((s) => s.id).join(", ")}`
@@ -183,4 +191,4 @@ export {
183
191
  callTool,
184
192
  resolveTargetSession
185
193
  };
186
- //# sourceMappingURL=chunk-CEW4BDXD.js.map
194
+ //# sourceMappingURL=chunk-4A4G5KTC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/session/daemon-client.ts"],"sourcesContent":["/**\n * Daemon client — HTTP client for the session daemon.\n *\n * Handles pidfile read/write, stale PID detection, auto-start,\n * and provides typed HTTP helpers for daemon communication.\n *\n * @module\n */\n\nimport { spawn } from 'node:child_process';\nimport fs from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport type {\n DaemonState,\n DaemonResponse,\n SessionInfo,\n CreateSessionRequest,\n SwapContextRequest,\n ToolResponse,\n StorageStateResponse,\n} from './types.js';\n\nconst PIDFILE_DIR = path.join(os.homedir(), '.config', 'canary-cli');\nconst PIDFILE_PATH = path.join(PIDFILE_DIR, 'daemon.json');\nconst HEALTH_POLL_INTERVAL_MS = 100;\nconst HEALTH_POLL_TIMEOUT_MS = 15_000;\n\n/* ── Pidfile helpers ─────────────────────────────────────────────────── */\n\nasync function readPidfile(): Promise<DaemonState | null> {\n try {\n const content = await fs.readFile(PIDFILE_PATH, 'utf-8');\n return JSON.parse(content) as DaemonState;\n } catch {\n return null;\n }\n}\n\nfunction isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n/* ── HTTP helpers ────────────────────────────────────────────────────── */\n\nasync function daemonFetch(\n port: number,\n method: string,\n path: string,\n body?: unknown\n): Promise<unknown> {\n const url = `http://127.0.0.1:${port}${path}`;\n const res = await fetch(url, {\n method,\n headers: body ? { 'Content-Type': 'application/json' } : undefined,\n body: body ? JSON.stringify(body) : undefined,\n });\n return res.json();\n}\n\nasync function healthCheck(port: number): Promise<boolean> {\n try {\n const res = await fetch(`http://127.0.0.1:${port}/health`, {\n signal: AbortSignal.timeout(2000),\n });\n return res.ok;\n } catch {\n return false;\n }\n}\n\n/* ── Auto-start ──────────────────────────────────────────────────────── */\n\nasync function spawnDaemon(): Promise<number> {\n // Resolve the canary CLI entry point\n // In source: this file is src/session/daemon-client.ts → ../index.ts\n // In dist: this file is dist/chunk-*.js → ./index.js (flat)\n const dir = path.dirname(new URL(import.meta.url).pathname);\n const candidates = [\n path.resolve(dir, '..', 'index.ts'), // source layout\n path.resolve(dir, 'index.js'), // dist layout (flat)\n path.resolve(dir, '..', 'index.js'), // fallback\n ];\n const cliEntry = candidates.find((p) => existsSync(p));\n if (!cliEntry) {\n throw new Error(`Cannot find CLI entry point. Searched: ${candidates.join(', ')}`);\n }\n\n const child = spawn(process.execPath, [cliEntry, 'session', 'daemon'], {\n detached: true,\n stdio: ['ignore', 'pipe', 'ignore'],\n env: { ...process.env },\n });\n\n child.unref();\n\n // Wait for \"DAEMON_READY:<port>\" on stdout\n return new Promise<number>((resolve, reject) => {\n let output = '';\n const timeout = setTimeout(() => {\n reject(new Error('Daemon startup timed out'));\n }, HEALTH_POLL_TIMEOUT_MS);\n\n child.stdout!.on('data', (data: Buffer) => {\n output += data.toString();\n const match = output.match(/DAEMON_READY:(\\d+)/);\n if (match) {\n clearTimeout(timeout);\n child.stdout!.destroy(); // Release the pipe so the CLI process can exit\n resolve(parseInt(match[1], 10));\n }\n });\n\n child.on('error', (err) => {\n clearTimeout(timeout);\n reject(err);\n });\n\n child.on('exit', (code) => {\n clearTimeout(timeout);\n if (!output.includes('DAEMON_READY')) {\n reject(new Error(`Daemon exited with code ${code} before becoming ready`));\n }\n });\n });\n}\n\n/* ── Public API ──────────────────────────────────────────────────────── */\n\n/**\n * Ensure the daemon is running and return its port.\n * Starts the daemon if needed, cleans up stale pidfiles.\n */\nasync function ensureDaemon(): Promise<number> {\n const state = await readPidfile();\n\n if (state) {\n if (isProcessAlive(state.pid)) {\n // Verify it actually responds\n if (await healthCheck(state.port)) {\n return state.port;\n }\n }\n // Stale pidfile — clean up\n try {\n await fs.unlink(PIDFILE_PATH);\n } catch {\n // ignore\n }\n }\n\n // Spawn new daemon\n const port = await spawnDaemon();\n\n // Poll until healthy\n const deadline = Date.now() + HEALTH_POLL_TIMEOUT_MS;\n while (Date.now() < deadline) {\n if (await healthCheck(port)) return port;\n await new Promise((r) => setTimeout(r, HEALTH_POLL_INTERVAL_MS));\n }\n\n throw new Error('Daemon failed to become healthy after spawn');\n}\n\n/* ── Session operations ──────────────────────────────────────────────── */\n\nexport async function createSession(\n params: CreateSessionRequest\n): Promise<DaemonResponse<SessionInfo>> {\n const port = await ensureDaemon();\n return daemonFetch(port, 'POST', '/sessions', params) as Promise<DaemonResponse<SessionInfo>>;\n}\n\nexport async function listSessions(): Promise<DaemonResponse<SessionInfo[]>> {\n const port = await ensureDaemon();\n return daemonFetch(port, 'GET', '/sessions') as Promise<DaemonResponse<SessionInfo[]>>;\n}\n\nexport async function getSession(sessionId: string): Promise<DaemonResponse<SessionInfo>> {\n const port = await ensureDaemon();\n return daemonFetch(port, 'GET', `/sessions/${sessionId}`) as Promise<DaemonResponse<SessionInfo>>;\n}\n\nexport async function deleteSession(sessionId: string): Promise<DaemonResponse> {\n const port = await ensureDaemon();\n return daemonFetch(port, 'DELETE', `/sessions/${sessionId}`) as Promise<DaemonResponse>;\n}\n\nexport async function deleteAllSessions(): Promise<DaemonResponse> {\n const port = await ensureDaemon();\n return daemonFetch(port, 'DELETE', '/sessions') as Promise<DaemonResponse>;\n}\n\nexport async function swapSessionContext(\n sessionId: string,\n params: SwapContextRequest\n): Promise<DaemonResponse<SessionInfo>> {\n const port = await ensureDaemon();\n return daemonFetch(port, 'POST', `/sessions/${sessionId}/swap-context`, params) as Promise<\n DaemonResponse<SessionInfo>\n >;\n}\n\nexport async function getSessionStorageState(sessionId: string): Promise<StorageStateResponse> {\n const port = await ensureDaemon();\n return daemonFetch(\n port,\n 'GET',\n `/sessions/${sessionId}/storage-state`\n ) as Promise<StorageStateResponse>;\n}\n\nexport async function callTool(\n sessionId: string,\n toolName: string,\n args: Record<string, unknown>\n): Promise<ToolResponse> {\n const port = await ensureDaemon();\n return daemonFetch(\n port,\n 'POST',\n `/sessions/${sessionId}/tools/${toolName}`,\n args\n ) as Promise<ToolResponse>;\n}\n\n/**\n * Resolve the target session for a command.\n * If there's exactly one session, auto-targets it.\n * If a sessionId or name is provided, looks it up.\n */\nexport async function resolveTargetSession(sessionIdOrName?: string): Promise<SessionInfo> {\n const result = await listSessions();\n if (!result.ok || !result.data) {\n throw new Error('Failed to list sessions');\n }\n const sessions = result.data;\n\n if (sessions.length === 0) {\n throw new Error('No active sessions. Start one with: canary session start');\n }\n\n if (sessionIdOrName) {\n const match = sessions.find((s) => s.id === sessionIdOrName || s.name === sessionIdOrName);\n if (!match) {\n throw new Error(\n `Session \"${sessionIdOrName}\" not found. Active sessions: ${sessions.map((s) => s.id).join(', ')}`\n );\n }\n return match;\n }\n\n if (sessions.length === 1) {\n return sessions[0];\n }\n\n throw new Error(\n `Multiple sessions active. Specify one with --session:\\n${sessions.map((s) => ` ${s.id} (${s.name})`).join('\\n')}`\n );\n}\n"],"mappings":"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","names":["path"]}