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.
Files changed (40) hide show
  1. package/bin/claude-craft.js +85 -0
  2. package/package.json +39 -0
  3. package/src/commands/auth.js +43 -0
  4. package/src/commands/create.js +543 -0
  5. package/src/commands/install.js +480 -0
  6. package/src/commands/logout.js +24 -0
  7. package/src/commands/update.js +339 -0
  8. package/src/constants.js +299 -0
  9. package/src/generators/directories.js +30 -0
  10. package/src/generators/metadata.js +57 -0
  11. package/src/generators/security.js +39 -0
  12. package/src/prompts/gather.js +308 -0
  13. package/src/ui/brand.js +62 -0
  14. package/src/ui/cards.js +179 -0
  15. package/src/ui/format.js +55 -0
  16. package/src/ui/phase-header.js +20 -0
  17. package/src/ui/prompts.js +56 -0
  18. package/src/ui/tables.js +89 -0
  19. package/src/ui/tasks.js +258 -0
  20. package/src/ui/theme.js +83 -0
  21. package/src/utils/analysis-cache.js +519 -0
  22. package/src/utils/api-client.js +253 -0
  23. package/src/utils/api-file-writer.js +197 -0
  24. package/src/utils/bootstrap-runner.js +148 -0
  25. package/src/utils/claude-analyzer.js +255 -0
  26. package/src/utils/claude-optimizer.js +341 -0
  27. package/src/utils/claude-rewriter.js +553 -0
  28. package/src/utils/claude-scorer.js +101 -0
  29. package/src/utils/description-analyzer.js +116 -0
  30. package/src/utils/detect-project.js +1276 -0
  31. package/src/utils/existing-setup.js +341 -0
  32. package/src/utils/file-writer.js +64 -0
  33. package/src/utils/json-extract.js +56 -0
  34. package/src/utils/logger.js +27 -0
  35. package/src/utils/mcp-setup.js +461 -0
  36. package/src/utils/preflight.js +112 -0
  37. package/src/utils/prompt-api-key.js +59 -0
  38. package/src/utils/run-claude.js +152 -0
  39. package/src/utils/security.js +82 -0
  40. 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
+ }