@codespar/cli 0.6.2 → 0.8.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 (40) hide show
  1. package/README.md +40 -0
  2. package/dist/api.js +78 -19
  3. package/dist/api.js.map +1 -1
  4. package/dist/commands/connect.js +26 -13
  5. package/dist/commands/connect.js.map +1 -1
  6. package/dist/commands/login.js +6 -6
  7. package/dist/commands/login.js.map +1 -1
  8. package/dist/commands/logs.js +73 -77
  9. package/dist/commands/logs.js.map +1 -1
  10. package/dist/commands/mandate.js +47 -16
  11. package/dist/commands/mandate.js.map +1 -1
  12. package/dist/commands/meta-input.js +11 -0
  13. package/dist/commands/meta-input.js.map +1 -1
  14. package/dist/commands/meta-tool.js +167 -0
  15. package/dist/commands/meta-tool.js.map +1 -0
  16. package/dist/commands/resource.js +74 -0
  17. package/dist/commands/resource.js.map +1 -0
  18. package/dist/commands/servers.js +40 -14
  19. package/dist/commands/servers.js.map +1 -1
  20. package/dist/commands/sessions.js +50 -27
  21. package/dist/commands/sessions.js.map +1 -1
  22. package/dist/commands/spend.js +4 -1
  23. package/dist/commands/spend.js.map +1 -1
  24. package/dist/commands/tools.js +38 -21
  25. package/dist/commands/tools.js.map +1 -1
  26. package/dist/commands/transfer.js +4 -1
  27. package/dist/commands/transfer.js.map +1 -1
  28. package/dist/commands/wallet.js +3 -1
  29. package/dist/commands/wallet.js.map +1 -1
  30. package/dist/commands/wizard.js +2 -2
  31. package/dist/commands/wizard.js.map +1 -1
  32. package/dist/index.js +113 -14
  33. package/dist/index.js.map +1 -1
  34. package/dist/output.js +100 -0
  35. package/dist/output.js.map +1 -1
  36. package/dist/surface.js +473 -0
  37. package/dist/surface.js.map +1 -0
  38. package/dist/version.js +18 -5
  39. package/dist/version.js.map +1 -1
  40. package/package.json +1 -1
@@ -1,6 +1,28 @@
1
1
  import { ApiClient } from "../api.js";
2
2
  import { CliError } from "../config.js";
3
3
  import { info, json, kv, success } from "../output.js";
