@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.
Files changed (48) hide show
  1. package/dist/{chunk-4A4G5KTC.js → chunk-N7L7AH6L.js} +48 -23
  2. package/dist/chunk-N7L7AH6L.js.map +1 -0
  3. package/dist/{chunk-ZQF72UTG.js → chunk-W3OTKNJB.js} +2 -2
  4. package/dist/{chunk-BOS2YLKH.js → chunk-XSOKWWRV.js} +2 -2
  5. package/dist/chunk-XSOKWWRV.js.map +1 -0
  6. package/dist/{chunk-6IAPGYZQ.js → chunk-ZYUOJQQX.js} +298 -2
  7. package/dist/chunk-ZYUOJQQX.js.map +1 -0
  8. package/dist/{debug-workflow-DIQZDFMN.js → debug-workflow-JZKUDSVY.js} +4 -4
  9. package/dist/{docs-CSVSGIGW.js → docs-FORYHZVU.js} +13 -7
  10. package/dist/docs-FORYHZVU.js.map +1 -0
  11. package/dist/{feature-flag-BIPFVVNC.js → feature-flag-7BD3NT6G.js} +2 -2
  12. package/dist/index.js +11 -11
  13. package/dist/{init-BTDX5N6P.js → init-JHZ3OWKQ.js} +7 -6
  14. package/dist/init-JHZ3OWKQ.js.map +1 -0
  15. package/dist/{issues-EWVB52CA.js → issues-37LDBJU7.js} +2 -2
  16. package/dist/{knobs-VYABZESR.js → knobs-QUJQ4NWV.js} +2 -2
  17. package/dist/{list-RCPYLS36.js → list-2L2NGCSF.js} +2 -2
  18. package/dist/{local-ZPVM4BXX.js → local-45POWSFC.js} +5 -5
  19. package/dist/{local-browser-WV4IH2DU.js → local-browser-LHJHPWXU.js} +3 -3
  20. package/dist/{login-W4GXV3VA.js → login-ZKF6GONZ.js} +3 -3
  21. package/dist/{mcp-YER5GQG7.js → mcp-ETZ3OTXY.js} +4 -4
  22. package/dist/{record-KRS2PHMW.js → record-Y4T5FPVF.js} +3 -3
  23. package/dist/{session-CLWAVJ2K.js → session-UPH7SPEU.js} +33 -7
  24. package/dist/session-UPH7SPEU.js.map +1 -0
  25. package/dist/{src-WLOHOI6P.js → src-3VT7JMAG.js} +2 -2
  26. package/dist/{start-CNNQUP5I.js → start-QMTRNSYD.js} +3 -3
  27. package/dist/{workflow-XXL4H5R4.js → workflow-U2NK4YED.js} +2 -2
  28. package/package.json +1 -1
  29. package/dist/chunk-4A4G5KTC.js.map +0 -1
  30. package/dist/chunk-6IAPGYZQ.js.map +0 -1
  31. package/dist/chunk-BOS2YLKH.js.map +0 -1
  32. package/dist/docs-CSVSGIGW.js.map +0 -1
  33. package/dist/init-BTDX5N6P.js.map +0 -1
  34. package/dist/session-CLWAVJ2K.js.map +0 -1
  35. /package/dist/{chunk-ZQF72UTG.js.map → chunk-W3OTKNJB.js.map} +0 -0
  36. /package/dist/{debug-workflow-DIQZDFMN.js.map → debug-workflow-JZKUDSVY.js.map} +0 -0
  37. /package/dist/{feature-flag-BIPFVVNC.js.map → feature-flag-7BD3NT6G.js.map} +0 -0
  38. /package/dist/{issues-EWVB52CA.js.map → issues-37LDBJU7.js.map} +0 -0
  39. /package/dist/{knobs-VYABZESR.js.map → knobs-QUJQ4NWV.js.map} +0 -0
  40. /package/dist/{list-RCPYLS36.js.map → list-2L2NGCSF.js.map} +0 -0
  41. /package/dist/{local-ZPVM4BXX.js.map → local-45POWSFC.js.map} +0 -0
  42. /package/dist/{local-browser-WV4IH2DU.js.map → local-browser-LHJHPWXU.js.map} +0 -0
  43. /package/dist/{login-W4GXV3VA.js.map → login-ZKF6GONZ.js.map} +0 -0
  44. /package/dist/{mcp-YER5GQG7.js.map → mcp-ETZ3OTXY.js.map} +0 -0
  45. /package/dist/{record-KRS2PHMW.js.map → record-Y4T5FPVF.js.map} +0 -0
  46. /package/dist/{src-WLOHOI6P.js.map → src-3VT7JMAG.js.map} +0 -0
  47. /package/dist/{start-CNNQUP5I.js.map → start-QMTRNSYD.js.map} +0 -0
  48. /package/dist/{workflow-XXL4H5R4.js.map → workflow-U2NK4YED.js.map} +0 -0
@@ -1,16 +1,16 @@
1
1
  import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
2
  import {
3
3
  downloadStorageState
4
- } from "./chunk-BOS2YLKH.js";
4
+ } from "./chunk-XSOKWWRV.js";
5
5
  import {
6
6
  LocalBrowserHost
7
- } from "./chunk-ZQF72UTG.js";
7
+ } from "./chunk-W3OTKNJB.js";
8
8
  import {
9
9
  getArgValue,
10
10
  hasFlag,
11
11
  resolveConfig
12
12
  } from "./chunk-ACRIE2YR.js";
