@commercelayer/agent-cli 1.0.0-dev.6 → 1.0.0-dev.7
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 +2 -2
- package/dist/argv.js +5 -5
- package/dist/builtins/loops.js +2 -3
- package/dist/help.js +3 -2
- package/dist/schema.js +6 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ This is the 1.0.0 line, in development on the `clean-slate` branch. It replaces
|
|
|
14
14
|
- A plain noun has no code in the CLI. Its fields, filters and verbs come from the API's schema, and `c11r schema <noun>` returns that schema.
|
|
15
15
|
- Flags are the schema's fields, in kebab or snake case: `--price-list` and `--price_list` are the same.
|
|
16
16
|
- On `list`, `--<field> <value>` filters by equality and `--<field>.<op> <value>` by another operator: `--placed-at.gte 2026-11-01`, `--status.in placed,approved`. `--waiting` lists what needs a decision now.
|
|
17
|
-
- A ref flag given `null
|
|
17
|
+
- A ref flag, or one the schema marks `nullable`, given `null` or an empty value sends `null` and takes it off: `c11r customers update ada@example.com --customer-group null` sends `customer_group: null`, `c11r orders update 1001 --coupon-code null` sends `coupon_code: null`. A ref the schema marks `nullable: false`, and any other field, sends the text.
|
|
18
18
|
- A dotted flag sets part of an object: `--customer.email ada@example.com`. An `in` filter takes several values as the flag repeated or a JSON array; on enums, numbers and dates also separated by commas, while a name or text is one value even with a comma in it (`--tax-calculator.in "UK VAT, manual"`), and a list that has one is sent as a JSON array. Any other array takes a JSON array, values separated by commas, or the flag repeated; an array of objects takes `key=value` pairs, one object per flag: `--items sku=COFFEE,quantity=2`. `--data` takes the fields as one JSON object, or `@` and a file name.
|
|
19
19
|
- Amounts are in major units: `--amount 12.50`.
|
|
20
20
|
- A secret field the schema marks `secret_input` (provider credentials) has no flag of its own: `--credentials-file <file>` reads it, as JSON or `KEY=value` lines, from a plain file only its owner can read (mode 600). Without the file, a terminal asks for it without echo; with neither, the command stops with `secret_required`. It is refused as a flag value or in `--data`, and never printed.
|
|
@@ -35,7 +35,7 @@ This is the 1.0.0 line, in development on the `clean-slate` branch. It replaces
|
|
|
35
35
|
| `c11r auth login [--client-id] [--secret-file] [--keep-file]` | The human's own Commerce Layer login, from their Provisioning API application. See below. |
|
|
36
36
|
| `c11r auth logout`, `auth switch <slug> [--global]` | Forgetting the login; the organization commands act on. |
|
|
37
37
|
|
|
38
|
-
A loop runs a skill a Manage noun's schema names in `loop.skill` (`manage-orders`, `manage-payments`, `
|
|
38
|
+
A loop runs a skill a Manage noun's schema names in `loop.skill` (`manage-orders`, `manage-payments`, `manage-stock`, ...); create and update refuse any other skill, and any verb that loop does not list, with the allowed values. A loop policy allows verbs: a bare verb is the skill's own noun (`approve`), `<noun>.<verb>` another Manage noun's verb on the same item (`payments.capture`). Verbs that delete or return money are never open to a policy.
|
|
39
39
|
|
|
40
40
|
## Login, organization tokens and secrets
|
|
41
41
|
|
package/dist/argv.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// verb's flags, which say whether a flag takes a value, what type it is and where it goes.
|
|
4
4
|
import fs from 'node:fs';
|
|
5
5
|
import { closest, fail, fixWith } from './errors.js';
|
|
6
|
+
import { clearable } from './schema.js';
|
|
6
7
|
const BOOLEAN_GLOBALS = {
|
|
7
8
|
'--json': 'json',
|
|
8
9
|
'--dry-run': 'dryRun',
|
|
@@ -130,13 +131,12 @@ export function coerce(key, spec, raw) {
|
|
|
130
131
|
if ((spec.type === 'enum' || (spec.type === 'array' && spec.items === 'enum')) && !spec.values?.length) {
|
|
131
132
|
fail('invalid_response', `The API's schema gives ${toFlag(key)} as an enum with no values, so c11r cannot check ${JSON.stringify(raw)}. It was not sent.`, { path: key, next_step: { action: 'none' } });
|
|
132
133
|
}
|
|
134
|
+
// null, or an empty value, clears what the schema lets null clear (--customer-group null, --coupon-code "").
|
|
135
|
+
if (clearable(spec) && (raw === 'null' || raw.trim() === ''))
|
|
136
|
+
return null;
|
|
133
137
|
switch (spec.type) {
|
|
134
138
|
case 'string':
|
|
135
|
-
return raw;
|
|
136
139
|
case 'ref':
|
|
137
|
-
// In a body, null or "" takes the relationship off (customers update --customer-group null).
|
|
138
|
-
if (spec.to === 'body' && (raw === 'null' || raw.trim() === ''))
|
|
139
|
-
return null;
|
|
140
140
|
return raw;
|
|
141
141
|
case 'integer':
|
|
142
142
|
if (!/^-?\d+$/.test(raw.trim()))
|
|
@@ -214,7 +214,7 @@ function json(raw, invalid) {
|
|
|
214
214
|
}
|
|
215
215
|
/**
|
|
216
216
|
* sku=A,quantity=2 as { sku: 'A', quantity: 2 }, each part typed by the schema's properties.
|
|
217
|
-
* A part the schema does not type stays text: a
|
|
217
|
+
* A part the schema does not type stays text: a zip code or a phone is never made a number.
|
|
218
218
|
*/
|
|
219
219
|
function pairs(key, raw, props, invalid) {
|
|
220
220
|
const out = {};
|
package/dist/builtins/loops.js
CHANGED
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
//
|
|
6
6
|
// A policy allows verbs: a bare verb is the skill's own noun (approve), <noun>.<verb> another
|
|
7
7
|
// Manage noun's verb on the same item (payments.capture). The skill must be one a Manage noun's
|
|
8
|
-
// schema names in loop.skill
|
|
9
|
-
// playbook-mail-to-order), and each verb in that loop.verbs; the API checks again on every pass.
|
|
8
|
+
// schema names in loop.skill, and each verb in that loop.verbs; the API checks again on every pass.
|
|
10
9
|
import fs from 'node:fs';
|
|
11
10
|
import path from 'node:path';
|
|
12
11
|
import YAML from 'yaml';
|
|
@@ -18,7 +17,7 @@ import { apiNouns, apiSchema } from '../schemas.js';
|
|
|
18
17
|
const NAME = /^[a-z0-9][a-z0-9-]{0,62}$/;
|
|
19
18
|
const EVERY = /^[1-9]\d*(m|h|d)$/;
|
|
20
19
|
const policyFlags = (required) => [
|
|
21
|
-
{ name: 'skill', type: 'string', required, description: 'The skill
|
|
20
|
+
{ name: 'skill', type: 'string', required, description: 'The skill the loop runs, as in manage-orders: one a noun\'s schema names in loop.skill.' },
|
|
22
21
|
{ name: 'every', type: 'string', required, description: 'How often a pass should run, as in 15m, 2h or 1d. The scheduler reads it; the CLI does not wait.' },
|
|
23
22
|
{ name: 'allow', type: 'array', description: 'A verb the policy allows, repeated: approve, payments.capture. Only verbs the noun\'s schema lists in loop.verbs. Without it the loop only reports what is waiting.' },
|
|
24
23
|
{ name: 'max_total', type: 'array', description: 'The largest order total acted on, in major units: 500 for every currency, or EUR=500, repeated per currency. Above it, the item waits for the human.' },
|
package/dist/help.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// reads it and offers to do the work.
|
|
4
4
|
import { toFlag } from './argv.js';
|
|
5
5
|
import { EXIT } from './errors.js';
|
|
6
|
+
import { clearable } from './schema.js';
|
|
6
7
|
export const USAGE = 'c11r <noun> <verb> [id] [--field value ...]';
|
|
7
8
|
export const GLOBAL_FLAG_HELP = {
|
|
8
9
|
'--json': 'Output as JSON. The default, and the only format: one object on stdout, { data, state, warnings, next } or { error, state }.',
|
|
@@ -29,7 +30,7 @@ export function indexHelp(builtins, api) {
|
|
|
29
30
|
description: 'c11r is the Commerce Layer CLI for coding agents. Every answer, errors included, is one JSON object on stdout.',
|
|
30
31
|
nouns: [...builtins, ...(api ?? [])].sort((a, b) => (a.noun < b.noun ? -1 : 1)),
|
|
31
32
|
standard_verbs: 'list, get, create, update, delete. Nouns with a state machine add their own verbs.',
|
|
32
|
-
flags: 'Fields in kebab or snake case (--price-list, --price_list). On list, --<field> <value> filters by equality and --<field>.<op> <value> by another operator (--created-at.gte 2026-11-01). in takes several values as the flag repeated or a JSON array; on enums, numbers and dates also separated by commas, while a name or text is one value even with a comma in it, and a list that has one is sent as a JSON array. A ref flag given null
|
|
33
|
+
flags: 'Fields in kebab or snake case (--price-list, --price_list). On list, --<field> <value> filters by equality and --<field>.<op> <value> by another operator (--created-at.gte 2026-11-01). in takes several values as the flag repeated or a JSON array; on enums, numbers and dates also separated by commas, while a name or text is one value even with a comma in it, and a list that has one is sent as a JSON array. A ref flag, or a flag the schema marks nullable, given null or an empty value sends null and takes it off (--customer-group null, --coupon-code null). A dotted flag sets part of an object (--customer.email). Any other array takes a JSON array, values separated by commas, or the flag repeated; an array of objects takes key=value pairs (--items sku=COFFEE,quantity=2). --data takes the fields as one JSON object, or @ and a file name.',
|
|
33
34
|
global_flags: GLOBAL_FLAG_HELP,
|
|
34
35
|
exit_codes: EXIT_CODE_HELP,
|
|
35
36
|
more: 'c11r <noun> --help describes a noun and its verbs; c11r <noun> <verb> --help a verb and its flags; c11r schema <noun> returns the full schema.',
|
|
@@ -67,7 +68,7 @@ function flagHelp(key, f) {
|
|
|
67
68
|
...(f.required || (f.input?.kind === 'secret' && f.input.required) ? { required: true } : {}),
|
|
68
69
|
...(f.input ? { reads: f.input.kind === 'secret' ? `${f.input.target}, a secret: never a flag value, never printed` : `${f.input.target}, a JSON document` } : {}),
|
|
69
70
|
...(f.values ? { values: f.values } : {}),
|
|
70
|
-
...(f
|
|
71
|
+
...(clearable(f) ? { clear: 'null, or an empty value, takes it off' } : {}),
|
|
71
72
|
...(f.filter ? { filter: f.filter.op } : {}),
|
|
72
73
|
...(f.description ? { description: f.description } : {}),
|
|
73
74
|
};
|
package/dist/schema.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// The schema of a noun, as the contract's schema document has it (section 5.1), and what the
|
|
2
2
|
// engine makes of it: for every verb, the flags it takes and where each one goes (body, query or
|
|
3
|
-
// filter). A plain noun (markets, orders,
|
|
3
|
+
// filter). A plain noun (markets, orders, payments, about 60 of them) has no code in the CLI: its
|
|
4
4
|
// schema is read from GET /v1/schema/<noun>. Built-in nouns (sandbox, loops, report) write theirs
|
|
5
5
|
// in the same document format, so one reader serves both.
|
|
6
6
|
import { closest, fail, fixWith } from './errors.js';
|
|
@@ -148,6 +148,7 @@ function flag(f, to, required) {
|
|
|
148
148
|
...(f.items ? { items: f.items } : {}),
|
|
149
149
|
...(f.properties?.length ? { properties: Object.fromEntries(f.properties.map((p) => [p.name, { type: p.type, ...(p.values ? { values: p.values } : {}) }])) } : {}),
|
|
150
150
|
...(f.noun ? { noun: f.noun } : {}),
|
|
151
|
+
...(f.nullable !== undefined ? { nullable: f.nullable } : {}),
|
|
151
152
|
...(required ? { required: true } : {}),
|
|
152
153
|
...(f.description ? { description: f.description } : {}),
|
|
153
154
|
};
|
|
@@ -181,3 +182,7 @@ export function verbOf(schema, verb) {
|
|
|
181
182
|
}
|
|
182
183
|
return v;
|
|
183
184
|
}
|
|
185
|
+
/** A body flag that null clears: a field marked nullable, or a ref unless marked nullable: false. */
|
|
186
|
+
export function clearable(f) {
|
|
187
|
+
return f.to === 'body' && (f.nullable === true || (f.type === 'ref' && f.nullable !== false));
|
|
188
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commercelayer/agent-cli",
|
|
3
|
-
"version": "1.0.0-dev.
|
|
3
|
+
"version": "1.0.0-dev.7",
|
|
4
4
|
"description": "c11r: the Commerce Layer CLI for coding agents. One grammar, c11r <noun> <verb>, from a sandbox to a running organization.",
|
|
5
5
|
"homepage": "https://commercelayer.ai",
|
|
6
6
|
"keywords": [
|