@puzzmo/cli 1.0.8 → 1.0.10

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.
@@ -1,5 +1,6 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
+ import * as p from "@clack/prompts";
3
4
  import { detectAgent } from "../../wizard/agent-detect.js";
4
5
  import { downloadPage } from "../../download/page-downloader.js";
5
6
  import { runCommand, gitCommit } from "../../util/exec.js";
@@ -31,37 +32,6 @@ const parseArgs = (args) => {
31
32
  }
32
33
  return opts;
33
34
  };
34
- /** Interactive text prompt (simple readline-based fallback) */
35
- const askText = async (message, defaultValue) => {
36
- const { createInterface } = await import("node:readline");
37
- const rl = createInterface({ input: process.stdin, output: process.stdout });
38
- const prompt = defaultValue ? `${message} (${defaultValue}): ` : `${message}: `;
39
- return new Promise((resolve) => {
40
- rl.question(prompt, (answer) => {
41
- rl.close();
42
- resolve(answer.trim() || defaultValue || "");
43
- });
44
- });
45
- };
46
- /** Interactive select prompt */
47
- const askSelect = async (message, options) => {
48
- console.log(`\n${message}`);
49
- const enabled = options.filter((o) => !o.disabled);
50
- options.forEach((opt) => {
51
- const prefix = opt.disabled ? " " : ` ${enabled.indexOf(opt) + 1}.`;
52
- const suffix = opt.disabled ? " (Coming soon)" : "";
53
- console.log(`${prefix} ${opt.label}${suffix}`);
54
- });
55
- const { createInterface } = await import("node:readline");
56
- const rl = createInterface({ input: process.stdin, output: process.stdout });
57
- return new Promise((resolve) => {
58
- rl.question(`\nChoice (1-${enabled.length}): `, (answer) => {
59
- rl.close();
60
- const idx = parseInt(answer.trim(), 10) - 1;
61
- resolve(enabled[idx]?.value ?? enabled[0].value);
62
- });
63
- });
64
- };
65
35
  /** Converts a string to a URL-friendly slug */
66
36
  const slugify = (str) => str
67
37
  .toLowerCase()
@@ -70,89 +40,97 @@ const slugify = (str) => str
70
40
  /** Main game create wizard */
