@antoneeo/agentic-sdlc-skill 1.17.0 → 1.20.2
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 +431 -299
- package/README.md +122 -93
- package/gemini-extension.json +6 -6
- package/package.json +4 -1
- package/scripts/init.js +224 -154
- package/scripts/lib.js +177 -168
- package/skills/agentic-sdlc-skill/ENFORCEMENT.md +11 -5
- package/skills/agentic-sdlc-skill/SKILL.md +19 -5
- package/skills/agentic-sdlc-skill/architect.md +215 -0
- package/skills/agentic-sdlc-skill/elicitation.md +124 -8
- package/skills/agentic-sdlc-skill/guides.md +8 -0
- package/skills/agentic-sdlc-skill/review.md +92 -7
- package/skills/agentic-sdlc-skill/routing.md +100 -0
- package/skills/agentic-sdlc-skill/scripts/sdlc_check.py +52 -1100
- package/skills/agentic-sdlc-skill/scripts/sdlc_core.py +1996 -0
- package/skills/agentic-sdlc-skill/templates.md +93 -2
package/scripts/init.js
CHANGED
|
@@ -1,154 +1,224 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const { execSync } = require('child_process');
|
|
6
|
-
const { SKILL_SOURCE, CLIENTS, clientDetected, loadTemplates, templateFor } = require('./lib');
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
'
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
If
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (!fs.existsSync(
|
|
103
|
-
fs.
|
|
104
|
-
console.log(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
|
|
136
|
-
let
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
console.log(
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { execSync } = require('child_process');
|
|
6
|
+
const { SKILL_SOURCE, CLIENTS, clientDetected, skillTarget, loadTemplates, templateFor } = require('./lib');
|
|
7
|
+
|
|
8
|
+
// Sibling lenses of the same family: one shared core, one `ai_docs/` tree, a different
|
|
9
|
+
// fidelity discipline each. Keyed by the installed skill directory name.
|
|
10
|
+
const SIBLING_LENSES = {
|
|
11
|
+
'kb-agentic': 'knowledge',
|
|
12
|
+
'mkt-agentic-sdlc': 'marketing',
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const cwd = process.cwd();
|
|
16
|
+
|
|
17
|
+
// 1. Directory layout (canonical ai_docs structure, including reference/)
|
|
18
|
+
const directories = [
|
|
19
|
+
'ai_docs',
|
|
20
|
+
'ai_docs/vision',
|
|
21
|
+
'ai_docs/vision/features',
|
|
22
|
+
'ai_docs/reference',
|
|
23
|
+
'ai_docs/strategic',
|
|
24
|
+
'ai_docs/audit',
|
|
25
|
+
'ai_docs/solutions',
|
|
26
|
+
].map((d) => path.join(cwd, d));
|
|
27
|
+
|
|
28
|
+
// 2. Project protocol (thin pointer — the operating contract is the skill).
|
|
29
|
+
// Deliberately short: duplicating the skill's rules here made them drift.
|
|
30
|
+
const protocolContent = `# Agentic SDLC — Project Protocol (pointer)
|
|
31
|
+
|
|
32
|
+
This project follows the Agentic SDLC Documentation-First process. The full
|
|
33
|
+
operating contract is the \`agentic-sdlc\` skill (installed in your agent's
|
|
34
|
+
skills directory); this file is only the minimal always-on pointer.
|
|
35
|
+
|
|
36
|
+
## Rule Zero — Triage every request
|
|
37
|
+
- L1 Trivial: ~10 lines, 1-2 files, no API/dependency/behavior change. Implement + run existing tests; no docs.
|
|
38
|
+
- L2 Small: clear root cause, at most 3 files, low risk. Mini-analysis in the reply; tests mandatory.
|
|
39
|
+
- L3 Significant: >3 files, APIs/contracts, new dependency, user-visible behavior, security-sensitive area, or architectural change. Full workflow via the skill: Vision Gate -> ANALYSIS -> plan -> implement -> test -> closure.
|
|
40
|
+
- Spike: time-boxed exploration; outcome in \`ai_docs/solutions/SPIKE_[topic].md\`; reclassify for production.
|
|
41
|
+
- Security-sensitive areas (external input parsing, authN/authZ, crypto, network, personal data, filesystem) are never L1.
|
|
42
|
+
- When in doubt, pick the higher level. Declare the chosen level when starting.
|
|
43
|
+
|
|
44
|
+
## Where things live
|
|
45
|
+
- Vision (gate for L3): \`ai_docs/vision/\` — \`Status: DRAFT\` informs, \`Status: APPROVED\` binds.
|
|
46
|
+
- Feature analyses: \`ai_docs/solutions/ANALYSIS_[feature].md\` (frontmatter = feature state).
|
|
47
|
+
- Must-reads: \`ai_docs/README.md\`; full generated manifest: \`ai_docs/INDEX.md\`.
|
|
48
|
+
- If devPNT is available for this project, its M-VISION / plans / governed artifacts take over (Hybrid mode — see the skill).
|
|
49
|
+
|
|
50
|
+
## Closure gate
|
|
51
|
+
Docs travel in the same commit/PR as the code they describe. If the project
|
|
52
|
+
adopts the validator, \`python <skill_dir>/scripts/sdlc_check.py check\` must be
|
|
53
|
+
CLEAN before declaring work done.
|
|
54
|
+
|
|
55
|
+
If the agentic-sdlc skill is not available in this client, ask the user to install it:
|
|
56
|
+
\`npm i -g @antoneeo/agentic-sdlc-skill && agentic-sdlc-install-skill\`
|
|
57
|
+
`;
|
|
58
|
+
|
|
59
|
+
console.log('🚀 Initializing Agentic SDLC workflow...');
|
|
60
|
+
|
|
61
|
+
// 3. Load templates from the single source (skill's templates.md)
|
|
62
|
+
let sections;
|
|
63
|
+
try {
|
|
64
|
+
sections = loadTemplates();
|
|
65
|
+
} catch (err) {
|
|
66
|
+
console.error(`❌ Cannot load templates: ${err.message}`);
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// audit_plan: the template block carries illustrative rows; a fresh project
|
|
71
|
+
// starts from a single root PENDING row instead.
|
|
72
|
+
function initialAuditPlan() {
|
|
73
|
+
const tpl = templateFor(sections, 'audit_plan.md');
|
|
74
|
+
const lines = tpl.split('\n');
|
|
75
|
+
const sepIdx = lines.findIndex((l) => /^\|[-\s|:]+\|$/.test(l.trim()));
|
|
76
|
+
if (sepIdx === -1) return tpl; // unexpected shape: keep the template as-is
|
|
77
|
+
// '.' (the project root), never '/': an absolute row makes `stale` walk the
|
|
78
|
+
// whole drive once the area is marked ANALYZED.
|
|
79
|
+
return lines.slice(0, sepIdx + 1).join('\n') + '\n| . | PENDING | - | Initial analysis |\n';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let seedFiles;
|
|
83
|
+
try {
|
|
84
|
+
seedFiles = [
|
|
85
|
+
['ai_docs/README.md', templateFor(sections, 'ai_docs/README.md')],
|
|
86
|
+
['ai_docs/vision/project_vision.md', templateFor(sections, 'project_vision.md')],
|
|
87
|
+
['ai_docs/vision/roadmap.md', templateFor(sections, 'vision/roadmap.md')],
|
|
88
|
+
['ai_docs/vision/principles.md', templateFor(sections, 'principles.md')],
|
|
89
|
+
['ai_docs/strategic/architecture.md', templateFor(sections, 'architecture.md and existing_features.md', 0)],
|
|
90
|
+
['ai_docs/strategic/existing_features.md', templateFor(sections, 'architecture.md and existing_features.md', 1)],
|
|
91
|
+
['ai_docs/audit/audit_plan.md', initialAuditPlan()],
|
|
92
|
+
// NOTE: features_history.md and INDEX.md are NOT seeded — they are
|
|
93
|
+
// generated by `sdlc_check.py index` and would immediately fail validate.
|
|
94
|
+
];
|
|
95
|
+
} catch (err) {
|
|
96
|
+
console.error(`❌ ${err.message}`);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 4. Create directories
|
|
101
|
+
directories.forEach((dir) => {
|
|
102
|
+
if (!fs.existsSync(dir)) {
|
|
103
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
104
|
+
console.log(`📁 Created directory: ${path.relative(cwd, dir)}`);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// 5. Write seed files (never overwrite)
|
|
109
|
+
const writeIfNotExists = (relPath, content, description) => {
|
|
110
|
+
const filePath = path.join(cwd, relPath);
|
|
111
|
+
if (!fs.existsSync(filePath)) {
|
|
112
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
113
|
+
console.log(`📄 Created file: ${relPath}${description ? ` (${description})` : ''}`);
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
console.log(`⏭️ Skipped: ${relPath} already exists.`);
|
|
117
|
+
return false;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
seedFiles.forEach(([relPath, content]) => writeIfNotExists(relPath, content));
|
|
121
|
+
|
|
122
|
+
// 6. Client discovery and protocol pointers
|
|
123
|
+
console.log('\n--- Environment Analysis ---');
|
|
124
|
+
|
|
125
|
+
const protocolFiles = {
|
|
126
|
+
claude: 'CLAUDE.md',
|
|
127
|
+
gemini: 'GEMINI.md',
|
|
128
|
+
codex: 'AGENTS.md',
|
|
129
|
+
antigravity: 'AGENTS.md', // Antigravity CLI reads AGENTS.md; single protocolContent reused.
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// A protocol pointer that ALREADY existed was written by someone else — typically a
|
|
133
|
+
// sibling lens's init, which seeded the project with its own triage ladder. This init
|
|
134
|
+
// must not overwrite it (create-only is the T1 guarantee), so the second ladder is
|
|
135
|
+
// written aside and merged by hand.
|
|
136
|
+
let protocolPreexisting = false;
|
|
137
|
+
|
|
138
|
+
for (const client of CLIENTS) {
|
|
139
|
+
if (clientDetected(client)) {
|
|
140
|
+
console.log(`✅ ${client.label} detected.`);
|
|
141
|
+
const created = writeIfNotExists(protocolFiles[client.key], protocolContent, `${client.label} protocol pointer`);
|
|
142
|
+
if (!created) protocolPreexisting = true;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Cursor/Windsurf (always recommended)
|
|
147
|
+
writeIfNotExists('.cursorrules', protocolContent, 'Cursor/Windsurf rules');
|
|
148
|
+
|
|
149
|
+
// 6b. Sibling lenses: additive only. Never edits a user-authored root file.
|
|
150
|
+
function installedSiblingLenses() {
|
|
151
|
+
const found = new Map();
|
|
152
|
+
for (const client of CLIENTS) {
|
|
153
|
+
if (!clientDetected(client)) continue;
|
|
154
|
+
const skillsDir = path.dirname(skillTarget(client));
|
|
155
|
+
for (const [dirName, lens] of Object.entries(SIBLING_LENSES)) {
|
|
156
|
+
if (fs.existsSync(path.join(skillsDir, dirName))) found.set(dirName, lens);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return found;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const siblings = installedSiblingLenses();
|
|
163
|
+
if (siblings.size > 0) {
|
|
164
|
+
const list = [...siblings].map(([dir, lens]) => `- \`${dir}\` — the **${lens}** lens`).join('\n');
|
|
165
|
+
console.log(`\n🔀 Sibling lens detected: ${[...siblings.keys()].join(', ')}.`);
|
|
166
|
+
const wrote = writeIfNotExists('AGENTIC_MULTI_LENS.md', `# Multi-lens project — routing note (additive)
|
|
167
|
+
|
|
168
|
+
This project has more than one lens of the Agentic SDLC family installed:
|
|
169
|
+
|
|
170
|
+
${list}
|
|
171
|
+
- \`agentic-sdlc\` — the **code** lens
|
|
172
|
+
|
|
173
|
+
One \`ai_docs/\` tree, one project default (\`default_domain:\` in \`ai_docs/README.md\`),
|
|
174
|
+
one lens per unit of work. Before acting on any L2, L3 or Spike, run the domain router
|
|
175
|
+
in the skill's \`routing.md\`: it decides which lens's method and validation rules govern
|
|
176
|
+
that unit. L1 never reaches it. Never refer to a document whose meaning differs by lens
|
|
177
|
+
("threat model", "vision", \`principles.md\`, \`handoff.md\`) by its bare name.
|
|
178
|
+
|
|
179
|
+
${protocolPreexisting ? `**Merge step owed.** The always-on protocol pointer of this project (\`CLAUDE.md\` /
|
|
180
|
+
\`GEMINI.md\` / \`AGENTS.md\` / \`.cursorrules\`) was written by another lens's init and
|
|
181
|
+
carries ITS triage ladder. This init did not overwrite it. Add the code lens's ladder
|
|
182
|
+
to that file by hand — the pointer below — so both are always loaded.
|
|
183
|
+
|
|
184
|
+
## Rule Zero — Triage every request (code lens)
|
|
185
|
+
- L1 Trivial: ~10 lines, 1-2 files, no API/dependency/behavior change.
|
|
186
|
+
- L2 Small: clear root cause, at most 3 files, low risk. Tests mandatory.
|
|
187
|
+
- L3 Significant: >3 files, APIs/contracts, new dependency, user-visible behavior,
|
|
188
|
+
security-sensitive area, or architectural change. Full workflow via the skill.
|
|
189
|
+
- Spike: time-boxed exploration; outcome in \`ai_docs/solutions/SPIKE_[topic].md\`.
|
|
190
|
+
` : `The always-on protocol pointer for the code lens was created by this init. When you
|
|
191
|
+
install another lens over this project, its init will leave its own ladder here for you
|
|
192
|
+
to merge.
|
|
193
|
+
`}
|
|
194
|
+
This file is NOT auto-loaded by any client: it is a note for you, deliberately additive.
|
|
195
|
+
Delete it once the merge is done.
|
|
196
|
+
`, 'multi-lens routing note');
|
|
197
|
+
if (wrote && protocolPreexisting) {
|
|
198
|
+
console.log(' ⚠️ A protocol pointer already existed and was NOT overwritten.');
|
|
199
|
+
console.log(' Merge the code-lens ladder from AGENTIC_MULTI_LENS.md into it by hand.');
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// 7. Generate ai_docs/INDEX.md so the very first `validate` is already clean.
|
|
204
|
+
// The manifest is generated, never seeded: delegate to the validator if Python is available.
|
|
205
|
+
const validator = path.join(SKILL_SOURCE, 'scripts', 'sdlc_check.py');
|
|
206
|
+
let indexed = false;
|
|
207
|
+
for (const py of ['python', 'python3', 'py']) {
|
|
208
|
+
try {
|
|
209
|
+
execSync(`${py} "${validator}" index --root "${cwd}"`, { stdio: 'ignore' });
|
|
210
|
+
console.log('📇 Generated ai_docs/INDEX.md (document manifest).');
|
|
211
|
+
indexed = true;
|
|
212
|
+
break;
|
|
213
|
+
} catch (e) { /* try the next interpreter */ }
|
|
214
|
+
}
|
|
215
|
+
if (!indexed) {
|
|
216
|
+
console.log('ℹ️ Python not found: generate the manifest later with '
|
|
217
|
+
+ '"python <skill_dir>/scripts/sdlc_check.py index" (validate reports it until then).');
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
console.log('\n✅ Setup completed successfully!');
|
|
221
|
+
console.log('💡 Next steps:');
|
|
222
|
+
console.log(' 1. Make sure the agentic-sdlc skill is installed (agentic-sdlc-install-skill).');
|
|
223
|
+
console.log(' 2. Restart/open the project in your AI client so it reads the protocol pointer.');
|
|
224
|
+
console.log(' 3. Start with an audit following ai_docs/audit/audit_plan.md.');
|