@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
@@ -0,0 +1,255 @@
1
+ import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
+ import {
3
+ apiRequest,
4
+ fetchList
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/account.ts
18
+ import process from "process";
19
+ var STAGES = ["prospect", "qualified", "engaged", "trial", "active", "churned"];
20
+ function formatAccount(account) {
21
+ const linked = account.linkedOrg ? ` org=${account.linkedOrg.name}` : "";
22
+ return ` ${account.id} ${account.title} (stage=${account.stage})${linked}`;
23
+ }
24
+ async function handleList(argv, apiUrl, token) {
25
+ const jsonOutput = hasFlag(argv, "--json");
26
+ const params = new URLSearchParams();
27
+ const search = getArgValue(argv, "--search");
28
+ if (search) params.set("search", search);
29
+ const stage = getArgValue(argv, "--stage");
30
+ if (stage) params.set("stage", stage);
31
+ const query = params.toString();
32
+ const path = `/superadmin/account-board/accounts${query ? `?${query}` : ""}`;
33
+ const accounts = await fetchList(apiUrl, token, path, "accounts");
34
+ if (jsonOutput) {
35
+ console.log(JSON.stringify(accounts, null, 2));
36
+ return;
37
+ }
38
+ if (accounts.length === 0) {
39
+ console.log("No accounts found.");
40
+ return;
41
+ }
42
+ for (const account of accounts) console.log(formatAccount(account));
43
+ }
44
+ async function handleCreate(argv, apiUrl, token) {
45
+ const title = argv[0];
46
+ if (!title || title.startsWith("--")) {
47
+ console.error("Error: Missing account name.");
48
+ console.error("Usage: canary account create <name> [--description <text>] [--stage <stage>]");
49
+ process.exit(1);
50
+ }
51
+ const description = getArgValue(argv, "--description");
52
+ const stage = getArgValue(argv, "--stage");
53
+ const result = await apiRequest(
54
+ apiUrl,
55
+ token,
56
+ "POST",
57
+ "/superadmin/account-board/accounts",
58
+ {
59
+ title,
60
+ ...description !== void 0 ? { description } : {},
61
+ ...stage !== void 0 ? { stage } : {}
62
+ }
63
+ );
64
+ if (!result.ok || !result.account) {
65
+ console.error(`Error: ${result.error ?? "Failed to create account"}`);
66
+ process.exit(1);
67
+ }
68
+ console.log(`Created account ${result.account.id}: ${result.account.title} (stage=${result.account.stage})`);
69
+ }
70
+ async function handleSet(argv, apiUrl, token) {
71
+ const id = argv[0];
72
+ if (!id || id.startsWith("--")) {
73
+ console.error("Error: Missing account id.");
74
+ console.error("Usage: canary account set <id> [--title <text>] [--description <text>] [--stage <stage>]");
75
+ process.exit(1);
76
+ }
77
+ const title = getArgValue(argv, "--title");
78
+ const description = getArgValue(argv, "--description");
79
+ const stage = getArgValue(argv, "--stage");
80
+ if (title === void 0 && description === void 0 && stage === void 0) {
81
+ console.error("Error: Provide at least one of --title, --description, --stage.");
82
+ process.exit(1);
83
+ }
84
+ const result = await apiRequest(
85
+ apiUrl,
86
+ token,
87
+ "PATCH",
88
+ `/superadmin/account-board/accounts/${encodeURIComponent(id)}`,
89
+ {
90
+ ...title !== void 0 ? { title } : {},
91
+ ...description !== void 0 ? { description } : {},
92
+ ...stage !== void 0 ? { stage } : {}
93
+ }
94
+ );
95
+ if (!result.ok || !result.account) {
96
+ console.error(`Error: ${result.error ?? "Failed to update account"}`);
97
+ process.exit(1);
98
+ }
99
+ console.log(`Updated account ${result.account.id}: ${result.account.title}`);
100
+ }
101
+ async function handleDelete(argv, apiUrl, token) {
102
+ const id = argv[0];
103
+ if (!id || id.startsWith("--")) {
104
+ console.error("Error: Missing account id.");
105
+ console.error("Usage: canary account delete <id>");
106
+ process.exit(1);
107
+ }
108
+ const result = await apiRequest(
109
+ apiUrl,
110
+ token,
111
+ "DELETE",
112
+ `/superadmin/account-board/accounts/${encodeURIComponent(id)}`
113
+ );
114
+ if (!result.ok) {
115
+ console.error(`Error: ${result.error}`);
116
+ process.exit(1);
117
+ }
118
+ console.log(`Deleted account ${id}`);
119
+ }
120
+ async function handleLinkOrg(argv, apiUrl, token) {
121
+ const id = argv[0];
122
+ const orgId = getArgValue(argv, "--org");
123
+ if (!id || id.startsWith("--")) {
124
+ console.error("Error: Missing account id.");
125
+ console.error("Usage: canary account link-org <id> --org <customerOrgId>");
126
+ process.exit(1);
127
+ }
128
+ if (!orgId) {
129
+ console.error("Error: --org <customerOrgId> is required.");
130
+ process.exit(1);
131
+ }
132
+ const result = await apiRequest(
133
+ apiUrl,
134
+ token,
135
+ "PUT",
136
+ `/superadmin/account-board/accounts/${encodeURIComponent(id)}/linked-org`,
137
+ { customerOrgId: orgId }
138
+ );
139
+ if (!result.ok || !result.linkedOrg) {
140
+ console.error(`Error: ${result.error ?? "Failed to link org"}`);
141
+ process.exit(1);
142
+ }
143
+ console.log(`Linked account ${id} to org ${result.linkedOrg.name} (${result.linkedOrg.id})`);
144
+ }
145
+ async function handleUnlinkOrg(argv, apiUrl, token) {
146
+ const id = argv[0];
147
+ if (!id || id.startsWith("--")) {
148
+ console.error("Error: Missing account id.");
149
+ console.error("Usage: canary account unlink-org <id>");
150
+ process.exit(1);
151
+ }
152
+ const result = await apiRequest(
153
+ apiUrl,
154
+ token,
155
+ "DELETE",
156
+ `/superadmin/account-board/accounts/${encodeURIComponent(id)}/linked-org`
157
+ );
158
+ if (!result.ok) {
159
+ console.error(`Error: ${result.error}`);
160
+ process.exit(1);
161
+ }
162
+ console.log(`Unlinked org from account ${id}`);
163
+ }
164
+ async function handleLinkedOrg(argv, apiUrl, token) {
165
+ const id = argv[0];
166
+ const jsonOutput = hasFlag(argv, "--json");
167
+ if (!id || id.startsWith("--")) {
168
+ console.error("Usage: canary account linked-org <id>");
169
+ process.exit(1);
170
+ }
171
+ const result = await apiRequest(
172
+ apiUrl,
173
+ token,
174
+ "GET",
175
+ `/superadmin/account-board/accounts/${encodeURIComponent(id)}/linked-org`
176
+ );
177
+ if (!result.ok) {
178
+ console.error(`Error: ${result.error}`);
179
+ process.exit(1);
180
+ }
181
+ if (jsonOutput) {
182
+ console.log(JSON.stringify(result.linkedOrg ?? null, null, 2));
183
+ return;
184
+ }
185
+ console.log(
186
+ result.linkedOrg ? `Account ${id} linked to org ${result.linkedOrg.name} (${result.linkedOrg.id})` : `Account ${id} has no linked org.`
187
+ );
188
+ }
189
+ function printAccountHelp() {
190
+ console.log(
191
+ [
192
+ "Usage: canary account <sub-command> [options]",
193
+ "",
194
+ "Manage the Accounts board (cards.boardType=account) for the org you are logged into.",
195
+ "",
196
+ "Sub-commands:",
197
+ " list [--search <text>] [--stage <stage>] [--json] List accounts",
198
+ " create <name> [--description <text>] [--stage <stage>]",
199
+ " Create an account (defaults to stage=prospect)",
200
+ " set <id> [--title <text>] [--description <text>] [--stage <stage>]",
201
+ " Update an account's fields",
202
+ " delete <id> Delete an account",
203
+ " link-org <id> --org <customerOrgId> Bind the account to a customer organization",
204
+ " unlink-org <id> Remove the account's org link",
205
+ " linked-org <id> [--json] Show the account's linked org",
206
+ "",
207
+ `Stages: ${STAGES.join(", ")}`,
208
+ "",
209
+ "Options:",
210
+ " --env <env> Target environment (prod, dev, local)",
211
+ " --json Output as JSON (list/linked-org only)",
212
+ " --api-url <url> API URL override (takes precedence over --env)",
213
+ " --token <key> API token override"
214
+ ].join("\n")
215
+ );
216
+ }
217
+ async function runAccount(argv) {
218
+ const [subCommand, ...rest] = argv;
219
+ if (!subCommand || subCommand === "help" || hasFlag(argv, "--help", "-h")) {
220
+ printAccountHelp();
221
+ return;
222
+ }
223
+ const { apiUrl, token } = await resolveConfig(argv);
224
+ switch (subCommand) {
225
+ case "list":
226
+ await handleList(rest, apiUrl, token);
227
+ break;
228
+ case "create":
229
+ await handleCreate(rest, apiUrl, token);
230
+ break;
231
+ case "set":
232
+ await handleSet(rest, apiUrl, token);
233
+ break;
234
+ case "delete":
235
+ await handleDelete(rest, apiUrl, token);
236
+ break;
237
+ case "link-org":
238
+ await handleLinkOrg(rest, apiUrl, token);
239
+ break;
240
+ case "unlink-org":
241
+ await handleUnlinkOrg(rest, apiUrl, token);
242
+ break;
243
+ case "linked-org":
244
+ await handleLinkedOrg(rest, apiUrl, token);
245
+ break;
246
+ default:
247
+ console.error(`Unknown sub-command: ${subCommand}`);
248
+ printAccountHelp();
249
+ process.exit(1);
250
+ }
251
+ }
252
+ export {
253
+ runAccount
254
+ };
255
+ //# sourceMappingURL=account-22LMP5PX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/account.ts"],"sourcesContent":["/**\n * CLI Account Board Management\n *\n * Superadmin CRUD for the Accounts board (cards.boardType='account') and the\n * account↔customer-org link, scoped to the org the CLI user is logged into.\n * Backed by `/superadmin/account-board/*`.\n */\n\nimport process from 'node:process';\nimport { resolveConfig, getArgValue, hasFlag } from './auth.js';\nimport { apiRequest, fetchList } from './cli-helpers.js';\n\ntype LinkedOrgRef = { id: string; name: string };\n\ntype Account = {\n id: string;\n title: string;\n description: string;\n stage: string;\n sortOrder: number;\n linkedOrg: LinkedOrgRef | null;\n};\n\ntype AccountApiResponse = {\n ok: boolean;\n error?: string;\n account?: Account;\n linkedOrg?: LinkedOrgRef | null;\n};\n\nconst STAGES = ['prospect', 'qualified', 'engaged', 'trial', 'active', 'churned'];\n\nfunction formatAccount(account: Account): string {\n const linked = account.linkedOrg ? ` org=${account.linkedOrg.name}` : '';\n return ` ${account.id} ${account.title} (stage=${account.stage})${linked}`;\n}\n\nasync function handleList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const jsonOutput = hasFlag(argv, '--json');\n const params = new URLSearchParams();\n const search = getArgValue(argv, '--search');\n if (search) params.set('search', search);\n const stage = getArgValue(argv, '--stage');\n if (stage) params.set('stage', stage);\n const query = params.toString();\n const path = `/superadmin/account-board/accounts${query ? `?${query}` : ''}`;\n const accounts = await fetchList<Account>(apiUrl, token, path, 'accounts');\n\n if (jsonOutput) {\n console.log(JSON.stringify(accounts, null, 2));\n return;\n }\n if (accounts.length === 0) {\n console.log('No accounts found.');\n return;\n }\n for (const account of accounts) console.log(formatAccount(account));\n}\n\nasync function handleCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const title = argv[0];\n if (!title || title.startsWith('--')) {\n console.error('Error: Missing account name.');\n console.error('Usage: canary account create <name> [--description <text>] [--stage <stage>]');\n process.exit(1);\n }\n\n const description = getArgValue(argv, '--description');\n const stage = getArgValue(argv, '--stage');\n\n const result = await apiRequest<AccountApiResponse>(\n apiUrl,\n token,\n 'POST',\n '/superadmin/account-board/accounts',\n {\n title,\n ...(description !== undefined ? { description } : {}),\n ...(stage !== undefined ? { stage } : {}),\n }\n );\n\n if (!result.ok || !result.account) {\n console.error(`Error: ${result.error ?? 'Failed to create account'}`);\n process.exit(1);\n }\n console.log(`Created account ${result.account.id}: ${result.account.title} (stage=${result.account.stage})`);\n}\n\nasync function handleSet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing account id.');\n console.error('Usage: canary account set <id> [--title <text>] [--description <text>] [--stage <stage>]');\n process.exit(1);\n }\n\n const title = getArgValue(argv, '--title');\n const description = getArgValue(argv, '--description');\n const stage = getArgValue(argv, '--stage');\n\n if (title === undefined && description === undefined && stage === undefined) {\n console.error('Error: Provide at least one of --title, --description, --stage.');\n process.exit(1);\n }\n\n const result = await apiRequest<AccountApiResponse>(\n apiUrl,\n token,\n 'PATCH',\n `/superadmin/account-board/accounts/${encodeURIComponent(id)}`,\n {\n ...(title !== undefined ? { title } : {}),\n ...(description !== undefined ? { description } : {}),\n ...(stage !== undefined ? { stage } : {}),\n }\n );\n\n if (!result.ok || !result.account) {\n console.error(`Error: ${result.error ?? 'Failed to update account'}`);\n process.exit(1);\n }\n console.log(`Updated account ${result.account.id}: ${result.account.title}`);\n}\n\nasync function handleDelete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing account id.');\n console.error('Usage: canary account delete <id>');\n process.exit(1);\n }\n\n const result = await apiRequest<AccountApiResponse>(\n apiUrl,\n token,\n 'DELETE',\n `/superadmin/account-board/accounts/${encodeURIComponent(id)}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n console.log(`Deleted account ${id}`);\n}\n\nasync function handleLinkOrg(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n const orgId = getArgValue(argv, '--org');\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing account id.');\n console.error('Usage: canary account link-org <id> --org <customerOrgId>');\n process.exit(1);\n }\n if (!orgId) {\n console.error('Error: --org <customerOrgId> is required.');\n process.exit(1);\n }\n\n const result = await apiRequest<AccountApiResponse>(\n apiUrl,\n token,\n 'PUT',\n `/superadmin/account-board/accounts/${encodeURIComponent(id)}/linked-org`,\n { customerOrgId: orgId }\n );\n\n if (!result.ok || !result.linkedOrg) {\n console.error(`Error: ${result.error ?? 'Failed to link org'}`);\n process.exit(1);\n }\n console.log(`Linked account ${id} to org ${result.linkedOrg.name} (${result.linkedOrg.id})`);\n}\n\nasync function handleUnlinkOrg(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n if (!id || id.startsWith('--')) {\n console.error('Error: Missing account id.');\n console.error('Usage: canary account unlink-org <id>');\n process.exit(1);\n }\n\n const result = await apiRequest<AccountApiResponse>(\n apiUrl,\n token,\n 'DELETE',\n `/superadmin/account-board/accounts/${encodeURIComponent(id)}/linked-org`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n console.log(`Unlinked org from account ${id}`);\n}\n\nasync function handleLinkedOrg(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv[0];\n const jsonOutput = hasFlag(argv, '--json');\n if (!id || id.startsWith('--')) {\n console.error('Usage: canary account linked-org <id>');\n process.exit(1);\n }\n\n const result = await apiRequest<AccountApiResponse>(\n apiUrl,\n token,\n 'GET',\n `/superadmin/account-board/accounts/${encodeURIComponent(id)}/linked-org`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n if (jsonOutput) {\n console.log(JSON.stringify(result.linkedOrg ?? null, null, 2));\n return;\n }\n console.log(\n result.linkedOrg\n ? `Account ${id} linked to org ${result.linkedOrg.name} (${result.linkedOrg.id})`\n : `Account ${id} has no linked org.`\n );\n}\n\nfunction printAccountHelp(): void {\n console.log(\n [\n 'Usage: canary account <sub-command> [options]',\n '',\n 'Manage the Accounts board (cards.boardType=account) for the org you are logged into.',\n '',\n 'Sub-commands:',\n ' list [--search <text>] [--stage <stage>] [--json] List accounts',\n ' create <name> [--description <text>] [--stage <stage>]',\n ' Create an account (defaults to stage=prospect)',\n ' set <id> [--title <text>] [--description <text>] [--stage <stage>]',\n ' Update an account\\'s fields',\n ' delete <id> Delete an account',\n ' link-org <id> --org <customerOrgId> Bind the account to a customer organization',\n ' unlink-org <id> Remove the account\\'s org link',\n ' linked-org <id> [--json] Show the account\\'s linked org',\n '',\n `Stages: ${STAGES.join(', ')}`,\n '',\n 'Options:',\n ' --env <env> Target environment (prod, dev, local)',\n ' --json Output as JSON (list/linked-org only)',\n ' --api-url <url> API URL override (takes precedence over --env)',\n ' --token <key> API token override',\n ].join('\\n')\n );\n}\n\nexport async function runAccount(argv: string[]): Promise<void> {\n const [subCommand, ...rest] = argv;\n\n if (!subCommand || subCommand === 'help' || hasFlag(argv, '--help', '-h')) {\n printAccountHelp();\n return;\n }\n\n const { apiUrl, token } = await resolveConfig(argv);\n\n switch (subCommand) {\n case 'list':\n await handleList(rest, apiUrl, token);\n break;\n case 'create':\n await handleCreate(rest, apiUrl, token);\n break;\n case 'set':\n await handleSet(rest, apiUrl, token);\n break;\n case 'delete':\n await handleDelete(rest, apiUrl, token);\n break;\n case 'link-org':\n await handleLinkOrg(rest, apiUrl, token);\n break;\n case 'unlink-org':\n await handleUnlinkOrg(rest, apiUrl, token);\n break;\n case 'linked-org':\n await handleLinkedOrg(rest, apiUrl, token);\n break;\n default:\n console.error(`Unknown sub-command: ${subCommand}`);\n printAccountHelp();\n process.exit(1);\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,14 +1,15 @@
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
- } from "./chunk-A4OFTUVV.js";
9
+ } from "./chunk-3X3NW7QA.js";
10
+ import "./chunk-JMJVGMXI.js";
11
11
  import "./chunk-JWHYXEA2.js";
