specli 0.0.10 → 0.0.12

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 (334) hide show
  1. package/bin/cli.sh +27 -0
  2. package/dist/{src/ai → ai}/tools.d.ts +0 -1
  3. package/dist/ai/tools.js +161 -0
  4. package/dist/ai/tools.test.d.ts +1 -0
  5. package/dist/ai/tools.test.js +56 -0
  6. package/dist/{src/cli → cli}/auth-requirements.d.ts +0 -1
  7. package/dist/cli/auth-requirements.js +65 -0
  8. package/dist/cli/auth-requirements.test.d.ts +1 -0
  9. package/dist/cli/auth-requirements.test.js +16 -0
  10. package/dist/{src/cli → cli}/auth-schemes.d.ts +0 -1
  11. package/dist/cli/auth-schemes.js +112 -0
  12. package/dist/cli/auth-schemes.test.d.ts +1 -0
  13. package/dist/cli/auth-schemes.test.js +56 -0
  14. package/dist/{src/cli → cli}/capabilities.d.ts +0 -1
  15. package/dist/cli/capabilities.js +41 -0
  16. package/dist/cli/capabilities.test.d.ts +1 -0
  17. package/dist/cli/capabilities.test.js +84 -0
  18. package/dist/{src/cli → cli}/command-id.d.ts +0 -1
  19. package/dist/cli/command-id.js +8 -0
  20. package/dist/cli/command-id.test.d.ts +1 -0
  21. package/dist/cli/command-id.test.js +27 -0
  22. package/dist/{src/cli → cli}/command-index.d.ts +0 -1
  23. package/dist/cli/command-index.js +9 -0
  24. package/dist/{src/cli → cli}/command-model.d.ts +0 -1
  25. package/dist/cli/command-model.js +53 -0
  26. package/dist/cli/command-model.test.d.ts +1 -0
  27. package/dist/cli/command-model.test.js +40 -0
  28. package/dist/{src/cli → cli}/compile.d.ts +0 -1
  29. package/dist/cli/compile.js +79 -0
  30. package/dist/{src/cli → cli}/crypto.d.ts +0 -1
  31. package/dist/cli/crypto.js +9 -0
  32. package/dist/{src/cli → cli}/derive-name.d.ts +0 -1
  33. package/dist/cli/derive-name.js +96 -0
  34. package/dist/{src/cli → cli}/exec.d.ts +0 -1
  35. package/dist/cli/exec.js +50 -0
  36. package/dist/{src/cli → cli}/main.d.ts +0 -1
  37. package/dist/cli/main.js +177 -0
  38. package/dist/{src/cli → cli}/naming.d.ts +0 -1
  39. package/dist/cli/naming.js +191 -0
  40. package/dist/cli/naming.test.d.ts +1 -0
  41. package/dist/cli/naming.test.js +75 -0
  42. package/dist/{src/cli → cli}/operations.d.ts +0 -1
  43. package/dist/cli/operations.js +100 -0
  44. package/dist/cli/operations.test.d.ts +1 -0
  45. package/dist/cli/operations.test.js +51 -0
  46. package/dist/{src/cli → cli}/params.d.ts +0 -1
  47. package/dist/cli/params.js +36 -0
  48. package/dist/cli/params.test.d.ts +1 -0
  49. package/dist/cli/params.test.js +62 -0
  50. package/dist/{src/cli → cli}/pluralize.d.ts +0 -1
  51. package/dist/cli/pluralize.js +38 -0
  52. package/dist/{src/cli → cli}/positional.d.ts +0 -1
  53. package/dist/cli/positional.js +35 -0
  54. package/dist/cli/positional.test.d.ts +1 -0
  55. package/dist/cli/positional.test.js +60 -0
  56. package/dist/{src/cli → cli}/request-body.d.ts +0 -1
  57. package/dist/cli/request-body.js +44 -0
  58. package/dist/cli/request-body.test.d.ts +1 -0
  59. package/dist/cli/request-body.test.js +31 -0
  60. package/dist/{src/cli → cli}/runtime/argv.d.ts +0 -1
  61. package/dist/cli/runtime/argv.js +15 -0
  62. package/dist/{src/cli → cli}/runtime/auth/resolve.d.ts +0 -1
  63. package/dist/cli/runtime/auth/resolve.js +39 -0
  64. package/dist/{src/cli → cli}/runtime/body-flags.d.ts +0 -1
  65. package/dist/cli/runtime/body-flags.js +117 -0
  66. package/dist/cli/runtime/body-flags.test.d.ts +1 -0
  67. package/dist/cli/runtime/body-flags.test.js +192 -0
  68. package/dist/{src/cli → cli}/runtime/body.d.ts +0 -1
  69. package/dist/cli/runtime/body.js +16 -0
  70. package/dist/{src/cli → cli}/runtime/collect.d.ts +0 -1
  71. package/dist/cli/runtime/collect.js +3 -0
  72. package/dist/{src/cli → cli}/runtime/compat.d.ts +0 -1
  73. package/dist/cli/runtime/compat.js +78 -0
  74. package/dist/{src/cli → cli}/runtime/context.d.ts +0 -1
  75. package/dist/cli/runtime/context.js +44 -0
  76. package/dist/{src/cli → cli}/runtime/execute.d.ts +0 -1
  77. package/dist/cli/runtime/execute.js +106 -0
  78. package/dist/{src/cli → cli}/runtime/generated.d.ts +0 -1
  79. package/dist/cli/runtime/generated.js +168 -0
  80. package/dist/{src/cli → cli}/runtime/headers.d.ts +0 -1
  81. package/dist/cli/runtime/headers.js +30 -0
  82. package/dist/{src/cli → cli}/runtime/index.d.ts +0 -1
  83. package/dist/cli/runtime/index.js +3 -0
  84. package/dist/{src/cli → cli}/runtime/profile/secrets.d.ts +0 -1
  85. package/dist/cli/runtime/profile/secrets.js +53 -0
  86. package/dist/{src/cli → cli}/runtime/profile/store.d.ts +0 -1
  87. package/dist/cli/runtime/profile/store.js +63 -0
  88. package/dist/{src/cli → cli}/runtime/request.d.ts +0 -1
  89. package/dist/cli/runtime/request.js +283 -0
  90. package/dist/cli/runtime/request.test.d.ts +1 -0
  91. package/dist/cli/runtime/request.test.js +332 -0
  92. package/dist/{src/cli → cli}/runtime/server-url.d.ts +0 -1
  93. package/dist/cli/runtime/server-url.js +28 -0
  94. package/dist/{src/cli → cli}/runtime/template.d.ts +0 -1
  95. package/dist/cli/runtime/template.js +22 -0
  96. package/dist/cli/runtime/validate/ajv.d.ts +2 -0
  97. package/dist/cli/runtime/validate/ajv.js +11 -0
  98. package/dist/{src/cli → cli}/runtime/validate/coerce.d.ts +0 -1
  99. package/dist/cli/runtime/validate/coerce.js +63 -0
  100. package/dist/cli/runtime/validate/coerce.test.d.ts +1 -0
  101. package/dist/cli/runtime/validate/coerce.test.js +75 -0
  102. package/dist/{src/cli → cli}/runtime/validate/error.d.ts +0 -1
  103. package/dist/cli/runtime/validate/error.js +19 -0
  104. package/dist/{src/cli → cli}/runtime/validate/index.d.ts +0 -1
  105. package/dist/cli/runtime/validate/index.js +4 -0
  106. package/dist/{src/cli → cli}/runtime/validate/schema.d.ts +0 -1
  107. package/dist/cli/runtime/validate/schema.js +38 -0
  108. package/dist/{src/cli → cli}/schema-shape.d.ts +0 -1
  109. package/dist/cli/schema-shape.js +34 -0
  110. package/dist/{src/cli → cli}/schema.d.ts +0 -1
  111. package/dist/cli/schema.js +31 -0
  112. package/dist/{src/cli → cli}/server.d.ts +0 -1
  113. package/dist/cli/server.js +130 -0
  114. package/dist/cli/server.test.d.ts +1 -0
  115. package/dist/cli/server.test.js +49 -0
  116. package/dist/{src/cli → cli}/spec-id.d.ts +0 -1
  117. package/dist/cli/spec-id.js +8 -0
  118. package/dist/{src/cli → cli}/spec-loader.d.ts +0 -1
  119. package/dist/cli/spec-loader.js +40 -0
  120. package/dist/{src/cli → cli}/stable-json.d.ts +0 -1
  121. package/dist/cli/stable-json.js +29 -0
  122. package/dist/{src/cli → cli}/strings.d.ts +0 -1
  123. package/dist/cli/strings.js +20 -0
  124. package/dist/{src/cli → cli}/types.d.ts +0 -1
  125. package/dist/cli/types.js +3 -0
  126. package/dist/cli.d.ts +0 -1
  127. package/dist/cli.js +52 -2325
  128. package/dist/compiled.d.ts +2 -0
  129. package/{src/compiled.ts → dist/compiled.js} +8 -11
  130. package/dist/macros/env.d.ts +10 -0
  131. package/dist/macros/env.js +22 -0
  132. package/dist/macros/spec.d.ts +5 -0
  133. package/dist/macros/spec.js +16 -0
  134. package/dist/weather +0 -0
  135. package/package.json +12 -25
  136. package/cli.ts +0 -77
  137. package/dist/cli.d.ts.map +0 -1
  138. package/dist/cli.js.map +0 -53
  139. package/dist/index.d.ts +0 -2
  140. package/dist/index.d.ts.map +0 -1
  141. package/dist/index.js +0 -2032
  142. package/dist/index.js.map +0 -48
  143. package/dist/src/ai/tools.d.ts.map +0 -1
  144. package/dist/src/ai/tools.js +0 -1656
  145. package/dist/src/ai/tools.js.map +0 -45
  146. package/dist/src/cli/auth-requirements.d.ts.map +0 -1
  147. package/dist/src/cli/auth-requirements.js +0 -66
  148. package/dist/src/cli/auth-requirements.js.map +0 -10
  149. package/dist/src/cli/auth-schemes.d.ts.map +0 -1
  150. package/dist/src/cli/auth-schemes.js +0 -116
  151. package/dist/src/cli/auth-schemes.js.map +0 -11
  152. package/dist/src/cli/capabilities.d.ts.map +0 -1
  153. package/dist/src/cli/capabilities.js +0 -45
  154. package/dist/src/cli/capabilities.js.map +0 -10
  155. package/dist/src/cli/command-id.d.ts.map +0 -1
  156. package/dist/src/cli/command-id.js +0 -18
  157. package/dist/src/cli/command-id.js.map +0 -11
  158. package/dist/src/cli/command-index.d.ts.map +0 -1
  159. package/dist/src/cli/command-index.js +0 -15
  160. package/dist/src/cli/command-index.js.map +0 -10
  161. package/dist/src/cli/command-model.d.ts.map +0 -1
  162. package/dist/src/cli/command-model.js +0 -274
  163. package/dist/src/cli/command-model.js.map +0 -18
  164. package/dist/src/cli/compile.d.ts.map +0 -1
  165. package/dist/src/cli/compile.js +0 -146
  166. package/dist/src/cli/compile.js.map +0 -11
  167. package/dist/src/cli/crypto.d.ts.map +0 -1
  168. package/dist/src/cli/crypto.js +0 -15
  169. package/dist/src/cli/crypto.js.map +0 -10
  170. package/dist/src/cli/derive-name.d.ts.map +0 -1
  171. package/dist/src/cli/derive-name.js +0 -70
  172. package/dist/src/cli/derive-name.js.map +0 -10
  173. package/dist/src/cli/exec.d.ts.map +0 -1
  174. package/dist/src/cli/exec.js +0 -2077
  175. package/dist/src/cli/exec.js.map +0 -49
  176. package/dist/src/cli/main.d.ts.map +0 -1
  177. package/dist/src/cli/main.js +0 -2032
  178. package/dist/src/cli/main.js.map +0 -48
  179. package/dist/src/cli/naming.d.ts.map +0 -1
  180. package/dist/src/cli/naming.js +0 -216
  181. package/dist/src/cli/naming.js.map +0 -12
  182. package/dist/src/cli/operations.d.ts.map +0 -1
  183. package/dist/src/cli/operations.js +0 -103
  184. package/dist/src/cli/operations.js.map +0 -10
  185. package/dist/src/cli/params.d.ts.map +0 -1
  186. package/dist/src/cli/params.js +0 -79
  187. package/dist/src/cli/params.js.map +0 -12
  188. package/dist/src/cli/pluralize.d.ts.map +0 -1
  189. package/dist/src/cli/pluralize.js +0 -43
  190. package/dist/src/cli/pluralize.js.map +0 -10
  191. package/dist/src/cli/positional.d.ts.map +0 -1
  192. package/dist/src/cli/positional.js +0 -39
  193. package/dist/src/cli/positional.js.map +0 -10
  194. package/dist/src/cli/request-body.d.ts.map +0 -1
  195. package/dist/src/cli/request-body.js +0 -82
  196. package/dist/src/cli/request-body.js.map +0 -12
  197. package/dist/src/cli/runtime/argv.d.ts.map +0 -1
  198. package/dist/src/cli/runtime/argv.js +0 -22
  199. package/dist/src/cli/runtime/argv.js.map +0 -10
  200. package/dist/src/cli/runtime/auth/resolve.d.ts.map +0 -1
  201. package/dist/src/cli/runtime/auth/resolve.js +0 -38
  202. package/dist/src/cli/runtime/auth/resolve.js.map +0 -10
  203. package/dist/src/cli/runtime/body-flags.d.ts.map +0 -1
  204. package/dist/src/cli/runtime/body-flags.js +0 -86
  205. package/dist/src/cli/runtime/body-flags.js.map +0 -10
  206. package/dist/src/cli/runtime/body.d.ts.map +0 -1
  207. package/dist/src/cli/runtime/body.js +0 -40
  208. package/dist/src/cli/runtime/body.js.map +0 -11
  209. package/dist/src/cli/runtime/collect.d.ts.map +0 -1
  210. package/dist/src/cli/runtime/collect.js +0 -9
  211. package/dist/src/cli/runtime/collect.js.map +0 -10
  212. package/dist/src/cli/runtime/compat.d.ts.map +0 -1
  213. package/dist/src/cli/runtime/compat.js +0 -62
  214. package/dist/src/cli/runtime/compat.js.map +0 -10
  215. package/dist/src/cli/runtime/context.d.ts.map +0 -1
  216. package/dist/src/cli/runtime/context.js +0 -936
  217. package/dist/src/cli/runtime/context.js.map +0 -32
  218. package/dist/src/cli/runtime/execute.d.ts.map +0 -1
  219. package/dist/src/cli/runtime/execute.js +0 -670
  220. package/dist/src/cli/runtime/execute.js.map +0 -22
  221. package/dist/src/cli/runtime/generated.d.ts.map +0 -1
  222. package/dist/src/cli/runtime/generated.js +0 -869
  223. package/dist/src/cli/runtime/generated.js.map +0 -23
  224. package/dist/src/cli/runtime/headers.d.ts.map +0 -1
  225. package/dist/src/cli/runtime/headers.js +0 -36
  226. package/dist/src/cli/runtime/headers.js.map +0 -10
  227. package/dist/src/cli/runtime/index.d.ts.map +0 -1
  228. package/dist/src/cli/runtime/index.js +0 -1808
  229. package/dist/src/cli/runtime/index.js.map +0 -46
  230. package/dist/src/cli/runtime/profile/secrets.d.ts.map +0 -1
  231. package/dist/src/cli/runtime/profile/secrets.js +0 -51
  232. package/dist/src/cli/runtime/profile/secrets.js.map +0 -11
  233. package/dist/src/cli/runtime/profile/store.d.ts.map +0 -1
  234. package/dist/src/cli/runtime/profile/store.js +0 -102
  235. package/dist/src/cli/runtime/profile/store.js.map +0 -11
  236. package/dist/src/cli/runtime/request.d.ts.map +0 -1
  237. package/dist/src/cli/runtime/request.js +0 -571
  238. package/dist/src/cli/runtime/request.js.map +0 -21
  239. package/dist/src/cli/runtime/server-url.d.ts.map +0 -1
  240. package/dist/src/cli/runtime/server-url.js +0 -55
  241. package/dist/src/cli/runtime/server-url.js.map +0 -11
  242. package/dist/src/cli/runtime/template.d.ts.map +0 -1
  243. package/dist/src/cli/runtime/template.js +0 -29
  244. package/dist/src/cli/runtime/template.js.map +0 -10
  245. package/dist/src/cli/runtime/validate/ajv.d.ts +0 -3
  246. package/dist/src/cli/runtime/validate/ajv.d.ts.map +0 -1
  247. package/dist/src/cli/runtime/validate/ajv.js +0 -17
  248. package/dist/src/cli/runtime/validate/ajv.js.map +0 -10
  249. package/dist/src/cli/runtime/validate/coerce.d.ts.map +0 -1
  250. package/dist/src/cli/runtime/validate/coerce.js +0 -60
  251. package/dist/src/cli/runtime/validate/coerce.js.map +0 -10
  252. package/dist/src/cli/runtime/validate/error.d.ts.map +0 -1
  253. package/dist/src/cli/runtime/validate/error.js +0 -21
  254. package/dist/src/cli/runtime/validate/error.js.map +0 -10
  255. package/dist/src/cli/runtime/validate/index.d.ts.map +0 -1
  256. package/dist/src/cli/runtime/validate/index.js +0 -122
  257. package/dist/src/cli/runtime/validate/index.js.map +0 -13
  258. package/dist/src/cli/runtime/validate/schema.d.ts.map +0 -1
  259. package/dist/src/cli/runtime/validate/schema.js +0 -36
  260. package/dist/src/cli/runtime/validate/schema.js.map +0 -10
  261. package/dist/src/cli/schema-shape.d.ts.map +0 -1
  262. package/dist/src/cli/schema-shape.js +0 -41
  263. package/dist/src/cli/schema-shape.js.map +0 -10
  264. package/dist/src/cli/schema.d.ts.map +0 -1
  265. package/dist/src/cli/schema.js +0 -38
  266. package/dist/src/cli/schema.js.map +0 -10
  267. package/dist/src/cli/server.d.ts.map +0 -1
  268. package/dist/src/cli/server.js +0 -64
  269. package/dist/src/cli/server.js.map +0 -11
  270. package/dist/src/cli/spec-id.d.ts.map +0 -1
  271. package/dist/src/cli/spec-id.js +0 -21
  272. package/dist/src/cli/spec-id.js.map +0 -11
  273. package/dist/src/cli/spec-loader.d.ts.map +0 -1
  274. package/dist/src/cli/spec-loader.js +0 -110
  275. package/dist/src/cli/spec-loader.js.map +0 -15
  276. package/dist/src/cli/stable-json.d.ts.map +0 -1
  277. package/dist/src/cli/stable-json.js +0 -35
  278. package/dist/src/cli/stable-json.js.map +0 -10
  279. package/dist/src/cli/strings.d.ts.map +0 -1
  280. package/dist/src/cli/strings.js +0 -16
  281. package/dist/src/cli/strings.js.map +0 -10
  282. package/dist/src/cli/types.d.ts.map +0 -1
  283. package/dist/src/cli/types.js +0 -9
  284. package/dist/src/cli/types.js.map +0 -10
  285. package/index.ts +0 -1
  286. package/src/ai/tools.ts +0 -211
  287. package/src/cli/auth-requirements.ts +0 -91
  288. package/src/cli/auth-schemes.ts +0 -187
  289. package/src/cli/capabilities.ts +0 -88
  290. package/src/cli/command-id.ts +0 -16
  291. package/src/cli/command-index.ts +0 -19
  292. package/src/cli/command-model.ts +0 -128
  293. package/src/cli/compile.ts +0 -101
  294. package/src/cli/crypto.ts +0 -9
  295. package/src/cli/derive-name.ts +0 -101
  296. package/src/cli/exec.ts +0 -72
  297. package/src/cli/main.ts +0 -231
  298. package/src/cli/naming.ts +0 -224
  299. package/src/cli/operations.ts +0 -152
  300. package/src/cli/params.ts +0 -71
  301. package/src/cli/pluralize.ts +0 -41
  302. package/src/cli/positional.ts +0 -75
  303. package/src/cli/request-body.ts +0 -94
  304. package/src/cli/runtime/argv.ts +0 -14
  305. package/src/cli/runtime/auth/resolve.ts +0 -59
  306. package/src/cli/runtime/body-flags.ts +0 -176
  307. package/src/cli/runtime/body.ts +0 -24
  308. package/src/cli/runtime/collect.ts +0 -6
  309. package/src/cli/runtime/compat.ts +0 -89
  310. package/src/cli/runtime/context.ts +0 -62
  311. package/src/cli/runtime/execute.ts +0 -147
  312. package/src/cli/runtime/generated.ts +0 -242
  313. package/src/cli/runtime/headers.ts +0 -37
  314. package/src/cli/runtime/index.ts +0 -3
  315. package/src/cli/runtime/profile/secrets.ts +0 -83
  316. package/src/cli/runtime/profile/store.ts +0 -100
  317. package/src/cli/runtime/request.ts +0 -390
  318. package/src/cli/runtime/server-url.ts +0 -45
  319. package/src/cli/runtime/template.ts +0 -26
  320. package/src/cli/runtime/validate/ajv.ts +0 -13
  321. package/src/cli/runtime/validate/coerce.ts +0 -71
  322. package/src/cli/runtime/validate/error.ts +0 -29
  323. package/src/cli/runtime/validate/index.ts +0 -4
  324. package/src/cli/runtime/validate/schema.ts +0 -54
  325. package/src/cli/schema-shape.ts +0 -36
  326. package/src/cli/schema.ts +0 -76
  327. package/src/cli/server.ts +0 -88
  328. package/src/cli/spec-id.ts +0 -12
  329. package/src/cli/spec-loader.ts +0 -58
  330. package/src/cli/stable-json.ts +0 -35
  331. package/src/cli/strings.ts +0 -21
  332. package/src/cli/types.ts +0 -59
  333. package/src/macros/env.ts +0 -21
  334. package/src/macros/spec.ts +0 -17