71
41
  export const gameCreate = async (args) => {
72
42
  const opts = parseArgs(args);
73
- console.log("\n Puzzmo Game Creator\n");
43
+ p.intro("Puzzmo Game Creator");
74
44
  // Step 1: Mode selection
75
- const mode = await askSelect("How would you like to create your game?", [
76
- { value: "import", label: "Import an HTML game from a web page" },
77
- { value: "new-repo", label: "Create game in a new repo", disabled: true },
78
- { value: "add-to-repo", label: "Add a game to this repo", disabled: true },
79
- ]);
45
+ const mode = await p.select({
46
+ message: "How would you like to create your game?",
47
+ options: [
48
+ { value: "import", label: "Import an HTML game from a web page" },
49
+ { value: "new-repo", label: "Create game in a new repo", hint: "coming soon" },
50
+ { value: "add-to-repo", label: "Add a game to this repo", hint: "coming soon" },
51
+ ],
52
+ });
53
+ if (p.isCancel(mode))
54
+ process.exit(0);
80
55
  if (mode !== "import") {
81
- console.log("This mode is not yet supported.");
56
+ p.log.warn("This mode is not yet supported.");
82
57
  process.exit(0);
83
58
  }
84
59
  // Step 2: Source URL
85
- const url = opts.url || (await askText("Source URL to import"));
60
+ let url = opts.url;
86
61
  if (!url) {
87
- console.error("Source URL is required for import mode");
88
- process.exit(1);
62
+ url = (await p.text({ message: "Source URL to import", validate: (v) => (!v ? "URL is required" : undefined) }));
63
+ if (p.isCancel(url))
64
+ process.exit(0);
89
65
  }
90
66
  // Step 3: Download page to a temp dir, extract title
91
67
  const tmpDir = path.resolve(".puzzmo-import-tmp");
92
- console.log(`\nDownloading ${url}...`);
68
+ const s = p.spinner();
69
+ s.start(`Downloading ${url}`);
93
70
  const { title } = await downloadPage(url, tmpDir);
94
- console.log("Download complete.");
71
+ s.stop("Download complete.");
95
72
  // Step 4: Game name (default to HTML title if available)
96
73
  const defaultName = opts.name || title;
97
- const name = await askText("Game name", defaultName);
98
- if (!name) {
99
- console.error("Game name is required");
100
- process.exit(1);
101
- }
74
+ const name = (await p.text({
75
+ message: "Game name",
76
+ initialValue: defaultName,
77
+ validate: (v) => (!v ? "Game name is required" : undefined),
78
+ }));
79
+ if (p.isCancel(name))
80
+ process.exit(0);
102
81
  // Step 5: Move downloaded files to slugified directory
103
82
  const slug = slugify(name);
104
83
  const gameDir = path.resolve(slug);
105
84
  fs.renameSync(tmpDir, gameDir);
106
- // Step 5: Detect agents
85
+ // Step 6: Detect agents
107
86
  const agents = detectAgent();
108
87
  const agentChoices = [
109
88
  ...agents.map((a) => ({ value: a.binary, label: `${a.displayName} (${a.path})` })),
110
89
  { value: "none", label: "None - I'll run the skills manually" },
111
90
  ];
112
- // Step 6: Ask about agent
91
+ // Step 7: Ask about agent
113
92
  let selectedAgent;
114
93
  if (opts.agent) {
115
94
  selectedAgent = opts.agent;
116
95
  }
117
96
  else if (agents.length > 0) {
118
- selectedAgent = await askSelect("Which LLM agent do you use?", agentChoices);
97
+ selectedAgent = (await p.select({ message: "Which LLM agent do you use?", options: agentChoices }));
98
+ if (p.isCancel(selectedAgent))
99
+ process.exit(0);
119
100
  }
120
101
  else {
121
- console.log("\nNo LLM agents detected (checked: claude, codex)");
102
+ p.log.info("No LLM agents detected (checked: claude, codex)");
122
103
  selectedAgent = "none";
123
104
  }
124
- // Step 7: Login if token provided
105
+ // Step 8: Login if token provided
125
106
  if (opts.accessToken) {
126
- console.log("\nLogging in...");
107
+ p.log.step("Logging in...");
127
108
  login(opts.accessToken);
128
109
  }
129
- // Step 8: Install skills into the game directory
110
+ // Step 9: Install skills into the game directory
130
111
  if (selectedAgent !== "none") {
131
- console.log("\nInstalling Puzzmo skills...");
132
- const count = installSkills(selectedAgent, gameDir, opts.pm);
133
- console.log(`Installed ${count} skill(s).`);
112
+ p.log.step("Installing Puzzmo skills...");
113
+ const count = installSkills(selectedAgent, gameDir);
114
+ p.log.success(`Installed ${count} skill(s).`);
134
115
  }
135
- // Step 9: Initialize git
116
+ // Step 10: Initialize git
136
117
  if (!fs.existsSync(path.join(gameDir, ".git"))) {
137
118
  runCommand("git init", { cwd: gameDir });
138
119
  runCommand("git add -A", { cwd: gameDir });
139
120
  gitCommit("Initial game import", { cwd: gameDir });
140
121
  }
141
- // Step 10: Run skills pipeline
122
+ // Step 11: Run skills pipeline
142
123
  if (selectedAgent !== "none") {
143
- console.log("\nStarting migration pipeline...\n");
124
+ p.log.step("Starting migration pipeline...");
144
125
  await runSkillsPipelineTUI(selectedAgent, gameDir);
145
126
  }
146
127
  // Done
147
128
  const pm = opts.pm || "npm";
148
129
  const runCmd = pm === "npm" ? "npx" : pm === "yarn" ? "yarn dlx" : "pnpm dlx";
149
- console.log(`\nDone! Your game is in ./${slug}/`);
150
- console.log(`\nNext steps:`);
151
- console.log(` cd ${slug}`);
152
- console.log(` ${runCmd} vite # Start development server`);
153
- console.log(` ${runCmd} vite build # Build for production`);
130
+ p.note([`cd ${slug}`, `${runCmd} vite # Start development server`, `${runCmd} vite build # Build for production`].join("\n"), "Next steps");
154
131
  if (selectedAgent === "none") {
155
- console.log(`\nTo run migration skills manually, see packages/skills/ for SKILL.md files.`);
132
+ p.log.info("To run migration skills manually, see packages/skills/ for SKILL.md files.");
156
133
  }
134
+ p.outro(`Done! Your game is in ./${slug}/`);
157
135
  };