4
+ /**
5
+ * The currencies and pin kinds the consent intent declares.
6
+ *
7
+ * Written here as `const`, and assigned into the request body below, so the
8
+ * compiler compares them with the document's own enum on every build: a
9
+ * currency the API drops, or one it adds, shows up as a type error rather
10
+ * than as a 400 the user sees at the end of a mandate ceremony.
11
+ */
12
+ const CURRENCIES = ["BRL", "USD", "MXN", "COP", "ARS", "USDC", "BRLA"];
13
+ const PIN_KINDS = ["pix-key", "merchant-id", "mcc"];
14
+ function parseCurrency(raw, where) {
15
+ if (!CURRENCIES.includes(raw)) {
16
+ throw new CliError(`${where} expects one of ${CURRENCIES.join(", ")}, got "${raw}".`);
17
+ }
18
+ return raw;
19
+ }
20
+ function parsePinKind(raw) {
21
+ if (!PIN_KINDS.includes(raw)) {
22
+ throw new CliError(`--pin-kind expects one of ${PIN_KINDS.join(", ")}, got "${raw}".`);
23
+ }
24
+ return raw;
25
+ }
4
26
  /**
5
27
  * Parse `--slot CURRENCY:RAIL:CAP:PER_TX_CAP` specs into the intent.slots shape.
6
28
  * Rails never contain a colon (e.g. usdc-onchain, pix-celcoin), so a 4-way
@@ -24,7 +46,12 @@ function parseSlots(specs) {
24
46
  if (!Number.isInteger(per_tx_cap_minor) || per_tx_cap_minor <= 0) {
25
47
  throw new CliError(`--slot ${spec}: per-tx cap must be a positive integer (minor units).`);
26
48
  }
27
- return { currency, rail, cap_minor, per_tx_cap_minor };
49
+ return {
50
+ currency: parseCurrency(currency, `--slot ${spec}`),
51
+ rail,
52
+ cap_minor,
53
+ per_tx_cap_minor,
54
+ };
28
55
  });
29
56
  }
30
57
  /**
@@ -79,7 +106,7 @@ export async function mandateCreateCommand(opts) {
79
106
  else {
80
107
  primaryCapMinor = Number(opts.cap);
81
108
  primaryPerTxMinor = Number(opts.perTxCap);
82
- primaryCurrency = opts.currency;
109
+ primaryCurrency = parseCurrency(opts.currency, "--currency");
83
110
  if (!Number.isInteger(primaryCapMinor) || primaryCapMinor <= 0) {
84
111
  throw new CliError("--cap must be a positive integer in minor units (or use --slot for a multi-currency mandate).");
85
112
  }
@@ -93,27 +120,31 @@ export async function mandateCreateCommand(opts) {
93
120
  project: opts.project,
94
121
  });
95
122
  // 1. Mint the consent token (authed). slots ride along in the intent.
96
- const intent = {
97
- purpose: opts.purpose,
98
- cap_minor: primaryCapMinor,
99
- per_tx_cap_minor: primaryPerTxMinor,
100
- currency: primaryCurrency,
101
- mandate_ttl_seconds: ttl,
102
- merchant_allowlist: allowlist,
103
- merchant_pin_kind: opts.pinKind,
104
- };
105
- if (slots)
106
- intent.slots = slots;
123
+ // The body is built inline so the document checks every field of it.
107
124
  const init = await client.post("/v1/consents/init", {
108
- agent_id: opts.agent,
109
- intent,
125
+ body: {
126
+ agent_id: opts.agent,
127
+ intent: {
128
+ purpose: opts.purpose,
129
+ cap_minor: primaryCapMinor,
130
+ per_tx_cap_minor: primaryPerTxMinor,
131
+ currency: primaryCurrency,
132
+ mandate_ttl_seconds: ttl,
133
+ merchant_allowlist: allowlist,
134
+ merchant_pin_kind: parsePinKind(opts.pinKind),
135
+ ...(slots ? { slots } : {}),
136
+ },
137
+ },
110
138
  });
111
139
  // 2. Submit the consumer side → funding source(s) + signed mandate (public;
112
140
  // the token in the URL is the auth, so an extra bearer header is ignored).
113
141
  // For a multi-slot mandate the backend derives one funding source per slot
114
142
  // from intent.slots; the rail/provider_token here only satisfy the submit
115
143
  // schema (a valid rail value), so the --rail default is fine.
116
- const submit = await client.post(`/v1/consents/${encodeURIComponent(init.token)}/submit`, {
144
+ // `POST /v1/consents/{token}/submit` answers in production but the served
145
+ // OpenAPI document does not declare it, so this call cannot be checked by
146
+ // the generated table. It is one of the two entries in OFF_SPEC_PATHS.
147
+ const submit = await client.offSpec("POST", `/v1/consents/${encodeURIComponent(init.token)}/submit`, {
117
148
  consumer_id: opts.consumer,
118
149
  rail: opts.rail,
119
150
  provider_token: opts.providerToken ?? `${opts.rail}:${opts.consumer}`,
@@ -1 +1 @@
1
- {"version":3,"file":"mandate.js","sourceRoot":"","sources":["../../src/commands/mandate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mandate.js","sourceRoot":"","sources":["../../src/commands/mandate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvD;;;;;;;GAOG;AACH,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;AAGhF,MAAM,SAAS,GAAG,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,CAAU,CAAC;AAG7D,SAAS,aAAa,CAAC,GAAW,EAAE,KAAa;IAC/C,IAAI,CAAE,UAAgC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,QAAQ,CAAC,GAAG,KAAK,mBAAmB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACxF,CAAC;IACD,OAAO,GAAe,CAAC;AACzB,CAAC;AAED,SAAS,YAAY,CAAC,GAAW;IAC/B,IAAI,CAAE,SAA+B,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,QAAQ,CAAC,6BAA6B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,GAAc,CAAC;AACxB,CAAC;AAgCD;;;;GAIG;AACH,SAAS,UAAU,CAAC,KAAe;IACjC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,QAAQ,CAChB,sFAAsF,IAAI,EAAE,CAC7F,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC;QACjD,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,QAAQ,CAAC,UAAU,IAAI,mCAAmC,CAAC,CAAC;QACxE,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,gBAAgB,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,QAAQ,CAAC,UAAU,IAAI,iDAAiD,CAAC,CAAC;QACtF,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,IAAI,gBAAgB,IAAI,CAAC,EAAE,CAAC;YACjE,MAAM,IAAI,QAAQ,CAAC,UAAU,IAAI,wDAAwD,CAAC,CAAC;QAC7F,CAAC;QACD,OAAO;YACL,QAAQ,EAAE,aAAa,CAAC,QAAQ,EAAE,UAAU,IAAI,EAAE,CAAC;YACnD,IAAI;YACJ,SAAS;YACT,gBAAgB;SACjB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAA0B;IACnE,IAAI,CAAC,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,QAAQ,CAAC,8BAA8B,CAAC,CAAC;IACvE,IAAI,CAAC,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,QAAQ,CAAC,2BAA2B,CAAC,CAAC;IACjE,IAAI,CAAC,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,QAAQ,CAAC,+BAA+B,CAAC,CAAC;IACvE,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;SACjC,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,QAAQ,CAChB,0GAA0G,CAC3G,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,QAAQ,CAAC,6CAA6C,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAEhF,4EAA4E;IAC5E,6EAA6E;IAC7E,IAAI,eAAuB,CAAC;IAC5B,IAAI,iBAAyB,CAAC;IAC9B,IAAI,eAAyB,CAAC;IAC9B,IAAI,KAAK,EAAE,CAAC;QACV,eAAe,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC;QACtC,iBAAiB,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,gBAAgB,CAAC;QAC/C,eAAe,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnC,iBAAiB,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1C,eAAe,GAAG,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAC7D,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,eAAe,IAAI,CAAC,EAAE,CAAC;YAC/D,MAAM,IAAI,QAAQ,CAChB,+FAA+F,CAChG,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,iBAAiB,IAAI,CAAC,EAAE,CAAC;YACnE,MAAM,IAAI,QAAQ,CAChB,yEAAyE,CAC1E,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC;IAEH,sEAAsE;IACtE,wEAAwE;IACxE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE;QAClD,IAAI,EAAE;YACJ,QAAQ,EAAE,IAAI,CAAC,KAAK;YACpB,MAAM,EAAE;gBACN,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,SAAS,EAAE,eAAe;gBAC1B,gBAAgB,EAAE,iBAAiB;gBACnC,QAAQ,EAAE,eAAe;gBACzB,mBAAmB,EAAE,GAAG;gBACxB,kBAAkB,EAAE,SAAS;gBAC7B,iBAAiB,EAAE,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC;gBAC7C,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC5B;SACF;KACF,CAAC,CAAC;IAEH,4EAA4E;IAC5E,8EAA8E;IAC9E,8EAA8E;IAC9E,6EAA6E;IAC7E,iEAAiE;IACjE,0EAA0E;IAC1E,0EAA0E;IAC1E,uEAAuE;IACvE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CACjC,MAAM,EACN,gBAAgB,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EACvD;QACE,WAAW,EAAE,IAAI,CAAC,QAAQ;QAC1B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,cAAc,EAAE,IAAI,CAAC,aAAa,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE;KACtE,CACF,CAAC;IAEF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,IAAI,CAAC,MAAM,CAAC,CAAC;QACb,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAI,MAAM,CAAC,UAAqB,IAAI,WAAW,CAAC;IAE/D,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,4BAA4B,CAAC,CAAC;QACtC,EAAE,CAAC;YACD,CAAC,SAAS,EAAE,SAAS,CAAC;YACtB,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC;YAC3B,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC;YACrB,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC;YACzB,CAAC,WAAW,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnC;gBACE,OAAO;gBACP,KAAK;qBACF,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,SAAS,YAAY,CAAC,CAAC,gBAAgB,GAAG,CAAC;qBACvF,IAAI,CAAC,OAAO,CAAC;aACjB;SACF,CAAC,CAAC;QACH,IAAI,CACF,kBAAkB,KAAK,CAAC,MAAM,oFAAoF,IAAI,CAAC,QAAQ,iDAAiD,SAAS,YAAY,SAAS,CAAC,CAAC,CAAC,uBAAuB,IAAI,CAAC,KAAK,EAAE,CACrP,CAAC;QACF,OAAO;IACT,CAAC;IAED,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC3B,EAAE,CAAC;QACD,CAAC,SAAS,EAAE,SAAS,CAAC;QACtB,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC;QAC3B,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC;QACrB,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC;QACzB,CAAC,WAAW,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC,YAAY,EAAE,GAAG,iBAAiB,IAAI,eAAe,UAAU,CAAC;QACjE,CAAC,WAAW,EAAE,GAAG,eAAe,IAAI,eAAe,UAAU,CAAC;QAC9D,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC;KACpB,CAAC,CAAC;IACH,IAAI,CACF,iDAAiD,SAAS,YAAY,SAAS,CAAC,CAAC,CAAC,uBAAuB,IAAI,CAAC,KAAK,EAAE,CACtH,CAAC;AACJ,CAAC"}
@@ -30,4 +30,15 @@ export async function resolveMetaInput(opts, name, example) {
30
30
  throw new CliError(`${source} is not valid JSON: ${err.message}`);
31
31
  }
32
32
  }
33
+ /**
34
+ * Same two flags, but the body is optional: a GET has nothing to send and
35
+ * a POST may take an empty body. Returns `undefined` when neither flag is
36
+ * given, and throws the same way as `resolveMetaInput` when one is given
37
+ * and does not parse.
38
+ */
39
+ export async function resolveOptionalInput(opts, what) {
40
+ if (opts.input === undefined && opts.inputFile === undefined)
41
+ return undefined;
42
+ return resolveMetaInput(opts, what, "{}");
43
+ }
33
44
  //# sourceMappingURL=meta-input.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"meta-input.js","sourceRoot":"","sources":["../../src/commands/meta-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAA4C,EAC5C,IAAY,EACZ,OAAe;IAEf,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACjC,MAAM,IAAI,QAAQ,CAAC,gDAAgD,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACnC,MAAM,IAAI,QAAQ,CAChB,GAAG,IAAI,wEAAwE,OAAO,GAAG,CAC1F,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS;QACxB,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC;QACzC,CAAC,CAAE,IAAI,CAAC,KAAgB,CAAC;IAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QAC1C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3E,MAAM,IAAI,QAAQ,CAAC,GAAG,MAAM,yBAAyB,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,MAAiC,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,QAAQ;YAAE,MAAM,GAAG,CAAC;QACvC,MAAM,IAAI,QAAQ,CAAC,GAAG,MAAM,uBAAwB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"meta-input.js","sourceRoot":"","sources":["../../src/commands/meta-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAA4C,EAC5C,IAAY,EACZ,OAAe;IAEf,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACjC,MAAM,IAAI,QAAQ,CAAC,gDAAgD,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACnC,MAAM,IAAI,QAAQ,CAChB,GAAG,IAAI,wEAAwE,OAAO,GAAG,CAC1F,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS;QACxB,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC;QACzC,CAAC,CAAE,IAAI,CAAC,KAAgB,CAAC;IAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QAC1C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3E,MAAM,IAAI,QAAQ,CAAC,GAAG,MAAM,yBAAyB,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,MAAiC,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,QAAQ;YAAE,MAAM,GAAG,CAAC;QACvC,MAAM,IAAI,QAAQ,CAAC,GAAG,MAAM,uBAAwB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAA4C,EAC5C,IAAY;IAEZ,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC/E,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,167 @@