@@ -0,0 +1,106 @@
1
+ import { buildRequest } from "./request.js";
2
+ /**
3
+ * Format an error message with a help hint.
4
+ */
5
+ function formatError(message, resourceName, actionName) {
6
+ const helpCmd = resourceName
7
+ ? `${resourceName} ${actionName} --help`
8
+ : `${actionName} --help`;
9
+ return `${message}\n\nRun '${helpCmd}' to see available options.`;
10
+ }
11
+ /**
12
+ * Execute an action and return the result as data.
13
+ * This is the core execution function used by both CLI and programmatic API.
14
+ */
15
+ export async function execute(input) {
16
+ const { request, curl } = await buildRequest({
17
+ specId: input.specId,
18
+ action: input.action,
19
+ positionalValues: input.positionalValues,
20
+ flagValues: input.flagValues,
21
+ globals: input.globals,
22
+ servers: input.servers,
23
+ authSchemes: input.authSchemes,
24
+ embeddedDefaults: input.embeddedDefaults,
25
+ bodyFlagDefs: input.bodyFlagDefs,
26
+ });
27
+ const res = await fetch(request);
28
+ const contentType = res.headers.get("content-type") ?? "";
29
+ const text = await res.text();
30
+ let body = text;
31
+ if (contentType.includes("json") && text) {
32
+ try {
33
+ body = JSON.parse(text);
34
+ }
35
+ catch {
36
+ // keep as text
37
+ }
38
+ }
39
+ return {
40
+ ok: res.ok,
41
+ status: res.status,
42
+ body,
43
+ curl,
44
+ };
45
+ }
46
+ /**
47
+ * Execute an action and write output to stdout/stderr.
48
+ * This is the CLI-facing wrapper around execute().
49
+ */
50
+ export async function executeAction(input) {
51
+ const actionName = input.action.action;
52
+ const resourceName = input.resourceName;
53
+ try {
54
+ if (input.globals.curl) {
55
+ const { curl } = await buildRequest({
56
+ specId: input.specId,
57
+ action: input.action,
58
+ positionalValues: input.positionalValues,
59
+ flagValues: input.flagValues,
60
+ globals: input.globals,
61
+ servers: input.servers,
62
+ authSchemes: input.authSchemes,
63
+ embeddedDefaults: input.embeddedDefaults,
64
+ bodyFlagDefs: input.bodyFlagDefs,
65
+ });
66
+ process.stdout.write(`${curl}\n`);
67
+ return;
68
+ }
69
+ const result = await execute(input);
70
+ if (!result.ok) {
71
+ if (input.globals.json) {
72
+ process.stdout.write(`${JSON.stringify({ status: result.status, body: result.body })}\n`);
73
+ }
74
+ else {
75
+ process.stderr.write(`HTTP ${result.status}\n`);
76
+ process.stderr.write(`${typeof result.body === "string" ? result.body : JSON.stringify(result.body, null, 2)}\n`);
77
+ }
78
+ process.exitCode = 1;
79
+ return;
80
+ }
81
+ if (input.globals.json) {
82
+ process.stdout.write(`${JSON.stringify(result.body)}\n`);
83
+ return;
84
+ }
85
+ // default (human + agent readable)
86
+ if (typeof result.body === "string") {
87
+ process.stdout.write(result.body);
88
+ if (!result.body.endsWith("\n"))
89
+ process.stdout.write("\n");
90
+ }
91
+ else {
92
+ process.stdout.write(`${JSON.stringify(result.body, null, 2)}\n`);
93
+ }
94
+ }
95
+ catch (err) {
96
+ const rawMessage = err instanceof Error ? err.message : String(err);
97
+ const message = formatError(rawMessage, resourceName, actionName);
98
+ if (input.globals.json) {
99
+ process.stdout.write(`${JSON.stringify({ error: rawMessage })}\n`);
100
+ }
101
+ else {
102
+ process.stderr.write(`error: ${message}\n`);
103
+ }
104
+ process.exitCode = 1;
105
+ }
106
+ }
@@ -11,4 +11,3 @@ export type GeneratedCliContext = {
11
11
  embeddedDefaults?: EmbeddedDefaults;
12
12
  };
