@jakkrichm/create-nexus-devflow 2.9.0 → 2.9.4

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.
Files changed (62) hide show
  1. package/dist/bin/create-nexus-devflow.d.ts +7 -2
  2. package/dist/bin/create-nexus-devflow.js +231 -23
  3. package/dist/bin/create-nexus-devflow.js.map +1 -1
  4. package/dist/lib/dashboard-page.d.ts +1 -1
  5. package/dist/lib/dashboard-page.js +76 -0
  6. package/dist/lib/dashboard-page.js.map +1 -1
  7. package/dist/lib/project-config.d.ts +1 -1
  8. package/dist/lib/project-config.js +4 -1
  9. package/dist/lib/project-config.js.map +1 -1
  10. package/dist/lib/run-state.d.ts +39 -0
  11. package/dist/lib/run-state.js +203 -0
  12. package/dist/lib/run-state.js.map +1 -0
  13. package/dist/lib/skill-manager.d.ts +40 -1
  14. package/dist/lib/skill-manager.js +270 -68
  15. package/dist/lib/skill-manager.js.map +1 -1
  16. package/dist/lib/status.d.ts +4 -1
  17. package/dist/lib/status.js +49 -3
  18. package/dist/lib/status.js.map +1 -1
  19. package/dist/lib/webview-studio.js +169 -47
  20. package/dist/lib/webview-studio.js.map +1 -1
  21. package/package.json +1 -1
  22. package/template/.agents/skills/adopt/SKILL.md +4 -0
  23. package/template/.agents/skills/audit/SKILL.md +4 -0
  24. package/template/.agents/skills/autopilot/SKILL.md +4 -0
  25. package/template/.agents/skills/check/SKILL.md +4 -0
  26. package/template/.agents/skills/ci/SKILL.md +4 -0
  27. package/template/.agents/skills/complete/SKILL.md +7 -1
  28. package/template/.agents/skills/continuous/SKILL.md +4 -0
  29. package/template/.agents/skills/debug/SKILL.md +4 -0
  30. package/template/.agents/skills/discovery/SKILL.md +8 -4
  31. package/template/.agents/skills/feature/SKILL.md +4 -0
  32. package/template/.agents/skills/fix/SKILL.md +4 -0
  33. package/template/.agents/skills/implement/SKILL.md +4 -0
  34. package/template/.agents/skills/onboard/SKILL.md +4 -0
  35. package/template/.agents/skills/overview/SKILL.md +4 -0
  36. package/template/.agents/skills/prototype/SKILL.md +4 -0
  37. package/template/.agents/skills/release/SKILL.md +4 -0
  38. package/template/.agents/skills/rollback/SKILL.md +18 -5
  39. package/template/.agents/skills/status/SKILL.md +7 -0
  40. package/template/.agents/skills/tests/SKILL.md +4 -0
  41. package/template/.claude/skills/adopt/SKILL.md +4 -0
  42. package/template/.claude/skills/audit/SKILL.md +4 -0
  43. package/template/.claude/skills/autopilot/SKILL.md +4 -0
  44. package/template/.claude/skills/check/SKILL.md +4 -0
  45. package/template/.claude/skills/ci/SKILL.md +4 -0
  46. package/template/.claude/skills/complete/SKILL.md +7 -1
  47. package/template/.claude/skills/continuous/SKILL.md +4 -0
  48. package/template/.claude/skills/debug/SKILL.md +4 -0
  49. package/template/.claude/skills/discovery/SKILL.md +8 -4
  50. package/template/.claude/skills/feature/SKILL.md +4 -0
  51. package/template/.claude/skills/fix/SKILL.md +4 -0
  52. package/template/.claude/skills/implement/SKILL.md +4 -0
  53. package/template/.claude/skills/onboard/SKILL.md +4 -0
  54. package/template/.claude/skills/overview/SKILL.md +4 -0
  55. package/template/.claude/skills/prototype/SKILL.md +4 -0
  56. package/template/.claude/skills/release/SKILL.md +4 -0
  57. package/template/.claude/skills/rollback/SKILL.md +18 -5
  58. package/template/.claude/skills/status/SKILL.md +7 -0
  59. package/template/.claude/skills/tests/SKILL.md +4 -0
  60. package/template/AGENTS.md +24 -5
  61. package/template/devflow/build-plan.md +24 -0
  62. package/template/devflow/context/ai-interaction.md +4 -4