1
+ import { CodeSpar } from "@codespar/sdk";
2
+ import { CliError } from "../config.js";
3
+ import { c, info, json, kv, renderResult, table } from "../output.js";
4
+ import { resolveOptionalInput } from "./meta-input.js";
5
+ import { metaToolActions, metaToolDefinition, metaToolNames, META_TOOLS } from "../surface.js";
6
+ /**
7
+ * Resolve a tool name against the published definitions. The list in the
8
+ * error is the published list — the CLI knows of no other tool, and a
9
+ * name it cannot find is a name `@codespar/types` does not publish.
10
+ */
11
+ export function requireDefinition(name) {
12
+ const definition = metaToolDefinition(name);
13
+ if (definition)
14
+ return definition;
15
+ throw new CliError(`Unknown meta-tool "${name}". Published tools:\n ${metaToolNames().join("\n ")}`);
16
+ }
17
+ /**
18
+ * Coerce a `--arg key=value` pair against the property's published type.
19
+ * An `object` or `array` property takes JSON; everything else takes the
20
+ * literal, so a Pix key that looks like a number stays a string when the
21
+ * contract says string.
22
+ */
23
+ export function coerceArg(definition, key, raw) {
24
+ const property = definition.input_schema.properties[key];
25
+ if (!property) {
26
+ throw new CliError(`${definition.name} has no property "${key}". Published properties:\n ${definition.contract.properties.join("\n ")}`);
27
+ }
28
+ let value = raw;
29
+ if (property.type === "number" || property.type === "integer") {
30
+ const n = Number(raw);
31
+ if (!Number.isFinite(n))
32
+ throw new CliError(`${key} expects a number, got "${raw}".`);
33
+ value = n;
34
+ }
35
+ else if (property.type === "boolean") {
36
+ if (raw !== "true" && raw !== "false") {
37
+ throw new CliError(`${key} expects true or false, got "${raw}".`);
38
+ }
39
+ value = raw === "true";
40
+ }
41
+ else if (property.type === "object" || property.type === "array") {
42
+ try {
43
+ value = JSON.parse(raw);
44
+ }
45
+ catch (err) {
46
+ throw new CliError(`${key} is a ${property.type}; --arg needs valid JSON for it (or use --input): ${err.message}`);
47
+ }
48
+ }
49
+ if (property.enum && typeof value === "string" && !property.enum.includes(value)) {
50
+ throw new CliError(`${key}="${value}" is outside the published vocabulary: ${property.enum.join(" | ")}`);
51
+ }
52
+ return value;
53
+ }
54
+ /**
55
+ * Build the tool arguments from `--input`, `--arg` and `--action`, then
56
+ * check them against the published contract before anything is sent. The
57
+ * checks are the contract's own: the property names it publishes, the
58
+ * subset it marks required, and the closed vocabularies it declares. No
59
+ * vocabulary is written here — a rail or an action added to the published
60
+ * definition is accepted by this CLI without a code change.
61
+ */
62
+ export function buildArgs(definition, base, argPairs, action) {
63
+ const args = { ...(base ?? {}) };
64
+ for (const pair of argPairs) {
65
+ const eq = pair.indexOf("=");
66
+ if (eq <= 0)
67
+ throw new CliError(`--arg expects key=value, got "${pair}".`);
68
+ const key = pair.slice(0, eq);
69
+ args[key] = coerceArg(definition, key, pair.slice(eq + 1));
70
+ }
71
+ if (action !== undefined) {
72
+ const actions = metaToolActions(definition.name);
73
+ if (actions.length === 0) {
74
+ const discriminator = definition.contract.required[0];
75
+ throw new CliError(`${definition.name} publishes no "action" property, so --action means nothing to it.` +
76
+ (discriminator
77
+ ? ` Its required input is: ${definition.contract.required.join(", ")} — pass it with --arg ${discriminator}=<value> or --input.`
78
+ : ""));
79
+ }
80
+ if (!actions.includes(action)) {
81
+ throw new CliError(`${definition.name} --action "${action}" is outside the published vocabulary: ${actions.join(" | ")}`);
82
+ }
83
+ args.action = action;
84
+ }
85
+ const missing = definition.contract.required.filter((name) => args[name] === undefined || args[name] === "");
86
+ if (missing.length > 0) {
87
+ const how = missing.map((m) => {
88
+ const vocabulary = definition.contract.enums?.[m];
89
+ if (m === "action" && vocabulary)
90
+ return `--action <${vocabulary.join("|")}>`;
91
+ if (vocabulary)
92
+ return `--arg ${m}=<${vocabulary.join("|")}>`;
93
+ return `--arg ${m}=<value>`;
94
+ });
95
+ throw new CliError(`${definition.name} requires ${missing.join(", ")}. Pass ${how.join(" ")} or --input '<json>'. Nothing was sent.`);
96
+ }
97
+ return args;
98
+ }
99
+ /**
100
+ * Invoke one of the published meta-tools through a throwaway session, the
101
+ * same wire `session.execute(name, args)` uses. The router picks the rail,
102
+ * so there is no `--server`.
103
+ */
104
+ export async function metaToolCommand(name, opts) {
105
+ const definition = requireDefinition(name);
106
+ const base = await resolveOptionalInput(opts, definition.name);
107
+ const args = buildArgs(definition, base, opts.arg, opts.action);
108
+ const cs = new CodeSpar({
109
+ apiKey: opts.apiKey,
110
+ baseUrl: opts.baseUrl,
111
+ projectId: opts.project,
112
+ });
113
+ const session = await cs.create(opts.user ?? "cli-user", { servers: [] });
114
+ try {
115
+ const result = await session.execute(definition.name, args);
116
+ if (!result.success) {
117
+ throw new CliError(`${definition.name} failed: ${result.error ?? "unknown error"}`);
118
+ }
119
+ if (opts.json) {
120
+ json(result.data ?? null);
121
+ return;
122
+ }
123
+ info(`${definition.name}${args.action ? ` action=${String(args.action)}` : ""}`);
124
+ renderResult(result.data);
125
+ }
126
+ finally {
127
+ await session.close();
128
+ }
129
+ }
130
+ /** `codespar tools meta` — the published definitions, as published. */
131
+ export function listMetaToolsCommand(opts) {
132
+ if (opts.json) {
133
+ json(META_TOOLS);
134
+ return;
135
+ }
136
+ table(["TOOL", "ACTIONS", "REQUIRED"], metaToolNames().map((name) => {
137
+ const definition = META_TOOLS[name];
138
+ const actions = metaToolActions(name);
139
+ return [
140
+ name,
141
+ actions.length > 0 ? actions.join(" | ") : "-",
142
+ definition.contract.required.join(", ") || "-",
143
+ ];
144
+ }));
145
+ }
146
+ /** `codespar tools meta <name>` — one definition, schema and vocabularies. */
147
+ export function showMetaToolCommand(name, opts) {
148
+ const definition = requireDefinition(name);
149
+ if (opts.json) {
150
+ json(definition);
151
+ return;
152
+ }
153
+ kv([
154
+ ["Name", definition.name],
155
+ ["Required", definition.contract.required.join(", ") || "-"],
156
+ ["Properties", definition.contract.properties.join(", ")],
157
+ ]);
158
+ process.stdout.write(`\n${definition.description}\n`);
159
+ const enums = definition.contract.enums ?? {};
160
+ if (Object.keys(enums).length > 0) {
161
+ process.stdout.write(`\n${c.bold("Vocabularies")}\n`);
162
+ kv(Object.entries(enums).map(([key, values]) => [key, values.join(" | ")]));
163
+ }
164
+ process.stdout.write("\nInput schema:\n");
165
+ process.stdout.write(JSON.stringify(definition.input_schema, null, 2) + "\n");
166
+ }
167
+ //# sourceMappingURL=meta-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta-tool.js","sourceRoot":"","sources":["../../src/commands/meta-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAc/F;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,UAAU,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAClC,MAAM,IAAI,QAAQ,CAChB,sBAAsB,IAAI,0BAA0B,aAAa,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CACnF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CACvB,UAAoC,EACpC,GAAW,EACX,GAAW;IAEX,MAAM,QAAQ,GAAG,UAAU,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACzD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,QAAQ,CAChB,GAAG,UAAU,CAAC,IAAI,qBAAqB,GAAG,+BAA+B,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CACvH,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,GAAY,GAAG,CAAC;IACzB,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9D,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,MAAM,IAAI,QAAQ,CAAC,GAAG,GAAG,2BAA2B,GAAG,IAAI,CAAC,CAAC;QACtF,KAAK,GAAG,CAAC,CAAC;IACZ,CAAC;SAAM,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACvC,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YACtC,MAAM,IAAI,QAAQ,CAAC,GAAG,GAAG,gCAAgC,GAAG,IAAI,CAAC,CAAC;QACpE,CAAC;QACD,KAAK,GAAG,GAAG,KAAK,MAAM,CAAC;IACzB,CAAC;SAAM,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACnE,IAAI,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QACrC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,QAAQ,CAChB,GAAG,GAAG,SAAS,QAAQ,CAAC,IAAI,qDAAsD,GAAa,CAAC,OAAO,EAAE,CAC1G,CAAC;QACJ,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACjF,MAAM,IAAI,QAAQ,CAChB,GAAG,GAAG,KAAK,KAAK,0CAA0C,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CACtF,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CACvB,UAAoC,EACpC,IAAyC,EACzC,QAA2B,EAC3B,MAA0B;IAE1B,MAAM,IAAI,GAA4B,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;IAE1D,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,EAAE,IAAI,CAAC;YAAE,MAAM,IAAI,QAAQ,CAAC,iCAAiC,IAAI,IAAI,CAAC,CAAC;QAC3E,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,UAAU,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,aAAa,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM,IAAI,QAAQ,CAChB,GAAG,UAAU,CAAC,IAAI,mEAAmE;gBACnF,CAAC,aAAa;oBACZ,CAAC,CAAC,2BAA2B,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,yBAAyB,aAAa,sBAAsB;oBAChI,CAAC,CAAC,EAAE,CAAC,CACV,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,QAAQ,CAChB,GAAG,UAAU,CAAC,IAAI,cAAc,MAAM,0CAA0C,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CACtG,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CACjD,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CACxD,CAAC;IACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC5B,MAAM,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YAClD,IAAI,CAAC,KAAK,QAAQ,IAAI,UAAU;gBAAE,OAAO,aAAa,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAC9E,IAAI,UAAU;gBAAE,OAAO,SAAS,CAAC,KAAK,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAC9D,OAAO,SAAS,CAAC,UAAU,CAAC;QAC9B,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,QAAQ,CAChB,GAAG,UAAU,CAAC,IAAI,aAAa,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,yCAAyC,CAClH,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAY,EACZ,IAA4B;IAE5B,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhE,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC;QACtB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,SAAS,EAAE,IAAI,CAAC,OAAO;KACxB,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;IAE1E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,QAAQ,CAAC,GAAG,UAAU,CAAC,IAAI,YAAY,MAAM,CAAC,KAAK,IAAI,eAAe,EAAE,CAAC,CAAC;QACtF,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;YAC1B,OAAO;QACT,CAAC;QACD,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACjF,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,oBAAoB,CAAC,IAAwB;IAC3D,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,IAAI,CAAC,UAAU,CAAC,CAAC;QACjB,OAAO;IACT,CAAC;IACD,KAAK,CACH,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,CAAC,EAC/B,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAC3B,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAE,CAAC;QACrC,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QACtC,OAAO;YACL,IAAI;YACJ,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG;YAC9C,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG;SAC/C,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,IAAwB;IACxE,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,IAAI,CAAC,UAAU,CAAC,CAAC;QACjB,OAAO;IACT,CAAC;IACD,EAAE,CAAC;QACD,CAAC,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC;QACzB,CAAC,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;QAC5D,CAAC,YAAY,EAAE,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC1D,CAAC,CAAC;IACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,UAAU,CAAC,WAAW,IAAI,CAAC,CAAC;IACtD,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC;IAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QACtD,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAChF,CAAC"}
@@ -0,0 +1,74 @@
1
+ import { CodeSpar } from "@codespar/sdk";
2
+ import { CliError } from "../config.js";
3
+ import { info, json, renderResult } from "../output.js";
4
+ import { resolveOptionalInput } from "./meta-input.js";
5
+ /** `--query k=v` (repeatable) → `{ k: v }`, repeats collect into an array. */
6
+ export function parseQuery(pairs) {
7
+ const out = {};
8
+ for (const pair of pairs) {
9
+ const eq = pair.indexOf("=");
10
+ if (eq <= 0) {
11
+ throw new CliError(`--query expects key=value, got "${pair}".`);
12
+ }
13
+ const key = pair.slice(0, eq);
14
+ const value = pair.slice(eq + 1);
15
+ const existing = out[key];
16
+ if (existing === undefined)
17
+ out[key] = value;
18
+ else if (Array.isArray(existing))
19
+ existing.push(value);
20
+ else
21
+ out[key] = [existing, value];
22
+ }
23
+ return out;
24
+ }
25
+ /** Positional arguments → the path parameter object the client expands. */
26
+ export function bindPathParams(command, args) {
27
+ if (args.length !== command.params.length) {
28
+ throw new CliError(`${command.path} takes ${command.params.length} argument(s) (${command.params.join(", ")}), got ${args.length}.`);
29
+ }
30
+ const out = {};
31
+ command.params.forEach((name, i) => {
32
+ const value = args[i] ?? "";
33
+ if (value === "")
34
+ throw new CliError(`Path parameter <${name}> must not be empty.`);
35
+ out[name] = value;
36
+ });
37
+ return out;
38
+ }
39
+ /**
40
+ * Run one derived resource command: bind the positionals to the path
41
+ * parameters, pass `--query` through, pass `--input` as the request body
42
+ * when the operation declares one, and print whatever came back. No
43
+ * response is synthesised: what prints is the API's own payload, and a
44
+ * non-2xx status surfaces as the API's error.
45
+ */
46
+ export async function runResourceCommand(command, opts) {
47
+ const body = await resolveOptionalInput(opts, `${command.method.toUpperCase()} ${command.path}`);
48
+ if (body !== undefined && !command.acceptsBody) {
49
+ throw new CliError(`${command.method.toUpperCase()} ${command.path} declares no request body; drop --input / --input-file.`);
50
+ }
51
+ const timeout = opts.timeout === undefined ? undefined : Number(opts.timeout);
52
+ if (timeout !== undefined && (!Number.isFinite(timeout) || timeout <= 0)) {
53
+ throw new CliError(`--timeout expects a positive number of milliseconds, got "${opts.timeout}".`);
54
+ }
55
+ const cs = new CodeSpar({
56
+ apiKey: opts.apiKey,
57
+ baseUrl: opts.baseUrl,
58
+ projectId: opts.project,
59
+ ...(timeout !== undefined ? { timeout } : {}),
60
+ });
61
+ const api = cs.api;
62
+ const result = await api.request(command.method, command.path, {
63
+ path: bindPathParams(command, opts.args),
64
+ query: parseQuery(opts.query),
65
+ ...(body !== undefined ? { body } : {}),
66
+ });
67
+ if (opts.json) {
68
+ json(result ?? null);
69
+ return;
70
+ }
71
+ info(`${command.method.toUpperCase()} ${command.path}`);
72
+ renderResult(result);
73
+ }
74
+ //# sourceMappingURL=resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource.js","sourceRoot":"","sources":["../../src/commands/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAsCvD,8EAA8E;AAC9E,MAAM,UAAU,UAAU,CAAC,KAAwB;IACjD,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACZ,MAAM,IAAI,QAAQ,CAAC,mCAAmC,IAAI,IAAI,CAAC,CAAC;QAClE,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QACjC,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,QAAQ,KAAK,SAAS;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;aACxC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;;YAClD,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,cAAc,CAC5B,OAAgD,EAChD,IAAuB;IAEvB,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QAC1C,MAAM,IAAI,QAAQ,CAChB,GAAG,OAAO,CAAC,IAAI,UAAU,OAAO,CAAC,MAAM,CAAC,MAAM,iBAAiB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM,GAAG,CACjH,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,KAAK,KAAK,EAAE;YAAE,MAAM,IAAI,QAAQ,CAAC,mBAAmB,IAAI,sBAAsB,CAAC,CAAC;QACpF,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IACpB,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAuB,EACvB,IAA4B;IAE5B,MAAM,IAAI,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACjG,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAC/C,MAAM,IAAI,QAAQ,CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,OAAO,CAAC,IAAI,yDAAyD,CACzG,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9E,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,EAAE,CAAC;QACzE,MAAM,IAAI,QAAQ,CAAC,6DAA6D,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;IACpG,CAAC;IAED,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC;QACtB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,SAAS,EAAE,IAAI,CAAC,OAAO;QACvB,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9C,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,EAAE,CAAC,GAA4B,CAAC;IAC5C,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE;QAC7D,IAAI,EAAE,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC;QACxC,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;QAC7B,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxC,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACxD,YAAY,CAAC,MAAM,CAAC,CAAC;AACvB,CAAC"}
@@ -2,46 +2,72 @@ import { CliError } from "../config.js";
2
2
  import { json, kv, table } from "../output.js";
