@stndrds/cli 1.0.0-alpha.230 → 1.0.0-alpha.232
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/bin.mjs +66 -30
- package/package.json +1 -1
package/dist/bin.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/program.ts
|
|
4
|
-
import
|
|
4
|
+
import chalk8 from "chalk";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
|
|
7
7
|
// src/client.ts
|
|
@@ -208,8 +208,43 @@ function registerAutofillCommand(program) {
|
|
|
208
208
|
);
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
// src/commands/
|
|
211
|
+
// src/commands/bundles.ts
|
|
212
212
|
import chalk3 from "chalk";
|
|
213
|
+
function registerBundlesCommand(program) {
|
|
214
|
+
const bundles = program.command("bundles").description("Manage system bundles assigned to the current tenant (admin)");
|
|
215
|
+
bundles.command("list").description("List the bundles actively assigned to the current tenant").action(async (_opts, cmd) => {
|
|
216
|
+
const client = getClientFromCommand(cmd);
|
|
217
|
+
const result = await client.get("/bundles/assigned");
|
|
218
|
+
formatOutput(result, getFormat(cmd));
|
|
219
|
+
});
|
|
220
|
+
bundles.command("updatable").description("List assigned bundles that have a newer version available").action(async (_opts, cmd) => {
|
|
221
|
+
const client = getClientFromCommand(cmd);
|
|
222
|
+
const result = await client.get("/bundles/updatable");
|
|
223
|
+
formatOutput(result, getFormat(cmd));
|
|
224
|
+
});
|
|
225
|
+
bundles.command("assign").description("Assign (install) a bundle to the current tenant").argument("<bundleId>", "bundle ID to assign").action(async (bundleId, _opts, cmd) => {
|
|
226
|
+
const client = getClientFromCommand(cmd);
|
|
227
|
+
const result = await client.post("/bundles/assign", { bundleId });
|
|
228
|
+
formatOutput(result, getFormat(cmd));
|
|
229
|
+
});
|
|
230
|
+
bundles.command("unassign").description("Remove a bundle assignment from the current tenant").argument("<bundleId>", "bundle ID to remove").option("--yes", "remove without confirmation").action(async (bundleId, opts, cmd) => {
|
|
231
|
+
if (!opts.yes) {
|
|
232
|
+
throw new Error('Removing a bundle is explicit. Re-run with "--yes" to confirm.');
|
|
233
|
+
}
|
|
234
|
+
const client = getClientFromCommand(cmd);
|
|
235
|
+
await client.delete(`/bundles/${bundleId}`);
|
|
236
|
+
process.stdout.write(`${chalk3.green("\u2713")} Bundle ${bundleId} unassigned.
|
|
237
|
+
`);
|
|
238
|
+
});
|
|
239
|
+
bundles.command("update").description("Apply assigned bundles \u2014 picks up newer bundle versions (additive sync)").action(async (_opts, cmd) => {
|
|
240
|
+
const client = getClientFromCommand(cmd);
|
|
241
|
+
const result = await client.post("/bundles/update");
|
|
242
|
+
formatOutput(result, getFormat(cmd));
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// src/commands/connectors.ts
|
|
247
|
+
import chalk4 from "chalk";
|
|
213
248
|
var PROVIDERS = ["gmail", "outlook"];
|
|
214
249
|
function resolveScope(scope) {
|
|
215
250
|
return scope === "actor" ? "actor" : "tenant";
|
|
@@ -240,7 +275,7 @@ function registerConnectorsCommand(program) {
|
|
|
240
275
|
}
|
|
241
276
|
const client = getClientFromCommand(cmd);
|
|
242
277
|
await client.delete(`/connectors/connections/${id}`);
|
|
243
|
-
process.stdout.write(`${
|
|
278
|
+
process.stdout.write(`${chalk4.green("\u2713")} Connector connection ${id} disconnected.
|
|
244
279
|
`);
|
|
245
280
|
});
|
|
246
281
|
}
|
|
@@ -341,7 +376,7 @@ function registerFoldersCommand(program) {
|
|
|
341
376
|
}
|
|
342
377
|
|
|
343
378
|
// src/commands/keys.ts
|
|
344
|
-
import
|
|
379
|
+
import chalk5 from "chalk";
|
|
345
380
|
function registerKeysCommand(program) {
|
|
346
381
|
const keys = program.command("keys").description("Manage Standards API keys");
|
|
347
382
|
keys.command("list").description("List API keys").action(async (_opts, cmd) => {
|
|
@@ -368,7 +403,7 @@ function registerKeysCommand(program) {
|
|
|
368
403
|
}
|
|
369
404
|
const client = getClientFromCommand(cmd);
|
|
370
405
|
await client.delete(`/api-keys/${id}`);
|
|
371
|
-
process.stdout.write(`${
|
|
406
|
+
process.stdout.write(`${chalk5.green("\u2713")} API key ${id} revoked.
|
|
372
407
|
`);
|
|
373
408
|
});
|
|
374
409
|
}
|
|
@@ -453,7 +488,7 @@ function registerRecordsCommand(program) {
|
|
|
453
488
|
// src/commands/root.ts
|
|
454
489
|
import { stdin as input, stdout as output } from "process";
|
|
455
490
|
import { createInterface } from "readline/promises";
|
|
456
|
-
import
|
|
491
|
+
import chalk6 from "chalk";
|
|
457
492
|
|
|
458
493
|
// src/config.ts
|
|
459
494
|
import { mkdir, readFile as readFile3, rm, writeFile } from "fs/promises";
|
|
@@ -593,7 +628,7 @@ function registerRootCommands(program) {
|
|
|
593
628
|
await client.get("/api-keys");
|
|
594
629
|
await upsertProfile({ name: opts.name, apiUrl: opts.url, apiKey });
|
|
595
630
|
process.stdout.write(
|
|
596
|
-
`${
|
|
631
|
+
`${chalk6.green("\u2713")} Standards instance "${opts.name}" saved and selected.
|
|
597
632
|
`
|
|
598
633
|
);
|
|
599
634
|
process.stdout.write(` API URL: ${opts.url}
|
|
@@ -605,7 +640,7 @@ function registerRootCommands(program) {
|
|
|
605
640
|
});
|
|
606
641
|
program.command("use").description("Select the active Standards instance").argument("<name>", "instance name").action(async (name) => {
|
|
607
642
|
await setCurrentProfile(name);
|
|
608
|
-
process.stdout.write(`${
|
|
643
|
+
process.stdout.write(`${chalk6.green("\u2713")} Standards instance "${name}" selected.
|
|
609
644
|
`);
|
|
610
645
|
});
|
|
611
646
|
program.command("instances").description("List configured Standards instances").action(async (_opts, cmd) => {
|
|
@@ -624,7 +659,7 @@ function registerRootCommands(program) {
|
|
|
624
659
|
});
|
|
625
660
|
program.command("logout").description("Remove a Standards instance from local CLI config").argument("[name]", "instance name, defaults to current").action(async (name) => {
|
|
626
661
|
await removeProfile(name);
|
|
627
|
-
process.stdout.write(`${
|
|
662
|
+
process.stdout.write(`${chalk6.green("\u2713")} Standards instance removed.
|
|
628
663
|
`);
|
|
629
664
|
});
|
|
630
665
|
}
|
|
@@ -634,7 +669,7 @@ import { createHash } from "crypto";
|
|
|
634
669
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
635
670
|
import { join as join2 } from "path";
|
|
636
671
|
import { fileURLToPath } from "url";
|
|
637
|
-
import
|
|
672
|
+
import chalk7 from "chalk";
|
|
638
673
|
function registerSchemaCommand(program) {
|
|
639
674
|
const schema = program.command("schema").description("Inspect schema objects and attributes");
|
|
640
675
|
schema.command("list").description("List all schema objects").action(async (_opts, cmd) => {
|
|
@@ -661,7 +696,7 @@ function registerSchemaCommand(program) {
|
|
|
661
696
|
const result = await fetchDrift(getClientFromCommand(cmd), opts.object);
|
|
662
697
|
const totalDrift = result.summary.totalCustomObjects + result.summary.totalCustomAttributes;
|
|
663
698
|
if (totalDrift === 0) {
|
|
664
|
-
console.info(
|
|
699
|
+
console.info(chalk7.green("\u2713 No drift detected \u2014 nothing to pull."));
|
|
665
700
|
process.exit(0);
|
|
666
701
|
}
|
|
667
702
|
const globalOpts = cmd.optsWithGlobals();
|
|
@@ -669,7 +704,7 @@ function registerSchemaCommand(program) {
|
|
|
669
704
|
const shouldSave = opts.save !== false;
|
|
670
705
|
if (opts.output) {
|
|
671
706
|
writeFileSync(opts.output, prompt, "utf-8");
|
|
672
|
-
console.info(
|
|
707
|
+
console.info(chalk7.green(`\u2713 Prompt written to ${opts.output}`));
|
|
673
708
|
return;
|
|
674
709
|
}
|
|
675
710
|
if (shouldSave) {
|
|
@@ -683,8 +718,8 @@ function registerSchemaCommand(program) {
|
|
|
683
718
|
const filename = join2(pullsDir, `${date}-${hash}.md`);
|
|
684
719
|
writeFileSync(filename, prompt, "utf-8");
|
|
685
720
|
writeFileSync(join2(diffDir, "latest.json"), JSON.stringify(result, null, 2), "utf-8");
|
|
686
|
-
console.info(
|
|
687
|
-
console.info(
|
|
721
|
+
console.info(chalk7.green(`\u2713 Pull prompt written to ${filename}`));
|
|
722
|
+
console.info(chalk7.dim(" Copy-paste its contents into your LLM to resolve the drift."));
|
|
688
723
|
} else {
|
|
689
724
|
process.stdout.write(prompt);
|
|
690
725
|
}
|
|
@@ -699,46 +734,46 @@ var attrInline = (attr) => {
|
|
|
699
734
|
function printDiffOutput(result) {
|
|
700
735
|
const lines = [];
|
|
701
736
|
for (const obj of result.customObjects) {
|
|
702
|
-
lines.push(
|
|
703
|
-
lines.push(
|
|
737
|
+
lines.push(chalk7.yellow(`\u26A0 ${obj.name} (${obj.label}) \u2014 custom object, not in code`));
|
|
738
|
+
lines.push(chalk7.dim(' \u2192 Run "standards pull" to promote or leave.'));
|
|
704
739
|
}
|
|
705
740
|
for (const entry of result.systemObjectDrift) {
|
|
706
741
|
const unexpected = entry.sealed ? entry.customAttributes.filter((a) => !a.tolerated) : [];
|
|
707
742
|
const tolerated = entry.customAttributes.filter((a) => a.tolerated);
|
|
708
743
|
if (entry.sealed && unexpected.length > 0) {
|
|
709
744
|
lines.push(
|
|
710
|
-
|
|
745
|
+
chalk7.red(
|
|
711
746
|
`\u2717 ${entry.objectName} \u2014 ${unexpected.length} unexpected custom attribute(s) (sealed object)`
|
|
712
747
|
)
|
|
713
748
|
);
|
|
714
|
-
for (const attr of unexpected) lines.push(
|
|
715
|
-
lines.push(
|
|
749
|
+
for (const attr of unexpected) lines.push(chalk7.red(attrInline(attr)));
|
|
750
|
+
lines.push(chalk7.dim(' \u2192 Run "standards pull" to promote or tolerate these attributes.'));
|
|
716
751
|
if (tolerated.length > 0) {
|
|
717
|
-
lines.push(
|
|
718
|
-
for (const attr of tolerated) lines.push(
|
|
752
|
+
lines.push(chalk7.dim(` Also tolerated: ${tolerated.length} attribute(s)`));
|
|
753
|
+
for (const attr of tolerated) lines.push(chalk7.dim(attrInline(attr)));
|
|
719
754
|
}
|
|
720
755
|
continue;
|
|
721
756
|
}
|
|
722
757
|
const okAttrs = entry.sealed ? tolerated : entry.customAttributes;
|
|
723
758
|
if (okAttrs.length === 0) continue;
|
|
724
759
|
const okSuffix = entry.sealed ? "tolerated custom attribute(s) (sealed)" : "custom attribute(s) (extensible)";
|
|
725
|
-
lines.push(
|
|
726
|
-
for (const attr of okAttrs) lines.push(
|
|
760
|
+
lines.push(chalk7.green(`\u2713 ${entry.objectName} \u2014 ${okAttrs.length} ${okSuffix}`));
|
|
761
|
+
for (const attr of okAttrs) lines.push(chalk7.dim(attrInline(attr)));
|
|
727
762
|
}
|
|
728
763
|
if (lines.length === 0) {
|
|
729
|
-
console.info(
|
|
764
|
+
console.info(chalk7.green("\u2713 No drift detected."));
|
|
730
765
|
return;
|
|
731
766
|
}
|
|
732
767
|
console.info(lines.join("\n"));
|
|
733
768
|
if (result.hasUnexpectedDrift) {
|
|
734
769
|
console.info(
|
|
735
|
-
|
|
770
|
+
chalk7.red(
|
|
736
771
|
`
|
|
737
772
|
\u2717 Unexpected drift: ${result.summary.totalUnexpected} attribute(s) on sealed object(s).`
|
|
738
773
|
)
|
|
739
774
|
);
|
|
740
775
|
} else {
|
|
741
|
-
console.info(
|
|
776
|
+
console.info(chalk7.green("\n\u2713 No unexpected drift."));
|
|
742
777
|
}
|
|
743
778
|
}
|
|
744
779
|
function resolveStandardsDir() {
|
|
@@ -857,6 +892,7 @@ function createProgram() {
|
|
|
857
892
|
registerKeysCommand(program);
|
|
858
893
|
registerAuthCommand(program);
|
|
859
894
|
registerAutofillCommand(program);
|
|
895
|
+
registerBundlesCommand(program);
|
|
860
896
|
registerConnectorsCommand(program);
|
|
861
897
|
program.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
862
898
|
const raw = program.opts();
|
|
@@ -871,7 +907,7 @@ function createProgram() {
|
|
|
871
907
|
program.setOptionValue("tenant", raw.tenant);
|
|
872
908
|
if (!(resolved.apiKey || isPublicCommand(actionCommand))) {
|
|
873
909
|
console.error(
|
|
874
|
-
|
|
910
|
+
chalk8.red(
|
|
875
911
|
`\u2717 Error: No Standards instance configured. Run "standards login" or pass --api-key.`
|
|
876
912
|
)
|
|
877
913
|
);
|
|
@@ -885,12 +921,12 @@ async function runProgram(argv = process.argv) {
|
|
|
885
921
|
await program.parseAsync(argv).catch((error) => {
|
|
886
922
|
if (error instanceof ApiClientError) {
|
|
887
923
|
if (error.statusCode > 0) {
|
|
888
|
-
console.error(
|
|
924
|
+
console.error(chalk8.red(`\u2717 Error (${error.statusCode}): ${error.message}`));
|
|
889
925
|
} else {
|
|
890
|
-
console.error(
|
|
926
|
+
console.error(chalk8.red(`\u2717 Error: ${error.message}`));
|
|
891
927
|
}
|
|
892
928
|
} else if (error instanceof Error) {
|
|
893
|
-
console.error(
|
|
929
|
+
console.error(chalk8.red(`\u2717 Error: ${error.message}`));
|
|
894
930
|
}
|
|
895
931
|
process.exit(1);
|
|
896
932
|
});
|