cc4pm 1.8.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/.claude-plugin/README.md +17 -0
- package/.claude-plugin/plugin.json +25 -0
- package/LICENSE +21 -0
- package/README.md +157 -0
- package/README.zh-CN.md +134 -0
- package/contexts/dev.md +20 -0
- package/contexts/research.md +26 -0
- package/contexts/review.md +22 -0
- package/examples/CLAUDE.md +100 -0
- package/examples/statusline.json +19 -0
- package/examples/user-CLAUDE.md +109 -0
- package/install.sh +17 -0
- package/manifests/install-components.json +173 -0
- package/manifests/install-modules.json +335 -0
- package/manifests/install-profiles.json +75 -0
- package/package.json +117 -0
- package/schemas/ecc-install-config.schema.json +58 -0
- package/schemas/hooks.schema.json +197 -0
- package/schemas/install-components.schema.json +56 -0
- package/schemas/install-modules.schema.json +105 -0
- package/schemas/install-profiles.schema.json +45 -0
- package/schemas/install-state.schema.json +210 -0
- package/schemas/package-manager.schema.json +23 -0
- package/schemas/plugin.schema.json +58 -0
- package/scripts/ci/catalog.js +83 -0
- package/scripts/ci/validate-agents.js +81 -0
- package/scripts/ci/validate-commands.js +135 -0
- package/scripts/ci/validate-hooks.js +239 -0
- package/scripts/ci/validate-install-manifests.js +211 -0
- package/scripts/ci/validate-no-personal-paths.js +63 -0
- package/scripts/ci/validate-rules.js +81 -0
- package/scripts/ci/validate-skills.js +54 -0
- package/scripts/claw.js +468 -0
- package/scripts/doctor.js +110 -0
- package/scripts/ecc.js +194 -0
- package/scripts/hooks/auto-tmux-dev.js +88 -0
- package/scripts/hooks/check-console-log.js +71 -0
- package/scripts/hooks/check-hook-enabled.js +12 -0
- package/scripts/hooks/cost-tracker.js +78 -0
- package/scripts/hooks/doc-file-warning.js +63 -0
- package/scripts/hooks/evaluate-session.js +100 -0
- package/scripts/hooks/insaits-security-monitor.py +269 -0
- package/scripts/hooks/insaits-security-wrapper.js +88 -0
- package/scripts/hooks/post-bash-build-complete.js +27 -0
- package/scripts/hooks/post-bash-pr-created.js +36 -0
- package/scripts/hooks/post-edit-console-warn.js +54 -0
- package/scripts/hooks/post-edit-format.js +109 -0
- package/scripts/hooks/post-edit-typecheck.js +96 -0
- package/scripts/hooks/pre-bash-dev-server-block.js +187 -0
- package/scripts/hooks/pre-bash-git-push-reminder.js +28 -0
- package/scripts/hooks/pre-bash-tmux-reminder.js +33 -0
- package/scripts/hooks/pre-compact.js +48 -0
- package/scripts/hooks/pre-write-doc-warn.js +9 -0
- package/scripts/hooks/quality-gate.js +168 -0
- package/scripts/hooks/run-with-flags-shell.sh +32 -0
- package/scripts/hooks/run-with-flags.js +120 -0
- package/scripts/hooks/session-end-marker.js +15 -0
- package/scripts/hooks/session-end.js +299 -0
- package/scripts/hooks/session-start.js +97 -0
- package/scripts/hooks/suggest-compact.js +80 -0
- package/scripts/install-apply.js +137 -0
- package/scripts/install-plan.js +254 -0
- package/scripts/lib/hook-flags.js +74 -0
- package/scripts/lib/install/apply.js +23 -0
- package/scripts/lib/install/config.js +82 -0
- package/scripts/lib/install/request.js +113 -0
- package/scripts/lib/install/runtime.js +42 -0
- package/scripts/lib/install-executor.js +605 -0
- package/scripts/lib/install-lifecycle.js +763 -0
- package/scripts/lib/install-manifests.js +305 -0
- package/scripts/lib/install-state.js +120 -0
- package/scripts/lib/install-targets/antigravity-project.js +9 -0
- package/scripts/lib/install-targets/claude-home.js +10 -0
- package/scripts/lib/install-targets/codex-home.js +10 -0
- package/scripts/lib/install-targets/cursor-project.js +10 -0
- package/scripts/lib/install-targets/helpers.js +89 -0
- package/scripts/lib/install-targets/opencode-home.js +10 -0
- package/scripts/lib/install-targets/registry.js +64 -0
- package/scripts/lib/orchestration-session.js +299 -0
- package/scripts/lib/package-manager.d.ts +119 -0
- package/scripts/lib/package-manager.js +431 -0
- package/scripts/lib/project-detect.js +428 -0
- package/scripts/lib/resolve-formatter.js +185 -0
- package/scripts/lib/session-adapters/canonical-session.js +138 -0
- package/scripts/lib/session-adapters/claude-history.js +149 -0
- package/scripts/lib/session-adapters/dmux-tmux.js +80 -0
- package/scripts/lib/session-adapters/registry.js +111 -0
- package/scripts/lib/session-aliases.d.ts +136 -0
- package/scripts/lib/session-aliases.js +481 -0
- package/scripts/lib/session-manager.d.ts +131 -0
- package/scripts/lib/session-manager.js +464 -0
- package/scripts/lib/shell-split.js +86 -0
- package/scripts/lib/skill-improvement/amendify.js +89 -0
- package/scripts/lib/skill-improvement/evaluate.js +59 -0
- package/scripts/lib/skill-improvement/health.js +118 -0
- package/scripts/lib/skill-improvement/observations.js +108 -0
- package/scripts/lib/tmux-worktree-orchestrator.js +491 -0
- package/scripts/lib/utils.d.ts +183 -0
- package/scripts/lib/utils.js +543 -0
- package/scripts/list-installed.js +90 -0
- package/scripts/orchestrate-codex-worker.sh +92 -0
- package/scripts/orchestrate-worktrees.js +108 -0
- package/scripts/orchestration-status.js +62 -0
- package/scripts/repair.js +97 -0
- package/scripts/session-inspect.js +150 -0
- package/scripts/setup-package-manager.js +204 -0
- package/scripts/skill-create-output.js +244 -0
- package/scripts/uninstall.js +96 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Package Manager Setup Script
|
|
4
|
+
*
|
|
5
|
+
* Interactive script to configure preferred package manager.
|
|
6
|
+
* Can be run directly or via the /setup-pm command.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* node scripts/setup-package-manager.js [pm-name]
|
|
10
|
+
* node scripts/setup-package-manager.js --detect
|
|
11
|
+
* node scripts/setup-package-manager.js --global pnpm
|
|
12
|
+
* node scripts/setup-package-manager.js --project bun
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const {
|
|
16
|
+
PACKAGE_MANAGERS,
|
|
17
|
+
getPackageManager,
|
|
18
|
+
setPreferredPackageManager,
|
|
19
|
+
setProjectPackageManager,
|
|
20
|
+
getAvailablePackageManagers,
|
|
21
|
+
detectFromLockFile,
|
|
22
|
+
detectFromPackageJson
|
|
23
|
+
} = require('./lib/package-manager');
|
|
24
|
+
|
|
25
|
+
function showHelp() {
|
|
26
|
+
console.log(`
|
|
27
|
+
Package Manager Setup for Claude Code
|
|
28
|
+
|
|
29
|
+
Usage:
|
|
30
|
+
node scripts/setup-package-manager.js [options] [package-manager]
|
|
31
|
+
|
|
32
|
+
Options:
|
|
33
|
+
--detect Detect and show current package manager
|
|
34
|
+
--global <pm> Set global preference (saves to ~/.claude/package-manager.json)
|
|
35
|
+
--project <pm> Set project preference (saves to .claude/package-manager.json)
|
|
36
|
+
--list List available package managers
|
|
37
|
+
--help Show this help message
|
|
38
|
+
|
|
39
|
+
Package Managers:
|
|
40
|
+
npm Node Package Manager (default with Node.js)
|
|
41
|
+
pnpm Fast, disk space efficient package manager
|
|
42
|
+
yarn Classic Yarn package manager
|
|
43
|
+
bun All-in-one JavaScript runtime & toolkit
|
|
44
|
+
|
|
45
|
+
Examples:
|
|
46
|
+
# Detect current package manager
|
|
47
|
+
node scripts/setup-package-manager.js --detect
|
|
48
|
+
|
|
49
|
+
# Set pnpm as global preference
|
|
50
|
+
node scripts/setup-package-manager.js --global pnpm
|
|
51
|
+
|
|
52
|
+
# Set bun for current project
|
|
53
|
+
node scripts/setup-package-manager.js --project bun
|
|
54
|
+
|
|
55
|
+
# List available package managers
|
|
56
|
+
node scripts/setup-package-manager.js --list
|
|
57
|
+
`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function detectAndShow() {
|
|
61
|
+
const pm = getPackageManager();
|
|
62
|
+
const available = getAvailablePackageManagers();
|
|
63
|
+
const fromLock = detectFromLockFile();
|
|
64
|
+
const fromPkg = detectFromPackageJson();
|
|
65
|
+
|
|
66
|
+
console.log('\n=== Package Manager Detection ===\n');
|
|
67
|
+
|
|
68
|
+
console.log('Current selection:');
|
|
69
|
+
console.log(` Package Manager: ${pm.name}`);
|
|
70
|
+
console.log(` Source: ${pm.source}`);
|
|
71
|
+
console.log('');
|
|
72
|
+
|
|
73
|
+
console.log('Detection results:');
|
|
74
|
+
console.log(` From package.json: ${fromPkg || 'not specified'}`);
|
|
75
|
+
console.log(` From lock file: ${fromLock || 'not found'}`);
|
|
76
|
+
console.log(` Environment var: ${process.env.CLAUDE_PACKAGE_MANAGER || 'not set'}`);
|
|
77
|
+
console.log('');
|
|
78
|
+
|
|
79
|
+
console.log('Available package managers:');
|
|
80
|
+
for (const pmName of Object.keys(PACKAGE_MANAGERS)) {
|
|
81
|
+
const installed = available.includes(pmName);
|
|
82
|
+
const indicator = installed ? '✓' : '✗';
|
|
83
|
+
const current = pmName === pm.name ? ' (current)' : '';
|
|
84
|
+
console.log(` ${indicator} ${pmName}${current}`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
console.log('');
|
|
88
|
+
console.log('Commands:');
|
|
89
|
+
console.log(` Install: ${pm.config.installCmd}`);
|
|
90
|
+
console.log(` Run script: ${pm.config.runCmd} [script-name]`);
|
|
91
|
+
console.log(` Execute binary: ${pm.config.execCmd} [binary-name]`);
|
|
92
|
+
console.log('');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function listAvailable() {
|
|
96
|
+
const available = getAvailablePackageManagers();
|
|
97
|
+
const pm = getPackageManager();
|
|
98
|
+
|
|
99
|
+
console.log('\nAvailable Package Managers:\n');
|
|
100
|
+
|
|
101
|
+
for (const pmName of Object.keys(PACKAGE_MANAGERS)) {
|
|
102
|
+
const config = PACKAGE_MANAGERS[pmName];
|
|
103
|
+
const installed = available.includes(pmName);
|
|
104
|
+
const current = pmName === pm.name ? ' (current)' : '';
|
|
105
|
+
|
|
106
|
+
console.log(`${pmName}${current}`);
|
|
107
|
+
console.log(` Installed: ${installed ? 'Yes' : 'No'}`);
|
|
108
|
+
console.log(` Lock file: ${config.lockFile}`);
|
|
109
|
+
console.log(` Install: ${config.installCmd}`);
|
|
110
|
+
console.log(` Run: ${config.runCmd}`);
|
|
111
|
+
console.log('');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function setGlobal(pmName) {
|
|
116
|
+
if (!PACKAGE_MANAGERS[pmName]) {
|
|
117
|
+
console.error(`Error: Unknown package manager "${pmName}"`);
|
|
118
|
+
console.error(`Available: ${Object.keys(PACKAGE_MANAGERS).join(', ')}`);
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const available = getAvailablePackageManagers();
|
|
123
|
+
if (!available.includes(pmName)) {
|
|
124
|
+
console.warn(`Warning: ${pmName} is not installed on your system`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
setPreferredPackageManager(pmName);
|
|
129
|
+
console.log(`\n✓ Global preference set to: ${pmName}`);
|
|
130
|
+
console.log(' Saved to: ~/.claude/package-manager.json');
|
|
131
|
+
console.log('');
|
|
132
|
+
} catch (err) {
|
|
133
|
+
console.error(`Error: ${err.message}`);
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function setProject(pmName) {
|
|
139
|
+
if (!PACKAGE_MANAGERS[pmName]) {
|
|
140
|
+
console.error(`Error: Unknown package manager "${pmName}"`);
|
|
141
|
+
console.error(`Available: ${Object.keys(PACKAGE_MANAGERS).join(', ')}`);
|
|
142
|
+
process.exit(1);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
setProjectPackageManager(pmName);
|
|
147
|
+
console.log(`\n✓ Project preference set to: ${pmName}`);
|
|
148
|
+
console.log(' Saved to: .claude/package-manager.json');
|
|
149
|
+
console.log('');
|
|
150
|
+
} catch (err) {
|
|
151
|
+
console.error(`Error: ${err.message}`);
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Main
|
|
157
|
+
const args = process.argv.slice(2);
|
|
158
|
+
|
|
159
|
+
if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
|
|
160
|
+
showHelp();
|
|
161
|
+
process.exit(0);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (args.includes('--detect')) {
|
|
165
|
+
detectAndShow();
|
|
166
|
+
process.exit(0);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (args.includes('--list')) {
|
|
170
|
+
listAvailable();
|
|
171
|
+
process.exit(0);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const globalIdx = args.indexOf('--global');
|
|
175
|
+
if (globalIdx !== -1) {
|
|
176
|
+
const pmName = args[globalIdx + 1];
|
|
177
|
+
if (!pmName || pmName.startsWith('-')) {
|
|
178
|
+
console.error('Error: --global requires a package manager name');
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
setGlobal(pmName);
|
|
182
|
+
process.exit(0);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const projectIdx = args.indexOf('--project');
|
|
186
|
+
if (projectIdx !== -1) {
|
|
187
|
+
const pmName = args[projectIdx + 1];
|
|
188
|
+
if (!pmName || pmName.startsWith('-')) {
|
|
189
|
+
console.error('Error: --project requires a package manager name');
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
setProject(pmName);
|
|
193
|
+
process.exit(0);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// If just a package manager name is provided, set it globally
|
|
197
|
+
const pmName = args[0];
|
|
198
|
+
if (PACKAGE_MANAGERS[pmName]) {
|
|
199
|
+
setGlobal(pmName);
|
|
200
|
+
} else {
|
|
201
|
+
console.error(`Error: Unknown option or package manager "${pmName}"`);
|
|
202
|
+
showHelp();
|
|
203
|
+
process.exit(1);
|
|
204
|
+
}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Skill Creator - Pretty Output Formatter
|
|
4
|
+
*
|
|
5
|
+
* Creates beautiful terminal output for the /skill-create command
|
|
6
|
+
* similar to @mvanhorn's /last30days skill
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// ANSI color codes - no external dependencies
|
|
10
|
+
const chalk = {
|
|
11
|
+
bold: (s) => `\x1b[1m${s}\x1b[0m`,
|
|
12
|
+
cyan: (s) => `\x1b[36m${s}\x1b[0m`,
|
|
13
|
+
green: (s) => `\x1b[32m${s}\x1b[0m`,
|
|
14
|
+
yellow: (s) => `\x1b[33m${s}\x1b[0m`,
|
|
15
|
+
magenta: (s) => `\x1b[35m${s}\x1b[0m`,
|
|
16
|
+
gray: (s) => `\x1b[90m${s}\x1b[0m`,
|
|
17
|
+
white: (s) => `\x1b[37m${s}\x1b[0m`,
|
|
18
|
+
red: (s) => `\x1b[31m${s}\x1b[0m`,
|
|
19
|
+
dim: (s) => `\x1b[2m${s}\x1b[0m`,
|
|
20
|
+
bgCyan: (s) => `\x1b[46m${s}\x1b[0m`,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Box drawing characters
|
|
24
|
+
const BOX = {
|
|
25
|
+
topLeft: '╭',
|
|
26
|
+
topRight: '╮',
|
|
27
|
+
bottomLeft: '╰',
|
|
28
|
+
bottomRight: '╯',
|
|
29
|
+
horizontal: '─',
|
|
30
|
+
vertical: '│',
|
|
31
|
+
verticalRight: '├',
|
|
32
|
+
verticalLeft: '┤',
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Progress spinner frames
|
|
36
|
+
const SPINNER = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
37
|
+
|
|
38
|
+
// Helper functions
|
|
39
|
+
function box(title, content, width = 60) {
|
|
40
|
+
const lines = content.split('\n');
|
|
41
|
+
const top = `${BOX.topLeft}${BOX.horizontal} ${chalk.bold(chalk.cyan(title))} ${BOX.horizontal.repeat(Math.max(0, width - title.length - 5))}${BOX.topRight}`;
|
|
42
|
+
const bottom = `${BOX.bottomLeft}${BOX.horizontal.repeat(width - 2)}${BOX.bottomRight}`;
|
|
43
|
+
const middle = lines.map(line => {
|
|
44
|
+
const padding = width - 4 - stripAnsi(line).length;
|
|
45
|
+
return `${BOX.vertical} ${line}${' '.repeat(Math.max(0, padding))} ${BOX.vertical}`;
|
|
46
|
+
}).join('\n');
|
|
47
|
+
return `${top}\n${middle}\n${bottom}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function stripAnsi(str) {
|
|
51
|
+
// eslint-disable-next-line no-control-regex
|
|
52
|
+
return str.replace(/\x1b\[[0-9;]*m/g, '');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function progressBar(percent, width = 30) {
|
|
56
|
+
const filled = Math.min(width, Math.max(0, Math.round(width * percent / 100)));
|
|
57
|
+
const empty = width - filled;
|
|
58
|
+
const bar = chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));
|
|
59
|
+
return `${bar} ${chalk.bold(percent)}%`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function sleep(ms) {
|
|
63
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async function animateProgress(label, steps, callback) {
|
|
67
|
+
process.stdout.write(`\n${chalk.cyan('⏳')} ${label}...\n`);
|
|
68
|
+
|
|
69
|
+
for (let i = 0; i < steps.length; i++) {
|
|
70
|
+
const step = steps[i];
|
|
71
|
+
process.stdout.write(` ${chalk.gray(SPINNER[i % SPINNER.length])} ${step.name}`);
|
|
72
|
+
await sleep(step.duration || 500);
|
|
73
|
+
process.stdout.clearLine?.(0) || process.stdout.write('\r');
|
|
74
|
+
process.stdout.cursorTo?.(0) || process.stdout.write('\r');
|
|
75
|
+
process.stdout.write(` ${chalk.green('✓')} ${step.name}\n`);
|
|
76
|
+
if (callback) callback(step, i);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Main output formatter
|
|
81
|
+
class SkillCreateOutput {
|
|
82
|
+
constructor(repoName, options = {}) {
|
|
83
|
+
this.repoName = repoName;
|
|
84
|
+
this.options = options;
|
|
85
|
+
this.width = options.width || 70;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
header() {
|
|
89
|
+
const subtitle = `Extracting patterns from ${chalk.cyan(this.repoName)}`;
|
|
90
|
+
|
|
91
|
+
console.log('\n');
|
|
92
|
+
console.log(chalk.bold(chalk.magenta('╔════════════════════════════════════════════════════════════════╗')));
|
|
93
|
+
console.log(chalk.bold(chalk.magenta('║')) + chalk.bold(' 🔮 cc4pm Skill Creator ') + chalk.bold(chalk.magenta('║')));
|
|
94
|
+
console.log(chalk.bold(chalk.magenta('║')) + ` ${subtitle}${' '.repeat(Math.max(0, 59 - stripAnsi(subtitle).length))}` + chalk.bold(chalk.magenta('║')));
|
|
95
|
+
console.log(chalk.bold(chalk.magenta('╚════════════════════════════════════════════════════════════════╝')));
|
|
96
|
+
console.log('');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async analyzePhase(data) {
|
|
100
|
+
const steps = [
|
|
101
|
+
{ name: 'Parsing git history...', duration: 300 },
|
|
102
|
+
{ name: `Found ${chalk.yellow(data.commits)} commits`, duration: 200 },
|
|
103
|
+
{ name: 'Analyzing commit patterns...', duration: 400 },
|
|
104
|
+
{ name: 'Detecting file co-changes...', duration: 300 },
|
|
105
|
+
{ name: 'Identifying workflows...', duration: 400 },
|
|
106
|
+
{ name: 'Extracting architecture patterns...', duration: 300 },
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
await animateProgress('Analyzing Repository', steps);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
analysisResults(data) {
|
|
113
|
+
console.log('\n');
|
|
114
|
+
console.log(box('📊 Analysis Results', `
|
|
115
|
+
${chalk.bold('Commits Analyzed:')} ${chalk.yellow(data.commits)}
|
|
116
|
+
${chalk.bold('Time Range:')} ${chalk.gray(data.timeRange)}
|
|
117
|
+
${chalk.bold('Contributors:')} ${chalk.cyan(data.contributors)}
|
|
118
|
+
${chalk.bold('Files Tracked:')} ${chalk.green(data.files)}
|
|
119
|
+
`));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
patterns(patterns) {
|
|
123
|
+
console.log('\n');
|
|
124
|
+
console.log(chalk.bold(chalk.cyan('🔍 Key Patterns Discovered:')));
|
|
125
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
126
|
+
|
|
127
|
+
patterns.forEach((pattern, i) => {
|
|
128
|
+
const confidence = pattern.confidence ?? 0.8;
|
|
129
|
+
const confidenceBar = progressBar(Math.round(confidence * 100), 15);
|
|
130
|
+
console.log(`
|
|
131
|
+
${chalk.bold(chalk.yellow(`${i + 1}.`))} ${chalk.bold(pattern.name)}
|
|
132
|
+
${chalk.gray('Trigger:')} ${pattern.trigger}
|
|
133
|
+
${chalk.gray('Confidence:')} ${confidenceBar}
|
|
134
|
+
${chalk.dim(pattern.evidence)}`);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
instincts(instincts) {
|
|
139
|
+
console.log('\n');
|
|
140
|
+
console.log(box('🧠 Instincts Generated', instincts.map((inst, i) =>
|
|
141
|
+
`${chalk.yellow(`${i + 1}.`)} ${chalk.bold(inst.name)} ${chalk.gray(`(${Math.round(inst.confidence * 100)}%)`)}`
|
|
142
|
+
).join('\n')));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
output(skillPath, instinctsPath) {
|
|
146
|
+
console.log('\n');
|
|
147
|
+
console.log(chalk.bold(chalk.green('✨ Generation Complete!')));
|
|
148
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
149
|
+
console.log(`
|
|
150
|
+
${chalk.green('📄')} ${chalk.bold('Skill File:')}
|
|
151
|
+
${chalk.cyan(skillPath)}
|
|
152
|
+
|
|
153
|
+
${chalk.green('🧠')} ${chalk.bold('Instincts File:')}
|
|
154
|
+
${chalk.cyan(instinctsPath)}
|
|
155
|
+
`);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
nextSteps() {
|
|
159
|
+
console.log(box('📋 Next Steps', `
|
|
160
|
+
${chalk.yellow('1.')} Review the generated SKILL.md
|
|
161
|
+
${chalk.yellow('2.')} Import instincts: ${chalk.cyan('/instinct-import <path>')}
|
|
162
|
+
${chalk.yellow('3.')} View learned patterns: ${chalk.cyan('/instinct-status')}
|
|
163
|
+
${chalk.yellow('4.')} Evolve into skills: ${chalk.cyan('/evolve')}
|
|
164
|
+
`));
|
|
165
|
+
console.log('\n');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
footer() {
|
|
169
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
170
|
+
console.log(chalk.dim(` Powered by cc4pm • ecc.tools`));
|
|
171
|
+
console.log(chalk.dim(` GitHub App: github.com/apps/skill-creator`));
|
|
172
|
+
console.log('\n');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Demo function to show the output
|
|
177
|
+
async function demo() {
|
|
178
|
+
const output = new SkillCreateOutput('PMX');
|
|
179
|
+
|
|
180
|
+
output.header();
|
|
181
|
+
|
|
182
|
+
await output.analyzePhase({
|
|
183
|
+
commits: 200,
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
output.analysisResults({
|
|
187
|
+
commits: 200,
|
|
188
|
+
timeRange: 'Nov 2024 - Jan 2025',
|
|
189
|
+
contributors: 4,
|
|
190
|
+
files: 847,
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
output.patterns([
|
|
194
|
+
{
|
|
195
|
+
name: 'Conventional Commits',
|
|
196
|
+
trigger: 'when writing commit messages',
|
|
197
|
+
confidence: 0.85,
|
|
198
|
+
evidence: 'Found in 150/200 commits (feat:, fix:, refactor:)',
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
name: 'Client/Server Component Split',
|
|
202
|
+
trigger: 'when creating Next.js pages',
|
|
203
|
+
confidence: 0.90,
|
|
204
|
+
evidence: 'Observed in markets/, premarkets/, portfolio/',
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
name: 'Service Layer Architecture',
|
|
208
|
+
trigger: 'when adding backend logic',
|
|
209
|
+
confidence: 0.85,
|
|
210
|
+
evidence: 'Business logic in services/, not routes/',
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
name: 'TDD with E2E Tests',
|
|
214
|
+
trigger: 'when adding features',
|
|
215
|
+
confidence: 0.75,
|
|
216
|
+
evidence: '9 E2E test files, test(e2e) commits common',
|
|
217
|
+
},
|
|
218
|
+
]);
|
|
219
|
+
|
|
220
|
+
output.instincts([
|
|
221
|
+
{ name: 'pmx-conventional-commits', confidence: 0.85 },
|
|
222
|
+
{ name: 'pmx-client-component-pattern', confidence: 0.90 },
|
|
223
|
+
{ name: 'pmx-service-layer', confidence: 0.85 },
|
|
224
|
+
{ name: 'pmx-e2e-test-location', confidence: 0.90 },
|
|
225
|
+
{ name: 'pmx-package-manager', confidence: 0.95 },
|
|
226
|
+
{ name: 'pmx-hot-path-caution', confidence: 0.90 },
|
|
227
|
+
]);
|
|
228
|
+
|
|
229
|
+
output.output(
|
|
230
|
+
'.claude/skills/pmx-patterns/SKILL.md',
|
|
231
|
+
'.claude/homunculus/instincts/inherited/pmx-instincts.yaml'
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
output.nextSteps();
|
|
235
|
+
output.footer();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Export for use in other scripts
|
|
239
|
+
module.exports = { SkillCreateOutput, demo };
|
|
240
|
+
|
|
241
|
+
// Run demo if executed directly
|
|
242
|
+
if (require.main === module) {
|
|
243
|
+
demo().catch(console.error);
|
|
244
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { uninstallInstalledStates } = require('./lib/install-lifecycle');
|
|
4
|
+
const { SUPPORTED_INSTALL_TARGETS } = require('./lib/install-manifests');
|
|
5
|
+
|
|
6
|
+
function showHelp(exitCode = 0) {
|
|
7
|
+
console.log(`
|
|
8
|
+
Usage: node scripts/uninstall.js [--target <${SUPPORTED_INSTALL_TARGETS.join('|')}>] [--dry-run] [--json]
|
|
9
|
+
|
|
10
|
+
Remove ECC-managed files recorded in install-state for the current context.
|
|
11
|
+
`);
|
|
12
|
+
process.exit(exitCode);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function parseArgs(argv) {
|
|
16
|
+
const args = argv.slice(2);
|
|
17
|
+
const parsed = {
|
|
18
|
+
targets: [],
|
|
19
|
+
dryRun: false,
|
|
20
|
+
json: false,
|
|
21
|
+
help: false,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
25
|
+
const arg = args[index];
|
|
26
|
+
|
|
27
|
+
if (arg === '--target') {
|
|
28
|
+
parsed.targets.push(args[index + 1] || null);
|
|
29
|
+
index += 1;
|
|
30
|
+
} else if (arg === '--dry-run') {
|
|
31
|
+
parsed.dryRun = true;
|
|
32
|
+
} else if (arg === '--json') {
|
|
33
|
+
parsed.json = true;
|
|
34
|
+
} else if (arg === '--help' || arg === '-h') {
|
|
35
|
+
parsed.help = true;
|
|
36
|
+
} else {
|
|
37
|
+
throw new Error(`Unknown argument: ${arg}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return parsed;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function printHuman(result) {
|
|
45
|
+
if (result.results.length === 0) {
|
|
46
|
+
console.log('No cc4pm install-state files found for the current home/project context.');
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
console.log('Uninstall summary:\n');
|
|
51
|
+
for (const entry of result.results) {
|
|
52
|
+
console.log(`- ${entry.adapter.id}`);
|
|
53
|
+
console.log(` Status: ${entry.status.toUpperCase()}`);
|
|
54
|
+
console.log(` Install-state: ${entry.installStatePath}`);
|
|
55
|
+
|
|
56
|
+
if (entry.error) {
|
|
57
|
+
console.log(` Error: ${entry.error}`);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const paths = result.dryRun ? entry.plannedRemovals : entry.removedPaths;
|
|
62
|
+
console.log(` ${result.dryRun ? 'Planned removals' : 'Removed paths'}: ${paths.length}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
console.log(`\nSummary: checked=${result.summary.checkedCount}, ${result.dryRun ? 'planned' : 'uninstalled'}=${result.dryRun ? result.summary.plannedRemovalCount : result.summary.uninstalledCount}, errors=${result.summary.errorCount}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function main() {
|
|
69
|
+
try {
|
|
70
|
+
const options = parseArgs(process.argv);
|
|
71
|
+
if (options.help) {
|
|
72
|
+
showHelp(0);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const result = uninstallInstalledStates({
|
|
76
|
+
homeDir: process.env.HOME,
|
|
77
|
+
projectRoot: process.cwd(),
|
|
78
|
+
targets: options.targets,
|
|
79
|
+
dryRun: options.dryRun,
|
|
80
|
+
});
|
|
81
|
+
const hasErrors = result.summary.errorCount > 0;
|
|
82
|
+
|
|
83
|
+
if (options.json) {
|
|
84
|
+
console.log(JSON.stringify(result, null, 2));
|
|
85
|
+
} else {
|
|
86
|
+
printHuman(result);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
process.exitCode = hasErrors ? 1 : 0;
|
|
90
|
+
} catch (error) {
|
|
91
|
+
console.error(`Error: ${error.message}`);
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
main();
|