158
136
  //# sourceMappingURL=create.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/game/create.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/game/create.ts"],"names":[],"mappings":"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"}
@@ -6,4 +6,5 @@ export type SkillDefinition = {
6
6
  export declare const skillsPipeline: SkillDefinition[];
7
7
  /** Returns the skills directory for a given agent inside the game dir */
8
8
  export declare const agentSkillsDir: (agent: string) => string;
9
- export declare const installSkills: (agent: string, gameDir: string, pm?: string) => number;
9
+ /** Installs all Puzzmo skills from the OSS repo using `npx skills add` */
10
+ export declare const installSkills: (agent: string, gameDir: string) => number;
@@ -1,6 +1,4 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import { fileURLToPath } from "node:url";
1
+ import { spawnSync } from "node:child_process";
4
2
  /** Ordered list of skills for the migration pipeline */
5
3
  export const skillsPipeline = [
6
4
  { name: "convert-to-vite", optional: false },
@@ -22,54 +20,17 @@ export const agentSkillsDir = (agent) => {
22
20
  return ".gemini/skills";
23
21
  return `.${agent}/skills`;
24
22
  };
25
- /**
26
- * Copies SKILL.md files from the bundled skills source into the game
27
- * directory under the agent-specific skills path.
28
- */
29
- /** Maps npm commands to their equivalents in other package managers */
30
- const rewriteForPM = (content, pm) => {
31
- if (pm === "npm")
32
- return content;
33
- if (pm === "yarn") {
34
- return content
35
- .replace(/npm install --save-dev /g, "yarn add --dev ")
36
- .replace(/npm install /g, "yarn add ")
37
- .replace(/npm run /g, "yarn ")
38
- .replace(/npx /g, "yarn dlx ");
23
+ /** Installs all Puzzmo skills from the OSS repo using `npx skills add` */
24
+ export const installSkills = (agent, gameDir) => {
25
+ const result = spawnSync("npx", ["skills", "add", "puzzmo-com/oss", "--agent", agent, "--skill", "*", "--copy", "-y"], {
26
+ cwd: gameDir,
27
+ stdio: "inherit",
28
+ encoding: "utf-8",
29
+ });
30
+ if (result.status !== 0) {
31
+ console.error("Failed to install skills from puzzmo-com/oss");
32
+ process.exit(1);
39
33
  }
40
- if (pm === "pnpm") {
41
- return content
42
- .replace(/npm install --save-dev /g, "pnpm add --save-dev ")
43
- .replace(/npm install /g, "pnpm add ")
44
- .replace(/npm run /g, "pnpm ")
45
- .replace(/npx /g, "pnpm dlx ");
46
- }
47
- return content;
48
- };
49
- export const installSkills = (agent, gameDir, pm) => {
50
- const skillsRoot = agentSkillsDir(agent);
51
- // Locate the bundled skills source (packages/skills/ relative to this file)
52
- // This file is at packages/cli/src/skills/registry.ts (or lib/skills/registry.js when built)
53
- const thisDir = path.dirname(fileURLToPath(import.meta.url));
54
- // Walk up to packages/cli, then over to packages/skills
55
- const packagesDir = path.resolve(thisDir, "..", "..", "..");
56
- const skillsSrcDir = path.join(packagesDir, "skills");
57
- let installed = 0;
58
- for (const skill of skillsPipeline) {
59
- const srcFile = path.join(skillsSrcDir, skill.name, "SKILL.md");
60
- if (!fs.existsSync(srcFile))
61
- continue;
62
- const destDir = path.join(gameDir, skillsRoot, skill.name);
63
- fs.mkdirSync(destDir, { recursive: true });
64
- if (pm && pm !== "npm") {
65
- const content = fs.readFileSync(srcFile, "utf-8");
66
- fs.writeFileSync(path.join(destDir, "SKILL.md"), rewriteForPM(content, pm));
67
- }
68
- else {
69
- fs.copyFileSync(srcFile, path.join(destDir, "SKILL.md"));
70
- }
71
- installed++;
72
- }
73
- return installed;
34
+ return skillsPipeline.length;
74
35
  };
75
36
  //# sourceMappingURL=registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/skills/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/skills/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAO9C,wDAAwD;AACxD,MAAM,CAAC,MAAM,cAAc,GAAsB;IAC/C,EAAE,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC5C,EAAE,IAAI,EAAE,sBAAsB,EAAE,QAAQ,EAAE,KAAK,EAAE;IACjD,EAAE,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC5C,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE;IACxC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE;IACtC,EAAE,IAAI,EAAE,qBAAqB,EAAE,QAAQ,EAAE,KAAK,EAAE;IAChD,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC9C,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE;CAC1C,CAAA;AAED,yEAAyE;AACzE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAa,EAAU,EAAE;IACtD,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,gBAAgB,CAAA;IAC/C,IAAI,KAAK,KAAK,OAAO;QAAE,OAAO,eAAe,CAAA;IAC7C,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,gBAAgB,CAAA;IAC/C,OAAO,IAAI,KAAK,SAAS,CAAA;AAC3B,CAAC,CAAA;AAED,0EAA0E;AAC1E,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAa,EAAE,OAAe,EAAU,EAAE;IACtE,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE;QACrH,GAAG,EAAE,OAAO;QACZ,KAAK,EAAE,SAAS;QAChB,QAAQ,EAAE,OAAO;KAClB,CAAC,CAAA;IAEF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAA;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,OAAO,cAAc,CAAC,MAAM,CAAA;AAC9B,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@puzzmo/cli",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "puzzmo": "./lib/index.js"
@@ -21,6 +21,7 @@
21
21
  "type-check": "tsc --noEmit"
22
22
  },
23
23
  "dependencies": {
24
+ "@clack/prompts": "^1.1.0",
24
25
  "@puzzmo/agent-cli-detect": "*"
25
26
  }
26
27
  }
@@ -1,5 +1,6 @@
1
1
  import fs from "node:fs"
2
2
  import path from "node:path"
3
+ import * as p from "@clack/prompts"
3
4
 
4
5
  import { detectAgent } from "../../wizard/agent-detect.js"
5
6
  import { downloadPage } from "../../download/page-downloader.js"
@@ -40,42 +41,6 @@ const parseArgs = (args: string[]): CreateOptions => {
40
41
  return opts
41
42
  }
42
43
 
43
- /** Interactive text prompt (simple readline-based fallback) */
44
- const askText = async (message: string, defaultValue?: string): Promise<string> => {
45
- const { createInterface } = await import("node:readline")
46
- const rl = createInterface({ input: process.stdin, output: process.stdout })
47
- const prompt = defaultValue ? `${message} (${defaultValue}): ` : `${message}: `
48
-
49
- return new Promise((resolve) => {
50
- rl.question(prompt, (answer) => {
51
- rl.close()
52
- resolve(answer.trim() || defaultValue || "")
53
- })
54
- })
55
- }
56
-
57
- /** Interactive select prompt */
58
- const askSelect = async (message: string, options: { value: string; label: string; disabled?: boolean }[]): Promise<string> => {
59
- console.log(`\n${message}`)
60
- const enabled = options.filter((o) => !o.disabled)
61
- options.forEach((opt) => {
62
- const prefix = opt.disabled ? " " : ` ${enabled.indexOf(opt) + 1}.`
63
- const suffix = opt.disabled ? " (Coming soon)" : ""
64
- console.log(`${prefix} ${opt.label}${suffix}`)
65
- })
66
-
67
- const { createInterface } = await import("node:readline")
68
- const rl = createInterface({ input: process.stdin, output: process.stdout })
69
-
70
- return new Promise((resolve) => {
71
- rl.question(`\nChoice (1-${enabled.length}): `, (answer) => {
72
- rl.close()
73
- const idx = parseInt(answer.trim(), 10) - 1
74
- resolve(enabled[idx]?.value ?? enabled[0].value)
75
- })
76
- })
77
- }
78
-
79
44
  /** Converts a string to a URL-friendly slug */
80
45
  const slugify = (str: string): string =>
81
46
  str
@@ -87,99 +52,110 @@ const slugify = (str: string): string =>
87
52
  export const gameCreate = async (args: string[]) => {
88
53
  const opts = parseArgs(args)
89
54
 
90
- console.log("\n Puzzmo Game Creator\n")
55
+ p.intro("Puzzmo Game Creator")
91
56
 
92
57
  // Step 1: Mode selection
93
- const mode = await askSelect("How would you like to create your game?", [
94
- { value: "import", label: "Import an HTML game from a web page" },
95
- { value: "new-repo", label: "Create game in a new repo", disabled: true },
96
- { value: "add-to-repo", label: "Add a game to this repo", disabled: true },
97
- ])
58
+ const mode = await p.select({
59
+ message: "How would you like to create your game?",
60
+ options: [
61
+ { value: "import", label: "Import an HTML game from a web page" },
62
+ { value: "new-repo", label: "Create game in a new repo", hint: "coming soon" },
63
+ { value: "add-to-repo", label: "Add a game to this repo", hint: "coming soon" },
64
+ ],
65
+ })
66
+
67
+ if (p.isCancel(mode)) process.exit(0)
98
68
 
99
69
  if (mode !== "import") {
100
- console.log("This mode is not yet supported.")
70
+ p.log.warn("This mode is not yet supported.")
101
71
  process.exit(0)
102
72
  }
103
73
 
104
74
  // Step 2: Source URL
105
- const url = opts.url || (await askText("Source URL to import"))
75
+ let url = opts.url
106
76
  if (!url) {
107
- console.error("Source URL is required for import mode")
108
- process.exit(1)
77
+ url = (await p.text({ message: "Source URL to import", validate: (v) => (!v ? "URL is required" : undefined) })) as string
78
+ if (p.isCancel(url)) process.exit(0)
109
79
  }
110
80
 
111
81
  // Step 3: Download page to a temp dir, extract title
112
82
  const tmpDir = path.resolve(".puzzmo-import-tmp")
113
- console.log(`\nDownloading ${url}...`)
83
+ const s = p.spinner()
84
+ s.start(`Downloading ${url}`)
114
85
  const { title } = await downloadPage(url, tmpDir)
115
- console.log("Download complete.")
86
+ s.stop("Download complete.")
116
87
 
117
88
  // Step 4: Game name (default to HTML title if available)
118
89
  const defaultName = opts.name || title
119
- const name = await askText("Game name", defaultName)
120
- if (!name) {
121
- console.error("Game name is required")
122
- process.exit(1)
123
- }
90
+ const name = (await p.text({
91
+ message: "Game name",
92
+ initialValue: defaultName,
93
+ validate: (v) => (!v ? "Game name is required" : undefined),
94
+ })) as string
95
+ if (p.isCancel(name)) process.exit(0)
124
96
 
125
97
  // Step 5: Move downloaded files to slugified directory
126
98
  const slug = slugify(name)
127
99
  const gameDir = path.resolve(slug)
128
100
  fs.renameSync(tmpDir, gameDir)
129
101
 
130
- // Step 5: Detect agents
102
+ // Step 6: Detect agents
131
103
  const agents = detectAgent()
132
104
  const agentChoices = [
133
105
  ...agents.map((a) => ({ value: a.binary, label: `${a.displayName} (${a.path})` })),
134
106
  { value: "none", label: "None - I'll run the skills manually" },
135
107
  ]
136
108
 
137
- // Step 6: Ask about agent
109
+ // Step 7: Ask about agent
138
110
  let selectedAgent: string
139
111
  if (opts.agent) {
140
112
  selectedAgent = opts.agent
141
113
  } else if (agents.length > 0) {
142
- selectedAgent = await askSelect("Which LLM agent do you use?", agentChoices)
114
+ selectedAgent = (await p.select({ message: "Which LLM agent do you use?", options: agentChoices })) as string
115
+ if (p.isCancel(selectedAgent)) process.exit(0)
143
116
  } else {
144
- console.log("\nNo LLM agents detected (checked: claude, codex)")
117
+ p.log.info("No LLM agents detected (checked: claude, codex)")
145
118
  selectedAgent = "none"
146
119
  }
147
120
 
148
- // Step 7: Login if token provided
121
+ // Step 8: Login if token provided
149
122
  if (opts.accessToken) {
150
- console.log("\nLogging in...")
123
+ p.log.step("Logging in...")
151
124
  login(opts.accessToken)
152
125
  }
153
126
 
154
- // Step 8: Install skills into the game directory
127
+ // Step 9: Install skills into the game directory
155
128
  if (selectedAgent !== "none") {
156
- console.log("\nInstalling Puzzmo skills...")
157
- const count = installSkills(selectedAgent, gameDir, opts.pm)
158
- console.log(`Installed ${count} skill(s).`)
129
+ p.log.step("Installing Puzzmo skills...")
130
+ const count = installSkills(selectedAgent, gameDir)
131
+ p.log.success(`Installed ${count} skill(s).`)
159
132
  }
160
133
 
161
- // Step 9: Initialize git
134
+ // Step 10: Initialize git
162
135
  if (!fs.existsSync(path.join(gameDir, ".git"))) {
163
136
  runCommand("git init", { cwd: gameDir })
164
137
  runCommand("git add -A", { cwd: gameDir })
165
138
  gitCommit("Initial game import", { cwd: gameDir })
166
139
  }
167
140
 
168
- // Step 10: Run skills pipeline
141
+ // Step 11: Run skills pipeline
169
142
  if (selectedAgent !== "none") {
170
- console.log("\nStarting migration pipeline...\n")
143
+ p.log.step("Starting migration pipeline...")
171
144
  await runSkillsPipelineTUI(selectedAgent, gameDir)
172
145
  }
173
146
 
174
147
  // Done
175
148
  const pm = opts.pm || "npm"
176
149
  const runCmd = pm === "npm" ? "npx" : pm === "yarn" ? "yarn dlx" : "pnpm dlx"
177
- console.log(`\nDone! Your game is in ./${slug}/`)
178
- console.log(`\nNext steps:`)
179
- console.log(` cd ${slug}`)
180
- console.log(` ${runCmd} vite # Start development server`)
181
- console.log(` ${runCmd} vite build # Build for production`)
150
+
151
+ p.note(
152
+ [`cd ${slug}`, `${runCmd} vite # Start development server`, `${runCmd} vite build # Build for production`].join("\n"),
153
+ "Next steps",
154
+ )
155
+
182
156
  if (selectedAgent === "none") {
183
- console.log(`\nTo run migration skills manually, see packages/skills/ for SKILL.md files.`)
157
+ p.log.info("To run migration skills manually, see packages/skills/ for SKILL.md files.")
184
158
  }
159
+
160
+ p.outro(`Done! Your game is in ./${slug}/`)
185
161
  }
@@ -1,6 +1,4 @@
1
- import fs from "node:fs"
2
- import path from "node:path"
3
- import { fileURLToPath } from "node:url"
1
+ import { spawnSync } from "node:child_process"
4
2
 
5
3
  export type SkillDefinition = {
6
4
  name: string
@@ -27,57 +25,18 @@ export const agentSkillsDir = (agent: string): string => {
27
25
  return `.${agent}/skills`
28
26
  }
29
27
 
30
- /**
31
- * Copies SKILL.md files from the bundled skills source into the game
32
- * directory under the agent-specific skills path.
33
- */
34
- /** Maps npm commands to their equivalents in other package managers */
35
- const rewriteForPM = (content: string, pm: string): string => {
36
- if (pm === "npm") return content
37
- if (pm === "yarn") {
38
- return content
39
- .replace(/npm install --save-dev /g, "yarn add --dev ")
40
- .replace(/npm install /g, "yarn add ")
41
- .replace(/npm run /g, "yarn ")
42
- .replace(/npx /g, "yarn dlx ")
43
- }
44
- if (pm === "pnpm") {
45
- return content
46
- .replace(/npm install --save-dev /g, "pnpm add --save-dev ")
47
- .replace(/npm install /g, "pnpm add ")
48
- .replace(/npm run /g, "pnpm ")
49
- .replace(/npx /g, "pnpm dlx ")
50
- }
51
- return content
52
- }
53
-
54
- export const installSkills = (agent: string, gameDir: string, pm?: string): number => {
55
- const skillsRoot = agentSkillsDir(agent)
56
-
57
- // Locate the bundled skills source (packages/skills/ relative to this file)
58
- // This file is at packages/cli/src/skills/registry.ts (or lib/skills/registry.js when built)
59
- const thisDir = path.dirname(fileURLToPath(import.meta.url))
60
- // Walk up to packages/cli, then over to packages/skills
61
- const packagesDir = path.resolve(thisDir, "..", "..", "..")
62
- const skillsSrcDir = path.join(packagesDir, "skills")
63
-
64
- let installed = 0
65
-
66
- for (const skill of skillsPipeline) {
67
- const srcFile = path.join(skillsSrcDir, skill.name, "SKILL.md")
68
- if (!fs.existsSync(srcFile)) continue
69
-
70
- const destDir = path.join(gameDir, skillsRoot, skill.name)
71
- fs.mkdirSync(destDir, { recursive: true })
72
-
73
- if (pm && pm !== "npm") {
74
- const content = fs.readFileSync(srcFile, "utf-8")
75
- fs.writeFileSync(path.join(destDir, "SKILL.md"), rewriteForPM(content, pm))
76
- } else {
77
- fs.copyFileSync(srcFile, path.join(destDir, "SKILL.md"))
78
- }
79
- installed++
28
+ /** Installs all Puzzmo skills from the OSS repo using `npx skills add` */
29
+ export const installSkills = (agent: string, gameDir: string): number => {
30
+ const result = spawnSync("npx", ["skills", "add", "puzzmo-com/oss", "--agent", agent, "--skill", "*", "--copy", "-y"], {
31
+ cwd: gameDir,
32
+ stdio: "inherit",
33
+ encoding: "utf-8",
34
+ })
35
+
36
+ if (result.status !== 0) {
37
+ console.error("Failed to install skills from puzzmo-com/oss")
38
+ process.exit(1)
80
39
  }
81
40
 
82
- return installed
41
+ return skillsPipeline.length
83
42
  }