@code-migration/wow-migrator 0.1.0 → 0.1.1

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/README.md CHANGED
@@ -1,75 +1,89 @@
1
- # KMP Skills Installer
1
+ # WOW Migrator
2
2
 
3
- Install the KMP migration skills into common AI coding tools through `npm install`.
3
+ Install Android to Kotlin Multiplatform migration skills into AI coding tools through npm.
4
4
 
5
- ## Install From This Repo
6
-
7
- The package is not published to the npm registry yet. Install it from the local package directory:
5
+ ## Install
8
6
 
9
7
  ```bash
10
- npm install -g /Users/winson/CodeBase/Online/cli-plugins/npx_skills
8
+ npm install -g @code-migration/wow-migrator
11
9
  ```
12
10
 
13
- Or, from the repository root:
11
+ During `npm install`, the package runs `postinstall` and installs the bundled skills into every supported tool it detects on the machine.
12
+
13
+ To install the CLI but skip automatic skill installation:
14
14
 
15
15
  ```bash
16
- npm install -g ./npx_skills
16
+ WOW_MIGRATOR_SKIP_POSTINSTALL=1 npm install -g @code-migration/wow-migrator
17
17
  ```
18
18
 
19
- To install from a tarball:
19
+ ## What Gets Installed
20
20
 
21
- ```bash
22
- cd /Users/winson/CodeBase/Online/cli-plugins/npx_skills
23
- npm pack
24
- npm install -g ./code-migration-wow-migrator-0.1.0.tgz
25
- ```
21
+ The package bundles these skills:
26
22
 
27
- After publishing this package to npm, the registry install command will be:
23
+ - `android-project-analyst`
24
+ - `android-to-kmp-migrator`
25
+ - `kmp-test-validator`
26
+
27
+ They are copied into each target tool's `skills` directory. Re-running install is idempotent: the bundled skill directories are replaced with the package version.
28
+
29
+ ## CLI Commands
30
+
31
+ The primary CLI command is `wow-migrator`.
28
32
 
29
33
  ```bash
30
- npm install -g @code-migration/wow-migrator
34
+ wow-migrator install --yes
35
+ wow-migrator install --platform claude --yes
36
+ wow-migrator install --platform cursor,codex --yes
37
+ wow-migrator install --target "Claude Code,Codex"
38
+ wow-migrator uninstall --target all --yes
39
+ wow-migrator list
40
+ wow-migrator config
31
41
  ```
32
42
 
33
- The package runs `postinstall` and installs bundled skills into detected tools.
34
- Set `KMP_SKILLS_SKIP_POSTINSTALL=1` to skip the automatic install.
43
+ ## Install By Platform
35
44
 
36
- ## Commands
45
+ Use `--platform`, `--target`, or `--tool`. They are aliases and accept a single platform, a comma-separated list, or `all`.
37
46
 
38
47
  ```bash
39
- kmp-skills install --yes
40
- kmp-skills install --target "Claude Code,Codex"
41
- kmp-skills uninstall --target all --yes
42
- kmp-skills list
43
- kmp-skills config
48
+ wow-migrator install --platform claude --yes
49
+ wow-migrator install --platform cursor,codex --yes
50
+ wow-migrator install --platform all --yes
44
51
  ```
45
52
 
46
- ## Supported Targets
53
+ Supported platforms:
47
54
 
48
- | Tool | Detection | Skills directory |
49
- | --- | --- | --- |
50
- | OpenClaw | `~/.openclaw` or `openclaw` | `~/.openclaw/skills` |
51
- | Claude Code | `~/.claude` or `claude` | `~/.claude/skills` |
52
- | OpenCode | `~/.config/opencode` or `opencode` | `~/.config/opencode/skills` |
53
- | Codex | `~/.codex` or `codex` | `~/.codex/skills` |
54
- | Cursor | `~/.cursor` or `cursor` | `~/.cursor/skills` |
55
- | Gemini | `~/.gemini` or `gemini` | `~/.gemini/skills` |
56
- | JiuwenSwarm | `~/.jiuwenswarm` or Jiuwen CLI commands | `~/.jiuwenswarm/agent/workspace/skills` |
55
+ | Platform | Aliases | Detection | Skills directory |
56
+ | --- | --- | --- | --- |
57
+ | OpenClaw | `openclaw`, `open-claw` | `~/.openclaw` or `openclaw` | `~/.openclaw/skills` |
58
+ | Claude Code | `claude`, `claude-code`, `claudecode` | `~/.claude` or `claude` | `~/.claude/skills` |
59
+ | OpenCode | `opencode`, `open-code` | `~/.config/opencode` or `opencode` | `~/.config/opencode/skills` |
60
+ | Codex | `codex`, `openai-codex` | `~/.codex` or `codex` | `~/.codex/skills` |
61
+ | Cursor | `cursor` | `~/.cursor` or `cursor` | `~/.cursor/skills` |
62
+ | Gemini | `gemini`, `gemini-cli` | `~/.gemini` or `gemini` | `~/.gemini/skills` |
63
+ | JiuwenSwarm | `jiuwen`, `jiuwenswarm`, `jiuwen-swarm`, `jiuwenclaw` | `~/.jiuwenswarm` or Jiuwen CLI commands | `~/.jiuwenswarm/agent/workspace/skills` |
57
64
 