13
13
  export declare function addGeneratedCommands(program: Command, context: GeneratedCliContext): void;
14
- //# sourceMappingURL=generated.d.ts.map
@@ -0,0 +1,168 @@
1
+ import { Command } from "commander";
2
+ import { generateBodyFlags } from "./body-flags.js";
3
+ import { executeAction } from "./execute.js";
4
+ import { coerceArrayInput, coerceValue } from "./validate/index.js";
5
+ /**
6
+ * Format help output that is clear for both humans and AI agents.
7
+ * Groups options into Required, Optional, and Global sections.
8
+ */
9
+ function formatCustomHelp(cmd, action, operationFlags, bodyFlagDefs) {
10
+ const lines = [];
11
+ const cmdName = cmd.name();
12
+ const parentName = cmd.parent?.name() ?? "";
13
+ const fullCmd = parentName ? `${parentName} ${cmdName}` : cmdName;
14
+ // Usage line
15
+ const positionals = action.positionals.map((p) => `<${p.name}>`).join(" ");
16
+ const usageSuffix = positionals ? ` ${positionals}` : "";
17
+ lines.push(`Usage: ${fullCmd}${usageSuffix} [options]`);
18
+ lines.push("");
19
+ // Description
20
+ const desc = action.summary ?? action.description ?? `${action.method} ${action.path}`;
21
+ lines.push(desc);
22
+ lines.push("");
23
+ // Collect all options into categories
24
+ const requiredOpts = [];
25
+ const optionalOpts = [];
26
+ // Format a single option line
27
+ const formatOpt = (flag, type, desc, required) => {
28
+ const typeStr = type === "boolean" ? "" : ` <${type}>`;
29
+ const reqMarker = required ? " (required)" : "";
30
+ return ` ${flag}${typeStr}${reqMarker}\n ${desc}`;
31
+ };
32
+ // Operation flags (query/header/path params)
33
+ for (const f of operationFlags) {
34
+ const type = f.type === "array" ? `${f.itemType ?? "string"}[]` : f.type;
35
+ const line = formatOpt(f.flag, type, f.description ?? `${f.in} parameter`, f.required);
36
+ if (f.required) {
37
+ requiredOpts.push(line);
38
+ }
39
+ else {
40
+ optionalOpts.push(line);
41
+ }
42
+ }
43
+ // Body flags
44
+ for (const def of bodyFlagDefs) {
45
+ const line = formatOpt(def.flag, def.type, def.description, def.required);
46
+ if (def.required) {
47
+ requiredOpts.push(line);
48
+ }
49
+ else {
50
+ optionalOpts.push(line);
51
+ }
52
+ }
53
+ // Required options section
54
+ if (requiredOpts.length > 0) {
55
+ lines.push("Required:");
56
+ lines.push(...requiredOpts);
57
+ lines.push("");
58
+ }
59
+ // Optional options section
60
+ if (optionalOpts.length > 0) {
61
+ lines.push("Options:");
62
+ lines.push(...optionalOpts);
63
+ lines.push("");
64
+ }
65
+ // Global options (always available)
66
+ lines.push("Global:");
67
+ lines.push(" --curl\n Print curl command instead of executing");
68
+ lines.push(" --json\n Output response as JSON");
69
+ lines.push(" --server <url>\n Override the API server URL");
70
+ lines.push(" --bearer-token <token>\n Provide auth token (or use 'login' command)");
71
+ lines.push(" -h, --help\n Show this help message");
72
+ lines.push("");
73
+ return lines.join("\n");
74
+ }
75
+ export function addGeneratedCommands(program, context) {
76
+ for (const resource of context.commands.resources) {
77
+ const resourceCmd = program
78
+ .command(resource.resource)
79
+ .description(`Operations for ${resource.resource}`);
80
+ for (const action of resource.actions) {
81
+ const cmd = resourceCmd.command(action.action);
82
+ cmd.description(action.summary ??
83
+ action.description ??
84
+ `${action.method} ${action.path}`);
85
+ for (const pos of action.positionals) {
86
+ cmd.argument(`<${pos.name}>`, pos.description);
87
+ }
88
+ for (const flag of action.flags) {
89
+ const opt = flag.flag;
90
+ const desc = flag.description ?? `${flag.in} parameter`;
91
+ if (flag.type === "boolean") {
92
+ cmd.option(opt, desc);
93
+ continue;
94
+ }
95
+ const isArray = flag.type === "array";
96
+ const itemType = flag.itemType ?? "string";
97
+ const flagType = isArray ? itemType : flag.type;
98
+ const parser = (raw) => coerceValue(raw, flagType);
99
+ if (isArray) {
100
+ const key = `${opt} <value>`;
101
+ cmd.option(key, desc, (value, prev) => {
102
+ const next = [...(prev ?? [])];
103
+ // Allow `--tags a,b` and `--tags '["a","b"]'` to expand.
104
+ const items = coerceArrayInput(value, itemType);
105
+ for (const item of items) {
106
+ next.push(item);
107
+ }
108
+ return next;
109
+ });
110
+ continue;
111
+ }
112
+ const key = `${opt} <value>`;
113
+ if (flag.required)
114
+ cmd.requiredOption(key, desc, parser);
115
+ else
116
+ cmd.option(key, desc, parser);
117
+ }
118
+ // Collect reserved flags: operation params + --curl
119
+ const operationFlagSet = new Set(action.flags.map((f) => f.flag));
120
+ const reservedFlags = new Set([...operationFlagSet, "--curl"]);
121
+ // Only --curl is a built-in flag (for debugging)
122
+ if (!operationFlagSet.has("--curl")) {
123
+ cmd.option("--curl", "Print curl command without sending");
124
+ }
125
+ // Track body flag definitions for this action
126
+ let bodyFlagDefs = [];
127
+ if (action.requestBody) {
128
+ // Generate body flags from schema (recursive with dot notation)
129
+ // Pass reserved flags to avoid conflicts with operation params and --curl
130
+ bodyFlagDefs = generateBodyFlags(action.requestBodySchema, reservedFlags);
131
+ for (const def of bodyFlagDefs) {
132
+ if (def.type === "boolean") {
133
+ cmd.option(def.flag, def.description);
134
+ }
135
+ else {
136
+ cmd.option(`${def.flag} <value>`, def.description);
137
+ }
138
+ }
139
+ }
140
+ // Custom help output for better agent/human readability
141
+ cmd.configureHelp({
142
+ formatHelp: () => formatCustomHelp(cmd, action, action.flags, bodyFlagDefs),
143
+ });
144
+ // Commander passes positional args and then the Command instance as last arg.
145
+ cmd.action(async (...args) => {
146
+ const command = args[args.length - 1];
147
+ const positionalValues = args.slice(0, -1).map((v) => String(v));
148
+ if (!(command instanceof Command)) {
149
+ throw new Error("Unexpected commander action signature");
150
+ }
151
+ const globals = command.optsWithGlobals();
152
+ const local = command.opts();
153
+ await executeAction({
154
+ action,
155
+ positionalValues,
156
+ flagValues: local,
157
+ globals,
158
+ servers: context.servers,
159
+ authSchemes: context.authSchemes,
160
+ specId: context.specId,
161
+ embeddedDefaults: context.embeddedDefaults,
162
+ bodyFlagDefs,
163
+ resourceName: resource.resource,
164
+ });
165
+ });
166
+ }
167
+ }
168
+ }
@@ -6,4 +6,3 @@ export declare function mergeHeaders(base: Headers, entries: Array<{
6
6
  name: string;
7
7
  value: string;
8
8
  }>): Headers;
