@standards/cli 1.0.0-alpha.416 → 1.0.0-alpha.419
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/*! © 2025-2026 AND YOU CREATE SAS (RCS Paris 940 190 614). Proprietary — see LICENSE (Standards SDK License 1.0). */
|
|
3
|
-
import { t as discoverBundles } from "./discover-bundles-
|
|
3
|
+
import { t as discoverBundles } from "./discover-bundles-DPpEZVv0.mjs";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { styleText } from "node:util";
|
|
6
6
|
import { BundleConflictError, StandardsRequestError, createTransport, syncBundle } from "@standards/client";
|
|
@@ -19,7 +19,7 @@ import { stdin, stdout } from "node:process";
|
|
|
19
19
|
import { createInterface } from "node:readline/promises";
|
|
20
20
|
import { homedir } from "node:os";
|
|
21
21
|
import { isSafeSkillFilePath, skillFileText } from "@standards/constants";
|
|
22
|
-
|
|
22
|
+
// src/output.ts
|
|
23
23
|
const MAX_CELL_WIDTH = 50;
|
|
24
24
|
function truncate(value, maxLength) {
|
|
25
25
|
if (value.length <= maxLength) return value;
|
|
@@ -71,8 +71,7 @@ function formatOutput(data, format) {
|
|
|
71
71
|
}
|
|
72
72
|
process.stdout.write(`${formatTable(items)}\n`);
|
|
73
73
|
}
|
|
74
|
-
|
|
75
|
-
//#region src/client.ts
|
|
74
|
+
// src/client.ts
|
|
76
75
|
/** The CLI's transport: the profile's bearer key and tenant header over the shared HTTP transport. */
|
|
77
76
|
function createClient(config) {
|
|
78
77
|
return createTransport({
|
|
@@ -81,8 +80,7 @@ function createClient(config) {
|
|
|
81
80
|
tenantId: config.tenantId
|
|
82
81
|
});
|
|
83
82
|
}
|
|
84
|
-
|
|
85
|
-
//#region src/commands/common.ts
|
|
83
|
+
// src/commands/common.ts
|
|
86
84
|
function getGlobalOptions(cmd) {
|
|
87
85
|
return cmd.optsWithGlobals();
|
|
88
86
|
}
|
|
@@ -154,8 +152,7 @@ function requireConfirmation(yes, message) {
|
|
|
154
152
|
function messageOf(error) {
|
|
155
153
|
return error instanceof Error ? error.message : String(error);
|
|
156
154
|
}
|
|
157
|
-
|
|
158
|
-
//#region src/commands/ai.ts
|
|
155
|
+
// src/commands/ai.ts
|
|
159
156
|
const SCOPES = ["me", "workspace"];
|
|
160
157
|
/** `GET /ai/usage` reads inclusive UTC days; anything else reaches the API as a 400. */
|
|
161
158
|
const ISO_DAY = /^\d{4}-\d{2}-\d{2}$/u;
|
|
@@ -185,8 +182,7 @@ function registerAiCommand(program) {
|
|
|
185
182
|
formatOutput(await getAppClientFromCommand(cmd).ai.wallet({}), getFormat(cmd));
|
|
186
183
|
});
|
|
187
184
|
}
|
|
188
|
-
|
|
189
|
-
//#region src/commands/auth.ts
|
|
185
|
+
// src/commands/auth.ts
|
|
190
186
|
function registerAuthCommand(program) {
|
|
191
187
|
program.command("auth").description("Inspect CLI authentication").command("whoami").description("Show current configuration and validate API key").action(async (_opts, cmd) => {
|
|
192
188
|
const root = getGlobalOptions(cmd);
|
|
@@ -201,8 +197,7 @@ function registerAuthCommand(program) {
|
|
|
201
197
|
if (Array.isArray(keys) && keys.length > 0) write(` Active keys: ${keys.filter((key) => !key.revokedAt).length}`);
|
|
202
198
|
});
|
|
203
199
|
}
|
|
204
|
-
|
|
205
|
-
//#region src/discovery/order-bundles.ts
|
|
200
|
+
// src/discovery/order-bundles.ts
|
|
206
201
|
/**
|
|
207
202
|
* Orders discovered bundles so each comes after the bundles it `uses`.
|
|
208
203
|
* Bundles a `uses` names that were not discovered are already the host's concern.
|
|
@@ -223,8 +218,7 @@ async function orderByUses(discovered) {
|
|
|
223
218
|
for (const entry of discovered) await visit(entry);
|
|
224
219
|
return ordered;
|
|
225
220
|
}
|
|
226
|
-
|
|
227
|
-
//#region src/commands/bundles.ts
|
|
221
|
+
// src/commands/bundles.ts
|
|
228
222
|
const HASH_PREFIX_LENGTH = 7;
|
|
229
223
|
function shortHash(hash) {
|
|
230
224
|
return hash?.slice(0, HASH_PREFIX_LENGTH) ?? "";
|
|
@@ -272,6 +266,10 @@ function collectDecision(value, decisions) {
|
|
|
272
266
|
};
|
|
273
267
|
throw new ValidationError(`--decision must read <pieceId>=bind, <pieceId>=skip or <pieceId>=rename:<name> (received: ${value})`, []);
|
|
274
268
|
}
|
|
269
|
+
/** A repeatable option's values, in the order given. */
|
|
270
|
+
function collectPieceId(value, pieceIds) {
|
|
271
|
+
return [...pieceIds, value];
|
|
272
|
+
}
|
|
275
273
|
/** The input `preview` and `add` share: whole bundles, in one locale. */
|
|
276
274
|
function addInput(names, opts) {
|
|
277
275
|
return {
|
|
@@ -286,8 +284,9 @@ function withAddOptions(command) {
|
|
|
286
284
|
}
|
|
287
285
|
/**
|
|
288
286
|
* The workspace's bundles: sync the ones the project declares, list what is
|
|
289
|
-
* installed, remove one,
|
|
290
|
-
* owns (`preview`, then `add` with the preview's fingerprint)
|
|
287
|
+
* installed and where each stands, remove one, add a bundle the workspace may
|
|
288
|
+
* add as a copy it owns (`preview`, then `add` with the preview's fingerprint)
|
|
289
|
+
* and update such a copy (`update-preview`, then `update` with its fingerprint).
|
|
291
290
|
*/
|
|
292
291
|
function registerBundlesCommand(program) {
|
|
293
292
|
const bundles = program.command("bundles").description("Sync and manage the workspace's bundles");
|
|
@@ -302,6 +301,9 @@ function registerBundlesCommand(program) {
|
|
|
302
301
|
installedAt: row.installedAt
|
|
303
302
|
})), getFormat(cmd));
|
|
304
303
|
}));
|
|
304
|
+
bundles.command("status").description("Show where each installed bundle stands and the bundles that depend on it").action((_opts, cmd) => run(async () => {
|
|
305
|
+
formatOutput(await getAppClientFromCommand(cmd).bundles.status({}), getFormat(cmd));
|
|
306
|
+
}));
|
|
305
307
|
bundles.command("available").description("List the bundles the workspace may add, and whether each is installed").option("--locale <locale>", `language of the labels (${BUNDLE_LOCALES.join(", ")})`, "en").action((opts, cmd) => run(async () => {
|
|
306
308
|
const { available } = await getAppClientFromCommand(cmd).bundles.list({ locale: parseLocale(opts.locale) });
|
|
307
309
|
formatOutput(available, getFormat(cmd));
|
|
@@ -316,14 +318,26 @@ function registerBundlesCommand(program) {
|
|
|
316
318
|
fingerprint: opts.fingerprint
|
|
317
319
|
}), getFormat(cmd));
|
|
318
320
|
}));
|
|
319
|
-
bundles.command("
|
|
321
|
+
bundles.command("update-preview").description("Plan an added bundle's update, piece by piece, and the plan's fingerprint").argument("<name>", "bundle name").action((name, _opts, cmd) => run(async () => {
|
|
322
|
+
formatOutput(await getAppClientFromCommand(cmd).bundles.updatePreview({ name }), getFormat(cmd));
|
|
323
|
+
}));
|
|
324
|
+
bundles.command("update").description("Update an added bundle as its preview showed; nothing is removed").argument("<name>", "bundle name").requiredOption("--fingerprint <fingerprint>", "the fingerprint `bundles update-preview` returned").option("--take <pieceId>", "take the new version of a piece you changed (repeatable)", collectPieceId, []).option("--skip-missing <pieceId>", "do not reinstall a missing piece (repeatable)", collectPieceId, []).option("--decision <pieceId=choice>", "how to settle a collision: bind, skip or rename:<name> (repeatable)", collectDecision, {}).action((name, opts, cmd) => run(async () => {
|
|
325
|
+
const { applied } = await getAppClientFromCommand(cmd).bundles.update({
|
|
326
|
+
name,
|
|
327
|
+
fingerprint: opts.fingerprint,
|
|
328
|
+
take: opts.take,
|
|
329
|
+
skipMissing: opts.skipMissing,
|
|
330
|
+
decisions: opts.decision
|
|
331
|
+
});
|
|
332
|
+
console.info(`${name} updated, ${applied} applied`);
|
|
333
|
+
}));
|
|
334
|
+
bundles.command("remove").description("Remove a synced bundle; its pieces are demoted, never deleted. An added bundle is refused: uninstall it from the Bundles window").argument("<name>", "bundle name").option("--yes", "remove without confirmation").action((name, opts, cmd) => run(async () => {
|
|
320
335
|
requireConfirmation(opts.yes, `Removing bundle "${name}" demotes its objects to workspace-owned. Re-run with "--yes" to confirm.`);
|
|
321
336
|
await getAppClientFromCommand(cmd).bundles.remove({ name });
|
|
322
337
|
console.info(`${name} removed`);
|
|
323
338
|
}));
|
|
324
339
|
}
|
|
325
|
-
|
|
326
|
-
//#region src/commands/connectors.ts
|
|
340
|
+
// src/commands/connectors.ts
|
|
327
341
|
const PROVIDERS = Object.keys({
|
|
328
342
|
github: true,
|
|
329
343
|
slack: true,
|
|
@@ -356,7 +370,7 @@ function connectDisclosure(provider, capabilities = []) {
|
|
|
356
370
|
if (modify) lines.push("- create, change and delete your events");
|
|
357
371
|
lines.push("It shows them in the workspace, links them to records and makes them searchable.", "The default assistant can read this calendar, and AI providers process your events whenever an agent works on them.");
|
|
358
372
|
} else return null;
|
|
359
|
-
lines.push("Your data is not sold and not used for ads.", "Disconnect at any time
|
|
373
|
+
lines.push("Your data is not sold and not used for ads.", "Disconnect at any time on the Connectors page.", "Details: https://docs.standards.new/docs/integrations/connected-accounts");
|
|
360
374
|
return lines.join("\n");
|
|
361
375
|
}
|
|
362
376
|
/** Parse a comma-separated `--capabilities` flag; unknown tiers are refused before the request. */
|
|
@@ -378,16 +392,12 @@ function registerConnectorsCommand(program) {
|
|
|
378
392
|
connectors.command("list").description("List connector connections").option("--scope <scope>", "connection scope (tenant or actor)", "tenant").action(async (opts, cmd) => {
|
|
379
393
|
formatOutput(await getAppClientFromCommand(cmd).connectors.list({ scope: resolveScope(opts.scope) }), getFormat(cmd));
|
|
380
394
|
});
|
|
381
|
-
connectors.command("connect").description("
|
|
395
|
+
connectors.command("connect").description("Check a provider and capabilities; the account itself is connected from the app").requiredOption("--provider <provider>", `connector provider (${PROVIDERS.join(", ")}); run "connectors providers" for the ones this deployment configured`).option("--scope <scope>", "connection scope (tenant or actor)", "tenant").option("--capabilities <list>", `comma-separated capability tiers beyond read (${CAPABILITIES.join(", ")})`).option("--yes", "confirm the access a mailbox or calendar connection gives Standards").action((opts) => {
|
|
382
396
|
if (!PROVIDERS.includes(opts.provider)) throw new ValidationError(`--provider must be one of: ${PROVIDERS.join(", ")}`, []);
|
|
383
397
|
const capabilities = parseCapabilities(opts.capabilities);
|
|
384
398
|
const disclosure = connectDisclosure(opts.provider, capabilities);
|
|
385
399
|
if (disclosure && !opts.yes) throw new Error(`${disclosure}\n\nRe-run with "--yes" to continue.`);
|
|
386
|
-
|
|
387
|
-
provider: opts.provider,
|
|
388
|
-
scope: resolveScope(opts.scope),
|
|
389
|
-
...capabilities ? { capabilities } : {}
|
|
390
|
-
}), getFormat(cmd));
|
|
400
|
+
process.stdout.write(`${opts.provider} is connected from the Standards app: open Connectors in the sidebar and connect it there.\n`);
|
|
391
401
|
});
|
|
392
402
|
connectors.command("disconnect").description("Disconnect (delete) a connector connection").argument("<id>", "connection ID").option("--yes", "disconnect without confirmation").option("--remove-imported", "also remove what a mail or calendar connection imported (kept by default)").action(async (id, opts, cmd) => {
|
|
393
403
|
if (!opts.yes) throw new Error("Disconnecting a connector is explicit. Re-run with \"--yes\" to confirm.");
|
|
@@ -398,8 +408,7 @@ function registerConnectorsCommand(program) {
|
|
|
398
408
|
process.stdout.write(`${styleText("green", "✓")} Connector connection ${id} disconnected.\n`);
|
|
399
409
|
});
|
|
400
410
|
}
|
|
401
|
-
|
|
402
|
-
//#region src/drift/shared-state.ts
|
|
411
|
+
// src/drift/shared-state.ts
|
|
403
412
|
async function readSchemaState(client) {
|
|
404
413
|
const state = parseSchemaState(await client.schemaState.get({}));
|
|
405
414
|
if (createHash("sha256").update(canonicalStringify(schemaStateSourcePayload(state.entries))).digest("hex") !== state.sourceFingerprint) throw new ValidationError("Invalid schema state: sourceFingerprint does not match deployed source", []);
|
|
@@ -408,8 +417,7 @@ async function readSchemaState(client) {
|
|
|
408
417
|
function prettyCanonical(value) {
|
|
409
418
|
return JSON.stringify(JSON.parse(canonicalStringify(value)), null, 2);
|
|
410
419
|
}
|
|
411
|
-
|
|
412
|
-
//#region src/commands/diff.ts
|
|
420
|
+
// src/commands/diff.ts
|
|
413
421
|
async function runDiffCommand(client) {
|
|
414
422
|
try {
|
|
415
423
|
const diff = diffSchemaState(await readSchemaState(client));
|
|
@@ -443,8 +451,7 @@ function registerDiffCommand(program) {
|
|
|
443
451
|
process.exit(result.exitCode);
|
|
444
452
|
});
|
|
445
453
|
}
|
|
446
|
-
|
|
447
|
-
//#region src/commands/documents.ts
|
|
454
|
+
// src/commands/documents.ts
|
|
448
455
|
/**
|
|
449
456
|
* Human-readable table row for a pack file. `id` is kept (unlike other
|
|
450
457
|
* dropped fields) because `remove-file <documentId> <fileId>` requires it —
|
|
@@ -517,8 +524,7 @@ function registerDocumentsCommand(program) {
|
|
|
517
524
|
process.stdout.write(text.endsWith("\n") ? text : `${text}\n`);
|
|
518
525
|
});
|
|
519
526
|
}
|
|
520
|
-
|
|
521
|
-
//#region src/commands/embeddings.ts
|
|
527
|
+
// src/commands/embeddings.ts
|
|
522
528
|
function registerEmbeddingsCommand(program) {
|
|
523
529
|
program.command("embeddings").description("Maintain record and email embeddings").command("drain").description("Embed every pending record and email of the tenant").action(async (_opts, cmd) => {
|
|
524
530
|
const tenant = requireTenant(cmd, "An embedding drain names its tenant explicitly. Pass \"--tenant <id>\".");
|
|
@@ -526,8 +532,7 @@ function registerEmbeddingsCommand(program) {
|
|
|
526
532
|
process.stdout.write(`${styleText("green", "✓")} Embedding drain accepted for tenant ${tenant}.\n`);
|
|
527
533
|
});
|
|
528
534
|
}
|
|
529
|
-
|
|
530
|
-
//#region src/commands/folders.ts
|
|
535
|
+
// src/commands/folders.ts
|
|
531
536
|
function registerFoldersCommand(program) {
|
|
532
537
|
program.command("folders").description("Manage record drive folders").command("reconcile-paths").description("Create a folder tree on a record drive from paths").argument("<object>", "object name (e.g. contacts)").argument("<recordId>", "record ID owning the drive").option("--path <path>", "folder path to create (repeatable)", (val, acc) => {
|
|
533
538
|
acc.push(val);
|
|
@@ -547,8 +552,7 @@ function registerFoldersCommand(program) {
|
|
|
547
552
|
}), getFormat(cmd));
|
|
548
553
|
});
|
|
549
554
|
}
|
|
550
|
-
|
|
551
|
-
//#region src/commands/invitations.ts
|
|
555
|
+
// src/commands/invitations.ts
|
|
552
556
|
/** Invitation ids are `randomUUID` server-side, so anything else is a caller mistake. */
|
|
553
557
|
const INVITATION_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
554
558
|
/**
|
|
@@ -586,8 +590,7 @@ function registerInvitationsCommand(program) {
|
|
|
586
590
|
formatOutput(await getAppClientFromCommand(cmd).tenantInvitations.revoke({ id: invitationId }), getFormat(cmd));
|
|
587
591
|
});
|
|
588
592
|
}
|
|
589
|
-
|
|
590
|
-
//#region src/commands/keys.ts
|
|
593
|
+
// src/commands/keys.ts
|
|
591
594
|
async function resolveRoleId(client, name) {
|
|
592
595
|
const match = (await client.permissions.listRoles({})).find((role) => role.name === name);
|
|
593
596
|
if (!match) throw new Error(`Unknown role "${name}". Roles are listed in the app's People settings.`);
|
|
@@ -617,8 +620,7 @@ function registerKeysCommand(program) {
|
|
|
617
620
|
process.stdout.write(`${styleText("green", "✓")} API key ${id} revoked.\n`);
|
|
618
621
|
});
|
|
619
622
|
}
|
|
620
|
-
|
|
621
|
-
//#region src/commands/mcp.ts
|
|
623
|
+
// src/commands/mcp.ts
|
|
622
624
|
/** The auth types `POST /mcp-servers` accepts today — `oauth` is rejected by the API. */
|
|
623
625
|
const AUTH_TYPES = ["none", "header"];
|
|
624
626
|
/** Build the `auth` block the API expects, failing before the request when a header auth is incomplete. */
|
|
@@ -682,8 +684,7 @@ function registerMcpCommand(program) {
|
|
|
682
684
|
process.stdout.write(`${styleText("green", "✓")} MCP server ${id} disconnected.\n`);
|
|
683
685
|
});
|
|
684
686
|
}
|
|
685
|
-
|
|
686
|
-
//#region src/commands/meetings.ts
|
|
687
|
+
// src/commands/meetings.ts
|
|
687
688
|
const ORDERS = ["asc", "desc"];
|
|
688
689
|
/** Reject a typo instead of letting it fall back to the API default silently. */
|
|
689
690
|
function parseOrder(order) {
|
|
@@ -760,8 +761,7 @@ function registerMeetingsCommand(program) {
|
|
|
760
761
|
process.stdout.write(`${styleText("green", "✓")} Meeting grants recompute accepted for tenant ${tenant}.\n`);
|
|
761
762
|
});
|
|
762
763
|
}
|
|
763
|
-
|
|
764
|
-
//#region src/commands/memory.ts
|
|
764
|
+
// src/commands/memory.ts
|
|
765
765
|
function registerMemoryCommand(program) {
|
|
766
766
|
program.command("memory").description("Maintain agent memory").command("backfill").description("Rebuild agent memory from the tenant's last 30 days of sessions and meetings").option("--yes", "backfill without confirmation").action(async (opts, cmd) => {
|
|
767
767
|
if (!opts.yes) throw new ValidationError("A memory backfill spends model calls on the last 30 days of evidence. Re-run with \"--yes\" to confirm.", []);
|
|
@@ -770,8 +770,7 @@ function registerMemoryCommand(program) {
|
|
|
770
770
|
process.stdout.write(`${styleText("green", "✓")} Memory backfill queued for tenant ${tenant}. It runs in the background — follow the server logs for progress.\n`);
|
|
771
771
|
});
|
|
772
772
|
}
|
|
773
|
-
|
|
774
|
-
//#region src/drift/reconciliation-prompt.ts
|
|
773
|
+
// src/drift/reconciliation-prompt.ts
|
|
775
774
|
function renderReconciliationPrompt(state) {
|
|
776
775
|
const lines = [
|
|
777
776
|
"# Standards schema reconciliation",
|
|
@@ -786,8 +785,7 @@ function renderReconciliationPrompt(state) {
|
|
|
786
785
|
for (const entry of changes) lines.push(`## ${entry.change} ${JSON.stringify(entry.address)}`, `Status: ${entry.status}${entry.status === "copy" ? " (retained)" : ""}`, "```json", prettyCanonical(entry.effective ?? entry.source), "```", "");
|
|
787
786
|
return `${lines.join("\n").trimEnd()}\n`;
|
|
788
787
|
}
|
|
789
|
-
|
|
790
|
-
//#region src/commands/pull.ts
|
|
788
|
+
// src/commands/pull.ts
|
|
791
789
|
function registerPullCommand(program) {
|
|
792
790
|
program.command("pull").description("Read deployed source vs shared runtime; excludes unbuilt local TypeScript").option("--json", "Emit canonical shared state JSON instead of guidance").action(async (opts, cmd) => {
|
|
793
791
|
let code = 0;
|
|
@@ -801,15 +799,13 @@ function registerPullCommand(program) {
|
|
|
801
799
|
process.exit(code);
|
|
802
800
|
});
|
|
803
801
|
}
|
|
804
|
-
|
|
805
|
-
//#region src/commands/quotas.ts
|
|
802
|
+
// src/commands/quotas.ts
|
|
806
803
|
function registerQuotasCommand(program) {
|
|
807
804
|
program.command("quotas").description("Inspect the tenant's remaining capacity").command("list").description("List one state per quota key (limit is null when nothing is enforced)").action(async (_opts, cmd) => {
|
|
808
805
|
formatOutput(await getAppClientFromCommand(cmd).quotas.list({}), getFormat(cmd));
|
|
809
806
|
});
|
|
810
807
|
}
|
|
811
|
-
|
|
812
|
-
//#region src/commands/records.ts
|
|
808
|
+
// src/commands/records.ts
|
|
813
809
|
function parseSortFlag(sort) {
|
|
814
810
|
const [attribute, direction = "asc"] = sort.split(":");
|
|
815
811
|
return [{
|
|
@@ -820,8 +816,8 @@ function parseSortFlag(sort) {
|
|
|
820
816
|
/** Build the shared list/search request body from common query flags. */
|
|
821
817
|
function buildQueryBody(opts) {
|
|
822
818
|
const body = {};
|
|
823
|
-
if (opts.limit) body.limit =
|
|
824
|
-
if (opts.offset) body.offset =
|
|
819
|
+
if (opts.limit !== void 0) body.limit = parseCount("--limit", opts.limit);
|
|
820
|
+
if (opts.offset !== void 0) body.offset = parseCount("--offset", opts.offset);
|
|
825
821
|
if (opts.sort) body.sorts = parseSortFlag(opts.sort);
|
|
826
822
|
if (opts.filter) body.filters = JSON.parse(opts.filter);
|
|
827
823
|
if (opts.fields !== void 0) body.fields = parseCsvList(opts.fields);
|
|
@@ -974,8 +970,7 @@ function registerRecordsCommand(program) {
|
|
|
974
970
|
}), getFormat(cmd));
|
|
975
971
|
});
|
|
976
972
|
}
|
|
977
|
-
|
|
978
|
-
//#region src/config.ts
|
|
973
|
+
// src/config.ts
|
|
979
974
|
const DEFAULT_API_URL = "http://localhost:4100/v1";
|
|
980
975
|
const ENV_PROFILE_NAME = "sandbox";
|
|
981
976
|
function getDefaultApiUrl() {
|
|
@@ -1092,8 +1087,7 @@ async function resolveCliConfig(options) {
|
|
|
1092
1087
|
apiKey: process.env.STANDARDS_API_KEY
|
|
1093
1088
|
};
|
|
1094
1089
|
}
|
|
1095
|
-
|
|
1096
|
-
//#region src/commands/root.ts
|
|
1090
|
+
// src/commands/root.ts
|
|
1097
1091
|
async function promptForMissingValue(label) {
|
|
1098
1092
|
const rl = createInterface({
|
|
1099
1093
|
input: stdin,
|
|
@@ -1143,8 +1137,7 @@ function registerRootCommands(program) {
|
|
|
1143
1137
|
process.stdout.write(`${styleText("green", "✓")} Standards instance removed.\n`);
|
|
1144
1138
|
});
|
|
1145
1139
|
}
|
|
1146
|
-
|
|
1147
|
-
//#region src/commands/schema.ts
|
|
1140
|
+
// src/commands/schema.ts
|
|
1148
1141
|
function registerSchemaCommand(program) {
|
|
1149
1142
|
const schema = program.command("schema").description("Inspect schema objects and attributes");
|
|
1150
1143
|
schema.command("list").description("List all schema objects").action(async (_opts, cmd) => {
|
|
@@ -1157,8 +1150,7 @@ function registerSchemaCommand(program) {
|
|
|
1157
1150
|
formatOutput(await getAppClientFromCommand(cmd).schemaGroups.list({}), getFormat(cmd));
|
|
1158
1151
|
});
|
|
1159
1152
|
}
|
|
1160
|
-
|
|
1161
|
-
//#region src/commands/search.ts
|
|
1153
|
+
// src/commands/search.ts
|
|
1162
1154
|
function registerSearchCommand(program) {
|
|
1163
1155
|
program.command("search").description("Maintain the Standards search index").command("reindex").description("Rebuild the tenant search index beside the live one, then switch").option("--yes", "reindex without confirmation").option("--emails", "hand the tenant's stored emails back to the email indexer instead (nothing is cleared)").option("--after-id <emailId>", "with --emails, resume after the last email id a failed run reported").option("--rebuild", "with --emails and --yes, rebuild the mail search index from the stored mail instead (lifts a quarantine)").action(async (opts, cmd) => {
|
|
1164
1156
|
if (opts.afterId !== void 0 && !opts.emails) throw new ValidationError("\"--after-id\" resumes an email reindex. Pass it with \"--emails\".", []);
|
|
@@ -1181,8 +1173,7 @@ function registerSearchCommand(program) {
|
|
|
1181
1173
|
process.stdout.write(`${styleText("green", "✓")} Index rebuild accepted for tenant ${tenant}. Search keeps answering from the current index until the rebuilt one replaces it — follow the server logs for progress.\n`);
|
|
1182
1174
|
});
|
|
1183
1175
|
}
|
|
1184
|
-
|
|
1185
|
-
//#region src/commands/skills.ts
|
|
1176
|
+
// src/commands/skills.ts
|
|
1186
1177
|
const SKILL_FILE = "SKILL.md";
|
|
1187
1178
|
const DEFAULT_SEARCH_LIMIT = 20;
|
|
1188
1179
|
/** A folder name: one path segment under the rule (`isSafeSkillFilePath`). */
|
|
@@ -1304,23 +1295,38 @@ async function runSkillsPull(client, dir, names) {
|
|
|
1304
1295
|
}
|
|
1305
1296
|
return written;
|
|
1306
1297
|
}
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
*/
|
|
1311
|
-
|
|
1312
|
-
const
|
|
1313
|
-
return
|
|
1314
|
-
query,
|
|
1315
|
-
scope: options.community === true ? "community" : "official",
|
|
1316
|
-
limit
|
|
1317
|
-
})).map(({ source, name, state, reason, description, installs }) => ({
|
|
1298
|
+
function searchLimit(limit) {
|
|
1299
|
+
return limit === void 0 ? DEFAULT_SEARCH_LIMIT : parseCount("--limit", limit);
|
|
1300
|
+
}
|
|
1301
|
+
/** Every row carries the same keys, because a table takes its columns from the first. */
|
|
1302
|
+
function catalogRow(result) {
|
|
1303
|
+
const { source, name, state, reason, description, installs } = result;
|
|
1304
|
+
return {
|
|
1318
1305
|
source,
|
|
1319
1306
|
name,
|
|
1320
1307
|
state,
|
|
1321
1308
|
reason,
|
|
1322
1309
|
description,
|
|
1323
1310
|
installs
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
/** `standards skills search`: our index, or skills.sh with `community`. */
|
|
1314
|
+
async function runSkillsSearch(client, query, options = {}) {
|
|
1315
|
+
return (await client.skillCatalog.search({
|
|
1316
|
+
query,
|
|
1317
|
+
scope: options.community === true ? "community" : "official",
|
|
1318
|
+
limit: searchLimit(options.limit)
|
|
1319
|
+
})).map(catalogRow);
|
|
1320
|
+
}
|
|
1321
|
+
/** `standards skills top`: skills.sh's all-time leaderboard, or the last 24 hours with `trending`. */
|
|
1322
|
+
async function runSkillsTop(client, options = {}) {
|
|
1323
|
+
return (await client.skillCatalog.search({
|
|
1324
|
+
query: "",
|
|
1325
|
+
scope: options.trending === true ? "trending" : "top",
|
|
1326
|
+
limit: searchLimit(options.limit)
|
|
1327
|
+
})).map((result) => ({
|
|
1328
|
+
...catalogRow(result),
|
|
1329
|
+
weeklyInstalls: result.weeklyInstalls
|
|
1324
1330
|
}));
|
|
1325
1331
|
}
|
|
1326
1332
|
/** `standards skills preview`: what a source would install, the source checked here first. */
|
|
@@ -1402,6 +1408,9 @@ function registerSkillsCommand(program) {
|
|
|
1402
1408
|
skills.command("search").description("Find skills to add: the official catalogue, or skills.sh with --community").argument("<query>", "what the skill should do").option("--community", "search skills.sh instead of the official catalogue").option("--limit <n>", "max results to return (up to 50)").action(async (query, opts, cmd) => {
|
|
1403
1409
|
await printAnswer(cmd, () => runSkillsSearch(getAppClientFromCommand(cmd), query, opts));
|
|
1404
1410
|
});
|
|
1411
|
+
skills.command("top").description("List skills.sh's most installed skills, or the last 24 hours with --trending").option("--trending", "rank by the last 24 hours instead of all time").option("--limit <n>", "max results to return (up to 50)").action(async (opts, cmd) => {
|
|
1412
|
+
await printAnswer(cmd, () => runSkillsTop(getAppClientFromCommand(cmd), opts));
|
|
1413
|
+
});
|
|
1405
1414
|
skills.command("preview").description("Show what a source would install, without installing it").argument("<source>", "owner/repo@skill or owner/repo@skill#ref").action(async (source, _opts, cmd) => {
|
|
1406
1415
|
await printAnswer(cmd, () => runSkillsPreview(getAppClientFromCommand(cmd), source));
|
|
1407
1416
|
});
|
|
@@ -1415,8 +1424,7 @@ function registerSkillsCommand(program) {
|
|
|
1415
1424
|
await printAnswer(cmd, () => runSkillsRefresh(getAppClientFromCommand(cmd)));
|
|
1416
1425
|
});
|
|
1417
1426
|
}
|
|
1418
|
-
|
|
1419
|
-
//#region src/version.ts
|
|
1427
|
+
// src/version.ts
|
|
1420
1428
|
/**
|
|
1421
1429
|
* The installed package's version, read from its own manifest: `src/` and the
|
|
1422
1430
|
* built `dist/` both sit one level under it, and npm always ships
|
|
@@ -1431,8 +1439,7 @@ function cliVersion() {
|
|
|
1431
1439
|
const manifest = createRequire(import.meta.url)("../package.json");
|
|
1432
1440
|
return typeof manifest === "object" && manifest !== null && "version" in manifest && typeof manifest.version === "string" ? manifest.version : "unknown";
|
|
1433
1441
|
}
|
|
1434
|
-
|
|
1435
|
-
//#region src/program.ts
|
|
1442
|
+
// src/program.ts
|
|
1436
1443
|
const PUBLIC_COMMANDS = /* @__PURE__ */ new Set([
|
|
1437
1444
|
"login",
|
|
1438
1445
|
"use",
|
|
@@ -1495,8 +1502,6 @@ async function runProgram(argv = process.argv) {
|
|
|
1495
1502
|
process.exit(1);
|
|
1496
1503
|
});
|
|
1497
1504
|
}
|
|
1498
|
-
|
|
1499
|
-
//#region src/bin.ts
|
|
1505
|
+
// src/bin.ts
|
|
1500
1506
|
await runProgram();
|
|
1501
|
-
//#endregion
|
|
1502
1507
|
export {};
|
|
@@ -5,7 +5,7 @@ import { existsSync } from "node:fs";
|
|
|
5
5
|
import { glob } from "node:fs/promises";
|
|
6
6
|
import { join, relative, resolve } from "node:path";
|
|
7
7
|
import { createJiti } from "jiti";
|
|
8
|
-
|
|
8
|
+
// src/discovery/discover-bundles.ts
|
|
9
9
|
const DEFAULT_PATTERNS = ["standards/bundles/*.ts"];
|
|
10
10
|
const CONFIG_FILE = "standards.config.ts";
|
|
11
11
|
function messageOf(error) {
|
|
@@ -64,5 +64,4 @@ async function discoverBundles(options = {}) {
|
|
|
64
64
|
if (files.length > 0 && found.size === 0) throw new ValidationError(`No bundle found in ${files.length} file(s) matching ${patterns.join(", ")}`, []);
|
|
65
65
|
return [...found.values()].sort((a, b) => a.bundle.name.localeCompare(b.bundle.name));
|
|
66
66
|
}
|
|
67
|
-
//#endregion
|
|
68
67
|
export { discoverBundles as t };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
|
|
2
2
|
import { BundleBuilder, ObjectBuilderLike } from "@standards/schema";
|
|
3
|
-
//#region src/discovery/define-config.d.ts
|
|
4
3
|
/** What `standards.config.ts` declares. Every key is optional: the conventions apply without a file. */
|
|
5
4
|
interface StandardsCliConfig {
|
|
6
5
|
/** Glob pattern(s), relative to the project root, that locate the bundle files. */
|
|
@@ -8,8 +7,6 @@ interface StandardsCliConfig {
|
|
|
8
7
|
}
|
|
9
8
|
/** Types a `standards.config.ts` default export. */
|
|
10
9
|
export declare function defineConfig(config: StandardsCliConfig): StandardsCliConfig;
|
|
11
|
-
//#endregion
|
|
12
|
-
//#region src/discovery/discover-bundles.d.ts
|
|
13
10
|
type AnyBundle = BundleBuilder<string, readonly ObjectBuilderLike[]>;
|
|
14
11
|
interface DiscoveredBundle {
|
|
15
12
|
bundle: AnyBundle;
|
|
@@ -28,5 +25,4 @@ interface DiscoverBundlesOptions {
|
|
|
28
25
|
* patterns match, that is a `BundleBuilder`. Files may hold anything else.
|
|
29
26
|
*/
|
|
30
27
|
export declare function discoverBundles(options?: DiscoverBundlesOptions): Promise<DiscoveredBundle[]>;
|
|
31
|
-
//#endregion
|
|
32
28
|
export type { DiscoverBundlesOptions, DiscoveredBundle, StandardsCliConfig };
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/*! © 2025-2026 AND YOU CREATE SAS (RCS Paris 940 190 614). Proprietary — see LICENSE (Standards SDK License 1.0). */
|
|
3
|
-
import { t as discoverBundles } from "./discover-bundles-
|
|
4
|
-
|
|
3
|
+
import { t as discoverBundles } from "./discover-bundles-DPpEZVv0.mjs";
|
|
4
|
+
// src/discovery/define-config.ts
|
|
5
5
|
/** Types a `standards.config.ts` default export. */
|
|
6
6
|
function defineConfig(config) {
|
|
7
7
|
return config;
|
|
8
8
|
}
|
|
9
|
-
//#endregion
|
|
10
9
|
export { defineConfig, discoverBundles };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@standards/cli",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.419",
|
|
4
4
|
"description": "CLI tool to interact with Standards API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -23,20 +23,20 @@
|
|
|
23
23
|
"node": ">=22"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
+
"@standards/client": "1.0.0-alpha.419",
|
|
27
|
+
"@standards/constants": "1.0.0-alpha.419",
|
|
28
|
+
"@standards/schema": "1.0.0-alpha.419",
|
|
26
29
|
"cli-table3": "^0.6.5",
|
|
27
30
|
"commander": "^13.1.0",
|
|
28
|
-
"jiti": "2.7.0"
|
|
29
|
-
"@standards/client": "1.0.0-alpha.416",
|
|
30
|
-
"@standards/constants": "1.0.0-alpha.416",
|
|
31
|
-
"@standards/schema": "1.0.0-alpha.416"
|
|
31
|
+
"jiti": "2.7.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/node": "^25.6.0",
|
|
35
35
|
"jsdom": "^25.0.1",
|
|
36
|
-
"tsdown": "^0.23.
|
|
36
|
+
"tsdown": "^0.23.7",
|
|
37
37
|
"typescript": "^5.6.3",
|
|
38
|
-
"typescript7": "npm:typescript
|
|
39
|
-
"vitest": "^5.0
|
|
38
|
+
"typescript7": "npm:typescript@7.1.0-beta",
|
|
39
|
+
"vitest": "^5.1.0"
|
|
40
40
|
},
|
|
41
41
|
"publishConfig": {
|
|
42
42
|
"access": "public",
|