13
- import "./chunk-6IAPGYZQ.js";
13
+ import "./chunk-ZYUOJQQX.js";
14
14
  import "./chunk-XAA5VQ5N.js";
15
15
  import "./chunk-P5Z2Y5VV.js";
16
16
  import "./chunk-VKVL7WBN.js";
@@ -260,4 +260,4 @@ async function runDebugWorkflow(argv) {
260
260
  export {
261
261
  runDebugWorkflow
262
262
  };
263
- //# sourceMappingURL=debug-workflow-DIQZDFMN.js.map
263
+ //# sourceMappingURL=debug-workflow-JZKUDSVY.js.map
@@ -1,8 +1,7 @@
1
1
  import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
2
  import {
3
- apiRequest,
4
- fetchList
5
- } from "./chunk-BOS2YLKH.js";
3
+ apiRequest
4
+ } from "./chunk-XSOKWWRV.js";
6
5
  import {
7
6
  getArgValue,
8
7
  hasFlag,
@@ -20,7 +19,8 @@ import process from "process";
20
19
  var DEFAULT_PULL_DIR = getSubDir("docs");
21
20
  async function handleList(argv, apiUrl, token) {
22
21
  const jsonOutput = hasFlag(argv, "--json");
23
- const pages = await fetchList(apiUrl, token, "/public/docs/pages", "pages");
22
+ const result = await apiRequest(apiUrl, token, "GET", "/public/docs/pages");
23
+ const pages = result.data?.pages ?? [];
24
24
  if (jsonOutput) {
25
25
  console.log(JSON.stringify(pages, null, 2));
26
26
  return;
@@ -29,10 +29,16 @@ async function handleList(argv, apiUrl, token) {
29
29
  console.log("No documentation pages found.");
30
30
  return;
31
31
  }
32
+ const slugWidth = Math.max(4, ...pages.map((p) => p.slug.length));
33
+ const titleWidth = Math.max(5, ...pages.map((p) => p.title.length));
34
+ const header = `| ${"Slug".padEnd(slugWidth)} | ${"Title".padEnd(titleWidth)} | Updated | Published By |`;
35
+ const sep = `| ${"-".repeat(slugWidth)} | ${"-".repeat(titleWidth)} | ---------- | ------------ |`;
36
+ console.log(header);
37
+ console.log(sep);
32
38
  for (const page of pages) {
33
39
  const date = new Date(page.updatedAt).toISOString().slice(0, 10);
34
- const by = page.publishedBy ? ` (${page.publishedBy})` : "";
35
- console.log(` ${page.slug} ${page.title} [${date}${by}]`);
40
+ const by = page.publishedBy ?? "";
41
+ console.log(`| ${page.slug.padEnd(slugWidth)} | ${page.title.padEnd(titleWidth)} | ${date} | ${by.padEnd(12)} |`);
36
42
  }
37
43
  }
38
44
  async function handleGet(argv, apiUrl, token) {
@@ -318,4 +324,4 @@ async function runDocs(argv) {
318
324
  export {
319
325
  runDocs
320
326
  };
321
- //# sourceMappingURL=docs-CSVSGIGW.js.map
327
+ //# sourceMappingURL=docs-FORYHZVU.js.map
@@ -0,0 +1 @@
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 } 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 result = await apiRequest<DocsApiResponse>(apiUrl, token, 'GET', '/public/docs/pages');\n const pages: DocsPageListItem[] = result.data?.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 // Default: markdown table for easy consumption by agents and humans\n const slugWidth = Math.max(4, ...pages.map((p) => p.slug.length));\n const titleWidth = Math.max(5, ...pages.map((p) => p.title.length));\n const header = `| ${'Slug'.padEnd(slugWidth)} | ${'Title'.padEnd(titleWidth)} | Updated | Published By |`;\n const sep = `| ${'-'.repeat(slugWidth)} | ${'-'.repeat(titleWidth)} | ---------- | ------------ |`;\n console.log(header);\n console.log(sep);\n for (const page of pages) {\n const date = new Date(page.updatedAt).toISOString().slice(0, 10);\n const by = page.publishedBy ?? '';\n console.log(`| ${page.slug.padEnd(slugWidth)} | ${page.title.padEnd(titleWidth)} | ${date} | ${by.padEnd(12)} |`);\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":";;;;;;;;;;;;;;;AAMA,SAAS,UAAU,WAAW,aAAa;AAC3C,OAAO,UAAU;AAEjB,OAAO,aAAa;AAiCpB,IAAM,mBAAmB,UAAU,MAAM;AAEzC,eAAe,WAAW,MAAgB,QAAgB,OAA8B;AACtF,QAAM,aAAa,QAAQ,MAAM,QAAQ;AACzC,QAAM,SAAS,MAAM,WAA4B,QAAQ,OAAO,OAAO,oBAAoB;AAC3F,QAAM,QAA4B,OAAO,MAAM,SAAS,CAAC;AAEzD,MAAI,YAAY;AACd,YAAQ,IAAI,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAC1C;AAAA,EACF;AAEA,MAAI,MAAM,WAAW,GAAG;AACtB,YAAQ,IAAI,+BAA+B;AAC3C;AAAA,EACF;AAGA,QAAM,YAAY,KAAK,IAAI,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,KAAK,MAAM,CAAC;AAChE,QAAM,aAAa,KAAK,IAAI,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC;AAClE,QAAM,SAAS,KAAK,OAAO,OAAO,SAAS,CAAC,MAAM,QAAQ,OAAO,UAAU,CAAC;AAC5E,QAAM,MAAM,KAAK,IAAI,OAAO,SAAS,CAAC,MAAM,IAAI,OAAO,UAAU,CAAC;AAClE,UAAQ,IAAI,MAAM;AAClB,UAAQ,IAAI,GAAG;AACf,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,IAAI,KAAK,KAAK,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAC/D,UAAM,KAAK,KAAK,eAAe;AAC/B,YAAQ,IAAI,KAAK,KAAK,KAAK,OAAO,SAAS,CAAC,MAAM,KAAK,MAAM,OAAO,UAAU,CAAC,MAAM,IAAI,MAAM,GAAG,OAAO,EAAE,CAAC,IAAI;AAAA,EAClH;AACF;AAEA,eAAe,UAAU,MAAgB,QAAgB,OAA8B;AACrF,QAAM,OAAO,KAAK,CAAC;AACnB,MAAI,CAAC,QAAQ,KAAK,WAAW,IAAI,GAAG;AAClC,YAAQ,MAAM,sBAAsB;AACpC,YAAQ,MAAM,+BAA+B;AAC7C,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,MAAM,MAAM,MAAM,GAAG,MAAM,+BAA+B,mBAAmB,IAAI,CAAC,IAAI;AAAA,IAC1F,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,EAC9C,CAAC;AAED,MAAI,IAAI,WAAW,KAAK;AACtB,YAAQ,MAAM,0BAA0B,IAAI,EAAE;AAC9C,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,CAAC,IAAI,IAAI;AACX,YAAQ,MAAM,UAAU,IAAI,UAAU,EAAE;AACxC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,UAAU,MAAM,IAAI,KAAK;AAC/B,UAAQ,IAAI,OAAO;AACrB;AAEA,eAAe,WAAW,MAAgB,QAAgB,OAA8B;AACtF,QAAM,OAAO,KAAK,CAAC;AACnB,MAAI,CAAC,QAAQ,KAAK,WAAW,IAAI,GAAG;AAClC,YAAQ,MAAM,sBAAsB;AACpC,YAAQ,MAAM,kDAAkD;AAChE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,aAAa,YAAY,MAAM,UAAU,KAAK,KAAK,KAAK,kBAAkB,GAAG,IAAI,KAAK;AAE5F,QAAM,MAAM,MAAM,MAAM,GAAG,MAAM,+BAA+B,mBAAmB,IAAI,CAAC,IAAI;AAAA,IAC1F,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,EAC9C,CAAC;AAED,MAAI,IAAI,WAAW,KAAK;AACtB,YAAQ,MAAM,0BAA0B,IAAI,EAAE;AAC9C,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,CAAC,IAAI,IAAI;AACX,YAAQ,MAAM,UAAU,IAAI,UAAU,EAAE;AACxC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,UAAU,MAAM,IAAI,KAAK;AAC/B,QAAM,MAAM,KAAK,QAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AACzD,QAAM,UAAU,YAAY,SAAS,MAAM;AAC3C,UAAQ,IAAI,UAAU,IAAI,WAAM,UAAU,EAAE;AAC9C;AAEA,eAAe,WAAW,MAAgB,QAAgB,OAA8B;AACtF,QAAM,OAAO,KAAK,CAAC;AACnB,MAAI,CAAC,QAAQ,KAAK,WAAW,IAAI,GAAG;AAClC,YAAQ,MAAM,sBAAsB;AACpC,YAAQ,MAAM,iEAAiE;AAC/E,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,WAAW,YAAY,MAAM,QAAQ;AAC3C,MAAI,CAAC,UAAU;AACb,YAAQ,MAAM,+BAA+B;AAC7C,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,UAAU,YAAY,MAAM,WAAW,KAAK;AAClD,QAAM,YAAY,YAAY,MAAM,cAAc,KAAK;AAEvD,MAAI;AACJ,MAAI;AACF,cAAU,MAAM,SAAS,UAAU,MAAM;AAAA,EAC3C,QAAQ;AACN,YAAQ,MAAM,+BAA+B,QAAQ,EAAE;AACvD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,+BAA+B,mBAAmB,IAAI,CAAC;AAAA,IACvD,EAAE,SAAS,SAAS,UAAU;AAAA,EAChC;AAEA,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;AACtC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,4BAA4B,IAAI,EAAE;AAChD;AAEA,eAAe,cAAc,MAAgB,QAAgB,OAA8B;AACzF,QAAM,OAAO,KAAK,CAAC;AACnB,MAAI,CAAC,QAAQ,KAAK,WAAW,IAAI,GAAG;AAClC,YAAQ,MAAM,sBAAsB;AACpC,YAAQ,MAAM,mCAAmC;AACjD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,aAAa,QAAQ,MAAM,QAAQ;AAEzC,QAAM,MAAM,MAAM,MAAM,GAAG,MAAM,oCAAoC,mBAAmB,IAAI,CAAC,IAAI;AAAA,IAC/F,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,EAC9C,CAAC;AAED,MAAI,CAAC,IAAI,IAAI;AACX,UAAMA,QAAO,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE;AACrE,YAAQ,MAAM,UAAWA,MAA4B,SAAS,IAAI,UAAU,EAAE;AAC9E,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,QAAM,WAAW,KAAK,MAAM,YAAY,CAAC;AAEzC,MAAI,YAAY;AACd,YAAQ,IAAI,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAC7C;AAAA,EACF;AAEA,MAAI,SAAS,WAAW,GAAG;AACzB,YAAQ,IAAI,yBAAyB,IAAI,GAAG;AAC5C;AAAA,EACF;AAEA,aAAW,KAAK,UAAU;AACxB,UAAM,OAAO,IAAI,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,EAAE,QAAQ,KAAK,GAAG;AAC9E,UAAM,MAAM,EAAE,UAAU,WAAM,EAAE,OAAO,KAAK;AAC5C,YAAQ,IAAI,MAAM,EAAE,OAAO,KAAK,IAAI,KAAK,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,EAC9D;AACF;AAEA,eAAe,aAAa,MAAgB,QAAgB,OAA8B;AACxF,QAAM,OAAO,KAAK,CAAC;AACnB,MAAI,CAAC,QAAQ,KAAK,WAAW,IAAI,GAAG;AAClC,YAAQ,MAAM,sBAAsB;AACpC,YAAQ,MAAM,+DAA+D;AAC7E,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,WAAW,YAAY,MAAM,QAAQ;AAC3C,QAAM,QAAQ,YAAY,MAAM,SAAS;AAEzC,MAAI,CAAC,UAAU;AACb,YAAQ,MAAM,+BAA+B;AAC7C,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,CAAC,OAAO;AACV,YAAQ,MAAM,gCAAgC;AAC9C,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,cAAc,YAAY,MAAM,eAAe,KAAK;AAC1D,QAAM,UAAU,YAAY,MAAM,WAAW,KAAK;AAElD,MAAI;AACJ,MAAI;AACF,cAAU,MAAM,SAAS,UAAU,MAAM;AAAA,EAC3C,QAAQ;AACN,YAAQ,MAAM,+BAA+B,QAAQ,EAAE;AACvD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;AACtC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,iBAAiB,IAAI,EAAE;AACrC;AAeA,eAAe,aAAa,MAAgB,QAAgB,OAA8B;AACxF,QAAM,QAAQ,KAAK,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,IAAI,CAAC,EAAE,KAAK,GAAG,EAAE,KAAK;AACrE,MAAI,CAAC,OAAO;AACV,YAAQ,MAAM,8BAA8B;AAC5C,YAAQ,MAAM,0DAA0D;AACxE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,aAAa,QAAQ,MAAM,QAAQ;AACzC,QAAM,WAAW,YAAY,MAAM,SAAS;AAC5C,QAAM,SAAS,IAAI,gBAAgB,EAAE,GAAG,MAAM,CAAC;AAC/C,MAAI,SAAU,QAAO,IAAI,SAAS,QAAQ;AAE1C,QAAM,MAAM,MAAM,MAAM,GAAG,MAAM,uBAAuB,OAAO,SAAS,CAAC,IAAI;AAAA,IAC3E,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,EAC9C,CAAC;AAED,MAAI,CAAC,IAAI,IAAI;AACX,UAAMA,QAAO,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE;AACrE,YAAQ,MAAM,UAAWA,MAA4B,SAAS,IAAI,UAAU,EAAE;AAC9E,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,QAAM,UAAU,KAAK,MAAM,WAAW,CAAC;AAEvC,MAAI,YAAY;AACd,YAAQ,IAAI,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAC5C;AAAA,EACF;AAEA,MAAI,QAAQ,WAAW,GAAG;AACxB,YAAQ,IAAI,mBAAmB;AAC/B;AAAA,EACF;AAEA,aAAW,KAAK,SAAS;AACvB,UAAM,OAAO,EAAE,cAAc,KAAK,EAAE,WAAW,KAAK;AACpD,UAAM,UAAU,EAAE,UACd,KAAK,EAAE,QAAQ,QAAQ,cAAc,EAAE,EAAE,QAAQ,OAAO,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,KAC1E;AACJ,YAAQ,IAAI,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE;AACpC,QAAI,EAAE,MAAO,SAAQ,IAAI,OAAO,EAAE,KAAK,GAAG,IAAI,EAAE;AAChD,QAAI,QAAS,SAAQ,IAAI,MAAM,OAAO,EAAE;AACxC,YAAQ,IAAI;AAAA,EACd;AACF;AAEA,eAAe,aAAa,MAAgB,QAAgB,OAA8B;AACxF,QAAM,OAAO,KAAK,CAAC;AACnB,MAAI,CAAC,QAAQ,KAAK,WAAW,IAAI,GAAG;AAClC,YAAQ,MAAM,sBAAsB;AACpC,YAAQ,MAAM,kCAAkC;AAChD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,+BAA+B,mBAAmB,IAAI,CAAC;AAAA,EACzD;AAEA,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;AACtC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,iBAAiB,IAAI,EAAE;AACrC;AAEA,SAAS,gBAAsB;AAC7B,UAAQ;AAAA,IACN;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AACF;AAEA,eAAsB,QAAQ,MAA+B;AAC3D,QAAM,CAAC,YAAY,GAAG,IAAI,IAAI;AAE9B,MAAI,CAAC,cAAc,eAAe,UAAU,QAAQ,MAAM,UAAU,IAAI,GAAG;AACzE,kBAAc;AACd;AAAA,EACF;AAEA,QAAM,EAAE,QAAQ,MAAM,IAAI,MAAM,cAAc,IAAI;AAElD,UAAQ,YAAY;AAAA,IAClB,KAAK;AACH,YAAM,WAAW,MAAM,QAAQ,KAAK;AACpC;AAAA,IACF,KAAK;AACH,YAAM,UAAU,MAAM,QAAQ,KAAK;AACnC;AAAA,IACF,KAAK;AACH,YAAM,aAAa,MAAM,QAAQ,KAAK;AACtC;AAAA,IACF,KAAK;AACH,YAAM,WAAW,MAAM,QAAQ,KAAK;AACpC;AAAA,IACF,KAAK;AACH,YAAM,WAAW,MAAM,QAAQ,KAAK;AACpC;AAAA,IACF,KAAK;AACH,YAAM,cAAc,MAAM,QAAQ,KAAK;AACvC;AAAA,IACF,KAAK;AACH,YAAM,aAAa,MAAM,QAAQ,KAAK;AACtC;AAAA,IACF,KAAK;AACH,YAAM,aAAa,MAAM,QAAQ,KAAK;AACtC;AAAA,IACF;AACE,cAAQ,MAAM,wBAAwB,UAAU,EAAE;AAClD,oBAAc;AACd,cAAQ,KAAK,CAAC;AAAA,EAClB;AACF;","names":["body"]}
@@ -4,7 +4,7 @@ import {
4
4
  fetchList,
5
5
  parseLifecycleStage,
6
6
  toLifecycleLabel
7
- } from "./chunk-BOS2YLKH.js";
7
+ } from "./chunk-XSOKWWRV.js";
8
8
  import {
9
9
  getArgValue,
10
10
  hasFlag,
@@ -277,4 +277,4 @@ async function runFeatureFlag(argv) {
277
277
  export {
278
278
  runFeatureFlag
279
279
  };
280
- //# sourceMappingURL=feature-flag-BIPFVVNC.js.map
280
+ //# sourceMappingURL=feature-flag-7BD3NT6G.js.map
package/dist/index.js CHANGED
@@ -928,12 +928,12 @@ function isSuperadminToken(token) {
928
928
  // src/index.ts
929
929
  var require2 = createRequire2(import.meta.url);
930
930
  var pkg = require2("../package.json");
931
- var loadMcp = () => import("./mcp-YER5GQG7.js").then((m) => m.runMcp);
932
- var loadLocalBrowser = () => import("./local-browser-WV4IH2DU.js").then((m) => m.runLocalBrowser);
933
- var loadDebugWorkflow = () => import("./debug-workflow-DIQZDFMN.js").then((m) => m.runDebugWorkflow);
934
- var loadRecord = () => import("./record-KRS2PHMW.js").then((m) => m.runRecord);
935
- var loadSession = () => import("./session-CLWAVJ2K.js").then((m) => m.runSession);
936
- var loadLocal = () => import("./local-ZPVM4BXX.js").then((m) => m.runLocal);
931
+ var loadMcp = () => import("./mcp-ETZ3OTXY.js").then((m) => m.runMcp);
932
+ var loadLocalBrowser = () => import("./local-browser-LHJHPWXU.js").then((m) => m.runLocalBrowser);
933
+ var loadDebugWorkflow = () => import("./debug-workflow-JZKUDSVY.js").then((m) => m.runDebugWorkflow);
934
+ var loadRecord = () => import("./record-Y4T5FPVF.js").then((m) => m.runRecord);
935
+ var loadSession = () => import("./session-UPH7SPEU.js").then((m) => m.runSession);
936
+ var loadLocal = () => import("./local-45POWSFC.js").then((m) => m.runLocal);
937
937
  var canary = { run };
938
938
  var baseDir = typeof __dirname !== "undefined" ? __dirname : path4.dirname(fileURLToPath2(import.meta.url));
939
939
  var preloadPath = path4.join(baseDir, "runner", "preload.js");
@@ -1231,27 +1231,27 @@ async function main(argv) {
1231
1231
  return;
1232
1232
  }
1233
1233
  if (command === "docs") {
1234
- const { runDocs } = await import("./docs-CSVSGIGW.js");
1234
+ const { runDocs } = await import("./docs-FORYHZVU.js");
1235
1235
  await runDocs(rest);
1236
1236
  return;
1237
1237
  }
1238
1238
  if (command === "feature-flag") {
1239
- const { runFeatureFlag } = await import("./feature-flag-BIPFVVNC.js");
1239
+ const { runFeatureFlag } = await import("./feature-flag-7BD3NT6G.js");
1240
1240
  await runFeatureFlag(rest);
1241
1241
  return;
1242
1242
  }
1243
1243
  if (command === "knobs") {
1244
- const { runKnobs } = await import("./knobs-VYABZESR.js");
1244
+ const { runKnobs } = await import("./knobs-QUJQ4NWV.js");
1245
1245
  await runKnobs(rest);
1246
1246
  return;
1247
1247
  }
1248
1248
  if (command === "issues") {
1249
- const { runIssues } = await import("./issues-EWVB52CA.js");
1249
+ const { runIssues } = await import("./issues-37LDBJU7.js");
1250
1250
  await runIssues(rest);
1251
1251
  return;
1252
1252
  }
1253
1253
  if (command === "workflow") {
1254
- const { runWorkflow } = await import("./workflow-XXL4H5R4.js");
1254
+ const { runWorkflow } = await import("./workflow-U2NK4YED.js");
1255
1255
  await runWorkflow(rest);
1256
1256
  return;
1257
1257
  }
@@ -5,12 +5,12 @@ import {
5
5
  promptInput,
6
6
  selectProperty,
7
7
  uploadStorageState
8
- } from "./chunk-BOS2YLKH.js";
8
+ } from "./chunk-XSOKWWRV.js";
9
9
  import {
10
10
  createSession,
11
11
  deleteSession,
12
12
  getSessionStorageState
13
- } from "./chunk-4A4G5KTC.js";
13
+ } from "./chunk-N7L7AH6L.js";
14
14
  import {
15
15
  resolveConfig
16
16
  } from "./chunk-ACRIE2YR.js";
@@ -79,7 +79,7 @@ async function handleEnterCredentials(config, propertyId, environmentId, localUr
79
79
  return;
80
80
  }
81
81
  console.log(`
82
- Created credential: ${credResult.item?.name}`);
82
+ Created credential: Local - ${username}`);
83
83
  console.log("Run `canary local start` to begin a session.");
84
84
  }
85
85
  async function handleManualLogin(config, propertyId, environmentId, localUrl) {
@@ -87,14 +87,15 @@ async function handleManualLogin(config, propertyId, environmentId, localUrl) {
87
87
  name: "Local - manual",
88
88
  environmentId,
89
89
  authProvider: "custom",
90
+ data: {},
90
91
  loginUrl: localUrl
91
92
  });
92
- if (!credResult.ok || !credResult.item) {
93
+ if (!credResult.ok || !credResult.id) {
93
94
  console.error(`Failed to create credential: ${credResult.error ?? "Unknown error"}`);
94
95
  process.exitCode = 1;
95
96
  return;
96
97
  }
97
- const credentialId = credResult.item.id;
98
+ const credentialId = credResult.id;
98
99
  console.log("\nOpening browser...");
99
100
  const sessionResult = await createSession({
100
101
  name: "local-login",
@@ -143,4 +144,4 @@ async function handleManualLogin(config, propertyId, environmentId, localUrl) {
143
144
  export {
144
145
  runLocalInit
145
146
  };
146
- //# sourceMappingURL=init-BTDX5N6P.js.map
147
+ //# sourceMappingURL=init-JHZ3OWKQ.js.map
@@ -0,0 +1 @@
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 id?: 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: Local - ${username}`);\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 id?: string;\n error?: string;\n }>(config.apiUrl, config.token, 'POST', `/org/properties/${propertyId}/credentials`, {\n name: 'Local - manual',\n environmentId,\n authProvider: 'custom',\n data: {},\n loginUrl: localUrl,\n });\n\n if (!credResult.ok || !credResult.id) {\n console.error(`Failed to create credential: ${credResult.error ?? 'Unknown error'}`);\n process.exitCode = 1;\n return;\n }\n\n const credentialId = credResult.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,7 +1,7 @@
1
1
  import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
2
  import {
3
3
  apiRequest
4
- } from "./chunk-BOS2YLKH.js";
4
+ } from "./chunk-XSOKWWRV.js";
5
5
  import {
6
6
  getArgValue,
7
7
  hasFlag,
@@ -380,4 +380,4 @@ async function runIssues(argv) {
380
380
  export {
381
381
  runIssues
382
382
  };
383
- //# sourceMappingURL=issues-EWVB52CA.js.map
383
+ //# sourceMappingURL=issues-37LDBJU7.js.map
@@ -4,7 +4,7 @@ import {
4
4
  fetchList,
5
5
  parseLifecycleStage,
6
6
  toLifecycleLabel
7
- } from "./chunk-BOS2YLKH.js";
7
+ } from "./chunk-XSOKWWRV.js";
8
8
  import {
9
9
  getArgValue,
10
10
  hasFlag,
@@ -286,4 +286,4 @@ async function runKnobs(argv) {
286
286
  export {
287
287
  runKnobs
288
288
  };
289
- //# sourceMappingURL=knobs-VYABZESR.js.map
289
+ //# sourceMappingURL=knobs-QUJQ4NWV.js.map
@@ -2,7 +2,7 @@ import { createRequire as __cr } from "module"; const require = __cr(import.meta
2
2
  import {
3
3
  fetchList,
4
4
  fetchProperties
5
- } from "./chunk-BOS2YLKH.js";
5
+ } from "./chunk-XSOKWWRV.js";
6
6
  import {
7
7
  resolveConfig
8
8
  } from "./chunk-ACRIE2YR.js";
@@ -54,4 +54,4 @@ async function runLocalList(argv) {
54
54
  export {
55
55
  runLocalList
56
56
  };
57
- //# sourceMappingURL=list-RCPYLS36.js.map
57
+ //# sourceMappingURL=list-2L2NGCSF.js.map
@@ -32,22 +32,22 @@ async function runLocal(argv) {
32
32
  }
33
33
  switch (subcommand) {
34
34
  case "init": {
35
- const { runLocalInit } = await import("./init-BTDX5N6P.js");
35
+ const { runLocalInit } = await import("./init-JHZ3OWKQ.js");
36
36
  await runLocalInit(rest);
37
37
  break;
38
38
  }
39
39
  case "start": {
40
- const { runLocalStart } = await import("./start-CNNQUP5I.js");
40
+ const { runLocalStart } = await import("./start-QMTRNSYD.js");
41
41
  await runLocalStart(rest);
42
42
  break;
43
43
  }
44
44
  case "list": {
45
- const { runLocalList } = await import("./list-RCPYLS36.js");
45
+ const { runLocalList } = await import("./list-2L2NGCSF.js");
46
46
  await runLocalList(rest);
47
47
  break;
48
48
  }
49
49
  case "login": {
50
- const { runLocalLogin } = await import("./login-W4GXV3VA.js");
50
+ const { runLocalLogin } = await import("./login-ZKF6GONZ.js");
51
51
  await runLocalLogin(rest);
52
52
  break;
53
53
  }
@@ -60,4 +60,4 @@ async function runLocal(argv) {
60
60
  export {
61
61
  runLocal
62
62
  };
63
- //# sourceMappingURL=local-ZPVM4BXX.js.map
63
+ //# sourceMappingURL=local-45POWSFC.js.map
@@ -1,11 +1,11 @@
1
1
  import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
2
  import {
3
3
  LocalBrowserHost
4
- } from "./chunk-ZQF72UTG.js";
4
+ } from "./chunk-W3OTKNJB.js";
5
5
  import {
6
6
  readStoredToken
7
7
  } from "./chunk-ACRIE2YR.js";
8
- import "./chunk-6IAPGYZQ.js";
8
+ import "./chunk-ZYUOJQQX.js";
9
9
  import "./chunk-XAA5VQ5N.js";
10
10
  import "./chunk-P5Z2Y5VV.js";
11
11
  import "./chunk-VKVL7WBN.js";
@@ -141,4 +141,4 @@ async function runLocalBrowser(args) {
141
141
  export {
142
142
  runLocalBrowser
143
143
  };
144
- //# sourceMappingURL=local-browser-WV4IH2DU.js.map
144
+ //# sourceMappingURL=local-browser-LHJHPWXU.js.map
@@ -4,12 +4,12 @@ import {
4
4
  promptChoice,
5
5
  selectProperty,
6
6
  uploadStorageState
7
- } from "./chunk-BOS2YLKH.js";
7
+ } from "./chunk-XSOKWWRV.js";
8
8
  import {
9
9
  createSession,
10
10
  deleteSession,
11
11
  getSessionStorageState
12
- } from "./chunk-4A4G5KTC.js";
12
+ } from "./chunk-N7L7AH6L.js";
13
13
  import {
14
14
  resolveConfig
15
15
  } from "./chunk-ACRIE2YR.js";
@@ -127,4 +127,4 @@ Opening browser at ${selectedEnv.url}...`);
127
127
  export {
128
128
  runLocalLogin
129
129
  };
130
- //# sourceMappingURL=login-W4GXV3VA.js.map
130
+ //# sourceMappingURL=login-ZKF6GONZ.js.map
@@ -1,20 +1,20 @@
1
1
  import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
2
  import {
3
3
  LocalBrowserHost
4
- } from "./chunk-ZQF72UTG.js";
4
+ } from "./chunk-W3OTKNJB.js";
5
5
  import {
6
6
  callTool,
7
7
  createSession,
8
8
  deleteAllSessions,
9
9
  deleteSession,
10
10
  resolveTargetSession
11
- } from "./chunk-4A4G5KTC.js";
11
+ } from "./chunk-N7L7AH6L.js";
12
12
  import {
13
13
  readStoredToken
14
14
  } from "./chunk-ACRIE2YR.js";
15
15
  import {
16
16
  getBrowserToolDefinitionsWithLifecycle
17
- } from "./chunk-6IAPGYZQ.js";
17
+ } from "./chunk-ZYUOJQQX.js";
18
18
  import "./chunk-XAA5VQ5N.js";
19
19
  import "./chunk-P5Z2Y5VV.js";
20
20
  import "./chunk-VKVL7WBN.js";
@@ -371,4 +371,4 @@ async function runMcp(_argv) {
371
371
  export {
372
372
  runMcp
373
373
  };
374
- //# sourceMappingURL=mcp-YER5GQG7.js.map
374
+ //# sourceMappingURL=mcp-ETZ3OTXY.js.map
@@ -3,7 +3,7 @@ import {
3
3
  apiRequest,
4
4
  downloadStorageState,
5
5
  selectCredential
6
- } from "./chunk-BOS2YLKH.js";
6
+ } from "./chunk-XSOKWWRV.js";
7
7
  import {
8
8
  getArgValue,
9
9
  hasFlag,
@@ -249,7 +249,7 @@ async function runRecord(argv) {
249
249
  );
250
250
  }
251
251
  console.log("Launching browser...");
252
- const { PlaywrightClient, consoleLogger, captureElementAtPoint } = await import("./src-WLOHOI6P.js");
252
+ const { PlaywrightClient, consoleLogger, captureElementAtPoint } = await import("./src-3VT7JMAG.js");
253
253
  const videoDir = path.join(getCanaryTmpDir(), `canary-record-video-${Date.now()}`);
254
254
  await fs.mkdir(videoDir, { recursive: true });
255
255
  const client = new PlaywrightClient({ logger: consoleLogger });
@@ -394,4 +394,4 @@ Output directory: ${outDir}`);
394
394
  export {
395
395
  runRecord
396
396
  };
397
- //# sourceMappingURL=record-KRS2PHMW.js.map
397
+ //# sourceMappingURL=record-Y4T5FPVF.js.map
@@ -2,7 +2,7 @@ import { createRequire as __cr } from "module"; const require = __cr(import.meta
2
2
  import {
3
3
  downloadStorageState,
4
4
  selectCredential
5
- } from "./chunk-BOS2YLKH.js";
5
+ } from "./chunk-XSOKWWRV.js";
6
6
  import {
7
7
  callTool,
8
8
  createSession,
@@ -12,7 +12,7 @@ import {
12
12
  listSessions,
13
13
  resolveTargetSession,
14
14
  swapSessionContext
15
- } from "./chunk-4A4G5KTC.js";
15
+ } from "./chunk-N7L7AH6L.js";
16
16
  import {
17
17
  getArgValue,
18
18
  hasFlag,
@@ -22,14 +22,18 @@ import {
22
22
  BrowserToolExecutor,
23
23
  PlaywrightClient,
24
24
  dispatchBrowserTool
25
- } from "./chunk-6IAPGYZQ.js";
26
- import "./chunk-XAA5VQ5N.js";
25
+ } from "./chunk-ZYUOJQQX.js";
26
+ import {
27
+ getCanaryTmpDir
28
+ } from "./chunk-XAA5VQ5N.js";
27
29
  import {
28
30
  consoleLogger
29
31
  } from "./chunk-P5Z2Y5VV.js";
30
32
  import "./chunk-VKVL7WBN.js";
31
33
 
32
34
  // src/session/index.ts
35
+ import fs2 from "fs";
36
+ import path2 from "path";
33
37
  import process2 from "process";
34
38
 
35
39
  // src/session/credentials.ts
@@ -380,7 +384,6 @@ async function cleanup() {
380
384
  }
381
385
  async function startDaemon() {
382
386
  const server = createServer(handleRequest);
383
- server.keepAliveTimeout = 0;
384
387
  return new Promise((resolve, reject) => {
385
388
  server.listen(0, "127.0.0.1", async () => {
386
389
  const addr = server.address();
@@ -409,12 +412,21 @@ async function startDaemon() {
409
412
  });
410
413
  }
411
414
  async function runDaemon() {
415
+ const { Console } = await import("console");
416
+ global.console = new Console({ stdout: process.stderr, stderr: process.stderr });
412
417
  const { port } = await startDaemon();
413
418
  process.stdout.write(`DAEMON_READY:${port}
414
419
  `);
415
420
  }
416
421
 
417
422
  // src/session/index.ts
423
+ function getScreenshotDir() {
424
+ return path2.join(getCanaryTmpDir(), "screenshots");
425
+ }
426
+ function cleanupScreenshots() {
427
+ const dir = getScreenshotDir();
428
+ fs2.rmSync(dir, { recursive: true, force: true });
429
+ }
418
430
  function formatUptime(startedAt) {
419
431
  const seconds = Math.floor((Date.now() - new Date(startedAt).getTime()) / 1e3);
420
432
  if (seconds < 60) return `${seconds}s`;
@@ -462,7 +474,14 @@ function printToolResult(result, jsonMode) {
462
474
  console.log(result.text);
463
475
  }
464
476
  if (result.images?.length) {
465
- console.log(`[${result.images.length} image(s) captured]`);
477
+ const screenshotDir = getScreenshotDir();
478
+ fs2.mkdirSync(screenshotDir, { recursive: true });
479
+ for (const img of result.images) {
480
+ const ext = img.mimeType === "image/png" ? "png" : "jpg";
481
+ const filePath = path2.join(screenshotDir, `screenshot-${Date.now()}.${ext}`);
482
+ fs2.writeFileSync(filePath, Buffer.from(img.data, "base64"));
483
+ console.log(`Screenshot saved: ${filePath}`);
484
+ }
466
485
  }
467
486
  }
468
487
  async function handleStart(argv) {
@@ -553,6 +572,7 @@ async function handleStop(argv) {
553
572
  const jsonMode = hasFlag(argv, "--json");
554
573
  if (hasFlag(argv, "--all")) {
555
574
  const result = await deleteAllSessions();
575
+ if (result.ok) cleanupScreenshots();
556
576
  if (jsonMode) {
557
577
  console.log(JSON.stringify(result, null, 2));
558
578
  } else if (result.ok) {
@@ -567,6 +587,12 @@ async function handleStop(argv) {
567
587
  try {
568
588
  const target = await resolveTargetSession(sessionId);
569
589
  const result = await deleteSession(target.id);
590
+ if (result.ok) {
591
+ const remaining = await listSessions();
592
+ if (remaining.ok && (!remaining.data || remaining.data.length === 0)) {
593
+ cleanupScreenshots();
594
+ }
595
+ }
570
596
  if (jsonMode) {
571
597
  console.log(JSON.stringify(result, null, 2));
572
598
  } else if (result.ok) {
@@ -837,4 +863,4 @@ async function runSession(argv) {
837
863
  export {
838
864
  runSession
839
865
  };
840
- //# sourceMappingURL=session-CLWAVJ2K.js.map
866
+ //# sourceMappingURL=session-UPH7SPEU.js.map