@chatlychat/cli 0.1.3 → 0.1.5
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 +100 -191
- 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 +3 -2
- 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 @@
|
|
|
1
|
+
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/commands/ai.ts"],"names":[],"mappings":"AAUA,OAAO,EAAa,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAIxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,wBAAsB,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAkLhF"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The AI configuration surface: tools, tone, provider keys and spend.
|
|
3
|
+
*
|
|
4
|
+
* Tools and tone rules are config-as-code — the body is a document, as in
|
|
5
|
+
* `config.ts`. Provider keys and quota are not: `add-provider` is two
|
|
6
|
+
* scalars, and quota is a read an operator makes to answer "are we about to
|
|
7
|
+
* be cut off".
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync } from 'node:fs';
|
|
10
|
+
import { bool, str } from '../args.js';
|
|
11
|
+
import { printJson } from '../output.js';
|
|
12
|
+
import { bodyFrom, need, showObject, showRows } from './common.js';
|
|
13
|
+
export async function ai(chatly, args) {
|
|
14
|
+
const sub = args.path[1] ?? 'quota';
|
|
15
|
+
switch (sub) {
|
|
16
|
+
// ── Spend ─────────────────────────────────────────────────────────────
|
|
17
|
+
case 'quota': {
|
|
18
|
+
/*
|
|
19
|
+
* Three spend figures, and reporting one as another is the mistake this
|
|
20
|
+
* endpoint exists to prevent:
|
|
21
|
+
*
|
|
22
|
+
* spent / platformSpent — month-to-date on the PLATFORM's key. The
|
|
23
|
+
* only spend `budget` bounds and the only
|
|
24
|
+
* spend that can get a call refused.
|
|
25
|
+
* byokSpent — on the workspace's OWN key. Metered so the
|
|
26
|
+
* customer can see it; never capped.
|
|
27
|
+
* totalSpent — the two together.
|
|
28
|
+
*
|
|
29
|
+
* `budget: null` is uncapped (free with BYOK, enterprise), not an
|
|
30
|
+
* error. The table labels each figure rather than picking one, because
|
|
31
|
+
* a BYOK-heavy workspace shown `spent` against `budget` reads "$412 of
|
|
32
|
+
* $5" for money nobody spent.
|
|
33
|
+
*/
|
|
34
|
+
const q = await chatly.request('GET', '/v1/ai/quota');
|
|
35
|
+
if (bool(args.flags, 'json')) {
|
|
36
|
+
printJson(q);
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
const money = (v) => v === null || v === undefined ? '—' : `$${v.toFixed(2)}`;
|
|
40
|
+
process.stdout.write(`plan ${q.plan ?? '—'} (${q.periodKey ?? '—'})\n`);
|
|
41
|
+
process.stdout.write(`platform spend ${money(q.platformSpent ?? q.spent)} (capped)\n`);
|
|
42
|
+
process.stdout.write(`your-key spend ${money(q.byokSpent)} (never capped)\n`);
|
|
43
|
+
process.stdout.write(`total spend ${money(q.totalSpent)}\n`);
|
|
44
|
+
process.stdout.write(`platform budget ${q.budget === null || q.budget === undefined ? 'unlimited' : money(q.budget)}` +
|
|
45
|
+
`${q.remaining === null || q.remaining === undefined ? '' : `, ${money(q.remaining)} left`}\n`);
|
|
46
|
+
if (q.warn === true) {
|
|
47
|
+
process.stdout.write('\nwarning: nearing the platform cap.\n');
|
|
48
|
+
}
|
|
49
|
+
if (q.projectedExhaustionAt !== null && q.projectedExhaustionAt !== undefined) {
|
|
50
|
+
process.stdout.write(`projected exhaustion ${q.projectedExhaustionAt}\n`);
|
|
51
|
+
}
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
// ── Provider keys ─────────────────────────────────────────────────────
|
|
55
|
+
case 'providers':
|
|
56
|
+
return showRows(args, await chatly.request('GET', '/v1/ai-providers'), [
|
|
57
|
+
'provider',
|
|
58
|
+
'status',
|
|
59
|
+
'lastValidatedAt',
|
|
60
|
+
'message',
|
|
61
|
+
]);
|
|
62
|
+
case 'add-provider': {
|
|
63
|
+
/*
|
|
64
|
+
* `{ provider, apiKey }` — the names are `connectSchema`'s. The key is
|
|
65
|
+
* validated against the provider on save, and only an
|
|
66
|
+
* authentication-class answer refuses the write: `unverified` means
|
|
67
|
+
* stored but unproven, not failed.
|
|
68
|
+
*/
|
|
69
|
+
const provider = args.path[2] ?? str(args.flags, 'provider');
|
|
70
|
+
const apiKey = str(args.flags, 'api-key');
|
|
71
|
+
if (provider === undefined || apiKey === undefined) {
|
|
72
|
+
throw new Error('Give a provider and a key: `chatly ai add-provider openai --api-key sk-…`.\n' +
|
|
73
|
+
'`chatly ai providers` lists what is connected.');
|
|
74
|
+
}
|
|
75
|
+
return showObject(await chatly.request('POST', '/v1/ai-providers', { body: { provider, apiKey } }));
|
|
76
|
+
}
|
|
77
|
+
case 'test-provider':
|
|
78
|
+
// Re-checks the STORED key against the provider. Nothing is sent.
|
|
79
|
+
return showObject(await chatly.request('POST', `/v1/ai-providers/${encodeURIComponent(need(args, 2, 'a provider'))}/test`));
|
|
80
|
+
// ── Tools ─────────────────────────────────────────────────────────────
|
|
81
|
+
case 'tools':
|
|
82
|
+
// Secret header VALUES are never returned — `secretHeaderNames` is the
|
|
83
|
+
// list of which ones are set.
|
|
84
|
+
return showRows(args, await chatly.request('GET', '/v1/ai/tools'), [
|
|
85
|
+
'id',
|
|
86
|
+
'name',
|
|
87
|
+
'method',
|
|
88
|
+
'urlTemplate',
|
|
89
|
+
'enabled',
|
|
90
|
+
'requiresApproval',
|
|
91
|
+
]);
|
|
92
|
+
case 'create-tool':
|
|
93
|
+
return showObject(await chatly.request('POST', '/v1/ai/tools', { body: bodyFrom(args, 'the tool') }));
|
|
94
|
+
case 'update-tool':
|
|
95
|
+
// Omit `secretHeaders` to KEEP the stored values. Sending an empty
|
|
96
|
+
// object is not the same as omitting the key.
|
|
97
|
+
return showObject(await chatly.request('PATCH', `/v1/ai/tools/${encodeURIComponent(need(args, 2, 'a tool id'))}`, { body: bodyFrom(args, 'the fields to change') }));
|
|
98
|
+
case 'delete-tool':
|
|
99
|
+
return showObject(await chatly.request('DELETE', `/v1/ai/tools/${encodeURIComponent(need(args, 2, 'a tool id'))}`));
|
|
100
|
+
// ── Tone ──────────────────────────────────────────────────────────────
|
|
101
|
+
case 'tone':
|
|
102
|
+
return showRows(args, await chatly.request('GET', '/v1/ai/tone'), [
|
|
103
|
+
'id',
|
|
104
|
+
'category',
|
|
105
|
+
'rule',
|
|
106
|
+
'enabled',
|
|
107
|
+
'position',
|
|
108
|
+
]);
|
|
109
|
+
case 'set-tone':
|
|
110
|
+
/*
|
|
111
|
+
* A PUT that REPLACES the whole rule set. The body is `{ rules: [...] }`
|
|
112
|
+
* — a document, and the wrapper key matters: a bare array is an unknown
|
|
113
|
+
* shape to `toneRulesWriteSchema`.
|
|
114
|
+
*
|
|
115
|
+
* There is no merge route. Read `chatly ai tone --json`, edit, send it
|
|
116
|
+
* all back.
|
|
117
|
+
*/
|
|
118
|
+
return showObject(await chatly.request('PUT', '/v1/ai/tone', {
|
|
119
|
+
body: bodyFrom(args, 'the complete rule set, as { "rules": [ … ] }'),
|
|
120
|
+
}));
|
|
121
|
+
case 'generate-tone': {
|
|
122
|
+
/*
|
|
123
|
+
* Proposes rules from a pasted style guide and SAVES NOTHING — the
|
|
124
|
+
* output is a draft for a person to approve and then `set-tone`.
|
|
125
|
+
*
|
|
126
|
+
* The field is `styleGuide`, minimum 40 characters. A guide is usually
|
|
127
|
+
* a document, so `--file` reads it as TEXT here rather than as JSON —
|
|
128
|
+
* this is the one write on the surface whose input is prose.
|
|
129
|
+
*/
|
|
130
|
+
const file = str(args.flags, 'file');
|
|
131
|
+
const inline = str(args.flags, 'style-guide');
|
|
132
|
+
let styleGuide;
|
|
133
|
+
if (file !== undefined) {
|
|
134
|
+
styleGuide = file === '-' ? readFileSync(0, 'utf8') : readFileSync(file, 'utf8');
|
|
135
|
+
}
|
|
136
|
+
else if (inline !== undefined) {
|
|
137
|
+
styleGuide = inline;
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
throw new Error('Give a style guide: `chatly ai generate-tone --file ./voice.md`, or ' +
|
|
141
|
+
"--style-guide 'your house style…'.\nIt must be at least 40 characters.");
|
|
142
|
+
}
|
|
143
|
+
return showObject(await chatly.request('POST', '/v1/ai/tone/generate', { body: { styleGuide } }));
|
|
144
|
+
}
|
|
145
|
+
default:
|
|
146
|
+
throw new Error(`Unknown: ai ${sub}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=ai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/commands/ai.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,IAAI,EAAE,GAAG,EAAmB,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAInE,MAAM,CAAC,KAAK,UAAU,EAAE,CAAC,MAAoB,EAAE,IAAgB;IAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC;IACpC,QAAQ,GAAG,EAAE,CAAC;QACZ,yEAAyE;QACzE,KAAK,OAAO,CAAC,CAAC,CAAC;YACb;;;;;;;;;;;;;;;eAeG;YACH,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,OAAO,CAW3B,KAAK,EAAE,cAAc,CAAC,CAAC;YAC1B,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;gBAC7B,SAAS,CAAC,CAAC,CAAC,CAAC;gBACb,OAAO,CAAC,CAAC;YACX,CAAC;YACD,MAAM,KAAK,GAAG,CAAC,CAA4B,EAAU,EAAE,CACrD,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,IAAI,IAAI,GAAG,MAAM,CAAC,CAAC,SAAS,IAAI,GAAG,KAAK,CAAC,CAAC;YACtF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,KAAK,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAC3F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;YAClF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACnE,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,qBAAqB,CAAC,CAAC,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE;gBAChG,GAAG,CAAC,CAAC,SAAS,KAAK,IAAI,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,IAAI,CACjG,CAAC;YACF,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;YACjE,CAAC;YACD,IAAI,CAAC,CAAC,qBAAqB,KAAK,IAAI,IAAI,CAAC,CAAC,qBAAqB,KAAK,SAAS,EAAE,CAAC;gBAC9E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,qBAAqB,IAAI,CAAC,CAAC;YAC7E,CAAC;YACD,OAAO,CAAC,CAAC;QACX,CAAC;QAED,yEAAyE;QACzE,KAAK,WAAW;YACd,OAAO,QAAQ,CAAC,IAAI,EAAE,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,kBAAkB,CAAC,EAAE;gBACrE,UAAU;gBACV,QAAQ;gBACR,iBAAiB;gBACjB,SAAS;aACV,CAAC,CAAC;QACL,KAAK,cAAc,CAAC,CAAC,CAAC;YACpB;;;;;eAKG;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;YAC7D,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YAC1C,IAAI,QAAQ,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACnD,MAAM,IAAI,KAAK,CACb,8EAA8E;oBAC5E,gDAAgD,CACnD,CAAC;YACJ,CAAC;YACD,OAAO,UAAU,CACf,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,kBAAkB,EAAE,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,CACjF,CAAC;QACJ,CAAC;QACD,KAAK,eAAe;YAClB,kEAAkE;YAClE,OAAO,UAAU,CACf,MAAM,MAAM,CAAC,OAAO,CAClB,MAAM,EACN,oBAAoB,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC,OAAO,CAC3E,CACF,CAAC;QAEJ,yEAAyE;QACzE,KAAK,OAAO;YACV,uEAAuE;YACvE,8BAA8B;YAC9B,OAAO,QAAQ,CAAC,IAAI,EAAE,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,cAAc,CAAC,EAAE;gBACjE,IAAI;gBACJ,MAAM;gBACN,QAAQ;gBACR,aAAa;gBACb,SAAS;gBACT,kBAAkB;aACnB,CAAC,CAAC;QACL,KAAK,aAAa;YAChB,OAAO,UAAU,CACf,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC,CACnF,CAAC;QACJ,KAAK,aAAa;YAChB,mEAAmE;YACnE,8CAA8C;YAC9C,OAAO,UAAU,CACf,MAAM,MAAM,CAAC,OAAO,CAClB,OAAO,EACP,gBAAgB,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,EAChE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC,EAAE,CACjD,CACF,CAAC;QACJ,KAAK,aAAa;YAChB,OAAO,UAAU,CACf,MAAM,MAAM,CAAC,OAAO,CAClB,QAAQ,EACR,gBAAgB,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,CACjE,CACF,CAAC;QAEJ,yEAAyE;QACzE,KAAK,MAAM;YACT,OAAO,QAAQ,CAAC,IAAI,EAAE,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,aAAa,CAAC,EAAE;gBAChE,IAAI;gBACJ,UAAU;gBACV,MAAM;gBACN,SAAS;gBACT,UAAU;aACX,CAAC,CAAC;QACL,KAAK,UAAU;YACb;;;;;;;eAOG;YACH,OAAO,UAAU,CACf,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,aAAa,EAAE;gBACzC,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,8CAA8C,CAAC;aACrE,CAAC,CACH,CAAC;QACJ,KAAK,eAAe,CAAC,CAAC,CAAC;YACrB;;;;;;;eAOG;YACH,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACrC,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;YAC9C,IAAI,UAAkB,CAAC;YACvB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,UAAU,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACnF,CAAC;iBAAM,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBAChC,UAAU,GAAG,MAAM,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CACb,sEAAsE;oBACpE,wEAAwE,CAC3E,CAAC;YACJ,CAAC;YACD,OAAO,UAAU,CACf,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,sBAAsB,EAAE,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAC/E,CAAC;QACJ,CAAC;QACD;YACE,MAAM,IAAI,KAAK,CAAC,eAAe,GAAG,EAAE,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { type ParsedArgs } from '../args.js';
|
|
2
|
+
import type { ChatlyClient, Query } from '@chatlychat/sdk-node';
|
|
3
|
+
/** Shared list behaviour: one page, or every page with `--all`. */
|
|
4
|
+
export declare function renderList(args: ParsedArgs, columns: ReadonlyArray<string>, onePage: (query: Record<string, string | number>) => Promise<unknown>, everyPage?: () => AsyncGenerator<unknown, void, void>): Promise<number>;
|
|
5
|
+
/**
|
|
6
|
+
* A table for a route that answers a bare array, or an object wrapping one.
|
|
7
|
+
*
|
|
8
|
+
* Deliberately NOT `renderList`: these routes are `@PaginationExempt` and
|
|
9
|
+
* have no cursor, so printing a "next page" hint or accepting `--all` would
|
|
10
|
+
* promise a walk that does not exist. `--all` on one of these falls through
|
|
11
|
+
* to `renderList`'s refusal only when the caller passes it; here it is simply
|
|
12
|
+
* not offered.
|
|
13
|
+
*/
|
|
14
|
+
export declare function showRows(args: ParsedArgs, value: unknown, columns: ReadonlyArray<string>, max?: number): number;
|
|
15
|
+
/** An object read: there is no table shape worth inventing, so print the JSON. */
|
|
16
|
+
export declare function showObject(value: unknown): number;
|
|
17
|
+
export declare function need(args: ParsedArgs, index: number, what: string): string;
|
|
18
|
+
/** `--prop key=value`, repeatable, into an object. */
|
|
19
|
+
export declare function props(args: ParsedArgs): Record<string, string> | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* One flag spec: the flag a person types, the name the API reads, and whether
|
|
22
|
+
* it must be a number.
|
|
23
|
+
*
|
|
24
|
+
* ── Why the wire name is written out ──────────────────────────────────────
|
|
25
|
+
*
|
|
26
|
+
* The API validates every query with zod and zod object schemas STRIP an
|
|
27
|
+
* unknown key, so a parameter under the wrong name produces a 200 and a
|
|
28
|
+
* server that quietly did something else. That shipped in three callers at
|
|
29
|
+
* once with `kinds[]` on `/v1/search`. The names on the right of these
|
|
30
|
+
* tuples are read off the handler's schema in `apps/api/src/modules/**`, not
|
|
31
|
+
* off the route's name, and several do not match what the name suggests:
|
|
32
|
+
* `/v1/reports/cohorts` takes `weeks` and ignores `days`,
|
|
33
|
+
* `/v1/reports/attribution` takes `dimension` and REFUSES an unknown value,
|
|
34
|
+
* `/v1/macros` takes `query` rather than `q`, and the two extended-report
|
|
35
|
+
* routes take snake_case `group_by` / `business_hours` while every other
|
|
36
|
+
* parameter in the API is camelCase.
|
|
37
|
+
*/
|
|
38
|
+
export type FlagSpec = readonly [flag: string, wire: string, numeric?: boolean];
|
|
39
|
+
/** Build a query from the flags that were actually passed. Absent flags are absent. */
|
|
40
|
+
export declare function queryFrom(args: ParsedArgs, specs: ReadonlyArray<FlagSpec>): Query;
|
|
41
|
+
/** `--days`, the window every `reports.*` route but three reads. */
|
|
42
|
+
export declare const DAYS: ReadonlyArray<FlagSpec>;
|
|
43
|
+
/**
|
|
44
|
+
* The full window contract, which only `reports/teams`, `reports/labels` and
|
|
45
|
+
* `reports/sla` accept. `--from`/`--to` on any other report is silently
|
|
46
|
+
* ignored by the handler, which is why they are not offered there.
|
|
47
|
+
*/
|
|
48
|
+
export declare const RANGE: ReadonlyArray<FlagSpec>;
|
|
49
|
+
/**
|
|
50
|
+
* A JSON body, from a file, from stdin, or inline.
|
|
51
|
+
*
|
|
52
|
+
* ── Why config writes take a document and not twenty flags ───────────────
|
|
53
|
+
*
|
|
54
|
+
* The bodies on this surface are nested objects — a bot carries guardrails,
|
|
55
|
+
* a kb scope and an escalation-rule array; a routing rule carries a
|
|
56
|
+
* condition list. Twenty flags per command would be a worse CLI and a second
|
|
57
|
+
* place for a key name to be spelled wrong. The body goes to the API exactly
|
|
58
|
+
* as written, so the schema in `apps/api` is the only spelling that matters.
|
|
59
|
+
*
|
|
60
|
+
* Note what that does and does not buy: the API still strips a key this file
|
|
61
|
+
* has never heard of, so a typo in YOUR json is a 200 that did nothing. The
|
|
62
|
+
* CLI simply refuses to add a second renaming layer on top.
|
|
63
|
+
*/
|
|
64
|
+
export declare function bodyFrom(args: ParsedArgs, what: string): unknown;
|
|
65
|
+
/**
|
|
66
|
+
* A cursor-paginated route the SDK has no typed walker for yet.
|
|
67
|
+
*
|
|
68
|
+
* Both halves go through `ChatlyClient.request` — the escape hatch the SDK
|
|
69
|
+
* contract defines for the key-accessible routes with no named method — so
|
|
70
|
+
* auth, the idempotency key, the retry policy and the typed errors are the
|
|
71
|
+
* same ones every other command gets. The walk is the SDK's own
|
|
72
|
+
* `autoPaginate`, which stops on a null cursor and throws rather than
|
|
73
|
+
* spinning when the server repeats one.
|
|
74
|
+
*/
|
|
75
|
+
export declare function pagedVia(chatly: ChatlyClient, path: string, extra?: Query): {
|
|
76
|
+
onePage: (query: Record<string, string | number>) => Promise<unknown>;
|
|
77
|
+
everyPage: () => AsyncGenerator<unknown, void, void>;
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=common.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/commands/common.ts"],"names":[],"mappings":"AAYA,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7D,OAAO,KAAK,EAAE,YAAY,EAAQ,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAEtE,mEAAmE;AACnE,wBAAsB,UAAU,CAC9B,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAC9B,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,EACrE,SAAS,CAAC,EAAE,MAAM,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,GACpD,OAAO,CAAC,MAAM,CAAC,CAyCjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAC9B,GAAG,CAAC,EAAE,MAAM,GACX,MAAM,CAOR;AAED,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGjD;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAM1E;AAED,sDAAsD;AACtD,wBAAgB,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAe1E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;AAEhF,uFAAuF;AACvF,wBAAgB,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,KAAK,CAgBjF;AAED,oEAAoE;AACpE,eAAO,MAAM,IAAI,EAAE,aAAa,CAAC,QAAQ,CAA4B,CAAC;AAEtE;;;;GAIG;AACH,eAAO,MAAM,KAAK,EAAE,aAAa,CAAC,QAAQ,CAMzC,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CA2BhE;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,MAAM,EACZ,KAAK,GAAE,KAAU,GAChB;IACD,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACtE,SAAS,EAAE,MAAM,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;CACtD,CAQA"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pieces every command group shares.
|
|
3
|
+
*
|
|
4
|
+
* Lifted out of `resources.ts` when the command surface grew past the point
|
|
5
|
+
* where one file could hold it under the 650-line ceiling. Nothing here is
|
|
6
|
+
* new behaviour — `renderList`, `need` and `props` are the same functions
|
|
7
|
+
* four groups were already importing from each other.
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync } from 'node:fs';
|
|
10
|
+
import { autoPaginate } from '@chatlychat/sdk-node';
|
|
11
|
+
import { bool, num, str } from '../args.js';
|
|
12
|
+
import { itemsOf, nextCursorOf, printJson, printTable } from '../output.js';
|
|
13
|
+
/** Shared list behaviour: one page, or every page with `--all`. */
|
|
14
|
+
export async function renderList(args, columns, onePage, everyPage) {
|
|
15
|
+
const json = bool(args.flags, 'json');
|
|
16
|
+
if (bool(args.flags, 'all')) {
|
|
17
|
+
if (everyPage === undefined) {
|
|
18
|
+
process.stderr.write('--all is not available for this command (it is not cursor-paginated).\n');
|
|
19
|
+
return 1;
|
|
20
|
+
}
|
|
21
|
+
const rows = [];
|
|
22
|
+
for await (const row of everyPage()) {
|
|
23
|
+
rows.push(row);
|
|
24
|
+
}
|
|
25
|
+
if (json) {
|
|
26
|
+
printJson(rows);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
printTable(rows, columns);
|
|
30
|
+
}
|
|
31
|
+
return 0;
|
|
32
|
+
}
|
|
33
|
+
const query = {};
|
|
34
|
+
const limit = num(args.flags, 'limit');
|
|
35
|
+
if (limit !== undefined) {
|
|
36
|
+
query['limit'] = limit;
|
|
37
|
+
}
|
|
38
|
+
const cursor = str(args.flags, 'cursor');
|
|
39
|
+
if (cursor !== undefined) {
|
|
40
|
+
query['cursor'] = cursor;
|
|
41
|
+
}
|
|
42
|
+
const page = await onePage(query);
|
|
43
|
+
if (json) {
|
|
44
|
+
printJson(page);
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
printTable(itemsOf(page), columns);
|
|
48
|
+
const next = nextCursorOf(page);
|
|
49
|
+
if (next !== null) {
|
|
50
|
+
process.stdout.write(`next page: --cursor ${next} (or --all)\n`);
|
|
51
|
+
}
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A table for a route that answers a bare array, or an object wrapping one.
|
|
56
|
+
*
|
|
57
|
+
* Deliberately NOT `renderList`: these routes are `@PaginationExempt` and
|
|
58
|
+
* have no cursor, so printing a "next page" hint or accepting `--all` would
|
|
59
|
+
* promise a walk that does not exist. `--all` on one of these falls through
|
|
60
|
+
* to `renderList`'s refusal only when the caller passes it; here it is simply
|
|
61
|
+
* not offered.
|
|
62
|
+
*/
|
|
63
|
+
export function showRows(args, value, columns, max) {
|
|
64
|
+
if (bool(args.flags, 'json')) {
|
|
65
|
+
printJson(value);
|
|
66
|
+
return 0;
|
|
67
|
+
}
|
|
68
|
+
printTable(itemsOf(value), columns, max);
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
/** An object read: there is no table shape worth inventing, so print the JSON. */
|
|
72
|
+
export function showObject(value) {
|
|
73
|
+
printJson(value ?? { ok: true });
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
export function need(args, index, what) {
|
|
77
|
+
const value = args.path[index];
|
|
78
|
+
if (value === undefined) {
|
|
79
|
+
throw new Error(`Missing ${what}. See \`chatly --help\`.`);
|
|
80
|
+
}
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
/** `--prop key=value`, repeatable, into an object. */
|
|
84
|
+
export function props(args) {
|
|
85
|
+
const raw = args.flags['prop'];
|
|
86
|
+
const list = raw === undefined ? [] : Array.isArray(raw) ? raw : [String(raw)];
|
|
87
|
+
if (list.length === 0) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
const out = {};
|
|
91
|
+
for (const pair of list) {
|
|
92
|
+
const eq = pair.indexOf('=');
|
|
93
|
+
if (eq <= 0) {
|
|
94
|
+
throw new Error(`--prop expects key=value, got "${pair}"`);
|
|
95
|
+
}
|
|
96
|
+
out[pair.slice(0, eq)] = pair.slice(eq + 1);
|
|
97
|
+
}
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
100
|
+
/** Build a query from the flags that were actually passed. Absent flags are absent. */
|
|
101
|
+
export function queryFrom(args, specs) {
|
|
102
|
+
const out = {};
|
|
103
|
+
for (const [flag, wire, numeric] of specs) {
|
|
104
|
+
if (numeric === true) {
|
|
105
|
+
const value = num(args.flags, flag);
|
|
106
|
+
if (value !== undefined) {
|
|
107
|
+
out[wire] = value;
|
|
108
|
+
}
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
const value = str(args.flags, flag);
|
|
112
|
+
if (value !== undefined) {
|
|
113
|
+
out[wire] = value;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return out;
|
|
117
|
+
}
|
|
118
|
+
/** `--days`, the window every `reports.*` route but three reads. */
|
|
119
|
+
export const DAYS = [['days', 'days', true]];
|
|
120
|
+
/**
|
|
121
|
+
* The full window contract, which only `reports/teams`, `reports/labels` and
|
|
122
|
+
* `reports/sla` accept. `--from`/`--to` on any other report is silently
|
|
123
|
+
* ignored by the handler, which is why they are not offered there.
|
|
124
|
+
*/
|
|
125
|
+
export const RANGE = [
|
|
126
|
+
['days', 'days', true],
|
|
127
|
+
['from', 'from'],
|
|
128
|
+
['to', 'to'],
|
|
129
|
+
['group-by', 'group_by'],
|
|
130
|
+
['business-hours', 'business_hours'],
|
|
131
|
+
];
|
|
132
|
+
/**
|
|
133
|
+
* A JSON body, from a file, from stdin, or inline.
|
|
134
|
+
*
|
|
135
|
+
* ── Why config writes take a document and not twenty flags ───────────────
|
|
136
|
+
*
|
|
137
|
+
* The bodies on this surface are nested objects — a bot carries guardrails,
|
|
138
|
+
* a kb scope and an escalation-rule array; a routing rule carries a
|
|
139
|
+
* condition list. Twenty flags per command would be a worse CLI and a second
|
|
140
|
+
* place for a key name to be spelled wrong. The body goes to the API exactly
|
|
141
|
+
* as written, so the schema in `apps/api` is the only spelling that matters.
|
|
142
|
+
*
|
|
143
|
+
* Note what that does and does not buy: the API still strips a key this file
|
|
144
|
+
* has never heard of, so a typo in YOUR json is a 200 that did nothing. The
|
|
145
|
+
* CLI simply refuses to add a second renaming layer on top.
|
|
146
|
+
*/
|
|
147
|
+
export function bodyFrom(args, what) {
|
|
148
|
+
const file = str(args.flags, 'file');
|
|
149
|
+
const inline = str(args.flags, 'body');
|
|
150
|
+
if (file !== undefined && inline !== undefined) {
|
|
151
|
+
throw new Error('Pass --file or --body, not both.');
|
|
152
|
+
}
|
|
153
|
+
let raw;
|
|
154
|
+
if (file !== undefined) {
|
|
155
|
+
try {
|
|
156
|
+
// `0` is stdin: `cat bot.json | chatly bots create --file -`.
|
|
157
|
+
raw = file === '-' ? readFileSync(0, 'utf8') : readFileSync(file, 'utf8');
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
throw new Error(`Cannot read ${file}: ${err instanceof Error ? err.message : String(err)}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else if (inline !== undefined) {
|
|
164
|
+
raw = inline;
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
throw new Error(`Give ${what} as JSON: --file ./config.json (or --file - for stdin), or --body '{…}'.`);
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
const parsed = JSON.parse(raw);
|
|
171
|
+
return parsed;
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
throw new Error(`${file === undefined ? '--body' : file} is not valid JSON.`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* A cursor-paginated route the SDK has no typed walker for yet.
|
|
179
|
+
*
|
|
180
|
+
* Both halves go through `ChatlyClient.request` — the escape hatch the SDK
|
|
181
|
+
* contract defines for the key-accessible routes with no named method — so
|
|
182
|
+
* auth, the idempotency key, the retry policy and the typed errors are the
|
|
183
|
+
* same ones every other command gets. The walk is the SDK's own
|
|
184
|
+
* `autoPaginate`, which stops on a null cursor and throws rather than
|
|
185
|
+
* spinning when the server repeats one.
|
|
186
|
+
*/
|
|
187
|
+
export function pagedVia(chatly, path, extra = {}) {
|
|
188
|
+
const fetchPage = (query) => chatly.request('GET', path, { query: { ...extra, ...query } });
|
|
189
|
+
return {
|
|
190
|
+
onePage: (query) => fetchPage(query),
|
|
191
|
+
everyPage: () => autoPaginate((cursor) => fetchPage(cursor === undefined ? {} : { cursor })),
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/commands/common.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config-as-code: the surface an integrator keeps in a repository.
|
|
3
|
+
*
|
|
4
|
+
* Bots, routing rules, triggers, brands, transactional email copy and macros
|
|
5
|
+
* are all workspace CONFIGURATION — the things a team wants reviewed in a
|
|
6
|
+
* pull request and applied from CI, not clicked through a settings screen.
|
|
7
|
+
* That is the reason the SDK manifest grew from 55 routes to 142, and it is
|
|
8
|
+
* the reason these are commands rather than `chatly api` calls.
|
|
9
|
+
*
|
|
10
|
+
* ── One idiom for every write ─────────────────────────────────────────────
|
|
11
|
+
*
|
|
12
|
+
* Writes take a JSON document (`--file`, `--file -`, or `--body`), not a flag
|
|
13
|
+
* per field. These bodies are nested — a bot carries guardrails, a KB scope
|
|
14
|
+
* and an escalation-rule array — and `bodyFrom` explains why a flag per field
|
|
15
|
+
* would be both a worse CLI and a second place for a key name to be wrong.
|
|
16
|
+
*
|
|
17
|
+
* ── Transport ─────────────────────────────────────────────────────────────
|
|
18
|
+
*
|
|
19
|
+
* Through `ChatlyClient.request`, the escape hatch the SDK contract defines
|
|
20
|
+
* for key-accessible routes with no typed method. It is the same auth, the
|
|
21
|
+
* same `Idempotency-Key` per write, the same retry policy and the same typed
|
|
22
|
+
* errors a named method would get — `apps/cli` adds no HTTP of its own.
|
|
23
|
+
*/
|
|
24
|
+
import { type ParsedArgs } from '../args.js';
|
|
25
|
+
import type { ChatlyClient } from '@chatlychat/sdk-node';
|
|
26
|
+
export declare function bots(chatly: ChatlyClient, args: ParsedArgs): Promise<number>;
|
|
27
|
+
export declare function botRoutes(chatly: ChatlyClient, args: ParsedArgs): Promise<number>;
|
|
28
|
+
export declare function triggers(chatly: ChatlyClient, args: ParsedArgs): Promise<number>;
|
|
29
|
+
export declare function brands(chatly: ChatlyClient, args: ParsedArgs): Promise<number>;
|
|
30
|
+
export declare function emailTemplates(chatly: ChatlyClient, args: ParsedArgs): Promise<number>;
|
|
31
|
+
export declare function macros(chatly: ChatlyClient, args: ParsedArgs): Promise<number>;
|
|
32
|
+
/**
|
|
33
|
+
* Knowledge gaps: the questions the KB could not answer, and the loop that
|
|
34
|
+
* closes them.
|
|
35
|
+
*
|
|
36
|
+
* `list` → pick the most-asked → `draft` → the article exists → `triage` it
|
|
37
|
+
* resolved. That whole loop is a terminal job, which is why it is a command.
|
|
38
|
+
*/
|
|
39
|
+
export declare function knowledgeGaps(chatly: ChatlyClient, args: ParsedArgs): Promise<number>;
|
|
40
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAa,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAGxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,wBAAsB,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA6HlF;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA2DvF;AAED,wBAAsB,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAsCtF;AAED,wBAAsB,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAmCpF;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA8C5F;AAED,wBAAsB,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA6EpF;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA+C3F"}
|