9
- //# sourceMappingURL=headers.d.ts.map
@@ -0,0 +1,30 @@
1
+ export function parseHeaderInput(input) {
2
+ const trimmed = input.trim();
3
+ if (!trimmed)
4
+ throw new Error("Empty header");
5
+ // Support either "Name: Value" or "Name=Value".
6
+ const colon = trimmed.indexOf(":");
7
+ if (colon !== -1) {
8
+ const name = trimmed.slice(0, colon).trim();
9
+ const value = trimmed.slice(colon + 1).trim();
10
+ if (!name)
11
+ throw new Error("Invalid header name");
12
+ return { name, value };
13
+ }
14
+ const eq = trimmed.indexOf("=");
15
+ if (eq !== -1) {
16
+ const name = trimmed.slice(0, eq).trim();
17
+ const value = trimmed.slice(eq + 1).trim();
18
+ if (!name)
19
+ throw new Error("Invalid header name");
20
+ return { name, value };
21
+ }
22
+ throw new Error("Invalid header format. Use 'Name: Value' or 'Name=Value'.");
23
+ }
24
+ export function mergeHeaders(base, entries) {
25
+ const h = new Headers(base);
26
+ for (const { name, value } of entries) {
27
+ h.set(name, value);
28
+ }
29
+ return h;
30
+ }
@@ -1,4 +1,3 @@
1
1
  export * from "./argv.js";
