@runcofactor/cli 0.10.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 (150) hide show
  1. package/README.md +125 -0
  2. package/dist/api-catalog-GFGCLVS4.js +401 -0
  3. package/dist/api-catalog-GFGCLVS4.js.map +1 -0
  4. package/dist/attachment-SJC7D7FY.js +276 -0
  5. package/dist/attachment-SJC7D7FY.js.map +1 -0
  6. package/dist/auth-EN6NQCJY.js +31 -0
  7. package/dist/auth-EN6NQCJY.js.map +1 -0
  8. package/dist/bin.js +7 -0
  9. package/dist/bin.js.map +1 -0
  10. package/dist/chunk-3CZU7XCS.js +272 -0
  11. package/dist/chunk-3CZU7XCS.js.map +1 -0
  12. package/dist/chunk-4NRDONSC.js +1048 -0
  13. package/dist/chunk-4NRDONSC.js.map +1 -0
  14. package/dist/chunk-4PNOV7OV.js +51980 -0
  15. package/dist/chunk-4PNOV7OV.js.map +1 -0
  16. package/dist/chunk-52IO7ACJ.js +2941 -0
  17. package/dist/chunk-52IO7ACJ.js.map +1 -0
  18. package/dist/chunk-6LEZCKKV.js +663 -0
  19. package/dist/chunk-6LEZCKKV.js.map +1 -0
  20. package/dist/chunk-A4OFTUVV.js +170 -0
  21. package/dist/chunk-A4OFTUVV.js.map +1 -0
  22. package/dist/chunk-B2VISN2V.js +2459 -0
  23. package/dist/chunk-B2VISN2V.js.map +1 -0
  24. package/dist/chunk-CLAWT7BJ.js +271 -0
  25. package/dist/chunk-CLAWT7BJ.js.map +1 -0
  26. package/dist/chunk-GKY2KXO5.js +281 -0
  27. package/dist/chunk-GKY2KXO5.js.map +1 -0
  28. package/dist/chunk-I4QLI3JO.js +413 -0
  29. package/dist/chunk-I4QLI3JO.js.map +1 -0
  30. package/dist/chunk-IMPZAX6L.js +180 -0
  31. package/dist/chunk-IMPZAX6L.js.map +1 -0
  32. package/dist/chunk-J6SH7GQT.js +241 -0
  33. package/dist/chunk-J6SH7GQT.js.map +1 -0
  34. package/dist/chunk-JDBCZ3Z2.js +298 -0
  35. package/dist/chunk-JDBCZ3Z2.js.map +1 -0
  36. package/dist/chunk-JICSYFRJ.js +46 -0
  37. package/dist/chunk-JICSYFRJ.js.map +1 -0
  38. package/dist/chunk-JWHYXEA2.js +32 -0
  39. package/dist/chunk-JWHYXEA2.js.map +1 -0
  40. package/dist/chunk-N7HFALX3.js +88 -0
  41. package/dist/chunk-N7HFALX3.js.map +1 -0
  42. package/dist/chunk-Q4BO4Z5V.js +178 -0
  43. package/dist/chunk-Q4BO4Z5V.js.map +1 -0
  44. package/dist/chunk-QFDOWABX.js +195 -0
  45. package/dist/chunk-QFDOWABX.js.map +1 -0
  46. package/dist/chunk-SJJW77WN.js +605 -0
  47. package/dist/chunk-SJJW77WN.js.map +1 -0
  48. package/dist/chunk-VKVL7WBN.js +50 -0
  49. package/dist/chunk-VKVL7WBN.js.map +1 -0
  50. package/dist/chunk-WOHL4FTB.js +353 -0
  51. package/dist/chunk-WOHL4FTB.js.map +1 -0
  52. package/dist/chunk-XQXVG7RA.js +426 -0
  53. package/dist/chunk-XQXVG7RA.js.map +1 -0
  54. package/dist/chunk-ZD3KHESI.js +94 -0
  55. package/dist/chunk-ZD3KHESI.js.map +1 -0
  56. package/dist/credential-COLTBV6D.js +450 -0
  57. package/dist/credential-COLTBV6D.js.map +1 -0
  58. package/dist/credential-template-EEPYFG7R.js +291 -0
  59. package/dist/credential-template-EEPYFG7R.js.map +1 -0
  60. package/dist/debug-workflow-KOVH5GOP.js +259 -0
  61. package/dist/debug-workflow-KOVH5GOP.js.map +1 -0
  62. package/dist/dist-44PZR7BQ.js +423 -0
  63. package/dist/dist-44PZR7BQ.js.map +1 -0
  64. package/dist/docs-3SSORHB5.js +366 -0
  65. package/dist/docs-3SSORHB5.js.map +1 -0
  66. package/dist/doctor-OTSIWV6G.js +132 -0
  67. package/dist/doctor-OTSIWV6G.js.map +1 -0
  68. package/dist/feature-flag-T2LRZME3.js +283 -0
  69. package/dist/feature-flag-T2LRZME3.js.map +1 -0
  70. package/dist/file-type-S3UUBVCT.js +4205 -0
  71. package/dist/file-type-S3UUBVCT.js.map +1 -0
  72. package/dist/index.d.ts +3 -0
  73. package/dist/index.js +982 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/init-TGWRECT2.js +208 -0
  76. package/dist/init-TGWRECT2.js.map +1 -0
  77. package/dist/install-DXSNWZKO.js +295 -0
  78. package/dist/install-DXSNWZKO.js.map +1 -0
  79. package/dist/issues-XIZOPX6T.js +564 -0
  80. package/dist/issues-XIZOPX6T.js.map +1 -0
  81. package/dist/knobs-NBINZIUB.js +295 -0
  82. package/dist/knobs-NBINZIUB.js.map +1 -0
  83. package/dist/list-3TDHK637.js +59 -0
  84. package/dist/list-3TDHK637.js.map +1 -0
  85. package/dist/local-HICVD6PU.js +100 -0
  86. package/dist/local-HICVD6PU.js.map +1 -0
  87. package/dist/login-UOIUXVUK.js +315 -0
  88. package/dist/login-UOIUXVUK.js.map +1 -0
  89. package/dist/mcp-54IJEOUA.js +1956 -0
  90. package/dist/mcp-54IJEOUA.js.map +1 -0
  91. package/dist/pdf-extract-ABWV3L5X.js +13 -0
  92. package/dist/pdf-extract-ABWV3L5X.js.map +1 -0
  93. package/dist/pdfjs-DQ2YA5S3.js +41561 -0
  94. package/dist/pdfjs-DQ2YA5S3.js.map +1 -0
  95. package/dist/property-UXLOLPTD.js +701 -0
  96. package/dist/property-UXLOLPTD.js.map +1 -0
  97. package/dist/property-skill-guide.md +189 -0
  98. package/dist/psql-BYUUNLGG.js +115 -0
  99. package/dist/psql-BYUUNLGG.js.map +1 -0
  100. package/dist/record-4TR2UIIS.js +233 -0
  101. package/dist/record-4TR2UIIS.js.map +1 -0
  102. package/dist/redis-35VBUYW7.js +116 -0
  103. package/dist/redis-35VBUYW7.js.map +1 -0
  104. package/dist/release-OOLTUBUT.js +354 -0
  105. package/dist/release-OOLTUBUT.js.map +1 -0
  106. package/dist/sandbox-XGSUU6G7.js +2046 -0
  107. package/dist/sandbox-XGSUU6G7.js.map +1 -0
  108. package/dist/scenarios-GWLJEGHA.js +280 -0
  109. package/dist/scenarios-GWLJEGHA.js.map +1 -0
  110. package/dist/session-MYFNZPRP.js +2414 -0
  111. package/dist/session-MYFNZPRP.js.map +1 -0
  112. package/dist/skill-KM34LDMO.js +1839 -0
  113. package/dist/skill-KM34LDMO.js.map +1 -0
  114. package/dist/skills/debug-run/SKILL.md +262 -0
  115. package/dist/skills/debug-run/history/1.0.0.md +244 -0
  116. package/dist/skills/debug-run/history/1.0.1.md +245 -0
  117. package/dist/skills/debug-run/history/1.0.2.md +254 -0
  118. package/dist/skills/debug-run/history/1.1.0.md +262 -0
  119. package/dist/skills/debug-run/version.json +3 -0
  120. package/dist/spec-RA3CFEKG.js +951 -0
  121. package/dist/spec-RA3CFEKG.js.map +1 -0
  122. package/dist/src-LB4HBTJQ.js +1516 -0
  123. package/dist/src-LB4HBTJQ.js.map +1 -0
  124. package/dist/src-N3TPKGTY.js +244 -0
  125. package/dist/src-N3TPKGTY.js.map +1 -0
  126. package/dist/src-UVDX5UP6.js +17 -0
  127. package/dist/src-UVDX5UP6.js.map +1 -0
  128. package/dist/start-PSEQSQA3.js +151 -0
  129. package/dist/start-PSEQSQA3.js.map +1 -0
  130. package/dist/tag-YY6YAABQ.js +22 -0
  131. package/dist/tag-YY6YAABQ.js.map +1 -0
  132. package/dist/task-IQC3YR5K.js +922 -0
  133. package/dist/task-IQC3YR5K.js.map +1 -0
  134. package/dist/test-suite-DZNJFXDW.js +394 -0
  135. package/dist/test-suite-DZNJFXDW.js.map +1 -0
  136. package/dist/trace-HXIW7U2D.js +14 -0
  137. package/dist/trace-HXIW7U2D.js.map +1 -0
  138. package/dist/triage-ORG45R5W.js +16 -0
  139. package/dist/triage-ORG45R5W.js.map +1 -0
  140. package/dist/upgrade-L2VYMP2V.js +61 -0
  141. package/dist/upgrade-L2VYMP2V.js.map +1 -0
  142. package/dist/workflow-XYFH5LTP.js +3708 -0
  143. package/dist/workflow-XYFH5LTP.js.map +1 -0
  144. package/dist/workflow-cache-NQJQFWMV.js +253 -0
  145. package/dist/workflow-cache-NQJQFWMV.js.map +1 -0
  146. package/dist/workflow-debug-BGD4UIXU.js +927 -0
  147. package/dist/workflow-debug-BGD4UIXU.js.map +1 -0
  148. package/dist/workflow-proposals-MTUDX46O.js +382 -0
  149. package/dist/workflow-proposals-MTUDX46O.js.map +1 -0
  150. package/package.json +61 -0
