@theholocron/cli 5.0.0-alpha.51 → 5.0.0-alpha.53

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 CHANGED
@@ -532,7 +532,8 @@ var PluginLoader = class {
532
532
  /** Default importer — resolves from cwd first so the global CLI finds project plugins. */
533
533
  const defaultImporter$1 = async (pkg) => {
534
534
  try {
535
- return import(pathToFileURL(createRequire(process.cwd() + "/").resolve(pkg)).href);
535
+ const resolved = createRequire(process.cwd() + "/").resolve(pkg);
536
+ return import(pathToFileURL(resolved).href);
536
537
  } catch {
537
538
  return import(pkg);
538
539
  }
@@ -664,7 +665,8 @@ const style = {
664
665
  */
665
666
  const defaultImporter = async (pkg) => {
666
667
  try {
667
- return await import(pathToFileURL(createRequire(process.cwd() + "/").resolve(pkg)).href);
668
+ const resolved = createRequire(process.cwd() + "/").resolve(pkg);
669
+ return await import(pathToFileURL(resolved).href);
668
670
  } catch {
669
671
  return await import(pkg);
670
672
  }
@@ -1106,8 +1108,10 @@ async function runClone(input) {
1106
1108
  }).status };
1107
1109
  });
1108
1110
  print(style.header(`Holocron clone — org=${input.org} → ${targetDir}${dryRun ? " (dry-run)" : ""}`));
1109
- if (!existsSync(targetDir)) if (dryRun) print(style.dim(` would create ${targetDir}`));
1110
- else mkdirSync(targetDir, { recursive: true });
1111
+ if (!existsSync(targetDir)) {
1112
+ if (dryRun) print(style.dim(` would create ${targetDir}`));
1113
+ else mkdirSync(targetDir, { recursive: true });
1114
+ }
1111
1115
  let repos;
