ccjk 13.3.5 → 13.3.7
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/dist/chunks/agent-teams.mjs +7 -5
- package/dist/chunks/agent.mjs +2 -2
- package/dist/chunks/agents.mjs +16 -16
- package/dist/chunks/api-cli.mjs +6 -6
- package/dist/chunks/api-providers.mjs +1 -1
- package/dist/chunks/api.mjs +4 -4
- package/dist/chunks/auto-bootstrap.mjs +1 -1
- package/dist/chunks/auto-fix.mjs +49 -4
- package/dist/chunks/auto-fixer.mjs +7 -5
- package/dist/chunks/auto-init.mjs +9 -7208
- package/dist/chunks/auto-memory-bridge.mjs +9 -3
- package/dist/chunks/auto-updater.mjs +9 -9
- package/dist/chunks/auto-upgrade.mjs +5 -3
- package/dist/chunks/banner.mjs +4 -3
- package/dist/chunks/boost.mjs +118 -62
- package/dist/chunks/ccjk-agents.mjs +3 -3
- package/dist/chunks/ccjk-all.mjs +7 -7
- package/dist/chunks/ccjk-config.mjs +2 -2
- package/dist/chunks/ccjk-hooks.mjs +4 -4
- package/dist/chunks/ccjk-mcp.mjs +5 -5
- package/dist/chunks/ccjk-setup.mjs +5 -5
- package/dist/chunks/ccjk-skills.mjs +5 -5
- package/dist/chunks/ccr.mjs +18 -16
- package/dist/chunks/ccu.mjs +2 -2
- package/dist/chunks/check-updates.mjs +8 -8
- package/dist/chunks/claude-code-config-manager.mjs +11 -8
- package/dist/chunks/claude-code-incremental-manager.mjs +7 -7
- package/dist/chunks/claude-config.mjs +1 -1
- package/dist/chunks/claude-wrapper.mjs +1 -1
- package/dist/chunks/cli-hook.mjs +15 -15
- package/dist/chunks/codex-config-switch.mjs +7 -7
- package/dist/chunks/codex-provider-manager.mjs +7 -7
- package/dist/chunks/codex-uninstaller.mjs +2 -2
- package/dist/chunks/codex.mjs +5 -5
- package/dist/chunks/commands.mjs +2 -2
- package/dist/chunks/commands2.mjs +3 -3
- package/dist/chunks/commit.mjs +2 -2
- package/dist/chunks/completion.mjs +2 -2
- package/dist/chunks/config-consolidator.mjs +2 -2
- package/dist/chunks/config-switch.mjs +8 -8
- package/dist/chunks/config.mjs +6 -5
- package/dist/chunks/config2.mjs +5 -5
- package/dist/chunks/config3.mjs +4 -4
- package/dist/chunks/constants.mjs +1 -1
- package/dist/chunks/context-opt.mjs +92 -90
- package/dist/chunks/context.mjs +659 -0
- package/dist/chunks/dashboard.mjs +14 -9
- package/dist/chunks/doctor.mjs +4 -4
- package/dist/chunks/eval.mjs +502 -0
- package/dist/chunks/evolution.mjs +46 -39
- package/dist/chunks/health-alerts.mjs +9 -9
- package/dist/chunks/help.mjs +1 -1
- package/dist/chunks/hook-installer.mjs +6 -3
- package/dist/chunks/index.mjs +23 -0
- package/dist/chunks/index10.mjs +634 -571
- package/dist/chunks/index11.mjs +1061 -569
- package/dist/chunks/index12.mjs +914 -1076
- package/dist/chunks/index13.mjs +136 -951
- package/dist/chunks/index14.mjs +209 -185
- package/dist/chunks/index2.mjs +19 -24
- package/dist/chunks/index3.mjs +19085 -12
- package/dist/chunks/index4.mjs +16 -19092
- package/dist/chunks/index5.mjs +7602 -16
- package/dist/chunks/index6.mjs +159 -7590
- package/dist/chunks/index7.mjs +1602 -171
- package/dist/chunks/index8.mjs +19 -1602
- package/dist/chunks/index9.mjs +612 -15
- package/dist/chunks/init.mjs +26 -19
- package/dist/chunks/installer.mjs +5 -5
- package/dist/chunks/installer2.mjs +2 -2
- package/dist/chunks/intent-engine.mjs +1 -1
- package/dist/chunks/interview.mjs +4 -4
- package/dist/chunks/manager.mjs +1 -1
- package/dist/chunks/marketplace.mjs +2 -2
- package/dist/chunks/mcp-cli.mjs +12 -12
- package/dist/chunks/mcp.mjs +8 -8
- package/dist/chunks/memory.mjs +8 -8
- package/dist/chunks/menu-hierarchical.mjs +24 -22
- package/dist/chunks/menu.mjs +27 -22
- package/dist/chunks/metrics-display.mjs +2 -2
- package/dist/chunks/migrator.mjs +1 -1
- package/dist/chunks/monitor.mjs +2 -2
- package/dist/chunks/notification.mjs +6 -6
- package/dist/chunks/onboarding-wizard.mjs +6 -5
- package/dist/chunks/onboarding.mjs +4 -4
- package/dist/chunks/package.mjs +1 -1
- package/dist/chunks/paradigm.mjs +2 -2
- package/dist/chunks/permission-manager.mjs +2 -2
- package/dist/chunks/permissions.mjs +3 -3
- package/dist/chunks/persistence-manager.mjs +19 -12
- package/dist/chunks/persistence.mjs +5 -3
- package/dist/chunks/plugin.mjs +2 -2
- package/dist/chunks/prompts.mjs +5 -5
- package/dist/chunks/providers.mjs +2 -2
- package/dist/chunks/quick-actions.mjs +7 -6
- package/dist/chunks/quick-provider.mjs +5 -4
- package/dist/chunks/quick-setup.mjs +20 -15
- package/dist/chunks/remote.mjs +15 -16
- package/dist/chunks/{convoy-manager.mjs → session-manager.mjs} +1129 -1095
- package/dist/chunks/session.mjs +2 -2
- package/dist/chunks/sessions.mjs +3 -3
- package/dist/chunks/silent-updater.mjs +1 -1
- package/dist/chunks/simple-config.mjs +2 -2
- package/dist/chunks/skill2.mjs +3 -3
- package/dist/chunks/skills-sync.mjs +5 -5
- package/dist/chunks/skills.mjs +3 -3
- package/dist/chunks/slash-commands.mjs +9 -8
- package/dist/chunks/smart-defaults.mjs +9 -5
- package/dist/chunks/startup.mjs +1 -1
- package/dist/chunks/stats.mjs +2 -2
- package/dist/chunks/status.mjs +37 -22
- package/dist/chunks/team.mjs +3 -3
- package/dist/chunks/thinking.mjs +4 -4
- package/dist/chunks/trace.mjs +2 -2
- package/dist/chunks/uninstall.mjs +9 -9
- package/dist/chunks/update.mjs +14 -11
- package/dist/chunks/upgrade-manager.mjs +3 -3
- package/dist/chunks/upgrade.mjs +25 -9
- package/dist/chunks/version-checker.mjs +4 -4
- package/dist/chunks/vim.mjs +3 -3
- package/dist/chunks/workflows.mjs +1 -1
- package/dist/chunks/wsl.mjs +1 -1
- package/dist/chunks/zero-config.mjs +4 -4
- package/dist/cli.mjs +60 -26
- package/dist/index.d.mts +4392 -4392
- package/dist/index.d.ts +4392 -4392
- package/dist/index.mjs +4314 -4314
- package/dist/shared/{ccjk.DcKLglJQ.mjs → ccjk.BIxuVL3_.mjs} +2 -2
- package/dist/shared/{ccjk.DJdmgr2d.mjs → ccjk.BJMRY2Ra.mjs} +5 -3
- package/dist/shared/{ccjk.B1TwPltj.mjs → ccjk.BOu1yav7.mjs} +3 -2
- package/dist/shared/{ccjk.mJpVRDZ8.mjs → ccjk.BWFpnOr3.mjs} +1 -1
- package/dist/shared/{ccjk.BfIpomdz.mjs → ccjk.CHUEFqmw.mjs} +3 -2
- package/dist/shared/{ccjk.CqdbaXqU.mjs → ccjk.CLUL0pAV.mjs} +9 -5
- package/dist/shared/{ccjk.Cot9p9_n.mjs → ccjk.Cjj8SVrn.mjs} +1 -1
- package/dist/shared/{ccjk.CfrpIIKy.mjs → ccjk.Crd_nEfj.mjs} +38 -20
- package/dist/shared/{ccjk.DCw2WnZU.mjs → ccjk.CvChMYvB.mjs} +1 -1
- package/dist/shared/{ccjk.CXzjn01x.mjs → ccjk.D8ZLYSZZ.mjs} +1 -1
- package/dist/shared/{ccjk.BrPUmTqm.mjs → ccjk.DJuyfrlL.mjs} +164 -82
- package/dist/shared/{ccjk.DHXfsrwn.mjs → ccjk.DRfdq6yl.mjs} +4 -4
- package/dist/shared/{ccjk.DXRAZcix.mjs → ccjk.DScm_NnL.mjs} +8 -4
- package/dist/shared/{ccjk.XsJWJuQP.mjs → ccjk.DfZKjHvG.mjs} +6 -128
- package/dist/shared/{ccjk.BFxsJM0k.mjs → ccjk.DwSebGy0.mjs} +4 -3
- package/dist/shared/ccjk.DxWqH-EF.mjs +170 -0
- package/dist/shared/{ccjk.Cwa_FiTX.mjs → ccjk.I6IuYdc_.mjs} +2 -2
- package/dist/shared/{ccjk.DpstNaeR.mjs → ccjk.KpFl2RDA.mjs} +3 -3
- package/dist/shared/{ccjk.dYDLfmph.mjs → ccjk._dESH4Rk.mjs} +1 -1
- package/dist/shared/{ccjk.BxSmJ8B7.mjs → ccjk.wLJHO0Af.mjs} +2 -1
- package/package.json +65 -67
- package/dist/chunks/index15.mjs +0 -218
- package/dist/shared/{ccjk.c-ETfBZ_.mjs → ccjk.eIn-g1yI.mjs} +96 -96
package/dist/chunks/index10.mjs
CHANGED
|
@@ -1,616 +1,679 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { existsSync, readFileSync, readdirSync, statSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { j as join, d as dirname } from '../shared/ccjk.bQ7Dh1g4.mjs';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const alibi = opts.alias !== void 0;
|
|
25
|
-
const strict = opts.unknown !== void 0;
|
|
26
|
-
const defaults = opts.default !== void 0;
|
|
27
|
-
|
|
28
|
-
opts.alias = opts.alias || {};
|
|
29
|
-
opts.string = toArr(opts.string);
|
|
30
|
-
opts.boolean = toArr(opts.boolean);
|
|
31
|
-
|
|
32
|
-
if (alibi) {
|
|
33
|
-
for (k in opts.alias) {
|
|
34
|
-
arr = opts.alias[k] = toArr(opts.alias[k]);
|
|
35
|
-
for (i=0; i < arr.length; i++) {
|
|
36
|
-
(opts.alias[arr[i]] = arr.concat(k)).splice(i, 1);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
for (i=opts.boolean.length; i-- > 0;) {
|
|
42
|
-
arr = opts.alias[opts.boolean[i]] || [];
|
|
43
|
-
for (j=arr.length; j-- > 0;) opts.boolean.push(arr[j]);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
for (i=opts.string.length; i-- > 0;) {
|
|
47
|
-
arr = opts.alias[opts.string[i]] || [];
|
|
48
|
-
for (j=arr.length; j-- > 0;) opts.string.push(arr[j]);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (defaults) {
|
|
52
|
-
for (k in opts.default) {
|
|
53
|
-
name = typeof opts.default[k];
|
|
54
|
-
arr = opts.alias[k] = opts.alias[k] || [];
|
|
55
|
-
if (opts[name] !== void 0) {
|
|
56
|
-
opts[name].push(k);
|
|
57
|
-
for (i=0; i < arr.length; i++) {
|
|
58
|
-
opts[name].push(arr[i]);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const keys = strict ? Object.keys(opts.alias) : [];
|
|
65
|
-
|
|
66
|
-
for (i=0; i < len; i++) {
|
|
67
|
-
arg = args[i];
|
|
68
|
-
|
|
69
|
-
if (arg === '--') {
|
|
70
|
-
out._ = out._.concat(args.slice(++i));
|
|
71
|
-
break;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
for (j=0; j < arg.length; j++) {
|
|
75
|
-
if (arg.charCodeAt(j) !== 45) break; // "-"
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (j === 0) {
|
|
79
|
-
out._.push(arg);
|
|
80
|
-
} else if (arg.substring(j, j + 3) === 'no-') {
|
|
81
|
-
name = arg.substring(j + 3);
|
|
82
|
-
if (strict && !~keys.indexOf(name)) {
|
|
83
|
-
return opts.unknown(arg);
|
|
84
|
-
}
|
|
85
|
-
out[name] = false;
|
|
86
|
-
} else {
|
|
87
|
-
for (idx=j+1; idx < arg.length; idx++) {
|
|
88
|
-
if (arg.charCodeAt(idx) === 61) break; // "="
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
name = arg.substring(j, idx);
|
|
92
|
-
val = arg.substring(++idx) || (i+1 === len || (''+args[i+1]).charCodeAt(0) === 45 || args[++i]);
|
|
93
|
-
arr = (j === 2 ? [name] : name);
|
|
94
|
-
|
|
95
|
-
for (idx=0; idx < arr.length; idx++) {
|
|
96
|
-
name = arr[idx];
|
|
97
|
-
if (strict && !~keys.indexOf(name)) return opts.unknown('-'.repeat(j) + name);
|
|
98
|
-
toVal(out, name, (idx + 1 < arr.length) || val, opts);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (defaults) {
|
|
104
|
-
for (k in opts.default) {
|
|
105
|
-
if (out[k] === void 0) {
|
|
106
|
-
out[k] = opts.default[k];
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (alibi) {
|
|
112
|
-
for (k in out) {
|
|
113
|
-
arr = opts.alias[k] || [];
|
|
114
|
-
while (arr.length > 0) {
|
|
115
|
-
out[arr.shift()] = out[k];
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return out;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const removeBrackets = (v) => v.replace(/[<[].+/, "").trim();
|
|
124
|
-
const findAllBrackets = (v) => {
|
|
125
|
-
const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g;
|
|
126
|
-
const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g;
|
|
127
|
-
const res = [];
|
|
128
|
-
const parse = (match) => {
|
|
129
|
-
let variadic = false;
|
|
130
|
-
let value = match[1];
|
|
131
|
-
if (value.startsWith("...")) {
|
|
132
|
-
value = value.slice(3);
|
|
133
|
-
variadic = true;
|
|
134
|
-
}
|
|
6
|
+
class ProjectAnalyzer {
|
|
7
|
+
projectRoot;
|
|
8
|
+
constructor(projectRoot = process.cwd()) {
|
|
9
|
+
this.projectRoot = projectRoot;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Analyze project and return comprehensive analysis
|
|
13
|
+
*/
|
|
14
|
+
async analyze() {
|
|
15
|
+
const packageJson = this.readPackageJson();
|
|
16
|
+
const techStack = this.detectTechStack(packageJson);
|
|
17
|
+
const projectType = this.detectProjectType(techStack, packageJson);
|
|
18
|
+
const frameworks = this.detectFrameworks(packageJson);
|
|
19
|
+
const hasTests = this.detectTestFramework(packageJson);
|
|
20
|
+
const hasDatabase = this.detectDatabase(packageJson);
|
|
21
|
+
const hasApi = this.detectApiEndpoints();
|
|
22
|
+
const buildTool = this.detectBuildTool(packageJson);
|
|
23
|
+
const cicd = this.detectCICD();
|
|
24
|
+
const patterns = this.detectPatterns();
|
|
25
|
+
const confidence = this.calculateConfidence(techStack, frameworks);
|
|
135
26
|
return {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
27
|
+
projectRoot: this.projectRoot,
|
|
28
|
+
projectType,
|
|
29
|
+
techStack,
|
|
30
|
+
frameworks,
|
|
31
|
+
hasTests,
|
|
32
|
+
hasDatabase,
|
|
33
|
+
hasApi,
|
|
34
|
+
buildTool,
|
|
35
|
+
cicd,
|
|
36
|
+
patterns,
|
|
37
|
+
confidence,
|
|
38
|
+
packageJson: packageJson ?? void 0
|
|
139
39
|
};
|
|
140
|
-
};
|
|
141
|
-
let angledMatch;
|
|
142
|
-
while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) {
|
|
143
|
-
res.push(parse(angledMatch));
|
|
144
|
-
}
|
|
145
|
-
let squareMatch;
|
|
146
|
-
while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) {
|
|
147
|
-
res.push(parse(squareMatch));
|
|
148
|
-
}
|
|
149
|
-
return res;
|
|
150
|
-
};
|
|
151
|
-
const getMriOptions = (options) => {
|
|
152
|
-
const result = {alias: {}, boolean: []};
|
|
153
|
-
for (const [index, option] of options.entries()) {
|
|
154
|
-
if (option.names.length > 1) {
|
|
155
|
-
result.alias[option.names[0]] = option.names.slice(1);
|
|
156
|
-
}
|
|
157
|
-
if (option.isBoolean) {
|
|
158
|
-
if (option.negated) {
|
|
159
|
-
const hasStringTypeOption = options.some((o, i) => {
|
|
160
|
-
return i !== index && o.names.some((name) => option.names.includes(name)) && typeof o.required === "boolean";
|
|
161
|
-
});
|
|
162
|
-
if (!hasStringTypeOption) {
|
|
163
|
-
result.boolean.push(option.names[0]);
|
|
164
|
-
}
|
|
165
|
-
} else {
|
|
166
|
-
result.boolean.push(option.names[0]);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
40
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
});
|
|
184
|
-
};
|
|
185
|
-
const setDotProp = (obj, keys, val) => {
|
|
186
|
-
let i = 0;
|
|
187
|
-
let length = keys.length;
|
|
188
|
-
let t = obj;
|
|
189
|
-
let x;
|
|
190
|
-
for (; i < length; ++i) {
|
|
191
|
-
x = t[keys[i]];
|
|
192
|
-
t = t[keys[i]] = i === length - 1 ? val : x != null ? x : !!~keys[i + 1].indexOf(".") || !(+keys[i + 1] > -1) ? {} : [];
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
const setByType = (obj, transforms) => {
|
|
196
|
-
for (const key of Object.keys(transforms)) {
|
|
197
|
-
const transform = transforms[key];
|
|
198
|
-
if (transform.shouldTransform) {
|
|
199
|
-
obj[key] = Array.prototype.concat.call([], obj[key]);
|
|
200
|
-
if (typeof transform.transformFunction === "function") {
|
|
201
|
-
obj[key] = obj[key].map(transform.transformFunction);
|
|
202
|
-
}
|
|
41
|
+
/**
|
|
42
|
+
* Read and parse package.json
|
|
43
|
+
*/
|
|
44
|
+
readPackageJson() {
|
|
45
|
+
const packageJsonPath = join(this.projectRoot, "package.json");
|
|
46
|
+
if (!existsSync(packageJsonPath)) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
51
|
+
return JSON.parse(content);
|
|
52
|
+
} catch {
|
|
53
|
+
return null;
|
|
203
54
|
}
|
|
204
55
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Detect technology stack from dependencies
|
|
58
|
+
*/
|
|
59
|
+
detectTechStack(packageJson) {
|
|
60
|
+
if (!packageJson) {
|
|
61
|
+
return {
|
|
62
|
+
languages: ["javascript"],
|
|
63
|
+
runtime: "node",
|
|
64
|
+
packageManager: this.detectPackageManager()
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const deps = {
|
|
68
|
+
...packageJson.dependencies,
|
|
69
|
+
...packageJson.devDependencies
|
|
70
|
+
};
|
|
71
|
+
const languages = [];
|
|
72
|
+
let runtime = "node";
|
|
73
|
+
if (deps.typescript || existsSync(join(this.projectRoot, "tsconfig.json"))) {
|
|
74
|
+
languages.push("typescript");
|
|
221
75
|
} else {
|
|
222
|
-
|
|
76
|
+
languages.push("javascript");
|
|
223
77
|
}
|
|
78
|
+
if (existsSync(join(this.projectRoot, "deno.json")) || existsSync(join(this.projectRoot, "deno.jsonc"))) {
|
|
79
|
+
runtime = "deno";
|
|
80
|
+
}
|
|
81
|
+
if (existsSync(join(this.projectRoot, "bun.lockb"))) {
|
|
82
|
+
runtime = "bun";
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
languages,
|
|
86
|
+
runtime,
|
|
87
|
+
packageManager: this.detectPackageManager()
|
|
88
|
+
};
|
|
224
89
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
this.
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
90
|
+
/**
|
|
91
|
+
* Detect package manager
|
|
92
|
+
*/
|
|
93
|
+
detectPackageManager() {
|
|
94
|
+
if (existsSync(join(this.projectRoot, "pnpm-lock.yaml"))) {
|
|
95
|
+
return "pnpm";
|
|
96
|
+
}
|
|
97
|
+
if (existsSync(join(this.projectRoot, "yarn.lock"))) {
|
|
98
|
+
return "yarn";
|
|
99
|
+
}
|
|
100
|
+
if (existsSync(join(this.projectRoot, "bun.lockb"))) {
|
|
101
|
+
return "bun";
|
|
102
|
+
}
|
|
103
|
+
if (existsSync(join(this.projectRoot, "package-lock.json"))) {
|
|
104
|
+
return "npm";
|
|
105
|
+
}
|
|
106
|
+
return "npm";
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Detect project type
|
|
110
|
+
*/
|
|
111
|
+
detectProjectType(techStack, packageJson) {
|
|
112
|
+
if (!packageJson) {
|
|
113
|
+
return "unknown";
|
|
114
|
+
}
|
|
115
|
+
const deps = {
|
|
116
|
+
...packageJson.dependencies,
|
|
117
|
+
...packageJson.devDependencies
|
|
118
|
+
};
|
|
119
|
+
const hasFrontend = deps.react || deps.vue || deps["@angular/core"] || deps.svelte;
|
|
120
|
+
const hasBackend = deps.express || deps.fastify || deps.koa || deps["@nestjs/core"] || deps.hapi;
|
|
121
|
+
if (deps.next || deps.nuxt || deps["@remix-run/react"] || deps["@sveltejs/kit"]) {
|
|
122
|
+
return "fullstack";
|
|
123
|
+
}
|
|
124
|
+
if (packageJson.bin || deps.commander || deps.yargs || deps.cac) {
|
|
125
|
+
return "cli";
|
|
126
|
+
}
|
|
127
|
+
if (packageJson.main && !hasFrontend && !hasBackend) {
|
|
128
|
+
return "library";
|
|
129
|
+
}
|
|
130
|
+
if (hasFrontend && hasBackend) {
|
|
131
|
+
return "fullstack";
|
|
132
|
+
}
|
|
133
|
+
if (hasFrontend) {
|
|
134
|
+
return "frontend";
|
|
135
|
+
}
|
|
136
|
+
if (hasBackend) {
|
|
137
|
+
return "backend";
|
|
138
|
+
}
|
|
139
|
+
return "unknown";
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Detect frameworks
|
|
143
|
+
*/
|
|
144
|
+
detectFrameworks(packageJson) {
|
|
145
|
+
if (!packageJson) {
|
|
146
|
+
return [];
|
|
147
|
+
}
|
|
148
|
+
const deps = {
|
|
149
|
+
...packageJson.dependencies,
|
|
150
|
+
...packageJson.devDependencies
|
|
151
|
+
};
|
|
152
|
+
const frameworks = [];
|
|
153
|
+
if (deps.react)
|
|
154
|
+
frameworks.push("react");
|
|
155
|
+
if (deps.vue)
|
|
156
|
+
frameworks.push("vue");
|
|
157
|
+
if (deps["@angular/core"])
|
|
158
|
+
frameworks.push("angular");
|
|
159
|
+
if (deps.svelte)
|
|
160
|
+
frameworks.push("svelte");
|
|
161
|
+
if (deps.next)
|
|
162
|
+
frameworks.push("next.js");
|
|
163
|
+
if (deps.nuxt)
|
|
164
|
+
frameworks.push("nuxt");
|
|
165
|
+
if (deps["@remix-run/react"])
|
|
166
|
+
frameworks.push("remix");
|
|
167
|
+
if (deps["@sveltejs/kit"])
|
|
168
|
+
frameworks.push("sveltekit");
|
|
169
|
+
if (deps.express)
|
|
170
|
+
frameworks.push("express");
|
|
171
|
+
if (deps.fastify)
|
|
172
|
+
frameworks.push("fastify");
|
|
173
|
+
if (deps.koa)
|
|
174
|
+
frameworks.push("koa");
|
|
175
|
+
if (deps["@nestjs/core"])
|
|
176
|
+
frameworks.push("nestjs");
|
|
177
|
+
if (deps.hapi)
|
|
178
|
+
frameworks.push("hapi");
|
|
179
|
+
return frameworks;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Detect test framework
|
|
183
|
+
*/
|
|
184
|
+
detectTestFramework(packageJson) {
|
|
185
|
+
if (!packageJson) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
const deps = {
|
|
189
|
+
...packageJson.dependencies,
|
|
190
|
+
...packageJson.devDependencies
|
|
191
|
+
};
|
|
192
|
+
return !!(deps.vitest || deps.jest || deps.mocha || deps.ava || deps["@playwright/test"] || deps.cypress);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Detect database usage
|
|
196
|
+
*/
|
|
197
|
+
detectDatabase(packageJson) {
|
|
198
|
+
if (!packageJson) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
const deps = {
|
|
202
|
+
...packageJson.dependencies,
|
|
203
|
+
...packageJson.devDependencies
|
|
204
|
+
};
|
|
205
|
+
return !!(deps.prisma || deps["@prisma/client"] || deps.drizzle || deps["drizzle-orm"] || deps.typeorm || deps.sequelize || deps.mongoose || deps.pg || deps.mysql || deps.mysql2 || deps.sqlite3 || deps["better-sqlite3"]);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Detect API endpoints
|
|
209
|
+
*/
|
|
210
|
+
detectApiEndpoints() {
|
|
211
|
+
const apiDirs = [
|
|
212
|
+
"src/api",
|
|
213
|
+
"src/routes",
|
|
214
|
+
"api",
|
|
215
|
+
"routes",
|
|
216
|
+
"pages/api",
|
|
217
|
+
// Next.js
|
|
218
|
+
"app/api"
|
|
219
|
+
// Next.js App Router
|
|
220
|
+
];
|
|
221
|
+
return apiDirs.some((dir) => existsSync(join(this.projectRoot, dir)));
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Detect build tool
|
|
225
|
+
*/
|
|
226
|
+
detectBuildTool(packageJson) {
|
|
227
|
+
if (!packageJson) {
|
|
228
|
+
return void 0;
|
|
229
|
+
}
|
|
230
|
+
const deps = {
|
|
231
|
+
...packageJson.dependencies,
|
|
232
|
+
...packageJson.devDependencies
|
|
233
|
+
};
|
|
234
|
+
if (deps.vite || existsSync(join(this.projectRoot, "vite.config.ts"))) {
|
|
235
|
+
return "vite";
|
|
236
|
+
}
|
|
237
|
+
if (deps.webpack || existsSync(join(this.projectRoot, "webpack.config.js"))) {
|
|
238
|
+
return "webpack";
|
|
239
|
+
}
|
|
240
|
+
if (deps.rollup || existsSync(join(this.projectRoot, "rollup.config.js"))) {
|
|
241
|
+
return "rollup";
|
|
242
|
+
}
|
|
243
|
+
if (deps.esbuild) {
|
|
244
|
+
return "esbuild";
|
|
245
|
+
}
|
|
246
|
+
if (deps.turbo || existsSync(join(this.projectRoot, "turbo.json"))) {
|
|
247
|
+
return "turbo";
|
|
248
|
+
}
|
|
249
|
+
return void 0;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Detect CI/CD configuration
|
|
253
|
+
*/
|
|
254
|
+
detectCICD() {
|
|
255
|
+
const cicd = [];
|
|
256
|
+
if (existsSync(join(this.projectRoot, ".github", "workflows"))) {
|
|
257
|
+
cicd.push("github-actions");
|
|
258
|
+
}
|
|
259
|
+
if (existsSync(join(this.projectRoot, ".gitlab-ci.yml"))) {
|
|
260
|
+
cicd.push("gitlab-ci");
|
|
261
|
+
}
|
|
262
|
+
if (existsSync(join(this.projectRoot, ".circleci", "config.yml"))) {
|
|
263
|
+
cicd.push("circleci");
|
|
264
|
+
}
|
|
265
|
+
if (existsSync(join(this.projectRoot, ".travis.yml"))) {
|
|
266
|
+
cicd.push("travis-ci");
|
|
267
|
+
}
|
|
268
|
+
return cicd;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Detect common patterns in the project
|
|
272
|
+
*/
|
|
273
|
+
detectPatterns() {
|
|
274
|
+
const patterns = [];
|
|
275
|
+
if (existsSync(join(this.projectRoot, "packages")) || existsSync(join(this.projectRoot, "apps"))) {
|
|
276
|
+
patterns.push("monorepo");
|
|
277
|
+
}
|
|
278
|
+
if (existsSync(join(this.projectRoot, "tsconfig.json"))) {
|
|
279
|
+
patterns.push("typescript");
|
|
280
|
+
}
|
|
281
|
+
if (existsSync(join(this.projectRoot, ".eslintrc.js")) || existsSync(join(this.projectRoot, "eslint.config.js"))) {
|
|
282
|
+
patterns.push("eslint");
|
|
283
|
+
}
|
|
284
|
+
if (existsSync(join(this.projectRoot, ".prettierrc")) || existsSync(join(this.projectRoot, "prettier.config.js"))) {
|
|
285
|
+
patterns.push("prettier");
|
|
286
|
+
}
|
|
287
|
+
if (existsSync(join(this.projectRoot, "Dockerfile")) || existsSync(join(this.projectRoot, "docker-compose.yml"))) {
|
|
288
|
+
patterns.push("docker");
|
|
289
|
+
}
|
|
290
|
+
if (existsSync(join(this.projectRoot, ".env.example")) || existsSync(join(this.projectRoot, ".env.local"))) {
|
|
291
|
+
patterns.push("env-config");
|
|
292
|
+
}
|
|
293
|
+
return patterns;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Calculate confidence score based on detected information
|
|
297
|
+
*/
|
|
298
|
+
calculateConfidence(techStack, frameworks) {
|
|
299
|
+
let confidence = 0.5;
|
|
300
|
+
if (techStack.languages.length > 0)
|
|
301
|
+
confidence += 0.1;
|
|
302
|
+
if (techStack.runtime !== "unknown")
|
|
303
|
+
confidence += 0.1;
|
|
304
|
+
if (techStack.packageManager)
|
|
305
|
+
confidence += 0.1;
|
|
306
|
+
if (frameworks.length > 0)
|
|
307
|
+
confidence += 0.1;
|
|
308
|
+
if (frameworks.length > 2)
|
|
309
|
+
confidence += 0.1;
|
|
310
|
+
return Math.min(confidence, 1);
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Get file count in directory
|
|
314
|
+
*/
|
|
315
|
+
getFileCount(dir) {
|
|
316
|
+
try {
|
|
317
|
+
if (!existsSync(dir)) {
|
|
318
|
+
return 0;
|
|
239
319
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
320
|
+
let count = 0;
|
|
321
|
+
const items = readdirSync(dir);
|
|
322
|
+
for (const item of items) {
|
|
323
|
+
const fullPath = join(dir, item);
|
|
324
|
+
const stat = statSync(fullPath);
|
|
325
|
+
if (stat.isDirectory()) {
|
|
326
|
+
count += this.getFileCount(fullPath);
|
|
327
|
+
} else {
|
|
328
|
+
count++;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return count;
|
|
332
|
+
} catch {
|
|
333
|
+
return 0;
|
|
252
334
|
}
|
|
253
335
|
}
|
|
254
336
|
}
|
|
337
|
+
async function analyzeProject(projectRoot) {
|
|
338
|
+
const analyzer = new ProjectAnalyzer(projectRoot);
|
|
339
|
+
return analyzer.analyze();
|
|
340
|
+
}
|
|
255
341
|
|
|
256
|
-
const
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
this.
|
|
263
|
-
this.
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
}
|
|
288
|
-
example(example) {
|
|
289
|
-
this.examples.push(example);
|
|
290
|
-
return this;
|
|
291
|
-
}
|
|
292
|
-
option(rawName, description, config) {
|
|
293
|
-
const option = new Option(rawName, description, config);
|
|
294
|
-
this.options.push(option);
|
|
295
|
-
return this;
|
|
296
|
-
}
|
|
297
|
-
alias(name) {
|
|
298
|
-
this.aliasNames.push(name);
|
|
299
|
-
return this;
|
|
300
|
-
}
|
|
301
|
-
action(callback) {
|
|
302
|
-
this.commandAction = callback;
|
|
303
|
-
return this;
|
|
304
|
-
}
|
|
305
|
-
isMatched(name) {
|
|
306
|
-
return this.name === name || this.aliasNames.includes(name);
|
|
307
|
-
}
|
|
308
|
-
get isDefaultCommand() {
|
|
309
|
-
return this.name === "" || this.aliasNames.includes("!");
|
|
310
|
-
}
|
|
311
|
-
get isGlobalCommand() {
|
|
312
|
-
return this instanceof GlobalCommand;
|
|
313
|
-
}
|
|
314
|
-
hasOption(name) {
|
|
315
|
-
name = name.split(".")[0];
|
|
316
|
-
return this.options.find((option) => {
|
|
317
|
-
return option.names.includes(name);
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
outputHelp() {
|
|
321
|
-
const {name, commands} = this.cli;
|
|
322
|
-
const {
|
|
323
|
-
versionNumber,
|
|
324
|
-
options: globalOptions,
|
|
325
|
-
helpCallback
|
|
326
|
-
} = this.cli.globalCommand;
|
|
327
|
-
let sections = [
|
|
328
|
-
{
|
|
329
|
-
body: `${name}${versionNumber ? `/${versionNumber}` : ""}`
|
|
342
|
+
const __filename$1 = fileURLToPath(import.meta.url);
|
|
343
|
+
const __dirname$1 = dirname(__filename$1);
|
|
344
|
+
class ConfigGenerator {
|
|
345
|
+
templatesDir;
|
|
346
|
+
outputDir;
|
|
347
|
+
constructor(templatesDir, outputDir) {
|
|
348
|
+
this.templatesDir = templatesDir || join(__dirname$1, "..", "templates");
|
|
349
|
+
this.outputDir = outputDir || join(homedir(), ".config", "claude");
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Generate configurations from template selection
|
|
353
|
+
*/
|
|
354
|
+
async generate(selection) {
|
|
355
|
+
const agentConfigs = await this.generateAgents(selection.agents);
|
|
356
|
+
const skillConfigs = await this.generateSkills(selection.skills);
|
|
357
|
+
return {
|
|
358
|
+
agents: agentConfigs,
|
|
359
|
+
skills: skillConfigs,
|
|
360
|
+
summary: this.generateSummary(agentConfigs, skillConfigs)
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Generate agent configurations
|
|
365
|
+
*/
|
|
366
|
+
async generateAgents(agents) {
|
|
367
|
+
const configs = [];
|
|
368
|
+
for (const agent of agents) {
|
|
369
|
+
const templatePath = join(this.templatesDir, "agents", agent.file);
|
|
370
|
+
if (!existsSync(templatePath)) {
|
|
371
|
+
console.warn(`Agent template not found: ${agent.file}`);
|
|
372
|
+
continue;
|
|
330
373
|
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
if (showCommands) {
|
|
338
|
-
const longestCommandName = findLongest(commands.map((command) => command.rawName));
|
|
339
|
-
sections.push({
|
|
340
|
-
title: "Commands",
|
|
341
|
-
body: commands.map((command) => {
|
|
342
|
-
return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`;
|
|
343
|
-
}).join("\n")
|
|
344
|
-
});
|
|
345
|
-
sections.push({
|
|
346
|
-
title: `For more info, run any command with the \`--help\` flag`,
|
|
347
|
-
body: commands.map((command) => ` $ ${name}${command.name === "" ? "" : ` ${command.name}`} --help`).join("\n")
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
let options = this.isGlobalCommand ? globalOptions : [...this.options, ...globalOptions || []];
|
|
351
|
-
if (!this.isGlobalCommand && !this.isDefaultCommand) {
|
|
352
|
-
options = options.filter((option) => option.name !== "version");
|
|
353
|
-
}
|
|
354
|
-
if (options.length > 0) {
|
|
355
|
-
const longestOptionName = findLongest(options.map((option) => option.rawName));
|
|
356
|
-
sections.push({
|
|
357
|
-
title: "Options",
|
|
358
|
-
body: options.map((option) => {
|
|
359
|
-
return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === void 0 ? "" : `(default: ${option.config.default})`}`;
|
|
360
|
-
}).join("\n")
|
|
374
|
+
const content = readFileSync(templatePath, "utf-8");
|
|
375
|
+
const outputPath = join(this.outputDir, "agents", agent.file);
|
|
376
|
+
configs.push({
|
|
377
|
+
id: agent.id,
|
|
378
|
+
path: outputPath,
|
|
379
|
+
content
|
|
361
380
|
});
|
|
362
381
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
382
|
+
return configs;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Generate skill configurations
|
|
386
|
+
*/
|
|
387
|
+
async generateSkills(skills) {
|
|
388
|
+
const configs = [];
|
|
389
|
+
for (const skill of skills) {
|
|
390
|
+
const templatePath = join(this.templatesDir, "skills", skill.file);
|
|
391
|
+
if (!existsSync(templatePath)) {
|
|
392
|
+
console.warn(`Skill template not found: ${skill.file}`);
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
const content = readFileSync(templatePath, "utf-8");
|
|
396
|
+
const outputPath = join(this.outputDir, "skills", skill.file);
|
|
397
|
+
configs.push({
|
|
398
|
+
id: skill.id,
|
|
399
|
+
path: outputPath,
|
|
400
|
+
content
|
|
372
401
|
});
|
|
373
402
|
}
|
|
374
|
-
|
|
375
|
-
|
|
403
|
+
return configs;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Write configurations to disk
|
|
407
|
+
*/
|
|
408
|
+
async write(config) {
|
|
409
|
+
const agentsDir = join(this.outputDir, "agents");
|
|
410
|
+
const skillsDir = join(this.outputDir, "skills");
|
|
411
|
+
if (!existsSync(agentsDir)) {
|
|
412
|
+
mkdirSync(agentsDir, { recursive: true });
|
|
376
413
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
${section.body}` : section.body;
|
|
380
|
-
}).join("\n\n"));
|
|
381
|
-
}
|
|
382
|
-
outputVersion() {
|
|
383
|
-
const {name} = this.cli;
|
|
384
|
-
const {versionNumber} = this.cli.globalCommand;
|
|
385
|
-
if (versionNumber) {
|
|
386
|
-
console.log(`${name}/${versionNumber} ${platformInfo}`);
|
|
414
|
+
if (!existsSync(skillsDir)) {
|
|
415
|
+
mkdirSync(skillsDir, { recursive: true });
|
|
387
416
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
417
|
+
for (const agent of config.agents) {
|
|
418
|
+
const dir = join(agent.path, "..");
|
|
419
|
+
if (!existsSync(dir)) {
|
|
420
|
+
mkdirSync(dir, { recursive: true });
|
|
421
|
+
}
|
|
422
|
+
writeFileSync(agent.path, agent.content, "utf-8");
|
|
393
423
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
for (const name of Object.keys(options)) {
|
|
399
|
-
if (name !== "--" && !this.hasOption(name) && !globalCommand.hasOption(name)) {
|
|
400
|
-
throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``);
|
|
401
|
-
}
|
|
424
|
+
for (const skill of config.skills) {
|
|
425
|
+
const dir = join(skill.path, "..");
|
|
426
|
+
if (!existsSync(dir)) {
|
|
427
|
+
mkdirSync(dir, { recursive: true });
|
|
402
428
|
}
|
|
429
|
+
writeFileSync(skill.path, skill.content, "utf-8");
|
|
403
430
|
}
|
|
404
431
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
}
|
|
432
|
+
/**
|
|
433
|
+
* Generate summary
|
|
434
|
+
*/
|
|
435
|
+
generateSummary(agents, skills) {
|
|
436
|
+
const lines = [];
|
|
437
|
+
lines.push("# Generated Configuration Summary\n");
|
|
438
|
+
lines.push(`Generated at: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
439
|
+
`);
|
|
440
|
+
lines.push("## Agents\n");
|
|
441
|
+
for (const agent of agents) {
|
|
442
|
+
lines.push(`- ${agent.id}: ${agent.path}`);
|
|
443
|
+
}
|
|
444
|
+
lines.push("\n## Skills\n");
|
|
445
|
+
for (const skill of skills) {
|
|
446
|
+
lines.push(`- ${skill.id}: ${skill.path}`);
|
|
416
447
|
}
|
|
448
|
+
lines.push("\n## Usage\n");
|
|
449
|
+
lines.push("1. Agents are automatically loaded by Claude Code");
|
|
450
|
+
lines.push("2. Skills can be triggered using their command triggers");
|
|
451
|
+
lines.push("3. Use `claude` command to start coding with AI assistance");
|
|
452
|
+
return lines.join("\n");
|
|
417
453
|
}
|
|
418
454
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
455
|
+
async function generateConfigs(selection) {
|
|
456
|
+
const generator = new ConfigGenerator();
|
|
457
|
+
return generator.generate(selection);
|
|
458
|
+
}
|
|
459
|
+
async function writeConfigs(config) {
|
|
460
|
+
const generator = new ConfigGenerator();
|
|
461
|
+
await generator.write(config);
|
|
423
462
|
}
|
|
424
463
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
this.
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
setParsedInfo({args, options}, matchedCommand, matchedCommandName) {
|
|
477
|
-
this.args = args;
|
|
478
|
-
this.options = options;
|
|
479
|
-
if (matchedCommand) {
|
|
480
|
-
this.matchedCommand = matchedCommand;
|
|
481
|
-
}
|
|
482
|
-
if (matchedCommandName) {
|
|
483
|
-
this.matchedCommandName = matchedCommandName;
|
|
484
|
-
}
|
|
485
|
-
return this;
|
|
486
|
-
}
|
|
487
|
-
unsetMatchedCommand() {
|
|
488
|
-
this.matchedCommand = void 0;
|
|
489
|
-
this.matchedCommandName = void 0;
|
|
490
|
-
}
|
|
491
|
-
parse(argv = processArgs, {
|
|
492
|
-
run = true
|
|
493
|
-
} = {}) {
|
|
494
|
-
this.rawArgs = argv;
|
|
495
|
-
if (!this.name) {
|
|
496
|
-
this.name = argv[1] ? getFileName(argv[1]) : "cli";
|
|
497
|
-
}
|
|
498
|
-
let shouldParse = true;
|
|
499
|
-
for (const command of this.commands) {
|
|
500
|
-
const parsed = this.mri(argv.slice(2), command);
|
|
501
|
-
const commandName = parsed.args[0];
|
|
502
|
-
if (command.isMatched(commandName)) {
|
|
503
|
-
shouldParse = false;
|
|
504
|
-
const parsedInfo = __assign(__assign({}, parsed), {
|
|
505
|
-
args: parsed.args.slice(1)
|
|
506
|
-
});
|
|
507
|
-
this.setParsedInfo(parsedInfo, command, commandName);
|
|
508
|
-
this.emit(`command:${commandName}`, command);
|
|
509
|
-
}
|
|
464
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
465
|
+
const __dirname = dirname(__filename);
|
|
466
|
+
class TemplateSelector {
|
|
467
|
+
templatesDir;
|
|
468
|
+
constructor(templatesDir) {
|
|
469
|
+
this.templatesDir = templatesDir || join(__dirname, "..", "..", "..", "templates");
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Select templates based on project analysis
|
|
473
|
+
*/
|
|
474
|
+
async select(analysis) {
|
|
475
|
+
const agents = await this.selectAgents(analysis);
|
|
476
|
+
const skills = await this.selectSkills(analysis);
|
|
477
|
+
return {
|
|
478
|
+
agents,
|
|
479
|
+
skills,
|
|
480
|
+
reasoning: this.generateReasoning(analysis, agents, skills)
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Select agent templates
|
|
485
|
+
*/
|
|
486
|
+
async selectAgents(analysis) {
|
|
487
|
+
const selectedAgents = [];
|
|
488
|
+
const agentIndex = this.loadAgentIndex();
|
|
489
|
+
switch (analysis.projectType) {
|
|
490
|
+
case "frontend":
|
|
491
|
+
selectedAgents.push(
|
|
492
|
+
...this.findAgentsByCategory(agentIndex, "frontend")
|
|
493
|
+
);
|
|
494
|
+
break;
|
|
495
|
+
case "backend":
|
|
496
|
+
selectedAgents.push(
|
|
497
|
+
...this.findAgentsByCategory(agentIndex, "backend")
|
|
498
|
+
);
|
|
499
|
+
break;
|
|
500
|
+
case "fullstack":
|
|
501
|
+
selectedAgents.push(
|
|
502
|
+
...this.findAgentsByCategory(agentIndex, "fullstack")
|
|
503
|
+
);
|
|
504
|
+
selectedAgents.push(
|
|
505
|
+
...this.findAgentsByCategory(agentIndex, "frontend").slice(0, 1),
|
|
506
|
+
...this.findAgentsByCategory(agentIndex, "backend").slice(0, 1)
|
|
507
|
+
);
|
|
508
|
+
break;
|
|
509
|
+
case "cli":
|
|
510
|
+
case "library":
|
|
511
|
+
selectedAgents.push(
|
|
512
|
+
...this.findAgentsByCategory(agentIndex, "backend")
|
|
513
|
+
);
|
|
514
|
+
break;
|
|
510
515
|
}
|
|
511
|
-
if (
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
const parsed = this.mri(argv.slice(2), command);
|
|
516
|
-
this.setParsedInfo(parsed, command);
|
|
517
|
-
this.emit(`command:!`, command);
|
|
518
|
-
}
|
|
519
|
-
}
|
|
516
|
+
if (analysis.hasTests) {
|
|
517
|
+
selectedAgents.push(
|
|
518
|
+
...this.findAgentsByCategory(agentIndex, "testing")
|
|
519
|
+
);
|
|
520
520
|
}
|
|
521
|
-
if (
|
|
522
|
-
|
|
523
|
-
|
|
521
|
+
if (analysis.cicd && analysis.cicd.length > 0) {
|
|
522
|
+
selectedAgents.push(
|
|
523
|
+
...this.findAgentsByCategory(agentIndex, "devops")
|
|
524
|
+
);
|
|
524
525
|
}
|
|
525
|
-
if (
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
526
|
+
if (analysis.hasApi || analysis.hasDatabase) {
|
|
527
|
+
selectedAgents.push(
|
|
528
|
+
...this.findAgentsByCategory(agentIndex, "security")
|
|
529
|
+
);
|
|
529
530
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
531
|
+
return this.deduplicateAndSort(selectedAgents);
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Select skill templates
|
|
535
|
+
*/
|
|
536
|
+
async selectSkills(analysis) {
|
|
537
|
+
const selectedSkills = [];
|
|
538
|
+
const skillIndex = this.loadSkillIndex();
|
|
539
|
+
selectedSkills.push(
|
|
540
|
+
...this.findSkillsByCategory(skillIndex, "git")
|
|
541
|
+
);
|
|
542
|
+
selectedSkills.push(
|
|
543
|
+
...this.findSkillsByCategory(skillIndex, "code-quality")
|
|
544
|
+
);
|
|
545
|
+
if (analysis.hasTests) {
|
|
546
|
+
selectedSkills.push(
|
|
547
|
+
...this.findSkillsByIds(skillIndex, ["generate-tests"])
|
|
548
|
+
);
|
|
534
549
|
}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
550
|
+
if (analysis.hasApi) {
|
|
551
|
+
selectedSkills.push(
|
|
552
|
+
...this.findSkillsByIds(skillIndex, ["api-docs"])
|
|
553
|
+
);
|
|
538
554
|
}
|
|
539
|
-
if (
|
|
540
|
-
|
|
555
|
+
if (analysis.hasDatabase) {
|
|
556
|
+
selectedSkills.push(
|
|
557
|
+
...this.findSkillsByIds(skillIndex, ["database-migration"])
|
|
558
|
+
);
|
|
541
559
|
}
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
...this.globalCommand.options,
|
|
547
|
-
...command ? command.options : []
|
|
548
|
-
];
|
|
549
|
-
const mriOptions = getMriOptions(cliOptions);
|
|
550
|
-
let argsAfterDoubleDashes = [];
|
|
551
|
-
const doubleDashesIndex = argv.indexOf("--");
|
|
552
|
-
if (doubleDashesIndex > -1) {
|
|
553
|
-
argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1);
|
|
554
|
-
argv = argv.slice(0, doubleDashesIndex);
|
|
555
|
-
}
|
|
556
|
-
let parsed = mri2(argv, mriOptions);
|
|
557
|
-
parsed = Object.keys(parsed).reduce((res, name) => {
|
|
558
|
-
return __assign(__assign({}, res), {
|
|
559
|
-
[camelcaseOptionName(name)]: parsed[name]
|
|
560
|
-
});
|
|
561
|
-
}, {_: []});
|
|
562
|
-
const args = parsed._;
|
|
563
|
-
const options = {
|
|
564
|
-
"--": argsAfterDoubleDashes
|
|
565
|
-
};
|
|
566
|
-
const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue;
|
|
567
|
-
let transforms = Object.create(null);
|
|
568
|
-
for (const cliOption of cliOptions) {
|
|
569
|
-
if (!ignoreDefault && cliOption.config.default !== void 0) {
|
|
570
|
-
for (const name of cliOption.names) {
|
|
571
|
-
options[name] = cliOption.config.default;
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
if (Array.isArray(cliOption.config.type)) {
|
|
575
|
-
if (transforms[cliOption.name] === void 0) {
|
|
576
|
-
transforms[cliOption.name] = Object.create(null);
|
|
577
|
-
transforms[cliOption.name]["shouldTransform"] = true;
|
|
578
|
-
transforms[cliOption.name]["transformFunction"] = cliOption.config.type[0];
|
|
579
|
-
}
|
|
580
|
-
}
|
|
560
|
+
if (analysis.projectType === "frontend" || analysis.projectType === "fullstack") {
|
|
561
|
+
selectedSkills.push(
|
|
562
|
+
...this.findSkillsByIds(skillIndex, ["performance-optimization"])
|
|
563
|
+
);
|
|
581
564
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
565
|
+
if (analysis.packageJson) {
|
|
566
|
+
selectedSkills.push(
|
|
567
|
+
...this.findSkillsByIds(skillIndex, ["dependency-update"])
|
|
568
|
+
);
|
|
569
|
+
}
|
|
570
|
+
selectedSkills.push(
|
|
571
|
+
...this.findSkillsByIds(skillIndex, ["refactor-code"])
|
|
572
|
+
);
|
|
573
|
+
return this.deduplicateAndSort(selectedSkills);
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Load agent index
|
|
577
|
+
*/
|
|
578
|
+
loadAgentIndex() {
|
|
579
|
+
try {
|
|
580
|
+
const indexPath = join(this.templatesDir, "agents", "index.json");
|
|
581
|
+
const content = readFileSync(indexPath, "utf-8");
|
|
582
|
+
return JSON.parse(content);
|
|
583
|
+
} catch {
|
|
584
|
+
return { templates: [] };
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Load skill index
|
|
589
|
+
*/
|
|
590
|
+
loadSkillIndex() {
|
|
591
|
+
try {
|
|
592
|
+
const indexPath = join(this.templatesDir, "skills", "index.json");
|
|
593
|
+
const content = readFileSync(indexPath, "utf-8");
|
|
594
|
+
return JSON.parse(content);
|
|
595
|
+
} catch {
|
|
596
|
+
return { templates: [] };
|
|
588
597
|
}
|
|
589
|
-
return {
|
|
590
|
-
args,
|
|
591
|
-
options
|
|
592
|
-
};
|
|
593
598
|
}
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
599
|
+
/**
|
|
600
|
+
* Find agents by category
|
|
601
|
+
*/
|
|
602
|
+
findAgentsByCategory(index, category) {
|
|
603
|
+
return index.templates.filter((agent) => agent.category === category);
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Find skills by category
|
|
607
|
+
*/
|
|
608
|
+
findSkillsByCategory(index, category) {
|
|
609
|
+
return index.templates.filter((skill) => skill.category === category);
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Find skills by IDs
|
|
613
|
+
*/
|
|
614
|
+
findSkillsByIds(index, ids) {
|
|
615
|
+
return index.templates.filter((skill) => ids.includes(skill.id));
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Deduplicate and sort templates by priority
|
|
619
|
+
*/
|
|
620
|
+
deduplicateAndSort(templates) {
|
|
621
|
+
const seen = /* @__PURE__ */ new Set();
|
|
622
|
+
const unique = [];
|
|
623
|
+
for (const template of templates) {
|
|
624
|
+
if (!seen.has(template.id)) {
|
|
625
|
+
seen.add(template.id);
|
|
626
|
+
unique.push(template);
|
|
607
627
|
}
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
|
|
628
|
+
}
|
|
629
|
+
return unique.sort((a, b) => b.priority - a.priority);
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Generate reasoning for template selection
|
|
633
|
+
*/
|
|
634
|
+
generateReasoning(analysis, agents, skills) {
|
|
635
|
+
const reasons = [];
|
|
636
|
+
reasons.push(`Detected ${analysis.projectType} project`);
|
|
637
|
+
if (analysis.frameworks.length > 0) {
|
|
638
|
+
reasons.push(`Using frameworks: ${analysis.frameworks.join(", ")}`);
|
|
639
|
+
}
|
|
640
|
+
reasons.push(`Tech stack: ${analysis.techStack.languages.join(", ")} on ${analysis.techStack.runtime}`);
|
|
641
|
+
if (analysis.hasTests) {
|
|
642
|
+
reasons.push("Tests detected - including test engineer and test generation");
|
|
643
|
+
}
|
|
644
|
+
if (analysis.hasDatabase) {
|
|
645
|
+
reasons.push("Database detected - including migration skills");
|
|
646
|
+
}
|
|
647
|
+
if (analysis.hasApi) {
|
|
648
|
+
reasons.push("API endpoints detected - including API documentation");
|
|
649
|
+
}
|
|
650
|
+
if (analysis.cicd && analysis.cicd.length > 0) {
|
|
651
|
+
reasons.push(`CI/CD detected (${analysis.cicd.join(", ")}) - including DevOps engineer`);
|
|
652
|
+
}
|
|
653
|
+
reasons.push(`
|
|
654
|
+
Selected ${agents.length} agents and ${skills.length} skills`);
|
|
655
|
+
return reasons.join("\n");
|
|
611
656
|
}
|
|
612
657
|
}
|
|
658
|
+
async function selectTemplates(analysis) {
|
|
659
|
+
const selector = new TemplateSelector();
|
|
660
|
+
return selector.select(analysis);
|
|
661
|
+
}
|
|
613
662
|
|
|
614
|
-
|
|
663
|
+
async function smartGenerate(projectRoot) {
|
|
664
|
+
const analysis = await analyzeProject(projectRoot);
|
|
665
|
+
const selection = await selectTemplates(analysis);
|
|
666
|
+
const config = await generateConfigs(selection);
|
|
667
|
+
return {
|
|
668
|
+
analysis,
|
|
669
|
+
selection,
|
|
670
|
+
config
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
async function smartGenerateAndInstall(projectRoot) {
|
|
674
|
+
const result = await smartGenerate(projectRoot);
|
|
675
|
+
await writeConfigs(result.config);
|
|
676
|
+
return result;
|
|
677
|
+
}
|
|
615
678
|
|
|
616
|
-
export {
|
|
679
|
+
export { ConfigGenerator, ProjectAnalyzer, TemplateSelector, analyzeProject, generateConfigs, selectTemplates, smartGenerate, smartGenerateAndInstall, writeConfigs };
|