3
3
  export async function listServersCommand(client, opts) {
4
4
  const data = await client.get("/v1/servers", {
5
- category: opts.category,
6
- region: opts.region,
5
+ query: { category: opts.category, country: opts.country, q: opts.q },
7
6
  });
8
7
  if (opts.json) {
9
- json(data.data);
8
+ json(data.servers);
10
9
  return;
11
10
  }
12
- table(["ID", "NAME", "CATEGORY", "REGION", "TOOLS", "STATUS"], data.data.map((s) => [
11
+ table(["ID", "NAME", "CATEGORY", "COUNTRY", "TOOLS", "STATUS"], data.servers.map((s) => [
13
12
  s.id,
14
13
  s.name,
15
14
  s.category ?? "-",
16
- s.region ?? "-",
17
- String(s.tool_count ?? "-"),
15
+ s.country ?? "-",
16
+ String(s.tools_count ?? "-"),
18
17
  s.status ?? "-",
19
18
  ]));
19
+ if (data.filtered !== data.total) {
20
+ process.stdout.write(`\n${data.filtered} of ${data.total} servers shown.\n`);
21
+ }
20
22
  }
23
+ /**
24
+ * One server, assembled from the three routes that describe it.
25
+ *
26
+ * There is no `GET /v1/servers/{id}`: this command used to call it and got
27
+ * a 404 every time it ran (core#130). What exists is the catalog listing,
28
+ * which carries the descriptive fields, plus the two per-server reads. The
29
+ * listing is fetched first because it is the only one that can tell an
30
+ * unknown id from an id whose tools have not been indexed.
31
+ */
21
32
  export async function showServerCommand(client, id, opts) {
22
33
  if (!id)
23
34
  throw new CliError("Server id is required. Example: `codespar servers show stripe`");
24
- const server = await client.get(`/v1/servers/${encodeURIComponent(id)}`);
35
+ const catalog = await client.get("/v1/servers");
36
+ const server = catalog.servers.find((s) => s.id === id);
37
+ if (!server) {
38
+ throw new CliError(`No server with id "${id}" in the catalog. Run \`codespar servers list\` to see the ${catalog.total} available.`);
39
+ }
40
+ const [tools, auth] = await Promise.all([
41
+ client.get("/v1/servers/{id}/tools", { path: { id } }),
42
+ client.get("/v1/servers/{id}/auth-schema", { path: { id } }),
43
+ ]);
25
44
  if (opts.json) {
26
- json(server);
45
+ json({ ...server, auth_schema: auth, tools: tools.tools });
27
46
  return;
28
47
  }
29
48
  kv([
30
49
  ["ID", server.id],
31
50
  ["Name", server.name],
32
51
  ["Category", server.category ?? "-"],
33
- ["Region", server.region ?? "-"],
52
+ ["Country", server.country ?? "-"],
34
53
  ["Status", server.status ?? "-"],
35
- ["Auth", server.auth_type ?? "-"],
36
- ["Tools", String(server.tool_count ?? server.tools?.length ?? "-")],
54
+ ["Auth", auth.auth_type],
55
+ ["Environment", auth.environment],
56
+ ["Tools", String(tools.total)],
37
57
  ]);
38
58
  if (server.description) {
39
59
  process.stdout.write(`\n${server.description}\n`);
40
60
  }
41
- if (server.tools && server.tools.length > 0) {
61
+ if (auth.fields.length > 0) {
62
+ process.stdout.write("\nCredentials it asks for:\n");
63
+ for (const field of auth.fields) {
64
+ process.stdout.write(` • ${field.label} (${field.name}, ${field.kind})\n`);
65
+ }
66
+ }
67
+ if (tools.tools.length > 0) {
42
68
  process.stdout.write("\nTools:\n");
43
- for (const t of server.tools) {
44
- process.stdout.write(` • ${t.name}${t.description ? ` — ${t.description}` : ""}\n`);
69
+ for (const tool of tools.tools) {
70
+ process.stdout.write(` • ${tool.name}${tool.description ? ` — ${tool.description}` : ""}\n`);
45
71
  }
46
72
  }
47
73
  }
@@ -1 +1 @@
1
- {"version":3,"file":"servers.js","sourceRoot":"","sources":["../../src/commands/servers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAyB/C,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAiB,EAAE,IAAiB;IAC3E,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAA4B,aAAa,EAAE;QACtE,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IAED,KAAK,CACH,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,EACvD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACnB,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,QAAQ,IAAI,GAAG;QACjB,CAAC,CAAC,MAAM,IAAI,GAAG;QACf,MAAM,CAAC,CAAC,CAAC,UAAU,IAAI,GAAG,CAAC;QAC3B,CAAC,CAAC,MAAM,IAAI,GAAG;KAChB,CAAC,CACH,CAAC;AACJ,CAAC;AAMD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAiB,EACjB,EAAU,EACV,IAAiB;IAEjB,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,QAAQ,CAAC,gEAAgE,CAAC,CAAC;IAE9F,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAe,eAAe,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAEvF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,IAAI,CAAC,MAAM,CAAC,CAAC;QACb,OAAO;IACT,CAAC;IAED,EAAE,CAAC;QACD,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;QACjB,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,IAAI,GAAG,CAAC;QACpC,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC;QAChC,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC;QAChC,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,IAAI,GAAG,CAAC;QACjC,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,IAAI,GAAG,CAAC,CAAC;KACpE,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACnC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"servers.js","sourceRoot":"","sources":["../../src/commands/servers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAS/C,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAiB,EAAE,IAAiB;IAC3E,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE;QAC3C,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE;KACrE,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnB,OAAO;IACT,CAAC;IAED,KAAK,CACH,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,EACxD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACtB,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,QAAQ,IAAI,GAAG;QACjB,CAAC,CAAC,OAAO,IAAI,GAAG;QAChB,MAAM,CAAC,CAAC,CAAC,WAAW,IAAI,GAAG,CAAC;QAC5B,CAAC,CAAC,MAAM,IAAI,GAAG;KAChB,CAAC,CACH,CAAC;IACF,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,QAAQ,OAAO,IAAI,CAAC,KAAK,mBAAmB,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC;AAMD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAiB,EACjB,EAAU,EACV,IAAiB;IAEjB,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,QAAQ,CAAC,gEAAgE,CAAC,CAAC;IAE9F,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,QAAQ,CAChB,sBAAsB,EAAE,8DAA8D,OAAO,CAAC,KAAK,aAAa,CACjH,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,wBAAwB,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;QACtD,MAAM,CAAC,GAAG,CAAC,8BAA8B,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;KAC7D,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3D,OAAO;IACT,CAAC;IAED,EAAE,CAAC;QACD,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;QACjB,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,IAAI,GAAG,CAAC;QACpC,CAAC,SAAS,EAAE,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC;QAClC,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC;QAChC,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC;QACxB,CAAC,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC;QACjC,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;KAC/B,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QACrD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACnC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAChG,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -1,35 +1,57 @@
1
1
  import { CliError } from "../config.js";
2
- import { json, kv, success, table } from "../output.js";
2
+ import { isoSeconds, isoTime, json, kv, success, table } from "../output.js";
3
+ /** `--limit 20` → 20, refusing anything the query parameter cannot carry. */
4
+ function parseLimit(raw, flag = "--limit") {
5
+ if (raw === undefined)
6
+ return undefined;
7
+ const value = Number(raw);
8
+ if (!Number.isInteger(value) || value <= 0) {
9
+ throw new CliError(`${flag} expects a positive whole number, got "${raw}".`);
10
+ }
11
+ return value;
12
+ }
13
+ const SESSION_STATUSES = ["active", "closed", "error"];
14
+ function parseStatus(raw) {
15
+ if (raw === undefined)
16
+ return undefined;
17
+ if (!SESSION_STATUSES.includes(raw)) {
18
+ throw new CliError(`--status expects one of ${SESSION_STATUSES.join(", ")}, got "${raw}".`);
19
+ }
20
+ return raw;
21
+ }
3
22
  export async function listSessionsCommand(client, opts) {
4
23
  const data = await client.get("/v1/sessions", {
5
- status: opts.status,
6
- limit: opts.limit,
24
+ query: { status: parseStatus(opts.status), limit: parseLimit(opts.limit) },
7
25
  });
8
26
  if (opts.json) {
9
- json(data.data);
27
+ json(data.sessions);
10
28
  return;
11
29
  }
12
- table(["ID", "USER", "STATUS", "SERVERS", "TOOL CALLS", "CREATED"], data.data.map((s) => [
30
+ // No tool-call count here: the listing does not carry one, and the column
31
+ // that used to be in this table printed 0 for every row.
32
+ table(["ID", "USER", "STATUS", "SERVERS", "CREATED"], data.sessions.map((s) => [
13
33
  s.id,
14
34
  s.user_id ?? "-",
15
35
  s.status ?? "-",
16
36
  (s.servers ?? []).join(", "),
17
- String(s.tool_call_count ?? 0),
18
- s.created_at ? new Date(s.created_at).toISOString().slice(0, 19).replace("T", " ") : "-",
37
+ isoSeconds(s.created_at),
19
38
  ]));
39
+ if (data.next_before) {
40
+ process.stdout.write(`\nMore rows: \`--limit\` with a larger number, or page from ${data.next_before}.\n`);
41
+ }
20
42
  }
21
43
  export async function showSessionCommand(client, id, opts) {
22
44
  if (!id)
23
45
  throw new CliError("Session id is required.");
24
- const session = await client.get(`/v1/sessions/${encodeURIComponent(id)}`);
46
+ const session = await client.get("/v1/sessions/{id}", { path: { id } });
47
+ // `--logs` reads the session's tool calls. It used to read
48
+ // `/v1/sessions/{id}/logs`, a route the API does not have, so the flag
49
+ // 404'd on every session that existed (core#130).
50
+ const calls = opts.logs
51
+ ? (await client.get("/v1/sessions/{id}/tool-calls", { path: { id } })).tool_calls
52
+ : undefined;
25
53
  if (opts.json) {
26
- if (opts.logs) {
27
- const logs = await client.get(`/v1/sessions/${encodeURIComponent(id)}/logs`);
28
- json({ session, logs: logs.data });
29
- }
30
- else {
31
- json(session);
32
- }
54
+ json(calls ? { session, tool_calls: calls } : session);
33
55
  return;
34
56
  }
35
57
  kv([
@@ -37,26 +59,27 @@ export async function showSessionCommand(client, id, opts) {
37
59
  ["User", session.user_id ?? "-"],
38
60
  ["Status", session.status ?? "-"],
39
61
  ["Servers", (session.servers ?? []).join(", ")],
40
- ["Tool calls", String(session.tool_call_count ?? 0)],
62
+ ["Tool calls", String(session.tool_calls_count ?? 0)],
41
63
  ["Created", session.created_at ?? "-"],
42
64
  ["Closed", session.closed_at ?? "-"],
43
65
  ]);
44
- if (opts.logs) {
45
- const logs = await client.get(`/v1/sessions/${encodeURIComponent(id)}/logs`);
46
- process.stdout.write("\nLogs:\n");
47
- table(["TOOL", "SERVER", "STATUS", "MS", "AT"], logs.data.map((l) => [
48
- l.tool,
49
- l.server,
50
- l.status,
51
- String(l.duration_ms ?? "-"),
52
- l.called_at ? new Date(l.called_at).toISOString().slice(11, 19) : "-",
66
+ if (calls) {
67
+ process.stdout.write("\nTool calls:\n");
68
+ table(["TOOL", "SERVER", "STATUS", "MS", "AT"], calls.map((call) => [
69
+ call.tool_name,
70
+ call.server_id ?? "-",
71
+ call.status ?? "-",
72
+ String(call.duration_ms ?? "-"),
73
+ isoTime(call.called_at),
53
74
  ]));
54
75
  }
55
76
  }
56
77
  export async function closeSessionCommand(client, id) {
57
78
  if (!id)
58
79
  throw new CliError("Session id is required.");
59
- await client.post(`/v1/sessions/${encodeURIComponent(id)}/close`);
60
- success(`Session ${id} closed.`);
80
+ // `DELETE /v1/sessions/{id}` is the documented close. The old
81
+ // `POST /v1/sessions/{id}/close` was never a route (core#130).
82
+ const closed = await client.delete("/v1/sessions/{id}", { path: { id } });
83
+ success(`Session ${closed.id} ${closed.status}${closed.closed_at ? ` at ${closed.closed_at}` : ""}.`);
61
84
  }
62
85
  //# sourceMappingURL=sessions.js.map