58
65
  ## Configuration
59
66
 
60
- The installer creates:
67
+ View or create the config file:
68
+
69
+ ```bash
70
+ wow-migrator config
71
+ ```
72
+
73
+ The config file is stored at:
61
74
 
62
75
  ```text
63
- ~/.kmp-skills/config.json
76
+ ~/.wow-migrator/config.json
64
77
  ```
65
78
 
66
- Edit it to add custom tools or paths. The shape is:
79
+ Edit it to add custom tools, aliases, commands, or skills directories:
67
80
 
68
81
  ```json
69
82
  {
70
83
  "tools": [
71
84
  {
72
85
  "name": "Claude Code",
86
+ "aliases": ["claude", "claude-code"],
73
87
  "markerDir": "~/.claude",
74
88
  "commands": ["claude"],
75
89
  "skillsDir": "~/.claude/skills"
@@ -78,36 +92,23 @@ Edit it to add custom tools or paths. The shape is:
78
92
  }
79
93
  ```
80
94
 
81
- ## Publishing From This Repo
95
+ ## Other Functions
82
96
 
83
- Before packing or publishing, sync the current plugin skills into this package:
97
+ List bundled skills:
84
98
 
85
99
  ```bash
86
- cd npx_skills
87
- npm run sync:skills
88
- npm pack
100
+ wow-migrator list
89
101
  ```
90
102
 
91
- `prepare` and `prepack` also run the sync script when the monorepo source is available.
92
-
93
- Publish with the existing `code-migration` npm org scope:
103
+ Remove bundled skills from selected platforms:
94
104
 
95
105
  ```bash
96
- npm publish --access public
106
+ wow-migrator uninstall --platform claude,cursor --yes
107
+ wow-migrator uninstall --platform all --yes
97
108
  ```
98
109
 
99
- If npm returns `E404 Scope not found`, confirm that the npm org exists and the
100
- current npm user has publish access:
110
+ Preview an install without writing files:
101
111
 
102
112
  ```bash
103
- npm whoami
104
- npm org ls code-migration
105
- ```
106
-
107
- For this package, `npm org ls code-migration` should list your user with owner
108
- or publish-capable access. After that, publish and install with:
109
-
110
- ```bash
111
- npm publish --access public
112
- npm install -g @code-migration/wow-migrator
113
+ wow-migrator install --platform all --dry-run --yes
113
114
  ```
@@ -8,9 +8,10 @@ import { fileURLToPath } from 'node:url';
8
8
  import readline from 'node:readline/promises';
9
9
 
10
10
  const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
11
- const CONFIG_DIR = path.join(os.homedir(), '.kmp-skills');
11
+ const CONFIG_DIR = path.join(os.homedir(), '.wow-migrator');
12
12
  const CONFIG_PATH = path.join(CONFIG_DIR, 'config.json');
13
13
  const isWindows = process.platform === 'win32';
14
+ const CLI_NAME = path.basename(process.argv[1] ?? 'wow-migrator').replace(/\.js$/, '') || 'wow-migrator';
14
15
 