@@ -4,7 +4,7 @@ import { type SliceStage } from "../lib/context-slicer.js";
4
4
  import { type GitHookType } from "../lib/git-hooks.js";
5
5
  interface CliOptions {
6
6
  command: "dashboard" | "install" | "status" | "ui" | "update" | "uninstall" | "eject" | "idea" | "ideas" | "findings" | "doctor" | "archive" | "check-gate" | "hook" | "mcp" | "slice" | "drift" | "reconcile" | "studio" | "swarm" | "graph" | "skill" | "skills";
7
- subcommandAction?: "add" | "list" | "resolve" | "stats" | "install" | "uninstall" | "remove" | "sync";
7
+ subcommandAction?: "add" | "list" | "resolve" | "stats" | "install" | "uninstall" | "remove" | "sync" | "update" | "upgrade";
8
8
  subcommandArg?: string;
9
9
  graphFile?: string;
10
10
  sliceStage?: SliceStage;
@@ -17,6 +17,9 @@ interface CliOptions {
17
17
  findingLocation?: string;
18
18
  findingImpact?: string;
19
19
  findingRemediation?: string;
20
+ skillName?: string;
21
+ installAllSkills: boolean;
22
+ recommended: boolean;
20
23
  blockersOnly: boolean;
21
24
  fix: boolean;
22
25
  statsOnly: boolean;
@@ -35,4 +38,6 @@ interface CliOptions {
35
38
  }
36
39
  declare function main(args?: readonly string[]): Promise<void>;
37
40
  declare function parseArgs(args: readonly string[]): CliOptions;
38
- export { main, parseArgs };
41
+ declare function findPackageRoot(startDir: string): string;
42
+ declare function formatMissingTemplateMessage(templateRoot: string): string;
43
+ export { findPackageRoot, formatMissingTemplateMessage, main, parseArgs };
@@ -20,11 +20,9 @@ import { installGitHook, uninstallGitHooks } from "../lib/git-hooks.js";
20
20
  import { createSpinner, createStyle } from "../lib/ui.js";
21
21
  import { applyPreparedUpdate, prepareUpdate } from "../lib/update.js";
22
22
  import { applyUninstall, prepareUninstall } from "../lib/uninstall.js";
23
- import { installThirdPartySkill, listInstalledSkills, removeThirdPartySkill, syncSkills } from "../lib/skill-manager.js";
23
+ import { installRecommendedSkills, installThirdPartySkill, listInstalledSkills, removeThirdPartySkill, syncSkills, updateRecommendedSkills, updateThirdPartySkills } from "../lib/skill-manager.js";
24
24
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
25
- const packageRoot = fsSync.existsSync(path.join(__dirname, "..", "package.json"))
26
- ? path.resolve(__dirname, "..")
27
- : path.resolve(__dirname, "..", "..");
25
+ const packageRoot = findPackageRoot(__dirname);
28
26
  const templateRoot = path.join(packageRoot, "template");
29
27
  const adapterChoices = new Set(["codex", "antigravity", "claude", "copilot", "opencode", "both", "all"]);
30
28
  async function main(args = process.argv.slice(2)) {
@@ -235,28 +233,75 @@ async function main(args = process.argv.slice(2)) {
235
233
  if (options.command === "skill" || options.command === "skills") {
236
234
  const style = createStyle(shouldUseColor());
237
235
  if (options.subcommandAction === "add" || options.subcommandAction === "install") {
236
+ if (options.recommended || options.subcommandArg === "recommended" || options.subcommandArg === "--recommended") {
237
+ const spinner = createSpinner("Installing recommended third-party skills (8 skills from 3 repositories)...").start();
238
+ try {
239
+ const detail = await installRecommendedSkills(targetDir, { force: options.force });
240
+ spinner.succeed(`Successfully installed ${detail.length} recommended third-party skill(s): ${detail.map((d) => style.bold(style.cyan(d.name))).join(", ")}`);
241
+ if (options.json) {
242
+ console.log(JSON.stringify(detail, null, 2));
243
+ }
244
+ else {
245
+ for (const d of detail) {
246
+ console.log(`\n ${style.dim("Name :")} ${style.bold(d.name)}`);
247
+ if (d.version)
248
+ console.log(` ${style.dim("Version :")} ${d.version}`);
249
+ if (d.description)
250
+ console.log(` ${style.dim("Desc :")} ${d.description}`);
251
+ console.log(` ${style.dim("Adapters:")} ${d.adapters.join(", ")}`);
252
+ }
253
+ console.log(`\n${style.green("✔")} All ${detail.length} recommended skills ready to use! Invocable as /<skill-name> in workflows.`);
254
+ }
255
+ }
256
+ catch (err) {
257
+ spinner.fail(`Failed to install recommended skills: ${err instanceof Error ? err.message : String(err)}`);
258
+ process.exitCode = 1;
259
+ }
260
+ return;
261
+ }
238
262
  const source = options.subcommandArg || "";
239
263
  if (!source.trim()) {
240
- throw new Error("Skill source (Git URL or local directory) is required. Example: nexus-devflow skill add https://github.com/cathrynlavery/diagram-design");
264
+ throw new Error("Skill source (Git URL or local directory) is required. Example: nexus-devflow skill add https://github.com/cathrynlavery/diagram-design or nexus-devflow skill add --recommended");
241
265
  }
242
266
  const spinner = createSpinner(`Installing skill from ${source}...`).start();
243
267
  try {
244
268
  const detail = await installThirdPartySkill(targetDir, source, {
269
+ name: options.skillName,
270
+ all: options.installAllSkills,
245
271
  force: options.force
246
272
  });
247
- spinner.succeed(`Successfully installed third-party skill: ${style.bold(style.cyan(detail.name))}`);
248
- if (options.json) {
249
- console.log(JSON.stringify(detail, null, 2));
273
+ if (Array.isArray(detail)) {
274
+ spinner.succeed(`Successfully installed ${detail.length} third-party skill(s): ${detail.map((d) => style.bold(style.cyan(d.name))).join(", ")}`);
275
+ if (options.json) {
276
+ console.log(JSON.stringify(detail, null, 2));
277
+ }
278
+ else {
279
+ for (const d of detail) {
280
+ console.log(`\n ${style.dim("Name :")} ${style.bold(d.name)}`);
281
+ if (d.version)
282
+ console.log(` ${style.dim("Version :")} ${d.version}`);
283
+ if (d.description)
284
+ console.log(` ${style.dim("Desc :")} ${d.description}`);
285
+ console.log(` ${style.dim("Adapters:")} ${d.adapters.join(", ")}`);
286
+ }
287
+ console.log(`\n${style.green("✔")} All ${detail.length} skills ready to use! Invocable as /<skill-name> in workflows.`);
288
+ }
250
289
  }
251
290
  else {
252
- console.log(`\n ${style.dim("Name :")} ${style.bold(detail.name)}`);
253
- if (detail.version)
254
- console.log(` ${style.dim("Version :")} ${detail.version}`);
255
- if (detail.description)
256
- console.log(` ${style.dim("Desc :")} ${detail.description}`);
257
- console.log(` ${style.dim("Source :")} ${detail.source}`);
258
- console.log(` ${style.dim("Adapters:")} ${detail.adapters.join(", ")}`);
259
- console.log(`\n${style.green("")} Skill ready to use! Invocable as ${style.cyan(`/${detail.name}`)} or inside /discovery, /feature, /brainstorm.`);
291
+ spinner.succeed(`Successfully installed third-party skill: ${style.bold(style.cyan(detail.name))}`);
292
+ if (options.json) {
293
+ console.log(JSON.stringify(detail, null, 2));
294
+ }
295
+ else {
296
+ console.log(`\n ${style.dim("Name :")} ${style.bold(detail.name)}`);
297
+ if (detail.version)
298
+ console.log(` ${style.dim("Version :")} ${detail.version}`);
299
+ if (detail.description)
300
+ console.log(` ${style.dim("Desc :")} ${detail.description}`);
301
+ console.log(` ${style.dim("Source :")} ${detail.source}`);
302
+ console.log(` ${style.dim("Adapters:")} ${detail.adapters.join(", ")}`);
303
+ console.log(`\n${style.green("✔")} Skill ready to use! Invocable as ${style.cyan(`/${detail.name}`)} or inside /discovery, /feature, /brainstorm.`);
304
+ }
260
305
  }
261
306
  }
262
307
  catch (err) {
@@ -298,6 +343,77 @@ async function main(args = process.argv.slice(2)) {
298
343
  }
299
344
  return;
300
345
  }
346
+ if (options.subcommandAction === "update" || options.subcommandAction === "upgrade") {
347
+ if (options.recommended || options.subcommandArg === "recommended" || options.subcommandArg === "--recommended") {
348
+ const spinner = createSpinner("Updating recommended third-party skills from latest upstream repositories...").start();
349
+ try {
350
+ const result = await updateRecommendedSkills(targetDir);
351
+ if (result.totalUpdated === 0 && result.failedSkills.length === 0) {
352
+ spinner.succeed("No recommended third-party skills installed to update.");
353
+ }
354
+ else if (result.failedSkills.length > 0 && result.totalUpdated === 0) {
355
+ spinner.fail(`Failed to update recommended skills: ${result.failedSkills.map((f) => `${f.name} (${f.reason})`).join(", ")}`);
356
+ process.exitCode = 1;
357
+ }
358
+ else {
359
+ spinner.succeed(`Successfully updated ${result.totalUpdated} recommended third-party skill(s): ${result.updatedSkills.map((s) => style.bold(style.cyan(s.name))).join(", ")}`);
360
+ if (options.json) {
361
+ console.log(JSON.stringify(result, null, 2));
362
+ }
363
+ else {
364
+ for (const d of result.updatedSkills) {
365
+ console.log(` ✔ ${style.bold(style.cyan(d.name))} ${d.version ? `v${d.version}` : ""}`);
366
+ }
367
+ if (result.failedSkills.length > 0) {
368
+ console.log(`\n${style.yellow("⚠")} Failed to update (${result.failedSkills.length}):`);
369
+ for (const f of result.failedSkills) {
370
+ console.log(` ✖ ${style.red(f.name)}: ${f.reason}`);
371
+ }
372
+ }
373
+ }
374
+ }
375
+ }
376
+ catch (err) {
377
+ spinner.fail(`Failed to update recommended skills: ${err instanceof Error ? err.message : String(err)}`);
378
+ process.exitCode = 1;
379
+ }
380
+ return;
381
+ }
382
+ const targetSkill = options.subcommandArg || (options.installAllSkills ? "--all" : undefined);
383
+ const spinner = createSpinner(targetSkill && targetSkill !== "--all" ? `Updating skill ${targetSkill}...` : "Updating third-party skills...").start();
384
+ try {
385
+ const result = await updateThirdPartySkills(targetDir, targetSkill);
386
+ if (result.totalUpdated === 0 && result.failedSkills.length === 0) {
387
+ spinner.succeed("No third-party skills installed to update.");
388
+ }
389
+ else if (result.failedSkills.length > 0 && result.totalUpdated === 0) {
390
+ spinner.fail(`Failed to update skills: ${result.failedSkills.map((f) => `${f.name} (${f.reason})`).join(", ")}`);
391
+ process.exitCode = 1;
392
+ }
393
+ else {
394
+ spinner.succeed(`Successfully updated ${result.totalUpdated} third-party skill(s): ${result.updatedSkills.map((s) => style.bold(style.cyan(s.name))).join(", ")}`);
395
+ if (options.json) {
396
+ console.log(JSON.stringify(result, null, 2));
397
+ }
398
+ else {
399
+ for (const d of result.updatedSkills) {
400
+ console.log(` ✔ ${style.bold(style.cyan(d.name))} ${d.version ? `v${d.version}` : ""}`);
401
+ }
402
+ if (result.failedSkills.length > 0) {
403
+ console.log(`\n${style.yellow("⚠")} Failed to update (${result.failedSkills.length}):`);
404
+ for (const f of result.failedSkills) {
405
+ console.log(` ✖ ${style.red(f.name)}: ${f.reason}`);
406
+ }
407
+ }
408
+ }
409
+ }
410
+ }
411
+ catch (err) {
412
+ spinner.fail(`Failed to update skills: ${err instanceof Error ? err.message : String(err)}`);
413
+ process.exitCode = 1;
414
+ }
415
+ return;
416
+ }
301
417
  // Default: list
302
418
  const result = await listInstalledSkills(targetDir);
303
419
  if (options.json) {
@@ -561,6 +677,9 @@ function parseArgs(args) {
561
677
  let findingLocation;
562
678
  let findingImpact;
563
679
  let findingRemediation;
680
+ let skillName;
681
+ let installAllSkills = false;
682
+ let recommended = false;
564
683
  let blockersOnly = false;
565
684
  let fix = false;
566
685
  let statsOnly = false;
@@ -790,8 +909,38 @@ function parseArgs(args) {
790
909
  adapter = "opencode";
791
910
  continue;
792
911
  }
912
+ if (arg === "--name" || arg === "-n") {
913
+ const next = args[++i];
914
+ if (!next) {
915
+ throw new Error(`${arg} requires a skill name`);
916
+ }
917
+ skillName = next;
918
+ continue;
919
+ }
920
+ if (arg.startsWith("--name=")) {
921
+ skillName = arg.slice("--name=".length);
922
+ continue;
923
+ }
924
+ if (arg === "--all-skills") {
925
+ installAllSkills = true;
926
+ continue;
927
+ }
928
+ if (arg === "--recommended") {
929
+ recommended = true;
930
+ continue;
931
+ }
932
+ if (arg === "--preset=recommended") {
933
+ recommended = true;
934
+ continue;
935
+ }
936
+ if (arg === "--preset" && args[i + 1] === "recommended") {
937
+ recommended = true;
938
+ i++;
939
+ continue;
940
+ }
793
941
  if (arg === "--all" || arg === "--both") {
794
942
  adapter = "all";
943
+ installAllSkills = true;
795
944
  continue;
796
945
  }
797
946
  if (arg.startsWith("-")) {
@@ -961,8 +1110,19 @@ function parseArgs(args) {
961
1110
  command = "skill";
962
1111
  if (positional[1] === "add" || positional[1] === "install") {
963
1112
  subcommandAction = "add";
964
- subcommandArg = positional[2];
965
- target = positional[3] || target || ".";
1113
+ if (positional[2] === "--recommended" || positional[2] === "recommended") {
1114
+ recommended = true;
1115
+ target = positional[3] || target || ".";
1116
+ }
1117
+ else {
1118
+ subcommandArg = positional[2];
1119
+ target = positional[3] || target || ".";
1120
+ }
1121
+ }
1122
+ else if (positional[1] === "add-recommended" || positional[1] === "install-recommended") {
1123
+ subcommandAction = "add";
1124
+ recommended = true;
1125
+ target = positional[2] || target || ".";
966
1126
  }
967
1127
  else if (positional[1] === "remove" || positional[1] === "uninstall" || positional[1] === "rm") {
968
1128
  subcommandAction = "remove";
@@ -973,14 +1133,36 @@ function parseArgs(args) {
973
1133
  subcommandAction = "sync";
974
1134
  target = positional[2] || target || ".";
975
1135
  }
1136
+ else if (positional[1] === "update" || positional[1] === "upgrade") {
1137
+ subcommandAction = "update";
1138
+ if (positional[2] === "--recommended" || positional[2] === "recommended") {
1139
+ recommended = true;
1140
+ target = positional[3] || target || ".";
1141
+ }
1142
+ else {
1143
+ subcommandArg = positional[2];
1144
+ target = positional[3] || target || ".";
1145
+ }
1146
+ }
1147
+ else if (positional[1] === "update-recommended" || positional[1] === "upgrade-recommended") {
1148
+ subcommandAction = "update";
1149
+ recommended = true;
1150
+ target = positional[2] || target || ".";
1151
+ }
976
1152
  else if (positional[1] === "list" || positional[1] === "ls") {
977
1153
  subcommandAction = "list";
978
1154
  target = positional[2] || target || ".";
979
1155
  }
980
1156
  else if (positional[1] && !positional[1].startsWith("-")) {
981
1157
  subcommandAction = "add";
982
- subcommandArg = positional[1];
983
- target = positional[2] || target || ".";
1158
+ if (positional[1] === "recommended") {
1159
+ recommended = true;
1160
+ target = positional[2] || target || ".";
1161
+ }
1162
+ else {
1163
+ subcommandArg = positional[1];
1164
+ target = positional[2] || target || ".";
1165
+ }
984
1166
  }
985
1167
  else {
986
1168
  subcommandAction = "list";
@@ -1010,6 +1192,9 @@ function parseArgs(args) {
1010
1192
  findingLocation,
1011
1193
  findingImpact,
1012
1194
  findingRemediation,
1195
+ skillName,
1196
+ installAllSkills,
1197
+ recommended,
1013
1198
  blockersOnly,
1014
1199
  fix,
1015
1200
  statsOnly,
@@ -1071,7 +1256,8 @@ ${style.bold("Usage:")}
1071
1256
  ${style.cyan("nexus-devflow findings resolve")} <ID> [--status <status>]
1072
1257
  ${style.cyan("nexus-devflow doctor")} [--fix] [--json]
1073
1258
  ${style.cyan("nexus-devflow skill")} [list] [--json]
1074
- ${style.cyan("nexus-devflow skill add")} <git-url-or-path> [--force]
1259
+ ${style.cyan("nexus-devflow skill add")} <git-url-or-path|--recommended> [--name <name>] [--all] [--force]
1260
+ ${style.cyan("nexus-devflow skill update")} [name|--all|--recommended]
1075
1261
  ${style.cyan("nexus-devflow skill remove")} <name>
1076
1262
  ${style.cyan("nexus-devflow skill sync")}
1077
1263
  ${style.cyan("nexus-devflow archive")} [list|stats] [--json]
@@ -1089,14 +1275,17 @@ ${style.bold("Commands:")}
1089
1275
  ${style.brightCyan("idea, ideas")} Manage idea backlog: add new ideas or list pending ideas
1090
1276
  ${style.brightCyan("findings")} Inspect findings ledger, record new findings, filter blockers, or resolve
1091
1277
  ${style.brightCyan("doctor")} Inspect project workspace health and auto-heal missing files (--fix)
1092
- ${style.brightCyan("skill, skills")} Manage third-party skills: add from Git/local, remove, sync, or list
1278
+ ${style.brightCyan("skill, skills")} Manage third-party skills: add from Git/local/preset, update, remove, sync, or list
1093
1279
  ${style.brightCyan("archive")} Explore delivered runs and release statistics from devflow/history/
1094
1280
  ${style.brightCyan("update")} Update existing DevFlow installation without overwriting user changes
1095
1281
  ${style.brightCyan("uninstall, eject")} Completely remove DevFlow workflow files and adapters from project
1096
1282
 
1097
1283
  ${style.bold("Options:")}
1284
+ ${style.cyan("--recommended")} Install or update all recommended community skills (archify, diagram-design, 9arm-skills)
1098
1285
  ${style.cyan("--strict")} Strict mode for check-gate (blocks unverified runs)
1099
1286
  ${style.cyan("--title <text>")} Custom title for idea add
1287
+ ${style.cyan("--name <skill-name>")} Target specific skill in a multi-skill repository
1288
+ ${style.cyan("--all, --all-skills")} Install all skills from a multi-skill repository
1100
1289
  ${style.cyan("--severity, -s")} Finding severity: P0, P1, P2, P3 (default: P2)
1101
1290
  ${style.cyan("--status <name>")} Status to set when resolving finding (default: closed)
1102
1291
  ${style.cyan("--location <path>")} Finding source code file and line location
@@ -1206,6 +1395,25 @@ function printUninstallSuccess(result) {
1206
1395
  console.log(`\n${style.green("✔")} ${style.bold("Nexus-DevFlow has been completely removed from the project.")}`);
1207
1396
  console.log(` ${style.dim("Deleted")} ${style.bold(String(result.deletedCount))} item(s). No DevFlow traces remain.`);
1208
1397
  }
1398
+ function findPackageRoot(startDir) {
1399
+ let current = startDir;
1400
+ for (;;) {
1401
+ if (fsSync.existsSync(path.join(current, "package.json"))) {
1402
+ return current;
1403
+ }
1404
+ const parent = path.dirname(current);
1405
+ if (parent === current) {
1406
+ throw new Error(`Could not locate the installer package root above ${startDir}.`);
1407
+ }
1408
+ current = parent;
1409
+ }
1410
+ }
1411
+ function formatMissingTemplateMessage(templateRoot) {
1412
+ return `Installer template is missing.
1413
+ Looked in: ${templateRoot}
1414
+ This looks like a source checkout, where the template is a build artifact.
1415
+ Run \`npm run link:local\` from the repository root, or \`npm run prepare-template\` inside the installer package.`;
1416
+ }
1209
1417
  if (process.argv[1] &&
1210
1418
  fsSync.realpathSync(process.argv[1]) === fsSync.realpathSync(fileURLToPath(import.meta.url))) {
1211
1419
  main().catch((err) => {
@@ -1213,5 +1421,5 @@ if (process.argv[1] &&
1213
1421
  process.exit(1);
1214
1422
  });
1215
1423
  }
1216
- export { main, parseArgs };
1424
+ export { findPackageRoot, formatMissingTemplateMessage, main, parseArgs };
1217
1425
  //# sourceMappingURL=create-nexus-devflow.js.map