@runcofactor/cli 0.10.0 → 0.15.0

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 (166) hide show
  1. package/dist/account-22LMP5PX.js +255 -0
  2. package/dist/account-22LMP5PX.js.map +1 -0
  3. package/dist/{api-catalog-GFGCLVS4.js → api-catalog-WTFQNLK6.js} +5 -4
  4. package/dist/{api-catalog-GFGCLVS4.js.map → api-catalog-WTFQNLK6.js.map} +1 -1
  5. package/dist/{attachment-SJC7D7FY.js → attachment-U3NKVPEY.js} +5 -4
  6. package/dist/{attachment-SJC7D7FY.js.map → attachment-U3NKVPEY.js.map} +1 -1
  7. package/dist/augmentor-5GMNAX4M.js +198 -0
  8. package/dist/augmentor-5GMNAX4M.js.map +1 -0
  9. package/dist/{auth-EN6NQCJY.js → auth-VQG2CDUD.js} +3 -2
  10. package/dist/{chunk-A4OFTUVV.js → chunk-3X3NW7QA.js} +7 -4
  11. package/dist/chunk-3X3NW7QA.js.map +1 -0
  12. package/dist/{chunk-N7HFALX3.js → chunk-46IUJXSD.js} +2 -2
  13. package/dist/{chunk-IMPZAX6L.js → chunk-5GD47G2D.js} +37 -1
  14. package/dist/{chunk-IMPZAX6L.js.map → chunk-5GD47G2D.js.map} +1 -1
  15. package/dist/{chunk-B2VISN2V.js → chunk-7VMO2WOZ.js} +238 -68
  16. package/dist/chunk-7VMO2WOZ.js.map +1 -0
  17. package/dist/{chunk-QFDOWABX.js → chunk-CMGI7UZD.js} +6 -3
  18. package/dist/chunk-CMGI7UZD.js.map +1 -0
  19. package/dist/{chunk-XQXVG7RA.js → chunk-FNPMWDUQ.js} +3 -3
  20. package/dist/chunk-G4UYGRZR.js +2 -0
  21. package/dist/{chunk-I4QLI3JO.js → chunk-HDFYUFBI.js} +2 -2
  22. package/dist/chunk-JMJVGMXI.js +92 -0
  23. package/dist/chunk-JMJVGMXI.js.map +1 -0
  24. package/dist/{chunk-SJJW77WN.js → chunk-JYGNMKZ5.js} +129 -38
  25. package/dist/chunk-JYGNMKZ5.js.map +1 -0
  26. package/dist/{chunk-52IO7ACJ.js → chunk-KCHKFYVX.js} +68 -10
  27. package/dist/{chunk-52IO7ACJ.js.map → chunk-KCHKFYVX.js.map} +1 -1
  28. package/dist/{chunk-ZD3KHESI.js → chunk-KRWRUU6R.js} +27 -7
  29. package/dist/chunk-KRWRUU6R.js.map +1 -0
  30. package/dist/{chunk-CLAWT7BJ.js → chunk-NHTEKEYE.js} +3 -3
  31. package/dist/{chunk-WOHL4FTB.js → chunk-PRBRSIZP.js} +16 -10
  32. package/dist/chunk-PRBRSIZP.js.map +1 -0
  33. package/dist/{chunk-GKY2KXO5.js → chunk-UETBLPKM.js} +154 -37
  34. package/dist/chunk-UETBLPKM.js.map +1 -0
  35. package/dist/{chunk-4PNOV7OV.js → chunk-VGYN2KU2.js} +9284 -1421
  36. package/dist/chunk-VGYN2KU2.js.map +1 -0
  37. package/dist/{chunk-Q4BO4Z5V.js → chunk-XJ5YYYGC.js} +4 -4
  38. package/dist/{credential-COLTBV6D.js → credential-E6KUHRGU.js} +24 -20
  39. package/dist/credential-E6KUHRGU.js.map +1 -0
  40. package/dist/{credential-template-EEPYFG7R.js → credential-template-4GPOPBGD.js} +30 -28
  41. package/dist/credential-template-4GPOPBGD.js.map +1 -0
  42. package/dist/{debug-workflow-KOVH5GOP.js → debug-workflow-XCLCY6S7.js} +5 -4
  43. package/dist/{debug-workflow-KOVH5GOP.js.map → debug-workflow-XCLCY6S7.js.map} +1 -1
  44. package/dist/{docs-3SSORHB5.js → docs-COCZYMW6.js} +95 -10
  45. package/dist/docs-COCZYMW6.js.map +1 -0
  46. package/dist/{doctor-OTSIWV6G.js → doctor-ERIVTCQS.js} +9 -5
  47. package/dist/doctor-ERIVTCQS.js.map +1 -0
  48. package/dist/environment-7Y4BV6XY.js +221 -0
  49. package/dist/environment-7Y4BV6XY.js.map +1 -0
  50. package/dist/{feature-flag-T2LRZME3.js → feature-flag-MHONEX6T.js} +164 -16
  51. package/dist/feature-flag-MHONEX6T.js.map +1 -0
  52. package/dist/index.js +123 -58
  53. package/dist/index.js.map +1 -1
  54. package/dist/{init-TGWRECT2.js → init-OROOM4HF.js} +5 -4
  55. package/dist/{init-TGWRECT2.js.map → init-OROOM4HF.js.map} +1 -1
  56. package/dist/{install-DXSNWZKO.js → install-OJFXHY6U.js} +7 -7
  57. package/dist/{issues-XIZOPX6T.js → issues-32GONR6C.js} +5 -4
  58. package/dist/{issues-XIZOPX6T.js.map → issues-32GONR6C.js.map} +1 -1
  59. package/dist/{knobs-NBINZIUB.js → knobs-UQGGY3CP.js} +7 -5
  60. package/dist/knobs-UQGGY3CP.js.map +1 -0
  61. package/dist/{list-3TDHK637.js → list-ZMIKEC5P.js} +5 -4
  62. package/dist/{list-3TDHK637.js.map → list-ZMIKEC5P.js.map} +1 -1
  63. package/dist/{local-HICVD6PU.js → local-PUD24GGQ.js} +7 -6
  64. package/dist/{local-HICVD6PU.js.map → local-PUD24GGQ.js.map} +1 -1
  65. package/dist/{login-UOIUXVUK.js → login-BSO7YX2D.js} +5 -4
  66. package/dist/{login-UOIUXVUK.js.map → login-BSO7YX2D.js.map} +1 -1
  67. package/dist/{mcp-54IJEOUA.js → mcp-4LS7OJUT.js} +24 -25
  68. package/dist/mcp-4LS7OJUT.js.map +1 -0
  69. package/dist/{pdf-extract-ABWV3L5X.js → pdf-extract-YHE54XU4.js} +2 -2
  70. package/dist/product-3JKSJCBC.js +346 -0
  71. package/dist/product-3JKSJCBC.js.map +1 -0
  72. package/dist/{property-UXLOLPTD.js → property-K5DBL4UE.js} +76 -4
  73. package/dist/property-K5DBL4UE.js.map +1 -0
  74. package/dist/{psql-BYUUNLGG.js → psql-PQFUFTSE.js} +3 -2
  75. package/dist/{psql-BYUUNLGG.js.map → psql-PQFUFTSE.js.map} +1 -1
  76. package/dist/{record-4TR2UIIS.js → record-EIIYLFJ4.js} +16 -17
  77. package/dist/record-EIIYLFJ4.js.map +1 -0
  78. package/dist/{redis-35VBUYW7.js → redis-BU36EZZI.js} +3 -2
  79. package/dist/redis-BU36EZZI.js.map +1 -0
  80. package/dist/{release-OOLTUBUT.js → release-LYC2P7DZ.js} +5 -4
  81. package/dist/{release-OOLTUBUT.js.map → release-LYC2P7DZ.js.map} +1 -1
  82. package/dist/{sandbox-XGSUU6G7.js → sandbox-CKHXXZHU.js} +55 -10
  83. package/dist/sandbox-CKHXXZHU.js.map +1 -0
  84. package/dist/{scenarios-GWLJEGHA.js → scenarios-2XJ2G3KR.js} +5 -4
  85. package/dist/{scenarios-GWLJEGHA.js.map → scenarios-2XJ2G3KR.js.map} +1 -1
  86. package/dist/{session-MYFNZPRP.js → session-UTOD5ZYH.js} +77 -10
  87. package/dist/session-UTOD5ZYH.js.map +1 -0
  88. package/dist/{skill-KM34LDMO.js → skill-GMAERMQL.js} +220 -70
  89. package/dist/skill-GMAERMQL.js.map +1 -0
  90. package/dist/skills/debug-run/SKILL.md +40 -23
  91. package/dist/skills/debug-run/history/1.2.0.md +262 -0
  92. package/dist/skills/debug-run/history/1.3.0.md +273 -0
  93. package/dist/skills/debug-run/history/1.3.1.md +279 -0
  94. package/dist/skills/debug-run/version.json +1 -1
  95. package/dist/skills/optimize-cache/SKILL.md +233 -0
  96. package/dist/{spec-RA3CFEKG.js → spec-2NP36U3Y.js} +54 -25
  97. package/dist/spec-2NP36U3Y.js.map +1 -0
  98. package/dist/{src-LB4HBTJQ.js → src-4T6GHXVO.js} +19 -11
  99. package/dist/src-4T6GHXVO.js.map +1 -0
  100. package/dist/{src-N3TPKGTY.js → src-CG52HEE7.js} +10 -7
  101. package/dist/{src-UVDX5UP6.js → src-PK5OZXCM.js} +4 -2
  102. package/dist/src-UEOOC425.js +5941 -0
  103. package/dist/src-UEOOC425.js.map +1 -0
  104. package/dist/{start-PSEQSQA3.js → start-3C7EEFW2.js} +5 -4
  105. package/dist/{start-PSEQSQA3.js.map → start-3C7EEFW2.js.map} +1 -1
  106. package/dist/{tag-YY6YAABQ.js → tag-JSHOMLBR.js} +6 -5
  107. package/dist/{task-IQC3YR5K.js → task-YGWVYTBJ.js} +5 -4
  108. package/dist/{task-IQC3YR5K.js.map → task-YGWVYTBJ.js.map} +1 -1
  109. package/dist/{test-suite-DZNJFXDW.js → test-suite-LI7ZH367.js} +12 -7
  110. package/dist/{test-suite-DZNJFXDW.js.map → test-suite-LI7ZH367.js.map} +1 -1
  111. package/dist/trace-UMLOSIIR.js +16 -0
  112. package/dist/{triage-ORG45R5W.js → triage-ZWJG4NBJ.js} +6 -5
  113. package/dist/triage-ZWJG4NBJ.js.map +1 -0
  114. package/dist/{upgrade-L2VYMP2V.js → upgrade-S7CGEK6H.js} +3 -3
  115. package/dist/{workflow-XYFH5LTP.js → workflow-T4HSAOGW.js} +316 -241
  116. package/dist/workflow-T4HSAOGW.js.map +1 -0
  117. package/dist/{workflow-cache-NQJQFWMV.js → workflow-cache-XVEZ36KF.js} +140 -7
  118. package/dist/workflow-cache-XVEZ36KF.js.map +1 -0
  119. package/dist/{workflow-debug-BGD4UIXU.js → workflow-debug-T2BULXZ7.js} +9 -8
  120. package/dist/{workflow-debug-BGD4UIXU.js.map → workflow-debug-T2BULXZ7.js.map} +1 -1
  121. package/dist/{workflow-proposals-MTUDX46O.js → workflow-proposals-XXEZICN2.js} +5 -6
  122. package/dist/workflow-proposals-XXEZICN2.js.map +1 -0
  123. package/package.json +2 -1
  124. package/dist/chunk-4PNOV7OV.js.map +0 -1
  125. package/dist/chunk-A4OFTUVV.js.map +0 -1
  126. package/dist/chunk-B2VISN2V.js.map +0 -1
  127. package/dist/chunk-GKY2KXO5.js.map +0 -1
  128. package/dist/chunk-JICSYFRJ.js +0 -46
  129. package/dist/chunk-JICSYFRJ.js.map +0 -1
  130. package/dist/chunk-QFDOWABX.js.map +0 -1
  131. package/dist/chunk-SJJW77WN.js.map +0 -1
  132. package/dist/chunk-WOHL4FTB.js.map +0 -1
  133. package/dist/chunk-ZD3KHESI.js.map +0 -1
  134. package/dist/credential-COLTBV6D.js.map +0 -1
  135. package/dist/credential-template-EEPYFG7R.js.map +0 -1
  136. package/dist/docs-3SSORHB5.js.map +0 -1
  137. package/dist/doctor-OTSIWV6G.js.map +0 -1
  138. package/dist/feature-flag-T2LRZME3.js.map +0 -1
  139. package/dist/knobs-NBINZIUB.js.map +0 -1
  140. package/dist/mcp-54IJEOUA.js.map +0 -1
  141. package/dist/property-UXLOLPTD.js.map +0 -1
  142. package/dist/record-4TR2UIIS.js.map +0 -1
  143. package/dist/redis-35VBUYW7.js.map +0 -1
  144. package/dist/sandbox-XGSUU6G7.js.map +0 -1
  145. package/dist/session-MYFNZPRP.js.map +0 -1
  146. package/dist/skill-KM34LDMO.js.map +0 -1
  147. package/dist/spec-RA3CFEKG.js.map +0 -1
  148. package/dist/src-LB4HBTJQ.js.map +0 -1
  149. package/dist/trace-HXIW7U2D.js +0 -14
  150. package/dist/workflow-XYFH5LTP.js.map +0 -1
  151. package/dist/workflow-cache-NQJQFWMV.js.map +0 -1
  152. package/dist/workflow-proposals-MTUDX46O.js.map +0 -1
  153. /package/dist/{auth-EN6NQCJY.js.map → auth-VQG2CDUD.js.map} +0 -0
  154. /package/dist/{chunk-N7HFALX3.js.map → chunk-46IUJXSD.js.map} +0 -0
  155. /package/dist/{chunk-XQXVG7RA.js.map → chunk-FNPMWDUQ.js.map} +0 -0
  156. /package/dist/{pdf-extract-ABWV3L5X.js.map → chunk-G4UYGRZR.js.map} +0 -0
  157. /package/dist/{chunk-I4QLI3JO.js.map → chunk-HDFYUFBI.js.map} +0 -0
  158. /package/dist/{chunk-CLAWT7BJ.js.map → chunk-NHTEKEYE.js.map} +0 -0
  159. /package/dist/{chunk-Q4BO4Z5V.js.map → chunk-XJ5YYYGC.js.map} +0 -0
  160. /package/dist/{install-DXSNWZKO.js.map → install-OJFXHY6U.js.map} +0 -0
  161. /package/dist/{src-N3TPKGTY.js.map → pdf-extract-YHE54XU4.js.map} +0 -0
  162. /package/dist/{src-UVDX5UP6.js.map → src-CG52HEE7.js.map} +0 -0
  163. /package/dist/{tag-YY6YAABQ.js.map → src-PK5OZXCM.js.map} +0 -0
  164. /package/dist/{trace-HXIW7U2D.js.map → tag-JSHOMLBR.js.map} +0 -0
  165. /package/dist/{triage-ORG45R5W.js.map → trace-UMLOSIIR.js.map} +0 -0
  166. /package/dist/{upgrade-L2VYMP2V.js.map → upgrade-S7CGEK6H.js.map} +0 -0