2
2
  export * from "./context.js";
3
3
  export * from "./generated.js";
4
- //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ export * from "./argv.js";
2
+ export * from "./context.js";
3
+ export * from "./generated.js";
@@ -22,4 +22,3 @@ export declare function getToken(specId: string, profile: string): Promise<strin
22
22
  * In Node.js: returns false (secrets not supported)
23
23
  */
24
24
  export declare function deleteToken(specId: string, profile: string): Promise<boolean>;
25
- //# sourceMappingURL=secrets.d.ts.map
@@ -0,0 +1,53 @@
1
+ import { isBun } from "../compat.js";
2
+ const bunLiteral = "bun";
3
+ export function secretServiceForSpec(specId) {
4
+ return `specli:${specId}`;
5
+ }
6
+ export function tokenSecretKey(specId, profile) {
7
+ return {
8
+ service: secretServiceForSpec(specId),
9
+ name: `profile:${profile}:token`,
10
+ };
11
+ }
12
+ /**
13
+ * Store a token securely.
14
+ * In Bun: uses the native secrets store (system keychain)
15
+ * In Node.js: secrets are not supported, warns user
16
+ */
17
+ export async function setToken(specId, profile, token) {
18
+ if (!isBun) {
19
+ console.warn("Warning: Secure token storage requires Bun. Token will not be persisted.");
20
+ console.warn("Use --bearer-token <token> flag instead when running with Node.js.");
21
+ return;
22
+ }
23
+ const { secrets } = await import(bunLiteral);
24
+ const key = tokenSecretKey(specId, profile);
25
+ await secrets.set({ service: key.service, name: key.name, value: token });
26
+ }
27
+ /**
28
+ * Retrieve a stored token.
29
+ * In Bun: retrieves from the native secrets store
30
+ * In Node.js: returns null (secrets not supported)
31
+ */
32
+ export async function getToken(specId, profile) {
33
+ if (!isBun) {
34
+ return null;
35
+ }
36
+ const { secrets } = await import(bunLiteral);
37
+ const key = tokenSecretKey(specId, profile);
38
+ return await secrets.get({ service: key.service, name: key.name });
39
+ }
40
+ /**
41
+ * Delete a stored token.
42
+ * In Bun: removes from the native secrets store
43
+ * In Node.js: returns false (secrets not supported)
44
+ */
45
+ export async function deleteToken(specId, profile) {
46
+ if (!isBun) {
47
+ console.warn("Warning: Secure token storage requires Bun. No token to delete.");
48
+ return false;
49
+ }
50
+ const { secrets } = await import(bunLiteral);
51
+ const key = tokenSecretKey(specId, profile);
52
+ return await secrets.delete({ service: key.service, name: key.name });
53
+ }
@@ -12,4 +12,3 @@ export declare function writeProfiles(data: ProfilesFile): Promise<void>;
12
12
  export declare function getProfile(data: ProfilesFile, name: string | undefined): Profile | undefined;