15
16
  function expandHome(input) {
16
17
  if (!input) return input;
@@ -107,42 +108,49 @@ function defaultTools() {
107
108
  return [
108
109
  {
109
110
  name: 'OpenClaw',
111
+ aliases: ['openclaw', 'open-claw'],
110
112
  markerDir: '~/.openclaw',
111
113
  commands: ['openclaw'],
112
114
  skillsDir: '~/.openclaw/skills'
113
115
  },
114
116
  {
115
117
  name: 'Claude Code',
118
+ aliases: ['claude', 'claude-code', 'claudecode'],
116
119
  markerDir: '~/.claude',
117
120
  commands: ['claude'],
118
121
  skillsDir: '~/.claude/skills'
119
122
  },
120
123
  {
121
124
  name: 'OpenCode',
125
+ aliases: ['opencode', 'open-code'],
122
126
  markerDir: '~/.config/opencode',
123
127
  commands: ['opencode'],
124
128
  skillsDir: '~/.config/opencode/skills'
125
129
  },
126
130
  {
127
131
  name: 'Codex',
132
+ aliases: ['codex', 'openai-codex'],
128
133
  markerDir: '~/.codex',
129
134
  commands: ['codex'],
130
135
  skillsDir: '~/.codex/skills'
131
136
  },
132
137
  {
133
138
  name: 'Cursor',
139
+ aliases: ['cursor'],
134
140
  markerDir: '~/.cursor',
135
141
  commands: ['cursor'],
136
142
  skillsDir: '~/.cursor/skills'
137
143
  },
138
144
  {
139
145
  name: 'Gemini',
146
+ aliases: ['gemini', 'gemini-cli'],
140
147
  markerDir: '~/.gemini',
141
148
  commands: ['gemini'],
142
149
  skillsDir: '~/.gemini/skills'
143
150
  },
144
151
  {
145
152
  name: 'JiuwenSwarm',
153
+ aliases: ['jiuwen', 'jiuwenswarm', 'jiuwen-swarm', 'jiuwenclaw'],
146
154
  markerDir: '~/.jiuwenswarm',
147
155
  commands: defaultJiuwenCommands(),
148
156
  skillsDir: '~/.jiuwenswarm/agent/workspace/skills'
@@ -156,6 +164,7 @@ function normalizeTool(raw) {
156
164
  if (!skillsDir) return null;
157
165
  return {
158
166
  name: String(raw.name),
167
+ aliases: Array.isArray(raw.aliases) ? raw.aliases.map(String).filter(Boolean) : [],
159
168
  markerDir: raw.markerDir ? String(raw.markerDir) : '',
160
169
  commands: Array.isArray(raw.commands) ? raw.commands.map(String).filter(Boolean) : [],
161
170
  skillsDir: String(skillsDir)
@@ -181,7 +190,11 @@ async function loadConfig(options = {}) {
181
190
  : [];
182
191
  const userTools = sourceTools.map(normalizeTool).filter(Boolean);
183
192
  const merged = new Map(defaultTools().map((tool) => [tool.name, tool]));
184
- for (const tool of userTools) merged.set(tool.name, tool);
193
+ for (const tool of userTools) {
194
+ const existing = merged.get(tool.name);
195
+ const aliases = [...new Set([...(existing?.aliases ?? []), ...(tool.aliases ?? [])])];
196
+ merged.set(tool.name, existing ? { ...existing, ...tool, aliases } : tool);
197
+ }
185
198
  return { tools: [...merged.values()] };
186
199
  }
187
200
 
@@ -269,10 +282,21 @@ function parseArgs(argv) {
269
282
  if (arg === '--yes' || arg === '-y') flags.yes = true;
270
283
  else if (arg === '--postinstall') flags.postinstall = true;
271
284
  else if (arg === '--dry-run') flags.dryRun = true;
272
- else if (arg === '--target' || arg === '--targets') {
285
+ else if (
286
+ arg === '--target' ||
287
+ arg === '--targets' ||
288
+ arg === '--platform' ||
289
+ arg === '--platforms' ||
290
+ arg === '--tool' ||
291
+ arg === '--tools'
292
+ ) {
273
293
  flags.targets = argv[++index]?.split(',').map((item) => item.trim()).filter(Boolean) ?? [];
274
294
  } else if (arg.startsWith('--target=')) {
275
295
  flags.targets = arg.slice('--target='.length).split(',').map((item) => item.trim()).filter(Boolean);
296
+ } else if (arg.startsWith('--platform=')) {
297
+ flags.targets = arg.slice('--platform='.length).split(',').map((item) => item.trim()).filter(Boolean);
298
+ } else if (arg.startsWith('--tool=')) {
299
+ flags.targets = arg.slice('--tool='.length).split(',').map((item) => item.trim()).filter(Boolean);
276
300
  } else {
277
301
  positional.push(arg);
278
302
  }
@@ -280,11 +304,31 @@ function parseArgs(argv) {
280
304
  return { command: positional[0] ?? 'install', flags };
281
305
  }
282
306
 
307
+ function normalizeTargetId(value) {
308
+ return String(value).toLowerCase().replace(/[\s_-]+/g, '');
309
+ }
310
+
311
+ function targetIdsForTool(tool) {
312
+ return [tool.name, ...(tool.aliases ?? []), ...(tool.commands ?? [])]
313
+ .map(normalizeTargetId)
314
+ .filter(Boolean);
315
+ }
316
+
283
317
  function selectTools(tools, detections, flags) {
284
318
  if (flags.targets?.length) {
285
- const wanted = new Set(flags.targets.map((target) => target.toLowerCase()));
319
+ const wanted = new Set(flags.targets.map(normalizeTargetId));
286
320
  if (wanted.has('all')) return tools;
287
- return tools.filter((tool) => wanted.has(tool.name.toLowerCase()));
321
+ const selected = tools.filter((tool) => targetIdsForTool(tool).some((id) => wanted.has(id)));
322
+ const matched = new Set(selected.flatMap(targetIdsForTool));
323
+ const unknown = [...wanted].filter((id) => !matched.has(id));
324
+ if (unknown.length > 0) {
325
+ const supported = tools
326
+ .map((tool) => `${tool.name} (${(tool.aliases ?? []).join(', ')})`)
327
+ .join('; ');
328
+ console.warn(`[wow-migrator] Unknown platform target(s): ${unknown.join(', ')}`);
329
+ console.warn(`[wow-migrator] Supported platforms: ${supported}`);
330
+ }
331
+ return selected;
288
332
  }
289
333
  if (flags.yes || flags.postinstall) {
290
334
  return tools.filter((tool) => detections.get(tool.name)?.installed);
@@ -303,13 +347,13 @@ async function confirm(message) {
303
347
  }
304
348
 
305
349
  async function installCommand(flags) {
306
- if (process.env.KMP_SKILLS_SKIP_POSTINSTALL === '1' && flags.postinstall) return;
350
+ if (process.env.WOW_MIGRATOR_SKIP_POSTINSTALL === '1' && flags.postinstall) return;
307
351
 
308
352
  const skillsRoot = await findSkillsRoot();
309
353
  if (!skillsRoot) {
310
354
  const message = 'No bundled KMP skills found. Run `npm run sync:skills` before publishing this package.';
311
355
  if (flags.postinstall) {
312
- console.warn(`[kmp-skills] ${message}`);
356
+ console.warn(`[wow-migrator] ${message}`);
313
357
  return;
314
358
  }
315
359
  throw new Error(message);
@@ -322,7 +366,7 @@ async function installCommand(flags) {
322
366
 
323
367
  const selectedTools = selectTools(tools, detections, flags);
324
368
  if (selectedTools.length === 0) {
325
- console.log('[kmp-skills] No supported AI tools detected. Edit config with `kmp-skills config`.');
369
+ console.log('[wow-migrator] No supported AI tools detected. Edit config with `wow-migrator config`.');
326
370
  return;
327
371
  }
328
372
 
@@ -335,7 +379,7 @@ async function installCommand(flags) {
335
379
  for (const tool of selectedTools) {
336
380
  const targetRoot = await installToTool(tool, skillsRoot, skillNames, flags.dryRun);
337
381
  const detected = detections.get(tool.name)?.installed ? 'detected' : 'custom';
338
- console.log(`[kmp-skills] ${flags.dryRun ? 'Would install' : 'Installed'} ${skillNames.length} skills -> ${tool.name} (${detected}) ${prettyPath(targetRoot)}`);
382
+ console.log(`[wow-migrator] ${flags.dryRun ? 'Would install' : 'Installed'} ${skillNames.length} skills -> ${tool.name} (${detected}) ${prettyPath(targetRoot)}`);
339
383
  }
340
384
  }
341
385
 
@@ -356,7 +400,7 @@ async function uninstallCommand(flags) {
356
400
 
357
401
  for (const tool of selectedTools) {
358
402
  const removed = await uninstallFromTool(tool, skillNames, flags.dryRun);
359
- console.log(`[kmp-skills] ${flags.dryRun ? 'Would remove' : 'Removed'} ${removed} skills from ${tool.name}`);
403
+ console.log(`[wow-migrator] ${flags.dryRun ? 'Would remove' : 'Removed'} ${removed} skills from ${tool.name}`);
360
404
  }
361
405
  }
362
406
 
@@ -374,16 +418,20 @@ async function configCommand() {
374
418
  }
375
419
 
376
420
  function printHelp() {
377
- console.log(`kmp-skills
421
+ console.log(`${CLI_NAME}
378
422
 
379
423
  Usage:
380
- kmp-skills install [--yes] [--target Claude Code,Codex] [--dry-run]
381
- kmp-skills uninstall [--yes] [--target all] [--dry-run]
382
- kmp-skills list
383
- kmp-skills config
424
+ ${CLI_NAME} install [--yes] [--platform claude,cursor] [--dry-run]
425
+ ${CLI_NAME} install [--yes] [--target "Claude Code,Codex"] [--dry-run]
426
+ ${CLI_NAME} uninstall [--yes] [--platform all] [--dry-run]
427
+ ${CLI_NAME} list
428
+ ${CLI_NAME} config
429
+
430
+ Platforms:
431
+ openclaw, claude, opencode, codex, cursor, gemini, jiuwen, all
384
432
 
385
433
  Environment:
386
- KMP_SKILLS_SKIP_POSTINSTALL=1 Skip npm postinstall auto-install.
434
+ WOW_MIGRATOR_SKIP_POSTINSTALL=1 Skip npm postinstall auto-install.
387
435
  `);
388
436
  }
389
437
 
@@ -402,6 +450,6 @@ async function main() {
402
450
 
403
451
  main().catch((error) => {
404
452
  const message = error instanceof Error ? error.message : String(error);
405
- console.error(`[kmp-skills] ${message}`);
453
+ console.error(`[wow-migrator] ${message}`);
406
454
  process.exitCode = 1;
407
455
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-migration/wow-migrator",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Install KMP migration skills into Claude Code, Codex, Cursor, Gemini, OpenCode, OpenClaw, and JiuwenSwarm via npm install.",
5
5
  "keywords": [
6
6
  "android",
@@ -18,10 +18,10 @@
18
18
  "type": "module",
19
19
  "repository": {
20
20
  "type": "git",
21
- "url": "https://github.com/winson-AI/cli-plugins.git"
21
+ "url": "git+https://github.com/winson-AI/cli-plugins.git"
22
22
  },
23
23
  "bin": {
24
- "kmp-skills": "bin/kmp-skills.js"
24
+ "wow-migrator": "bin/wow-migrator.js"
25
25
  },
26
26
  "files": [
27
27
  "bin",
@@ -30,14 +30,22 @@
30
30
  "README.md"
31
31
  ],
32
32
  "scripts": {
33
- "install:skills": "node ./bin/kmp-skills.js install",
34
- "uninstall:skills": "node ./bin/kmp-skills.js uninstall",
35
- "config": "node ./bin/kmp-skills.js config",
36
- "list": "node ./bin/kmp-skills.js list",
33
+ "install:skills": "node ./bin/wow-migrator.js install",
34
+ "install:all": "node ./bin/wow-migrator.js install --target all --yes",
35
+ "install:openclaw": "node ./bin/wow-migrator.js install --platform openclaw --yes",
36
+ "install:claude": "node ./bin/wow-migrator.js install --platform claude --yes",
37
+ "install:opencode": "node ./bin/wow-migrator.js install --platform opencode --yes",
38
+ "install:codex": "node ./bin/wow-migrator.js install --platform codex --yes",
39
+ "install:cursor": "node ./bin/wow-migrator.js install --platform cursor --yes",
40
+ "install:gemini": "node ./bin/wow-migrator.js install --platform gemini --yes",
41
+ "install:jiuwen": "node ./bin/wow-migrator.js install --platform jiuwen --yes",
42
+ "uninstall:skills": "node ./bin/wow-migrator.js uninstall",
43
+ "config": "node ./bin/wow-migrator.js config",
44
+ "list": "node ./bin/wow-migrator.js list",
37
45
  "sync:skills": "node ./scripts/sync-skills.js",
38
46
  "prepare": "node ./scripts/sync-skills.js --if-present",
39
47
  "prepack": "node ./scripts/sync-skills.js",
40
- "postinstall": "node ./bin/kmp-skills.js install --yes --postinstall"
48
+ "postinstall": "node ./bin/wow-migrator.js install --yes --postinstall"
41
49
  },
42
50
  "engines": {
43
51
  "node": ">=18.0.0"