@@ -0,0 +1,366 @@
1
+ import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
+ import {
3
+ apiRequest
4
+ } from "./chunk-WOHL4FTB.js";
5
+ import "./chunk-SJJW77WN.js";
6
+ import "./chunk-3CZU7XCS.js";
7
+ import {
8
+ getArgValue,
9
+ hasFlag,
10
+ resolveConfig
11
+ } from "./chunk-A4OFTUVV.js";
12
+ import {
13
+ getSubDir
14
+ } from "./chunk-JWHYXEA2.js";
15
+ import "./chunk-VKVL7WBN.js";
16
+
17
+ // src/docs.ts
18
+ import { readFile, writeFile, mkdir } from "fs/promises";
19
+ import path from "path";
20
+ import process from "process";
21
+ var DEFAULT_PULL_DIR = getSubDir("docs");
22
+ function parseNavFields(argv) {
23
+ const out = {};
24
+ const section = getArgValue(argv, "--section");
25
+ const group = getArgValue(argv, "--group");
26
+ const order = getArgValue(argv, "--order");
27
+ if (section != null) out.navSection = section;
28
+ if (group != null) out.navGroup = group;
29
+ if (order != null) {
30
+ const n = Number.parseInt(order, 10);
31
+ if (Number.isNaN(n)) {
32
+ console.error("Error: --order must be an integer.");
33
+ process.exit(1);
34
+ }
35
+ out.navOrder = n;
36
+ }
37
+ return out;
38
+ }
39
+ function readPrefix(orgMode) {
40
+ return orgMode ? "/docs" : "/public/docs";
41
+ }
42
+ function writePrefix(orgMode) {
43
+ return orgMode ? "/docs" : "/superadmin/docs";
44
+ }
45
+ async function handleList(argv, apiUrl, token, orgMode) {
46
+ const jsonOutput = hasFlag(argv, "--json");
47
+ const result = await apiRequest(apiUrl, token, "GET", `${readPrefix(orgMode)}/pages`);
48
+ const pages = result.data?.pages ?? [];
49
+ if (jsonOutput) {
50
+ console.log(JSON.stringify(pages, null, 2));
51
+ return;
52
+ }
53
+ if (pages.length === 0) {
54
+ console.log("No documentation pages found.");
55
+ return;
56
+ }
57
+ const slugWidth = Math.max(4, ...pages.map((p) => p.slug.length));
58
+ const titleWidth = Math.max(5, ...pages.map((p) => p.title.length));
59
+ const header = `| ${"Slug".padEnd(slugWidth)} | ${"Title".padEnd(titleWidth)} | Updated | Published By |`;
60
+ const sep = `| ${"-".repeat(slugWidth)} | ${"-".repeat(titleWidth)} | ---------- | ------------ |`;
61
+ console.log(header);
62
+ console.log(sep);
63
+ for (const page of pages) {
64
+ const date = new Date(page.updatedAt).toISOString().slice(0, 10);
65
+ const by = page.publishedBy ?? "";
66
+ console.log(`| ${page.slug.padEnd(slugWidth)} | ${page.title.padEnd(titleWidth)} | ${date} | ${by.padEnd(12)} |`);
67
+ }
68
+ }
69
+ async function fetchDocContent(slug, apiUrl, token, orgMode) {
70
+ if (orgMode) {
71
+ const result = await apiRequest(
72
+ apiUrl,
73
+ token,
74
+ "GET",
75
+ `/docs/pages/content?slug=${encodeURIComponent(slug)}`
76
+ );
77
+ if (!result.ok) {
78
+ console.error(`Error: ${result.error}`);
79
+ process.exit(1);
80
+ }
81
+ return result.data?.content ?? "";
82
+ }
83
+ const res = await fetch(`${apiUrl}/public/docs/pages/raw?slug=${encodeURIComponent(slug)}`, {
84
+ headers: { Authorization: `Bearer ${token}` }
85
+ });
86
+ if (res.status === 404) {
87
+ console.error(`Error: Page not found: ${slug}`);
88
+ process.exit(1);
89
+ }
90
+ if (!res.ok) {
91
+ console.error(`Error: ${res.statusText}`);
92
+ process.exit(1);
93
+ }
94
+ return res.text();
95
+ }
96
+ async function handleGet(argv, apiUrl, token, orgMode) {
97
+ const slug = argv[0];
98
+ if (!slug || slug.startsWith("--")) {
99
+ console.error("Error: Missing slug.");
100
+ console.error("Usage: canary docs get <slug>");
101
+ process.exit(1);
102
+ }
103
+ const content = await fetchDocContent(slug, apiUrl, token, orgMode);
104
+ console.log(content);
105
+ }
106
+ async function handlePull(argv, apiUrl, token, orgMode) {
107
+ const slug = argv[0];
108
+ if (!slug || slug.startsWith("--")) {
109
+ console.error("Error: Missing slug.");
110
+ console.error("Usage: canary docs pull <slug> [--output <path>]");
111
+ process.exit(1);
112
+ }
113
+ const outputPath = getArgValue(argv, "--output") ?? path.join(DEFAULT_PULL_DIR, `${slug}.md`);
114
+ const content = await fetchDocContent(slug, apiUrl, token, orgMode);
115
+ await mkdir(path.dirname(outputPath), { recursive: true });
116
+ await writeFile(outputPath, content, "utf8");
117
+ console.log(`Pulled ${slug} \u2192 ${outputPath}`);
118
+ }
119
+ async function handlePush(argv, apiUrl, token, orgMode) {
120
+ const slug = argv[0];
121
+ if (!slug || slug.startsWith("--")) {
122
+ console.error("Error: Missing slug.");
123
+ console.error("Usage: canary docs push <slug> --file <path> [--message <text>]");
124
+ process.exit(1);
125
+ }
126
+ const filePath = getArgValue(argv, "--file");
127
+ if (!filePath) {
128
+ console.error("Error: Missing --file <path>.");
129
+ process.exit(1);
130
+ }
131
+ const message = getArgValue(argv, "--message") ?? void 0;
132
+ const createdBy = getArgValue(argv, "--created-by") ?? void 0;
133
+ let content;
134
+ try {
135
+ content = await readFile(filePath, "utf8");
136
+ } catch {
137
+ console.error(`Error: Could not read file: ${filePath}`);
138
+ process.exit(1);
139
+ }
140
+ content = content.replace(/^\s*export\s+const\s+meta\s*=\s*\{[^}]*\};\s*/, "");
141
+ const result = await apiRequest(
142
+ apiUrl,
143
+ token,
144
+ "PUT",
145
+ `${writePrefix(orgMode)}/pages?slug=${encodeURIComponent(slug)}`,
146
+ { content, message, createdBy, ...parseNavFields(argv) }
147
+ );
148
+ if (!result.ok) {
149
+ console.error(`Error: ${result.error}`);
150
+ process.exit(1);
151
+ }
152
+ console.log(`Published new version of ${slug}`);
153
+ }
154
+ async function handleHistory(argv, apiUrl, token, orgMode) {
155
+ const slug = argv[0];
156
+ if (!slug || slug.startsWith("--")) {
157
+ console.error("Error: Missing slug.");
158
+ console.error("Usage: canary docs history <slug>");
159
+ process.exit(1);
160
+ }
161
+ const jsonOutput = hasFlag(argv, "--json");
162
+ const res = await fetch(`${apiUrl}${readPrefix(orgMode)}/pages/versions?slug=${encodeURIComponent(slug)}`, {
163
+ headers: { Authorization: `Bearer ${token}` }
164
+ });
165
+ if (!res.ok) {
166
+ const body2 = await res.json().catch(() => ({ error: res.statusText }));
167
+ console.error(`Error: ${body2.error ?? res.statusText}`);
168
+ process.exit(1);
169
+ }
170
+ const body = await res.json();
171
+ const versions = body.data?.versions ?? [];
172
+ if (jsonOutput) {
173
+ console.log(JSON.stringify(versions, null, 2));
174
+ return;
175
+ }
176
+ if (versions.length === 0) {
177
+ console.log(`No versions found for ${slug}.`);
178
+ return;
179
+ }
180
+ for (const v of versions) {
181
+ const date = new Date(v.createdAt).toISOString().slice(0, 19).replace("T", " ");
182
+ const msg = v.message ? ` \u2014 ${v.message}` : "";
183
+ console.log(` v${v.version} ${date} ${v.createdBy}${msg}`);
184
+ }
185
+ }
186
+ async function handleCreate(argv, apiUrl, token, orgMode) {
187
+ const slug = argv[0];
188
+ if (!slug || slug.startsWith("--")) {
189
+ console.error("Error: Missing slug.");
190
+ console.error("Usage: canary docs create <slug> --file <path> --title <text>");
191
+ process.exit(1);
192
+ }
193
+ const filePath = getArgValue(argv, "--file");
194
+ const title = getArgValue(argv, "--title");
195
+ if (!filePath) {
196
+ console.error("Error: Missing --file <path>.");
197
+ process.exit(1);
198
+ }
199
+ if (!title) {
200
+ console.error("Error: Missing --title <text>.");
201
+ process.exit(1);
202
+ }
203
+ const description = getArgValue(argv, "--description") ?? void 0;
204
+ const message = getArgValue(argv, "--message") ?? void 0;
205
+ let content;
206
+ try {
207
+ content = await readFile(filePath, "utf8");
208
+ } catch {
209
+ console.error(`Error: Could not read file: ${filePath}`);
210
+ process.exit(1);
211
+ }
212
+ content = content.replace(/^\s*export\s+const\s+meta\s*=\s*\{[^}]*\};\s*/, "");
213
+ const result = await apiRequest(
214
+ apiUrl,
215
+ token,
216
+ "POST",
217
+ `${writePrefix(orgMode)}/pages`,
218
+ {
219
+ slug,
220
+ title,
221
+ description,
222
+ content,
223
+ message,
224
+ ...parseNavFields(argv)
225
+ }
226
+ );
227
+ if (!result.ok) {
228
+ console.error(`Error: ${result.error}`);
229
+ process.exit(1);
230
+ }
231
+ console.log(`Created page: ${slug}`);
232
+ }
233
+ async function handleSearch(argv, apiUrl, token, orgMode) {
234
+ const query = argv.filter((a) => !a.startsWith("--")).join(" ").trim();
235
+ if (!query) {
236
+ console.error("Error: Missing search query.");
237
+ console.error("Usage: canary docs search <query> [--limit <n>] [--json]");
238
+ process.exit(1);
239
+ }
240
+ const jsonOutput = hasFlag(argv, "--json");
241
+ const limitArg = getArgValue(argv, "--limit");
242
+ const params = new URLSearchParams({ q: query });
243
+ if (limitArg) params.set("limit", limitArg);
244
+ const searchPath = orgMode ? "/docs/search" : "/public/docs/search";
245
+ const res = await fetch(`${apiUrl}${searchPath}?${params.toString()}`, {
246
+ headers: { Authorization: `Bearer ${token}` }
247
+ });
248
+ if (!res.ok) {
249
+ const body2 = await res.json().catch(() => ({ error: res.statusText }));
250
+ console.error(`Error: ${body2.error ?? res.statusText}`);
251
+ process.exit(1);
252
+ }
253
+ const body = await res.json();
254
+ const results = body.data?.results ?? [];
255
+ if (jsonOutput) {
256
+ console.log(JSON.stringify(results, null, 2));
257
+ return;
258
+ }
259
+ if (results.length === 0) {
260
+ console.log("No results found.");
261
+ return;
262
+ }
263
+ for (const r of results) {
264
+ const desc = r.description ? ` ${r.description}` : "";
265
+ const excerpt = r.excerpt ? ` ${r.excerpt.replace(/<\/?mark>/g, "").replace(/\n/g, " ").slice(0, 120)}` : "";
266
+ console.log(` ${r.path ?? r.title}`);
267
+ if (r.title) console.log(` ${r.title}${desc}`);
268
+ if (excerpt) console.log(` ${excerpt}`);
269
+ console.log();
270
+ }
271
+ }
272
+ async function handleDelete(argv, apiUrl, token, orgMode) {
273
+ const slug = argv[0];
274
+ if (!slug || slug.startsWith("--")) {
275
+ console.error("Error: Missing slug.");
276
+ console.error("Usage: canary docs delete <slug>");
277
+ process.exit(1);
278
+ }
279
+ const result = await apiRequest(
280
+ apiUrl,
281
+ token,
282
+ "DELETE",
283
+ `${writePrefix(orgMode)}/pages?slug=${encodeURIComponent(slug)}`
284
+ );
285
+ if (!result.ok) {
286
+ console.error(`Error: ${result.error}`);
287
+ process.exit(1);
288
+ }
289
+ console.log(`Deleted page: ${slug}`);
290
+ }
291
+ function printDocsHelp() {
292
+ console.log(
293
+ [
294
+ "Usage: canary docs <sub-command> [options]",
295
+ "",
296
+ "Sub-commands:",
297
+ " list List all doc pages",
298
+ " get <slug> Print content to stdout",
299
+ " search <query> Full-text search docs",
300
+ " pull <slug> [--output <path>] Download to local file",
301
+ " push <slug> --file <path> [--message] Publish new version",
302
+ " history <slug> Show version history",
303
+ " create <slug> --file <path> --title ... Create new page",
304
+ " delete <slug> Soft-delete a page",
305
+ "",
306
+ "Options:",
307
+ " --org Use org-scoped endpoints (requires auth)",
308
+ " --file <path> Path to markdown file",
309
+ " --title <text> Page title (create only)",
310
+ " --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)",
314
+ " --message <text> Version commit message",
315
+ " --limit <n> Max results for search (default: 8, max: 20)",
316
+ " --output <path> Output path for pull (default: <tmpdir>/canary/docs/<slug>.md)",
317
+ " --json Output as JSON (list, history, search)",
318
+ " --env <env> Target environment (prod, dev)",
319
+ " --api-url <url> API URL override",
320
+ " --token <key> API token override"
321
+ ].join("\n")
322
+ );
323
+ }
324
+ async function runDocs(argv) {
325
+ const [subCommand, ...rest] = argv;
326
+ if (!subCommand || subCommand === "help" || hasFlag(argv, "--help", "-h")) {
327
+ printDocsHelp();
328
+ return;
329
+ }
330
+ const { apiUrl, token } = await resolveConfig(argv);
331
+ const orgMode = hasFlag(rest, "--org");
332
+ switch (subCommand) {
333
+ case "list":
334
+ await handleList(rest, apiUrl, token, orgMode);
335
+ break;
336
+ case "get":
337
+ await handleGet(rest, apiUrl, token, orgMode);
338
+ break;
339
+ case "search":
340
+ await handleSearch(rest, apiUrl, token, orgMode);
341
+ break;
342
+ case "pull":
343
+ await handlePull(rest, apiUrl, token, orgMode);
344
+ break;
345
+ case "push":
346
+ await handlePush(rest, apiUrl, token, orgMode);
347
+ break;
348
+ case "history":
349
+ await handleHistory(rest, apiUrl, token, orgMode);
350
+ break;
351
+ case "create":
352
+ await handleCreate(rest, apiUrl, token, orgMode);
353
+ break;
354
+ case "delete":
355
+ await handleDelete(rest, apiUrl, token, orgMode);
356
+ break;
357
+ default:
358
+ console.error(`Unknown sub-command: ${subCommand}`);
359
+ printDocsHelp();
360
+ process.exit(1);
361
+ }
362
+ }
363
+ export {
364
+ runDocs
365
+ };
366
+ //# sourceMappingURL=docs-3SSORHB5.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) out.navSection = section;\n if (group != null) out.navGroup = group;\n if (order != null) {\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\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 ' --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 ' --section <text> Sidebar section (data-driven nav; create/push)',\n ' --group <text> Sidebar sub-group within the section (create/push)',\n ' --order <n> Sort order within the section/group (create/push)',\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 default:\n console.error(`Unknown sub-command: ${subCommand}`);\n printDocsHelp();\n process.exit(1);\n }\n}\n"],"mappings":"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","names":["body"]}
@@ -0,0 +1,132 @@
1
+ import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
+ import {
3
+ apiFetch,
4
+ decodeJwtPayload
5
+ } from "./chunk-3CZU7XCS.js";
6
+ import {
7
+ ENV_URLS,
8
+ envToProfile,
9
+ getArgValue,
10
+ readStoredAuth
11
+ } from "./chunk-A4OFTUVV.js";
12
+ import "./chunk-VKVL7WBN.js";
13
+
14
+ // src/doctor.ts
15
+ import process from "process";
16
+ var DEFAULT_PROBES = [
17
+ { name: "GET /me", path: "/me" },
18
+ { name: "GET /org/credentials", path: "/org/credentials" },
19
+ { name: "GET /org/properties", path: "/org/properties" }
20
+ ];
21
+ function fmtExp(expSec) {
22
+ if (!expSec) return "unknown";
23
+ const now = Math.floor(Date.now() / 1e3);
24
+ const deltaSec = expSec - now;
25
+ const date = new Date(expSec * 1e3).toISOString();
26
+ if (deltaSec < 0) return `${date} (expired ${Math.abs(deltaSec)}s ago)`;
27
+ const days = Math.round(deltaSec / 86400);
28
+ return `${date} (in ~${days} days)`;
29
+ }
30
+ function truncateId(id) {
31
+ if (!id) return "(n/a)";
32
+ return id.length > 8 ? `${id.slice(0, 8)}\u2026` : id;
33
+ }
34
+ async function runAuthDoctor(argv) {
35
+ const env = getArgValue(argv, "--env");
36
+ const profile = env ? envToProfile(env) : void 0;
37
+ const apiUrlOverride = getArgValue(argv, "--api-url") ?? process.env.CANARY_API_URL;
38
+ const stored = await readStoredAuth(profile);
39
+ const token = process.env.CANARY_API_TOKEN ?? stored?.token;
40
+ const apiUrl = apiUrlOverride ?? (env && ENV_URLS[env]?.api) ?? stored?.apiUrl ?? "https://api.trycanary.ai";
41
+ console.log("\u2500\u2500 canary auth doctor \u2500\u2500");
42
+ console.log(`node: ${process.version}`);
43
+ console.log(`platform: ${process.platform}`);
44
+ console.log(`api url: ${apiUrl}`);
45
+ console.log(`profile: ${profile ?? "(default)"}`);
46
+ console.log(`token source: ${process.env.CANARY_API_TOKEN ? "CANARY_API_TOKEN env" : stored?.token ? "auth.json" : "NONE"}`);
47
+ console.log(
48
+ `NODE_EXTRA_CA_CERTS: ${process.env.NODE_EXTRA_CA_CERTS ?? "(not set)"}`
49
+ );
50
+ console.log(`NODE_OPTIONS: ${process.env.NODE_OPTIONS ?? "(not set)"}`);
51
+ if (!token) {
52
+ console.log("");
53
+ console.log("No token found. Run: canary login" + (env ? ` --env ${env}` : ""));
54
+ process.exit(1);
55
+ }
56
+ const payload = decodeJwtPayload(token);
57
+ const exp = typeof payload?.exp === "number" ? payload.exp : void 0;
58
+ const sub = typeof payload?.sub === "string" ? payload.sub : void 0;
59
+ const orgId = typeof payload?.org_id === "string" ? payload.org_id : void 0;
60
+ console.log("");
61
+ console.log("\u2500\u2500 token \u2500\u2500");
62
+ console.log(`decoded: ${payload ? "ok" : "UNDECODABLE (likely corrupted file)"}`);
63
+ console.log(`sub: ${truncateId(sub)}`);
64
+ console.log(`org_id: ${truncateId(orgId)}`);
65
+ console.log(`exp: ${fmtExp(exp)}`);
66
+ console.log("");
67
+ console.log("\u2500\u2500 probes \u2500\u2500");
68
+ console.log("Each probe exercises a different path \u2014 mixed pass/fail here is the");
69
+ console.log("signal for Zscaler URL-category or DLP filtering.");
70
+ console.log("");
71
+ let hadProxyInjection = false;
72
+ let hadTls = false;
73
+ let passed = 0;
74
+ for (const probe of DEFAULT_PROBES) {
75
+ const url = `${apiUrl}${probe.path}`;
76
+ const result = await apiFetch(url, {
77
+ method: probe.method ?? "GET",
78
+ headers: { Authorization: `Bearer ${token}` },
79
+ token,
80
+ // Short per-probe timeout so one stalled endpoint doesn't block diagnosis.
81
+ timeoutMs: 1e4
82
+ });
83
+ if (result.ok) {
84
+ const rid = result.requestId ?? "(absent)";
85
+ console.log(` \u2713 ${probe.name.padEnd(28)} 200 rid=${rid}`);
86
+ passed += 1;
87
+ } else {
88
+ const f = result.failure;
89
+ const rid = f.requestId ?? "(absent)";
90
+ console.log(
91
+ ` \u2717 ${probe.name.padEnd(28)} ${f.status ?? "ERR"} [${f.kind}] rid=${rid}`
92
+ );
93
+ const firstLine = f.message.split("\n")[0];
94
+ console.log(` ${firstLine}`);
95
+ if (f.kind === "tls") hadTls = true;
96
+ if (f.kind === "html-body" || f.kind === "proxy-injected-4xx") hadProxyInjection = true;
97
+ }
98
+ }
99
+ console.log("");
100
+ console.log("\u2500\u2500 diagnosis \u2500\u2500");
101
+ if (hadTls) {
102
+ console.log("TLS verification failed on at least one probe.");
103
+ console.log(" \u2192 A corporate proxy is intercepting HTTPS. Trust the proxy root CA:");
104
+ console.log(" export NODE_EXTRA_CA_CERTS=/path/to/corporate-root.pem");
105
+ console.log(" or on Node 20+:");
106
+ console.log(" export NODE_OPTIONS=--use-system-ca");
107
+ } else if (hadProxyInjection) {
108
+ console.log("At least one response was NOT from our API (HTML body or missing");
109
+ console.log("x-canary-request-id). A proxy block page or captive portal is in the way.");
110
+ console.log(" \u2192 Share this output with your IT/Zscaler admin and ask them to");
111
+ console.log(` allowlist ${apiUrl}.`);
112
+ } else if (passed === DEFAULT_PROBES.length) {
113
+ console.log("All probes reached our API successfully. Auth + connectivity look healthy.");
114
+ console.log("If you are still seeing intermittent issues, re-run with --debug on the");
115
+ console.log("failing command: CANARY_DEBUG=1 canary <cmd> \u2026");
116
+ } else if (passed > 0) {
117
+ console.log("Mixed results: some probes reached our API, others did not.");
118
+ console.log(" \u2192 This is the classic signature of URL-category filtering at the proxy");
119
+ console.log(" (certain paths like /run, /execute are blocked while others pass)");
120
+ console.log(" or partial domain allowlisting.");
121
+ console.log(" \u2192 Share the probe table with your IT/Zscaler admin; include the exact");
122
+ console.log(' failing paths and the "[kind]" column.');
123
+ } else {
124
+ console.log("Every probe failed. Check your network connection and proxy settings,");
125
+ console.log("then retry with CANARY_DEBUG=1 canary auth doctor.");
126
+ }
127
+ if (passed < DEFAULT_PROBES.length) process.exit(1);
128
+ }
129
+ export {
130
+ runAuthDoctor
131
+ };
132
+ //# sourceMappingURL=doctor-OTSIWV6G.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';\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') ?? process.env.CANARY_API_URL;\n\n const stored = await readStoredAuth(profile);\n const token = process.env.CANARY_API_TOKEN ?? 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: ${process.env.CANARY_API_TOKEN ? 'CANARY_API_TOKEN env' : 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":[]}