@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.
- package/README.md +40 -0
- package/dist/api.js +78 -19
- package/dist/api.js.map +1 -1
- package/dist/commands/connect.js +26 -13
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/login.js +6 -6
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logs.js +73 -77
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/mandate.js +47 -16
- package/dist/commands/mandate.js.map +1 -1
- package/dist/commands/meta-input.js +11 -0
- package/dist/commands/meta-input.js.map +1 -1
- package/dist/commands/meta-tool.js +167 -0
- package/dist/commands/meta-tool.js.map +1 -0
- package/dist/commands/resource.js +74 -0
- package/dist/commands/resource.js.map +1 -0
- package/dist/commands/servers.js +40 -14
- package/dist/commands/servers.js.map +1 -1
- package/dist/commands/sessions.js +50 -27
- package/dist/commands/sessions.js.map +1 -1
- package/dist/commands/spend.js +4 -1
- package/dist/commands/spend.js.map +1 -1
- package/dist/commands/tools.js +38 -21
- package/dist/commands/tools.js.map +1 -1
- package/dist/commands/transfer.js +4 -1
- package/dist/commands/transfer.js.map +1 -1
- package/dist/commands/wallet.js +3 -1
- package/dist/commands/wallet.js.map +1 -1
- package/dist/commands/wizard.js +2 -2
- package/dist/commands/wizard.js.map +1 -1
- package/dist/index.js +113 -14
- package/dist/index.js.map +1 -1
- package/dist/output.js +100 -0
- package/dist/output.js.map +1 -1
- package/dist/surface.js +473 -0
- package/dist/surface.js.map +1 -0
- package/dist/version.js +18 -5
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
package/dist/commands/mandate.js
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
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
|
-
|
|
109
|
-
|
|
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
|
-
|
|
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":"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;
|
|
1
|
+
{"version":3,"file":"mandate.js","sourceRoot":"","sources":["../../src/commands/mandate.ts"],"names":[],"mappings":"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"}
|
|
@@ -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":"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"}
|
|
@@ -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":"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"}
|
package/dist/commands/servers.js
CHANGED
|
@@ -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.
|
|
8
|
+
json(data.servers);
|
|
10
9
|
return;
|
|
11
10
|
}
|
|
12
|
-
table(["ID", "NAME", "CATEGORY", "
|
|
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.
|
|
17
|
-
String(s.
|
|
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
|
|
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
|
-
["
|
|
52
|
+
["Country", server.country ?? "-"],
|
|
34
53
|
["Status", server.status ?? "-"],
|
|
35
|
-
["Auth",
|
|
36
|
-
["
|
|
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 (
|
|
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
|
|
44
|
-
process.stdout.write(` • ${
|
|
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;
|
|
1
|
+
{"version":3,"file":"servers.js","sourceRoot":"","sources":["../../src/commands/servers.ts"],"names":[],"mappings":"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"}
|
|
@@ -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.
|
|
27
|
+
json(data.sessions);
|
|
10
28
|
return;
|
|
11
29
|
}
|
|
12
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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.
|
|
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 (
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
60
|
-
|
|
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
|