@runtypelabs/cli 2.59.1 → 2.59.4
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/chunk-0x7UKC1U.js +17 -0
- package/dist/chunk-2ySxXtcg.js +418 -0
- package/dist/chunk-3An_BRHv.js +501 -0
- package/dist/chunk-6uTxgdiY.js +16218 -0
- package/dist/chunk-87nRnNRG.js +1363 -0
- package/dist/chunk-B3wo8uRx.js +322 -0
- package/dist/chunk-BGp3ZdBy.js +560 -0
- package/dist/chunk-BJQv9Elp.js +107 -0
- package/dist/chunk-BOpO6xE-.js +6053 -0
- package/dist/chunk-BQXXCL8B.js +102 -0
- package/dist/chunk-BV-8isOd.js +34 -0
- package/dist/chunk-BVMhjGVe.js +826 -0
- package/dist/chunk-BW2fg46T.js +141 -0
- package/dist/chunk-BWJdY5Ag.js +36 -0
- package/dist/chunk-BYJOrLhh.js +302 -0
- package/dist/chunk-BYab8EVL.js +127 -0
- package/dist/chunk-BfEKvp7h.js +82 -0
- package/dist/chunk-BhgLSfH6.js +1123 -0
- package/dist/chunk-BirUxTtH.js +296 -0
- package/dist/chunk-BmB6UVZ9.js +1559 -0
- package/dist/chunk-BnWhIqW1.js +109 -0
- package/dist/chunk-Bpfnfk0t.js +123 -0
- package/dist/chunk-BrhgdnM3.js +108 -0
- package/dist/chunk-Bt0XAgX5.js +327 -0
- package/dist/chunk-Bu0FJr6S.js +84 -0
- package/dist/chunk-BvEoKpN3.js +255 -0
- package/dist/chunk-BxNJgYbE.js +28 -0
- package/dist/chunk-C1OFhd7F.js +6131 -0
- package/dist/chunk-C7e7WwbU.js +331 -0
- package/dist/chunk-CDTYP6bN.js +558 -0
- package/dist/chunk-CGDQoqDC.js +24 -0
- package/dist/chunk-CJraEBVd.js +127 -0
- package/dist/chunk-CQrNhOtv.js +40 -0
- package/dist/chunk-CW6AzBH6.js +128 -0
- package/dist/chunk-CXgL4w-9.js +317 -0
- package/dist/chunk-CZrqoPyf.js +233 -0
- package/dist/chunk-CcFCyqbB.js +83 -0
- package/dist/chunk-CdaIvO-y.js +485 -0
- package/dist/chunk-CehSXtgK.js +624 -0
- package/dist/chunk-Ciqkop65.js +218 -0
- package/dist/chunk-CoAWdSiE.js +43 -0
- package/dist/chunk-Crb4y7t4.js +830 -0
- package/dist/chunk-CrlqIfmb.js +337 -0
- package/dist/chunk-Cs4pwCQ-.js +324 -0
- package/dist/chunk-CwM_9y01.js +519 -0
- package/dist/chunk-CyRbIJg8.js +440 -0
- package/dist/chunk-D0OHsyMy.js +212 -0
- package/dist/chunk-D3y2bURs.js +1347 -0
- package/dist/chunk-D4_mJk03.js +2338 -0
- package/dist/chunk-D6C8rned.js +578 -0
- package/dist/chunk-D9ZbUnks.js +11 -0
- package/dist/chunk-DEPmLshX.js +834 -0
- package/dist/chunk-DFj1UPB2.js +330 -0
- package/dist/chunk-DGdFdZVf.js +197 -0
- package/dist/chunk-DGv7X9S_.js +63 -0
- package/dist/chunk-DJQ47WYZ.js +664 -0
- package/dist/chunk-DJw3O61j.js +1974 -0
- package/dist/chunk-DK4FbWVK.js +100 -0
- package/dist/chunk-DPuofXMp.js +3907 -0
- package/dist/chunk-DSRYhUus.js +993 -0
- package/dist/chunk-DajZ9Eg4.js +299 -0
- package/dist/chunk-Df4dunvU.js +195 -0
- package/dist/chunk-DjNTPhfO.js +481 -0
- package/dist/chunk-Dn8eaJuu.js +1042 -0
- package/dist/chunk-DwDWqSxM.js +637 -0
- package/dist/chunk-Dz7cEtxl.js +84 -0
- package/dist/chunk-E_0bgjrS.js +359 -0
- package/dist/chunk-KPYN2vUp.js +776 -0
- package/dist/chunk-KcqPQJBi.js +86 -0
- package/dist/chunk-N9H0JnoG.js +349 -0
- package/dist/chunk-NONFcXkn.js +728 -0
- package/dist/chunk-PrFjcpmH.js +256 -0
- package/dist/chunk-QSfNYiw9.js +11 -0
- package/dist/chunk-R265bzj9.js +226 -0
- package/dist/chunk-X9V_r6jM.js +166 -0
- package/dist/chunk-ZBtPUtyA.js +55 -0
- package/dist/chunk-ZCTfmOs7.js +4939 -0
- package/dist/chunk-h6oavj0t.js +97 -0
- package/dist/chunk-i7DwkvvD.js +42 -0
- package/dist/chunk-mG-4eZ6S.js +203 -0
- package/dist/chunk-o0ygUbCf.js +313 -0
- package/dist/chunk-ucu5lrDZ.js +5715 -0
- package/dist/index.js +11367 -73789
- package/package.json +5 -5
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { r as createCliClient } from "./chunk-BW2fg46T.js";
|
|
3
|
+
import { n as ensureAuth } from "./chunk-CJraEBVd.js";
|
|
4
|
+
import { a as printJson } from "./chunk-CcFCyqbB.js";
|
|
5
|
+
import { t as readJsonFile } from "./chunk-DGv7X9S_.js";
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import chalk from "chalk";
|
|
8
|
+
import { writeFileSync } from "fs";
|
|
9
|
+
import { ClientTokensNamespace, EvalsNamespace, FlowsNamespace, ProductsNamespace, SkillsNamespace, SurfacesNamespace, ToolsNamespace, defineEval, defineFlow, defineFpo, defineProduct, defineSkill, defineSurface, defineTool } from "@runtypelabs/sdk";
|
|
10
|
+
// src/lib/ensure-output.ts
|
|
11
|
+
/**
|
|
12
|
+
* Emit a pulled definition as JSON: to `out` when given, otherwise to stdout so
|
|
13
|
+
* `runtype <entity> pull <name> > file.json` works. Hash and warnings go to stderr.
|
|
14
|
+
*/
|
|
15
|
+
function writePulledDefinition(data, meta) {
|
|
16
|
+
const json = `${JSON.stringify(data, null, 2)}\n`;
|
|
17
|
+
if (meta.out) {
|
|
18
|
+
writeFileSync(meta.out, json);
|
|
19
|
+
console.error(chalk.green(`Wrote ${meta.out}`));
|
|
20
|
+
} else process.stdout.write(json);
|
|
21
|
+
if (meta.contentHash) console.error(chalk.gray(`contentHash ${meta.contentHash}`));
|
|
22
|
+
for (const warning of meta.warnings ?? []) console.error(chalk.yellow(`warning: ${warning}`));
|
|
23
|
+
}
|
|
24
|
+
// src/commands/entity-ensure.ts
|
|
25
|
+
function namespaceTransport(client) {
|
|
26
|
+
const transport = {
|
|
27
|
+
get: (path, params) => client.get(path, params),
|
|
28
|
+
post: (path, body) => client.post(path, body)
|
|
29
|
+
};
|
|
30
|
+
return () => transport;
|
|
31
|
+
}
|
|
32
|
+
/** The SDK ensure options these flags ask for, shared by every entity. */
|
|
33
|
+
function buildEntityEnsureOptions(flags, support) {
|
|
34
|
+
if (flags.release !== void 0 && !["none", "publish"].includes(flags.release)) throw new Error("--release must be none or publish");
|
|
35
|
+
const version = support.version && (flags.label || flags.notes) ? {
|
|
36
|
+
...flags.label ? { label: flags.label } : {},
|
|
37
|
+
...flags.notes ? { notes: flags.notes } : {}
|
|
38
|
+
} : void 0;
|
|
39
|
+
return {
|
|
40
|
+
...flags.dryRun ? { dryRun: true } : {},
|
|
41
|
+
...flags.expectNoChanges ? { expectNoChanges: true } : {},
|
|
42
|
+
...flags.overwriteManaged ? { onConflict: "overwrite" } : {},
|
|
43
|
+
...flags.expectedRemoteHash ? { expectedRemoteHash: flags.expectedRemoteHash } : {},
|
|
44
|
+
...support.release && flags.release ? { release: flags.release } : {},
|
|
45
|
+
...version ? { version } : {}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const define = (fn, definition) => fn(definition);
|
|
49
|
+
const SKILL_ENSURE_SPEC = {
|
|
50
|
+
noun: "skill",
|
|
51
|
+
idKey: "skillId",
|
|
52
|
+
release: true,
|
|
53
|
+
version: true,
|
|
54
|
+
productScoped: false,
|
|
55
|
+
ensure: async (t, def, options) => new SkillsNamespace(t).ensure(define(defineSkill, def), options),
|
|
56
|
+
pull: (t, name) => new SkillsNamespace(t).pull(name)
|
|
57
|
+
};
|
|
58
|
+
const FLOW_ENSURE_SPEC = {
|
|
59
|
+
noun: "flow",
|
|
60
|
+
idKey: "flowId",
|
|
61
|
+
release: true,
|
|
62
|
+
version: true,
|
|
63
|
+
productScoped: false,
|
|
64
|
+
ensure: async (t, def, options) => new FlowsNamespace(t).ensure(define(defineFlow, def), options),
|
|
65
|
+
pull: (t, name) => new FlowsNamespace(t).pull(name)
|
|
66
|
+
};
|
|
67
|
+
const TOOL_ENSURE_SPEC = {
|
|
68
|
+
noun: "tool",
|
|
69
|
+
idKey: "toolId",
|
|
70
|
+
release: false,
|
|
71
|
+
version: false,
|
|
72
|
+
productScoped: false,
|
|
73
|
+
ensure: async (t, def, options) => new ToolsNamespace(t).ensure(define(defineTool, def), options),
|
|
74
|
+
pull: (t, name) => new ToolsNamespace(t).pull(name)
|
|
75
|
+
};
|
|
76
|
+
const PRODUCT_ENSURE_SPEC = {
|
|
77
|
+
noun: "product",
|
|
78
|
+
idKey: "productId",
|
|
79
|
+
release: false,
|
|
80
|
+
version: false,
|
|
81
|
+
productScoped: false,
|
|
82
|
+
ensure: async (t, def, options) => new ProductsNamespace(t).ensure(define(defineProduct, def), options),
|
|
83
|
+
pull: (t, name) => new ProductsNamespace(t).pull(name)
|
|
84
|
+
};
|
|
85
|
+
const SURFACE_ENSURE_SPEC = {
|
|
86
|
+
noun: "surface",
|
|
87
|
+
idKey: "surfaceId",
|
|
88
|
+
release: false,
|
|
89
|
+
version: false,
|
|
90
|
+
productScoped: true,
|
|
91
|
+
ensure: async (t, def, options, productId) => new SurfacesNamespace(t).ensure(productId, define(defineSurface, def), options),
|
|
92
|
+
pull: (t, name, productId) => new SurfacesNamespace(t).pull(productId, name)
|
|
93
|
+
};
|
|
94
|
+
const EVAL_ENSURE_SPEC = {
|
|
95
|
+
noun: "eval",
|
|
96
|
+
idKey: "suiteId",
|
|
97
|
+
release: false,
|
|
98
|
+
version: false,
|
|
99
|
+
productScoped: false,
|
|
100
|
+
ensure: async (t, def, options) => new EvalsNamespace(t).ensure(define(defineEval, def), options),
|
|
101
|
+
pull: (t, name) => new EvalsNamespace(t).pull(name)
|
|
102
|
+
};
|
|
103
|
+
function isDriftError(error) {
|
|
104
|
+
return error instanceof Error && error.name.endsWith("DriftError") && "plan" in error;
|
|
105
|
+
}
|
|
106
|
+
function printEnsureOutcome(spec, name, result) {
|
|
107
|
+
if (result.result === "plan") {
|
|
108
|
+
console.log(chalk.cyan(`Plan for ${spec.noun} "${name}": ${result.changes ?? "n/a"}`));
|
|
109
|
+
for (const key of result.changedKeys ?? []) console.log(` ${key}`);
|
|
110
|
+
if (result.remoteHash) console.log(chalk.gray(`Apply this plan with --expected-remote-hash ${result.remoteHash}`));
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const id = typeof result[spec.idKey] === "string" ? ` (${result[spec.idKey]})` : "";
|
|
114
|
+
console.log(chalk.green(`${spec.noun[0].toUpperCase()}${spec.noun.slice(1)} "${name}" ${result.result}${id}`));
|
|
115
|
+
if (result.versionId) console.log(chalk.gray(`Version ${result.versionId}`));
|
|
116
|
+
}
|
|
117
|
+
function fail(message, detail) {
|
|
118
|
+
console.error(chalk.red(message));
|
|
119
|
+
if (detail !== void 0) console.error(chalk.red(detail instanceof Error ? detail.message : String(detail)));
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
/** `ensure <file>`: converge a definition file (a pull's output, or its `definition`). */
|
|
123
|
+
function buildEntityEnsureCommand(spec) {
|
|
124
|
+
const command = new Command("ensure").description(`Converge a ${spec.noun} definition from a JSON file (config-as-code)`).argument("<file>", `${spec.noun} definition JSON file, or - to read from stdin`);
|
|
125
|
+
if (spec.productScoped) command.requiredOption("--product <productId>", "Product the surface belongs to");
|
|
126
|
+
command.option("--dry-run", "Plan without writing").option("--expect-no-changes", "Plan and exit 1 on any drift (the CI gate)").option("--overwrite-managed", "Converge even when the last write came from the dashboard").option("--expected-remote-hash <hash>", "Apply only if the remote still hashes to this value (the remoteHash a dry run printed)");
|
|
127
|
+
if (spec.release) command.option("--release <mode>", "none or publish");
|
|
128
|
+
if (spec.version) command.option("--label <text>", "Version label recorded on the version this converge appends").option("--notes <text>", "Version notes recorded on the version this converge appends");
|
|
129
|
+
command.option("--json", "Output as JSON").action(async (file, flags) => {
|
|
130
|
+
let options;
|
|
131
|
+
let definition;
|
|
132
|
+
try {
|
|
133
|
+
options = buildEntityEnsureOptions(flags, spec);
|
|
134
|
+
definition = readJsonFile(file, {
|
|
135
|
+
label: `${spec.noun} definition`,
|
|
136
|
+
unwrapKey: "definition"
|
|
137
|
+
});
|
|
138
|
+
} catch (error) {
|
|
139
|
+
fail(error instanceof Error ? error.message : String(error));
|
|
140
|
+
}
|
|
141
|
+
const name = typeof definition.name === "string" ? definition.name : "";
|
|
142
|
+
const apiKey = await ensureAuth();
|
|
143
|
+
if (!apiKey) return;
|
|
144
|
+
const transport = namespaceTransport(createCliClient(apiKey));
|
|
145
|
+
try {
|
|
146
|
+
const result = await spec.ensure(transport, definition, options, flags.product);
|
|
147
|
+
if (flags.json) printJson(result);
|
|
148
|
+
else printEnsureOutcome(spec, name, result);
|
|
149
|
+
} catch (error) {
|
|
150
|
+
if (isDriftError(error)) {
|
|
151
|
+
if (flags.json) printJson({
|
|
152
|
+
drift: true,
|
|
153
|
+
plan: error.plan
|
|
154
|
+
});
|
|
155
|
+
else console.error(chalk.yellow(error.message));
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
fail(`Failed to converge the ${spec.noun}`, error);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
return command;
|
|
162
|
+
}
|
|
163
|
+
/** `pull <name>`: print the definition file `ensure` reads back (dashboard wins). */
|
|
164
|
+
function buildEntityPullCommand(spec) {
|
|
165
|
+
const command = new Command("pull").description(`Print a ${spec.noun} as the definition file \`ensure\` reads (dashboard wins)`).argument("<name>", `${spec.noun} name`);
|
|
166
|
+
if (spec.productScoped) command.requiredOption("--product <productId>", "Product the surface belongs to");
|
|
167
|
+
command.option("-o, --out <file>", "Write the definition file here instead of stdout").option("--json", "Print the full pull response (definition, contentHash, provenance)").action(async (name, flags) => {
|
|
168
|
+
const apiKey = await ensureAuth();
|
|
169
|
+
if (!apiKey) return;
|
|
170
|
+
const transport = namespaceTransport(createCliClient(apiKey));
|
|
171
|
+
try {
|
|
172
|
+
const pulled = await spec.pull(transport, name, flags.product);
|
|
173
|
+
writePulledDefinition(flags.json ? pulled : pulled.definition, {
|
|
174
|
+
out: flags.out,
|
|
175
|
+
contentHash: pulled.contentHash,
|
|
176
|
+
warnings: pulled.warnings
|
|
177
|
+
});
|
|
178
|
+
} catch (error) {
|
|
179
|
+
fail(`Failed to pull ${spec.noun} "${name}"`, error);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
return command;
|
|
183
|
+
}
|
|
184
|
+
function buildFpoEnsureOptions(flags) {
|
|
185
|
+
if (flags.release !== void 0 && !["none", "publish"].includes(flags.release)) throw new Error("--release must be none or publish");
|
|
186
|
+
return {
|
|
187
|
+
...flags.dryRun ? { dryRun: true } : {},
|
|
188
|
+
...flags.expectNoChanges ? { expectNoChanges: true } : {},
|
|
189
|
+
...flags.overwriteManaged ? { onConflict: "overwrite" } : {},
|
|
190
|
+
...flags.expectedRemoteHash ? { expectedRemoteHash: flags.expectedRemoteHash } : {},
|
|
191
|
+
...flags.prune ? { prune: true } : {},
|
|
192
|
+
...flags.hashProbe ? { hashProbe: true } : {},
|
|
193
|
+
...flags.release ? { release: flags.release } : {}
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/** `ensure-fpo <file>`: converge a whole Full Product Object. */
|
|
197
|
+
const productEnsureFpoCommand = new Command("ensure-fpo").description("Converge a whole Full Product Object (product, capabilities, surfaces, ...) from a JSON file").argument("<file>", "FPO JSON file (a pull-fpo output, or its fpo), or - to read from stdin").option("--dry-run", "Plan without writing").option("--expect-no-changes", "Plan and exit 1 when any entity would change (the CI gate)").option("--overwrite-managed", "Converge over dashboard/API edits").option("--expected-remote-hash <hash>", "Apply only if the live product still hashes to this value (the remoteHash a dry run printed)").option("--prune", "Remove product-scoped capabilities and surfaces absent from the FPO").option("--release <mode>", "publish (default: converged agents and flows go live) or none (save drafts)").option("--hash-probe", "With --release none, skip the upload when the live product already matches (best for pulled FPOs)").option("--json", "Output as JSON").action(async (file, flags) => {
|
|
198
|
+
let fpo;
|
|
199
|
+
try {
|
|
200
|
+
fpo = defineFpo(readJsonFile(file, {
|
|
201
|
+
label: "FPO",
|
|
202
|
+
unwrapKey: "fpo"
|
|
203
|
+
}));
|
|
204
|
+
} catch (error) {
|
|
205
|
+
fail(error instanceof Error ? error.message : String(error));
|
|
206
|
+
}
|
|
207
|
+
const apiKey = await ensureAuth();
|
|
208
|
+
if (!apiKey) return;
|
|
209
|
+
const products = new ProductsNamespace(namespaceTransport(createCliClient(apiKey)));
|
|
210
|
+
try {
|
|
211
|
+
const result = await products.ensureFpo(fpo, buildFpoEnsureOptions(flags));
|
|
212
|
+
if (flags.json) printJson(result);
|
|
213
|
+
else {
|
|
214
|
+
console.log(chalk.cyan(`Product FPO ${result.result}${result.productId ? ` (${result.productId})` : ""}`));
|
|
215
|
+
for (const entity of result.entities) {
|
|
216
|
+
const line = ` ${entity.kind}:${entity.name} ${entity.result}`;
|
|
217
|
+
console.log(entity.result === "failed" ? chalk.red(`${line} — ${entity.error ?? ""}`) : line);
|
|
218
|
+
for (const warning of entity.warnings ?? []) console.warn(chalk.yellow(` Warning: ${warning}`));
|
|
219
|
+
}
|
|
220
|
+
if (result.remoteHash) console.log(chalk.gray(`Apply this plan with --expected-remote-hash ${result.remoteHash}`));
|
|
221
|
+
}
|
|
222
|
+
if (result.hasFailures) process.exit(1);
|
|
223
|
+
} catch (error) {
|
|
224
|
+
if (isDriftError(error)) {
|
|
225
|
+
if (flags.json) printJson({
|
|
226
|
+
drift: true,
|
|
227
|
+
plan: error.plan
|
|
228
|
+
});
|
|
229
|
+
else console.error(chalk.yellow(error.message));
|
|
230
|
+
process.exit(1);
|
|
231
|
+
}
|
|
232
|
+
fail("Failed to converge the product FPO", error);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
/** Runtype Agent Skills live under `agents` because `runtype skills` installs coding-agent skills. */
|
|
236
|
+
const agentSkillsCommand = new Command("skills").description("Runtype Agent Skills: context bundles deployed agents load (for coding-agent skills see `runtype skills`)");
|
|
237
|
+
agentSkillsCommand.addCommand(buildEntityEnsureCommand(SKILL_ENSURE_SPEC));
|
|
238
|
+
agentSkillsCommand.addCommand(buildEntityPullCommand(SKILL_ENSURE_SPEC));
|
|
239
|
+
/** `pull-fpo <name>`: print the whole product as the FPO `ensure-fpo` reads. */
|
|
240
|
+
const productPullFpoCommand = new Command("pull-fpo").description("Print a product graph as the FPO `ensure-fpo` reads (dashboard wins)").argument("<name>", "Product name").option("-o, --out <file>", "Write the FPO here instead of stdout").option("--json", "Print the full pull response (fpo, contentHash, warnings)").action(async (name, flags) => {
|
|
241
|
+
const apiKey = await ensureAuth();
|
|
242
|
+
if (!apiKey) return;
|
|
243
|
+
const products = new ProductsNamespace(namespaceTransport(createCliClient(apiKey)));
|
|
244
|
+
try {
|
|
245
|
+
const pulled = await products.pullFpo(name);
|
|
246
|
+
writePulledDefinition(flags.json ? pulled : pulled.fpo, {
|
|
247
|
+
out: flags.out,
|
|
248
|
+
contentHash: pulled.contentHash,
|
|
249
|
+
warnings: pulled.warnings
|
|
250
|
+
});
|
|
251
|
+
} catch (error) {
|
|
252
|
+
fail(`Failed to pull product "${name}"`, error);
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
/** Converge a client token file through the SDK; it keys on `name` and never deletes or regenerates. */
|
|
256
|
+
async function ensureClientTokenFromFile(client, definition, flags) {
|
|
257
|
+
const getClient = (() => client);
|
|
258
|
+
return new ClientTokensNamespace(getClient).ensure(definition, {
|
|
259
|
+
...flags.dryRun ? { dryRun: true } : {},
|
|
260
|
+
...flags.expectNoChanges ? { expectNoChanges: true } : {}
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
/** `client-tokens ensure <file>`: the widget token step of the agent-plus-token workflow. */
|
|
264
|
+
const clientTokenEnsureCommand = new Command("ensure").description("Converge a client token definition from a JSON file, keyed by its name").argument("<file>", "Client token definition JSON file, or - to read from stdin").option("--dry-run", "Plan without writing").option("--expect-no-changes", "Plan and exit 1 on any drift (the CI gate)").option("--json", "Output as JSON").action(async (file, flags) => {
|
|
265
|
+
let definition;
|
|
266
|
+
try {
|
|
267
|
+
definition = readJsonFile(file, { label: "client token definition" });
|
|
268
|
+
} catch (error) {
|
|
269
|
+
fail(error instanceof Error ? error.message : String(error));
|
|
270
|
+
}
|
|
271
|
+
const apiKey = await ensureAuth();
|
|
272
|
+
if (!apiKey) return;
|
|
273
|
+
try {
|
|
274
|
+
const result = await ensureClientTokenFromFile(createCliClient(apiKey), definition, flags);
|
|
275
|
+
if (flags.json) printJson(result);
|
|
276
|
+
else if (result.result === "plan") {
|
|
277
|
+
console.log(chalk.cyan(`Plan for client token "${String(definition.name)}": ${result.changes}`));
|
|
278
|
+
for (const key of result.changedKeys) console.log(` ${key}`);
|
|
279
|
+
} else {
|
|
280
|
+
console.log(chalk.green(`Client token "${result.clientToken.name}" ${result.result} (${result.clientToken.id})`));
|
|
281
|
+
if (result.token) console.log(`Token ${result.token}`);
|
|
282
|
+
}
|
|
283
|
+
} catch (error) {
|
|
284
|
+
if (isDriftError(error)) {
|
|
285
|
+
if (flags.json) printJson({
|
|
286
|
+
drift: true,
|
|
287
|
+
plan: error.plan
|
|
288
|
+
});
|
|
289
|
+
else console.error(chalk.yellow(error.message));
|
|
290
|
+
process.exit(1);
|
|
291
|
+
}
|
|
292
|
+
fail("Failed to converge the client token", error);
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
export { TOOL_ENSURE_SPEC as a, buildEntityPullCommand as c, productPullFpoCommand as d, writePulledDefinition as f, SURFACE_ENSURE_SPEC as i, clientTokenEnsureCommand as l, FLOW_ENSURE_SPEC as n, agentSkillsCommand as o, PRODUCT_ENSURE_SPEC as r, buildEntityEnsureCommand as s, EVAL_ENSURE_SPEC as t, productEnsureFpoCommand as u };
|
|
296
|
+
|