infernoflow 0.37.1 → 0.37.3
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/CHANGELOG.md +64 -0
- package/dist/bin/infernoflow.mjs +29 -277
- package/dist/lib/adopters/angular.mjs +1 -128
- package/dist/lib/adopters/css.mjs +1 -111
- package/dist/lib/adopters/react.mjs +1 -104
- package/dist/lib/ai/ideDetection.mjs +1 -31
- package/dist/lib/ai/localProvider.mjs +1 -88
- package/dist/lib/ai/providerRouter.mjs +2 -295
- package/dist/lib/commands/adopt.mjs +20 -869
- package/dist/lib/commands/adoptWizard.mjs +9 -320
- package/dist/lib/commands/agent.mjs +5 -191
- package/dist/lib/commands/ai.mjs +2 -407
- package/dist/lib/commands/ask.mjs +4 -299
- package/dist/lib/commands/audit.mjs +13 -300
- package/dist/lib/commands/changelog.mjs +26 -594
- package/dist/lib/commands/check.mjs +3 -184
- package/dist/lib/commands/ci.mjs +3 -208
- package/dist/lib/commands/claudeMd.mjs +30 -135
- package/dist/lib/commands/cloud.mjs +10 -773
- package/dist/lib/commands/context.mjs +34 -346
- package/dist/lib/commands/coverage.mjs +2 -282
- package/dist/lib/commands/dashboard.mjs +123 -635
- package/dist/lib/commands/demo.mjs +8 -465
- package/dist/lib/commands/diff.mjs +5 -274
- package/dist/lib/commands/docGate.mjs +2 -81
- package/dist/lib/commands/doctor.mjs +3 -321
- package/dist/lib/commands/explain.mjs +8 -438
- package/dist/lib/commands/export.mjs +10 -239
- package/dist/lib/commands/feedback.mjs +12 -216
- package/dist/lib/commands/generateSkills.mjs +38 -163
- package/dist/lib/commands/graph.mjs +11 -378
- package/dist/lib/commands/health.mjs +2 -309
- package/dist/lib/commands/impact.mjs +2 -325
- package/dist/lib/commands/implement.mjs +7 -103
- package/dist/lib/commands/init.mjs +45 -631
- package/dist/lib/commands/installCursorHooks.mjs +1 -36
- package/dist/lib/commands/installVsCodeCopilotHooks.mjs +1 -37
- package/dist/lib/commands/link.mjs +2 -342
- package/dist/lib/commands/log.mjs +18 -248
- package/dist/lib/commands/monorepo.mjs +4 -428
- package/dist/lib/commands/notify.mjs +4 -258
- package/dist/lib/commands/onboard.mjs +4 -296
- package/dist/lib/commands/prComment.mjs +2 -361
- package/dist/lib/commands/prImpact.mjs +2 -157
- package/dist/lib/commands/publish.mjs +15 -316
- package/dist/lib/commands/recap.mjs +6 -380
- package/dist/lib/commands/report.mjs +28 -272
- package/dist/lib/commands/review.mjs +9 -223
- package/dist/lib/commands/run.mjs +8 -336
- package/dist/lib/commands/scaffold.mjs +54 -419
- package/dist/lib/commands/scan.mjs +11 -1118
- package/dist/lib/commands/scout.mjs +2 -291
- package/dist/lib/commands/setup.mjs +5 -310
- package/dist/lib/commands/share.mjs +13 -196
- package/dist/lib/commands/snapshot.mjs +3 -383
- package/dist/lib/commands/stability.mjs +2 -293
- package/dist/lib/commands/stats.mjs +5 -402
- package/dist/lib/commands/status.mjs +4 -172
- package/dist/lib/commands/suggest.mjs +21 -563
- package/dist/lib/commands/switch.mjs +13 -520
- package/dist/lib/commands/syncAuto.mjs +1 -96
- package/dist/lib/commands/synthesize.mjs +10 -228
- package/dist/lib/commands/teamSync.mjs +2 -388
- package/dist/lib/commands/test.mjs +6 -363
- package/dist/lib/commands/theme.mjs +18 -195
- package/dist/lib/commands/uninstall.mjs +13 -406
- package/dist/lib/commands/upgrade.mjs +20 -153
- package/dist/lib/commands/version.mjs +2 -282
- package/dist/lib/commands/vibe.mjs +7 -357
- package/dist/lib/commands/watch.mjs +4 -203
- package/dist/lib/commands/why.mjs +4 -358
- package/dist/lib/cursorHooksInstall.mjs +1 -60
- package/dist/lib/draftToolingInstall.mjs +7 -68
- package/dist/lib/git/detect-drift.mjs +4 -208
- package/dist/lib/learning/adapt.mjs +6 -101
- package/dist/lib/learning/observe.mjs +1 -119
- package/dist/lib/learning/patternDetector.mjs +1 -298
- package/dist/lib/learning/profile.mjs +2 -279
- package/dist/lib/learning/skillSynthesizer.mjs +24 -145
- package/dist/lib/telemetry.mjs +19 -269
- package/dist/lib/templates/index.mjs +1 -131
- package/dist/lib/theme/scanner.mjs +4 -343
- package/dist/lib/ui/errors.mjs +1 -142
- package/dist/lib/ui/output.mjs +6 -95
- package/dist/lib/ui/prompts.mjs +6 -147
- package/dist/lib/vsCodeCopilotHooksInstall.mjs +1 -42
- package/package.json +2 -4
- package/scripts/postinstall.js +2 -2
|
@@ -1,90 +1,40 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* Reads inferno/developer-profile.json and generates personalised skill files:
|
|
5
|
-
* - inferno/generated-skills/cursor-rules.md → copy to .cursor/rules/infernoflow.md
|
|
6
|
-
* - inferno/generated-skills/quick-restore.md → session startup skill
|
|
7
|
-
* - inferno/generated-skills/naming-guide.md → detected naming conventions
|
|
8
|
-
* - inferno/generated-skills/feature-scaffold.md → personal feature checklist
|
|
9
|
-
*
|
|
10
|
-
* Run: infernoflow generate-skills [--cursor] [--force]
|
|
11
|
-
* --cursor Also copy generated rules to .cursor/rules/infernoflow.md
|
|
12
|
-
* --force Overwrite existing generated files
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import * as fs from "node:fs";
|
|
16
|
-
import * as path from "node:path";
|
|
17
|
-
import { readProfile } from "../learning/profile.mjs";
|
|
18
|
-
import { header, ok, warn, done, nextSteps, cyan, yellow, bold, gray } from "../ui/output.mjs";
|
|
19
|
-
|
|
20
|
-
const SKILLS_DIR = path.join("inferno", "generated-skills");
|
|
21
|
-
|
|
22
|
-
function write(filePath, content, force) {
|
|
23
|
-
if (fs.existsSync(filePath) && !force) {
|
|
24
|
-
warn(`Already exists (use --force to overwrite): ${path.relative(process.cwd(), filePath)}`);
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
28
|
-
fs.writeFileSync(filePath, content, "utf8");
|
|
29
|
-
ok(`Generated: ${path.relative(process.cwd(), filePath)}`);
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function buildCursorRules(profile, contract) {
|
|
34
|
-
const naming = profile.namingStyle !== "unknown" ? profile.namingStyle : "PascalCase";
|
|
35
|
-
const verbs = profile.preferredVerbs.length > 0 ? profile.preferredVerbs.slice(0, 5).join(", ") : "Add, Update, Remove";
|
|
36
|
-
const framework = profile.stack?.framework || "unknown";
|
|
37
|
-
const clusters = profile.featureClusters.slice(0, 3);
|
|
38
|
-
const sessionStyle = profile.sessionCount >= 20 ? "experienced" : profile.sessionCount >= 5 ? "intermediate" : "new";
|
|
39
|
-
|
|
40
|
-
const clusterRules = clusters.map(cluster =>
|
|
41
|
-
`- When touching [${cluster.slice(0, 3).join(", ")}], check whether related capabilities also need updating`
|
|
42
|
-
).join("\n");
|
|
43
|
-
|
|
44
|
-
return `# infernoflow — Cursor Rules (auto-generated)
|
|
45
|
-
# Project: ${contract?.policyId || "unknown"} | Stack: ${framework}
|
|
1
|
+
import*as l from"node:fs";import*as s from"node:path";import{readProfile as k}from"../learning/profile.mjs";import{header as y,ok as w,warn as b,done as $,nextSteps as C,cyan as m,yellow as j}from"../ui/output.mjs";const p=s.join("inferno","generated-skills");function f(e,n,i){return l.existsSync(e)&&!i?(b(`Already exists (use --force to overwrite): ${s.relative(process.cwd(),e)}`),!1):(l.mkdirSync(s.dirname(e),{recursive:!0}),l.writeFileSync(e,n,"utf8"),w(`Generated: ${s.relative(process.cwd(),e)}`),!0)}function S(e,n){const i=e.namingStyle!=="unknown"?e.namingStyle:"PascalCase",r=e.preferredVerbs.length>0?e.preferredVerbs.slice(0,5).join(", "):"Add, Update, Remove",t=e.stack?.framework||"unknown",o=e.featureClusters.slice(0,3),a=e.sessionCount>=20?"experienced":e.sessionCount>=5?"intermediate":"new",c=o.map(u=>`- When touching [${u.slice(0,3).join(", ")}], check whether related capabilities also need updating`).join(`
|
|
2
|
+
`);return`# infernoflow \u2014 Cursor Rules (auto-generated)
|
|
3
|
+
# Project: ${n?.policyId||"unknown"} | Stack: ${t}
|
|
46
4
|
# Regenerate with: infernoflow generate-skills --cursor
|
|
47
5
|
|
|
48
6
|
## Contract awareness
|
|
49
7
|
- This project uses infernoflow to track capability contracts
|
|
50
8
|
- After implementing any feature, always call \`infernoflow_run\` then \`infernoflow_apply\`
|
|
51
9
|
- Run \`infernoflow_check\` before every commit
|
|
52
|
-
- Current capabilities: [${(
|
|
10
|
+
- Current capabilities: [${(n?.capabilities||[]).join(", ")}]
|
|
53
11
|
|
|
54
12
|
## Naming conventions (detected from this developer's history)
|
|
55
|
-
- Capability IDs use **${
|
|
56
|
-
- Preferred action verbs: ${
|
|
13
|
+
- Capability IDs use **${i}** (e.g. ${r.split(", ").slice(0,2).map(u=>u+"Item").join(", ")})
|
|
14
|
+
- Preferred action verbs: ${r}
|
|
57
15
|
- Match this style when suggesting new capability names
|
|
58
16
|
|
|
59
17
|
## Feature clusters (capabilities this developer adds together)
|
|
60
|
-
${
|
|
18
|
+
${c||"- No clusters detected yet \u2014 build more features to train this"}
|
|
61
19
|
|
|
62
|
-
## Session style (${
|
|
63
|
-
${
|
|
64
|
-
|
|
65
|
-
|
|
20
|
+
## Session style (${a})
|
|
21
|
+
${a==="experienced"?`- Skip basic explanations \u2014 this developer knows the codebase well
|
|
22
|
+
- Be direct and minimal in responses`:`- Include brief context for non-obvious decisions
|
|
23
|
+
- Explain infernoflow commands when used`}
|
|
66
24
|
|
|
67
25
|
## Workflow reminders
|
|
68
26
|
- Start sessions with: \`infernoflow context --show\`
|
|
69
27
|
- Use \`infernoflow_git_drift\` to check what's changed before starting work
|
|
70
28
|
- Use \`infernoflow_implement\` to get a structured coding prompt before writing code
|
|
71
|
-
- Changelog entries should be ${
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function buildQuickRestore(profile, contract) {
|
|
76
|
-
const working = ""; // will be filled at runtime from context-state.json
|
|
77
|
-
const framework = profile.stack?.framework || "unknown";
|
|
78
|
-
const capabilities = (contract?.capabilities || []).slice(0, 6);
|
|
79
|
-
|
|
80
|
-
return `# Quick Restore — ${contract?.policyId || "this project"}
|
|
29
|
+
- Changelog entries should be ${e.changelogVerbosity==="detailed"?"detailed (include context and impact)":"brief (one line, action-focused)"}
|
|
30
|
+
`}function R(e,n){const r=e.stack?.framework||"unknown",t=(n?.capabilities||[]).slice(0,6);return`# Quick Restore \u2014 ${n?.policyId||"this project"}
|
|
81
31
|
# Paste this at the start of any new AI session to restore context instantly.
|
|
82
32
|
# Regenerate with: infernoflow generate-skills
|
|
83
33
|
|
|
84
34
|
## Project snapshot
|
|
85
|
-
- **Project:** ${
|
|
86
|
-
- **Stack:** ${
|
|
87
|
-
- **Capabilities:** ${
|
|
35
|
+
- **Project:** ${n?.policyId||"unknown"}
|
|
36
|
+
- **Stack:** ${r} / ${e.stack?.language||"unknown"} (${e.stack?.projectType||"unknown"})
|
|
37
|
+
- **Capabilities:** ${t.join(", ")}${(n?.capabilities||[]).length>6?` +${(n?.capabilities||[]).length-6} more`:""}
|
|
88
38
|
|
|
89
39
|
## How to start a session
|
|
90
40
|
1. Run: \`infernoflow context --show\`
|
|
@@ -93,64 +43,42 @@ function buildQuickRestore(profile, contract) {
|
|
|
93
43
|
4. Pick up where you left off
|
|
94
44
|
|
|
95
45
|
## infernoflow tools available (in Cursor / VS Code Agent mode)
|
|
96
|
-
- \`infernoflow_run\`
|
|
97
|
-
- \`infernoflow_apply\`
|
|
98
|
-
- \`infernoflow_implement\`
|
|
99
|
-
- \`infernoflow_git_drift\`
|
|
100
|
-
- \`infernoflow_check\`
|
|
101
|
-
- \`infernoflow_status\`
|
|
46
|
+
- \`infernoflow_run\` \u2014 generate a contract update prompt
|
|
47
|
+
- \`infernoflow_apply\` \u2014 apply a JSON response
|
|
48
|
+
- \`infernoflow_implement\` \u2014 get a structured coding prompt
|
|
49
|
+
- \`infernoflow_git_drift\` \u2014 see what capabilities may have drifted
|
|
50
|
+
- \`infernoflow_check\` \u2014 validate contract is in sync
|
|
51
|
+
- \`infernoflow_status\` \u2014 quick health check
|
|
102
52
|
|
|
103
53
|
## Definition of done (every feature branch)
|
|
104
54
|
- [ ] Code works as intended
|
|
105
|
-
- [ ] \`infernoflow_run\`
|
|
55
|
+
- [ ] \`infernoflow_run\` \u2192 \`infernoflow_apply\` completed
|
|
106
56
|
- [ ] \`infernoflow_check\` passes
|
|
107
57
|
- [ ] Commit message references the capability changed
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
function buildNamingGuide(profile) {
|
|
112
|
-
const naming = profile.namingStyle !== "unknown" ? profile.namingStyle : "PascalCase";
|
|
113
|
-
const verbs = profile.preferredVerbs.length > 0 ? profile.preferredVerbs : ["Create", "Read", "Update", "Delete", "Search"];
|
|
114
|
-
|
|
115
|
-
const examples = verbs.slice(0, 5).map(v => {
|
|
116
|
-
if (naming === "PascalCase") return ` - ${v}Item, ${v}Task, ${v}User`;
|
|
117
|
-
if (naming === "camelCase") return ` - ${v.toLowerCase()}Item, ${v.toLowerCase()}Task`;
|
|
118
|
-
return ` - ${v.toLowerCase()}-item, ${v.toLowerCase()}-task`;
|
|
119
|
-
}).join("\n");
|
|
58
|
+
`}function _(e){const n=e.namingStyle!=="unknown"?e.namingStyle:"PascalCase",i=e.preferredVerbs.length>0?e.preferredVerbs:["Create","Read","Update","Delete","Search"],r=i.slice(0,5).map(t=>n==="PascalCase"?` - ${t}Item, ${t}Task, ${t}User`:n==="camelCase"?` - ${t.toLowerCase()}Item, ${t.toLowerCase()}Task`:` - ${t.toLowerCase()}-item, ${t.toLowerCase()}-task`).join(`
|
|
59
|
+
`);return`# Naming Guide \u2014 auto-generated from your capability history
|
|
120
60
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
## Detected style: ${naming}
|
|
61
|
+
## Detected style: ${n}
|
|
124
62
|
|
|
125
63
|
### Your preferred action verbs
|
|
126
|
-
${
|
|
64
|
+
${i.map(t=>`- **${t}**`).join(`
|
|
65
|
+
`)}
|
|
127
66
|
|
|
128
67
|
### Examples matching your style
|
|
129
|
-
${
|
|
68
|
+
${r}
|
|
130
69
|
|
|
131
70
|
### Rules
|
|
132
71
|
- All capability IDs in \`inferno/contract.json\` must follow this style
|
|
133
|
-
- New capabilities suggested by AI should match
|
|
72
|
+
- New capabilities suggested by AI should match \u2014 reject any that don't
|
|
134
73
|
- If you rename a capability, update contract.json + capabilities.json + any scenarios
|
|
135
74
|
|
|
136
75
|
### When naming a new capability, ask:
|
|
137
76
|
1. Does it describe a single, discrete behavior? (If not, split it)
|
|
138
77
|
2. Does it start with one of your preferred verbs?
|
|
139
|
-
3. Is it in ${
|
|
140
|
-
4. Is it unique
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function buildFeatureScaffold(profile, contract) {
|
|
145
|
-
const clusters = profile.featureClusters.slice(0, 2);
|
|
146
|
-
const topCluster = clusters[0] || [];
|
|
147
|
-
const framework = profile.stack?.framework || "unknown";
|
|
148
|
-
|
|
149
|
-
const clusterChecks = topCluster.slice(0, 4).map(id =>
|
|
150
|
-
`- [ ] Does **${id}** need updating? (check inferno/capabilities.json)`
|
|
151
|
-
).join("\n");
|
|
152
|
-
|
|
153
|
-
return `# Feature Scaffold — ${framework} project
|
|
78
|
+
3. Is it in ${n}?
|
|
79
|
+
4. Is it unique \u2014 not already in contract.json?
|
|
80
|
+
`}function I(e,n){const r=e.featureClusters.slice(0,2)[0]||[],t=e.stack?.framework||"unknown",o=r.slice(0,4).map(a=>`- [ ] Does **${a}** need updating? (check inferno/capabilities.json)`).join(`
|
|
81
|
+
`);return`# Feature Scaffold \u2014 ${t} project
|
|
154
82
|
# Use this checklist whenever starting a new feature.
|
|
155
83
|
# Regenerate with: infernoflow generate-skills
|
|
156
84
|
|
|
@@ -166,13 +94,13 @@ function buildFeatureScaffold(profile, contract) {
|
|
|
166
94
|
- [ ] Verify it works end-to-end
|
|
167
95
|
|
|
168
96
|
## Capability cluster check
|
|
169
|
-
${
|
|
97
|
+
${o||"- [ ] Review existing capabilities \u2014 do any need updating?"}
|
|
170
98
|
|
|
171
99
|
## Contract update (required before merge)
|
|
172
100
|
- [ ] Run \`infernoflow_run\` with a description of what changed
|
|
173
101
|
- [ ] Review the suggested JSON
|
|
174
102
|
- [ ] Run \`infernoflow_apply\` with the JSON
|
|
175
|
-
- [ ] Run \`infernoflow_check\`
|
|
103
|
+
- [ ] Run \`infernoflow_check\` \u2014 must pass
|
|
176
104
|
|
|
177
105
|
## Commit message
|
|
178
106
|
- Reference the capability: "feat: add SearchItems endpoint (#42)"
|
|
@@ -182,58 +110,5 @@ ${clusterChecks || "- [ ] Review existing capabilities — do any need updating?
|
|
|
182
110
|
- [ ] Feature works
|
|
183
111
|
- [ ] \`infernoflow_check\` passes
|
|
184
112
|
- [ ] PR description mentions which capabilities changed
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
export async function generateSkillsCommand(args) {
|
|
189
|
-
const cwd = process.cwd();
|
|
190
|
-
const force = args.includes("--force") || args.includes("-f");
|
|
191
|
-
const installCursor = args.includes("--cursor");
|
|
192
|
-
|
|
193
|
-
header("generate-skills");
|
|
194
|
-
|
|
195
|
-
const infernoDir = path.join(cwd, "inferno");
|
|
196
|
-
if (!fs.existsSync(infernoDir)) {
|
|
197
|
-
console.error(" ✘ inferno/ not found — run: infernoflow init\n");
|
|
198
|
-
process.exit(1);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
const profile = readProfile(infernoDir);
|
|
202
|
-
let contract = null;
|
|
203
|
-
try { contract = JSON.parse(fs.readFileSync(path.join(infernoDir, "contract.json"), "utf8")); } catch {}
|
|
204
|
-
|
|
205
|
-
const skillsDir = path.join(cwd, SKILLS_DIR);
|
|
206
|
-
|
|
207
|
-
// Generate all four skill files
|
|
208
|
-
write(path.join(skillsDir, "cursor-rules.md"), buildCursorRules(profile, contract), force);
|
|
209
|
-
write(path.join(skillsDir, "quick-restore.md"), buildQuickRestore(profile, contract), force);
|
|
210
|
-
write(path.join(skillsDir, "naming-guide.md"), buildNamingGuide(profile), force);
|
|
211
|
-
write(path.join(skillsDir, "feature-scaffold.md"), buildFeatureScaffold(profile, contract), force);
|
|
212
|
-
|
|
213
|
-
// Optionally install cursor rules
|
|
214
|
-
if (installCursor) {
|
|
215
|
-
const rulesDir = path.join(cwd, ".cursor", "rules");
|
|
216
|
-
fs.mkdirSync(rulesDir, { recursive: true });
|
|
217
|
-
const src = path.join(skillsDir, "cursor-rules.md");
|
|
218
|
-
const dst = path.join(rulesDir, "infernoflow.md");
|
|
219
|
-
fs.copyFileSync(src, dst);
|
|
220
|
-
ok(`Installed to: .cursor/rules/infernoflow.md`);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
const profileSummary = [
|
|
224
|
-
profile.namingStyle !== "unknown" ? `naming: ${profile.namingStyle}` : null,
|
|
225
|
-
profile.stack?.framework !== "unknown" ? `stack: ${profile.stack.framework}` : null,
|
|
226
|
-
profile.sessionCount > 0 ? `sessions: ${profile.sessionCount}` : null,
|
|
227
|
-
].filter(Boolean).join(" · ");
|
|
228
|
-
|
|
229
|
-
done(`Skills generated${profileSummary ? ` (${profileSummary})` : ""}`);
|
|
230
|
-
|
|
231
|
-
nextSteps([
|
|
232
|
-
`Review files in ${yellow(SKILLS_DIR + "/")}`,
|
|
233
|
-
`Copy to Cursor: ${cyan("infernoflow generate-skills --cursor")}`,
|
|
234
|
-
`Re-run any time to refresh after more sessions: ${cyan("infernoflow generate-skills --force")}`,
|
|
235
|
-
profile.sessionCount < 5
|
|
236
|
-
? `Run more commands to improve personalisation (${profile.sessionCount} sessions so far)`
|
|
237
|
-
: `Profile has ${profile.sessionCount} sessions — personalisation is well-trained`,
|
|
238
|
-
]);
|
|
239
|
-
}
|
|
113
|
+
`}async function A(e){const n=process.cwd(),i=e.includes("--force")||e.includes("-f"),r=e.includes("--cursor");y("generate-skills");const t=s.join(n,"inferno");l.existsSync(t)||(console.error(` \u2718 inferno/ not found \u2014 run: infernoflow init
|
|
114
|
+
`),process.exit(1));const o=k(t);let a=null;try{a=JSON.parse(l.readFileSync(s.join(t,"contract.json"),"utf8"))}catch{}const c=s.join(n,p);if(f(s.join(c,"cursor-rules.md"),S(o,a),i),f(s.join(c,"quick-restore.md"),R(o,a),i),f(s.join(c,"naming-guide.md"),_(o),i),f(s.join(c,"feature-scaffold.md"),I(o,a),i),r){const d=s.join(n,".cursor","rules");l.mkdirSync(d,{recursive:!0});const h=s.join(c,"cursor-rules.md"),g=s.join(d,"infernoflow.md");l.copyFileSync(h,g),w("Installed to: .cursor/rules/infernoflow.md")}const u=[o.namingStyle!=="unknown"?`naming: ${o.namingStyle}`:null,o.stack?.framework!=="unknown"?`stack: ${o.stack.framework}`:null,o.sessionCount>0?`sessions: ${o.sessionCount}`:null].filter(Boolean).join(" \xB7 ");$(`Skills generated${u?` (${u})`:""}`),C([`Review files in ${j(p+"/")}`,`Copy to Cursor: ${m("infernoflow generate-skills --cursor")}`,`Re-run any time to refresh after more sessions: ${m("infernoflow generate-skills --force")}`,o.sessionCount<5?`Run more commands to improve personalisation (${o.sessionCount} sessions so far)`:`Profile has ${o.sessionCount} sessions \u2014 personalisation is well-trained`])}export{A as generateSkillsCommand};
|