refacil-sdd-ai 2.2.1 → 2.6.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/README.md +150 -2
- package/bin/cli.js +204 -33
- package/lib/compact/bash.js +50 -0
- package/lib/compact/rules.js +190 -0
- package/lib/compact/telemetry.js +93 -0
- package/lib/compact-guidance.js +77 -0
- package/package.json +2 -1
- package/skills/apply/SKILL.md +2 -6
- package/skills/archive/SKILL.md +1 -4
- package/skills/bug/SKILL.md +9 -42
- package/skills/explore/SKILL.md +1 -3
- package/skills/prereqs/SKILL.md +16 -25
- package/skills/propose/SKILL.md +1 -3
- package/skills/review/SKILL.md +9 -47
- package/skills/setup/SKILL.md +6 -0
- package/skills/test/SKILL.md +10 -23
- package/skills/up-code/SKILL.md +5 -10
- package/skills/verify/SKILL.md +1 -4
- package/templates/compact-guidance.md +45 -0
- package/templates/{claude-md.md → methodology-guide.md} +10 -6
- package/templates/cursorrules.md +0 -22
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
function hasFlagAfterBase(cmd, baseTokens) {
|
|
2
|
+
const tokens = cmd.trim().split(/\s+/);
|
|
3
|
+
return tokens.slice(baseTokens).some((t) => t.startsWith('-'));
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function hasPipeOrRedirect(cmd) {
|
|
7
|
+
return /[|><]/.test(cmd);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const RULES = [
|
|
11
|
+
// --- Fase 1: git / tests / docker logs ---
|
|
12
|
+
{
|
|
13
|
+
id: 'git-log',
|
|
14
|
+
match: (cmd) =>
|
|
15
|
+
/^\s*git\s+log(\s|$)/.test(cmd) && !hasFlagAfterBase(cmd, 2),
|
|
16
|
+
rewrite: (cmd) => cmd.replace(/^(\s*git\s+log)/, '$1 --oneline -20'),
|
|
17
|
+
reason: 'git log → --oneline -20',
|
|
18
|
+
savedTokensEst: 850,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: 'git-status',
|
|
22
|
+
match: (cmd) =>
|
|
23
|
+
/^\s*git\s+status(\s|$)/.test(cmd) && !hasFlagAfterBase(cmd, 2),
|
|
24
|
+
rewrite: (cmd) => cmd.replace(/^(\s*git\s+status)/, '$1 -s'),
|
|
25
|
+
reason: 'git status → -s',
|
|
26
|
+
savedTokensEst: 120,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: 'git-diff',
|
|
30
|
+
match: (cmd) => /^\s*git\s+diff\s*$/.test(cmd),
|
|
31
|
+
rewrite: (cmd) => cmd.replace(/^(\s*git\s+diff)\s*$/, '$1 --stat'),
|
|
32
|
+
reason: 'git diff → --stat',
|
|
33
|
+
savedTokensEst: 400,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: 'git-show',
|
|
37
|
+
match: (cmd) =>
|
|
38
|
+
/^\s*git\s+show(\s|$)/.test(cmd) && !hasFlagAfterBase(cmd, 2),
|
|
39
|
+
rewrite: (cmd) => cmd.replace(/^(\s*git\s+show)/, '$1 --stat'),
|
|
40
|
+
reason: 'git show → --stat',
|
|
41
|
+
savedTokensEst: 200,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: 'docker-logs',
|
|
45
|
+
match: (cmd) => {
|
|
46
|
+
if (!/^\s*docker\s+logs(\s|$)/.test(cmd)) return false;
|
|
47
|
+
if (/\s--tail\b/.test(cmd)) return false;
|
|
48
|
+
if (/\s-n\s+\d/.test(cmd)) return false;
|
|
49
|
+
if (/\s--since\b/.test(cmd)) return false;
|
|
50
|
+
return true;
|
|
51
|
+
},
|
|
52
|
+
rewrite: (cmd) => cmd.replace(/^(\s*docker\s+logs)/, '$1 --tail 100'),
|
|
53
|
+
reason: 'docker logs → --tail 100',
|
|
54
|
+
savedTokensEst: 1500,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 'pkg-test',
|
|
58
|
+
match: (cmd) => /^\s*(npm|yarn|pnpm)\s+(test|t)\s*$/.test(cmd),
|
|
59
|
+
rewrite: (cmd) => `${cmd.trim()} 2>&1 | tail -80`,
|
|
60
|
+
reason: 'test bare → tail -80',
|
|
61
|
+
savedTokensEst: 2400,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: 'jest-bare',
|
|
65
|
+
match: (cmd) => /^\s*(npx\s+)?jest\s*$/.test(cmd),
|
|
66
|
+
rewrite: (cmd) =>
|
|
67
|
+
cmd.replace(/^(\s*(?:npx\s+)?jest)\s*$/, '$1 --silent --reporters=summary'),
|
|
68
|
+
reason: 'jest → silent summary',
|
|
69
|
+
savedTokensEst: 1800,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: 'pytest-bare',
|
|
73
|
+
match: (cmd) => /^\s*pytest\s*$/.test(cmd),
|
|
74
|
+
rewrite: (cmd) => cmd.replace(/^(\s*pytest)\s*$/, '$1 -q'),
|
|
75
|
+
reason: 'pytest → -q',
|
|
76
|
+
savedTokensEst: 600,
|
|
77
|
+
},
|
|
78
|
+
// --- Fase 2A: linters / type checkers / build ---
|
|
79
|
+
{
|
|
80
|
+
id: 'eslint',
|
|
81
|
+
match: (cmd) => /^\s*eslint(\s+[^-]\S*)*\s*$/.test(cmd),
|
|
82
|
+
rewrite: (cmd) => {
|
|
83
|
+
const tokens = cmd.trim().split(/\s+/);
|
|
84
|
+
if (tokens.length === 1) {
|
|
85
|
+
return 'eslint . --format compact --quiet';
|
|
86
|
+
}
|
|
87
|
+
return `${cmd.trim()} --format compact`;
|
|
88
|
+
},
|
|
89
|
+
reason: 'eslint → --format compact',
|
|
90
|
+
savedTokensEst: 700,
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: 'biome-check',
|
|
94
|
+
match: (cmd) =>
|
|
95
|
+
/^\s*biome\s+check(\s|$)/.test(cmd) && !/--reporter\b/.test(cmd),
|
|
96
|
+
rewrite: (cmd) =>
|
|
97
|
+
cmd.replace(/^(\s*biome\s+check)/, '$1 --reporter=summary'),
|
|
98
|
+
reason: 'biome check → --reporter=summary',
|
|
99
|
+
savedTokensEst: 500,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
id: 'tsc',
|
|
103
|
+
match: (cmd) => {
|
|
104
|
+
if (!/^\s*(npx\s+)?tsc(\s|$)/.test(cmd)) return false;
|
|
105
|
+
if (/(^|\s)--watch\b|(^|\s)-w\b/.test(cmd)) return false;
|
|
106
|
+
if (hasPipeOrRedirect(cmd)) return false;
|
|
107
|
+
return true;
|
|
108
|
+
},
|
|
109
|
+
rewrite: (cmd) => `${cmd.trim()} 2>&1 | head -80`,
|
|
110
|
+
reason: 'tsc → head -80',
|
|
111
|
+
savedTokensEst: 1200,
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
id: 'prettier-check',
|
|
115
|
+
match: (cmd) =>
|
|
116
|
+
/^\s*prettier\s+--check\b/.test(cmd) && !/--loglevel\b/.test(cmd),
|
|
117
|
+
rewrite: (cmd) =>
|
|
118
|
+
cmd.replace(/^(\s*prettier\s+--check)/, '$1 --loglevel warn'),
|
|
119
|
+
reason: 'prettier --check → --loglevel warn',
|
|
120
|
+
savedTokensEst: 300,
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
id: 'npm-audit',
|
|
124
|
+
match: (cmd) => /^\s*npm\s+audit\s*$/.test(cmd),
|
|
125
|
+
rewrite: (cmd) => `${cmd.trim()} 2>&1 | tail -10`,
|
|
126
|
+
reason: 'npm audit → tail -10',
|
|
127
|
+
savedTokensEst: 900,
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
id: 'npm-ls',
|
|
131
|
+
match: (cmd) => /^\s*npm\s+ls\s*$/.test(cmd),
|
|
132
|
+
rewrite: (cmd) => cmd.replace(/^(\s*npm\s+ls)/, '$1 --depth=0'),
|
|
133
|
+
reason: 'npm ls → --depth=0',
|
|
134
|
+
savedTokensEst: 700,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
id: 'cargo-bare',
|
|
138
|
+
match: (cmd) => /^\s*cargo\s+(build|test|check)\s*$/.test(cmd),
|
|
139
|
+
rewrite: (cmd) => `${cmd.trim()} --quiet`,
|
|
140
|
+
reason: 'cargo → --quiet',
|
|
141
|
+
savedTokensEst: 400,
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
id: 'go-test',
|
|
145
|
+
match: (cmd) => {
|
|
146
|
+
if (!/^\s*go\s+test\b/.test(cmd)) return false;
|
|
147
|
+
const rest = cmd.trim().substring('go test'.length);
|
|
148
|
+
if (/\s-\S/.test(rest)) return false;
|
|
149
|
+
if (hasPipeOrRedirect(cmd)) return false;
|
|
150
|
+
return true;
|
|
151
|
+
},
|
|
152
|
+
rewrite: (cmd) => `${cmd.trim()} 2>&1 | tail -80`,
|
|
153
|
+
reason: 'go test → tail -80',
|
|
154
|
+
savedTokensEst: 1500,
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
id: 'mvn-test',
|
|
158
|
+
match: (cmd) => /^\s*mvn\s+test\s*$/.test(cmd),
|
|
159
|
+
rewrite: (cmd) => `${cmd.trim()} -q`,
|
|
160
|
+
reason: 'mvn test → -q',
|
|
161
|
+
savedTokensEst: 1800,
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
id: 'gradle-test',
|
|
165
|
+
match: (cmd) => /^\s*(\.\/gradlew|gradle)\s+test\s*$/.test(cmd),
|
|
166
|
+
rewrite: (cmd) => `${cmd.trim()} -q`,
|
|
167
|
+
reason: 'gradle test → -q',
|
|
168
|
+
savedTokensEst: 1500,
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
id: 'ps-aux',
|
|
172
|
+
// Unix-only: en Windows `ps` mapea a PowerShell Get-Process y no entiende estos flags
|
|
173
|
+
match: (cmd) =>
|
|
174
|
+
process.platform !== 'win32' && /^\s*ps\s+aux\s*$/.test(cmd),
|
|
175
|
+
rewrite: () => 'ps -eo pid,pcpu,pmem,comm | head -30',
|
|
176
|
+
reason: 'ps aux → compact columns + head -30',
|
|
177
|
+
savedTokensEst: 800,
|
|
178
|
+
},
|
|
179
|
+
];
|
|
180
|
+
|
|
181
|
+
function findRule(cmd) {
|
|
182
|
+
if (typeof cmd !== 'string' || !cmd.trim()) return null;
|
|
183
|
+
if (/\bCOMPACT=0\b/.test(cmd)) return null;
|
|
184
|
+
for (const rule of RULES) {
|
|
185
|
+
if (rule.match(cmd)) return rule;
|
|
186
|
+
}
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
module.exports = { RULES, findRule };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
|
|
5
|
+
const HOME_DIR = path.join(os.homedir(), '.refacil-sdd-ai');
|
|
6
|
+
const LOG_PATH = path.join(HOME_DIR, 'compact.log');
|
|
7
|
+
const DISABLED_PATH = path.join(HOME_DIR, 'disabled');
|
|
8
|
+
|
|
9
|
+
function ensureDir() {
|
|
10
|
+
try {
|
|
11
|
+
fs.mkdirSync(HOME_DIR, { recursive: true });
|
|
12
|
+
} catch (_) {}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function isDisabled() {
|
|
16
|
+
return fs.existsSync(DISABLED_PATH);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function logRewrite(ruleId, savedTokensEst) {
|
|
20
|
+
try {
|
|
21
|
+
ensureDir();
|
|
22
|
+
const line =
|
|
23
|
+
JSON.stringify({
|
|
24
|
+
ts: new Date().toISOString(),
|
|
25
|
+
ruleId,
|
|
26
|
+
savedTokensEst: savedTokensEst || 0,
|
|
27
|
+
}) + '\n';
|
|
28
|
+
fs.appendFileSync(LOG_PATH, line);
|
|
29
|
+
} catch (_) {
|
|
30
|
+
// Telemetry must never break the hook
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function readLog() {
|
|
35
|
+
try {
|
|
36
|
+
const content = fs.readFileSync(LOG_PATH, 'utf8');
|
|
37
|
+
return content
|
|
38
|
+
.split('\n')
|
|
39
|
+
.filter(Boolean)
|
|
40
|
+
.map((line) => {
|
|
41
|
+
try {
|
|
42
|
+
return JSON.parse(line);
|
|
43
|
+
} catch (_) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
.filter(Boolean);
|
|
48
|
+
} catch (_) {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function stats() {
|
|
54
|
+
const entries = readLog();
|
|
55
|
+
const byRule = {};
|
|
56
|
+
let totalSaved = 0;
|
|
57
|
+
for (const e of entries) {
|
|
58
|
+
if (!byRule[e.ruleId]) byRule[e.ruleId] = { count: 0, saved: 0 };
|
|
59
|
+
byRule[e.ruleId].count++;
|
|
60
|
+
byRule[e.ruleId].saved += e.savedTokensEst || 0;
|
|
61
|
+
totalSaved += e.savedTokensEst || 0;
|
|
62
|
+
}
|
|
63
|
+
return { byRule, totalSaved, totalRewrites: entries.length };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function disable() {
|
|
67
|
+
ensureDir();
|
|
68
|
+
fs.writeFileSync(DISABLED_PATH, new Date().toISOString());
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function enable() {
|
|
72
|
+
try {
|
|
73
|
+
fs.unlinkSync(DISABLED_PATH);
|
|
74
|
+
} catch (_) {}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function clearLog() {
|
|
78
|
+
try {
|
|
79
|
+
fs.unlinkSync(LOG_PATH);
|
|
80
|
+
} catch (_) {}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
module.exports = {
|
|
84
|
+
HOME_DIR,
|
|
85
|
+
LOG_PATH,
|
|
86
|
+
DISABLED_PATH,
|
|
87
|
+
isDisabled,
|
|
88
|
+
logRewrite,
|
|
89
|
+
stats,
|
|
90
|
+
disable,
|
|
91
|
+
enable,
|
|
92
|
+
clearLog,
|
|
93
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const MARKER_START = '<!-- refacil-sdd-ai:compact-guidance:start -->';
|
|
5
|
+
const MARKER_END = '<!-- refacil-sdd-ai:compact-guidance:end -->';
|
|
6
|
+
|
|
7
|
+
function readTemplate(packageRoot) {
|
|
8
|
+
const tplPath = path.join(packageRoot, 'templates', 'compact-guidance.md');
|
|
9
|
+
return fs.readFileSync(tplPath, 'utf8').trimEnd();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function buildBlock(templateContent) {
|
|
13
|
+
return `${MARKER_START}\n${templateContent}\n${MARKER_END}`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function syncCompactGuidance(projectRoot, packageRoot) {
|
|
17
|
+
const agentsPath = path.join(projectRoot, 'AGENTS.md');
|
|
18
|
+
if (!fs.existsSync(agentsPath)) {
|
|
19
|
+
return { status: 'skipped-no-agents-md' };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const template = readTemplate(packageRoot);
|
|
23
|
+
const block = buildBlock(template);
|
|
24
|
+
const existing = fs.readFileSync(agentsPath, 'utf8');
|
|
25
|
+
|
|
26
|
+
const startIdx = existing.indexOf(MARKER_START);
|
|
27
|
+
const endIdx = existing.indexOf(MARKER_END);
|
|
28
|
+
|
|
29
|
+
let next;
|
|
30
|
+
let action;
|
|
31
|
+
|
|
32
|
+
if (startIdx === -1 || endIdx === -1) {
|
|
33
|
+
next = existing.trimEnd() + '\n\n' + block + '\n';
|
|
34
|
+
action = 'appended';
|
|
35
|
+
} else {
|
|
36
|
+
const before = existing.substring(0, startIdx);
|
|
37
|
+
const after = existing.substring(endIdx + MARKER_END.length);
|
|
38
|
+
next = before + block + after;
|
|
39
|
+
action = 'replaced';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (next === existing) {
|
|
43
|
+
return { status: 'unchanged' };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
fs.writeFileSync(agentsPath, next);
|
|
47
|
+
return { status: action };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function removeCompactGuidance(projectRoot) {
|
|
51
|
+
const agentsPath = path.join(projectRoot, 'AGENTS.md');
|
|
52
|
+
if (!fs.existsSync(agentsPath)) {
|
|
53
|
+
return { status: 'skipped-no-agents-md' };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const existing = fs.readFileSync(agentsPath, 'utf8');
|
|
57
|
+
const startIdx = existing.indexOf(MARKER_START);
|
|
58
|
+
const endIdx = existing.indexOf(MARKER_END);
|
|
59
|
+
|
|
60
|
+
if (startIdx === -1 || endIdx === -1) {
|
|
61
|
+
return { status: 'not-present' };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const before = existing.substring(0, startIdx).trimEnd();
|
|
65
|
+
const after = existing.substring(endIdx + MARKER_END.length);
|
|
66
|
+
const next = (before + '\n' + after.replace(/^\s+/, '')).trimEnd() + '\n';
|
|
67
|
+
|
|
68
|
+
fs.writeFileSync(agentsPath, next);
|
|
69
|
+
return { status: 'removed' };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
module.exports = {
|
|
73
|
+
syncCompactGuidance,
|
|
74
|
+
removeCompactGuidance,
|
|
75
|
+
MARKER_START,
|
|
76
|
+
MARKER_END,
|
|
77
|
+
};
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "refacil-sdd-ai",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "SDD-AI: Specification-Driven Development with AI — metodologia de desarrollo con IA usando OpenSpec, Claude Code y Cursor",
|
|
5
5
|
"bin": {
|
|
6
6
|
"refacil-sdd-ai": "./bin/cli.js"
|
|
7
7
|
},
|
|
8
8
|
"files": [
|
|
9
9
|
"bin/",
|
|
10
|
+
"lib/",
|
|
10
11
|
"skills/",
|
|
11
12
|
"templates/",
|
|
12
13
|
"config/",
|
package/skills/apply/SKILL.md
CHANGED
|
@@ -8,10 +8,7 @@ user-invocable: true
|
|
|
8
8
|
|
|
9
9
|
Este comando envuelve la funcionalidad de OpenSpec apply y agrega las convenciones del equipo.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Lee `SKILL.md` en `.claude/skills/refacil-prereqs/` o `.cursor/skills/refacil-prereqs/` (misma skill en Claude Code y Cursor) y aplica el **perfil `openspec`** antes de continuar.
|
|
14
|
-
Lee `METHODOLOGY-CONTRACT.md` en `refacil-prereqs` para reglas transversales del flujo.
|
|
11
|
+
**Prerequisitos**: perfil `openspec` de `refacil-prereqs/SKILL.md` + reglas de `METHODOLOGY-CONTRACT.md`.
|
|
15
12
|
|
|
16
13
|
## Instrucciones
|
|
17
14
|
|
|
@@ -79,7 +76,6 @@ Al terminar la implementacion de OpenSpec, agrega este resumen:
|
|
|
79
76
|
|
|
80
77
|
## Reglas
|
|
81
78
|
|
|
82
|
-
- NUNCA implementar codigo sin proposal, design, tasks y **especificacion** (`specs.md` y/o `specs/**/*.md` segun la tabla del Paso 0)
|
|
83
79
|
- NUNCA generar artefactos SDD desde este comando — eso es responsabilidad exclusiva de `/refacil:propose`
|
|
84
|
-
-
|
|
80
|
+
- Antes de implementar, cumplir las precondiciones del Paso 0 (artefactos completos) y del Paso 1 (rama de trabajo valida)
|
|
85
81
|
- Si `openspec/changes/` no tiene cambios activos o estan incompletos, informar y redirigir a `/refacil:propose`
|
package/skills/archive/SKILL.md
CHANGED
|
@@ -8,10 +8,7 @@ user-invocable: true
|
|
|
8
8
|
|
|
9
9
|
Este comando envuelve la funcionalidad de OpenSpec archive (que internamente llama a sync-specs) y agrega verificaciones previas del equipo.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Lee `SKILL.md` en `.claude/skills/refacil-prereqs/` o `.cursor/skills/refacil-prereqs/` (misma skill en Claude Code y Cursor) y aplica el **perfil `openspec`** antes de continuar.
|
|
14
|
-
Lee `METHODOLOGY-CONTRACT.md` en `refacil-prereqs` para reglas transversales del flujo.
|
|
11
|
+
**Prerequisitos**: perfil `openspec` de `refacil-prereqs/SKILL.md` + reglas de `METHODOLOGY-CONTRACT.md`.
|
|
15
12
|
|
|
16
13
|
## Instrucciones
|
|
17
14
|
|
package/skills/bug/SKILL.md
CHANGED
|
@@ -8,10 +8,7 @@ user-invocable: true
|
|
|
8
8
|
|
|
9
9
|
Eres un asistente especializado en investigacion y correccion de bugs. Guias al desarrollador por un flujo estructurado paso a paso.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Lee `SKILL.md` en `.claude/skills/refacil-prereqs/` o `.cursor/skills/refacil-prereqs/` (misma skill en Claude Code y Cursor) y aplica el **perfil `agents`** antes de continuar.
|
|
14
|
-
Lee `METHODOLOGY-CONTRACT.md` en `refacil-prereqs` para reglas transversales del flujo.
|
|
11
|
+
**Prerequisitos**: perfil `agents` de `refacil-prereqs/SKILL.md` + reglas de `METHODOLOGY-CONTRACT.md`.
|
|
15
12
|
|
|
16
13
|
## Instrucciones
|
|
17
14
|
|
|
@@ -29,52 +26,22 @@ Este flujo crea evidencia en `openspec/changes/`. Antes de continuar:
|
|
|
29
26
|
|
|
30
27
|
### Paso 1: Describir el bug
|
|
31
28
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
1. **Que esta pasando?** — Comportamiento actual (el error)
|
|
35
|
-
2. **Que deberia pasar?** — Comportamiento esperado
|
|
36
|
-
3. **Pasos para reproducir** — Como llegar al error
|
|
37
|
-
4. **Evidencia** — Logs, screenshots, stack traces (pedir que los peguen)
|
|
38
|
-
5. **Desde cuando ocurre?** — Siempre, desde un deploy, desde un cambio especifico
|
|
39
|
-
6. **Severidad** — Critico (bloquea produccion), Alto, Medio, Bajo
|
|
40
|
-
|
|
41
|
-
### Paso 2: Investigar la causa raiz
|
|
42
|
-
|
|
43
|
-
Con la informacion del paso 1:
|
|
29
|
+
Si `$ARGUMENTS` no los trae, pregunta al usuario: comportamiento actual, esperado, pasos de reproduccion, evidencia (logs/stack traces), cuando empezo a ocurrir, severidad (Critico/Alto/Medio/Bajo).
|
|
44
30
|
|
|
45
|
-
|
|
46
|
-
- Busca las funciones/archivos mencionados en los logs o stack traces
|
|
47
|
-
- Busca el flujo de datos del escenario que falla
|
|
48
|
-
- Revisa commits recientes si el bug es nuevo (`git log --oneline -20`)
|
|
31
|
+
### Paso 2: Investigar causa raiz
|
|
49
32
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
3. **Formular hipotesis**:
|
|
56
|
-
- Presenta al usuario 1-3 hipotesis de causa raiz
|
|
57
|
-
- Para cada una, muestra el archivo y linea sospechosa
|
|
58
|
-
- Pide al usuario que confirme o descarte
|
|
33
|
+
- Busca en codebase los simbolos/archivos de logs o stack traces.
|
|
34
|
+
- Traza el flujo desde entrada (controller/endpoint) hasta el punto de falla.
|
|
35
|
+
- Revisa commits recientes si el bug es nuevo: `git log --oneline -20`.
|
|
36
|
+
- Presenta al usuario 1-3 hipotesis con archivo y linea sospechosa; pide que confirme o descarte.
|
|
59
37
|
|
|
60
38
|
### Paso 3: Diagnosticar
|
|
61
39
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
1. **Confirmar la causa raiz**: Muestra el codigo exacto que causa el bug
|
|
65
|
-
2. **Explicar por que falla**: Que condicion o caso no esta manejado
|
|
66
|
-
3. **Evaluar impacto**: Que mas podria estar afectado
|
|
40
|
+
Con la hipotesis confirmada: muestra el codigo exacto que falla, explica que condicion no se maneja, evalua impacto en otras zonas.
|
|
67
41
|
|
|
68
42
|
### Paso 4: Proponer correccion
|
|
69
43
|
|
|
70
|
-
Presenta
|
|
71
|
-
|
|
72
|
-
1. **Cambio minimo**: La correccion mas pequeña posible que resuelve el bug
|
|
73
|
-
2. **Archivos a modificar**: Lista con descripcion del cambio
|
|
74
|
-
3. **Riesgos**: Que podria romperse con el fix
|
|
75
|
-
4. **Alternativas**: Si hay mas de una forma de corregirlo
|
|
76
|
-
|
|
77
|
-
Espera aprobacion del usuario antes de implementar.
|
|
44
|
+
Presenta: cambio minimo, archivos a modificar, riesgos, alternativas (si existen). Espera aprobacion antes de implementar.
|
|
78
45
|
|
|
79
46
|
### Paso 5: Validar rama de trabajo (antes de escribir codigo)
|
|
80
47
|
|
package/skills/explore/SKILL.md
CHANGED
|
@@ -8,9 +8,7 @@ user-invocable: true
|
|
|
8
8
|
|
|
9
9
|
Este comando envuelve la funcionalidad de OpenSpec explore y agrega contexto del proyecto.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Lee `SKILL.md` en `.claude/skills/refacil-prereqs/` o `.cursor/skills/refacil-prereqs/` (misma skill en Claude Code y Cursor) y aplica el **perfil `openspec`** antes de continuar (incluye el uso continuo de `AGENTS.md` durante la exploracion, segun ese archivo).
|
|
11
|
+
**Prerequisitos**: perfil `openspec` de `refacil-prereqs/SKILL.md` — usa `AGENTS.md` como contexto activo durante toda la exploracion.
|
|
14
12
|
|
|
15
13
|
## Instrucciones
|
|
16
14
|
|
package/skills/prereqs/SKILL.md
CHANGED
|
@@ -4,39 +4,30 @@ description: Referencia interna — prerequisitos SDD-AI compartidos por el rest
|
|
|
4
4
|
user-invocable: false
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
# Prerequisitos SDD-AI
|
|
7
|
+
# Prerequisitos SDD-AI
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Metodologia identica en Claude Code (`.claude/skills/refacil-*`) y Cursor (`.cursor/skills/refacil-*`). Usa la ruta del IDE abierto.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
Ademas, lee y aplica `METHODOLOGY-CONTRACT.md` (misma carpeta) para reglas transversales: estados del flujo, politica de ramas, tests multi-stack y modo de salida.
|
|
11
|
+
Reglas transversales (estados, ramas, tests, salida): `METHODOLOGY-CONTRACT.md` en esta misma carpeta.
|
|
13
12
|
|
|
14
|
-
## Perfil `openspec`
|
|
13
|
+
## Perfil `openspec`
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
Una skill pide este perfil cuando usa OpenSpec y necesita `AGENTS.md`. Estas validaciones son obligatorias en cada ejecucion de skill que declare este perfil.
|
|
17
16
|
|
|
18
|
-
1.
|
|
17
|
+
1. Verifica comando OpenSpec: `openspec --version 2>&1`. Si falla: *"OpenSpec no esta instalado o no esta en PATH. Ejecuta `/refacil:setup`"* y **detente**.
|
|
18
|
+
2. Verifica `openspec/` en la raiz del repo. Si falta: *"OpenSpec no esta inicializado en este repo. Ejecuta `/refacil:setup`"* y **detente**.
|
|
19
|
+
3. Lee `AGENTS.md` de la raiz. Si falta: *"No se encontro AGENTS.md. Ejecuta `/refacil:setup`"* y **detente**.
|
|
20
|
+
4. Si un comando de OpenSpec falla despues, consulta `.claude/skills/refacil-setup/troubleshooting.md`.
|
|
21
|
+
5. Si `AGENTS.md` incluye bloque `compact-guidance`, aplica esas reglas de eficiencia de tokens en toda la ejecucion.
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
Caso especial: en `refacil:explore`, `AGENTS.md` es contexto activo durante toda la exploracion.
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
## Perfil `agents`
|
|
23
26
|
|
|
24
|
-
|
|
27
|
+
Solo requiere `AGENTS.md`. Si existe, leelo y aplica `compact-guidance` si esta presente. Si falta: continua con baseline generico y avisa al usuario: *"No se encontro AGENTS.md; ejecuta `/refacil:setup` para reglas del proyecto."*
|
|
25
28
|
|
|
26
|
-
##
|
|
29
|
+
## OPENSPEC-DELTAS.md
|
|
27
30
|
|
|
28
|
-
|
|
31
|
+
Convenciones Refacil al delegar a skills `openspec-*`: ver `OPENSPEC-DELTAS.md` (misma carpeta), leer junto a la skill OpenSpec que se invoque.
|
|
29
32
|
|
|
30
|
-
Si
|
|
31
|
-
Si NO existe, informa al usuario: "No se encontro AGENTS.md. Continuare con baseline generico; para reglas del proyecto ejecuta `/refacil:setup`." y continua.
|
|
32
|
-
|
|
33
|
-
## Ubicacion de este archivo
|
|
34
|
-
|
|
35
|
-
En el repo del proyecto (elige segun herramienta):
|
|
36
|
-
|
|
37
|
-
- Claude Code: `.claude/skills/refacil-prereqs/SKILL.md`
|
|
38
|
-
- Cursor: `.cursor/skills/refacil-prereqs/SKILL.md`
|
|
39
|
-
|
|
40
|
-
En la **misma carpeta** esta `OPENSPEC-DELTAS.md`: convenciones Refacil al delegar en skills `openspec-*` (leer junto a la skill OpenSpec indicada).
|
|
41
|
-
|
|
42
|
-
Si ninguna existe, ejecuta `refacil-sdd-ai update` (o `init`).
|
|
33
|
+
Si faltan estos archivos, ejecuta `refacil-sdd-ai update` (o `init`).
|
package/skills/propose/SKILL.md
CHANGED
|
@@ -8,9 +8,7 @@ user-invocable: true
|
|
|
8
8
|
|
|
9
9
|
Este comando envuelve la funcionalidad de OpenSpec fast-forward (ff) y agrega las convenciones del equipo.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Lee `SKILL.md` en `.claude/skills/refacil-prereqs/` o `.cursor/skills/refacil-prereqs/` (misma skill en Claude Code y Cursor) y aplica el **perfil `openspec`** antes de continuar.
|
|
11
|
+
**Prerequisitos**: perfil `openspec` de `refacil-prereqs/SKILL.md` + reglas de `METHODOLOGY-CONTRACT.md`.
|
|
14
12
|
|
|
15
13
|
## Instrucciones
|
|
16
14
|
|
package/skills/review/SKILL.md
CHANGED
|
@@ -8,12 +8,9 @@ user-invocable: true
|
|
|
8
8
|
|
|
9
9
|
Eres un reviewer exigente pero constructivo que evalua el codigo contra el checklist de calidad del equipo.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
**Prerequisitos**: perfil `agents` de `refacil-prereqs/SKILL.md` + modo de salida de `METHODOLOGY-CONTRACT.md`.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
Lee `METHODOLOGY-CONTRACT.md` en `refacil-prereqs` y aplica el modo de salida definido ahi.
|
|
15
|
-
|
|
16
|
-
### Cargar checklists
|
|
13
|
+
## Checklists a cargar
|
|
17
14
|
|
|
18
15
|
1. **Siempre** lee el checklist general: [checklist.md](checklist.md)
|
|
19
16
|
2. **Detecta el tipo de proyecto** inspeccionando dependencias, `AGENTS.md`, o la estructura del repo:
|
|
@@ -77,62 +74,27 @@ Usa severidad para priorizar correcciones, no para inflar el reporte.
|
|
|
77
74
|
|
|
78
75
|
### Paso 4: Reporte
|
|
79
76
|
|
|
77
|
+
Por defecto, usa salida **concisa** (segun `METHODOLOGY-CONTRACT.md`):
|
|
78
|
+
|
|
80
79
|
```
|
|
81
80
|
=== Review Report ===
|
|
82
|
-
|
|
83
81
|
VEREDICTO: APROBADO | APROBADO CON OBSERVACIONES | REQUIERE CORRECCIONES
|
|
84
82
|
BLOCKERS: [si/no]
|
|
85
83
|
|
|
86
|
-
## Hallazgos priorizados (solo FAIL)
|
|
84
|
+
## Hallazgos priorizados (solo FAIL, maximo 5)
|
|
87
85
|
1. [CRITICO|ALTO|MEDIO|BAJO] [seccion/item] — [problema]
|
|
88
86
|
- Evidencia: [archivo/rango o comportamiento]
|
|
89
87
|
- Correccion sugerida: [accion concreta]
|
|
90
88
|
|
|
91
|
-
## Checklist General
|
|
92
|
-
- Alcance y foco: [PASS/FAIL/N/A]
|
|
93
|
-
- Conformidad con Spec: [PASS/FAIL/N/A]
|
|
94
|
-
- Calidad de Codigo: [PASS/FAIL/N/A]
|
|
95
|
-
- Arquitectura: [PASS/FAIL/N/A]
|
|
96
|
-
- Manejo de errores: [PASS/FAIL/N/A]
|
|
97
|
-
- Testing: [PASS/FAIL/N/A]
|
|
98
|
-
- Seguridad: [PASS/FAIL/N/A]
|
|
99
|
-
- Dependencias: [PASS/FAIL/N/A]
|
|
100
|
-
- Mantenibilidad y observabilidad: [PASS/FAIL/N/A]
|
|
101
|
-
- Git y Deploy: [PASS/FAIL/N/A]
|
|
102
|
-
- Reglas del proyecto (AGENTS.md): [PASS/FAIL/N/A]
|
|
103
|
-
|
|
104
|
-
## Checklist Backend (si aplica)
|
|
105
|
-
- Validacion de entrada: [PASS/FAIL/N/A]
|
|
106
|
-
- Contratos de API: [PASS/FAIL/N/A]
|
|
107
|
-
- Manejo de errores: [PASS/FAIL/N/A]
|
|
108
|
-
- Arquitectura y patrones: [PASS/FAIL/N/A]
|
|
109
|
-
- Concurrencia y atomicidad: [PASS/FAIL/N/A]
|
|
110
|
-
- Consultas a BD: [PASS/FAIL/N/A]
|
|
111
|
-
- Caching: [PASS/FAIL/N/A]
|
|
112
|
-
- Resiliencia y conexiones: [PASS/FAIL/N/A]
|
|
113
|
-
- Colas y mensajeria: [PASS/FAIL/N/A]
|
|
114
|
-
- Performance: [PASS/FAIL/N/A]
|
|
115
|
-
- Logging: [PASS/FAIL/N/A]
|
|
116
|
-
- Testing backend: [PASS/FAIL/N/A]
|
|
117
|
-
|
|
118
|
-
## Checklist Frontend (si aplica)
|
|
119
|
-
- Componentes y estructura: [PASS/FAIL/N/A]
|
|
120
|
-
- Estado y datos: [PASS/FAIL/N/A]
|
|
121
|
-
- Manejo de errores en UI: [PASS/FAIL/N/A]
|
|
122
|
-
- Integracion con APIs: [PASS/FAIL/N/A]
|
|
123
|
-
- Validacion de formularios: [PASS/FAIL/N/A]
|
|
124
|
-
- Ruteo y navegacion: [PASS/FAIL/N/A]
|
|
125
|
-
- Consistencia visual: [PASS/FAIL/N/A]
|
|
126
|
-
- Performance frontend: [PASS/FAIL/N/A]
|
|
127
|
-
- Accesibilidad: [PASS/FAIL/N/A]
|
|
128
|
-
- Seguridad frontend: [PASS/FAIL/N/A]
|
|
129
|
-
- Testing frontend: [PASS/FAIL/N/A]
|
|
130
|
-
|
|
131
89
|
## Correcciones minimas para aprobar
|
|
132
90
|
1. [item accionable]
|
|
133
91
|
2. [item accionable]
|
|
92
|
+
|
|
93
|
+
Siguiente paso: [/refacil:archive | /refacil:verify]
|
|
134
94
|
```
|
|
135
95
|
|
|
96
|
+
Si el usuario pide modo **detallado**, agrega tras el bloque conciso una seccion por cada checklist cargado (`checklist.md`, `checklist-back.md`, `checklist-front.md` segun aplique) con cada item y su estado `[PASS/FAIL/N/A]`. No inventes items; usa literalmente los de los archivos. Marca N/A si un item no aplica.
|
|
97
|
+
|
|
136
98
|
### Paso 5: Marcador de review (obligatorio si APROBADO)
|
|
137
99
|
|
|
138
100
|
Si el veredicto es **APROBADO** o **APROBADO CON OBSERVACIONES**, crea un archivo marcador en el directorio del cambio activo:
|
package/skills/setup/SKILL.md
CHANGED
|
@@ -64,6 +64,12 @@ Analiza el repo y genera `AGENTS.md` (espanol, terminos tecnicos en ingles). Si
|
|
|
64
64
|
|
|
65
65
|
**6.4** — Muestra el resultado; si el usuario aprueba, escribe en la raiz.
|
|
66
66
|
|
|
67
|
+
**6.5 Eficiencia de tokens (hook + bloque auto-gestionado)**:
|
|
68
|
+
- Explica al usuario que `refacil-sdd-ai` mantiene en `AGENTS.md` un bloque `compact-guidance` para reducir consumo de contexto.
|
|
69
|
+
- Ese bloque se sincroniza automaticamente por el hook `check-update` en cada `SessionStart` (y tambien en `init`/`update`).
|
|
70
|
+
- Si `AGENTS.md` aun no existe, la sincronizacion se omite sin error.
|
|
71
|
+
- Indica que no debe editar manualmente el contenido entre marcadores `compact-guidance` porque se sobrescribe.
|
|
72
|
+
|
|
67
73
|
### Paso 7: Verificar skills
|
|
68
74
|
|
|
69
75
|
- OpenSpec: 10 carpetas bajo `.claude/skills/` y `.cursor/skills/`: `openspec-apply-change`, `openspec-archive-change`, `openspec-bulk-archive-change`, `openspec-continue-change`, `openspec-explore`, `openspec-ff-change`, `openspec-new-change`, `openspec-onboard`, `openspec-sync-specs`, `openspec-verify-change`. Si falta alguna: sugerir `openspec init --tools claude,cursor` o `openspec config list`.
|