12
+ import "./chunk-JYGNMKZ5.js";
12
13
  import "./chunk-VKVL7WBN.js";
13
14
 
14
15
  // src/api-catalog.ts
@@ -398,4 +399,4 @@ function exitErr(msg) {
398
399
  export {
399
400
  runApiCatalog
400
401
  };
401
- //# sourceMappingURL=api-catalog-GFGCLVS4.js.map
402
+ //# sourceMappingURL=api-catalog-WTFQNLK6.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api-catalog.ts"],"sourcesContent":["/**\n * `canary api-catalog <sources|endpoints> <verb>` — CRUD for API catalog\n * sources (OpenAPI/Postman imports) and endpoints (aka api_requests).\n *\n * Lets a coding agent seed a catalog from scratch, search for endpoints to\n * wire into API sequences, and curate existing entries.\n *\n * @module ApiCatalogCLI\n */\n\nimport fs from 'node:fs/promises';\nimport process from 'node:process';\nimport { getArgValue, hasFlag } from './auth.js';\nimport { apiRequest } from './cli-helpers.js';\n\n/* ── Arg helpers ───────────────────────────────────────────────────────── */\n\nfunction getArg(argv: string[], key: string): string | undefined {\n const prefix = `${key}=`;\n const eq = argv.find((a) => a.startsWith(prefix));\n if (eq) return eq.slice(prefix.length);\n return getArgValue(argv, key);\n}\n\nfunction wantsJson(argv: string[]): boolean {\n if (hasFlag(argv, '--json')) return true;\n if (hasFlag(argv, '--text')) return false;\n return !process.stdout.isTTY;\n}\n\nfunction emit(argv: string[], textFallback: string, json: unknown): void {\n if (wantsJson(argv)) {\n console.log(JSON.stringify(json, null, 2));\n } else {\n console.log(textFallback);\n }\n}\n\nasync function readJsonInput(argv: string[]): Promise<unknown> {\n const fromFile = getArg(argv, '--from-file');\n let raw: string;\n if (fromFile) {\n raw = await fs.readFile(fromFile, 'utf-8');\n } else if (hasFlag(argv, '--from-stdin') || !process.stdin.isTTY) {\n raw = await readStdin();\n } else {\n throw new Error('Provide --from-file <path> or pipe JSON on stdin.');\n }\n try {\n return JSON.parse(raw);\n } catch {\n throw new Error('Invalid JSON input.');\n }\n}\n\nfunction readStdin(): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n process.stdin.on('data', (chunk) => {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);\n });\n process.stdin.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));\n process.stdin.on('error', reject);\n });\n}\n\nfunction positional(argv: string[]): string[] {\n return argv.filter((a) => !a.startsWith('-'));\n}\n\n/* ── Types ─────────────────────────────────────────────────────────────── */\n\ninterface GenericResponse<T = unknown> {\n ok: boolean;\n error?: string;\n data?: T;\n pagination?: unknown;\n filters?: unknown;\n meta?: unknown;\n}\n\n/* ── Entry point ───────────────────────────────────────────────────────── */\n\nexport async function runApiCatalog(\n argv: string[],\n apiUrl: string,\n token: string,\n): Promise<void> {\n const [group, ...rest] = argv;\n\n if (!group || group === 'help' || hasFlag(argv, '--help', '-h')) {\n printHelp();\n return;\n }\n\n switch (group) {\n case 'sources':\n await runSources(rest, apiUrl, token);\n break;\n case 'endpoints':\n await runEndpoints(rest, apiUrl, token);\n break;\n default:\n console.error(`Unknown group: ${group}`);\n printHelp();\n process.exit(1);\n }\n}\n\nfunction printHelp() {\n console.error(\n [\n 'Usage: canary api-catalog <sources|endpoints> <verb> [options]',\n '',\n 'Sources (OpenAPI / Postman imports):',\n ' sources list list catalog sources',\n ' sources get <id> fetch a source',\n ' sources create --from-file <f> create source + run initial import',\n ' sources patch <id> --from-file <f> update source metadata',\n ' sources refresh <id> re-sync a source',\n ' sources delete <id> delete a source',\n '',\n 'Endpoints (individual requests):',\n ' endpoints list [--search <q>] [--application <id>] [--method <m>] [--page <n>]',\n ' list/search endpoints',\n ' endpoints get <id> fetch one endpoint',\n ' endpoints create --from-file <f> create a manual endpoint',\n ' body: { method, url, propertyId, name? }',\n ' endpoints patch <id> --from-file <f> update endpoint fields (name, schemas)',\n ' endpoints delete <id> delete one endpoint',\n ' endpoints delete-many --ids a,b,c delete many endpoints',\n ' endpoints test <id> run the endpoint against its application',\n ' endpoints domains list distinct domains',\n '',\n 'Global options:',\n ' --json force JSON output',\n ' --text force pretty-text output',\n '',\n 'Input for create/patch: JSON via --from-file or stdin. Field shapes match the API route',\n 'schemas (see apps/api/src/api-catalog/*.ts for the authoritative definitions).',\n ].join('\\n'),\n );\n}\n\n/* ── Sources ───────────────────────────────────────────────────────────── */\n\nasync function runSources(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [verb, ...rest] = argv;\n switch (verb) {\n case 'list':\n await sourcesList(rest, apiUrl, token);\n break;\n case 'get':\n await sourcesGet(rest, apiUrl, token);\n break;\n case 'create':\n await sourcesCreate(rest, apiUrl, token);\n break;\n case 'patch':\n await sourcesPatch(rest, apiUrl, token);\n break;\n case 'refresh':\n await sourcesRefresh(rest, apiUrl, token);\n break;\n case 'delete':\n await sourcesDelete(rest, apiUrl, token);\n break;\n default:\n printHelp();\n process.exit(verb ? 1 : 0);\n }\n}\n\nasync function sourcesList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const result = await apiRequest<GenericResponse<unknown[]>>(\n apiUrl,\n token,\n 'GET',\n '/api-catalog-sources',\n );\n if (!result.ok) exitErr(result.error);\n const sources = (result.data ?? []) as Array<Record<string, unknown>>;\n const text =\n sources.length === 0\n ? 'No sources.'\n : sources\n .map((s) => {\n const id = String(s.id ?? '?');\n const name = String(s.name ?? '(unnamed)');\n const format = String(s.format ?? '?');\n const count = s.lastEndpointCount ?? '-';\n const status = String(s.lastSyncStatus ?? '?');\n return `${id} ${name.padEnd(30)} ${format.padEnd(10)} ${count} endpoints (${status})`;\n })\n .join('\\n');\n emit(argv, text, result);\n}\n\nasync function sourcesGet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = positional(argv);\n if (!id) exitErr('Missing source ID.');\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'GET',\n `/api-catalog-sources/${id}`,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, JSON.stringify(result.data, null, 2), result);\n}\n\nasync function sourcesCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n let body: unknown;\n try {\n body = await readJsonInput(argv);\n } catch (err) {\n exitErr(err instanceof Error ? err.message : String(err));\n }\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'POST',\n '/api-catalog-sources',\n body as Record<string, unknown>,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, 'Source created.', result);\n}\n\nasync function sourcesPatch(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = positional(argv);\n if (!id) exitErr('Missing source ID.');\n let body: unknown;\n try {\n body = await readJsonInput(argv);\n } catch (err) {\n exitErr(err instanceof Error ? err.message : String(err));\n }\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'PATCH',\n `/api-catalog-sources/${id}`,\n body as Record<string, unknown>,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, `Source ${id} patched.`, result);\n}\n\nasync function sourcesRefresh(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = positional(argv);\n if (!id) exitErr('Missing source ID.');\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'POST',\n `/api-catalog-sources/${id}/refresh`,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, `Source ${id} refreshed.`, result);\n}\n\nasync function sourcesDelete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = positional(argv);\n if (!id) exitErr('Missing source ID.');\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'DELETE',\n `/api-catalog-sources/${id}`,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, `Source ${id} deleted.`, result);\n}\n\n/* ── Endpoints ─────────────────────────────────────────────────────────── */\n\nasync function runEndpoints(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [verb, ...rest] = argv;\n switch (verb) {\n case 'list':\n await endpointsList(rest, apiUrl, token);\n break;\n case 'get':\n await endpointsGet(rest, apiUrl, token);\n break;\n case 'create':\n await endpointsCreate(rest, apiUrl, token);\n break;\n case 'patch':\n await endpointsPatch(rest, apiUrl, token);\n break;\n case 'delete':\n await endpointsDelete(rest, apiUrl, token);\n break;\n case 'delete-many':\n await endpointsDeleteMany(rest, apiUrl, token);\n break;\n case 'test':\n await endpointsTest(rest, apiUrl, token);\n break;\n case 'domains':\n await endpointsDomains(rest, apiUrl, token);\n break;\n default:\n printHelp();\n process.exit(verb ? 1 : 0);\n }\n}\n\nasync function endpointsList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const params = new URLSearchParams();\n const search = getArg(argv, '--search');\n const propertyId = getArg(argv, '--application') ?? getArg(argv, '--property');\n const method = getArg(argv, '--method');\n const page = getArg(argv, '--page');\n const pageSize = getArg(argv, '--page-size');\n if (search) params.set('search', search);\n if (propertyId) params.set('propertyId', propertyId);\n if (method) params.set('method', method);\n if (page) params.set('page', page);\n if (pageSize) params.set('pageSize', pageSize);\n\n const qs = params.toString();\n const result = await apiRequest<GenericResponse<Array<Record<string, unknown>>>>(\n apiUrl,\n token,\n 'GET',\n `/api-requests${qs ? `?${qs}` : ''}`,\n );\n if (!result.ok) exitErr(result.error);\n\n const items = (result.data ?? []) as Array<Record<string, unknown>>;\n const text =\n items.length === 0\n ? 'No endpoints.'\n : items\n .map((ep) => {\n const id = String(ep.id ?? '?');\n const method = String(ep.method ?? '?').toUpperCase().padEnd(6);\n const url = String(ep.url ?? ep.path ?? '');\n const name = ep.name ? ` — ${String(ep.name)}` : '';\n return `${id} ${method} ${url}${name}`;\n })\n .join('\\n');\n emit(argv, text, result);\n}\n\nasync function endpointsGet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = positional(argv);\n if (!id) exitErr('Missing endpoint ID.');\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'GET',\n `/api-requests/${id}`,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, JSON.stringify(result.data, null, 2), result);\n}\n\nasync function endpointsCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n let body: unknown;\n try {\n body = await readJsonInput(argv);\n } catch (err) {\n exitErr(err instanceof Error ? err.message : String(err));\n }\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'POST',\n '/api-requests',\n body as Record<string, unknown>,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, 'Endpoint created.', result);\n}\n\nasync function endpointsPatch(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = positional(argv);\n if (!id) exitErr('Missing endpoint ID.');\n let body: unknown;\n try {\n body = await readJsonInput(argv);\n } catch (err) {\n exitErr(err instanceof Error ? err.message : String(err));\n }\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'PATCH',\n `/api-requests/${id}`,\n body as Record<string, unknown>,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, `Endpoint ${id} patched.`, result);\n}\n\nasync function endpointsDelete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = positional(argv);\n if (!id) exitErr('Missing endpoint ID.');\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'DELETE',\n '/api-requests/bulk',\n { ids: [id] },\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, `Endpoint ${id} deleted.`, result);\n}\n\nasync function endpointsDeleteMany(\n argv: string[],\n apiUrl: string,\n token: string,\n): Promise<void> {\n const idsArg = getArg(argv, '--ids');\n if (!idsArg) exitErr('Missing --ids <a,b,c>.');\n const ids = idsArg\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n if (ids.length === 0) exitErr('No IDs provided.');\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'DELETE',\n '/api-requests/bulk',\n { ids },\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, `Deleted ${ids.length} endpoint(s).`, result);\n}\n\nasync function endpointsTest(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = positional(argv);\n if (!id) exitErr('Missing endpoint ID.');\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'POST',\n `/api-requests/${id}/test`,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, JSON.stringify(result.data, null, 2), result);\n}\n\nasync function endpointsDomains(argv: string[], apiUrl: string, token: string): Promise<void> {\n const result = await apiRequest<GenericResponse<unknown>>(\n apiUrl,\n token,\n 'GET',\n '/api-requests/domains',\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, JSON.stringify(result.data, null, 2), result);\n}\n\n/* ── Error helper ──────────────────────────────────────────────────────── */\n\nfunction exitErr(msg: string | undefined): never {\n console.error(`Error: ${msg ?? 'Unknown error'}`);\n process.exit(1);\n}\n"],"mappings":"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","names":["method"]}
1
+ {"version":3,"sources":["../src/api-catalog.ts"],"sourcesContent":["/**\n * `canary api-catalog <sources|endpoints> <verb>` — CRUD for API catalog\n * sources (OpenAPI/Postman imports) and endpoints (aka api_requests).\n *\n * Lets a coding agent seed a catalog from scratch, search for endpoints to\n * wire into API sequences, and curate existing entries.\n *\n * @module ApiCatalogCLI\n */\n\nimport fs from 'node:fs/promises';\nimport process from 'node:process';\nimport { getArgValue, hasFlag } from './auth.js';\nimport { apiRequest } from './cli-helpers.js';\n\n/* ── Arg helpers ───────────────────────────────────────────────────────── */\n\nfunction getArg(argv: string[], key: string): string | undefined {\n const prefix = `${key}=`;\n const eq = argv.find((a) => a.startsWith(prefix));\n if (eq) return eq.slice(prefix.length);\n return getArgValue(argv, key);\n}\n\nfunction wantsJson(argv: string[]): boolean {\n if (hasFlag(argv, '--json')) return true;\n if (hasFlag(argv, '--text')) return false;\n return !process.stdout.isTTY;\n}\n\nfunction emit(argv: string[], textFallback: string, json: unknown): void {\n if (wantsJson(argv)) {\n console.log(JSON.stringify(json, null, 2));\n } else {\n console.log(textFallback);\n }\n}\n\nasync function readJsonInput(argv: string[]): Promise<unknown> {\n const fromFile = getArg(argv, '--from-file');\n let raw: string;\n if (fromFile) {\n raw = await fs.readFile(fromFile, 'utf-8');\n } else if (hasFlag(argv, '--from-stdin') || !process.stdin.isTTY) {\n raw = await readStdin();\n } else {\n throw new Error('Provide --from-file <path> or pipe JSON on stdin.');\n }\n try {\n return JSON.parse(raw);\n } catch {\n throw new Error('Invalid JSON input.');\n }\n}\n\nfunction readStdin(): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n process.stdin.on('data', (chunk) => {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);\n });\n process.stdin.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));\n process.stdin.on('error', reject);\n });\n}\n\nfunction positional(argv: string[]): string[] {\n return argv.filter((a) => !a.startsWith('-'));\n}\n\n/* ── Types ─────────────────────────────────────────────────────────────── */\n\ninterface GenericResponse<T = unknown> {\n ok: boolean;\n error?: string;\n data?: T;\n pagination?: unknown;\n filters?: unknown;\n meta?: unknown;\n}\n\n/* ── Entry point ───────────────────────────────────────────────────────── */\n\nexport async function runApiCatalog(\n argv: string[],\n apiUrl: string,\n token: string,\n): Promise<void> {\n const [group, ...rest] = argv;\n\n if (!group || group === 'help' || hasFlag(argv, '--help', '-h')) {\n printHelp();\n return;\n }\n\n switch (group) {\n case 'sources':\n await runSources(rest, apiUrl, token);\n break;\n case 'endpoints':\n await runEndpoints(rest, apiUrl, token);\n break;\n default:\n console.error(`Unknown group: ${group}`);\n printHelp();\n process.exit(1);\n }\n}\n\nfunction printHelp() {\n console.error(\n [\n 'Usage: canary api-catalog <sources|endpoints> <verb> [options]',\n '',\n 'Sources (OpenAPI / Postman imports):',\n ' sources list list catalog sources',\n ' sources get <id> fetch a source',\n ' sources create --from-file <f> create source + run initial import',\n ' sources patch <id> --from-file <f> update source metadata',\n ' sources refresh <id> re-sync a source',\n ' sources delete <id> delete a source',\n '',\n 'Endpoints (individual requests):',\n ' endpoints list [--search <q>] [--application <id>] [--method <m>] [--page <n>]',\n ' list/search endpoints',\n ' endpoints get <id> fetch one endpoint',\n ' endpoints create --from-file <f> create a manual endpoint',\n ' body: { method, url, propertyId, name? }',\n ' endpoints patch <id> --from-file <f> update endpoint fields (name, schemas)',\n ' endpoints delete <id> delete one endpoint',\n ' endpoints delete-many --ids a,b,c delete many endpoints',\n ' endpoints test <id> run the endpoint against its application',\n ' endpoints domains list distinct domains',\n '',\n 'Global options:',\n ' --json force JSON output',\n ' --text force pretty-text output',\n '',\n 'Input for create/patch: JSON via --from-file or stdin. Field shapes match the API route',\n 'schemas (see apps/api/src/api-catalog/*.ts for the authoritative definitions).',\n ].join('\\n'),\n );\n}\n\n/* ── Sources ───────────────────────────────────────────────────────────── */\n\nasync function runSources(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [verb, ...rest] = argv;\n switch (verb) {\n case 'list':\n await sourcesList(rest, apiUrl, token);\n break;\n case 'get':\n await sourcesGet(rest, apiUrl, token);\n break;\n case 'create':\n await sourcesCreate(rest, apiUrl, token);\n break;\n case 'patch':\n await sourcesPatch(rest, apiUrl, token);\n break;\n case 'refresh':\n await sourcesRefresh(rest, apiUrl, token);\n break;\n case 'delete':\n await sourcesDelete(rest, apiUrl, token);\n break;\n default:\n printHelp();\n process.exit(verb ? 1 : 0);\n }\n}\n\nasync function sourcesList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const result = await apiRequest<GenericResponse<unknown[]>>(\n apiUrl,\n token,\n 'GET',\n '/api-catalog-sources',\n );\n if (!result.ok) exitErr(result.error);\n const sources = (result.data ?? []) as Array<Record<string, unknown>>;\n const text =\n sources.length === 0\n ? 'No sources.'\n : sources\n .map((s) => {\n const id = String(s.id ?? '?');\n const name = String(s.name ?? '(unnamed)');\n const format = String(s.format ?? '?');\n const count = s.lastEndpointCount ?? '-';\n const status = String(s.lastSyncStatus ?? '?');\n return `${id} ${name.padEnd(30)} ${format.padEnd(10)} ${count} endpoints (${status})`;\n })\n .join('\\n');\n emit(argv, text, result);\n}\n\nasync function sourcesGet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = positional(argv);\n if (!id) exitErr('Missing source ID.');\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'GET',\n `/api-catalog-sources/${id}`,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, JSON.stringify(result.data, null, 2), result);\n}\n\nasync function sourcesCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n let body: unknown;\n try {\n body = await readJsonInput(argv);\n } catch (err) {\n exitErr(err instanceof Error ? err.message : String(err));\n }\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'POST',\n '/api-catalog-sources',\n body as Record<string, unknown>,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, 'Source created.', result);\n}\n\nasync function sourcesPatch(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = positional(argv);\n if (!id) exitErr('Missing source ID.');\n let body: unknown;\n try {\n body = await readJsonInput(argv);\n } catch (err) {\n exitErr(err instanceof Error ? err.message : String(err));\n }\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'PATCH',\n `/api-catalog-sources/${id}`,\n body as Record<string, unknown>,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, `Source ${id} patched.`, result);\n}\n\nasync function sourcesRefresh(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = positional(argv);\n if (!id) exitErr('Missing source ID.');\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'POST',\n `/api-catalog-sources/${id}/refresh`,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, `Source ${id} refreshed.`, result);\n}\n\nasync function sourcesDelete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = positional(argv);\n if (!id) exitErr('Missing source ID.');\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'DELETE',\n `/api-catalog-sources/${id}`,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, `Source ${id} deleted.`, result);\n}\n\n/* ── Endpoints ─────────────────────────────────────────────────────────── */\n\nasync function runEndpoints(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [verb, ...rest] = argv;\n switch (verb) {\n case 'list':\n await endpointsList(rest, apiUrl, token);\n break;\n case 'get':\n await endpointsGet(rest, apiUrl, token);\n break;\n case 'create':\n await endpointsCreate(rest, apiUrl, token);\n break;\n case 'patch':\n await endpointsPatch(rest, apiUrl, token);\n break;\n case 'delete':\n await endpointsDelete(rest, apiUrl, token);\n break;\n case 'delete-many':\n await endpointsDeleteMany(rest, apiUrl, token);\n break;\n case 'test':\n await endpointsTest(rest, apiUrl, token);\n break;\n case 'domains':\n await endpointsDomains(rest, apiUrl, token);\n break;\n default:\n printHelp();\n process.exit(verb ? 1 : 0);\n }\n}\n\nasync function endpointsList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const params = new URLSearchParams();\n const search = getArg(argv, '--search');\n const propertyId = getArg(argv, '--application') ?? getArg(argv, '--property');\n const method = getArg(argv, '--method');\n const page = getArg(argv, '--page');\n const pageSize = getArg(argv, '--page-size');\n if (search) params.set('search', search);\n if (propertyId) params.set('propertyId', propertyId);\n if (method) params.set('method', method);\n if (page) params.set('page', page);\n if (pageSize) params.set('pageSize', pageSize);\n\n const qs = params.toString();\n const result = await apiRequest<GenericResponse<Array<Record<string, unknown>>>>(\n apiUrl,\n token,\n 'GET',\n `/api-requests${qs ? `?${qs}` : ''}`,\n );\n if (!result.ok) exitErr(result.error);\n\n const items = (result.data ?? []) as Array<Record<string, unknown>>;\n const text =\n items.length === 0\n ? 'No endpoints.'\n : items\n .map((ep) => {\n const id = String(ep.id ?? '?');\n const method = String(ep.method ?? '?').toUpperCase().padEnd(6);\n const url = String(ep.url ?? ep.path ?? '');\n const name = ep.name ? ` — ${String(ep.name)}` : '';\n return `${id} ${method} ${url}${name}`;\n })\n .join('\\n');\n emit(argv, text, result);\n}\n\nasync function endpointsGet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = positional(argv);\n if (!id) exitErr('Missing endpoint ID.');\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'GET',\n `/api-requests/${id}`,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, JSON.stringify(result.data, null, 2), result);\n}\n\nasync function endpointsCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n let body: unknown;\n try {\n body = await readJsonInput(argv);\n } catch (err) {\n exitErr(err instanceof Error ? err.message : String(err));\n }\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'POST',\n '/api-requests',\n body as Record<string, unknown>,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, 'Endpoint created.', result);\n}\n\nasync function endpointsPatch(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = positional(argv);\n if (!id) exitErr('Missing endpoint ID.');\n let body: unknown;\n try {\n body = await readJsonInput(argv);\n } catch (err) {\n exitErr(err instanceof Error ? err.message : String(err));\n }\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'PATCH',\n `/api-requests/${id}`,\n body as Record<string, unknown>,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, `Endpoint ${id} patched.`, result);\n}\n\nasync function endpointsDelete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = positional(argv);\n if (!id) exitErr('Missing endpoint ID.');\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'DELETE',\n '/api-requests/bulk',\n { ids: [id] },\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, `Endpoint ${id} deleted.`, result);\n}\n\nasync function endpointsDeleteMany(\n argv: string[],\n apiUrl: string,\n token: string,\n): Promise<void> {\n const idsArg = getArg(argv, '--ids');\n if (!idsArg) exitErr('Missing --ids <a,b,c>.');\n const ids = idsArg\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n if (ids.length === 0) exitErr('No IDs provided.');\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'DELETE',\n '/api-requests/bulk',\n { ids },\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, `Deleted ${ids.length} endpoint(s).`, result);\n}\n\nasync function endpointsTest(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [id] = positional(argv);\n if (!id) exitErr('Missing endpoint ID.');\n const result = await apiRequest<GenericResponse>(\n apiUrl,\n token,\n 'POST',\n `/api-requests/${id}/test`,\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, JSON.stringify(result.data, null, 2), result);\n}\n\nasync function endpointsDomains(argv: string[], apiUrl: string, token: string): Promise<void> {\n const result = await apiRequest<GenericResponse<unknown>>(\n apiUrl,\n token,\n 'GET',\n '/api-requests/domains',\n );\n if (!result.ok) exitErr(result.error);\n emit(argv, JSON.stringify(result.data, null, 2), result);\n}\n\n/* ── Error helper ──────────────────────────────────────────────────────── */\n\nfunction exitErr(msg: string | undefined): never {\n console.error(`Error: ${msg ?? 'Unknown error'}`);\n process.exit(1);\n}\n"],"mappings":"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","names":["method"]}
@@ -1,15 +1,16 @@
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 "./chunk-JWHYXEA2.js";
13
+ import "./chunk-JYGNMKZ5.js";
13
14
  import "./chunk-VKVL7WBN.js";
14
15
 
15
16
  // src/attachment.ts
@@ -273,4 +274,4 @@ async function runAttachment(argv) {
273
274
  export {
274
275
  runAttachment
275
276
  };
276
- //# sourceMappingURL=attachment-SJC7D7FY.js.map
277
+ //# sourceMappingURL=attachment-U3NKVPEY.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/attachment.ts"],"sourcesContent":["/**\n * CLI Attachment Commands\n *\n * List, upload, fetch, and delete org-scoped attachments used by action\n * and notification nodes (config.attachmentIds).\n *\n * @module attachment\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport process from 'node:process';\nimport { resolveConfig, getArgValue, hasFlag } from './auth.js';\nimport { apiRequest } from './cli-helpers.js';\n\ntype AttachmentListItem = {\n id: string;\n filename: string;\n contentType: string;\n sizeBytes: number;\n createdAt: string;\n createdBy: string | null;\n};\n\ntype ListResponse = {\n ok: boolean;\n error?: string;\n data: AttachmentListItem[];\n pagination: { page: number; pageSize: number; totalItems: number; totalPages: number };\n};\n\ntype UploadResponse = {\n ok: boolean;\n error?: string;\n data?: AttachmentListItem[];\n};\n\ntype UrlResponse = { ok: boolean; error?: string; url?: string };\n\nconst VALID_KINDS = ['all', 'image', 'pdf', 'spreadsheet', 'data'] as const;\n\nfunction printAttachmentHelp(): void {\n console.log(\n [\n 'Usage: canary attachment <sub-command> [options]',\n '',\n 'Sub-commands:',\n ' list [options] List uploaded attachments',\n ' upload <file> [options] Upload a local file; prints the new ID',\n ' get <id> [--url] Print attachment metadata (or signed URL)',\n ' delete <id> Soft-delete an attachment',\n '',\n 'List options:',\n ' --kind <kind> Filter: all, image, pdf, spreadsheet, data (default: all)',\n ' --search <query> Search by filename',\n ' --page <n> Page number (default: 1)',\n ' --page-size <n> Page size (default: 25)',\n ' --json Output raw JSON',\n '',\n 'Upload options:',\n ' --filename <name> Override filename (default: basename of file)',\n ' --json Output raw JSON',\n '',\n 'Get options:',\n ' --url Print short-lived signed download URL',\n ' --json Output raw JSON',\n '',\n 'Tip: use the returned ID in a node\\'s `configJson.attachmentIds` array',\n 'for action or notification nodes when creating/patching workflows.',\n '',\n 'Common options:',\n ' --env <env> Target environment (prod, dev, local)',\n ' --api-url <url> API URL override',\n ' --token <key> API token override',\n ].join('\\n')\n );\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction truncate(s: string, max: number): string {\n return s.length <= max ? s : s.slice(0, max - 1) + '…';\n}\n\nasync function handleList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const kind = getArgValue(argv, '--kind');\n const search = getArgValue(argv, '--search');\n const page = getArgValue(argv, '--page');\n const pageSize = getArgValue(argv, '--page-size');\n const jsonOutput = hasFlag(argv, '--json');\n\n if (kind && !VALID_KINDS.includes(kind as (typeof VALID_KINDS)[number])) {\n console.error(`Error: invalid --kind \"${kind}\". Must be one of: ${VALID_KINDS.join(', ')}`);\n process.exit(1);\n }\n\n const params = new URLSearchParams();\n if (kind) params.set('kind', kind);\n if (search) params.set('search', search);\n if (page) params.set('page', page);\n if (pageSize) params.set('pageSize', pageSize);\n\n const qs = params.toString();\n const route = `/org/attachments${qs ? `?${qs}` : ''}`;\n const result = await apiRequest<ListResponse>(apiUrl, token, 'GET', route);\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify({ data: result.data, pagination: result.pagination }, null, 2));\n return;\n }\n\n const { data, pagination } = result;\n console.log(\n `Attachments: ${pagination.totalItems} total (page ${pagination.page}/${pagination.totalPages})\\n`\n );\n\n if (data.length === 0) {\n console.log('No attachments found.');\n return;\n }\n\n const idW = 36;\n const nameW = 40;\n const typeW = 24;\n const sizeW = 10;\n\n console.log(\n ['ID'.padEnd(idW), 'Filename'.padEnd(nameW), 'Type'.padEnd(typeW), 'Size'.padEnd(sizeW)].join(\n ' '\n )\n );\n for (const a of data) {\n console.log(\n [\n a.id.padEnd(idW),\n truncate(a.filename, nameW).padEnd(nameW),\n truncate(a.contentType, typeW).padEnd(typeW),\n formatSize(a.sizeBytes).padEnd(sizeW),\n ].join(' ')\n );\n }\n}\n\nasync function handleUpload(argv: string[], apiUrl: string, token: string): Promise<void> {\n const filePath = argv.find((a) => !a.startsWith('-'));\n if (!filePath) {\n console.error('Error: missing file path.');\n console.error('Usage: canary attachment upload <file> [--filename <name>]');\n process.exit(1);\n }\n\n const overrideName = getArgValue(argv, '--filename');\n const jsonOutput = hasFlag(argv, '--json');\n\n let buf: Buffer;\n try {\n buf = await fs.readFile(filePath);\n } catch (err) {\n console.error(`Error: failed to read ${filePath}: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n\n const filename = overrideName ?? path.basename(filePath);\n const form = new FormData();\n form.append('files', new Blob([new Uint8Array(buf)]), filename);\n\n const res = await fetch(`${apiUrl}/org/attachments`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${token}` },\n body: form,\n });\n\n if (res.status === 401) {\n console.error('Error: Unauthorized. Run: canary login');\n process.exit(1);\n }\n\n let body: UploadResponse;\n try {\n body = (await res.json()) as UploadResponse;\n } catch {\n console.error(`Error: invalid JSON response (${res.status})`);\n process.exit(1);\n }\n\n if (!body.ok || !body.data || body.data.length === 0) {\n console.error(`Error: ${body.error ?? `upload failed (${res.status})`}`);\n process.exit(1);\n }\n\n const [created] = body.data;\n\n if (jsonOutput) {\n console.log(JSON.stringify(created, null, 2));\n return;\n }\n\n console.log(`\\u2713 Uploaded ${created.filename}`);\n console.log(` ID: ${created.id}`);\n console.log(` Type: ${created.contentType}`);\n console.log(` Size: ${formatSize(created.sizeBytes)}`);\n console.log('');\n console.log('Reference in a workflow node:');\n console.log(` configJson.attachmentIds = [\"${created.id}\"]`);\n}\n\nasync function handleGet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv.find((a) => !a.startsWith('-'));\n if (!id) {\n console.error('Error: missing attachment ID.');\n console.error('Usage: canary attachment get <id> [--url]');\n process.exit(1);\n }\n\n const wantUrl = hasFlag(argv, '--url');\n const jsonOutput = hasFlag(argv, '--json');\n\n if (wantUrl) {\n const result = await apiRequest<UrlResponse>(\n apiUrl,\n token,\n 'GET',\n `/org/attachments/${id}/url`\n );\n if (!result.ok || !result.url) {\n console.error(`Error: ${result.error ?? 'failed to fetch signed URL'}`);\n process.exit(1);\n }\n if (jsonOutput) {\n console.log(JSON.stringify({ id, url: result.url }, null, 2));\n } else {\n console.log(result.url);\n }\n return;\n }\n\n // No dedicated GET by id metadata endpoint; use bulk resolve as the read path.\n const res = await fetch(`${apiUrl}/org/attachments/resolve`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({ ids: [id] }),\n });\n if (res.status === 401) {\n console.error('Error: Unauthorized. Run: canary login');\n process.exit(1);\n }\n const body = (await res.json()) as { ok: boolean; error?: string; data?: AttachmentListItem[] };\n if (!body.ok || !body.data || body.data.length === 0) {\n console.error(`Error: ${body.error ?? 'attachment not found'}`);\n process.exit(1);\n }\n const [att] = body.data;\n if (jsonOutput) {\n console.log(JSON.stringify(att, null, 2));\n return;\n }\n console.log(`${att.filename}`);\n console.log(` ID: ${att.id}`);\n console.log(` Type: ${att.contentType}`);\n console.log(` Size: ${formatSize(att.sizeBytes)}`);\n console.log(` Created: ${att.createdAt}`);\n}\n\nasync function handleDelete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv.find((a) => !a.startsWith('-'));\n if (!id) {\n console.error('Error: missing attachment ID.');\n console.error('Usage: canary attachment delete <id>');\n process.exit(1);\n }\n const jsonOutput = hasFlag(argv, '--json');\n\n const result = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'DELETE',\n `/org/attachments/${id}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'delete failed'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify({ ok: true, id }, null, 2));\n return;\n }\n console.log(`\\u2713 Deleted attachment ${id}`);\n}\n\nexport async function runAttachment(argv: string[]): Promise<void> {\n const [subCommand, ...rest] = argv;\n\n if (!subCommand || subCommand === 'help' || hasFlag(argv, '--help', '-h')) {\n printAttachmentHelp();\n return;\n }\n\n const { apiUrl, token } = await resolveConfig(rest);\n\n switch (subCommand) {\n case 'list':\n await handleList(rest, apiUrl, token);\n return;\n case 'upload':\n await handleUpload(rest, apiUrl, token);\n return;\n case 'get':\n await handleGet(rest, apiUrl, token);\n return;\n case 'delete':\n await handleDelete(rest, apiUrl, token);\n return;\n default:\n console.error(`Unknown attachment sub-command: ${subCommand}`);\n printAttachmentHelp();\n process.exit(1);\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/attachment.ts"],"sourcesContent":["/**\n * CLI Attachment Commands\n *\n * List, upload, fetch, and delete org-scoped attachments used by action\n * and notification nodes (config.attachmentIds).\n *\n * @module attachment\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport process from 'node:process';\nimport { resolveConfig, getArgValue, hasFlag } from './auth.js';\nimport { apiRequest } from './cli-helpers.js';\n\ntype AttachmentListItem = {\n id: string;\n filename: string;\n contentType: string;\n sizeBytes: number;\n createdAt: string;\n createdBy: string | null;\n};\n\ntype ListResponse = {\n ok: boolean;\n error?: string;\n data: AttachmentListItem[];\n pagination: { page: number; pageSize: number; totalItems: number; totalPages: number };\n};\n\ntype UploadResponse = {\n ok: boolean;\n error?: string;\n data?: AttachmentListItem[];\n};\n\ntype UrlResponse = { ok: boolean; error?: string; url?: string };\n\nconst VALID_KINDS = ['all', 'image', 'pdf', 'spreadsheet', 'data'] as const;\n\nfunction printAttachmentHelp(): void {\n console.log(\n [\n 'Usage: canary attachment <sub-command> [options]',\n '',\n 'Sub-commands:',\n ' list [options] List uploaded attachments',\n ' upload <file> [options] Upload a local file; prints the new ID',\n ' get <id> [--url] Print attachment metadata (or signed URL)',\n ' delete <id> Soft-delete an attachment',\n '',\n 'List options:',\n ' --kind <kind> Filter: all, image, pdf, spreadsheet, data (default: all)',\n ' --search <query> Search by filename',\n ' --page <n> Page number (default: 1)',\n ' --page-size <n> Page size (default: 25)',\n ' --json Output raw JSON',\n '',\n 'Upload options:',\n ' --filename <name> Override filename (default: basename of file)',\n ' --json Output raw JSON',\n '',\n 'Get options:',\n ' --url Print short-lived signed download URL',\n ' --json Output raw JSON',\n '',\n 'Tip: use the returned ID in a node\\'s `configJson.attachmentIds` array',\n 'for action or notification nodes when creating/patching workflows.',\n '',\n 'Common options:',\n ' --env <env> Target environment (prod, dev, local)',\n ' --api-url <url> API URL override',\n ' --token <key> API token override',\n ].join('\\n')\n );\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction truncate(s: string, max: number): string {\n return s.length <= max ? s : s.slice(0, max - 1) + '…';\n}\n\nasync function handleList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const kind = getArgValue(argv, '--kind');\n const search = getArgValue(argv, '--search');\n const page = getArgValue(argv, '--page');\n const pageSize = getArgValue(argv, '--page-size');\n const jsonOutput = hasFlag(argv, '--json');\n\n if (kind && !VALID_KINDS.includes(kind as (typeof VALID_KINDS)[number])) {\n console.error(`Error: invalid --kind \"${kind}\". Must be one of: ${VALID_KINDS.join(', ')}`);\n process.exit(1);\n }\n\n const params = new URLSearchParams();\n if (kind) params.set('kind', kind);\n if (search) params.set('search', search);\n if (page) params.set('page', page);\n if (pageSize) params.set('pageSize', pageSize);\n\n const qs = params.toString();\n const route = `/org/attachments${qs ? `?${qs}` : ''}`;\n const result = await apiRequest<ListResponse>(apiUrl, token, 'GET', route);\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify({ data: result.data, pagination: result.pagination }, null, 2));\n return;\n }\n\n const { data, pagination } = result;\n console.log(\n `Attachments: ${pagination.totalItems} total (page ${pagination.page}/${pagination.totalPages})\\n`\n );\n\n if (data.length === 0) {\n console.log('No attachments found.');\n return;\n }\n\n const idW = 36;\n const nameW = 40;\n const typeW = 24;\n const sizeW = 10;\n\n console.log(\n ['ID'.padEnd(idW), 'Filename'.padEnd(nameW), 'Type'.padEnd(typeW), 'Size'.padEnd(sizeW)].join(\n ' '\n )\n );\n for (const a of data) {\n console.log(\n [\n a.id.padEnd(idW),\n truncate(a.filename, nameW).padEnd(nameW),\n truncate(a.contentType, typeW).padEnd(typeW),\n formatSize(a.sizeBytes).padEnd(sizeW),\n ].join(' ')\n );\n }\n}\n\nasync function handleUpload(argv: string[], apiUrl: string, token: string): Promise<void> {\n const filePath = argv.find((a) => !a.startsWith('-'));\n if (!filePath) {\n console.error('Error: missing file path.');\n console.error('Usage: canary attachment upload <file> [--filename <name>]');\n process.exit(1);\n }\n\n const overrideName = getArgValue(argv, '--filename');\n const jsonOutput = hasFlag(argv, '--json');\n\n let buf: Buffer;\n try {\n buf = await fs.readFile(filePath);\n } catch (err) {\n console.error(`Error: failed to read ${filePath}: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n\n const filename = overrideName ?? path.basename(filePath);\n const form = new FormData();\n form.append('files', new Blob([new Uint8Array(buf)]), filename);\n\n const res = await fetch(`${apiUrl}/org/attachments`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${token}` },\n body: form,\n });\n\n if (res.status === 401) {\n console.error('Error: Unauthorized. Run: canary login');\n process.exit(1);\n }\n\n let body: UploadResponse;\n try {\n body = (await res.json()) as UploadResponse;\n } catch {\n console.error(`Error: invalid JSON response (${res.status})`);\n process.exit(1);\n }\n\n if (!body.ok || !body.data || body.data.length === 0) {\n console.error(`Error: ${body.error ?? `upload failed (${res.status})`}`);\n process.exit(1);\n }\n\n const [created] = body.data;\n\n if (jsonOutput) {\n console.log(JSON.stringify(created, null, 2));\n return;\n }\n\n console.log(`\\u2713 Uploaded ${created.filename}`);\n console.log(` ID: ${created.id}`);\n console.log(` Type: ${created.contentType}`);\n console.log(` Size: ${formatSize(created.sizeBytes)}`);\n console.log('');\n console.log('Reference in a workflow node:');\n console.log(` configJson.attachmentIds = [\"${created.id}\"]`);\n}\n\nasync function handleGet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv.find((a) => !a.startsWith('-'));\n if (!id) {\n console.error('Error: missing attachment ID.');\n console.error('Usage: canary attachment get <id> [--url]');\n process.exit(1);\n }\n\n const wantUrl = hasFlag(argv, '--url');\n const jsonOutput = hasFlag(argv, '--json');\n\n if (wantUrl) {\n const result = await apiRequest<UrlResponse>(\n apiUrl,\n token,\n 'GET',\n `/org/attachments/${id}/url`\n );\n if (!result.ok || !result.url) {\n console.error(`Error: ${result.error ?? 'failed to fetch signed URL'}`);\n process.exit(1);\n }\n if (jsonOutput) {\n console.log(JSON.stringify({ id, url: result.url }, null, 2));\n } else {\n console.log(result.url);\n }\n return;\n }\n\n // No dedicated GET by id metadata endpoint; use bulk resolve as the read path.\n const res = await fetch(`${apiUrl}/org/attachments/resolve`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({ ids: [id] }),\n });\n if (res.status === 401) {\n console.error('Error: Unauthorized. Run: canary login');\n process.exit(1);\n }\n const body = (await res.json()) as { ok: boolean; error?: string; data?: AttachmentListItem[] };\n if (!body.ok || !body.data || body.data.length === 0) {\n console.error(`Error: ${body.error ?? 'attachment not found'}`);\n process.exit(1);\n }\n const [att] = body.data;\n if (jsonOutput) {\n console.log(JSON.stringify(att, null, 2));\n return;\n }\n console.log(`${att.filename}`);\n console.log(` ID: ${att.id}`);\n console.log(` Type: ${att.contentType}`);\n console.log(` Size: ${formatSize(att.sizeBytes)}`);\n console.log(` Created: ${att.createdAt}`);\n}\n\nasync function handleDelete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const id = argv.find((a) => !a.startsWith('-'));\n if (!id) {\n console.error('Error: missing attachment ID.');\n console.error('Usage: canary attachment delete <id>');\n process.exit(1);\n }\n const jsonOutput = hasFlag(argv, '--json');\n\n const result = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'DELETE',\n `/org/attachments/${id}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'delete failed'}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify({ ok: true, id }, null, 2));\n return;\n }\n console.log(`\\u2713 Deleted attachment ${id}`);\n}\n\nexport async function runAttachment(argv: string[]): Promise<void> {\n const [subCommand, ...rest] = argv;\n\n if (!subCommand || subCommand === 'help' || hasFlag(argv, '--help', '-h')) {\n printAttachmentHelp();\n return;\n }\n\n const { apiUrl, token } = await resolveConfig(rest);\n\n switch (subCommand) {\n case 'list':\n await handleList(rest, apiUrl, token);\n return;\n case 'upload':\n await handleUpload(rest, apiUrl, token);\n return;\n case 'get':\n await handleGet(rest, apiUrl, token);\n return;\n case 'delete':\n await handleDelete(rest, apiUrl, token);\n return;\n default:\n console.error(`Unknown attachment sub-command: ${subCommand}`);\n printAttachmentHelp();\n process.exit(1);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AASA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,OAAO,aAAa;AA4BpB,IAAM,cAAc,CAAC,OAAO,SAAS,OAAO,eAAe,MAAM;AAEjE,SAAS,sBAA4B;AACnC,UAAQ;AAAA,IACN;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AACF;AAEA,SAAS,WAAW,OAAuB;AACzC,MAAI,QAAQ,KAAM,QAAO,GAAG,KAAK;AACjC,MAAI,QAAQ,OAAO,KAAM,QAAO,IAAI,QAAQ,MAAM,QAAQ,CAAC,CAAC;AAC5D,SAAO,IAAI,SAAS,OAAO,OAAO,QAAQ,CAAC,CAAC;AAC9C;AAEA,SAAS,SAAS,GAAW,KAAqB;AAChD,SAAO,EAAE,UAAU,MAAM,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,IAAI;AACrD;AAEA,eAAe,WAAW,MAAgB,QAAgB,OAA8B;AACtF,QAAM,OAAO,YAAY,MAAM,QAAQ;AACvC,QAAM,SAAS,YAAY,MAAM,UAAU;AAC3C,QAAM,OAAO,YAAY,MAAM,QAAQ;AACvC,QAAM,WAAW,YAAY,MAAM,aAAa;AAChD,QAAM,aAAa,QAAQ,MAAM,QAAQ;AAEzC,MAAI,QAAQ,CAAC,YAAY,SAAS,IAAoC,GAAG;AACvE,YAAQ,MAAM,0BAA0B,IAAI,sBAAsB,YAAY,KAAK,IAAI,CAAC,EAAE;AAC1F,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,IAAI,gBAAgB;AACnC,MAAI,KAAM,QAAO,IAAI,QAAQ,IAAI;AACjC,MAAI,OAAQ,QAAO,IAAI,UAAU,MAAM;AACvC,MAAI,KAAM,QAAO,IAAI,QAAQ,IAAI;AACjC,MAAI,SAAU,QAAO,IAAI,YAAY,QAAQ;AAE7C,QAAM,KAAK,OAAO,SAAS;AAC3B,QAAM,QAAQ,mBAAmB,KAAK,IAAI,EAAE,KAAK,EAAE;AACnD,QAAM,SAAS,MAAM,WAAyB,QAAQ,OAAO,OAAO,KAAK;AAEzE,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;AACtC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,YAAY;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,MAAM,OAAO,MAAM,YAAY,OAAO,WAAW,GAAG,MAAM,CAAC,CAAC;AACzF;AAAA,EACF;AAEA,QAAM,EAAE,MAAM,WAAW,IAAI;AAC7B,UAAQ;AAAA,IACN,gBAAgB,WAAW,UAAU,gBAAgB,WAAW,IAAI,IAAI,WAAW,UAAU;AAAA;AAAA,EAC/F;AAEA,MAAI,KAAK,WAAW,GAAG;AACrB,YAAQ,IAAI,uBAAuB;AACnC;AAAA,EACF;AAEA,QAAM,MAAM;AACZ,QAAM,QAAQ;AACd,QAAM,QAAQ;AACd,QAAM,QAAQ;AAEd,UAAQ;AAAA,IACN,CAAC,KAAK,OAAO,GAAG,GAAG,WAAW,OAAO,KAAK,GAAG,OAAO,OAAO,KAAK,GAAG,OAAO,OAAO,KAAK,CAAC,EAAE;AAAA,MACvF;AAAA,IACF;AAAA,EACF;AACA,aAAW,KAAK,MAAM;AACpB,YAAQ;AAAA,MACN;AAAA,QACE,EAAE,GAAG,OAAO,GAAG;AAAA,QACf,SAAS,EAAE,UAAU,KAAK,EAAE,OAAO,KAAK;AAAA,QACxC,SAAS,EAAE,aAAa,KAAK,EAAE,OAAO,KAAK;AAAA,QAC3C,WAAW,EAAE,SAAS,EAAE,OAAO,KAAK;AAAA,MACtC,EAAE,KAAK,IAAI;AAAA,IACb;AAAA,EACF;AACF;AAEA,eAAe,aAAa,MAAgB,QAAgB,OAA8B;AACxF,QAAM,WAAW,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC;AACpD,MAAI,CAAC,UAAU;AACb,YAAQ,MAAM,2BAA2B;AACzC,YAAQ,MAAM,4DAA4D;AAC1E,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,eAAe,YAAY,MAAM,YAAY;AACnD,QAAM,aAAa,QAAQ,MAAM,QAAQ;AAEzC,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,GAAG,SAAS,QAAQ;AAAA,EAClC,SAAS,KAAK;AACZ,YAAQ,MAAM,yBAAyB,QAAQ,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AACtG,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,WAAW,gBAAgB,KAAK,SAAS,QAAQ;AACvD,QAAM,OAAO,IAAI,SAAS;AAC1B,OAAK,OAAO,SAAS,IAAI,KAAK,CAAC,IAAI,WAAW,GAAG,CAAC,CAAC,GAAG,QAAQ;AAE9D,QAAM,MAAM,MAAM,MAAM,GAAG,MAAM,oBAAoB;AAAA,IACnD,QAAQ;AAAA,IACR,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,IAC5C,MAAM;AAAA,EACR,CAAC;AAED,MAAI,IAAI,WAAW,KAAK;AACtB,YAAQ,MAAM,wCAAwC;AACtD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI;AACJ,MAAI;AACF,WAAQ,MAAM,IAAI,KAAK;AAAA,EACzB,QAAQ;AACN,YAAQ,MAAM,iCAAiC,IAAI,MAAM,GAAG;AAC5D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,CAAC,KAAK,MAAM,CAAC,KAAK,QAAQ,KAAK,KAAK,WAAW,GAAG;AACpD,YAAQ,MAAM,UAAU,KAAK,SAAS,kBAAkB,IAAI,MAAM,GAAG,EAAE;AACvE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,CAAC,OAAO,IAAI,KAAK;AAEvB,MAAI,YAAY;AACd,YAAQ,IAAI,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAC5C;AAAA,EACF;AAEA,UAAQ,IAAI,mBAAmB,QAAQ,QAAQ,EAAE;AACjD,UAAQ,IAAI,SAAS,QAAQ,EAAE,EAAE;AACjC,UAAQ,IAAI,WAAW,QAAQ,WAAW,EAAE;AAC5C,UAAQ,IAAI,WAAW,WAAW,QAAQ,SAAS,CAAC,EAAE;AACtD,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,+BAA+B;AAC3C,UAAQ,IAAI,kCAAkC,QAAQ,EAAE,IAAI;AAC9D;AAEA,eAAe,UAAU,MAAgB,QAAgB,OAA8B;AACrF,QAAM,KAAK,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC;AAC9C,MAAI,CAAC,IAAI;AACP,YAAQ,MAAM,+BAA+B;AAC7C,YAAQ,MAAM,2CAA2C;AACzD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,UAAU,QAAQ,MAAM,OAAO;AACrC,QAAM,aAAa,QAAQ,MAAM,QAAQ;AAEzC,MAAI,SAAS;AACX,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA,oBAAoB,EAAE;AAAA,IACxB;AACA,QAAI,CAAC,OAAO,MAAM,CAAC,OAAO,KAAK;AAC7B,cAAQ,MAAM,UAAU,OAAO,SAAS,4BAA4B,EAAE;AACtE,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,QAAI,YAAY;AACd,cAAQ,IAAI,KAAK,UAAU,EAAE,IAAI,KAAK,OAAO,IAAI,GAAG,MAAM,CAAC,CAAC;AAAA,IAC9D,OAAO;AACL,cAAQ,IAAI,OAAO,GAAG;AAAA,IACxB;AACA;AAAA,EACF;AAGA,QAAM,MAAM,MAAM,MAAM,GAAG,MAAM,4BAA4B;AAAA,IAC3D,QAAQ;AAAA,IACR,SAAS,EAAE,eAAe,UAAU,KAAK,IAAI,gBAAgB,mBAAmB;AAAA,IAChF,MAAM,KAAK,UAAU,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;AAAA,EACpC,CAAC;AACD,MAAI,IAAI,WAAW,KAAK;AACtB,YAAQ,MAAM,wCAAwC;AACtD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,MAAI,CAAC,KAAK,MAAM,CAAC,KAAK,QAAQ,KAAK,KAAK,WAAW,GAAG;AACpD,YAAQ,MAAM,UAAU,KAAK,SAAS,sBAAsB,EAAE;AAC9D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,CAAC,GAAG,IAAI,KAAK;AACnB,MAAI,YAAY;AACd,YAAQ,IAAI,KAAK,UAAU,KAAK,MAAM,CAAC,CAAC;AACxC;AAAA,EACF;AACA,UAAQ,IAAI,GAAG,IAAI,QAAQ,EAAE;AAC7B,UAAQ,IAAI,SAAS,IAAI,EAAE,EAAE;AAC7B,UAAQ,IAAI,WAAW,IAAI,WAAW,EAAE;AACxC,UAAQ,IAAI,WAAW,WAAW,IAAI,SAAS,CAAC,EAAE;AAClD,UAAQ,IAAI,cAAc,IAAI,SAAS,EAAE;AAC3C;AAEA,eAAe,aAAa,MAAgB,QAAgB,OAA8B;AACxF,QAAM,KAAK,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC;AAC9C,MAAI,CAAC,IAAI;AACP,YAAQ,MAAM,+BAA+B;AAC7C,YAAQ,MAAM,sCAAsC;AACpD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,aAAa,QAAQ,MAAM,QAAQ;AAEzC,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,oBAAoB,EAAE;AAAA,EACxB;AAEA,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,MAAM,UAAU,OAAO,SAAS,eAAe,EAAE;AACzD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,YAAY;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,IAAI,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC;AACrD;AAAA,EACF;AACA,UAAQ,IAAI,6BAA6B,EAAE,EAAE;AAC/C;AAEA,eAAsB,cAAc,MAA+B;AACjE,QAAM,CAAC,YAAY,GAAG,IAAI,IAAI;AAE9B,MAAI,CAAC,cAAc,eAAe,UAAU,QAAQ,MAAM,UAAU,IAAI,GAAG;AACzE,wBAAoB;AACpB;AAAA,EACF;AAEA,QAAM,EAAE,QAAQ,MAAM,IAAI,MAAM,cAAc,IAAI;AAElD,UAAQ,YAAY;AAAA,IAClB,KAAK;AACH,YAAM,WAAW,MAAM,QAAQ,KAAK;AACpC;AAAA,IACF,KAAK;AACH,YAAM,aAAa,MAAM,QAAQ,KAAK;AACtC;AAAA,IACF,KAAK;AACH,YAAM,UAAU,MAAM,QAAQ,KAAK;AACnC;AAAA,IACF,KAAK;AACH,YAAM,aAAa,MAAM,QAAQ,KAAK;AACtC;AAAA,IACF;AACE,cAAQ,MAAM,mCAAmC,UAAU,EAAE;AAC7D,0BAAoB;AACpB,cAAQ,KAAK,CAAC;AAAA,EAClB;AACF;","names":[]}