@canaryai/cli 0.2.14 → 0.2.15
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/{chunk-4A4G5KTC.js → chunk-N7L7AH6L.js} +48 -23
- package/dist/chunk-N7L7AH6L.js.map +1 -0
- package/dist/{chunk-ZQF72UTG.js → chunk-W3OTKNJB.js} +2 -2
- package/dist/{chunk-BOS2YLKH.js → chunk-XSOKWWRV.js} +2 -2
- package/dist/chunk-XSOKWWRV.js.map +1 -0
- package/dist/{chunk-6IAPGYZQ.js → chunk-ZYUOJQQX.js} +298 -2
- package/dist/chunk-ZYUOJQQX.js.map +1 -0
- package/dist/{debug-workflow-DIQZDFMN.js → debug-workflow-JZKUDSVY.js} +4 -4
- package/dist/{docs-CSVSGIGW.js → docs-FORYHZVU.js} +13 -7
- package/dist/docs-FORYHZVU.js.map +1 -0
- package/dist/{feature-flag-BIPFVVNC.js → feature-flag-7BD3NT6G.js} +2 -2
- package/dist/index.js +11 -11
- package/dist/{init-BTDX5N6P.js → init-JHZ3OWKQ.js} +7 -6
- package/dist/init-JHZ3OWKQ.js.map +1 -0
- package/dist/{issues-EWVB52CA.js → issues-37LDBJU7.js} +2 -2
- package/dist/{knobs-VYABZESR.js → knobs-QUJQ4NWV.js} +2 -2
- package/dist/{list-RCPYLS36.js → list-2L2NGCSF.js} +2 -2
- package/dist/{local-ZPVM4BXX.js → local-45POWSFC.js} +5 -5
- package/dist/{local-browser-WV4IH2DU.js → local-browser-LHJHPWXU.js} +3 -3
- package/dist/{login-W4GXV3VA.js → login-ZKF6GONZ.js} +3 -3
- package/dist/{mcp-YER5GQG7.js → mcp-ETZ3OTXY.js} +4 -4
- package/dist/{record-KRS2PHMW.js → record-Y4T5FPVF.js} +3 -3
- package/dist/{session-CLWAVJ2K.js → session-UPH7SPEU.js} +33 -7
- package/dist/session-UPH7SPEU.js.map +1 -0
- package/dist/{src-WLOHOI6P.js → src-3VT7JMAG.js} +2 -2
- package/dist/{start-CNNQUP5I.js → start-QMTRNSYD.js} +3 -3
- package/dist/{workflow-XXL4H5R4.js → workflow-U2NK4YED.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-4A4G5KTC.js.map +0 -1
- package/dist/chunk-6IAPGYZQ.js.map +0 -1
- package/dist/chunk-BOS2YLKH.js.map +0 -1
- package/dist/docs-CSVSGIGW.js.map +0 -1
- package/dist/init-BTDX5N6P.js.map +0 -1
- package/dist/session-CLWAVJ2K.js.map +0 -1
- /package/dist/{chunk-ZQF72UTG.js.map → chunk-W3OTKNJB.js.map} +0 -0
- /package/dist/{debug-workflow-DIQZDFMN.js.map → debug-workflow-JZKUDSVY.js.map} +0 -0
- /package/dist/{feature-flag-BIPFVVNC.js.map → feature-flag-7BD3NT6G.js.map} +0 -0
- /package/dist/{issues-EWVB52CA.js.map → issues-37LDBJU7.js.map} +0 -0
- /package/dist/{knobs-VYABZESR.js.map → knobs-QUJQ4NWV.js.map} +0 -0
- /package/dist/{list-RCPYLS36.js.map → list-2L2NGCSF.js.map} +0 -0
- /package/dist/{local-ZPVM4BXX.js.map → local-45POWSFC.js.map} +0 -0
- /package/dist/{local-browser-WV4IH2DU.js.map → local-browser-LHJHPWXU.js.map} +0 -0
- /package/dist/{login-W4GXV3VA.js.map → login-ZKF6GONZ.js.map} +0 -0
- /package/dist/{mcp-YER5GQG7.js.map → mcp-ETZ3OTXY.js.map} +0 -0
- /package/dist/{record-KRS2PHMW.js.map → record-Y4T5FPVF.js.map} +0 -0
- /package/dist/{src-WLOHOI6P.js.map → src-3VT7JMAG.js.map} +0 -0
- /package/dist/{start-CNNQUP5I.js.map → start-QMTRNSYD.js.map} +0 -0
- /package/dist/{workflow-XXL4H5R4.js.map → workflow-U2NK4YED.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli-helpers.ts"],"sourcesContent":["/**\n * Shared CLI helpers for superadmin management commands (knobs, feature-flags).\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport process from 'node:process';\nimport { getCanaryTmpDir } from '@chatsdet/tmp';\nimport { getArgValue } from './auth.js';\n\nexport type LifecycleStage = 'active' | 'deprecated' | 'ready_for_cleanup';\n\nexport function toLifecycleLabel(stage: LifecycleStage): string {\n switch (stage) {\n case 'deprecated':\n return 'deprecated';\n case 'ready_for_cleanup':\n return 'ready_for_cleanup';\n default:\n return 'active';\n }\n}\n\nexport function parseLifecycleStage(argv: string[]): LifecycleStage {\n const stage = getArgValue(argv, '--stage');\n if (!stage || !['active', 'deprecated', 'ready_for_cleanup'].includes(stage)) {\n console.error(\n 'Error: --stage is required and must be one of: active, deprecated, ready_for_cleanup'\n );\n process.exit(1);\n }\n return stage as LifecycleStage;\n}\n\nexport async function apiRequest<T extends { ok: boolean; error?: string }>(\n apiUrl: string,\n token: string,\n method: string,\n path: string,\n body?: Record<string, unknown>\n): Promise<T> {\n const res = await fetch(`${apiUrl}${path}`, {\n method,\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n ...(body ? { body: JSON.stringify(body) } : {}),\n });\n\n if (res.status === 401) {\n console.error('Error: Unauthorized. Your session may have expired.');\n console.error('Run: canary login');\n process.exit(1);\n }\n\n return (await res.json()) as T;\n}\n\nexport async function downloadStorageState(opts: {\n apiUrl: string;\n token: string;\n propertyId: string;\n credentialId: string;\n prefix?: string;\n}): Promise<string | undefined> {\n const tmpFile = path.join(getCanaryTmpDir(), `${opts.prefix ?? 'canary-ss'}-${Date.now()}.json`);\n try {\n const res = await fetch(\n `${opts.apiUrl}/org/properties/${opts.propertyId}/credentials/${opts.credentialId}/storage-state/download`,\n {\n headers: { Authorization: `Bearer ${opts.token}` },\n redirect: 'follow',\n }\n );\n if (res.ok) {\n const body = await res.text();\n await fs.writeFile(tmpFile, body, 'utf-8');\n return tmpFile;\n }\n } catch {\n // Caller handles missing storage state\n }\n return undefined;\n}\n\n/* ── Credential selection ─────────────────────────────────────────────── */\n\nexport interface CredentialListItem {\n id: string;\n name: string;\n propertyId: string;\n propertyName?: string;\n propertyBaseUrl?: string;\n loginUrl?: string;\n storageStateS3Key?: string | null;\n}\n\n/**\n * Fetch org credentials and let the user pick one interactively.\n *\n * @param credentialArg - Credential name or ID to auto-select, or undefined for interactive\n * @returns The selected credential, or null if none found / invalid selection\n */\nexport async function selectCredential(\n apiUrl: string,\n token: string,\n credentialArg?: string\n): Promise<CredentialListItem | null> {\n const credentials = await fetchList<CredentialListItem>(\n apiUrl,\n token,\n '/org/credentials',\n 'items'\n );\n\n if (credentials.length === 0) {\n console.error('No credentials found. Create one first in the web app.');\n return null;\n }\n\n if (credentialArg) {\n const match = credentials.find(\n (c) => c.id === credentialArg || c.name.toLowerCase() === credentialArg.toLowerCase()\n );\n if (!match) {\n console.error(`Credential \"${credentialArg}\" not found.`);\n console.error('Available credentials:');\n for (const c of credentials) {\n const baseUrl = c.propertyBaseUrl ? ` — ${c.propertyBaseUrl}` : '';\n console.error(` - ${c.name} [${c.propertyName ?? c.propertyId}${baseUrl}]`);\n }\n return null;\n }\n return match;\n }\n\n // Interactive selection\n console.log('\\nSelect a credential:\\n');\n const labels = credentials.map((c) => {\n const property = c.propertyName ?? c.propertyId;\n const baseUrl = c.propertyBaseUrl ? ` — ${c.propertyBaseUrl}` : '';\n return `${c.name} [${property}${baseUrl}]`;\n });\n\n const readline = await import('node:readline');\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n const answer = await new Promise<string>((resolve) => {\n for (let i = 0; i < labels.length; i++) {\n console.log(` ${i + 1}. ${labels[i]}`);\n }\n rl.question('\\nEnter number: ', (ans) => {\n rl.close();\n resolve(ans.trim());\n });\n });\n\n const idx = parseInt(answer, 10) - 1;\n if (isNaN(idx) || idx < 0 || idx >= credentials.length) {\n console.error('Invalid selection.');\n return null;\n }\n\n return credentials[idx];\n}\n\n/* ── Property selection ──────────────────────────────────────────────── */\n\ninterface PropertyListItem {\n id: string;\n name: string;\n baseUrl: string;\n}\n\nexport async function fetchProperties(apiUrl: string, token: string): Promise<PropertyListItem[]> {\n return fetchList<PropertyListItem>(apiUrl, token, '/org/properties', 'data');\n}\n\nexport async function selectProperty(\n apiUrl: string,\n token: string,\n hint?: string\n): Promise<PropertyListItem | null> {\n const properties = await fetchProperties(apiUrl, token);\n\n if (properties.length === 0) {\n console.error('No properties found. Create one first in the web app.');\n return null;\n }\n\n if (hint) {\n const match = properties.find(\n (p) => p.id === hint || p.name.toLowerCase() === hint.toLowerCase()\n );\n if (!match) {\n console.error(`Property \"${hint}\" not found.`);\n console.error('Available properties:');\n for (const p of properties) {\n console.error(` - ${p.name} (${p.baseUrl})`);\n }\n return null;\n }\n return match;\n }\n\n if (properties.length === 1) {\n console.log(`Auto-selected property: ${properties[0].name}`);\n return properties[0];\n }\n\n return promptChoice(\n 'Select a property:',\n properties.map((p) => ({ label: `${p.name} — ${p.baseUrl}`, value: p }))\n );\n}\n\n/* ── Interactive prompt helpers ──────────────────────────────────────── */\n\nexport async function promptInput(question: string, defaultValue?: string): Promise<string> {\n const readline = await import('node:readline');\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n const prompt = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;\n const answer = await new Promise<string>((resolve) => {\n rl.question(prompt, (ans) => {\n rl.close();\n resolve(ans.trim());\n });\n });\n return answer || defaultValue || '';\n}\n\nexport async function promptChoice<T>(\n question: string,\n options: Array<{ label: string; value: T }>\n): Promise<T | null> {\n console.log(`\\n${question}\\n`);\n for (let i = 0; i < options.length; i++) {\n console.log(` ${i + 1}. ${options[i].label}`);\n }\n const readline = await import('node:readline');\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n const answer = await new Promise<string>((resolve) => {\n rl.question('\\nEnter number: ', (ans) => {\n rl.close();\n resolve(ans.trim());\n });\n });\n\n const idx = parseInt(answer, 10) - 1;\n if (isNaN(idx) || idx < 0 || idx >= options.length) {\n console.error('Invalid selection.');\n return null;\n }\n return options[idx].value;\n}\n\nexport async function uploadStorageState(opts: {\n apiUrl: string;\n token: string;\n propertyId: string;\n credentialId: string;\n storageState: unknown;\n}): Promise<{ ok: boolean; s3Key?: string; error?: string }> {\n const res = await fetch(\n `${opts.apiUrl}/org/properties/${opts.propertyId}/credentials/${opts.credentialId}/storage-state/upload`,\n {\n method: 'PUT',\n headers: {\n Authorization: `Bearer ${opts.token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ storageState: opts.storageState }),\n }\n );\n\n if (res.status === 401) {\n console.error('Error: Unauthorized. Your session may have expired.');\n console.error('Run: canary login');\n process.exit(1);\n }\n\n return (await res.json()) as { ok: boolean; s3Key?: string; error?: string };\n}\n\nexport async function fetchList<T>(\n apiUrl: string,\n token: string,\n path: string,\n listKey: string\n): Promise<T[]> {\n const res = await fetch(`${apiUrl}${path}`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (res.status === 401) {\n console.error('Error: Unauthorized. Your session may have expired.');\n console.error('Run: canary login');\n process.exit(1);\n }\n\n const json = (await res.json()) as Record<string, unknown>;\n\n if (!json.ok) {\n console.error(`Error: ${json.error}`);\n process.exit(1);\n }\n\n return (json[listKey] as T[]) ?? [];\n}\n"],"mappings":"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","names":["path"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/docs.ts"],"sourcesContent":["/**\n * CLI Documentation Management\n *\n * Allows agents and superadmins to list, pull, edit, and push documentation pages.\n */\n\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport { getSubDir } from '@chatsdet/tmp';\nimport process from 'node:process';\nimport { resolveConfig, getArgValue, hasFlag } from './auth.js';\nimport { apiRequest, fetchList } from './cli-helpers.js';\n\ntype DocsPageListItem = {\n slug: string;\n title: string;\n description: string | null;\n updatedAt: string;\n publishedBy: string | null;\n};\n\ntype DocsVersionItem = {\n version: number;\n title: string;\n checksum: string;\n message: string | null;\n createdBy: string;\n createdAt: string;\n};\n\ntype DocsApiResponse = {\n ok: boolean;\n error?: string;\n data?: {\n slug?: string;\n title?: string;\n pages?: DocsPageListItem[];\n content?: string;\n versions?: DocsVersionItem[];\n };\n};\n\nconst DEFAULT_PULL_DIR = getSubDir('docs');\n\nasync function handleList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const jsonOutput = hasFlag(argv, '--json');\n const pages = await fetchList<DocsPageListItem>(apiUrl, token, '/public/docs/pages', 'pages');\n\n if (jsonOutput) {\n console.log(JSON.stringify(pages, null, 2));\n return;\n }\n\n if (pages.length === 0) {\n console.log('No documentation pages found.');\n return;\n }\n\n for (const page of pages) {\n const date = new Date(page.updatedAt).toISOString().slice(0, 10);\n const by = page.publishedBy ? ` (${page.publishedBy})` : '';\n console.log(` ${page.slug} ${page.title} [${date}${by}]`);\n }\n}\n\nasync function handleGet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const slug = argv[0];\n if (!slug || slug.startsWith('--')) {\n console.error('Error: Missing slug.');\n console.error('Usage: canary docs get <slug>');\n process.exit(1);\n }\n\n const res = await fetch(`${apiUrl}/public/docs/pages/raw?slug=${encodeURIComponent(slug)}`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (res.status === 404) {\n console.error(`Error: Page not found: ${slug}`);\n process.exit(1);\n }\n\n if (!res.ok) {\n console.error(`Error: ${res.statusText}`);\n process.exit(1);\n }\n\n const content = await res.text();\n console.log(content);\n}\n\nasync function handlePull(argv: string[], apiUrl: string, token: string): Promise<void> {\n const slug = argv[0];\n if (!slug || slug.startsWith('--')) {\n console.error('Error: Missing slug.');\n console.error('Usage: canary docs pull <slug> [--output <path>]');\n process.exit(1);\n }\n\n const outputPath = getArgValue(argv, '--output') ?? path.join(DEFAULT_PULL_DIR, `${slug}.md`);\n\n const res = await fetch(`${apiUrl}/public/docs/pages/raw?slug=${encodeURIComponent(slug)}`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (res.status === 404) {\n console.error(`Error: Page not found: ${slug}`);\n process.exit(1);\n }\n\n if (!res.ok) {\n console.error(`Error: ${res.statusText}`);\n process.exit(1);\n }\n\n const content = await res.text();\n await mkdir(path.dirname(outputPath), { recursive: true });\n await writeFile(outputPath, content, 'utf8');\n console.log(`Pulled ${slug} → ${outputPath}`);\n}\n\nasync function handlePush(argv: string[], apiUrl: string, token: string): Promise<void> {\n const slug = argv[0];\n if (!slug || slug.startsWith('--')) {\n console.error('Error: Missing slug.');\n console.error('Usage: canary docs push <slug> --file <path> [--message <text>]');\n process.exit(1);\n }\n\n const filePath = getArgValue(argv, '--file');\n if (!filePath) {\n console.error('Error: Missing --file <path>.');\n process.exit(1);\n }\n\n const message = getArgValue(argv, '--message') ?? undefined;\n const createdBy = getArgValue(argv, '--created-by') ?? undefined;\n\n let content: string;\n try {\n content = await readFile(filePath, 'utf8');\n } catch {\n console.error(`Error: Could not read file: ${filePath}`);\n process.exit(1);\n }\n\n const result = await apiRequest<DocsApiResponse>(\n apiUrl,\n token,\n 'PUT',\n `/superadmin/docs/pages?slug=${encodeURIComponent(slug)}`,\n { content, message, createdBy }\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n\n console.log(`Published new version of ${slug}`);\n}\n\nasync function handleHistory(argv: string[], apiUrl: string, token: string): Promise<void> {\n const slug = argv[0];\n if (!slug || slug.startsWith('--')) {\n console.error('Error: Missing slug.');\n console.error('Usage: canary docs history <slug>');\n process.exit(1);\n }\n\n const jsonOutput = hasFlag(argv, '--json');\n\n const res = await fetch(`${apiUrl}/public/docs/pages/versions?slug=${encodeURIComponent(slug)}`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({ error: res.statusText }));\n console.error(`Error: ${(body as { error?: string }).error ?? res.statusText}`);\n process.exit(1);\n }\n\n const body = (await res.json()) as DocsApiResponse;\n const versions = body.data?.versions ?? [];\n\n if (jsonOutput) {\n console.log(JSON.stringify(versions, null, 2));\n return;\n }\n\n if (versions.length === 0) {\n console.log(`No versions found for ${slug}.`);\n return;\n }\n\n for (const v of versions) {\n const date = new Date(v.createdAt).toISOString().slice(0, 19).replace('T', ' ');\n const msg = v.message ? ` — ${v.message}` : '';\n console.log(` v${v.version} ${date} ${v.createdBy}${msg}`);\n }\n}\n\nasync function handleCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const slug = argv[0];\n if (!slug || slug.startsWith('--')) {\n console.error('Error: Missing slug.');\n console.error('Usage: canary docs create <slug> --file <path> --title <text>');\n process.exit(1);\n }\n\n const filePath = getArgValue(argv, '--file');\n const title = getArgValue(argv, '--title');\n\n if (!filePath) {\n console.error('Error: Missing --file <path>.');\n process.exit(1);\n }\n if (!title) {\n console.error('Error: Missing --title <text>.');\n process.exit(1);\n }\n\n const description = getArgValue(argv, '--description') ?? undefined;\n const message = getArgValue(argv, '--message') ?? undefined;\n\n let content: string;\n try {\n content = await readFile(filePath, 'utf8');\n } catch {\n console.error(`Error: Could not read file: ${filePath}`);\n process.exit(1);\n }\n\n const result = await apiRequest<DocsApiResponse>(\n apiUrl,\n token,\n 'POST',\n '/superadmin/docs/pages',\n {\n slug,\n title,\n description,\n content,\n message,\n }\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n\n console.log(`Created page: ${slug}`);\n}\n\ntype DocsSearchResult = {\n path: string;\n title: string;\n description: string | null;\n excerpt: string;\n};\n\ntype DocsSearchResponse = {\n ok: boolean;\n error?: string;\n data?: { results: DocsSearchResult[] };\n};\n\nasync function handleSearch(argv: string[], apiUrl: string, token: string): Promise<void> {\n const query = argv.filter((a) => !a.startsWith('--')).join(' ').trim();\n if (!query) {\n console.error('Error: Missing search query.');\n console.error('Usage: canary docs search <query> [--limit <n>] [--json]');\n process.exit(1);\n }\n\n const jsonOutput = hasFlag(argv, '--json');\n const limitArg = getArgValue(argv, '--limit');\n const params = new URLSearchParams({ q: query });\n if (limitArg) params.set('limit', limitArg);\n\n const res = await fetch(`${apiUrl}/public/docs/search?${params.toString()}`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({ error: res.statusText }));\n console.error(`Error: ${(body as { error?: string }).error ?? res.statusText}`);\n process.exit(1);\n }\n\n const body = (await res.json()) as DocsSearchResponse;\n const results = body.data?.results ?? [];\n\n if (jsonOutput) {\n console.log(JSON.stringify(results, null, 2));\n return;\n }\n\n if (results.length === 0) {\n console.log('No results found.');\n return;\n }\n\n for (const r of results) {\n const desc = r.description ? ` ${r.description}` : '';\n const excerpt = r.excerpt\n ? ` ${r.excerpt.replace(/<\\/?mark>/g, '').replace(/\\n/g, ' ').slice(0, 120)}`\n : '';\n console.log(` ${r.path ?? r.title}`);\n if (r.title) console.log(` ${r.title}${desc}`);\n if (excerpt) console.log(` ${excerpt}`);\n console.log();\n }\n}\n\nasync function handleDelete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const slug = argv[0];\n if (!slug || slug.startsWith('--')) {\n console.error('Error: Missing slug.');\n console.error('Usage: canary docs delete <slug>');\n process.exit(1);\n }\n\n const result = await apiRequest<DocsApiResponse>(\n apiUrl,\n token,\n 'DELETE',\n `/superadmin/docs/pages?slug=${encodeURIComponent(slug)}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n\n console.log(`Deleted page: ${slug}`);\n}\n\nfunction printDocsHelp(): void {\n console.log(\n [\n 'Usage: canary docs <sub-command> [options]',\n '',\n 'Sub-commands:',\n ' list List all doc pages',\n ' get <slug> Print content to stdout',\n ' search <query> Full-text search docs',\n ' pull <slug> [--output <path>] Download to local file',\n ' push <slug> --file <path> [--message] Publish new version',\n ' history <slug> Show version history',\n ' create <slug> --file <path> --title ... Create new page',\n ' delete <slug> Soft-delete a page',\n '',\n 'Options:',\n ' --file <path> Path to markdown file',\n ' --title <text> Page title (create only)',\n ' --description <text> Page description (create only)',\n ' --message <text> Version commit message',\n ' --limit <n> Max results for search (default: 8, max: 20)',\n ' --output <path> Output path for pull (default: /tmp/canary/docs/<slug>.md)',\n ' --json Output as JSON (list, history, search)',\n ' --env <env> Target environment (prod, dev)',\n ' --api-url <url> API URL override',\n ' --token <key> API token override',\n ].join('\\n')\n );\n}\n\nexport async function runDocs(argv: string[]): Promise<void> {\n const [subCommand, ...rest] = argv;\n\n if (!subCommand || subCommand === 'help' || hasFlag(argv, '--help', '-h')) {\n printDocsHelp();\n return;\n }\n\n const { apiUrl, token } = await resolveConfig(argv);\n\n switch (subCommand) {\n case 'list':\n await handleList(rest, apiUrl, token);\n break;\n case 'get':\n await handleGet(rest, apiUrl, token);\n break;\n case 'search':\n await handleSearch(rest, apiUrl, token);\n break;\n case 'pull':\n await handlePull(rest, apiUrl, token);\n break;\n case 'push':\n await handlePush(rest, apiUrl, token);\n break;\n case 'history':\n await handleHistory(rest, apiUrl, token);\n break;\n case 'create':\n await handleCreate(rest, apiUrl, token);\n break;\n case 'delete':\n await handleDelete(rest, apiUrl, token);\n break;\n default:\n console.error(`Unknown sub-command: ${subCommand}`);\n printDocsHelp();\n process.exit(1);\n }\n}\n"],"mappings":"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","names":["body"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/local/init.ts"],"sourcesContent":["/**\n * `canary local init` — Interactive wizard for setting up local testing.\n *\n * Walks through: property selection, local URL, credential setup.\n *\n * @module\n */\n\nimport process from 'node:process';\nimport { resolveConfig } from '../auth.js';\nimport {\n selectProperty,\n promptInput,\n promptChoice,\n apiRequest,\n uploadStorageState,\n} from '../cli-helpers.js';\nimport {\n createSession,\n deleteSession,\n getSessionStorageState,\n} from '../session/daemon-client.js';\n\nexport async function runLocalInit(argv: string[]) {\n const config = await resolveConfig(argv);\n\n // 1. Select property\n console.log('\\n🔧 Local Testing Setup\\n');\n const property = await selectProperty(config.apiUrl, config.token);\n if (!property) {\n process.exitCode = 1;\n return;\n }\n\n // 2. Prompt for local URL\n const localUrl = await promptInput('What is the local testing URL?', 'http://localhost:3000');\n if (!localUrl) {\n console.error('URL is required.');\n process.exitCode = 1;\n return;\n }\n\n // 3. Create local environment\n const envName = `Local - ${localUrl}`;\n const envResult = await apiRequest<{\n ok: boolean;\n item?: { id: string; name: string };\n error?: string;\n }>(config.apiUrl, config.token, 'POST', `/org/properties/${property.id}/environments`, {\n name: envName,\n url: localUrl,\n type: 'local',\n });\n\n if (!envResult.ok || !envResult.item) {\n console.error(`Failed to create environment: ${envResult.error ?? 'Unknown error'}`);\n process.exitCode = 1;\n return;\n }\n\n console.log(`Created local environment: ${envResult.item.name}`);\n\n // 4. Credential setup\n const credentialChoice = await promptChoice('Does this app need credentials?', [\n { label: \"Yes, I'll enter username & password\", value: 'enter' },\n { label: \"No credentials, I'll log in myself\", value: 'manual' },\n { label: 'Skip — no login needed', value: 'skip' },\n ]);\n\n if (credentialChoice === 'enter') {\n await handleEnterCredentials(config, property.id, envResult.item.id, localUrl);\n } else if (credentialChoice === 'manual') {\n await handleManualLogin(config, property.id, envResult.item.id, localUrl);\n } else {\n console.log('\\nLocal environment ready. Run `canary local start` to begin.');\n }\n}\n\nasync function handleEnterCredentials(\n config: { apiUrl: string; token: string },\n propertyId: string,\n environmentId: string,\n localUrl: string\n) {\n const username = await promptInput('Username');\n const password = await promptInput('Password');\n\n if (!username || !password) {\n console.error('Username and password are required.');\n process.exitCode = 1;\n return;\n }\n\n const credResult = await apiRequest<{\n ok: boolean;\n item?: { id: string; name: string };\n error?: string;\n }>(config.apiUrl, config.token, 'POST', `/org/properties/${propertyId}/credentials`, {\n name: `Local - ${username}`,\n environmentId,\n authProvider: 'basic',\n data: { username, password },\n loginUrl: `${localUrl}/login`,\n });\n\n if (!credResult.ok) {\n console.error(`Failed to create credential: ${credResult.error ?? 'Unknown error'}`);\n process.exitCode = 1;\n return;\n }\n\n console.log(`\\nCreated credential: ${credResult.item?.name}`);\n console.log('Run `canary local start` to begin a session.');\n}\n\nasync function handleManualLogin(\n config: { apiUrl: string; token: string },\n propertyId: string,\n environmentId: string,\n localUrl: string\n) {\n // Create a minimal credential\n const credResult = await apiRequest<{\n ok: boolean;\n item?: { id: string; name: string };\n error?: string;\n }>(config.apiUrl, config.token, 'POST', `/org/properties/${propertyId}/credentials`, {\n name: 'Local - manual',\n environmentId,\n authProvider: 'custom',\n loginUrl: localUrl,\n });\n\n if (!credResult.ok || !credResult.item) {\n console.error(`Failed to create credential: ${credResult.error ?? 'Unknown error'}`);\n process.exitCode = 1;\n return;\n }\n\n const credentialId = credResult.item.id;\n\n // Start a headed session\n console.log('\\nOpening browser...');\n const sessionResult = await createSession({\n name: 'local-login',\n url: localUrl,\n });\n\n if (!sessionResult.ok || !sessionResult.data) {\n console.error(`Failed to start browser session: ${sessionResult.error ?? 'Unknown error'}`);\n process.exitCode = 1;\n return;\n }\n\n const sessionId = sessionResult.data.id;\n\n console.log(`Browser opened at ${localUrl}. Log in, then press Enter when done.`);\n\n // Wait for Enter keypress\n const readline = await import('node:readline');\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n await new Promise<void>((resolve) => {\n rl.question('', () => {\n rl.close();\n resolve();\n });\n });\n\n // Extract storage state\n console.log('Extracting login state...');\n const storageResult = await getSessionStorageState(sessionId);\n\n if (!storageResult.ok || !storageResult.data) {\n console.error(`Failed to extract storage state: ${storageResult.error ?? 'Unknown error'}`);\n await deleteSession(sessionId);\n process.exitCode = 1;\n return;\n }\n\n // Upload storage state\n console.log('Saving login state...');\n const uploadResult = await uploadStorageState({\n apiUrl: config.apiUrl,\n token: config.token,\n propertyId,\n credentialId,\n storageState: storageResult.data,\n });\n\n if (!uploadResult.ok) {\n console.error(`Failed to save login state: ${uploadResult.error ?? 'Unknown error'}`);\n await deleteSession(sessionId);\n process.exitCode = 1;\n return;\n }\n\n // Clean up login session\n await deleteSession(sessionId);\n\n console.log('\\nLogin state saved! Run `canary local start` to begin.');\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/session/index.ts","../src/session/credentials.ts","../src/session/daemon.ts"],"sourcesContent":["/**\n * CLI session command — `canary session <subcommand>`.\n *\n * Flat subcommands for session lifecycle and browser tool execution.\n * All commands delegate to the session daemon via HTTP.\n *\n * @module\n */\n\nimport process from 'node:process';\nimport { getArgValue, hasFlag } from '../auth.js';\nimport {\n createSession,\n listSessions,\n getSession,\n deleteSession,\n deleteAllSessions,\n swapSessionContext,\n callTool,\n resolveTargetSession,\n} from './daemon-client.js';\nimport { resolveCredential } from './credentials.js';\nimport { runDaemon } from './daemon.js';\nimport type { SessionInfo, ToolResponse } from './types.js';\n\n/* ── Output formatting ───────────────────────────────────────────────── */\n\nfunction formatUptime(startedAt: string): string {\n const seconds = Math.floor((Date.now() - new Date(startedAt).getTime()) / 1000);\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n const secs = seconds % 60;\n if (minutes < 60) return `${minutes}m ${secs}s`;\n const hours = Math.floor(minutes / 60);\n const mins = minutes % 60;\n return `${hours}h ${mins}m`;\n}\n\nfunction printSessionTable(sessions: SessionInfo[]) {\n if (sessions.length === 0) {\n console.log('No active sessions.');\n return;\n }\n\n const header = ['ID', 'NAME', 'MODE', 'CREDENTIAL', 'URL', 'UPTIME'];\n const rows = sessions.map((s) => [\n s.id,\n s.name,\n s.mode,\n s.credentialName ?? '(none)',\n s.url ?? '(none)',\n formatUptime(s.startedAt),\n ]);\n\n // Calculate column widths\n const widths = header.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n const pad = (str: string, width: number) => str.padEnd(width);\n console.log(header.map((h, i) => pad(h, widths[i])).join(' '));\n for (const row of rows) {\n console.log(row.map((cell, i) => pad(cell, widths[i])).join(' '));\n }\n}\n\nfunction printToolResult(result: ToolResponse, jsonMode: boolean) {\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exitCode = 1;\n return;\n }\n\n if (result.text) {\n console.log(result.text);\n }\n\n if (result.images?.length) {\n console.log(`[${result.images.length} image(s) captured]`);\n }\n}\n\n/* ── Subcommand: start ───────────────────────────────────────────────── */\n\nasync function handleStart(argv: string[]) {\n const headless = hasFlag(argv, '--headless');\n const name = getArgValue(argv, '--name');\n const url = getArgValue(argv, '--url');\n const storageStatePath = getArgValue(argv, '--storage-state');\n const jsonMode = hasFlag(argv, '--json');\n\n // Credential handling\n const credentialIdx = argv.indexOf('--credential');\n let resolvedCred: { storageStatePath: string | undefined; credentialName: string } | null = null;\n\n if (credentialIdx !== -1) {\n // Check if next arg is a value or another flag\n const nextArg = argv[credentialIdx + 1];\n const credentialArg = nextArg && !nextArg.startsWith('--') ? nextArg : undefined;\n resolvedCred = await resolveCredential(argv, credentialArg);\n if (!resolvedCred) {\n process.exitCode = 1;\n return;\n }\n }\n\n const result = await createSession({\n headless,\n name,\n url,\n storageStatePath: resolvedCred?.storageStatePath ?? storageStatePath,\n credentialName: resolvedCred?.credentialName,\n });\n\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exitCode = 1;\n return;\n }\n\n const session = result.data!;\n console.log(`Session \"${session.id}\" started (${session.mode})`);\n if (session.credentialName) {\n console.log(` Credential: ${session.credentialName}`);\n }\n // Show the requested URL if provided, since the daemon responds before navigation completes\n const displayUrl = url ?? session.url;\n if (displayUrl) {\n console.log(` URL: ${displayUrl}`);\n }\n}\n\n/* ── Subcommand: list ────────────────────────────────────────────────── */\n\nasync function handleList(argv: string[]) {\n const jsonMode = hasFlag(argv, '--json');\n const result = await listSessions();\n\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exitCode = 1;\n return;\n }\n\n printSessionTable(result.data ?? []);\n}\n\n/* ── Subcommand: status ──────────────────────────────────────────────── */\n\nasync function handleStatus(argv: string[]) {\n const sessionId =\n getArgValue(argv, '--session') ||\n (argv[0] && !argv[0].startsWith('--') ? argv[0] : undefined);\n const jsonMode = hasFlag(argv, '--json');\n\n try {\n const target = await resolveTargetSession(sessionId);\n const result = await getSession(target.id);\n\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (!result.ok || !result.data) {\n console.error(`Error: ${result.error}`);\n process.exitCode = 1;\n return;\n }\n\n const s = result.data;\n console.log(`Session: ${s.id} (${s.name})`);\n console.log(` Mode: ${s.mode}`);\n console.log(` Credential: ${s.credentialName ?? '(none)'}`);\n console.log(` URL: ${s.url ?? '(none)'}`);\n console.log(` Uptime: ${formatUptime(s.startedAt)}`);\n console.log(` Started: ${s.startedAt}`);\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n }\n}\n\n/* ── Subcommand: stop ────────────────────────────────────────────────── */\n\nasync function handleStop(argv: string[]) {\n const jsonMode = hasFlag(argv, '--json');\n\n if (hasFlag(argv, '--all')) {\n const result = await deleteAllSessions();\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n } else if (result.ok) {\n console.log('All sessions stopped.');\n } else {\n console.error(`Error: ${result.error}`);\n process.exitCode = 1;\n }\n return;\n }\n\n const sessionId =\n getArgValue(argv, '--session') ||\n (argv[0] && !argv[0].startsWith('--') ? argv[0] : undefined);\n\n try {\n const target = await resolveTargetSession(sessionId);\n const result = await deleteSession(target.id);\n\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n } else if (result.ok) {\n console.log(`Session \"${target.id}\" stopped.`);\n } else {\n console.error(`Error: ${result.error}`);\n process.exitCode = 1;\n }\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n }\n}\n\n/* ── Subcommand: load-credential ────────────────────────────────────── */\n\nasync function handleLoadCredential(argv: string[]) {\n const jsonMode = hasFlag(argv, '--json');\n const sessionId =\n getArgValue(argv, '--session') ||\n (argv[0] && !argv[0].startsWith('--') ? argv[0] : undefined);\n\n // Resolve which session to target\n let target;\n try {\n target = await resolveTargetSession(sessionId);\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n return;\n }\n\n // Credential selection (interactive by default, or --credential <name|id>)\n const credentialIdx = argv.indexOf('--credential');\n const nextArg = credentialIdx !== -1 ? argv[credentialIdx + 1] : undefined;\n const credentialArg = nextArg && !nextArg.startsWith('--') ? nextArg : undefined;\n\n // Also support --storage-state for local files\n const storageStatePath = getArgValue(argv, '--storage-state');\n\n let resolvedStorageStatePath: string | undefined;\n let credentialName: string | undefined;\n\n if (storageStatePath) {\n resolvedStorageStatePath = storageStatePath;\n credentialName = '(local storage state)';\n } else {\n // Interactive or named credential resolution\n const resolvedCred = await resolveCredential(argv, credentialArg);\n if (!resolvedCred) {\n process.exitCode = 1;\n return;\n }\n resolvedStorageStatePath = resolvedCred.storageStatePath;\n credentialName = resolvedCred.credentialName;\n }\n\n const result = await swapSessionContext(target.id, {\n storageStatePath: resolvedStorageStatePath,\n credentialName,\n });\n\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exitCode = 1;\n return;\n }\n\n const session = result.data!;\n console.log(`Credential loaded into session \"${session.id}\".`);\n if (session.credentialName) {\n console.log(` Credential: ${session.credentialName}`);\n }\n if (session.url) {\n console.log(` URL: ${session.url}`);\n }\n}\n\n/* ── Browser tool subcommands ────────────────────────────────────────── */\n\nasync function handleToolCommand(toolName: string, argv: string[]) {\n const sessionIdOrName = getArgValue(argv, '--session');\n const jsonMode = hasFlag(argv, '--json');\n\n try {\n const target = await resolveTargetSession(sessionIdOrName);\n const args = buildToolArgs(toolName, argv);\n const result = await callTool(target.id, toolName, args);\n printToolResult(result, jsonMode);\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n }\n}\n\nfunction buildToolArgs(toolName: string, argv: string[]): Record<string, unknown> {\n const args: Record<string, unknown> = {};\n\n switch (toolName) {\n case 'navigate':\n args.url = getArgValue(argv, '--url');\n break;\n\n case 'snapshot':\n args.search = getArgValue(argv, '--search');\n args.mode = getArgValue(argv, '--mode') ?? 'tree';\n break;\n\n case 'screenshot':\n args.fullPage = hasFlag(argv, '--full-page');\n args.label = getArgValue(argv, '--label');\n args.returnImage = true;\n break;\n\n case 'evaluate':\n args.function = getArgValue(argv, '--js');\n break;\n\n case 'click': {\n const ref = getArgValue(argv, '--ref');\n const x = getArgValue(argv, '--x');\n const y = getArgValue(argv, '--y');\n if (ref) args.ref = ref;\n if (x) args.x = parseInt(x, 10);\n if (y) args.y = parseInt(y, 10);\n args.element = getArgValue(argv, '--element') ?? '';\n break;\n }\n\n case 'type':\n args.ref = getArgValue(argv, '--ref');\n args.text = getArgValue(argv, '--text');\n args.element = getArgValue(argv, '--element') ?? '';\n args.submit = hasFlag(argv, '--submit');\n break;\n\n case 'fill_form': {\n const fieldsStr = getArgValue(argv, '--fields');\n if (fieldsStr) {\n try {\n args.fields = JSON.parse(fieldsStr);\n } catch {\n console.error('Error: --fields must be valid JSON');\n process.exitCode = 1;\n }\n }\n break;\n }\n\n case 'select_option':\n args.ref = getArgValue(argv, '--ref');\n args.value = getArgValue(argv, '--value');\n args.element = getArgValue(argv, '--element') ?? '';\n break;\n\n case 'press_key':\n args.key = getArgValue(argv, '--key');\n break;\n\n case 'scroll':\n args.direction = getArgValue(argv, '--direction') ?? 'down';\n {\n const amount = getArgValue(argv, '--amount');\n if (amount) args.amount = parseInt(amount, 10);\n }\n break;\n\n case 'hover':\n args.ref = getArgValue(argv, '--ref');\n args.element = getArgValue(argv, '--element') ?? '';\n break;\n\n case 'tabs': {\n args.action = getArgValue(argv, '--action') ?? 'list';\n const index = getArgValue(argv, '--index');\n if (index) args.index = parseInt(index, 10);\n break;\n }\n\n case 'wait_for': {\n args.text = getArgValue(argv, '--text');\n const timeout = getArgValue(argv, '--timeout');\n if (timeout) args.timeout = parseInt(timeout, 10);\n break;\n }\n\n case 'console_messages':\n args.onlyErrors = hasFlag(argv, '--only-errors');\n break;\n\n // navigate_back, network_requests, close, list_downloads, read_download\n // have no special args or use defaults\n }\n\n return args;\n}\n\n/* ── Command aliases ─────────────────────────────────────────────────── */\n\n/** Map flat CLI subcommands to browser tool names */\nconst TOOL_ALIASES: Record<string, string> = {\n navigate: 'navigate',\n back: 'navigate_back',\n snapshot: 'snapshot',\n screenshot: 'screenshot',\n evaluate: 'evaluate',\n click: 'click',\n type: 'type',\n fill: 'fill_form',\n select: 'select_option',\n press: 'press_key',\n scroll: 'scroll',\n hover: 'hover',\n drag: 'drag',\n tabs: 'tabs',\n wait: 'wait_for',\n console: 'console_messages',\n network: 'network_requests',\n};\n\n/* ── Help ────────────────────────────────────────────────────────────── */\n\nfunction printHelp() {\n console.log(\n [\n 'Usage: canary session <subcommand> [options]',\n '',\n 'Session lifecycle:',\n ' start [options] Start a new browser session',\n ' list List active sessions',\n ' status [<id>] Show session details',\n ' stop [<id>] Stop a session (or --all)',\n ' load-credential Load a credential into a running session',\n '',\n 'Browser actions:',\n ' navigate --url <url> Navigate to URL',\n ' back Navigate back',\n ' snapshot [--search <text>] [--mode tree|screenshot|both]',\n ' screenshot [--full-page] [--label <text>]',\n ' evaluate --js <expression> Evaluate JavaScript',\n ' click --ref <ref> [--element <desc>]',\n ' click --x <n> --y <n> [--element <desc>]',\n ' type --ref <ref> --text <text> [--submit]',\n ' fill --fields \\'[{\"ref\":\"e1\",\"value\":\"test\"}]\\'',\n ' select --ref <ref> --value <val> [--element <desc>]',\n ' press --key <key> Press keyboard key',\n ' scroll --direction <dir> [--amount <n>]',\n ' hover --ref <ref> [--element <desc>]',\n ' tabs [--action list|new|close|select] [--index <n>]',\n ' wait --text <text> [--timeout <ms>]',\n ' console [--only-errors] Show console messages',\n ' network Show network requests',\n '',\n 'Start options:',\n ' --credential [<name|id>] Use a credential (interactive if no value)',\n ' --storage-state <path> Use a local storage state file',\n ' --headless Run browser without visible UI',\n ' --url <url> Navigate to URL after launch',\n ' --name <label> Name the session',\n '',\n 'Load-credential options:',\n ' --credential [<name|id>] Use a credential (interactive if no value)',\n ' --storage-state <path> Use a local storage state file',\n '',\n 'Common options:',\n ' --session <id|name> Target a specific session (when multiple)',\n ' --json Output raw JSON',\n ' --env <env> Environment for credential resolution',\n ' -h, --help Show this help',\n ].join('\\n')\n );\n}\n\n/* ── Main entry ──────────────────────────────────────────────────────── */\n\nexport async function runSession(argv: string[]) {\n const [subcommand, ...rest] = argv;\n\n if (!subcommand || subcommand === 'help' || hasFlag(argv, '-h', '--help')) {\n printHelp();\n return;\n }\n\n // Internal: daemon process mode\n if (subcommand === 'daemon') {\n await runDaemon();\n return;\n }\n\n switch (subcommand) {\n case 'start':\n await handleStart(rest);\n break;\n case 'list':\n await handleList(rest);\n break;\n case 'status':\n await handleStatus(rest);\n break;\n case 'stop':\n await handleStop(rest);\n break;\n case 'load-credential':\n await handleLoadCredential(rest);\n break;\n default: {\n // Check for tool alias\n const toolName = TOOL_ALIASES[subcommand];\n if (toolName) {\n await handleToolCommand(toolName, rest);\n } else {\n console.error(`Unknown session subcommand: ${subcommand}`);\n printHelp();\n process.exitCode = 1;\n }\n }\n }\n}\n","/**\n * Credential resolution and storage state download for session commands.\n *\n * Uses shared selectCredential from cli-helpers for interactive selection,\n * then downloads the storage state for the selected credential.\n *\n * @module\n */\n\nimport { resolveConfig } from '../auth.js';\nimport { selectCredential, downloadStorageState } from '../cli-helpers.js';\n\n/**\n * Resolve a credential and download its storage state.\n *\n * @param argv - CLI arguments (for --env, --token, --api-url resolution)\n * @param credentialArg - Credential name, ID, or undefined for interactive selection\n * @returns Object with storageStatePath and credentialName, or null if no match\n */\nexport async function resolveCredential(\n argv: string[],\n credentialArg: string | undefined\n): Promise<{ storageStatePath: string | undefined; credentialName: string } | null> {\n const { apiUrl, token } = await resolveConfig(argv);\n\n const credential = await selectCredential(apiUrl, token, credentialArg);\n if (!credential) {\n return null;\n }\n\n console.log(`Fetching credential \"${credential.name}\"...`);\n\n let storageStatePath: string | undefined;\n if (credential.storageStateS3Key) {\n storageStatePath = await downloadStorageState({\n apiUrl,\n token,\n propertyId: credential.propertyId,\n credentialId: credential.id,\n prefix: 'session-ss',\n });\n\n if (storageStatePath) {\n console.log('Downloaded storage state.');\n } else {\n console.warn('Warning: Could not download storage state. Starting without auth.');\n }\n } else {\n console.log('Credential has no storage state. Starting without auth.');\n }\n\n return {\n storageStatePath,\n credentialName: credential.name,\n };\n}\n","/**\n * Session daemon — lightweight HTTP server that owns all browser sessions.\n *\n * Runs on localhost with an OS-assigned port. Both CLI and MCP delegate\n * browser lifecycle and tool execution to this daemon.\n *\n * @module\n */\n\nimport { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport os from 'node:os';\nimport {\n PlaywrightClient,\n BrowserToolExecutor,\n consoleLogger,\n dispatchBrowserTool,\n} from '@chatsdet/browser-core';\nimport type {\n DaemonState,\n SessionInfo,\n CreateSessionRequest,\n SwapContextRequest,\n DaemonResponse,\n ToolResponse,\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 IDLE_TIMEOUT_MS = 60_000;\n\ninterface ManagedSession {\n id: string;\n name: string;\n mode: 'headed' | 'headless';\n credentialName?: string;\n client: PlaywrightClient;\n executor: BrowserToolExecutor;\n startedAt: string;\n}\n\nconst sessions = new Map<string, ManagedSession>();\nlet nextId = 1;\nlet idleTimer: ReturnType<typeof setTimeout> | null = null;\n\nfunction resetIdleTimer() {\n if (idleTimer) clearTimeout(idleTimer);\n if (sessions.size === 0) {\n idleTimer = setTimeout(async () => {\n if (sessions.size === 0) {\n await removePidfile();\n process.exit(0);\n }\n }, IDLE_TIMEOUT_MS);\n }\n}\n\nfunction generateId(): string {\n return `s${nextId++}`;\n}\n\nasync function getSessionUrl(session: ManagedSession): Promise<string | undefined> {\n try {\n return await session.client.getCurrentUrl();\n } catch {\n return undefined;\n }\n}\n\nasync function toSessionInfo(s: ManagedSession): Promise<SessionInfo> {\n return {\n id: s.id,\n name: s.name,\n mode: s.mode,\n credentialName: s.credentialName,\n url: await getSessionUrl(s),\n startedAt: s.startedAt,\n };\n}\n\n/* ── Request parsing helpers ─────────────────────────────────────────── */\n\nasync function readBody(req: IncomingMessage): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);\n }\n return Buffer.concat(chunks).toString('utf-8');\n}\n\nfunction parseJson(body: string): Record<string, unknown> {\n if (!body.trim()) return {};\n try {\n return JSON.parse(body);\n } catch {\n return {};\n }\n}\n\nfunction json(res: ServerResponse, status: number, data: unknown) {\n const body = JSON.stringify(data);\n res.writeHead(status, {\n 'Content-Type': 'application/json',\n 'Content-Length': Buffer.byteLength(body),\n });\n res.end(body);\n}\n\nfunction parseRoute(url: string): { path: string[]; query: Record<string, string> } {\n const [pathname] = url.split('?');\n const segments = pathname.split('/').filter(Boolean);\n return { path: segments, query: {} };\n}\n\n/* ── Route handlers ──────────────────────────────────────────────────── */\n\nasync function handleHealth(res: ServerResponse) {\n json(res, 200, { ok: true, sessions: sessions.size });\n}\n\nasync function handleCreateSession(body: string, res: ServerResponse) {\n const params = parseJson(body) as CreateSessionRequest;\n const id = generateId();\n const name = params.name ?? id;\n const mode = params.headless ? 'headless' : 'headed';\n\n try {\n const client = new PlaywrightClient({ logger: consoleLogger });\n await client.connect({\n browserMode: mode,\n storageStatePath: params.storageStatePath,\n });\n\n const executor = new BrowserToolExecutor(client, {\n autoSnapshotAfterAction: true,\n includeScreenshotWithSnapshot: true,\n clickValidation: true,\n logger: consoleLogger,\n });\n\n const session: ManagedSession = {\n id,\n name,\n mode,\n credentialName: params.credentialName,\n client,\n executor,\n startedAt: new Date().toISOString(),\n };\n\n sessions.set(id, session);\n if (idleTimer) {\n clearTimeout(idleTimer);\n idleTimer = null;\n }\n\n const result: DaemonResponse<SessionInfo> = {\n ok: true,\n data: await toSessionInfo(session),\n };\n json(res, 201, result);\n\n // Navigate after responding — navigation can take 30+ seconds and the\n // CLI intentionally does not wait so callers can issue commands in parallel.\n if (params.url) {\n client.navigate(params.url).catch((err) => {\n consoleLogger.warn(`Initial navigation to ${params.url} failed: ${err}`);\n });\n }\n } catch (err) {\n const result: DaemonResponse = {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n json(res, 500, result);\n }\n}\n\nasync function handleListSessions(res: ServerResponse) {\n const list = await Promise.all(Array.from(sessions.values()).map(toSessionInfo));\n json(res, 200, { ok: true, data: list } satisfies DaemonResponse<SessionInfo[]>);\n}\n\nasync function handleGetSession(sessionId: string, res: ServerResponse) {\n const session = sessions.get(sessionId);\n if (!session) {\n json(res, 404, {\n ok: false,\n error: `Session \"${sessionId}\" not found`,\n } satisfies DaemonResponse);\n return;\n }\n json(res, 200, {\n ok: true,\n data: await toSessionInfo(session),\n } satisfies DaemonResponse<SessionInfo>);\n}\n\nasync function handleDeleteSession(sessionId: string, res: ServerResponse) {\n const session = sessions.get(sessionId);\n if (!session) {\n json(res, 404, {\n ok: false,\n error: `Session \"${sessionId}\" not found`,\n } satisfies DaemonResponse);\n return;\n }\n\n try {\n await session.client.disconnect();\n } catch {\n // Best effort\n }\n sessions.delete(sessionId);\n json(res, 200, { ok: true } satisfies DaemonResponse);\n resetIdleTimer();\n}\n\nasync function handleDeleteAllSessions(res: ServerResponse) {\n for (const session of sessions.values()) {\n try {\n await session.client.disconnect();\n } catch {\n // Best effort\n }\n }\n sessions.clear();\n json(res, 200, { ok: true } satisfies DaemonResponse);\n resetIdleTimer();\n}\n\nasync function handleSwapContext(sessionId: string, body: string, res: ServerResponse) {\n const session = sessions.get(sessionId);\n if (!session) {\n json(res, 404, {\n ok: false,\n error: `Session \"${sessionId}\" not found`,\n } satisfies DaemonResponse);\n return;\n }\n\n const params = parseJson(body) as SwapContextRequest;\n\n try {\n await session.client.swapContext({\n storageStatePath: params.storageStatePath,\n });\n\n if (params.credentialName) {\n session.credentialName = params.credentialName;\n }\n\n json(res, 200, {\n ok: true,\n data: await toSessionInfo(session),\n } satisfies DaemonResponse<SessionInfo>);\n } catch (err) {\n json(res, 500, {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n } satisfies DaemonResponse);\n }\n}\n\nasync function handleGetStorageState(sessionId: string, res: ServerResponse) {\n const session = sessions.get(sessionId);\n if (!session) {\n json(res, 404, {\n ok: false,\n error: `Session \"${sessionId}\" not found`,\n } satisfies DaemonResponse);\n return;\n }\n\n try {\n const storageState = await session.client.getStorageState();\n json(res, 200, { ok: true, data: storageState } satisfies DaemonResponse);\n } catch (err) {\n json(res, 500, {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n } satisfies DaemonResponse);\n }\n}\n\nasync function handleToolCall(\n sessionId: string,\n toolName: string,\n body: string,\n res: ServerResponse\n) {\n const session = sessions.get(sessionId);\n if (!session) {\n json(res, 404, {\n ok: false,\n error: `Session \"${sessionId}\" not found`,\n } satisfies DaemonResponse);\n return;\n }\n\n const args = parseJson(body);\n const fullToolName = toolName.startsWith('browser_') ? toolName : `browser_${toolName}`;\n\n try {\n const result = await dispatchBrowserTool(session.executor, fullToolName, args);\n\n if (typeof result === 'string') {\n json(res, 200, { ok: true, text: result } satisfies ToolResponse);\n } else {\n json(res, 200, {\n ok: true,\n text: result.text,\n images: result.images,\n } satisfies ToolResponse);\n }\n } catch (err) {\n json(res, 500, {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n } satisfies ToolResponse);\n }\n}\n\n/* ── Server routing ──────────────────────────────────────────────────── */\n\nasync function handleRequest(req: IncomingMessage, res: ServerResponse) {\n const method = req.method ?? 'GET';\n const { path: segments } = parseRoute(req.url ?? '/');\n const body = method === 'POST' || method === 'DELETE' ? await readBody(req) : '';\n\n try {\n // GET /health\n if (method === 'GET' && segments[0] === 'health') {\n await handleHealth(res);\n return;\n }\n\n // POST /sessions\n if (method === 'POST' && segments[0] === 'sessions' && segments.length === 1) {\n await handleCreateSession(body, res);\n return;\n }\n\n // GET /sessions\n if (method === 'GET' && segments[0] === 'sessions' && segments.length === 1) {\n await handleListSessions(res);\n return;\n }\n\n // GET /sessions/:id\n if (method === 'GET' && segments[0] === 'sessions' && segments.length === 2) {\n await handleGetSession(segments[1], res);\n return;\n }\n\n // DELETE /sessions (all)\n if (method === 'DELETE' && segments[0] === 'sessions' && segments.length === 1) {\n await handleDeleteAllSessions(res);\n return;\n }\n\n // DELETE /sessions/:id\n if (method === 'DELETE' && segments[0] === 'sessions' && segments.length === 2) {\n await handleDeleteSession(segments[1], res);\n return;\n }\n\n // POST /sessions/:id/swap-context\n if (\n method === 'POST' &&\n segments[0] === 'sessions' &&\n segments[2] === 'swap-context' &&\n segments.length === 3\n ) {\n await handleSwapContext(segments[1], body, res);\n return;\n }\n\n // GET /sessions/:id/storage-state\n if (\n method === 'GET' &&\n segments[0] === 'sessions' &&\n segments[2] === 'storage-state' &&\n segments.length === 3\n ) {\n await handleGetStorageState(segments[1], res);\n return;\n }\n\n // POST /sessions/:id/tools/:toolName\n if (\n method === 'POST' &&\n segments[0] === 'sessions' &&\n segments[2] === 'tools' &&\n segments.length === 4\n ) {\n await handleToolCall(segments[1], segments[3], body, res);\n return;\n }\n\n json(res, 404, { ok: false, error: 'Not found' });\n } catch (err) {\n json(res, 500, { ok: false, error: err instanceof Error ? err.message : String(err) });\n }\n}\n\n/* ── Pidfile management ──────────────────────────────────────────────── */\n\nasync function writePidfile(port: number) {\n await fs.mkdir(PIDFILE_DIR, { recursive: true, mode: 0o700 });\n const state: DaemonState = {\n pid: process.pid,\n port,\n startedAt: new Date().toISOString(),\n };\n await fs.writeFile(PIDFILE_PATH, JSON.stringify(state, null, 2), { mode: 0o600 });\n}\n\nasync function removePidfile() {\n try {\n await fs.unlink(PIDFILE_PATH);\n } catch {\n // Already removed\n }\n}\n\n/* ── Cleanup ─────────────────────────────────────────────────────────── */\n\nasync function cleanup() {\n for (const session of sessions.values()) {\n try {\n await session.client.disconnect();\n } catch {\n // Best effort\n }\n }\n sessions.clear();\n await removePidfile();\n}\n\n/* ── Main entry ──────────────────────────────────────────────────────── */\n\nasync function startDaemon(): Promise<{ port: number }> {\n const server = createServer(handleRequest);\n // Disable keep-alive to prevent \"other side closed\" socket errors when\n // the client reuses a connection the server is about to close.\n server.keepAliveTimeout = 0;\n\n return new Promise((resolve, reject) => {\n server.listen(0, '127.0.0.1', async () => {\n const addr = server.address();\n if (!addr || typeof addr === 'string') {\n reject(new Error('Failed to get server address'));\n return;\n }\n\n const port = addr.port;\n await writePidfile(port);\n resetIdleTimer();\n\n // Graceful shutdown\n process.on('SIGINT', async () => {\n await cleanup();\n process.exit(0);\n });\n process.on('SIGTERM', async () => {\n await cleanup();\n process.exit(0);\n });\n process.on('exit', () => {\n removePidfile().catch(() => {});\n });\n\n resolve({ port });\n });\n\n server.on('error', reject);\n });\n}\n\n/** CLI entry point: `canary session daemon` (internal, spawned by daemon-client) */\nexport async function runDaemon() {\n const { port } = await startDaemon();\n // Write the port to stdout so the spawner can read it\n process.stdout.write(`DAEMON_READY:${port}\\n`);\n}\n"],"mappings":"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","names":["process","sessions","process"]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|