@theholocron/cli 3.27.0 → 3.28.0
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/cli.mjs +56 -25
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +8 -0
- package/dist/index.mjs +1 -0
- package/package.json +3 -3
package/dist/cli.mjs
CHANGED
|
@@ -257,6 +257,7 @@ function resolveConfig(raw) {
|
|
|
257
257
|
name: raw.name,
|
|
258
258
|
description: raw.description,
|
|
259
259
|
homepage,
|
|
260
|
+
org: raw.org,
|
|
260
261
|
repo: raw.repo,
|
|
261
262
|
workflows: raw.workflows,
|
|
262
263
|
providers,
|
|
@@ -333,6 +334,7 @@ async function runAuthSet(input) {
|
|
|
333
334
|
const print = input.print ?? ((l) => console.log(l));
|
|
334
335
|
const importer = input.importer ?? defaultImporter$1;
|
|
335
336
|
const { provider } = input;
|
|
337
|
+
const keyringKey = input.org ? `${provider}.${input.org}` : provider;
|
|
336
338
|
const token = resolveAuthSetToken({
|
|
337
339
|
provider,
|
|
338
340
|
positional: input.positional,
|
|
@@ -341,7 +343,7 @@ async function runAuthSet(input) {
|
|
|
341
343
|
const isFeatureKey = provider.includes(".");
|
|
342
344
|
const packageName = isFeatureKey ? null : resolvePluginPackage(provider);
|
|
343
345
|
if (!token) {
|
|
344
|
-
print(style.fail(`no token supplied for \`${
|
|
346
|
+
print(style.fail(`no token supplied for \`${keyringKey}\`.`));
|
|
345
347
|
print(style.hint(` pass as positional arg: holocron auth set ${provider} <token>`));
|
|
346
348
|
if (!isFeatureKey) {
|
|
347
349
|
print(style.hint(` or via env: HOLOCRON_${provider.toUpperCase()}_TOKEN / ${provider.toUpperCase()}_TOKEN`));
|
|
@@ -373,14 +375,14 @@ async function runAuthSet(input) {
|
|
|
373
375
|
print(style.warn(`cannot verify token — failed to load ${packageName}: ${msg}`));
|
|
374
376
|
print(style.hint(` storing token anyway; run 'holocron auth check ${provider}' once the plugin is installed`));
|
|
375
377
|
}
|
|
376
|
-
if (!setToken(
|
|
378
|
+
if (!setToken(keyringKey, token)) {
|
|
377
379
|
print(style.fail(`keyring unavailable — token not stored. Use env vars instead.`));
|
|
378
380
|
return {
|
|
379
381
|
status: "fail",
|
|
380
382
|
message: "keyring unavailable"
|
|
381
383
|
};
|
|
382
384
|
}
|
|
383
|
-
print(style.success(`stored ${
|
|
385
|
+
print(style.success(`stored ${keyringKey} token${subject ? ` (${subject})` : ""}`));
|
|
384
386
|
return {
|
|
385
387
|
status: "ok",
|
|
386
388
|
...subject ? { message: subject } : {}
|
|
@@ -402,16 +404,17 @@ async function runAuthCheck(input) {
|
|
|
402
404
|
const print = input.print ?? ((l) => console.log(l));
|
|
403
405
|
const importer = input.importer ?? defaultImporter$1;
|
|
404
406
|
const { provider } = input;
|
|
405
|
-
const
|
|
407
|
+
const keyringKey = input.org ? `${provider}.${input.org}` : provider;
|
|
408
|
+
const token = getToken(keyringKey);
|
|
406
409
|
if (!token) {
|
|
407
|
-
print(style.dim(`no stored token for ${
|
|
410
|
+
print(style.dim(`no stored token for ${keyringKey}`));
|
|
408
411
|
return {
|
|
409
412
|
status: "skip",
|
|
410
413
|
message: "no stored token"
|
|
411
414
|
};
|
|
412
415
|
}
|
|
413
416
|
if (provider.includes(".")) {
|
|
414
|
-
print(style.success(`${
|
|
417
|
+
print(style.success(`${keyringKey}: token stored (feature key — no plugin verification)`));
|
|
415
418
|
return {
|
|
416
419
|
status: "ok",
|
|
417
420
|
message: "stored"
|
|
@@ -421,22 +424,22 @@ async function runAuthCheck(input) {
|
|
|
421
424
|
try {
|
|
422
425
|
const module = await importer(packageName);
|
|
423
426
|
if (typeof module.verifyToken !== "function") {
|
|
424
|
-
print(style.warn(`${
|
|
427
|
+
print(style.warn(`${keyringKey}: token stored (plugin has no verifyToken; can't confirm validity)`));
|
|
425
428
|
return {
|
|
426
429
|
status: "ok",
|
|
427
430
|
message: "stored, unverified"
|
|
428
431
|
};
|
|
429
432
|
}
|
|
430
433
|
const verify = () => module.verifyToken(token);
|
|
431
|
-
const verified = input.showSpinner !== false ? await withSpinner(`Verifying ${
|
|
434
|
+
const verified = input.showSpinner !== false ? await withSpinner(`Verifying ${keyringKey} token…`, verify) : await verify();
|
|
432
435
|
if (verified.ok) {
|
|
433
|
-
print(style.success(`${
|
|
436
|
+
print(style.success(`${keyringKey}: ok — ${verified.subject}`));
|
|
434
437
|
return {
|
|
435
438
|
status: "ok",
|
|
436
439
|
message: verified.subject
|
|
437
440
|
};
|
|
438
441
|
}
|
|
439
|
-
print(style.fail(`${
|
|
442
|
+
print(style.fail(`${keyringKey}: rejected — ${verified.message}`));
|
|
440
443
|
if (module.AUTH_HINT) print(style.hint(` hint: ${module.AUTH_HINT}`));
|
|
441
444
|
return {
|
|
442
445
|
status: "fail",
|
|
@@ -444,7 +447,7 @@ async function runAuthCheck(input) {
|
|
|
444
447
|
};
|
|
445
448
|
} catch (err) {
|
|
446
449
|
const msg = err instanceof Error ? err.message : String(err);
|
|
447
|
-
print(style.fail(`${
|
|
450
|
+
print(style.fail(`${keyringKey}: cannot verify — ${msg}`));
|
|
448
451
|
return {
|
|
449
452
|
status: "fail",
|
|
450
453
|
message: msg
|
|
@@ -5192,6 +5195,15 @@ const resolveSyncToken = createFeatureResolver({
|
|
|
5192
5195
|
keyringKey: "github.sync"
|
|
5193
5196
|
});
|
|
5194
5197
|
const { version: CLI_VERSION } = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
|
|
5198
|
+
/**
|
|
5199
|
+
* Resolves the active org in priority order:
|
|
5200
|
+
* 1. `--org` CLI flag
|
|
5201
|
+
* 2. `HOLOCRON_ORG` env var
|
|
5202
|
+
* 3. `org` from `holocron.config.ts`
|
|
5203
|
+
*/
|
|
5204
|
+
function resolveOrg(argv, config) {
|
|
5205
|
+
return argv.org ?? process.env["HOLOCRON_ORG"] ?? config.org;
|
|
5206
|
+
}
|
|
5195
5207
|
/** Parses --token values and returns the context spread, or null on parse error (exits with code 1). */
|
|
5196
5208
|
function tokenContext(rawTokens) {
|
|
5197
5209
|
if (!rawTokens?.length) return {};
|
|
@@ -5220,6 +5232,9 @@ try {
|
|
|
5220
5232
|
type: "string",
|
|
5221
5233
|
array: true,
|
|
5222
5234
|
describe: "Vendor token override for plugins. Bare form: --token <value> (fallback for all plugins, single-plugin commands). Keyed form: --token vendor=value (targets a specific provider; repeat for each). Example: --token github=ghp_xxx --token vercel=v_yyy"
|
|
5235
|
+
}).option("org", {
|
|
5236
|
+
type: "string",
|
|
5237
|
+
describe: "Active org name for namespaced keyring lookup. Overrides HOLOCRON_ORG env var and the `org` field in holocron.config.ts. Example: --org theholocron"
|
|
5223
5238
|
}).option("cwd", {
|
|
5224
5239
|
type: "string",
|
|
5225
5240
|
default: process.cwd(),
|
|
@@ -5256,13 +5271,15 @@ try {
|
|
|
5256
5271
|
}), async (argv) => {
|
|
5257
5272
|
const tokens = tokenContext(argv.token);
|
|
5258
5273
|
if (!tokens) return;
|
|
5274
|
+
const loaded = await loadConfig(argv.cwd);
|
|
5259
5275
|
if ((await runDoctor({
|
|
5260
|
-
loaded
|
|
5276
|
+
loaded,
|
|
5261
5277
|
context: {
|
|
5262
5278
|
repoRoot: argv.cwd,
|
|
5263
5279
|
dryRun: argv.dryRun,
|
|
5264
5280
|
...argv.repo ? { repo: argv.repo } : {},
|
|
5265
|
-
...tokens
|
|
5281
|
+
...tokens,
|
|
5282
|
+
org: resolveOrg(argv, loaded.resolved)
|
|
5266
5283
|
}
|
|
5267
5284
|
})).summary.fail > 0) process.exitCode = 1;
|
|
5268
5285
|
}).command("setup", "Apply infra setup actions across every configured capability", (y) => y.option("repo", {
|
|
@@ -5271,13 +5288,15 @@ try {
|
|
|
5271
5288
|
}), async (argv) => {
|
|
5272
5289
|
const tokens = tokenContext(argv.token);
|
|
5273
5290
|
if (!tokens) return;
|
|
5291
|
+
const loaded = await loadConfig(argv.cwd);
|
|
5274
5292
|
if ((await runSetup({
|
|
5275
|
-
loaded
|
|
5293
|
+
loaded,
|
|
5276
5294
|
context: {
|
|
5277
5295
|
repoRoot: argv.cwd,
|
|
5278
5296
|
dryRun: argv.dryRun,
|
|
5279
5297
|
...argv.repo ? { repo: argv.repo } : {},
|
|
5280
|
-
...tokens
|
|
5298
|
+
...tokens,
|
|
5299
|
+
org: resolveOrg(argv, loaded.resolved)
|
|
5281
5300
|
}
|
|
5282
5301
|
})).summary.fail > 0) process.exitCode = 1;
|
|
5283
5302
|
}).command("skills", "Manage agent skills from the @theholocron/skills registry", (y) => y.command("install", "Copy skills from @theholocron/skills into .agents/ with agent symlinks", () => {}, async (argv) => {
|
|
@@ -5334,12 +5353,14 @@ try {
|
|
|
5334
5353
|
if (!tokens) return;
|
|
5335
5354
|
const scopeArg = argv.scope;
|
|
5336
5355
|
const scope = parseScope(scopeArg);
|
|
5356
|
+
const loaded = await loadConfig(argv.cwd);
|
|
5337
5357
|
if ((await runSecretSet({
|
|
5338
|
-
loaded
|
|
5358
|
+
loaded,
|
|
5339
5359
|
context: {
|
|
5340
5360
|
repoRoot: argv.cwd,
|
|
5341
5361
|
dryRun: argv.dryRun,
|
|
5342
|
-
...tokens
|
|
5362
|
+
...tokens,
|
|
5363
|
+
org: resolveOrg(argv, loaded.resolved)
|
|
5343
5364
|
},
|
|
5344
5365
|
name: argv.name,
|
|
5345
5366
|
...argv.value ? { value: argv.value } : {},
|
|
@@ -5361,12 +5382,14 @@ try {
|
|
|
5361
5382
|
}), async (argv) => {
|
|
5362
5383
|
const tokens = tokenContext(argv.token);
|
|
5363
5384
|
if (!tokens) return;
|
|
5385
|
+
const loaded = await loadConfig(argv.cwd);
|
|
5364
5386
|
if ((await runSecretsSync({
|
|
5365
|
-
loaded
|
|
5387
|
+
loaded,
|
|
5366
5388
|
context: {
|
|
5367
5389
|
repoRoot: argv.cwd,
|
|
5368
5390
|
dryRun: argv.dryRun,
|
|
5369
|
-
...tokens
|
|
5391
|
+
...tokens,
|
|
5392
|
+
org: resolveOrg(argv, loaded.resolved)
|
|
5370
5393
|
},
|
|
5371
5394
|
environmentId: argv.environmentId,
|
|
5372
5395
|
...argv.projectId ? { projectId: argv.projectId } : {},
|
|
@@ -5387,12 +5410,14 @@ try {
|
|
|
5387
5410
|
}), async (argv) => {
|
|
5388
5411
|
const tokens = tokenContext(argv.token);
|
|
5389
5412
|
if (!tokens) return;
|
|
5413
|
+
const loaded = await loadConfig(argv.cwd);
|
|
5390
5414
|
if ((await runDeploy({
|
|
5391
|
-
loaded
|
|
5415
|
+
loaded,
|
|
5392
5416
|
context: {
|
|
5393
5417
|
repoRoot: argv.cwd,
|
|
5394
5418
|
dryRun: argv.dryRun,
|
|
5395
|
-
...tokens
|
|
5419
|
+
...tokens,
|
|
5420
|
+
org: resolveOrg(argv, loaded.resolved)
|
|
5396
5421
|
},
|
|
5397
5422
|
projectId: argv.projectId,
|
|
5398
5423
|
branch: argv.branch,
|
|
@@ -5432,13 +5457,15 @@ try {
|
|
|
5432
5457
|
}), async (argv) => {
|
|
5433
5458
|
const tokens = tokenContext(argv.token);
|
|
5434
5459
|
if (!tokens) return;
|
|
5460
|
+
const loaded = await loadConfig(argv.cwd);
|
|
5435
5461
|
if ((await runSync({
|
|
5436
|
-
loaded
|
|
5462
|
+
loaded,
|
|
5437
5463
|
context: {
|
|
5438
5464
|
repoRoot: argv.cwd,
|
|
5439
5465
|
dryRun: argv.dryRun,
|
|
5440
5466
|
...argv.repo ? { repo: argv.repo } : {},
|
|
5441
|
-
...tokens
|
|
5467
|
+
...tokens,
|
|
5468
|
+
org: resolveOrg(argv, loaded.resolved)
|
|
5442
5469
|
},
|
|
5443
5470
|
...argv.steps && argv.steps.length > 0 ? { steps: argv.steps } : {}
|
|
5444
5471
|
})).summary.fail > 0) process.exitCode = 1;
|
|
@@ -5853,7 +5880,8 @@ try {
|
|
|
5853
5880
|
}).positional("value", { type: "string" }), async (argv) => {
|
|
5854
5881
|
if ((await runAuthSet({
|
|
5855
5882
|
provider: argv.provider,
|
|
5856
|
-
...argv.value ? { positional: argv.value } : {}
|
|
5883
|
+
...argv.value ? { positional: argv.value } : {},
|
|
5884
|
+
...argv.org ? { org: argv.org } : {}
|
|
5857
5885
|
})).status === "fail") process.exitCode = 1;
|
|
5858
5886
|
}).command("unset <provider>", "Remove a stored bootstrap token", (yy) => yy.positional("provider", {
|
|
5859
5887
|
type: "string",
|
|
@@ -5864,7 +5892,10 @@ try {
|
|
|
5864
5892
|
type: "string",
|
|
5865
5893
|
demandOption: true
|
|
5866
5894
|
}), async (argv) => {
|
|
5867
|
-
if ((await runAuthCheck({
|
|
5895
|
+
if ((await runAuthCheck({
|
|
5896
|
+
provider: argv.provider,
|
|
5897
|
+
...argv.org ? { org: argv.org } : {}
|
|
5898
|
+
})).status === "fail") process.exitCode = 1;
|
|
5868
5899
|
}).command("list", "List every provider with a stored bootstrap token", () => {}, async () => {
|
|
5869
5900
|
await runAuthList();
|
|
5870
5901
|
}).demandCommand(1, "Run `holocron auth --help` to see available auth subcommands."), () => {}).demandCommand(1, "Run `holocron --help` to see available commands.").strict().help().parse();
|