@@ -1,17 +1,18 @@
1
1
  import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
2
  import {
3
3
  apiRequest
4
- } from "./chunk-WOHL4FTB.js";
5
- import "./chunk-SJJW77WN.js";
4
+ } from "./chunk-PRBRSIZP.js";
6
5
  import "./chunk-3CZU7XCS.js";
7
6
  import {
8
7
  getArgValue,
9
8
  hasFlag,
10
9
  resolveConfig
11
- } from "./chunk-A4OFTUVV.js";
10
+ } from "./chunk-3X3NW7QA.js";
11
+ import "./chunk-JMJVGMXI.js";
12
12
  import {
13
13
  getSubDir
14
14
  } from "./chunk-JWHYXEA2.js";
15
+ import "./chunk-JYGNMKZ5.js";
15
16
  import "./chunk-VKVL7WBN.js";
16
17
 
17
18
  // src/docs.ts
@@ -24,9 +25,9 @@ function parseNavFields(argv) {
24
25
  const section = getArgValue(argv, "--section");
25
26
  const group = getArgValue(argv, "--group");
26
27
  const order = getArgValue(argv, "--order");
27
- if (section != null) out.navSection = section;
28
- if (group != null) out.navGroup = group;
29
- if (order != null) {
28
+ if (section !== null && section !== void 0) out.navSection = section;
29
+ if (group !== null && group !== void 0) out.navGroup = group;
30
+ if (order !== null && order !== void 0) {
30
31
  const n = Number.parseInt(order, 10);
31
32
  if (Number.isNaN(n)) {
32
33
  console.error("Error: --order must be an integer.");
@@ -288,6 +289,83 @@ async function handleDelete(argv, apiUrl, token, orgMode) {
288
289
  }
289
290
  console.log(`Deleted page: ${slug}`);
290
291
  }
292
+ async function handleNav(argv, apiUrl, token) {
293
+ const [action, ...rest] = argv;
294
+ switch (action) {
295
+ case void 0:
296
+ case "list": {
297
+ const result = await apiRequest(
298
+ apiUrl,
299
+ token,
300
+ "GET",
301
+ "/public/docs/nav"
302
+ );
303
+ const groups = result.data?.groups ?? [];
304
+ if (hasFlag(rest, "--json")) {
305
+ console.log(JSON.stringify(groups, null, 2));
306
+ return;
307
+ }
308
+ if (groups.length === 0) {
309
+ console.log("No sidebar groups found.");
310
+ return;
311
+ }
312
+ const keyWidth = Math.max(3, ...groups.map((g) => g.key.length));
313
+ const titleWidth = Math.max(5, ...groups.map((g) => g.title.length));
314
+ console.log(`| ${"Key".padEnd(keyWidth)} | ${"Title".padEnd(titleWidth)} | Order |`);
315
+ console.log(`| ${"-".repeat(keyWidth)} | ${"-".repeat(titleWidth)} | ----- |`);
316
+ for (const g of groups) {
317
+ console.log(`| ${g.key.padEnd(keyWidth)} | ${g.title.padEnd(titleWidth)} | ${String(g.sortOrder).padEnd(5)} |`);
318
+ }
319
+ return;
320
+ }
321
+ case "set": {
322
+ const key = rest[0];
323
+ if (!key || key.startsWith("--")) {
324
+ console.error("Usage: canary docs nav set <key> [--title <text>] [--order <n>]");
325
+ process.exit(1);
326
+ }
327
+ const title = getArgValue(rest, "--title");
328
+ const orderRaw = getArgValue(rest, "--order");
329
+ const body = {};
330
+ if (title !== null && title !== void 0) body.title = title;
331
+ if (orderRaw !== null && orderRaw !== void 0) {
332
+ const n = Number.parseInt(orderRaw, 10);
333
+ if (Number.isNaN(n)) {
334
+ console.error("Error: --order must be an integer.");
335
+ process.exit(1);
336
+ }
337
+ body.sortOrder = n;
338
+ }
339
+ await apiRequest(apiUrl, token, "PUT", `/superadmin/docs/nav?key=${encodeURIComponent(key)}`, body);
340
+ console.log(`Updated sidebar group: ${key}`);
341
+ return;
342
+ }
343
+ case "reorder": {
344
+ const keys = rest.filter((a) => !a.startsWith("--"));
345
+ if (keys.length === 0) {
346
+ console.error("Usage: canary docs nav reorder <key1> <key2> ...");
347
+ process.exit(1);
348
+ }
349
+ await apiRequest(apiUrl, token, "PUT", "/superadmin/docs/nav/reorder", { keys });
350
+ console.log(`Reordered ${keys.length} sidebar groups.`);
351
+ return;
352
+ }
353
+ case "delete": {
354
+ const key = rest[0];
355
+ if (!key || key.startsWith("--")) {
356
+ console.error("Usage: canary docs nav delete <key>");
357
+ process.exit(1);
358
+ }
359
+ await apiRequest(apiUrl, token, "DELETE", `/superadmin/docs/nav?key=${encodeURIComponent(key)}`);
360
+ console.log(`Deleted sidebar group: ${key}`);
361
+ return;
362
+ }
363
+ default:
364
+ console.error(`Unknown nav action: ${action}`);
365
+ console.error("Actions: list, set <key>, reorder <keys...>, delete <key>");
366
+ process.exit(1);
367
+ }
368
+ }
291
369
  function printDocsHelp() {
292
370
  console.log(
293
371
  [
@@ -302,15 +380,19 @@ function printDocsHelp() {
302
380
  " history <slug> Show version history",
303
381
  " create <slug> --file <path> --title ... Create new page",
304
382
  " delete <slug> Soft-delete a page",
383
+ " nav list [--json] List sidebar groups + order",
384
+ " nav set <key> [--title <t>] [--order n] Create or update a sidebar group",
385
+ " nav reorder <key1> <key2> ... Set sidebar group order",
386
+ " nav delete <key> Remove a sidebar group",
305
387
  "",
306
388
  "Options:",
307
389
  " --org Use org-scoped endpoints (requires auth)",
308
390
  " --file <path> Path to markdown file",
309
391
  " --title <text> Page title (create only)",
310
392
  " --description <text> Page description (create only)",
311
- " --section <text> Sidebar section (data-driven nav; create/push)",
312
- " --group <text> Sidebar sub-group within the section (create/push)",
313
- " --order <n> Sort order within the section/group (create/push)",
393
+ " --group <key> Sidebar group key the page belongs to (see `nav list`; create/push)",
394
+ " --order <n> Sort order within the group (create/push)",
395
+ " --section <text> Deprecated; sidebar grouping is driven by --group now",
314
396
  " --message <text> Version commit message",
315
397
  " --limit <n> Max results for search (default: 8, max: 20)",
316
398
  " --output <path> Output path for pull (default: <tmpdir>/canary/docs/<slug>.md)",
@@ -354,6 +436,9 @@ async function runDocs(argv) {
354
436
  case "delete":
355
437
  await handleDelete(rest, apiUrl, token, orgMode);
356
438
  break;
439
+ case "nav":
440
+ await handleNav(rest, apiUrl, token);
441
+ break;
357
442
  default:
358
443
  console.error(`Unknown sub-command: ${subCommand}`);
359
444
  printDocsHelp();
@@ -363,4 +448,4 @@ async function runDocs(argv) {
363
448
  export {
364
449
  runDocs
365
450
  };
366
- //# sourceMappingURL=docs-3SSORHB5.js.map
451
+ //# sourceMappingURL=docs-COCZYMW6.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 * Supports both global (public/superadmin) and org-scoped (--org) modes.\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\n/**\n * Parse the optional data-driven sidebar-placement flags. Only present flags\n * are included, so `push`/`create` without them leaves existing values intact.\n */\nfunction parseNavFields(argv: string[]): {\n navSection?: string;\n navGroup?: string;\n navOrder?: number;\n} {\n const out: { navSection?: string; navGroup?: string; navOrder?: number } = {};\n const section = getArgValue(argv, '--section');\n const group = getArgValue(argv, '--group');\n const order = getArgValue(argv, '--order');\n if (section !== null && section !== undefined) out.navSection = section;\n if (group !== null && group !== undefined) out.navGroup = group;\n if (order !== null && order !== undefined) {\n const n = Number.parseInt(order, 10);\n if (Number.isNaN(n)) {\n console.error('Error: --order must be an integer.');\n process.exit(1);\n }\n out.navOrder = n;\n }\n return out;\n}\n\n/** Return the base path prefix for read endpoints based on --org flag */\nfunction readPrefix(orgMode: boolean): string {\n return orgMode ? '/docs' : '/public/docs';\n}\n\n/** Return the base path prefix for write endpoints based on --org flag */\nfunction writePrefix(orgMode: boolean): string {\n return orgMode ? '/docs' : '/superadmin/docs';\n}\n\nasync function handleList(argv: string[], apiUrl: string, token: string, orgMode: boolean): Promise<void> {\n const jsonOutput = hasFlag(argv, '--json');\n const result = await apiRequest<DocsApiResponse>(apiUrl, token, 'GET', `${readPrefix(orgMode)}/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 fetchDocContent(slug: string, apiUrl: string, token: string, orgMode: boolean): Promise<string> {\n if (orgMode) {\n const result = await apiRequest<DocsApiResponse>(\n apiUrl,\n token,\n 'GET',\n `/docs/pages/content?slug=${encodeURIComponent(slug)}`\n );\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n return result.data?.content ?? '';\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 return res.text();\n}\n\nasync function handleGet(argv: string[], apiUrl: string, token: string, orgMode: boolean): 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 content = await fetchDocContent(slug, apiUrl, token, orgMode);\n console.log(content);\n}\n\nasync function handlePull(argv: string[], apiUrl: string, token: string, orgMode: boolean): 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 const content = await fetchDocContent(slug, apiUrl, token, orgMode);\n\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, orgMode: boolean): 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 // Strip `export const meta = { ... };` block so raw JS isn't stored as doc content\n content = content.replace(/^\\s*export\\s+const\\s+meta\\s*=\\s*\\{[^}]*\\};\\s*/, '');\n\n const result = await apiRequest<DocsApiResponse>(\n apiUrl,\n token,\n 'PUT',\n `${writePrefix(orgMode)}/pages?slug=${encodeURIComponent(slug)}`,\n { content, message, createdBy, ...parseNavFields(argv) }\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, orgMode: boolean): 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}${readPrefix(orgMode)}/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, orgMode: boolean): 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 // Strip `export const meta = { ... };` block so raw JS isn't stored as doc content\n content = content.replace(/^\\s*export\\s+const\\s+meta\\s*=\\s*\\{[^}]*\\};\\s*/, '');\n\n const result = await apiRequest<DocsApiResponse>(\n apiUrl,\n token,\n 'POST',\n `${writePrefix(orgMode)}/pages`,\n {\n slug,\n title,\n description,\n content,\n message,\n ...parseNavFields(argv),\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, orgMode: boolean): 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 searchPath = orgMode ? '/docs/search' : '/public/docs/search';\n const res = await fetch(`${apiUrl}${searchPath}?${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, orgMode: boolean): 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 `${writePrefix(orgMode)}/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\ntype DocsNavGroup = { key: string; title: string; sortOrder: number };\n\nasync function handleNav(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [action, ...rest] = argv;\n\n switch (action) {\n case undefined:\n case 'list': {\n const result = await apiRequest<{ ok: boolean; data?: { groups: DocsNavGroup[] }; error?: string }>(\n apiUrl,\n token,\n 'GET',\n '/public/docs/nav'\n );\n const groups = result.data?.groups ?? [];\n if (hasFlag(rest, '--json')) {\n console.log(JSON.stringify(groups, null, 2));\n return;\n }\n if (groups.length === 0) {\n console.log('No sidebar groups found.');\n return;\n }\n const keyWidth = Math.max(3, ...groups.map((g) => g.key.length));\n const titleWidth = Math.max(5, ...groups.map((g) => g.title.length));\n console.log(`| ${'Key'.padEnd(keyWidth)} | ${'Title'.padEnd(titleWidth)} | Order |`);\n console.log(`| ${'-'.repeat(keyWidth)} | ${'-'.repeat(titleWidth)} | ----- |`);\n for (const g of groups) {\n console.log(`| ${g.key.padEnd(keyWidth)} | ${g.title.padEnd(titleWidth)} | ${String(g.sortOrder).padEnd(5)} |`);\n }\n return;\n }\n case 'set': {\n const key = rest[0];\n if (!key || key.startsWith('--')) {\n console.error('Usage: canary docs nav set <key> [--title <text>] [--order <n>]');\n process.exit(1);\n }\n const title = getArgValue(rest, '--title');\n const orderRaw = getArgValue(rest, '--order');\n const body: Record<string, unknown> = {};\n if (title !== null && title !== undefined) body.title = title;\n if (orderRaw !== null && orderRaw !== undefined) {\n const n = Number.parseInt(orderRaw, 10);\n if (Number.isNaN(n)) {\n console.error('Error: --order must be an integer.');\n process.exit(1);\n }\n body.sortOrder = n;\n }\n await apiRequest(apiUrl, token, 'PUT', `/superadmin/docs/nav?key=${encodeURIComponent(key)}`, body);\n console.log(`Updated sidebar group: ${key}`);\n return;\n }\n case 'reorder': {\n const keys = rest.filter((a) => !a.startsWith('--'));\n if (keys.length === 0) {\n console.error('Usage: canary docs nav reorder <key1> <key2> ...');\n process.exit(1);\n }\n await apiRequest(apiUrl, token, 'PUT', '/superadmin/docs/nav/reorder', { keys });\n console.log(`Reordered ${keys.length} sidebar groups.`);\n return;\n }\n case 'delete': {\n const key = rest[0];\n if (!key || key.startsWith('--')) {\n console.error('Usage: canary docs nav delete <key>');\n process.exit(1);\n }\n await apiRequest(apiUrl, token, 'DELETE', `/superadmin/docs/nav?key=${encodeURIComponent(key)}`);\n console.log(`Deleted sidebar group: ${key}`);\n return;\n }\n default:\n console.error(`Unknown nav action: ${action}`);\n console.error('Actions: list, set <key>, reorder <keys...>, delete <key>');\n process.exit(1);\n }\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 ' nav list [--json] List sidebar groups + order',\n ' nav set <key> [--title <t>] [--order n] Create or update a sidebar group',\n ' nav reorder <key1> <key2> ... Set sidebar group order',\n ' nav delete <key> Remove a sidebar group',\n '',\n 'Options:',\n ' --org Use org-scoped endpoints (requires auth)',\n ' --file <path> Path to markdown file',\n ' --title <text> Page title (create only)',\n ' --description <text> Page description (create only)',\n ' --group <key> Sidebar group key the page belongs to (see `nav list`; create/push)',\n ' --order <n> Sort order within the group (create/push)',\n ' --section <text> Deprecated; sidebar grouping is driven by --group now',\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: <tmpdir>/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 const orgMode = hasFlag(rest, '--org');\n\n switch (subCommand) {\n case 'list':\n await handleList(rest, apiUrl, token, orgMode);\n break;\n case 'get':\n await handleGet(rest, apiUrl, token, orgMode);\n break;\n case 'search':\n await handleSearch(rest, apiUrl, token, orgMode);\n break;\n case 'pull':\n await handlePull(rest, apiUrl, token, orgMode);\n break;\n case 'push':\n await handlePush(rest, apiUrl, token, orgMode);\n break;\n case 'history':\n await handleHistory(rest, apiUrl, token, orgMode);\n break;\n case 'create':\n await handleCreate(rest, apiUrl, token, orgMode);\n break;\n case 'delete':\n await handleDelete(rest, apiUrl, token, orgMode);\n break;\n case 'nav':\n await handleNav(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"]}
@@ -8,7 +8,10 @@ import {
8
8
  envToProfile,
9
9
  getArgValue,
10
10
  readStoredAuth
11
- } from "./chunk-A4OFTUVV.js";
11
+ } from "./chunk-3X3NW7QA.js";
12
+ import {
13
+ readBrandEnv
14
+ } from "./chunk-JMJVGMXI.js";
12
15
  import "./chunk-VKVL7WBN.js";
13
16
 
14
17
  // src/doctor.ts
@@ -34,16 +37,17 @@ function truncateId(id) {
34
37
  async function runAuthDoctor(argv) {
35
38
  const env = getArgValue(argv, "--env");
36
39
  const profile = env ? envToProfile(env) : void 0;
37
- const apiUrlOverride = getArgValue(argv, "--api-url") ?? process.env.CANARY_API_URL;
40
+ const apiUrlOverride = getArgValue(argv, "--api-url") ?? readBrandEnv("CANARY_API_URL");
38
41
  const stored = await readStoredAuth(profile);
39
- const token = process.env.CANARY_API_TOKEN ?? stored?.token;
42
+ const envToken = readBrandEnv("CANARY_API_TOKEN");
43
+ const token = envToken ?? stored?.token;
40
44
  const apiUrl = apiUrlOverride ?? (env && ENV_URLS[env]?.api) ?? stored?.apiUrl ?? "https://api.trycanary.ai";
41
45
  console.log("\u2500\u2500 canary auth doctor \u2500\u2500");
42
46
  console.log(`node: ${process.version}`);
43
47
  console.log(`platform: ${process.platform}`);
44
48
  console.log(`api url: ${apiUrl}`);
45
49
  console.log(`profile: ${profile ?? "(default)"}`);
46
- console.log(`token source: ${process.env.CANARY_API_TOKEN ? "CANARY_API_TOKEN env" : stored?.token ? "auth.json" : "NONE"}`);
50
+ console.log(`token source: ${envToken ? "API token env var" : stored?.token ? "auth.json" : "NONE"}`);
47
51
  console.log(
48
52
  `NODE_EXTRA_CA_CERTS: ${process.env.NODE_EXTRA_CA_CERTS ?? "(not set)"}`
49
53
  );
@@ -129,4 +133,4 @@ async function runAuthDoctor(argv) {
129
133
  export {
130
134
  runAuthDoctor
131
135
  };
132
- //# sourceMappingURL=doctor-OTSIWV6G.js.map
136
+ //# sourceMappingURL=doctor-ERIVTCQS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/doctor.ts"],"sourcesContent":["/**\n * `canary auth doctor` — print everything a user or IT admin needs to see\n * when the CLI is misbehaving against a corporate proxy (Zscaler, Netskope,\n * ZPA, Cloudflare Access). Reads the stored auth, decodes the JWT locally,\n * and probes a curated set of endpoints so we can tell apart:\n * - TLS interception (Node doesn't trust the proxy CA)\n * - URL-category filtering (some paths fail, others pass)\n * - Proxy-injected block pages (HTML body / missing request-id header)\n * - Real auth failures (401 with our header present)\n */\n\nimport process from 'node:process';\nimport { getArgValue, readStoredAuth, envToProfile, ENV_URLS } from './auth.js';\nimport { decodeJwtPayload } from './jwt.js';\nimport { apiFetch } from './api-fetch.js';\nimport { readBrandEnv } from './brand.js';\n\ninterface Probe {\n name: string;\n path: string;\n method?: string;\n}\n\nconst DEFAULT_PROBES: Probe[] = [\n { name: 'GET /me', path: '/me' },\n { name: 'GET /org/credentials', path: '/org/credentials' },\n { name: 'GET /org/properties', path: '/org/properties' },\n];\n\nfunction fmtExp(expSec: number | undefined): string {\n if (!expSec) return 'unknown';\n const now = Math.floor(Date.now() / 1000);\n const deltaSec = expSec - now;\n const date = new Date(expSec * 1000).toISOString();\n if (deltaSec < 0) return `${date} (expired ${Math.abs(deltaSec)}s ago)`;\n const days = Math.round(deltaSec / 86400);\n return `${date} (in ~${days} days)`;\n}\n\n/** Keep the first 8 chars of an identifier so users pasting doctor output\n * to IT don't leak full user/org IDs, but we still have enough for triage. */\nfunction truncateId(id: string | undefined): string {\n if (!id) return '(n/a)';\n return id.length > 8 ? `${id.slice(0, 8)}…` : id;\n}\n\nexport async function runAuthDoctor(argv: string[]): Promise<void> {\n const env = getArgValue(argv, '--env');\n const profile = env ? envToProfile(env) : undefined;\n const apiUrlOverride = getArgValue(argv, '--api-url') ?? readBrandEnv('CANARY_API_URL');\n\n const stored = await readStoredAuth(profile);\n const envToken = readBrandEnv('CANARY_API_TOKEN');\n const token = envToken ?? stored?.token;\n const apiUrl =\n apiUrlOverride ?? (env && ENV_URLS[env]?.api) ?? stored?.apiUrl ?? 'https://api.trycanary.ai';\n\n console.log('── canary auth doctor ──');\n console.log(`node: ${process.version}`);\n console.log(`platform: ${process.platform}`);\n console.log(`api url: ${apiUrl}`);\n console.log(`profile: ${profile ?? '(default)'}`);\n console.log(`token source: ${envToken ? 'API token env var' : stored?.token ? 'auth.json' : 'NONE'}`);\n console.log(\n `NODE_EXTRA_CA_CERTS: ${process.env.NODE_EXTRA_CA_CERTS ?? '(not set)'}`\n );\n console.log(`NODE_OPTIONS: ${process.env.NODE_OPTIONS ?? '(not set)'}`);\n\n if (!token) {\n console.log('');\n console.log('No token found. Run: canary login' + (env ? ` --env ${env}` : ''));\n process.exit(1);\n }\n\n const payload = decodeJwtPayload(token);\n const exp = typeof payload?.exp === 'number' ? (payload.exp as number) : undefined;\n const sub = typeof payload?.sub === 'string' ? (payload.sub as string) : undefined;\n const orgId = typeof payload?.org_id === 'string' ? (payload.org_id as string) : undefined;\n console.log('');\n console.log('── token ──');\n console.log(`decoded: ${payload ? 'ok' : 'UNDECODABLE (likely corrupted file)'}`);\n console.log(`sub: ${truncateId(sub)}`);\n console.log(`org_id: ${truncateId(orgId)}`);\n console.log(`exp: ${fmtExp(exp)}`);\n\n console.log('');\n console.log('── probes ──');\n console.log('Each probe exercises a different path — mixed pass/fail here is the');\n console.log('signal for Zscaler URL-category or DLP filtering.');\n console.log('');\n\n let hadProxyInjection = false;\n let hadTls = false;\n let passed = 0;\n\n for (const probe of DEFAULT_PROBES) {\n const url = `${apiUrl}${probe.path}`;\n const result = await apiFetch(url, {\n method: probe.method ?? 'GET',\n headers: { Authorization: `Bearer ${token}` },\n token,\n // Short per-probe timeout so one stalled endpoint doesn't block diagnosis.\n timeoutMs: 10_000,\n });\n if (result.ok) {\n const rid = result.requestId ?? '(absent)';\n console.log(` ✓ ${probe.name.padEnd(28)} 200 rid=${rid}`);\n passed += 1;\n } else {\n const f = result.failure;\n const rid = f.requestId ?? '(absent)';\n console.log(\n ` ✗ ${probe.name.padEnd(28)} ${f.status ?? 'ERR'} [${f.kind}] rid=${rid}`\n );\n const firstLine = f.message.split('\\n')[0];\n console.log(` ${firstLine}`);\n if (f.kind === 'tls') hadTls = true;\n if (f.kind === 'html-body' || f.kind === 'proxy-injected-4xx') hadProxyInjection = true;\n }\n }\n\n console.log('');\n console.log('── diagnosis ──');\n if (hadTls) {\n console.log('TLS verification failed on at least one probe.');\n console.log(' → A corporate proxy is intercepting HTTPS. Trust the proxy root CA:');\n console.log(' export NODE_EXTRA_CA_CERTS=/path/to/corporate-root.pem');\n console.log(' or on Node 20+:');\n console.log(' export NODE_OPTIONS=--use-system-ca');\n } else if (hadProxyInjection) {\n console.log('At least one response was NOT from our API (HTML body or missing');\n console.log('x-canary-request-id). A proxy block page or captive portal is in the way.');\n console.log(' → Share this output with your IT/Zscaler admin and ask them to');\n console.log(` allowlist ${apiUrl}.`);\n } else if (passed === DEFAULT_PROBES.length) {\n console.log('All probes reached our API successfully. Auth + connectivity look healthy.');\n console.log('If you are still seeing intermittent issues, re-run with --debug on the');\n console.log('failing command: CANARY_DEBUG=1 canary <cmd> …');\n } else if (passed > 0) {\n console.log('Mixed results: some probes reached our API, others did not.');\n console.log(' → This is the classic signature of URL-category filtering at the proxy');\n console.log(' (certain paths like /run, /execute are blocked while others pass)');\n console.log(' or partial domain allowlisting.');\n console.log(' → Share the probe table with your IT/Zscaler admin; include the exact');\n console.log(' failing paths and the \"[kind]\" column.');\n } else {\n console.log('Every probe failed. Check your network connection and proxy settings,');\n console.log('then retry with CANARY_DEBUG=1 canary auth doctor.');\n }\n\n if (passed < DEFAULT_PROBES.length) process.exit(1);\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,221 @@
1
+ import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
+ import {
3
+ apiRequest,
4
+ fetchProperties
5
+ } from "./chunk-PRBRSIZP.js";
6
+ import "./chunk-3CZU7XCS.js";
7
+ import {
8
+ getArgValue,
9
+ hasFlag,
10
+ resolveConfig
11
+ } from "./chunk-3X3NW7QA.js";
12
+ import "./chunk-JMJVGMXI.js";
13
+ import "./chunk-JWHYXEA2.js";
14
+ import "./chunk-JYGNMKZ5.js";
15
+ import "./chunk-VKVL7WBN.js";
16
+
17
+ // src/environment.ts
18
+ import process from "process";
19
+ function pad(s, n) {
20
+ return s.padEnd(n);
21
+ }
22
+ function printHelp() {
23
+ console.log(
24
+ [
25
+ "canary environment: Manage application environments (alias: canary env)",
26
+ "",
27
+ "Sub-commands:",
28
+ " list [options] List environments for an application",
29
+ " create [options] Create an environment (incl. sandbox)",
30
+ " set-default [options] Set an environment as the application default",
31
+ "",
32
+ "List options:",
33
+ " --application <name|id> Application (required; alias: --property)",
34
+ "",
35
+ "Create options:",
36
+ " --application <name|id> Application (required; alias: --property)",
37
+ " --name <name> Environment name (required)",
38
+ " --type <permanent|ephemeral|local|sandbox> Environment type (default: permanent)",
39
+ " --url <url> Base URL (required unless --type sandbox)",
40
+ " --sandbox-template <uuid> Backing template (required iff --type sandbox)",
41
+ " --login-path </path> Per-env login path override",
42
+ " --description <text> Optional description",
43
+ " --default Set this environment as the application default",
44
+ "",
45
+ "Set-default options:",
46
+ " --application <name|id> Application (required; alias: --property)",
47
+ " --environment <name|id> Environment to make default (required)",
48
+ "",
49
+ "Common options:",
50
+ " --json Output as JSON"
51
+ ].join("\n")
52
+ );
53
+ }
54
+ async function resolveApplicationId(argv, apiUrl, token) {
55
+ const arg = getArgValue(argv, "--application") ?? getArgValue(argv, "--property");
56
+ if (!arg) {
57
+ console.error("Error: --application <name|id> is required.");
58
+ process.exit(1);
59
+ }
60
+ const properties = await fetchProperties(apiUrl, token);
61
+ const match = properties.find(
62
+ (p) => p.id === arg || p.name.toLowerCase() === arg.toLowerCase()
63
+ );
64
+ if (!match) {
65
+ console.error(`Error: Application "${arg}" not found.`);
66
+ if (properties.length > 0) {
67
+ console.error("Available applications:");
68
+ for (const p of properties) console.error(` - ${p.name} (${p.id})`);
69
+ }
70
+ process.exit(1);
71
+ }
72
+ return match.id;
73
+ }
74
+ async function fetchEnvironments(propertyId, apiUrl, token) {
75
+ const res = await apiRequest(
76
+ apiUrl,
77
+ token,
78
+ "GET",
79
+ `/org/properties/${propertyId}/environments`
80
+ );
81
+ if (!res.ok) {
82
+ console.error(`Error: ${res.error ?? "Failed to list environments"}`);
83
+ process.exit(1);
84
+ }
85
+ return res.items ?? [];
86
+ }
87
+ async function handleList(argv, apiUrl, token) {
88
+ const json = hasFlag(argv, "--json");
89
+ const propertyId = await resolveApplicationId(argv, apiUrl, token);
90
+ const items = await fetchEnvironments(propertyId, apiUrl, token);
91
+ if (json) {
92
+ console.log(JSON.stringify(items, null, 2));
93
+ return;
94
+ }
95
+ if (items.length === 0) {
96
+ console.log("No environments found.");
97
+ return;
98
+ }
99
+ console.log(`${pad("Name", 28)} ${pad("Type", 11)} ${pad("Default", 8)} ${pad("URL", 36)} Template`);
100
+ for (const e of items) {
101
+ console.log(
102
+ `${pad(e.name, 28)} ${pad(e.type, 11)} ${pad(e.isDefault ? "yes" : "", 8)} ${pad(e.url || "(none)", 36)} ${e.sandboxTemplateId ?? ""}`
103
+ );
104
+ }
105
+ }
106
+ async function handleCreate(argv, apiUrl, token) {
107
+ const json = hasFlag(argv, "--json");
108
+ const propertyId = await resolveApplicationId(argv, apiUrl, token);
109
+ const name = getArgValue(argv, "--name");
110
+ const type = getArgValue(argv, "--type") ?? "permanent";
111
+ const url = getArgValue(argv, "--url");
112
+ const sandboxTemplateId = getArgValue(argv, "--sandbox-template");
113
+ const loginPath = getArgValue(argv, "--login-path");
114
+ const description = getArgValue(argv, "--description");
115
+ const isDefault = hasFlag(argv, "--default");
116
+ if (!name) {
117
+ console.error("Error: --name is required.");
118
+ process.exit(1);
119
+ }
120
+ if (type === "sandbox" && !sandboxTemplateId) {
121
+ console.error("Error: --sandbox-template <uuid> is required when --type sandbox.");
122
+ process.exit(1);
123
+ }
124
+ if (type !== "sandbox" && !url) {
125
+ console.error(`Error: --url is required for --type ${type}.`);
126
+ process.exit(1);
127
+ }
128
+ const body = { name, type };
129
+ if (url !== void 0) body.url = url;
130
+ if (sandboxTemplateId !== void 0) body.sandboxTemplateId = sandboxTemplateId;
131
+ if (loginPath !== void 0) body.loginPath = loginPath;
132
+ if (description !== void 0) body.description = description;
133
+ if (isDefault) body.isDefault = true;
134
+ const result = await apiRequest(
135
+ apiUrl,
136
+ token,
137
+ "POST",
138
+ `/org/properties/${propertyId}/environments`,
139
+ body
140
+ );
141
+ if (!result.ok) {
142
+ if (json) console.log(JSON.stringify(result, null, 2));
143
+ else console.error(`Error: ${result.error ?? "Unknown error"}`);
144
+ process.exit(1);
145
+ }
146
+ if (json) {
147
+ console.log(JSON.stringify(result, null, 2));
148
+ return;
149
+ }
150
+ console.log(`Created ${type} environment "${name}" (${result.item?.id ?? "?"})`);
151
+ }
152
+ async function handleSetDefault(argv, apiUrl, token) {
153
+ const json = hasFlag(argv, "--json");
154
+ const propertyId = await resolveApplicationId(argv, apiUrl, token);
155
+ const envArg = getArgValue(argv, "--environment");
156
+ if (!envArg) {
157
+ console.error("Error: --environment <name|id> is required.");
158
+ process.exit(1);
159
+ }
160
+ const items = await fetchEnvironments(propertyId, apiUrl, token);
161
+ const match = items.find(
162
+ (e) => e.id === envArg || e.name.toLowerCase() === envArg.toLowerCase()
163
+ );
164
+ if (!match) {
165
+ console.error(`Error: Environment "${envArg}" not found for this application.`);
166
+ if (items.length > 0) {
167
+ console.error("Available environments:");
168
+ for (const e of items) console.error(` - ${e.name} (${e.id})`);
169
+ }
170
+ process.exit(1);
171
+ }
172
+ const result = await apiRequest(
173
+ apiUrl,
174
+ token,
175
+ "POST",
176
+ `/org/properties/${propertyId}/environments/${match.id}/set-default`
177
+ );
178
+ if (!result.ok) {
179
+ if (json) console.log(JSON.stringify(result, null, 2));
180
+ else console.error(`Error: ${result.error ?? "Unknown error"}`);
181
+ process.exit(1);
182
+ }
183
+ if (json) {
184
+ console.log(JSON.stringify({ ok: true, environmentId: match.id }, null, 2));
185
+ return;
186
+ }
187
+ console.log(`Set "${match.name}" (${match.id}) as the default environment.`);
188
+ }
189
+ async function runEnvironment(argv) {
190
+ const [subCommand, ...rest] = argv;
191
+ if (!subCommand || subCommand === "help" || hasFlag(argv, "--help", "-h")) {
192
+ printHelp();
193
+ return;
194
+ }
195
+ const { apiUrl, token } = await resolveConfig(argv);
196
+ const globalFlags = /* @__PURE__ */ new Set(["--env", "--api-url", "--token"]);
197
+ const args = rest.filter((arg, i) => {
198
+ if (globalFlags.has(arg)) return false;
199
+ if (i > 0 && globalFlags.has(rest[i - 1])) return false;
200
+ return true;
201
+ });
202
+ switch (subCommand) {
203
+ case "list":
204
+ await handleList(args, apiUrl, token);
205
+ break;
206
+ case "create":
207
+ await handleCreate(args, apiUrl, token);
208
+ break;
209
+ case "set-default":
210
+ await handleSetDefault(args, apiUrl, token);
211
+ break;
212
+ default:
213
+ console.error(`Unknown sub-command: ${subCommand}`);
214
+ printHelp();
215
+ process.exit(1);
216
+ }
217
+ }
218
+ export {
219
+ runEnvironment
220
+ };
221
+ //# sourceMappingURL=environment-7Y4BV6XY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/environment.ts"],"sourcesContent":["/**\n * CLI Environment Management\n *\n * List, create, and set the default environment for an application, including\n * `type='sandbox'` environments backed by a verified sandbox template. Reuses\n * the existing `/org/properties/:id/environments` endpoints — no new API.\n */\n\nimport process from 'node:process';\nimport { resolveConfig, hasFlag, getArgValue } from './auth.js';\nimport { fetchProperties, apiRequest } from './cli-helpers.js';\n\ntype EnvironmentItem = {\n id: string;\n name: string;\n type: 'permanent' | 'ephemeral' | 'local' | 'sandbox';\n url: string;\n isDefault: boolean;\n sandboxTemplateId: string | null;\n};\n\nfunction pad(s: string, n: number): string {\n return s.padEnd(n);\n}\n\nfunction printHelp(): void {\n console.log(\n [\n 'canary environment: Manage application environments (alias: canary env)',\n '',\n 'Sub-commands:',\n ' list [options] List environments for an application',\n ' create [options] Create an environment (incl. sandbox)',\n ' set-default [options] Set an environment as the application default',\n '',\n 'List options:',\n ' --application <name|id> Application (required; alias: --property)',\n '',\n 'Create options:',\n ' --application <name|id> Application (required; alias: --property)',\n ' --name <name> Environment name (required)',\n ' --type <permanent|ephemeral|local|sandbox> Environment type (default: permanent)',\n ' --url <url> Base URL (required unless --type sandbox)',\n ' --sandbox-template <uuid> Backing template (required iff --type sandbox)',\n ' --login-path </path> Per-env login path override',\n ' --description <text> Optional description',\n ' --default Set this environment as the application default',\n '',\n 'Set-default options:',\n ' --application <name|id> Application (required; alias: --property)',\n ' --environment <name|id> Environment to make default (required)',\n '',\n 'Common options:',\n ' --json Output as JSON',\n ].join('\\n')\n );\n}\n\n/** Resolve `--application`/`--property` (name or id) to a property id. */\nasync function resolveApplicationId(\n argv: string[],\n apiUrl: string,\n token: string\n): Promise<string> {\n const arg = getArgValue(argv, '--application') ?? getArgValue(argv, '--property');\n if (!arg) {\n console.error('Error: --application <name|id> is required.');\n process.exit(1);\n }\n const properties = await fetchProperties(apiUrl, token);\n const match = properties.find(\n (p) => p.id === arg || p.name.toLowerCase() === arg.toLowerCase()\n );\n if (!match) {\n console.error(`Error: Application \"${arg}\" not found.`);\n if (properties.length > 0) {\n console.error('Available applications:');\n for (const p of properties) console.error(` - ${p.name} (${p.id})`);\n }\n process.exit(1);\n }\n return match.id;\n}\n\nasync function fetchEnvironments(\n propertyId: string,\n apiUrl: string,\n token: string\n): Promise<EnvironmentItem[]> {\n const res = await apiRequest<{ ok: boolean; items?: EnvironmentItem[]; error?: string }>(\n apiUrl,\n token,\n 'GET',\n `/org/properties/${propertyId}/environments`\n );\n if (!res.ok) {\n console.error(`Error: ${res.error ?? 'Failed to list environments'}`);\n process.exit(1);\n }\n return res.items ?? [];\n}\n\nasync function handleList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const propertyId = await resolveApplicationId(argv, apiUrl, token);\n const items = await fetchEnvironments(propertyId, apiUrl, token);\n\n if (json) {\n console.log(JSON.stringify(items, null, 2));\n return;\n }\n if (items.length === 0) {\n console.log('No environments found.');\n return;\n }\n console.log(`${pad('Name', 28)} ${pad('Type', 11)} ${pad('Default', 8)} ${pad('URL', 36)} Template`);\n for (const e of items) {\n console.log(\n `${pad(e.name, 28)} ${pad(e.type, 11)} ${pad(e.isDefault ? 'yes' : '', 8)} ` +\n `${pad(e.url || '(none)', 36)} ${e.sandboxTemplateId ?? ''}`\n );\n }\n}\n\nasync function handleCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const propertyId = await resolveApplicationId(argv, apiUrl, token);\n const name = getArgValue(argv, '--name');\n const type = (getArgValue(argv, '--type') ?? 'permanent') as EnvironmentItem['type'];\n const url = getArgValue(argv, '--url');\n const sandboxTemplateId = getArgValue(argv, '--sandbox-template');\n const loginPath = getArgValue(argv, '--login-path');\n const description = getArgValue(argv, '--description');\n const isDefault = hasFlag(argv, '--default');\n\n if (!name) {\n console.error('Error: --name is required.');\n process.exit(1);\n }\n if (type === 'sandbox' && !sandboxTemplateId) {\n console.error('Error: --sandbox-template <uuid> is required when --type sandbox.');\n process.exit(1);\n }\n if (type !== 'sandbox' && !url) {\n console.error(`Error: --url is required for --type ${type}.`);\n process.exit(1);\n }\n\n const body: Record<string, unknown> = { name, type };\n if (url !== undefined) body.url = url;\n if (sandboxTemplateId !== undefined) body.sandboxTemplateId = sandboxTemplateId;\n if (loginPath !== undefined) body.loginPath = loginPath;\n if (description !== undefined) body.description = description;\n if (isDefault) body.isDefault = true;\n\n const result = await apiRequest<{ ok: boolean; item?: EnvironmentItem; error?: string }>(\n apiUrl,\n token,\n 'POST',\n `/org/properties/${propertyId}/environments`,\n body\n );\n\n if (!result.ok) {\n if (json) console.log(JSON.stringify(result, null, 2));\n else console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n console.log(`Created ${type} environment \"${name}\" (${result.item?.id ?? '?'})`);\n}\n\nasync function handleSetDefault(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const propertyId = await resolveApplicationId(argv, apiUrl, token);\n const envArg = getArgValue(argv, '--environment');\n if (!envArg) {\n console.error('Error: --environment <name|id> is required.');\n process.exit(1);\n }\n\n const items = await fetchEnvironments(propertyId, apiUrl, token);\n const match = items.find(\n (e) => e.id === envArg || e.name.toLowerCase() === envArg.toLowerCase()\n );\n if (!match) {\n console.error(`Error: Environment \"${envArg}\" not found for this application.`);\n if (items.length > 0) {\n console.error('Available environments:');\n for (const e of items) console.error(` - ${e.name} (${e.id})`);\n }\n process.exit(1);\n }\n\n const result = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'POST',\n `/org/properties/${propertyId}/environments/${match.id}/set-default`\n );\n\n if (!result.ok) {\n if (json) console.log(JSON.stringify(result, null, 2));\n else console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n if (json) {\n console.log(JSON.stringify({ ok: true, environmentId: match.id }, null, 2));\n return;\n }\n console.log(`Set \"${match.name}\" (${match.id}) as the default environment.`);\n}\n\nexport async function runEnvironment(argv: string[]): Promise<void> {\n const [subCommand, ...rest] = argv;\n\n if (!subCommand || subCommand === 'help' || hasFlag(argv, '--help', '-h')) {\n printHelp();\n return;\n }\n\n const { apiUrl, token } = await resolveConfig(argv);\n\n const globalFlags = new Set(['--env', '--api-url', '--token']);\n const args = rest.filter((arg, i) => {\n if (globalFlags.has(arg)) return false;\n if (i > 0 && globalFlags.has(rest[i - 1])) return false;\n return true;\n });\n\n switch (subCommand) {\n case 'list':\n await handleList(args, apiUrl, token);\n break;\n case 'create':\n await handleCreate(args, apiUrl, token);\n break;\n case 'set-default':\n await handleSetDefault(args, apiUrl, token);\n break;\n default:\n console.error(`Unknown sub-command: ${subCommand}`);\n printHelp();\n process.exit(1);\n }\n}\n"],"mappings":"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","names":[]}