@theholocron/cli 2.0.0-alpha.63 → 2.0.0-alpha.64
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 +89 -13
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -3,11 +3,13 @@ import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSy
|
|
|
3
3
|
import path, { basename, dirname, join } from "node:path";
|
|
4
4
|
import yargs from "yargs";
|
|
5
5
|
import { hideBin } from "yargs/helpers";
|
|
6
|
+
import { createInterface } from "node:readline";
|
|
7
|
+
import { stdin, stdout } from "node:process";
|
|
6
8
|
import { ProviderApiError, ProviderApiError as ProviderApiError$1 } from "@theholocron/http-client";
|
|
7
9
|
import { Entry, findCredentials } from "@napi-rs/keyring";
|
|
8
10
|
import { createHash } from "node:crypto";
|
|
9
11
|
import { createGitHubClient } from "@theholocron/github-client";
|
|
10
|
-
import { execFile, spawnSync } from "node:child_process";
|
|
12
|
+
import { execFile, execFileSync, spawnSync } from "node:child_process";
|
|
11
13
|
import { access, readFile, readdir, stat, writeFile } from "node:fs/promises";
|
|
12
14
|
import { pathToFileURL } from "node:url";
|
|
13
15
|
import { promisify } from "node:util";
|
|
@@ -2365,7 +2367,7 @@ async function runNpmPublishInitial(input = {}) {
|
|
|
2365
2367
|
const dryRun = input.dryRun ?? false;
|
|
2366
2368
|
const otp = input.otp;
|
|
2367
2369
|
const env = input.env ?? process.env;
|
|
2368
|
-
const exec = input.exec ?? defaultExec;
|
|
2370
|
+
const exec = input.exec ?? defaultExec$1;
|
|
2369
2371
|
const publishArgs = [
|
|
2370
2372
|
"-r",
|
|
2371
2373
|
"--filter=./packages/*",
|
|
@@ -2441,7 +2443,7 @@ function printNextSteps$1(print, env) {
|
|
|
2441
2443
|
print(" https://www.npmjs.com/settings/~/tokens");
|
|
2442
2444
|
}
|
|
2443
2445
|
}
|
|
2444
|
-
const defaultExec = async (cmd, args, opts) => {
|
|
2446
|
+
const defaultExec$1 = async (cmd, args, opts) => {
|
|
2445
2447
|
const result = spawnSync(cmd, args, {
|
|
2446
2448
|
cwd: opts.cwd,
|
|
2447
2449
|
encoding: "utf8",
|
|
@@ -3292,13 +3294,11 @@ export default defineConfig({
|
|
|
3292
3294
|
* 2. Slug collision — packages/holocron-plugin-<slug>/ must not exist.
|
|
3293
3295
|
* 3. Capability sanity — must be one of the 14 known keys; warn for
|
|
3294
3296
|
* many-cardinality caps.
|
|
3295
|
-
* 4.
|
|
3296
|
-
* (Phase B; Phase A takes fully-populated input).
|
|
3297
|
-
* 5. Generate — for each template, write to
|
|
3297
|
+
* 4. Generate — for each template, write to
|
|
3298
3298
|
* packages/holocron-plugin-<slug>/<path>.
|
|
3299
|
-
*
|
|
3299
|
+
* 5. Verify (unless --no-verify) — runs pnpm install +
|
|
3300
3300
|
* pnpm --filter <pkg> typecheck lint test.
|
|
3301
|
-
*
|
|
3301
|
+
* 6. Print next steps.
|
|
3302
3302
|
*/
|
|
3303
3303
|
var PluginCreateError = class extends Error {
|
|
3304
3304
|
name = "PluginCreateError";
|
|
@@ -3421,6 +3421,51 @@ function runPluginCreate(input) {
|
|
|
3421
3421
|
}
|
|
3422
3422
|
filesWritten.push(resolvedPath);
|
|
3423
3423
|
}
|
|
3424
|
+
if (!input.dryRun && !input.noVerify) {
|
|
3425
|
+
const execFn = input.exec ?? defaultExec;
|
|
3426
|
+
const pkg = `@theholocron/holocron-plugin-${inputs.slug}`;
|
|
3427
|
+
print("");
|
|
3428
|
+
print(" Verifying scaffold…");
|
|
3429
|
+
try {
|
|
3430
|
+
execFn("pnpm", ["install", "--frozen-lockfile=false"], {
|
|
3431
|
+
cwd,
|
|
3432
|
+
stdio: "inherit"
|
|
3433
|
+
});
|
|
3434
|
+
execFn("pnpm", [
|
|
3435
|
+
"--filter",
|
|
3436
|
+
pkg,
|
|
3437
|
+
"typecheck"
|
|
3438
|
+
], {
|
|
3439
|
+
cwd,
|
|
3440
|
+
stdio: "inherit"
|
|
3441
|
+
});
|
|
3442
|
+
execFn("pnpm", [
|
|
3443
|
+
"--filter",
|
|
3444
|
+
pkg,
|
|
3445
|
+
"lint"
|
|
3446
|
+
], {
|
|
3447
|
+
cwd,
|
|
3448
|
+
stdio: "inherit"
|
|
3449
|
+
});
|
|
3450
|
+
execFn("pnpm", [
|
|
3451
|
+
"--filter",
|
|
3452
|
+
pkg,
|
|
3453
|
+
"test"
|
|
3454
|
+
], {
|
|
3455
|
+
cwd,
|
|
3456
|
+
stdio: "inherit"
|
|
3457
|
+
});
|
|
3458
|
+
print(" ✓ scaffold verified");
|
|
3459
|
+
} catch (err) {
|
|
3460
|
+
print(` ✗ verify failed — ${err instanceof Error ? err.message : String(err)}`);
|
|
3461
|
+
return {
|
|
3462
|
+
status: "fail",
|
|
3463
|
+
packagePath: packageDir,
|
|
3464
|
+
filesWritten,
|
|
3465
|
+
message: "post-scaffold verify failed; inspect output above"
|
|
3466
|
+
};
|
|
3467
|
+
}
|
|
3468
|
+
}
|
|
3424
3469
|
if (!input.dryRun) printNextSteps(print, inputs);
|
|
3425
3470
|
return {
|
|
3426
3471
|
status: "ok",
|
|
@@ -3464,6 +3509,12 @@ function defaultWrite(filepath, content) {
|
|
|
3464
3509
|
mkdirSync(path.dirname(filepath), { recursive: true });
|
|
3465
3510
|
writeFileSync(filepath, content, "utf8");
|
|
3466
3511
|
}
|
|
3512
|
+
function defaultExec(cmd, args, opts) {
|
|
3513
|
+
execFileSync(cmd, args, {
|
|
3514
|
+
cwd: opts.cwd,
|
|
3515
|
+
stdio: opts.stdio
|
|
3516
|
+
});
|
|
3517
|
+
}
|
|
3467
3518
|
function printNextSteps(print, inputs) {
|
|
3468
3519
|
print("");
|
|
3469
3520
|
print(` Scaffolded @theholocron/holocron-plugin-${inputs.slug} (18 files).`);
|
|
@@ -4943,15 +4994,40 @@ await yargs(hideBin(process.argv)).scriptName("holocron").usage("$0 <command> [o
|
|
|
4943
4994
|
type: "boolean",
|
|
4944
4995
|
default: true,
|
|
4945
4996
|
describe: "Run post-scaffold pnpm install + typecheck + lint + test (default true; --no-verify skips)"
|
|
4946
|
-
}), (argv) => {
|
|
4997
|
+
}), async (argv) => {
|
|
4947
4998
|
try {
|
|
4948
|
-
|
|
4999
|
+
const capabilityKeys = Object.keys(CARDINALITY).join(", ");
|
|
5000
|
+
const needsPrompt = !argv.capability || !argv.vendorEnv || !argv.baseUrl;
|
|
5001
|
+
let capability;
|
|
5002
|
+
let vendorEnv;
|
|
5003
|
+
let baseUrl;
|
|
5004
|
+
if (needsPrompt) {
|
|
5005
|
+
const rl = createInterface({
|
|
5006
|
+
input: stdin,
|
|
5007
|
+
output: stdout
|
|
5008
|
+
});
|
|
5009
|
+
const ask = (question) => new Promise((resolve) => rl.question(` ${question} `, (answer) => resolve(answer.trim())));
|
|
5010
|
+
try {
|
|
5011
|
+
if (!argv.capability) {
|
|
5012
|
+
console.log(` Available capabilities: ${capabilityKeys}`);
|
|
5013
|
+
capability = await ask("Capability:");
|
|
5014
|
+
} else capability = argv.capability;
|
|
5015
|
+
vendorEnv = argv.vendorEnv ? argv.vendorEnv : await ask(`Vendor-native env var for the ${argv.vendor} token (e.g. MYVENDOR_API_KEY):`);
|
|
5016
|
+
baseUrl = argv.baseUrl ? argv.baseUrl : await ask(`REST base URL for the ${argv.vendor} API (e.g. https://api.myvendor.com):`);
|
|
5017
|
+
} finally {
|
|
5018
|
+
rl.close();
|
|
5019
|
+
}
|
|
5020
|
+
} else {
|
|
5021
|
+
capability = argv.capability;
|
|
5022
|
+
vendorEnv = argv.vendorEnv;
|
|
5023
|
+
baseUrl = argv.baseUrl;
|
|
5024
|
+
}
|
|
4949
5025
|
if (runPluginCreate({
|
|
4950
5026
|
slug: argv.slug,
|
|
4951
5027
|
vendorName: argv.vendor,
|
|
4952
|
-
capability
|
|
4953
|
-
vendorEnv
|
|
4954
|
-
baseUrl
|
|
5028
|
+
capability,
|
|
5029
|
+
vendorEnv,
|
|
5030
|
+
baseUrl,
|
|
4955
5031
|
...argv.tokenEnv ? { tokenEnv: argv.tokenEnv } : {},
|
|
4956
5032
|
dryRun: argv.dryRun,
|
|
4957
5033
|
noVerify: !argv.verify,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/cli",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.64",
|
|
4
4
|
"description": "The Holocron CLI — a pluggable, capability-based orchestrator for spinning up and operating software projects.",
|
|
5
5
|
"homepage": "https://github.com/theholocron/holocron/tree/main/packages/cli#readme",
|
|
6
6
|
"bugs": "https://github.com/theholocron/holocron/issues",
|