claude-code-pack 1.2.0 → 1.2.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 +3 -3
- package/claude-pack.config.json +28 -2
- package/package.json +1 -1
- package/src/install.mjs +48 -55
package/README.md
CHANGED
|
@@ -96,10 +96,10 @@ Everything is fetched fresh from GitHub, so you always get the latest version.
|
|
|
96
96
|
|
|
97
97
|
The installer also generates a `~/.codex/config.toml` that **reuses the same MCP servers and skills** as Claude Code — no duplicate configuration needed.
|
|
98
98
|
|
|
99
|
-
| What | How it
|
|
100
|
-
|
|
99
|
+
| What | How it works |
|
|
100
|
+
|------|-------------|
|
|
101
101
|
| **MCP servers** | Generated into `config.toml` from the same `mcpServers` in `claude-pack.config.json` |
|
|
102
|
-
| **Skills** |
|
|
102
|
+
| **Skills** | Installed to both `~/.claude/skills/` (Claude Code) and `~/.codex/skills/` (Codex) from the same bundled source |
|
|
103
103
|
|
|
104
104
|
This means when you add a new MCP server or skill to the pack, both Claude Code and Codex pick it up.
|
|
105
105
|
|
package/claude-pack.config.json
CHANGED
|
@@ -76,6 +76,33 @@
|
|
|
76
76
|
"args": [
|
|
77
77
|
"mcp-server-time"
|
|
78
78
|
]
|
|
79
|
+
},
|
|
80
|
+
"playwright": {
|
|
81
|
+
"command": "npx",
|
|
82
|
+
"args": ["-y", "@playwright/mcp@latest"]
|
|
83
|
+
},
|
|
84
|
+
"aws_knowledge_mcp": {
|
|
85
|
+
"type": "http",
|
|
86
|
+
"url": "https://knowledge-mcp.global.api.aws"
|
|
87
|
+
},
|
|
88
|
+
"awslabs_core_mcp_server": {
|
|
89
|
+
"command": "uvx",
|
|
90
|
+
"args": ["awslabs.core-mcp-server@latest"],
|
|
91
|
+
"env": { "FASTMCP_LOG_LEVEL": "ERROR" }
|
|
92
|
+
},
|
|
93
|
+
"awslabs_aws_api_mcp_server": {
|
|
94
|
+
"command": "uvx",
|
|
95
|
+
"args": ["awslabs.aws-api-mcp-server@latest"],
|
|
96
|
+
"env": { "AWS_REGION": "us-east-1" }
|
|
97
|
+
},
|
|
98
|
+
"awslabs_aws_documentation_mcp_server": {
|
|
99
|
+
"command": "uvx",
|
|
100
|
+
"args": ["awslabs.aws-documentation-mcp-server@latest"],
|
|
101
|
+
"env": { "FASTMCP_LOG_LEVEL": "ERROR", "AWS_DOCUMENTATION_PARTITION": "aws" }
|
|
102
|
+
},
|
|
103
|
+
"exa": {
|
|
104
|
+
"command": "npx",
|
|
105
|
+
"args": ["-y", "exa-mcp-server"]
|
|
79
106
|
}
|
|
80
107
|
},
|
|
81
108
|
"settings": {
|
|
@@ -92,7 +119,6 @@
|
|
|
92
119
|
"enabled": true,
|
|
93
120
|
"model": "gpt-5.4",
|
|
94
121
|
"model_reasoning_effort": "xhigh",
|
|
95
|
-
"configPath": "$HOME/.codex/config.toml"
|
|
96
|
-
"skillsPath": "$HOME/.claude/skills"
|
|
122
|
+
"configPath": "$HOME/.codex/config.toml"
|
|
97
123
|
}
|
|
98
124
|
}
|
package/package.json
CHANGED
package/src/install.mjs
CHANGED
|
@@ -13,6 +13,8 @@ const PLUGINS_DIR = join(CLAUDE_DIR, 'plugins');
|
|
|
13
13
|
const MARKETPLACES_DIR = join(PLUGINS_DIR, 'marketplaces');
|
|
14
14
|
const CACHE_DIR = join(PLUGINS_DIR, 'cache');
|
|
15
15
|
const SKILLS_DIR = join(CLAUDE_DIR, 'skills');
|
|
16
|
+
const CODEX_DIR = join(homedir(), '.codex');
|
|
17
|
+
const CODEX_SKILLS_DIR = join(CODEX_DIR, 'skills');
|
|
16
18
|
const SETTINGS_PATH = join(CLAUDE_DIR, 'settings.json');
|
|
17
19
|
const KNOWN_MARKETPLACES_PATH = join(PLUGINS_DIR, 'known_marketplaces.json');
|
|
18
20
|
const INSTALLED_PLUGINS_PATH = join(PLUGINS_DIR, 'installed_plugins.json');
|
|
@@ -264,56 +266,55 @@ function installPlugins(config, flags) {
|
|
|
264
266
|
|
|
265
267
|
// ─── Skill Installation ────────────────────────────────────────────────
|
|
266
268
|
|
|
267
|
-
function
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
for (const skill of config.skills || []) {
|
|
271
|
-
const dest = join(SKILLS_DIR, skill.name);
|
|
272
|
-
const exists = existsSync(dest);
|
|
273
|
-
|
|
274
|
-
if (skill.source === 'bundled') {
|
|
275
|
-
// Copy from package's bundled skills/
|
|
276
|
-
const src = join(PACK_ROOT, 'skills', skill.name);
|
|
277
|
-
if (!existsSync(src)) {
|
|
278
|
-
log('✗', `Skill "${skill.name}": bundled source not found at ${src}`);
|
|
279
|
-
continue;
|
|
280
|
-
}
|
|
269
|
+
function installSkillTo(skill, targetDir, label, flags) {
|
|
270
|
+
const dest = join(targetDir, skill.name);
|
|
271
|
+
const exists = existsSync(dest);
|
|
281
272
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
if (
|
|
300
|
-
|
|
301
|
-
log('●', `Skill "${skill.name}": already installed`);
|
|
302
|
-
} else {
|
|
303
|
-
log('↻', `Updating skill "${skill.name}" from ${skill.repo}...`);
|
|
304
|
-
gitClone(skill.repo, dest);
|
|
305
|
-
}
|
|
273
|
+
if (skill.source === 'bundled') {
|
|
274
|
+
const src = join(PACK_ROOT, 'skills', skill.name);
|
|
275
|
+
if (!existsSync(src)) {
|
|
276
|
+
log('✗', `${label} "${skill.name}": bundled source not found`);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
if (exists && !flags.force) {
|
|
280
|
+
log('●', `${label} "${skill.name}": already installed`);
|
|
281
|
+
} else if (flags.dryRun) {
|
|
282
|
+
log('○', `Would install bundled skill "${skill.name}" to ${label}`);
|
|
283
|
+
} else {
|
|
284
|
+
ensureDir(targetDir);
|
|
285
|
+
cpSync(src, dest, { recursive: true });
|
|
286
|
+
log('✓', `${label} "${skill.name}" installed`);
|
|
287
|
+
}
|
|
288
|
+
} else if (skill.source === 'github' && skill.repo) {
|
|
289
|
+
if (exists && !flags.force) {
|
|
290
|
+
if (flags.dryRun) {
|
|
291
|
+
log('●', `${label} "${skill.name}": already installed`);
|
|
306
292
|
} else {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
} else {
|
|
310
|
-
log('↓', `Cloning skill "${skill.name}" from ${skill.repo}...`);
|
|
311
|
-
const result = gitClone(skill.repo, dest);
|
|
312
|
-
log('✓', `Skill "${skill.name}" ${result}`);
|
|
313
|
-
}
|
|
293
|
+
log('↻', `Updating ${label} "${skill.name}" from ${skill.repo}...`);
|
|
294
|
+
gitClone(skill.repo, dest);
|
|
314
295
|
}
|
|
296
|
+
} else if (flags.dryRun) {
|
|
297
|
+
log('○', `Would clone skill "${skill.name}" to ${label}`);
|
|
315
298
|
} else {
|
|
316
|
-
log('
|
|
299
|
+
log('↓', `Cloning ${label} "${skill.name}" from ${skill.repo}...`);
|
|
300
|
+
const result = gitClone(skill.repo, dest);
|
|
301
|
+
log('✓', `${label} "${skill.name}" ${result}`);
|
|
302
|
+
}
|
|
303
|
+
} else {
|
|
304
|
+
log('✗', `${label} "${skill.name}": unknown source "${skill.source}"`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function installSkills(config, flags) {
|
|
309
|
+
console.log('\n🛠 Skills (Claude Code → ~/.claude/skills/)');
|
|
310
|
+
for (const skill of config.skills || []) {
|
|
311
|
+
installSkillTo(skill, SKILLS_DIR, 'Claude', flags);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (!flags.skipCodex && config.codex?.enabled) {
|
|
315
|
+
console.log('\n🛠 Skills (Codex → ~/.codex/skills/)');
|
|
316
|
+
for (const skill of config.skills || []) {
|
|
317
|
+
installSkillTo(skill, CODEX_SKILLS_DIR, 'Codex', flags);
|
|
317
318
|
}
|
|
318
319
|
}
|
|
319
320
|
}
|
|
@@ -483,13 +484,6 @@ function generateCodexToml(config, resolvedFsPath) {
|
|
|
483
484
|
lines.push('');
|
|
484
485
|
}
|
|
485
486
|
|
|
486
|
-
// Skills — point to the shared ~/.claude/skills directory
|
|
487
|
-
const skillsPath = (codex.skillsPath || '$HOME/.claude/skills').replace(/\$HOME/g, home);
|
|
488
|
-
lines.push('[[skills.config]]');
|
|
489
|
-
lines.push(`path = "${skillsPath}"`);
|
|
490
|
-
lines.push('enabled = true');
|
|
491
|
-
lines.push('');
|
|
492
|
-
|
|
493
487
|
return lines.join('\n');
|
|
494
488
|
}
|
|
495
489
|
|
|
@@ -505,7 +499,6 @@ async function installCodex(config, flags, resolvedFsPath) {
|
|
|
505
499
|
if (flags.dryRun) {
|
|
506
500
|
log('○', `Would generate Codex config at ${configPath}`);
|
|
507
501
|
log('○', `Model: ${config.codex.model}`);
|
|
508
|
-
log('○', `Skills path: ~/.claude/skills (shared with Claude Code)`);
|
|
509
502
|
const mcpCount = Object.keys(config.mcpServers || {}).length;
|
|
510
503
|
log('○', `MCP servers: ${mcpCount} (same as Claude Code)`);
|
|
511
504
|
return;
|
|
@@ -526,7 +519,7 @@ async function installCodex(config, flags, resolvedFsPath) {
|
|
|
526
519
|
writeFileSync(configPath, toml);
|
|
527
520
|
log('✓', `Codex config written to ${configPath}`);
|
|
528
521
|
log('✓', `Model: ${config.codex.model}`);
|
|
529
|
-
log('✓', `Skills: ~/.
|
|
522
|
+
log('✓', `Skills: ~/.codex/skills/ (installed separately)`);
|
|
530
523
|
log('✓', `MCP servers: ${Object.keys(config.mcpServers || {}).length} configured`);
|
|
531
524
|
}
|
|
532
525
|
|