1112
1116
  try {
1113
1117
  repos = await listOrgRepos(input.org, input.token, fetchFn);
@@ -1129,7 +1133,8 @@ async function runClone(input) {
1129
1133
  let skipped = 0;
1130
1134
  let failed = 0;
1131
1135
  for (const repo of repos) {
1132
- const dest = join(targetDir, repo.name.startsWith(".") ? repo.name.slice(1) : repo.name);
1136
+ const dirName = repo.name.startsWith(".") ? repo.name.slice(1) : repo.name;
1137
+ const dest = join(targetDir, dirName);
1133
1138
  if (existsSync(dest)) {
1134
1139
  print(style.dim(` skip ${repo.full_name}`));
1135
1140
  skipped++;
@@ -5413,34 +5418,36 @@ async function runSetup(input) {
5413
5418
  print(formatStep(steps[steps.length - 1]));
5414
5419
  }
5415
5420
  const teams = repo?.teams ?? [];
5416
- if (teams.length > 0) if (source.syncTeams) {
5417
- steps.push(await runStep("source", "sync teams", dryRun, () => source.syncTeams(teams), { skipCodes: [422] }));
5418
- print(formatStep(steps[steps.length - 1]));
5419
- const repoCoord = input.context.repo ?? repo?.name ?? "";
5420
- const org = repoCoord.includes("/") ? repoCoord.split("/")[0] : "";
5421
- const writeableTeams = teams.map((t) => typeof t === "string" ? {
5422
- slug: t,
5423
- permission: "push"
5424
- } : t).filter((t) => [
5425
- "push",
5426
- "maintain",
5427
- "admin"
5428
- ].includes(t.permission));
5429
- if (org && writeableTeams.length > 0) {
5430
- steps.push(await runStep("source", "write .github/CODEOWNERS", dryRun, async () => {
5431
- const content = writeableTeams.map((t) => `* @${org}/${t.slug}`).join("\n") + "\n";
5432
- await source.writeRepoFile(".github/CODEOWNERS", content);
5433
- }));
5421
+ if (teams.length > 0) {
5422
+ if (source.syncTeams) {
5423
+ steps.push(await runStep("source", "sync teams", dryRun, () => source.syncTeams(teams), { skipCodes: [422] }));
5424
+ print(formatStep(steps[steps.length - 1]));
5425
+ const repoCoord = input.context.repo ?? repo?.name ?? "";
5426
+ const org = repoCoord.includes("/") ? repoCoord.split("/")[0] : "";
5427
+ const writeableTeams = teams.map((t) => typeof t === "string" ? {
5428
+ slug: t,
5429
+ permission: "push"
5430
+ } : t).filter((t) => [
5431
+ "push",
5432
+ "maintain",
5433
+ "admin"
5434
+ ].includes(t.permission));
5435
+ if (org && writeableTeams.length > 0) {
5436
+ steps.push(await runStep("source", "write .github/CODEOWNERS", dryRun, async () => {
5437
+ const content = writeableTeams.map((t) => `* @${org}/${t.slug}`).join("\n") + "\n";
5438
+ await source.writeRepoFile(".github/CODEOWNERS", content);
5439
+ }));
5440
+ print(formatStep(steps[steps.length - 1]));
5441
+ }
5442
+ } else {
5443
+ steps.push({
5444
+ capability: "source",
5445
+ step: "sync teams",
5446
+ status: "skip",
5447
+ message: "provider does not implement syncTeams"
5448
+ });
5434
5449
  print(formatStep(steps[steps.length - 1]));
5435
5450
  }
5436
- } else {
5437
- steps.push({
5438
- capability: "source",
5439
- step: "sync teams",
5440
- status: "skip",
5441
- message: "provider does not implement syncTeams"
5442
- });
5443
- print(formatStep(steps[steps.length - 1]));
5444
5451
  }
5445
5452
  }
5446
5453
  if (loader.has("environments")) {
@@ -6002,11 +6009,13 @@ async function runSyncReadme(input) {
6002
6009
  }
6003
6010
  const description = loaded.resolved.description ?? "";
6004
6011
  const homepage = loaded.resolved.homepage ?? pkg.homepage ?? "";
6012
+ const scripts = pkg.scripts ?? {};
6013
+ const packages = pkg.name ? REGISTRY_MAP[pkg.name]?.() : void 0;
6005
6014
  const sections = generateReadme({
6006
6015
  description,
6007
6016
  homepage,
6008
- scripts: pkg.scripts ?? {},
6009
- packages: pkg.name ? REGISTRY_MAP[pkg.name]?.() : void 0
6017
+ scripts,
6018
+ packages
6010
6019
  });
6011
6020
  const markerSections = {
6012
6021
  ...sections.packages !== void 0 && { packages: sections.packages },
@@ -6248,7 +6257,7 @@ async function runSyncWiki(input) {
6248
6257
  capability: "local",
6249
6258
  step: "sync wiki",
6250
6259
  status: "fail",
6251
- message: err instanceof Error ? err.message : /* c8 ignore next */ String(err)
6260
+ message: err instanceof Error ? err.message : /* c8 ignore next */ String(err)
6252
6261
  };
6253
6262
  }
6254
6263
  }
@@ -6310,55 +6319,59 @@ async function runSync(input) {
6310
6319
  for (const stepName of SYNC_STEPS) {
6311
6320
  if (requestedSteps !== void 0 && !requestedSteps.includes(stepName)) continue;
6312
6321
  if (LOCAL_STEPS.has(stepName)) continue;
6313
- if (stepName === "labels") if (source.syncLabels) {
6314
- steps.push(await runSyncStep("source", "sync labels", dryRun, () => source.syncLabels(CANONICAL_LABELS, STALE_LABELS)));
6315
- print(formatSyncStep(steps[steps.length - 1]));
6316
- } else {
6317
- steps.push({
6318
- capability: "source",
6319
- step: "sync labels",
6320
- status: "skip",
6321
- message: "provider does not implement syncLabels"
6322
- });
6323
- print(formatSyncStep(steps[steps.length - 1]));
6322
+ if (stepName === "labels") {
6323
+ if (source.syncLabels) {
6324
+ steps.push(await runSyncStep("source", "sync labels", dryRun, () => source.syncLabels(CANONICAL_LABELS, STALE_LABELS)));
6325
+ print(formatSyncStep(steps[steps.length - 1]));
6326
+ } else {
6327
+ steps.push({
6328
+ capability: "source",
6329
+ step: "sync labels",
6330
+ status: "skip",
6331
+ message: "provider does not implement syncLabels"
6332
+ });
6333
+ print(formatSyncStep(steps[steps.length - 1]));
6334
+ }
6324
6335
  }
6325
- if (stepName === "properties") if (source.syncProperties) {
6326
- const repo = config.repo;
6327
- const properties = {};
6328
- const effectivePreset = repo?.protection;
6329
- if (effectivePreset && effectivePreset !== "none") properties["holocron_branch_protection_level"] = effectivePreset;
6330
- const isMonorepo = await access(join(input.context.repoRoot, "pnpm-workspace.yaml")).then(() => true).catch(() => false);
6331
- properties["monorepo"] = String(isMonorepo);
6332
- const manual = repo?.properties ?? {};
6333
- if (manual.lifecycle) properties["lifecycle"] = manual.lifecycle;
6334
- if (manual.open_source !== void 0) properties["open_source"] = String(manual.open_source);
6335
- if (manual.runtime_environment) properties["runtime_environment"] = manual.runtime_environment;
6336
- if (manual.uses_external_packages !== void 0) properties["uses_external_packages"] = String(manual.uses_external_packages);
6337
- {
6338
- const rootPackageJson = await readFile(join(input.context.repoRoot, "package.json"), "utf8").then((raw) => JSON.parse(raw)).catch(() => null);
6339
- const workspacePackages = readWorkspacePackages(input.context.repoRoot);
6340
- const workspacePackageJsons = await readWorkspacePackageJsons(input.context.repoRoot, workspacePackages);
6341
- properties["holocron_profile"] = deriveProfile({
6342
- rootPackageJson,
6343
- repoName: basename(input.context.repoRoot),
6344
- isMonorepo,
6345
- workspacePackageJsons
6336
+ if (stepName === "properties") {
6337
+ if (source.syncProperties) {
6338
+ const repo = config.repo;
6339
+ const properties = {};
6340
+ const effectivePreset = repo?.protection;
6341
+ if (effectivePreset && effectivePreset !== "none") properties["holocron_branch_protection_level"] = effectivePreset;
6342
+ const isMonorepo = await access(join(input.context.repoRoot, "pnpm-workspace.yaml")).then(() => true).catch(() => false);
6343
+ properties["monorepo"] = String(isMonorepo);
6344
+ const manual = repo?.properties ?? {};
6345
+ if (manual.lifecycle) properties["lifecycle"] = manual.lifecycle;
6346
+ if (manual.open_source !== void 0) properties["open_source"] = String(manual.open_source);
6347
+ if (manual.runtime_environment) properties["runtime_environment"] = manual.runtime_environment;
6348
+ if (manual.uses_external_packages !== void 0) properties["uses_external_packages"] = String(manual.uses_external_packages);
6349
+ {
6350
+ const rootPackageJson = await readFile(join(input.context.repoRoot, "package.json"), "utf8").then((raw) => JSON.parse(raw)).catch(() => null);
6351
+ const workspacePackages = readWorkspacePackages(input.context.repoRoot);
6352
+ const workspacePackageJsons = await readWorkspacePackageJsons(input.context.repoRoot, workspacePackages);
6353
+ properties["holocron_profile"] = deriveProfile({
6354
+ rootPackageJson,
6355
+ repoName: basename(input.context.repoRoot),
6356
+ isMonorepo,
6357
+ workspacePackageJsons
6358
+ });
6359
+ properties["holocron_stack"] = deriveStack(rootPackageJson);
6360
+ const capabilities = deriveCapabilities(config.providers);
6361
+ properties["holocron_capabilities"] = capabilities;
6362
+ properties["holocron_compliance"] = deriveCompliance(capabilities);
6363
+ }
6364
+ steps.push(await runSyncStep("source", "sync properties", dryRun, () => source.syncProperties(properties)));
6365
+ print(formatSyncStep(steps[steps.length - 1]));
6366
+ } else {
6367
+ steps.push({
6368
+ capability: "source",
6369
+ step: "sync properties",
6370
+ status: "skip",
6371
+ message: "provider does not implement syncProperties"
6346
6372
  });
6347
- properties["holocron_stack"] = deriveStack(rootPackageJson);
6348
- const capabilities = deriveCapabilities(config.providers);
6349
- properties["holocron_capabilities"] = capabilities;
6350
- properties["holocron_compliance"] = deriveCompliance(capabilities);
6373
+ print(formatSyncStep(steps[steps.length - 1]));
6351
6374
  }
6352
- steps.push(await runSyncStep("source", "sync properties", dryRun, () => source.syncProperties(properties)));
6353
- print(formatSyncStep(steps[steps.length - 1]));
6354
- } else {
6355
- steps.push({
6356
- capability: "source",
6357
- step: "sync properties",
6358
- status: "skip",
6359
- message: "provider does not implement syncProperties"
6360
- });
6361
- print(formatSyncStep(steps[steps.length - 1]));
6362
6375
  }
6363
6376
  if (stepName === "teams") {
6364
6377
  const teams = config.repo?.teams ?? [];
@@ -6570,32 +6583,34 @@ async function runSync(input) {
6570
6583
  }
6571
6584
  }
6572
6585
  }
6573
- if (stepName === "scripts") if (config.syncScripts === false) {
6574
- steps.push({
6575
- capability: "local",
6576
- step: "sync scripts",
6577
- status: "skip",
6578
- message: "syncScripts: false"
6579
- });
6580
- print(formatSyncStep(steps[steps.length - 1]));
6581
- } else {
6582
- const tasksConfig = { tasks: config.tasks };
6583
- if (config.holocronScript !== void 0) tasksConfig.holocronScript = config.holocronScript;
6584
- const astromechScripts = createAstromech({
6585
- cwd: input.context.repoRoot,
6586
- config: tasksConfig,
6587
- logger
6588
- });
6589
- const desired = astromechScripts.packageScripts();
6590
- const turboContent = astromechScripts.turboConfig();
6591
- const turboEligible = new Set(turboContent ? Object.keys(JSON.parse(turboContent).tasks) : []);
6592
- steps.push(await runSyncStep("local", "sync scripts", dryRun, async () => {
6593
- const changed = await mergePackageJsonScripts(input.context.repoRoot, desired, turboEligible);
6594
- if (changed === null) return "no package.json";
6595
- if (changed.length === 0) return `${Object.keys(desired).length} scripts already current`;
6596
- return `${changed.join(", ")} set`;
6597
- }));
6598
- print(formatSyncStep(steps[steps.length - 1]));
6586
+ if (stepName === "scripts") {
6587
+ if (config.syncScripts === false) {
6588
+ steps.push({
6589
+ capability: "local",
6590
+ step: "sync scripts",
6591
+ status: "skip",
6592
+ message: "syncScripts: false"
6593
+ });
6594
+ print(formatSyncStep(steps[steps.length - 1]));
6595
+ } else {
6596
+ const tasksConfig = { tasks: config.tasks };
6597
+ if (config.holocronScript !== void 0) tasksConfig.holocronScript = config.holocronScript;
6598
+ const astromechScripts = createAstromech({
6599
+ cwd: input.context.repoRoot,
6600
+ config: tasksConfig,
6601
+ logger
6602
+ });
6603
+ const desired = astromechScripts.packageScripts();
6604
+ const turboContent = astromechScripts.turboConfig();
6605
+ const turboEligible = new Set(turboContent ? Object.keys(JSON.parse(turboContent).tasks) : []);
6606
+ steps.push(await runSyncStep("local", "sync scripts", dryRun, async () => {
6607
+ const changed = await mergePackageJsonScripts(input.context.repoRoot, desired, turboEligible);
6608
+ if (changed === null) return "no package.json";
6609
+ if (changed.length === 0) return `${Object.keys(desired).length} scripts already current`;
6610
+ return `${changed.join(", ")} set`;
6611
+ }));
6612
+ print(formatSyncStep(steps[steps.length - 1]));
6613
+ }
6599
6614
  }
6600
6615
  if (stepName === "turbo") {
6601
6616
  const astromechTurbo = createAstromech({
@@ -8057,7 +8072,7 @@ async function launchMenu(entries, parentArgv, pickMessage, nonInteractiveMessag
8057
8072
  //#endregion
8058
8073
  //#region src/update-notifier.ts
8059
8074
  const PACKAGE_NAME = "@theholocron/cli";
8060
- const CACHE_TTL_MS = 1440 * 60 * 1e3;
8075
+ const CACHE_TTL_MS = 864e5;
8061
8076
  const FETCH_TIMEOUT_MS = 3e3;
8062
8077
  function getCacheDir() {
8063
8078
  return env.get("HOLOCRON_CACHE_DIR") ?? join(homedir(), ".cache", "holocron");