13
13
  export declare function upsertProfile(data: ProfilesFile, profile: Profile): ProfilesFile;
14
14
  export declare function removeProfile(data: ProfilesFile, name: string): ProfilesFile;
15
- //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1,63 @@
1
+ import { fileExists, mkdirp, parseYamlContent, readFileText, writeFileText, } from "../compat.js";
2
+ function configDir() {
3
+ // Keep it simple (v1). We can move to env-paths later.
4
+ const home = process.env.HOME;
5
+ if (!home)
6
+ throw new Error("Missing HOME env var");
7
+ return `${home}/.config/specli`;
8
+ }
9
+ function configPathJson() {
10
+ return `${configDir()}/profiles.json`;
11
+ }
12
+ function configPathYaml() {
13
+ return `${configDir()}/profiles.yaml`;
14
+ }
15
+ export async function readProfiles() {
16
+ const jsonPath = configPathJson();
17
+ const yamlPath = configPathYaml();
18
+ const jsonExists = await fileExists(jsonPath);
19
+ const yamlExists = await fileExists(yamlPath);
20
+ const filePath = jsonExists ? jsonPath : yamlExists ? yamlPath : null;
21
+ if (!filePath)
22
+ return { profiles: [] };
23
+ const text = await readFileText(filePath);
24
+ let parsed;
25
+ try {
26
+ parsed = parseYamlContent(text);
27
+ }
28
+ catch {
29
+ parsed = JSON.parse(text);
30
+ }
31
+ const obj = parsed && typeof parsed === "object"
32
+ ? parsed
33
+ : {};
34
+ const profiles = Array.isArray(obj.profiles)
35
+ ? obj.profiles
36
+ : [];
37
+ return {
38
+ profiles: profiles.filter(Boolean),
39
+ defaultProfile: typeof obj.defaultProfile === "string"
40
+ ? obj.defaultProfile
41
+ : undefined,
42
+ };
43
+ }
44
+ export async function writeProfiles(data) {
45
+ const dir = configDir();
46
+ await mkdirp(dir);
47
+ await writeFileText(configPathJson(), JSON.stringify(data, null, 2));
48
+ }
49
+ export function getProfile(data, name) {
50
+ const wanted = name ?? data.defaultProfile;
51
+ if (!wanted)
52
+ return undefined;
53
+ return data.profiles.find((p) => p?.name === wanted);
54
+ }
55
+ export function upsertProfile(data, profile) {
56
+ const profiles = data.profiles.filter((p) => p.name !== profile.name);
57
+ profiles.push(profile);
58
+ profiles.sort((a, b) => a.name.localeCompare(b.name));
59
+ return { ...data, profiles };
60
+ }
61
+ export function removeProfile(data, name) {
62
+ return { ...data, profiles: data.profiles.filter((p) => p.name !== name) };
63
+ }
@@ -33,4 +33,3 @@ export declare function buildRequest(input: BuildRequestInput): Promise<{
33
33
  request: Request;
34
34
  curl: string;
35
35
  }>;
36
- //# sourceMappingURL=request.d.ts.map