ccraft 1.0.0
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/bin/claude-craft.js +85 -0
- package/package.json +39 -0
- package/src/commands/auth.js +43 -0
- package/src/commands/create.js +543 -0
- package/src/commands/install.js +480 -0
- package/src/commands/logout.js +24 -0
- package/src/commands/update.js +339 -0
- package/src/constants.js +299 -0
- package/src/generators/directories.js +30 -0
- package/src/generators/metadata.js +57 -0
- package/src/generators/security.js +39 -0
- package/src/prompts/gather.js +308 -0
- package/src/ui/brand.js +62 -0
- package/src/ui/cards.js +179 -0
- package/src/ui/format.js +55 -0
- package/src/ui/phase-header.js +20 -0
- package/src/ui/prompts.js +56 -0
- package/src/ui/tables.js +89 -0
- package/src/ui/tasks.js +258 -0
- package/src/ui/theme.js +83 -0
- package/src/utils/analysis-cache.js +519 -0
- package/src/utils/api-client.js +253 -0
- package/src/utils/api-file-writer.js +197 -0
- package/src/utils/bootstrap-runner.js +148 -0
- package/src/utils/claude-analyzer.js +255 -0
- package/src/utils/claude-optimizer.js +341 -0
- package/src/utils/claude-rewriter.js +553 -0
- package/src/utils/claude-scorer.js +101 -0
- package/src/utils/description-analyzer.js +116 -0
- package/src/utils/detect-project.js +1276 -0
- package/src/utils/existing-setup.js +341 -0
- package/src/utils/file-writer.js +64 -0
- package/src/utils/json-extract.js +56 -0
- package/src/utils/logger.js +27 -0
- package/src/utils/mcp-setup.js +461 -0
- package/src/utils/preflight.js +112 -0
- package/src/utils/prompt-api-key.js +59 -0
- package/src/utils/run-claude.js +152 -0
- package/src/utils/security.js +82 -0
- package/src/utils/toolkit-rule-generator.js +364 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const [major] = process.versions.node.split('.').map(Number);
|
|
4
|
+
if (major < 18) {
|
|
5
|
+
console.error('claude-craft requires Node.js >= 18. Current: ' + process.version);
|
|
6
|
+
process.exit(1);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Load .env files (lightweight, no dependency)
|
|
10
|
+
import { readFileSync } from 'fs';
|
|
11
|
+
import { resolve as resolvePath } from 'path';
|
|
12
|
+
|
|
13
|
+
function loadEnvFile(filePath) {
|
|
14
|
+
try {
|
|
15
|
+
const content = readFileSync(filePath, 'utf8');
|
|
16
|
+
for (const line of content.split('\n')) {
|
|
17
|
+
const trimmed = line.trim();
|
|
18
|
+
if (!trimmed || trimmed.startsWith('#')) continue;
|
|
19
|
+
const eqIdx = trimmed.indexOf('=');
|
|
20
|
+
if (eqIdx === -1) continue;
|
|
21
|
+
const key = trimmed.slice(0, eqIdx).trim();
|
|
22
|
+
const value = trimmed.slice(eqIdx + 1).trim();
|
|
23
|
+
if (!process.env[key]) process.env[key] = value;
|
|
24
|
+
}
|
|
25
|
+
} catch {}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// .env.development takes priority in dev, then .env as fallback
|
|
29
|
+
const cliRoot = resolvePath(import.meta.dirname, '..');
|
|
30
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
31
|
+
loadEnvFile(resolvePath(cliRoot, '.env.development'));
|
|
32
|
+
}
|
|
33
|
+
loadEnvFile(resolvePath(cliRoot, '.env'));
|
|
34
|
+
|
|
35
|
+
import { Command } from 'commander';
|
|
36
|
+
import { VERSION, PRESET_ALIASES } from '../src/constants.js';
|
|
37
|
+
import { runInstall } from '../src/commands/install.js';
|
|
38
|
+
import { runCreate } from '../src/commands/create.js';
|
|
39
|
+
import { runUpdate } from '../src/commands/update.js';
|
|
40
|
+
import { runAuth } from '../src/commands/auth.js';
|
|
41
|
+
import { runLogout } from '../src/commands/logout.js';
|
|
42
|
+
|
|
43
|
+
const program = new Command();
|
|
44
|
+
|
|
45
|
+
program
|
|
46
|
+
.name('claude-craft')
|
|
47
|
+
.description('Scaffold Claude Code project structure')
|
|
48
|
+
.version(VERSION);
|
|
49
|
+
|
|
50
|
+
program
|
|
51
|
+
.command('auth <key>')
|
|
52
|
+
.description('Store API key for claude-craft server')
|
|
53
|
+
.option('-s, --server <url>', 'Server URL (default: https://api.claude-craft.dev)')
|
|
54
|
+
.action(runAuth);
|
|
55
|
+
|
|
56
|
+
program
|
|
57
|
+
.command('logout')
|
|
58
|
+
.description('Remove stored API key')
|
|
59
|
+
.action(runLogout);
|
|
60
|
+
|
|
61
|
+
program
|
|
62
|
+
.command('create')
|
|
63
|
+
.description('Create a new project from scratch with Claude scaffolding')
|
|
64
|
+
.option('-y, --yes', 'Accept all defaults (non-interactive)')
|
|
65
|
+
.option('-n, --name <name>', 'Project name (non-interactive mode)')
|
|
66
|
+
.option('--description <text>', 'Project description (non-interactive mode)')
|
|
67
|
+
.option('-d, --dir <path>', 'Parent directory to create the project in (default: cwd)')
|
|
68
|
+
.action(runCreate);
|
|
69
|
+
|
|
70
|
+
program
|
|
71
|
+
.command('install', { isDefault: true })
|
|
72
|
+
.description('Generate Claude Code configuration files in the current project')
|
|
73
|
+
.option('-y, --yes', 'Accept all defaults (non-interactive)')
|
|
74
|
+
.option(`-p, --preset <preset>`, `Apply a framework preset (${Object.keys(PRESET_ALIASES).join(', ')})`)
|
|
75
|
+
.option('-d, --dir <path>', 'Target directory (default: cwd)')
|
|
76
|
+
.action(runInstall);
|
|
77
|
+
|
|
78
|
+
program
|
|
79
|
+
.command('update')
|
|
80
|
+
.description('Re-analyze project and install any new components for detected stack changes')
|
|
81
|
+
.option('-y, --yes', 'Accept all defaults (non-interactive)')
|
|
82
|
+
.option('-d, --dir <path>', 'Target directory (default: cwd)')
|
|
83
|
+
.action(runUpdate);
|
|
84
|
+
|
|
85
|
+
program.parse();
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ccraft",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Intelligent Claude Code project configurator — role-aware agents, skills, rules, MCPs, and workflows",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"claude-craft": "./bin/claude-craft.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"src/"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"test": "echo \"No tests yet\" && exit 0"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"claude",
|
|
18
|
+
"claude-code",
|
|
19
|
+
"scaffolding",
|
|
20
|
+
"cli"
|
|
21
|
+
],
|
|
22
|
+
"author": "",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=18"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@inquirer/prompts": "^7.10.1",
|
|
29
|
+
"boxen": "^8.0.1",
|
|
30
|
+
"chalk": "^5.6.2",
|
|
31
|
+
"cli-table3": "^0.6.5",
|
|
32
|
+
"commander": "^12.1.0",
|
|
33
|
+
"figlet": "^1.11.0",
|
|
34
|
+
"fs-extra": "^11.3.4",
|
|
35
|
+
"gradient-string": "^3.0.0",
|
|
36
|
+
"listr2": "^10.2.1",
|
|
37
|
+
"ora": "^8.2.0"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth command — store API key for claude-craft server.
|
|
3
|
+
*
|
|
4
|
+
* Usage: claude-craft auth <key> [-s <server-url>]
|
|
5
|
+
*/
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import { validateKey, saveConfig, loadConfig, ApiError } from '../utils/api-client.js';
|
|
8
|
+
import * as logger from '../utils/logger.js';
|
|
9
|
+
|
|
10
|
+
export async function runAuth(key, options = {}) {
|
|
11
|
+
const serverUrl = options.server || process.env.CLAUDE_CRAFT_SERVER_URL || 'https://api.claude-craft.dev';
|
|
12
|
+
|
|
13
|
+
if (!key.startsWith('ck_live_')) {
|
|
14
|
+
logger.error('Invalid key format. API keys must start with ' + chalk.bold('ck_live_'));
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
console.log();
|
|
19
|
+
console.log(chalk.dim(' Validating API key against ' + serverUrl + '...'));
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
const valid = await validateKey(key, serverUrl);
|
|
23
|
+
if (!valid) {
|
|
24
|
+
logger.error('API key is not valid. Check the key and try again.');
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
} catch (err) {
|
|
28
|
+
if (err instanceof ApiError && err.code === 'NETWORK_ERROR') {
|
|
29
|
+
logger.error('Could not reach server at ' + chalk.bold(serverUrl));
|
|
30
|
+
console.log(chalk.dim(' Ensure the server is running, or specify a different URL with -s <url>'));
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
throw err;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const existing = loadConfig() || {};
|
|
37
|
+
saveConfig({ ...existing, apiKey: key, serverUrl });
|
|
38
|
+
|
|
39
|
+
console.log();
|
|
40
|
+
logger.success('API key saved to ~/.claude-craft/config.json');
|
|
41
|
+
console.log(chalk.dim(' Server: ' + serverUrl));
|
|
42
|
+
console.log();
|
|
43
|
+
}
|