@chatlychat/cli 0.1.4 → 0.1.6
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/dist/commands/ai.d.ts +4 -0
- package/dist/commands/ai.d.ts.map +1 -0
- package/dist/commands/ai.js +149 -0
- package/dist/commands/ai.js.map +1 -0
- package/dist/commands/common.d.ts +79 -0
- package/dist/commands/common.d.ts.map +1 -0
- package/dist/commands/common.js +194 -0
- package/dist/commands/common.js.map +1 -0
- package/dist/commands/config.d.ts +40 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +336 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/insights.d.ts +5 -0
- package/dist/commands/insights.d.ts.map +1 -0
- package/dist/commands/insights.js +277 -0
- package/dist/commands/insights.js.map +1 -0
- package/dist/commands/integrations.d.ts +15 -0
- package/dist/commands/integrations.d.ts.map +1 -0
- package/dist/commands/integrations.js +256 -0
- package/dist/commands/integrations.js.map +1 -0
- package/dist/commands/resources.d.ts +19 -7
- package/dist/commands/resources.d.ts.map +1 -1
- package/dist/commands/resources.js +92 -167
- package/dist/commands/resources.js.map +1 -1
- package/dist/commands/workspace-as-code.d.ts +27 -0
- package/dist/commands/workspace-as-code.d.ts.map +1 -0
- package/dist/commands/workspace-as-code.js +377 -0
- package/dist/commands/workspace-as-code.js.map +1 -0
- package/dist/help.d.ts +25 -1
- package/dist/help.d.ts.map +1 -1
- package/dist/help.js +104 -8
- package/dist/help.js.map +1 -1
- package/dist/run.d.ts +17 -0
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +88 -41
- package/dist/run.js.map +1 -1
- package/dist/wac/__tests__/wac-fixtures.d.ts +20 -0
- package/dist/wac/__tests__/wac-fixtures.d.ts.map +1 -0
- package/dist/wac/__tests__/wac-fixtures.js +38 -0
- package/dist/wac/__tests__/wac-fixtures.js.map +1 -0
- package/dist/wac/apply.d.ts +113 -0
- package/dist/wac/apply.d.ts.map +1 -0
- package/dist/wac/apply.js +265 -0
- package/dist/wac/apply.js.map +1 -0
- package/dist/wac/diff.d.ts +137 -0
- package/dist/wac/diff.d.ts.map +1 -0
- package/dist/wac/diff.js +413 -0
- package/dist/wac/diff.js.map +1 -0
- package/dist/wac/document.d.ts +110 -0
- package/dist/wac/document.d.ts.map +1 -0
- package/dist/wac/document.js +429 -0
- package/dist/wac/document.js.map +1 -0
- package/dist/wac/render.d.ts +52 -0
- package/dist/wac/render.d.ts.map +1 -0
- package/dist/wac/render.js +156 -0
- package/dist/wac/render.js.map +1 -0
- package/dist/wac/resource-def.d.ts +116 -0
- package/dist/wac/resource-def.d.ts.map +1 -0
- package/dist/wac/resource-def.js +44 -0
- package/dist/wac/resource-def.js.map +1 -0
- package/dist/wac/resources.d.ts +104 -0
- package/dist/wac/resources.d.ts.map +1 -0
- package/dist/wac/resources.js +541 -0
- package/dist/wac/resources.js.map +1 -0
- package/dist/wac/values.d.ts +16 -0
- package/dist/wac/values.d.ts.map +1 -0
- package/dist/wac/values.js +53 -0
- package/dist/wac/values.js.map +1 -0
- package/package.json +2 -1
- package/dist/cli.spec.d.ts +0 -2
- package/dist/cli.spec.d.ts.map +0 -1
- package/dist/cli.spec.js +0 -226
- package/dist/cli.spec.js.map +0 -1
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chatly plan` and `chatly apply` — the workspace as a file.
|
|
3
|
+
*
|
|
4
|
+
* ═══ THE ASK ══════════════════════════════════════════════════════════════
|
|
5
|
+
*
|
|
6
|
+
* From the integrator who prompted it: "We wrote ~600 lines to idempotently
|
|
7
|
+
* upsert tools, bots, routes, cards and channel config. Offer a declarative
|
|
8
|
+
* `chatly.yaml` with `chatly plan` / `chatly apply` (diff, then apply; never
|
|
9
|
+
* deletes unless told). This is the single biggest DX win for teams that run
|
|
10
|
+
* more than one environment."
|
|
11
|
+
*
|
|
12
|
+
* A CLI rather than a Terraform provider, deliberately. A provider is a
|
|
13
|
+
* second artifact to version, publish, document and keep in step with 142
|
|
14
|
+
* routes, and this CLI is already on npm as `@chatlychat/cli` with a release
|
|
15
|
+
* pipeline. The provider is the better answer for somebody whose whole
|
|
16
|
+
* platform is Terraform; it is not the better answer for the next six months.
|
|
17
|
+
*
|
|
18
|
+
* ═══ THE CONTRACT ═════════════════════════════════════════════════════════
|
|
19
|
+
*
|
|
20
|
+
* plan reads the live workspace, prints a diff, WRITES NOTHING. Not one
|
|
21
|
+
* POST, not one PATCH. `wac.spec.ts` drives the whole path through
|
|
22
|
+
* a recording transport and fails if a single non-GET is issued —
|
|
23
|
+
* and asserts the GETs it did make, so a plan that silently stopped
|
|
24
|
+
* reading cannot pass the same test.
|
|
25
|
+
* apply makes the plan's changes. A resource on the server and absent
|
|
26
|
+
* from the document is REPORTED AND LEFT ALONE; `--prune` is the
|
|
27
|
+
* only thing that deletes, and there is no way to set it in the
|
|
28
|
+
* file. Default safe, as asked.
|
|
29
|
+
*
|
|
30
|
+
* ═══ YAML ═════════════════════════════════════════════════════════════════
|
|
31
|
+
*
|
|
32
|
+
* This reads JSON. `yaml` is in the lockfile only as a transitive
|
|
33
|
+
* devDependency of `lint-staged`, which is not reachable from `apps/cli` and
|
|
34
|
+
* would not ship with the published package either way, and CLAUDE.md §2
|
|
35
|
+
* forbids adding a dependency without explicit approval. A hand-rolled YAML
|
|
36
|
+
* subset was considered and rejected: indentation, quoting, anchors and
|
|
37
|
+
* multi-line scalars are exactly the surface where a parser that is 95%
|
|
38
|
+
* right produces a document that means something other than it says, which
|
|
39
|
+
* is worse than one that will not load.
|
|
40
|
+
*
|
|
41
|
+
* So a `.yaml` path is refused with the one-line conversion rather than
|
|
42
|
+
* half-parsed, and `--file -` reads stdin, which makes any converter a pipe.
|
|
43
|
+
* The documented filename stays `chatly.yaml` in the integrator's words and
|
|
44
|
+
* `chatly.json` in this implementation; when YAML is approved, `loadDocument`
|
|
45
|
+
* is the only function that changes.
|
|
46
|
+
*/
|
|
47
|
+
import { readFileSync } from 'node:fs';
|
|
48
|
+
import { bool, str } from '../args.js';
|
|
49
|
+
import { printJson } from '../output.js';
|
|
50
|
+
import { harvestSecrets, renderOutcomes, writesFor, } from '../wac/apply.js';
|
|
51
|
+
import { buildPlan, tally } from '../wac/diff.js';
|
|
52
|
+
import { parseDocument } from '../wac/document.js';
|
|
53
|
+
import { planFooter, planForJson, renderPlan } from '../wac/render.js';
|
|
54
|
+
import { resourceDef } from '../wac/resources.js';
|
|
55
|
+
/** Looked for in order when `--file` is absent. */
|
|
56
|
+
const DEFAULT_FILES = ['chatly.json', 'chatly.yaml', 'chatly.yml'];
|
|
57
|
+
/**
|
|
58
|
+
* The row cap on `/v1/macros`, used to decide whether `--prune` is safe.
|
|
59
|
+
*
|
|
60
|
+
* `@PaginationExempt` routes answer a bare array with no cursor, so a list
|
|
61
|
+
* that comes back at exactly the cap may be truncated — and a row past the
|
|
62
|
+
* cap is INVISIBLE, not absent, which would make it an orphan and then a
|
|
63
|
+
* deletion. `diff.ts` refuses prune for a type in that state. The number is
|
|
64
|
+
* the handler's, and if it ever rises this becomes conservative rather than
|
|
65
|
+
* wrong, which is the right direction for a flag that deletes.
|
|
66
|
+
*/
|
|
67
|
+
const EXEMPT_LIST_CAP = 200;
|
|
68
|
+
/* ── Loading ──────────────────────────────────────────────────────────── */
|
|
69
|
+
function readFile(path) {
|
|
70
|
+
try {
|
|
71
|
+
// `0` is stdin, so `converter | chatly plan --file -` works.
|
|
72
|
+
return path === '-' ? readFileSync(0, 'utf8') : readFileSync(path, 'utf8');
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
throw new Error(`Cannot read ${path}: ${err instanceof Error ? err.message : String(err)}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function findDefault() {
|
|
79
|
+
for (const candidate of DEFAULT_FILES) {
|
|
80
|
+
try {
|
|
81
|
+
readFileSync(candidate, 'utf8');
|
|
82
|
+
return candidate;
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
throw new Error('No document found. Looked for chatly.json, chatly.yaml and chatly.yml in this ' +
|
|
89
|
+
'directory.\nPass one with --file, or --file - to read stdin.\n' +
|
|
90
|
+
'There is a worked example at https://chatlychat.com/docs/sdk-cli#workspace-as-code');
|
|
91
|
+
}
|
|
92
|
+
export function loadDocument(args, env = process.env) {
|
|
93
|
+
const path = str(args.flags, 'file') ?? findDefault();
|
|
94
|
+
const raw = readFile(path);
|
|
95
|
+
if (/\.ya?ml$/i.test(path) || /^\s*(?:version|resources)\s*:/m.test(raw)) {
|
|
96
|
+
/*
|
|
97
|
+
* Refused, not half-parsed.
|
|
98
|
+
*
|
|
99
|
+
* The second half of that test catches a YAML document passed under a
|
|
100
|
+
* `.json` name or through stdin, which is the shape of the mistake
|
|
101
|
+
* somebody makes once. A YAML file handed to `JSON.parse` fails with
|
|
102
|
+
* "Unexpected token v", which sends the reader looking for a syntax error
|
|
103
|
+
* in their own file rather than at the one sentence they need.
|
|
104
|
+
*/
|
|
105
|
+
throw new Error(`${path} looks like YAML, and this CLI reads JSON.\n\n` +
|
|
106
|
+
'YAML needs a parser, and adding a dependency to a published CLI is a decision this\n' +
|
|
107
|
+
'repo does not make casually (CLAUDE.md §2) — `yaml` is in the monorepo lockfile only\n' +
|
|
108
|
+
'as a transitive devDependency of lint-staged, so it is not something we already ship.\n' +
|
|
109
|
+
'A 95%-right hand-rolled YAML subset is worse than no YAML: it loads a document that\n' +
|
|
110
|
+
'means something other than what it says.\n\n' +
|
|
111
|
+
'Convert it and pipe it:\n' +
|
|
112
|
+
` npx js-yaml ${path} | chatly plan --file -\n` +
|
|
113
|
+
' python3 -c "import sys,yaml,json;json.dump(yaml.safe_load(sys.stdin),sys.stdout)" \\\n' +
|
|
114
|
+
` < ${path} | chatly plan --file -`);
|
|
115
|
+
}
|
|
116
|
+
let parsed;
|
|
117
|
+
try {
|
|
118
|
+
parsed = JSON.parse(raw);
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
throw new Error(`${path} is not valid JSON: ${err instanceof Error ? err.message : '?'}`);
|
|
122
|
+
}
|
|
123
|
+
return parseDocument(parsed, env);
|
|
124
|
+
}
|
|
125
|
+
/* ── Reading the live workspace ───────────────────────────────────────── */
|
|
126
|
+
/**
|
|
127
|
+
* The live rows for every type the document mentions, and nothing else.
|
|
128
|
+
*
|
|
129
|
+
* All through `chatly.request` — the escape hatch CONTRACT.md defines — so
|
|
130
|
+
* auth, retries and the typed errors are the same ones every other command
|
|
131
|
+
* gets, and `apps/cli` still adds no HTTP of its own. Every call here is a
|
|
132
|
+
* GET; that is the property `wac.spec.ts` pins.
|
|
133
|
+
*/
|
|
134
|
+
export async function readLive(chatly, doc) {
|
|
135
|
+
const out = new Map();
|
|
136
|
+
for (const section of doc.sections) {
|
|
137
|
+
const { def } = section;
|
|
138
|
+
if (def.list.paged) {
|
|
139
|
+
const rows = [];
|
|
140
|
+
let cursor;
|
|
141
|
+
/*
|
|
142
|
+
* Walked by hand rather than through `autoPaginate` because the loop
|
|
143
|
+
* needs the raw envelope: `@PaginationExempt` neighbours answer a bare
|
|
144
|
+
* array and this one answers `{ items, nextCursor }`, and conflating
|
|
145
|
+
* the two is the bug that shipped in two SDKs.
|
|
146
|
+
*/
|
|
147
|
+
for (let guard = 0; guard < 200; guard += 1) {
|
|
148
|
+
const page = await chatly.request('GET', def.list.path, {
|
|
149
|
+
query: cursor === undefined ? {} : { cursor },
|
|
150
|
+
});
|
|
151
|
+
rows.push(...(page.items ?? []));
|
|
152
|
+
const next = page.nextCursor;
|
|
153
|
+
if (typeof next !== 'string' || next.length === 0 || next === cursor) {
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
cursor = next;
|
|
157
|
+
}
|
|
158
|
+
out.set(def.type, { rows });
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
const answer = await chatly.request('GET', def.list.path);
|
|
162
|
+
const rows = Array.isArray(answer) ? answer : [];
|
|
163
|
+
out.set(def.type, { rows, possiblyTruncated: rows.length >= EXEMPT_LIST_CAP });
|
|
164
|
+
}
|
|
165
|
+
return out;
|
|
166
|
+
}
|
|
167
|
+
/* ── plan ─────────────────────────────────────────────────────────────── */
|
|
168
|
+
export async function plan(chatly, args) {
|
|
169
|
+
const doc = loadDocument(args);
|
|
170
|
+
/*
|
|
171
|
+
* The guard first, before a single read.
|
|
172
|
+
*
|
|
173
|
+
* It was second for one revision, which meant a staging document aimed at
|
|
174
|
+
* production issued nine GETs and computed a whole diff before refusing.
|
|
175
|
+
* Harmless here because they are reads — and exactly the ordering mistake
|
|
176
|
+
* that is not harmless in `apply`, where the same code shape would have
|
|
177
|
+
* written before checking.
|
|
178
|
+
*/
|
|
179
|
+
const guard = await workspaceGuard(chatly, doc);
|
|
180
|
+
if (guard !== undefined) {
|
|
181
|
+
process.stderr.write(`${guard}\n`);
|
|
182
|
+
return 1;
|
|
183
|
+
}
|
|
184
|
+
const live = await readLive(chatly, doc);
|
|
185
|
+
const built = buildPlan(doc, live, { writeOnly: bool(args.flags, 'write-only') });
|
|
186
|
+
const opts = { prune: bool(args.flags, 'prune'), pruneUnsafe: built.pruneUnsafe };
|
|
187
|
+
if (bool(args.flags, 'json')) {
|
|
188
|
+
printJson(planForJson(built));
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
process.stdout.write(renderPlan(built, opts));
|
|
192
|
+
process.stdout.write(planFooter(built, opts));
|
|
193
|
+
}
|
|
194
|
+
/*
|
|
195
|
+
* `--exit-code`, off by default.
|
|
196
|
+
*
|
|
197
|
+
* CI wants "is production still what the repo says" as an exit status, and
|
|
198
|
+
* a plan that exits 1 by default would make `chatly plan` unusable in a
|
|
199
|
+
* shell with `set -e` for the ordinary case of looking. So the behaviour is
|
|
200
|
+
* opt-in and the code is 2 — distinct from 1, which on this CLI means the
|
|
201
|
+
* request failed, and conflating "there is drift" with "the call errored"
|
|
202
|
+
* is how a drift alarm becomes a flake alarm.
|
|
203
|
+
*/
|
|
204
|
+
if (bool(args.flags, 'exit-code')) {
|
|
205
|
+
const counts = tally(built);
|
|
206
|
+
return counts.create + counts.update + counts.blocked > 0 ? 2 : 0;
|
|
207
|
+
}
|
|
208
|
+
return built.items.some((i) => i.action === 'blocked') ? 1 : 0;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* `workspace:` in the document, against the key's actual workspace.
|
|
212
|
+
*
|
|
213
|
+
* The guard that stops a staging document reaching production. It is checked
|
|
214
|
+
* on `plan` as well as `apply` — a plan is what somebody reads before they
|
|
215
|
+
* approve, so a plan computed against the wrong workspace is a worse failure
|
|
216
|
+
* than an apply that is refused.
|
|
217
|
+
*
|
|
218
|
+
* `whoami` is a GET, so this does not spend the no-writes property.
|
|
219
|
+
*/
|
|
220
|
+
async function workspaceGuard(chatly, doc) {
|
|
221
|
+
if (doc.workspace === undefined) {
|
|
222
|
+
return undefined;
|
|
223
|
+
}
|
|
224
|
+
const me = await chatly.whoami();
|
|
225
|
+
if (me.workspaceId === doc.workspace) {
|
|
226
|
+
return undefined;
|
|
227
|
+
}
|
|
228
|
+
return (`Refusing to run: the document says \`"workspace": "${doc.workspace}"\` and this key ` +
|
|
229
|
+
`belongs to ${me.workspaceId}.\n` +
|
|
230
|
+
'Either point --key / CHATLY_API_KEY at the right workspace, or remove the `workspace` ' +
|
|
231
|
+
'line if this document is meant to be portable.');
|
|
232
|
+
}
|
|
233
|
+
/* ── apply ────────────────────────────────────────────────────────────── */
|
|
234
|
+
export async function apply(chatly, args) {
|
|
235
|
+
const doc = loadDocument(args);
|
|
236
|
+
const guard = await workspaceGuard(chatly, doc);
|
|
237
|
+
if (guard !== undefined) {
|
|
238
|
+
process.stderr.write(`${guard}\n`);
|
|
239
|
+
return 1;
|
|
240
|
+
}
|
|
241
|
+
const live = await readLive(chatly, doc);
|
|
242
|
+
const writeOnly = bool(args.flags, 'write-only');
|
|
243
|
+
const built = buildPlan(doc, live, { writeOnly });
|
|
244
|
+
const opts = {
|
|
245
|
+
prune: bool(args.flags, 'prune'),
|
|
246
|
+
pruneUnsafe: built.pruneUnsafe,
|
|
247
|
+
writeOnly,
|
|
248
|
+
};
|
|
249
|
+
if (!bool(args.flags, 'json')) {
|
|
250
|
+
// The plan, then the result. An apply that printed only its result would
|
|
251
|
+
// make the reader diff two commands' output to find out what it did.
|
|
252
|
+
process.stdout.write(renderPlan(built, opts));
|
|
253
|
+
process.stdout.write('\nApplying…\n\n');
|
|
254
|
+
}
|
|
255
|
+
const outcomes = await execute(chatly, built, opts);
|
|
256
|
+
if (bool(args.flags, 'json')) {
|
|
257
|
+
printJson({ outcomes, warnings: built.warnings });
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
process.stdout.write(renderOutcomes(outcomes));
|
|
261
|
+
}
|
|
262
|
+
return outcomes.some((o) => o.state === 'failed' || o.state === 'skipped') ? 1 : 0;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Walk the plan and do it. Continue on failure; never cascade.
|
|
266
|
+
*
|
|
267
|
+
* Exported so `wac.spec.ts` can drive it with a scripted transport and assert
|
|
268
|
+
* on the requests that went over the wire — the shape CLAUDE.md insists on
|
|
269
|
+
* ("assert on the request, not the canned response"), since a fake transport
|
|
270
|
+
* that echoes whatever the caller sent agrees with the bug.
|
|
271
|
+
*/
|
|
272
|
+
export async function execute(chatly, built, opts) {
|
|
273
|
+
const outcomes = [];
|
|
274
|
+
/** `type/key` → the id a create in THIS run returned. */
|
|
275
|
+
const refIds = new Map();
|
|
276
|
+
/** `type/key` that failed, so its dependents are skipped not attempted. */
|
|
277
|
+
const failed = new Set();
|
|
278
|
+
for (const item of built.items) {
|
|
279
|
+
const def = resourceDef(item.type);
|
|
280
|
+
if (def === undefined) {
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
const address = `${item.type}/${item.key}`;
|
|
284
|
+
if (item.action === 'noop') {
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
if (item.action === 'blocked') {
|
|
288
|
+
outcomes.push({ ...base(item), state: 'skipped', detail: item.reason, secrets: [] });
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
const blocker = item.dependsOn.find((d) => failed.has(d));
|
|
292
|
+
if (blocker !== undefined) {
|
|
293
|
+
outcomes.push({
|
|
294
|
+
...base(item),
|
|
295
|
+
state: 'skipped',
|
|
296
|
+
detail: `${blocker} failed above, and this names it. Attempting it anyway would produce a ` +
|
|
297
|
+
'second error about a missing id that points at the wrong thing.',
|
|
298
|
+
secrets: [],
|
|
299
|
+
});
|
|
300
|
+
failed.add(address);
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
const ops = writesFor(def, item, refIds, opts);
|
|
304
|
+
if (ops.length === 0) {
|
|
305
|
+
outcomes.push({
|
|
306
|
+
...base(item),
|
|
307
|
+
state: 'kept',
|
|
308
|
+
detail: item.action === 'orphan'
|
|
309
|
+
? opts.prune
|
|
310
|
+
? def.remove === null
|
|
311
|
+
? (def.removeBlocked ?? 'no DELETE route.')
|
|
312
|
+
: 'this type cannot be pruned safely on this run (see the warnings)'
|
|
313
|
+
: '`--prune` would delete it'
|
|
314
|
+
: undefined,
|
|
315
|
+
secrets: [],
|
|
316
|
+
});
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
const secrets = [];
|
|
320
|
+
let ok = true;
|
|
321
|
+
for (const op of ops) {
|
|
322
|
+
try {
|
|
323
|
+
const response = await chatly.request(op.method, op.path, op.body === undefined ? {} : { body: op.body });
|
|
324
|
+
secrets.push(...harvestSecrets(def, item, response));
|
|
325
|
+
const id = idOf(response, def);
|
|
326
|
+
if (id !== undefined) {
|
|
327
|
+
refIds.set(address, id);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
catch (err) {
|
|
331
|
+
ok = false;
|
|
332
|
+
failed.add(address);
|
|
333
|
+
outcomes.push({
|
|
334
|
+
...base(item),
|
|
335
|
+
state: 'failed',
|
|
336
|
+
detail: `${op.method} ${op.path} — ${err instanceof Error ? err.message : String(err)}`,
|
|
337
|
+
secrets,
|
|
338
|
+
});
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
if (ok) {
|
|
343
|
+
outcomes.push({ ...base(item), state: 'applied', detail: undefined, secrets });
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return outcomes;
|
|
347
|
+
}
|
|
348
|
+
function base(item) {
|
|
349
|
+
return { type: item.type, key: item.key, action: item.action };
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* The id out of a write response, for a reference a later section needs.
|
|
353
|
+
*
|
|
354
|
+
* Two levels, because `POST /v1/customer-cards` answers
|
|
355
|
+
* `{ card: { id }, secret }` rather than the card itself — the same envelope
|
|
356
|
+
* quirk that makes the secret sweep two levels deep.
|
|
357
|
+
*/
|
|
358
|
+
function idOf(response, def) {
|
|
359
|
+
if (typeof response !== 'object' || response === null) {
|
|
360
|
+
return undefined;
|
|
361
|
+
}
|
|
362
|
+
const top = response;
|
|
363
|
+
const direct = top[def.idField];
|
|
364
|
+
if (typeof direct === 'string' && direct.length > 0) {
|
|
365
|
+
return direct;
|
|
366
|
+
}
|
|
367
|
+
for (const value of Object.values(top)) {
|
|
368
|
+
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
369
|
+
const nested = value[def.idField];
|
|
370
|
+
if (typeof nested === 'string' && nested.length > 0) {
|
|
371
|
+
return nested;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return undefined;
|
|
376
|
+
}
|
|
377
|
+
//# sourceMappingURL=workspace-as-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-as-code.js","sourceRoot":"","sources":["../../src/commands/workspace-as-code.ts"],"names":[],"mappings":"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"}
|
package/dist/help.d.ts
CHANGED
|
@@ -1,2 +1,26 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* `--help`, and the one thing it has to be: complete.
|
|
3
|
+
*
|
|
4
|
+
* ── Why this is 22 sections and not 7 ─────────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* It was 7. `run.ts`'s own docblock said a check "makes certain that every
|
|
7
|
+
* command documented in `--help` is reachable — a command with no help entry
|
|
8
|
+
* is a command nobody finds", and no such check existed: fifteen of the
|
|
9
|
+
* twenty-two command groups had never been mentioned here, among them `ai`,
|
|
10
|
+
* `billing`, `bot-routes`, `brands`, `customer-cards`, `docs-sources`,
|
|
11
|
+
* `email-templates`, `knowledge-gaps`, `macros` and `triggers`.
|
|
12
|
+
*
|
|
13
|
+
* A CLI's help IS its documentation. An undocumented command is an unshipped
|
|
14
|
+
* command, however complete its implementation — the same defect
|
|
15
|
+
* `check-endpoint-with-no-caller` exists for one layer down.
|
|
16
|
+
*
|
|
17
|
+
* `cli.spec.ts` now checks BOTH directions on every run: every key in
|
|
18
|
+
* `COMMANDS` appears here, and every command word here resolves through
|
|
19
|
+
* `COMMANDS` or `ALIASES`. The first half is what was missing; the second is
|
|
20
|
+
* what stops this file growing a promise the CLI does not keep.
|
|
21
|
+
*
|
|
22
|
+
* The convention the spec relies on: a command line starts with exactly two
|
|
23
|
+
* spaces and its first word is the command group.
|
|
24
|
+
*/
|
|
25
|
+
export declare const HELP = "chatly \u2014 the Chatly command line\n\nUSAGE\n chatly <command> [subcommand] [flags]\n\nAUTH\n login Store an API key in ~/.config/chatly/config.json (0600)\n logout Remove the stored key\n whoami Which workspace this key belongs to, and its scopes\n\nCONVERSATIONS\n conversations list Open conversations, newest first\n conversations get <id> One conversation\n conversations messages <id> The thread\n conversations send <id> <body>\n Reply as the key's machine identity\n conversations unattended Open with no agent reply yet\n conversations mood <id> Sentiment over the thread\n conversations return-to-bot <id> <bot-id>\n Give an open thread back to an assistant\n\nCONTACTS\n contacts list People in this workspace\n contacts get <id>\n contacts upsert --email --name --external-id --phone\n contacts tag <id> <tag> Add a tag\n contacts journey <id> Timeline: conversations, events, tickets\n contacts cards <id> Customer-card data for this person\n\nTICKETS\n tickets list --status --queue\n tickets get <id>\n tickets comments <id>\n tickets queues\n tickets lineage <id> Merge and split history\n tickets time <id> Time logged\n tickets status-history <id>\n\nKNOWLEDGE + SEARCH\n search <query> Across contacts, conversations, messages, tickets, KB\n kb articles Help-centre articles\n kb article <slug>\n kb collections\n\nEVENTS\n events track <contact-id> <name>\n Fire a CDP event. --prop key=value, repeatable\n events list --contact-id\n\nBOTS + EXTERNAL AGENTS\n bots list | get <id>\n bots create --body. type:\"external\" answers with a secret, ONCE\n bots update <id> --body\n bots update-external <id> --body. webhookUrl, timeoutSeconds, fallbackMessage\n bots rotate-secret <id> New signing secret, shown once. No overlap window\n bots deliveries <id> The push ledger. --status pending|delivered|failed|dead\n bots delivery <id> <delivery-id>\n One delivery, with the exact signed payload\n bots redeliver <id> <delivery-id>\n Queue the recorded payload again, from attempt 0\n bots test-delivery <id> Sign and POST a rehearsal payload; prints the response\n\nROUTING + AUTOMATION\n bot-routes list | fields | create | update <id> | delete <id>\n bot-routes resolve Dry-run the table. --body with a hypothetical visitor\n triggers list | get <id> | upsert | delete <id>\n brands list | get <id> | create | update <id> | delete <id>\n macros list | get <id> | create | update <id> | delete <id>\n email-templates templates | get <kind> | set <kind> | reset <kind>\n knowledge-gaps list | triage <id>\n\nINTEGRATIONS\n webhooks deliveries --status\n webhooks delivery <id>\n webhooks redeliver <id>\n webhooks endpoints Subscriptions, not traffic\n webhooks events The subscribable event catalogue\n webhooks schema-versions\n webhooks create --url --event (repeatable). Answers with whsec_, once\n webhooks pin <id> <version>\n customer-cards list | create | update <id> | delete <id>\n customer-cards rotate-secret <id>\n Update your endpoint BEFORE calling this\n docs-sources list | providers | discover | create | update <id> | delete <id>\n docs-sources sync <id> --full re-reads every page\n docs-sources subscribe <id> A refusal is a success: read the response\n channels list | get <id> | adapters | create | update <id>\n channels rotate-secret <id>\n\nWORKSPACE AS CODE\n plan Diff chatly.json against the live workspace. Reads only\n apply Make the plan's changes. Never deletes unless told\n --file <path> the document (- for stdin). Default: ./chatly.json\n --prune also delete what the document omits\n --write-only also send fields that cannot be read back\n --exit-code plan only: exit 2 when there is drift\n\nAI\n ai providers | quota\n ai add-provider BYOK. --body\n ai test-provider <key>\n ai tools | create-tool | update-tool <id> | delete-tool <id>\n ai tone | set-tone | generate-tone <sample>\n\nREPORTS\n reports overview --days\n reports agents Means, not percentiles\n reports conversations-by-day\n reports sources | response-times | voice\n reports attribution <dim> One of ten dimensions; an unknown one is refused\n reports cohorts --weeks, NOT --days\n reports themes --date. A daily snapshot; there is no regenerate\n reports theme-conversations <theme-id>\n reports teams | labels | sla\n --from --to --days --group-by\n\nBILLING\n billing summary | plans | invoices\n billing usage <event-type> One meter over a window. --from --to\n billing usage-daily <event-type>\n Dense: one row per UTC day, zeros included\n billing usage-monthly --month\n\nWORKSPACE\n workspace settings\n workspace labels | inboxes | skills\n workspace team-members <team-id>\n workspace key-scopes What a key may be granted\n\nRAW\n api <METHOD> <path> Any route, with auth, idempotency and retries\n chatly api GET /v1/feature-flags\n chatly api POST /v1/macros --body '{\"name\":\"Refund\"}'\n\nGLOBAL FLAGS\n --json Raw API response instead of a table\n --all Follow pagination to the end (list commands)\n --limit <n> Page size\n --cursor <c> Start from a cursor\n --key <ck_\u2026> Override the stored key for this call\n --api-url <url> Point at another Chatly environment\n --help, --version\n\nDocs: https://chatlychat.com/docs/sdk-cli\n";
|
|
2
26
|
//# sourceMappingURL=help.d.ts.map
|
package/dist/help.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,IAAI,8lMAgJhB,CAAC"}
|
package/dist/help.js
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `--help`, and the one thing it has to be: complete.
|
|
3
|
+
*
|
|
4
|
+
* ── Why this is 22 sections and not 7 ─────────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* It was 7. `run.ts`'s own docblock said a check "makes certain that every
|
|
7
|
+
* command documented in `--help` is reachable — a command with no help entry
|
|
8
|
+
* is a command nobody finds", and no such check existed: fifteen of the
|
|
9
|
+
* twenty-two command groups had never been mentioned here, among them `ai`,
|
|
10
|
+
* `billing`, `bot-routes`, `brands`, `customer-cards`, `docs-sources`,
|
|
11
|
+
* `email-templates`, `knowledge-gaps`, `macros` and `triggers`.
|
|
12
|
+
*
|
|
13
|
+
* A CLI's help IS its documentation. An undocumented command is an unshipped
|
|
14
|
+
* command, however complete its implementation — the same defect
|
|
15
|
+
* `check-endpoint-with-no-caller` exists for one layer down.
|
|
16
|
+
*
|
|
17
|
+
* `cli.spec.ts` now checks BOTH directions on every run: every key in
|
|
18
|
+
* `COMMANDS` appears here, and every command word here resolves through
|
|
19
|
+
* `COMMANDS` or `ALIASES`. The first half is what was missing; the second is
|
|
20
|
+
* what stops this file growing a promise the CLI does not keep.
|
|
21
|
+
*
|
|
22
|
+
* The convention the spec relies on: a command line starts with exactly two
|
|
23
|
+
* spaces and its first word is the command group.
|
|
24
|
+
*/
|
|
1
25
|
export const HELP = `chatly — the Chatly command line
|
|
2
26
|
|
|
3
27
|
USAGE
|
|
@@ -15,6 +39,9 @@ CONVERSATIONS
|
|
|
15
39
|
conversations send <id> <body>
|
|
16
40
|
Reply as the key's machine identity
|
|
17
41
|
conversations unattended Open with no agent reply yet
|
|
42
|
+
conversations mood <id> Sentiment over the thread
|
|
43
|
+
conversations return-to-bot <id> <bot-id>
|
|
44
|
+
Give an open thread back to an assistant
|
|
18
45
|
|
|
19
46
|
CONTACTS
|
|
20
47
|
contacts list People in this workspace
|
|
@@ -22,38 +49,107 @@ CONTACTS
|
|
|
22
49
|
contacts upsert --email --name --external-id --phone
|
|
23
50
|
contacts tag <id> <tag> Add a tag
|
|
24
51
|
contacts journey <id> Timeline: conversations, events, tickets
|
|
52
|
+
contacts cards <id> Customer-card data for this person
|
|
25
53
|
|
|
26
54
|
TICKETS
|
|
27
55
|
tickets list --status --queue
|
|
56
|
+
tickets get <id>
|
|
28
57
|
tickets comments <id>
|
|
29
58
|
tickets queues
|
|
59
|
+
tickets lineage <id> Merge and split history
|
|
60
|
+
tickets time <id> Time logged
|
|
61
|
+
tickets status-history <id>
|
|
30
62
|
|
|
31
63
|
KNOWLEDGE + SEARCH
|
|
32
64
|
search <query> Across contacts, conversations, messages, tickets, KB
|
|
33
65
|
kb articles Help-centre articles
|
|
34
66
|
kb article <slug>
|
|
67
|
+
kb collections
|
|
35
68
|
|
|
36
69
|
EVENTS
|
|
37
70
|
events track <contact-id> <name>
|
|
38
71
|
Fire a CDP event. --prop key=value, repeatable
|
|
39
72
|
events list --contact-id
|
|
40
73
|
|
|
41
|
-
|
|
74
|
+
BOTS + EXTERNAL AGENTS
|
|
75
|
+
bots list | get <id>
|
|
76
|
+
bots create --body. type:"external" answers with a secret, ONCE
|
|
77
|
+
bots update <id> --body
|
|
78
|
+
bots update-external <id> --body. webhookUrl, timeoutSeconds, fallbackMessage
|
|
79
|
+
bots rotate-secret <id> New signing secret, shown once. No overlap window
|
|
80
|
+
bots deliveries <id> The push ledger. --status pending|delivered|failed|dead
|
|
81
|
+
bots delivery <id> <delivery-id>
|
|
82
|
+
One delivery, with the exact signed payload
|
|
83
|
+
bots redeliver <id> <delivery-id>
|
|
84
|
+
Queue the recorded payload again, from attempt 0
|
|
85
|
+
bots test-delivery <id> Sign and POST a rehearsal payload; prints the response
|
|
86
|
+
|
|
87
|
+
ROUTING + AUTOMATION
|
|
88
|
+
bot-routes list | fields | create | update <id> | delete <id>
|
|
89
|
+
bot-routes resolve Dry-run the table. --body with a hypothetical visitor
|
|
90
|
+
triggers list | get <id> | upsert | delete <id>
|
|
91
|
+
brands list | get <id> | create | update <id> | delete <id>
|
|
92
|
+
macros list | get <id> | create | update <id> | delete <id>
|
|
93
|
+
email-templates templates | get <kind> | set <kind> | reset <kind>
|
|
94
|
+
knowledge-gaps list | triage <id>
|
|
95
|
+
|
|
96
|
+
INTEGRATIONS
|
|
42
97
|
webhooks deliveries --status
|
|
98
|
+
webhooks delivery <id>
|
|
43
99
|
webhooks redeliver <id>
|
|
100
|
+
webhooks endpoints Subscriptions, not traffic
|
|
101
|
+
webhooks events The subscribable event catalogue
|
|
102
|
+
webhooks schema-versions
|
|
103
|
+
webhooks create --url --event (repeatable). Answers with whsec_, once
|
|
104
|
+
webhooks pin <id> <version>
|
|
105
|
+
customer-cards list | create | update <id> | delete <id>
|
|
106
|
+
customer-cards rotate-secret <id>
|
|
107
|
+
Update your endpoint BEFORE calling this
|
|
108
|
+
docs-sources list | providers | discover | create | update <id> | delete <id>
|
|
109
|
+
docs-sources sync <id> --full re-reads every page
|
|
110
|
+
docs-sources subscribe <id> A refusal is a success: read the response
|
|
111
|
+
channels list | get <id> | adapters | create | update <id>
|
|
112
|
+
channels rotate-secret <id>
|
|
113
|
+
|
|
114
|
+
WORKSPACE AS CODE
|
|
115
|
+
plan Diff chatly.json against the live workspace. Reads only
|
|
116
|
+
apply Make the plan's changes. Never deletes unless told
|
|
117
|
+
--file <path> the document (- for stdin). Default: ./chatly.json
|
|
118
|
+
--prune also delete what the document omits
|
|
119
|
+
--write-only also send fields that cannot be read back
|
|
120
|
+
--exit-code plan only: exit 2 when there is drift
|
|
121
|
+
|
|
122
|
+
AI
|
|
123
|
+
ai providers | quota
|
|
124
|
+
ai add-provider BYOK. --body
|
|
125
|
+
ai test-provider <key>
|
|
126
|
+
ai tools | create-tool | update-tool <id> | delete-tool <id>
|
|
127
|
+
ai tone | set-tone | generate-tone <sample>
|
|
44
128
|
|
|
45
129
|
REPORTS
|
|
46
|
-
reports overview --
|
|
47
|
-
reports agents
|
|
48
|
-
reports
|
|
130
|
+
reports overview --days
|
|
131
|
+
reports agents Means, not percentiles
|
|
132
|
+
reports conversations-by-day
|
|
133
|
+
reports sources | response-times | voice
|
|
134
|
+
reports attribution <dim> One of ten dimensions; an unknown one is refused
|
|
135
|
+
reports cohorts --weeks, NOT --days
|
|
136
|
+
reports themes --date. A daily snapshot; there is no regenerate
|
|
137
|
+
reports theme-conversations <theme-id>
|
|
138
|
+
reports teams | labels | sla
|
|
139
|
+
--from --to --days --group-by
|
|
140
|
+
|
|
141
|
+
BILLING
|
|
142
|
+
billing summary | plans | invoices
|
|
143
|
+
billing usage <event-type> One meter over a window. --from --to
|
|
144
|
+
billing usage-daily <event-type>
|
|
145
|
+
Dense: one row per UTC day, zeros included
|
|
146
|
+
billing usage-monthly --month
|
|
49
147
|
|
|
50
148
|
WORKSPACE
|
|
51
149
|
workspace settings
|
|
52
150
|
workspace labels | inboxes | skills
|
|
53
151
|
workspace team-members <team-id>
|
|
54
|
-
|
|
55
|
-
billing usage <event-type> One meter over a window. --from --to
|
|
56
|
-
billing plans
|
|
152
|
+
workspace key-scopes What a key may be granted
|
|
57
153
|
|
|
58
154
|
RAW
|
|
59
155
|
api <METHOD> <path> Any route, with auth, idempotency and retries
|
|
@@ -69,6 +165,6 @@ GLOBAL FLAGS
|
|
|
69
165
|
--api-url <url> Point at another Chatly environment
|
|
70
166
|
--help, --version
|
|
71
167
|
|
|
72
|
-
Docs: https://chatlychat.com/docs/cli
|
|
168
|
+
Docs: https://chatlychat.com/docs/sdk-cli
|
|
73
169
|
`;
|
|
74
170
|
//# sourceMappingURL=help.js.map
|
package/dist/help.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,IAAI,GAAG
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgJnB,CAAC"}
|
package/dist/run.d.ts
CHANGED
|
@@ -7,6 +7,23 @@
|
|
|
7
7
|
* errors are unhelpful, we feel it first.
|
|
8
8
|
*/
|
|
9
9
|
import { ChatlyClient } from '@chatlychat/sdk-node';
|
|
10
|
+
import { type ParsedArgs } from './args.js';
|
|
11
|
+
/**
|
|
12
|
+
* Every authenticated command, by the word a person types.
|
|
13
|
+
*
|
|
14
|
+
* A table rather than a `switch`, for one reason that is worth the churn:
|
|
15
|
+
* `cli.spec.ts` can now assert that every key here appears in `--help` and
|
|
16
|
+
* that every command documented in `--help` is reachable. A command with no
|
|
17
|
+
* help entry is a command nobody finds; a help entry with no command is a
|
|
18
|
+
* promise the CLI breaks. The `switch` this replaced could be checked for
|
|
19
|
+
* neither.
|
|
20
|
+
*
|
|
21
|
+
* Singular aliases are listed explicitly rather than derived by stripping an
|
|
22
|
+
* `s`, so `kb`, `search`, `whoami` and `ai` cannot acquire a nonsense twin.
|
|
23
|
+
*/
|
|
24
|
+
export declare const COMMANDS: Readonly<Record<string, (c: ChatlyClient, a: ParsedArgs) => Promise<number>>>;
|
|
25
|
+
/** Singular spellings, for the groups where typing one reads naturally. */
|
|
26
|
+
export declare const ALIASES: Readonly<Record<string, string>>;
|
|
10
27
|
/**
|
|
11
28
|
* How a client is made. Injectable for tests ONLY.
|
|
12
29
|
*
|
package/dist/run.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAkB,YAAY,EAAwB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAkB,YAAY,EAAwB,MAAM,sBAAsB,CAAC;AAE1F,OAAO,EAAwB,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAyBlE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,QAAQ,EAAE,QAAQ,CAC7B,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,CA+CpE,CAAC;AAEF,2EAA2E;AAC3E,eAAO,MAAM,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiBpD,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,YAAY,CAAC;AAIxF,wBAAsB,GAAG,CACvB,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,UAAU,GAAE,aAA8B,GACzC,OAAO,CAAC,MAAM,CAAC,CAkDjB;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAqBvE"}
|