@antoneeo/agentic-sdlc-skill 1.5.0 → 1.7.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/CHANGELOG.md +69 -25
- package/gemini-extension.json +2 -2
- package/package.json +6 -8
- package/scripts/init.js +125 -176
- package/scripts/lib.js +138 -0
- package/scripts/postinstall.js +17 -113
- package/scripts/preuninstall.js +5 -14
- package/skills/agentic-sdlc-skill/ENFORCEMENT.md +56 -55
- package/skills/agentic-sdlc-skill/SKILL.md +244 -141
- package/skills/agentic-sdlc-skill/scripts/sdlc_check.py +713 -474
- package/skills/agentic-sdlc-skill/templates.md +212 -169
- package/references/analysis_template.md +0 -44
- package/references/architecture_template.md +0 -19
- package/references/existing_features_template.md +0 -4
- package/references/feature_vision_template.md +0 -21
- package/references/features_history_template.md +0 -5
- package/references/principles_template.md +0 -13
- package/references/project_vision_template.md +0 -26
- package/references/roadmap_template.md +0 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,30 +1,74 @@
|
|
|
1
1
|
# Changelog - Agentic SDLC Skill
|
|
2
2
|
|
|
3
|
-
Tutte le modifiche significative a questa skill saranno documentate in questo file.
|
|
4
|
-
|
|
5
|
-
## [1.
|
|
6
|
-
###
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
- `
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
###
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
3
|
+
Tutte le modifiche significative a questa skill saranno documentate in questo file.
|
|
4
|
+
|
|
5
|
+
## [1.7.0] - 2026-07-02 (Phases 0-1 of the evolution roadmap)
|
|
6
|
+
### Changed (breaking-soft)
|
|
7
|
+
- **English is now the canonical language of the skill**: `SKILL.md`, `templates.md`, `ENFORCEMENT.md`, validator messages, generated indexes and the project protocol are in English. New ANALYSIS documents use English frontmatter keys (`status`, `level`, `start_date`, `end_date`) and English section headings. **Existing projects keep working**: the validator silently accepts the deprecated Italian keys (`stato`, `livello`, `data_inizio`, `data_fine`) and Italian headings.
|
|
8
|
+
- The generated project protocol (`CLAUDE.md`/`GEMINI.md`/`AGENTS.md`/`.cursorrules`) is now a **thin pointer** to the skill (triage summary + where things live + closure gate) instead of a condensed copy of its rules, which had drifted from `SKILL.md`.
|
|
9
|
+
- `init.js` now seeds `ai_docs/` from `templates.md` (single template source) instead of inline boilerplates; it creates `ai_docs/reference/` and the curated `ai_docs/README.md`, no longer seeds the generated `features_history.md`, and generates `INDEX.md` via the validator when Python is available, so the very first `sdlc_check.py check` on a fresh project is CLEAN.
|
|
10
|
+
- Client detection unified between `init.js` and `postinstall.js` (`scripts/lib.js`): CLI on PATH **or** config home present (covers Claude Desktop with integrated Claude Code).
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `sdlc_check.py validate --strict` / `check --strict`: warnings and a missing `ai_docs/` become failures (for CI).
|
|
14
|
+
- **Coexistence with devPNT (Phase 1, the Hybrid seam)**: new SKILL.md section with the ownership matrix (who is master per artifact in Standalone vs Hybrid), the triage equivalence table (one significance threshold, two vocabularies), the ANALYSIS↔plan-node state mapping and the shadow discipline (`SHADOW_[doc_key]_vX.Y.md`, exported BEFORE implementation; never saved under an `ANALYSIS_*` name).
|
|
15
|
+
- `sdlc_check.py --hybrid` (explicit, never auto-detected) on `check`/`stale` (audit-plan staleness delegated to devPNT/KL) and on `gate` (an approved E-TDD shadow in `solutions/` authorizes writes on protected paths).
|
|
16
|
+
- devPNT MCP doctrine (`mcp_system_prompt.md`, devPNT repo) slimmed accordingly: process (triage, phases, lifecycle, closure) deferred to the skill; `ai_docs/` layout aligned (adds `vision/` and `reference/`); shadow naming and shadow-before-implementation rule; checklist items for methodology, shadow export and hybrid closure gate.
|
|
17
|
+
- Evolution roadmap for v1.7.0 in `ai_docs/vision/roadmap_evoluzione_agenti.md` (subagent execution, operative guides + agent-level knowledge base, devPNT seam, open-core positioning).
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
- Shadow detection is structural (filename `SHADOW_*` or `<!-- SHADOW` marker on the first line): an ANALYSIS merely *mentioning* shadows is no longer silently skipped from index and validation.
|
|
21
|
+
- `mark`/`index` fail fast when `ai_docs/` is missing instead of silently creating a second documentation root in the wrong directory.
|
|
22
|
+
|
|
23
|
+
### Removed
|
|
24
|
+
- Divergent `agentic-sdlc-v2/` copy (integrated in 1.5.0, the leftover risked edits on the wrong files).
|
|
25
|
+
- `references/*_template.md` (duplicated `templates.md` and had already diverged).
|
|
26
|
+
|
|
27
|
+
## [1.6.0] - 2026-06-15
|
|
28
|
+
### Added
|
|
29
|
+
- **Manifest generato dei documenti canonici** (`ai_docs/INDEX.md`): `sdlc_check.py index` ora produce, oltre a `features_history.md`, un indice completo di tutti i doc in `vision/`, `reference/`, `architecture/`, `functional/`, `strategic/`, con descrizione e stato letti dall'header. Si rigenera, quindi non drifta.
|
|
30
|
+
- **Lifecycle dei documenti canonici**: convenzione header `status: CURRENT|SUPERSEDED|DRAFT|DEPRECATED` + `supersedes:`. `validate` avvisa se `status` manca/è invalido o se un doc superseduto è ancora `CURRENT`. Stop ai grep che riportano a guide obsolete.
|
|
31
|
+
- **Modello a due indici** documentato nella sezione "Documenti ai_docs" di `SKILL.md`: `README.md` curato (must-read, a mano) vs `INDEX.md` generato (completo, meccanico) — ruoli separati, prima confusi in un unico README che driftava.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
- §1 Audit: leggere `README.md` + `INDEX.md` all'avvio per sapere cosa esiste prima di esplorare il codice.
|
|
35
|
+
- §3 Analisi: cercare con glob/grep un'ANALYSIS esistente prima di crearne una nuova (anti-duplicazione).
|
|
36
|
+
- §5 Chiusura: gate "Indici allineati" — rigenerare `INDEX.md`, aggiornare il `README.md` curato per i must-read, marcare lo `status`; doc canonico non indicizzato o senza `status` = chiusura sporca.
|
|
37
|
+
- `templates.md`: aggiunto il template dell'header dei documenti canonici.
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
- `sdlc_check.py` legge ora i file con `utf-8-sig`: un BOM iniziale (file autorati su Windows) non impedisce più il riconoscimento del frontmatter `---`.
|
|
41
|
+
- L'estrattore dell'header riconosce sia il frontmatter `status:` sia la riga in corpo `**Status:**`/`Stato:`, e gli stati di tutte le convenzioni in uso (canonici `CURRENT/SUPERSEDED/DRAFT/DEPRECATED`, vision `DRAFT/APPROVED`, ADR `Accepted/Proposed/Rejected`) — niente più falsi avvisi "status non riconosciuto" su `APPROVED`/`Accepted`.
|
|
42
|
+
- La descrizione del manifest salta righe di metadati (`Date`, `Created`, `Task ref`, ...) e i commenti HTML, così non finiscono come descrizione del documento.
|
|
43
|
+
- `index` non genera più un `INDEX.md` vuoto su progetti senza documenti canonici (solo `solutions/`+`audit/`).
|
|
44
|
+
|
|
45
|
+
### Migrazione (da 1.5.x)
|
|
46
|
+
- Al primo `sdlc_check.py check`/`validate` dopo l'upgrade, un progetto con documenti canonici darà **un errore** `ai_docs/INDEX.md mancante`: è atteso — esegui **una volta** `sdlc_check.py index` per generarlo. Da lì in poi resta allineato.
|
|
47
|
+
- I documenti canonici preesistenti senza `status:` produrranno **avvisi** (non errori): aggiungi l'header `description:`/`status:` per silenziarli. I nuovi progetti nascono già compatibili (template aggiornati).
|
|
48
|
+
|
|
49
|
+
## [1.5.0] - 2026-06-13
|
|
50
|
+
### Added
|
|
51
|
+
- Introdotta la Regola Zero di triage (`L1`, `L2`, `L3`, `Spike`) per rendere il processo proporzionale al rischio.
|
|
52
|
+
- Aggiunta simbiosi esplicita con devPNT: in Hybrid la `M-VISION` guida la milestone, il Master Plan resta roadmap strategica e l'Action Plan governa l'esecuzione tattica.
|
|
53
|
+
- Aggiunti support file dentro la skill runtime: `templates.md`, `ENFORCEMENT.md`, `scripts/sdlc_check.py`.
|
|
54
|
+
- `agentic-sdlc-install-skill` ora installa la skill nativa anche in `~/.gemini/skills/agentic-sdlc/`.
|
|
55
|
+
- Aggiunto validatore meccanico opzionale per frontmatter ANALYSIS, Vision state, indice feature e audit stale.
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
- Il nome pubblico resta `agentic-sdlc`; la proposta v2 e' stata integrata come evoluzione, non come skill parallela.
|
|
59
|
+
- Aggiornati `agentic-sdlc-init`, template, protocolli generati, README e metadata.
|
|
60
|
+
- La modalita Standalone resta completa; devPNT e' un livello di governance superiore, non un prerequisito.
|
|
61
|
+
|
|
62
|
+
## [1.4.0] - 2026-06-07
|
|
63
|
+
### Added
|
|
64
|
+
- Introdotta la governance della **Vision** con nuova struttura `ai_docs/vision/` (`project_vision.md`, `roadmap.md`, `principles.md`, `features/`).
|
|
65
|
+
- Aggiunto il **Vision Gate** nel workflow operativo: ogni feature significativa deve essere verificata rispetto a obiettivi, non-obiettivi, benefici attesi e segnali di successo prima dell'analisi tecnica.
|
|
66
|
+
- Aggiunti template Vision in `references/` e sezione `Allineamento alla Vision` nel template di analisi.
|
|
67
|
+
- `agentic-sdlc-init` ora crea i documenti Vision boilerplate nei nuovi progetti.
|
|
68
|
+
|
|
69
|
+
## [1.3.1] - 2026-05-14
|
|
70
|
+
### Fixed
|
|
71
|
+
- Correzione documentazione (README + CHANGELOG) della sintassi per invocare il bin `agentic-sdlc-install-skill`. La forma `npx @antoneeo/agentic-sdlc-skill agentic-sdlc-install-skill` documentata in 1.3.0 **non funziona** perché npx non riesce a disambiguare il bin quando il pacchetto ne espone più di uno (errore: `could not determine executable to run`). Sintassi corretta: lanciare `agentic-sdlc-install-skill` direttamente dopo `npm install -g`, oppure usare `npx -p @antoneeo/agentic-sdlc-skill agentic-sdlc-install-skill` con `-p` esplicito.
|
|
28
72
|
- Nessuna modifica al codice della skill: il bin di 1.3.0 funziona correttamente, era solo la doc a indicare la sintassi sbagliata.
|
|
29
73
|
|
|
30
74
|
## [1.3.0] - 2026-05-14
|
package/gemini-extension.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentic-sdlc-skill",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.7.0",
|
|
4
|
+
"description": "Documentation-First SDLC protocol with triage, Vision governance and optional devPNT integration.",
|
|
5
5
|
"author": "Antonio Pinto (https://github.com/Antoneeo)"
|
|
6
6
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antoneeo/agentic-sdlc-skill",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.7.0",
|
|
4
|
+
"description": "Documentation-First SDLC protocol for Claude Code, Gemini CLI and Codex with risk triage, Vision governance, installed support files and optional devPNT integration.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
7
7
|
"claude-skill",
|
|
@@ -25,15 +25,13 @@
|
|
|
25
25
|
"preuninstall": "node scripts/preuninstall.js"
|
|
26
26
|
},
|
|
27
27
|
"files": [
|
|
28
|
-
"skills/agentic-sdlc-skill/SKILL.md",
|
|
29
|
-
"skills/agentic-sdlc-skill/templates.md",
|
|
30
|
-
"skills/agentic-sdlc-skill/ENFORCEMENT.md",
|
|
31
|
-
"skills/agentic-sdlc-skill/scripts/sdlc_check.py",
|
|
28
|
+
"skills/agentic-sdlc-skill/SKILL.md",
|
|
29
|
+
"skills/agentic-sdlc-skill/templates.md",
|
|
30
|
+
"skills/agentic-sdlc-skill/ENFORCEMENT.md",
|
|
31
|
+
"skills/agentic-sdlc-skill/scripts/sdlc_check.py",
|
|
32
32
|
"gemini-extension.json",
|
|
33
|
-
"references",
|
|
34
33
|
"README.md",
|
|
35
34
|
"CHANGELOG.md",
|
|
36
|
-
"assets",
|
|
37
35
|
"scripts"
|
|
38
36
|
]
|
|
39
37
|
}
|
package/scripts/init.js
CHANGED
|
@@ -1,204 +1,153 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const { execSync } = require('child_process');
|
|
6
|
+
const { SKILL_SOURCE, CLIENTS, clientDetected, loadTemplates, templateFor } = require('./lib');
|
|
6
7
|
|
|
7
8
|
const cwd = process.cwd();
|
|
8
9
|
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
// 1. Directory layout (canonical ai_docs structure, including reference/)
|
|
11
|
+
const directories = [
|
|
12
|
+
'ai_docs',
|
|
13
|
+
'ai_docs/vision',
|
|
14
|
+
'ai_docs/vision/features',
|
|
15
|
+
'ai_docs/reference',
|
|
16
|
+
'ai_docs/strategic',
|
|
17
|
+
'ai_docs/audit',
|
|
18
|
+
'ai_docs/solutions',
|
|
19
|
+
].map((d) => path.join(cwd, d));
|
|
20
|
+
|
|
21
|
+
// 2. Project protocol (thin pointer — the operating contract is the skill).
|
|
22
|
+
// Deliberately short: duplicating the skill's rules here made them drift.
|
|
23
|
+
const protocolContent = `# Agentic SDLC — Project Protocol (pointer)
|
|
24
|
+
|
|
25
|
+
This project follows the Agentic SDLC Documentation-First process. The full
|
|
26
|
+
operating contract is the \`agentic-sdlc\` skill (installed in your agent's
|
|
27
|
+
skills directory); this file is only the minimal always-on pointer.
|
|
28
|
+
|
|
29
|
+
## Rule Zero — Triage every request
|
|
30
|
+
- L1 Trivial: ~10 lines, 1-2 files, no API/dependency/behavior change. Implement + run existing tests; no docs.
|
|
31
|
+
- L2 Small: clear root cause, at most 3 files, low risk. Mini-analysis in the reply; tests mandatory.
|
|
32
|
+
- 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.
|
|
33
|
+
- Spike: time-boxed exploration; outcome in \`ai_docs/solutions/SPIKE_[topic].md\`; reclassify for production.
|
|
34
|
+
- Security-sensitive areas (external input parsing, authN/authZ, crypto, network, personal data, filesystem) are never L1.
|
|
35
|
+
- When in doubt, pick the higher level. Declare the chosen level when starting.
|
|
36
|
+
|
|
37
|
+
## Where things live
|
|
38
|
+
- Vision (gate for L3): \`ai_docs/vision/\` — \`Status: DRAFT\` informs, \`Status: APPROVED\` binds.
|
|
39
|
+
- Feature analyses: \`ai_docs/solutions/ANALYSIS_[feature].md\` (frontmatter = feature state).
|
|
40
|
+
- Must-reads: \`ai_docs/README.md\`; full generated manifest: \`ai_docs/INDEX.md\`.
|
|
41
|
+
- If devPNT is available for this project, its M-VISION / plans / governed artifacts take over (Hybrid mode — see the skill).
|
|
42
|
+
|
|
43
|
+
## Closure gate
|
|
44
|
+
Docs travel in the same commit/PR as the code they describe. If the project
|
|
45
|
+
adopts the validator, \`python <skill_dir>/scripts/sdlc_check.py check\` must be
|
|
46
|
+
CLEAN before declaring work done.
|
|
47
|
+
|
|
48
|
+
If the agentic-sdlc skill is not available in this client, ask the user to install it:
|
|
49
|
+
\`npm i -g @antoneeo/agentic-sdlc-skill && agentic-sdlc-install-skill\`
|
|
50
|
+
`;
|
|
51
|
+
|
|
52
|
+
console.log('🚀 Initializing Agentic SDLC workflow...');
|
|
53
|
+
|
|
54
|
+
// 3. Load templates from the single source (skill's templates.md)
|
|
55
|
+
let sections;
|
|
56
|
+
try {
|
|
57
|
+
sections = loadTemplates();
|
|
58
|
+
} catch (err) {
|
|
59
|
+
console.error(`❌ Cannot load templates: ${err.message}`);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// audit_plan: the template block carries illustrative rows; a fresh project
|
|
64
|
+
// starts from a single root PENDING row instead.
|
|
65
|
+
function initialAuditPlan() {
|
|
66
|
+
const tpl = templateFor(sections, 'audit_plan.md');
|
|
67
|
+
const lines = tpl.split('\n');
|
|
68
|
+
const sepIdx = lines.findIndex((l) => /^\|[-\s|:]+\|$/.test(l.trim()));
|
|
69
|
+
if (sepIdx === -1) return tpl; // unexpected shape: keep the template as-is
|
|
70
|
+
return lines.slice(0, sepIdx + 1).join('\n') + '\n| / | PENDING | - | Initial analysis |\n';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let seedFiles;
|
|
74
|
+
try {
|
|
75
|
+
seedFiles = [
|
|
76
|
+
['ai_docs/README.md', templateFor(sections, 'ai_docs/README.md')],
|
|
77
|
+
['ai_docs/vision/project_vision.md', templateFor(sections, 'project_vision.md')],
|
|
78
|
+
['ai_docs/vision/roadmap.md', templateFor(sections, 'vision/roadmap.md')],
|
|
79
|
+
['ai_docs/vision/principles.md', templateFor(sections, 'principles.md')],
|
|
80
|
+
['ai_docs/strategic/architecture.md', templateFor(sections, 'architecture.md and existing_features.md', 0)],
|
|
81
|
+
['ai_docs/strategic/existing_features.md', templateFor(sections, 'architecture.md and existing_features.md', 1)],
|
|
82
|
+
['ai_docs/audit/audit_plan.md', initialAuditPlan()],
|
|
83
|
+
// NOTE: features_history.md and INDEX.md are NOT seeded — they are
|
|
84
|
+
// generated by `sdlc_check.py index` and would immediately fail validate.
|
|
85
|
+
];
|
|
86
|
+
} catch (err) {
|
|
87
|
+
console.error(`❌ ${err.message}`);
|
|
88
|
+
process.exit(1);
|
|
17
89
|
}
|
|
18
90
|
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
path.join(cwd, 'ai_docs'),
|
|
22
|
-
path.join(cwd, 'ai_docs', 'vision'),
|
|
23
|
-
path.join(cwd, 'ai_docs', 'vision', 'features'),
|
|
24
|
-
path.join(cwd, 'ai_docs', 'strategic'),
|
|
25
|
-
path.join(cwd, 'ai_docs', 'audit'),
|
|
26
|
-
path.join(cwd, 'ai_docs', 'solutions')
|
|
27
|
-
];
|
|
28
|
-
|
|
29
|
-
const files = {
|
|
30
|
-
projectVision: path.join(cwd, 'ai_docs', 'vision', 'project_vision.md'),
|
|
31
|
-
roadmap: path.join(cwd, 'ai_docs', 'vision', 'roadmap.md'),
|
|
32
|
-
principles: path.join(cwd, 'ai_docs', 'vision', 'principles.md'),
|
|
33
|
-
architecture: path.join(cwd, 'ai_docs', 'strategic', 'architecture.md'),
|
|
34
|
-
existingFeatures: path.join(cwd, 'ai_docs', 'strategic', 'existing_features.md'),
|
|
35
|
-
featuresHistory: path.join(cwd, 'ai_docs', 'strategic', 'features_history.md'),
|
|
36
|
-
auditPlan: path.join(cwd, 'ai_docs', 'audit', 'audit_plan.md'),
|
|
37
|
-
handoff: path.join(cwd, 'ai_docs', 'audit', 'handoff.md'),
|
|
38
|
-
claudeConfig: path.join(cwd, 'CLAUDE.md'),
|
|
39
|
-
geminiConfig: path.join(cwd, 'GEMINI.md'),
|
|
40
|
-
codexAgents: path.join(cwd, 'AGENTS.md'),
|
|
41
|
-
cursorRules: path.join(cwd, '.cursorrules')
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
// 2. Operational Protocol (System Prompt)
|
|
45
|
-
const protocolContent = `# "Agentic SDLC" Operational Protocol
|
|
46
|
-
|
|
47
|
-
You are a senior software engineer following a Documentation-First and Vision-Guided process. The process is proportional to risk: do not apply heavyweight governance to trivial work, but never bypass Vision, security, or design gates for significant changes.
|
|
48
|
-
|
|
49
|
-
## 0. Triage First
|
|
50
|
-
Classify every operational request:
|
|
51
|
-
- L1 Trivial: small local fix, no API/dependency/behavior expansion. Implement with relevant tests; no new docs.
|
|
52
|
-
- L2 Small: clear root cause, up to 3 files, low risk. Provide mini-analysis in the response; test.
|
|
53
|
-
- L3 Significant: public contract, user-visible behavior, security-sensitive area, new dependency, architectural impact, or more than 3 files. Use the full workflow below.
|
|
54
|
-
- Spike: time-boxed exploration; document result in \`ai_docs/solutions/SPIKE_[topic].md\`; production work must be reclassified.
|
|
55
|
-
|
|
56
|
-
Security-sensitive areas are never L1.
|
|
57
|
-
|
|
58
|
-
## 1. Mode Selection
|
|
59
|
-
- Standalone: if devPNT is unavailable, use \`ai_docs/\` as the complete source of truth.
|
|
60
|
-
- Hybrid/devPNT: if devPNT is available and configured for this project, use it for governed state. The devPNT M-VISION is the milestone north star, Master Plan is strategic roadmap, Action Plan is tactical execution, and governed artifacts live in devPNT.
|
|
61
|
-
- Do not create silent double truth. In Hybrid, \`ai_docs/\` is human-readable context, fallback, handoff, or shadow; devPNT governs plans and versioned artifacts.
|
|
62
|
-
|
|
63
|
-
## 2. Audit and Alignment
|
|
64
|
-
For L3 or explicit audit requests:
|
|
65
|
-
- Check \`ai_docs/\`, \`ai_docs/vision/\`, \`ai_docs/strategic/\`, \`ai_docs/audit/\`, and \`ai_docs/solutions/\`.
|
|
66
|
-
- If missing, create them by analyzing the codebase in batches.
|
|
67
|
-
- Never treat architecture or feature history as a substitute for Vision.
|
|
68
|
-
|
|
69
|
-
## 3. Vision Gate
|
|
70
|
-
Standalone:
|
|
71
|
-
- Read \`ai_docs/vision/project_vision.md\`, \`roadmap.md\`, and \`principles.md\`.
|
|
72
|
-
- Vision documents start as \`Stato: DRAFT\`; DRAFT informs but does not block an explicit user request.
|
|
73
|
-
- \`Stato: APPROVED\` is binding: surface conflicts before implementation.
|
|
74
|
-
|
|
75
|
-
Hybrid/devPNT:
|
|
76
|
-
- Read the active M-VISION before design or code.
|
|
77
|
-
- Verify the request advances a stated benefit or success signal.
|
|
78
|
-
- If request, local Vision, and M-VISION diverge, stop and surface the conflict.
|
|
79
|
-
|
|
80
|
-
## 4. Request Analysis
|
|
81
|
-
For L3 in Standalone:
|
|
82
|
-
- Create or update \`ai_docs/solutions/ANALYSIS_[feature].md\`.
|
|
83
|
-
- Include Objective, Feature Vision, Impact, Security and Threat Model, Action Plan, Test Strategy, and Diary/Current State.
|
|
84
|
-
|
|
85
|
-
For L3 in Hybrid:
|
|
86
|
-
- Restore Master Plan, Action Plan, and related devPNT artifacts.
|
|
87
|
-
- Use devPNT for D-UC, P-TM, E-ISP, E-TDD, E-TP, ADR, and plan updates.
|
|
88
|
-
- Use Markdown shadows only as readable mirrors, never as the authoritative source over devPNT.
|
|
89
|
-
|
|
90
|
-
## 5. Development and Testing
|
|
91
|
-
Only after the required gate for the triage level:
|
|
92
|
-
1. Implement surgically following the plan.
|
|
93
|
-
2. Write or update automated tests where possible, using AAA for unit tests.
|
|
94
|
-
3. Run tests/lint/smoke checks. If the environment cannot run them, document the alternative verification.
|
|
95
|
-
4. After 3 consecutive test runs without progress, stop and ask for guidance.
|
|
96
|
-
|
|
97
|
-
## 6. Closing
|
|
98
|
-
- Verify the result against local Vision or devPNT M-VISION.
|
|
99
|
-
- Update only documents actually impacted.
|
|
100
|
-
- In Hybrid, propose ADR/KL updates when architectural facts changed.
|
|
101
|
-
- Keep docs and code in the same commit/PR.
|
|
102
|
-
`;
|
|
103
|
-
|
|
104
|
-
const projectVisionBoilerplate = `# Project Vision
|
|
105
|
-
Stato: DRAFT
|
|
106
|
-
|
|
107
|
-
## North Star
|
|
108
|
-
- TBD
|
|
109
|
-
|
|
110
|
-
## Target Users
|
|
111
|
-
- TBD
|
|
112
|
-
|
|
113
|
-
## Goals
|
|
114
|
-
- TBD
|
|
115
|
-
|
|
116
|
-
## Non-Goals
|
|
117
|
-
- TBD
|
|
118
|
-
|
|
119
|
-
## Success Signals
|
|
120
|
-
- TBD
|
|
121
|
-
`;
|
|
122
|
-
|
|
123
|
-
const roadmapBoilerplate = `# Vision Roadmap
|
|
124
|
-
Stato: DRAFT
|
|
125
|
-
|
|
126
|
-
| Milestone | Expected Benefit | Priority | Success Signal | Status |
|
|
127
|
-
|:---|:---|:---|:---|:---|
|
|
128
|
-
| M1 | - | - | - | [PLANNED] |
|
|
129
|
-
`;
|
|
130
|
-
|
|
131
|
-
const principlesBoilerplate = `# Vision Principles
|
|
132
|
-
Stato: DRAFT
|
|
133
|
-
|
|
134
|
-
## Principles
|
|
135
|
-
- TBD
|
|
136
|
-
|
|
137
|
-
## Strategic Anti-Patterns
|
|
138
|
-
- TBD
|
|
139
|
-
`;
|
|
140
|
-
|
|
141
|
-
const historyBoilerplate = `<!-- GENERATED by agentic-sdlc - update manually only if the project does not use sdlc_check.py index. -->
|
|
142
|
-
# Feature History
|
|
143
|
-
|
|
144
|
-
| ID | Feature Name | Level | Status | Start Date | End Date | Analysis Doc |
|
|
145
|
-
|:---|:---|:---|:---|:---|:---|:---|
|
|
146
|
-
`;
|
|
147
|
-
|
|
148
|
-
console.log('🚀 Initializing Agentic SDLC workflow (Discovery Mode)...');
|
|
149
|
-
|
|
150
|
-
// 3. Directory creation
|
|
151
|
-
directories.forEach(dir => {
|
|
91
|
+
// 4. Create directories
|
|
92
|
+
directories.forEach((dir) => {
|
|
152
93
|
if (!fs.existsSync(dir)) {
|
|
153
94
|
fs.mkdirSync(dir, { recursive: true });
|
|
154
95
|
console.log(`📁 Created directory: ${path.relative(cwd, dir)}`);
|
|
155
96
|
}
|
|
156
97
|
});
|
|
157
98
|
|
|
158
|
-
//
|
|
159
|
-
const writeIfNotExists = (
|
|
99
|
+
// 5. Write seed files (never overwrite)
|
|
100
|
+
const writeIfNotExists = (relPath, content, description) => {
|
|
101
|
+
const filePath = path.join(cwd, relPath);
|
|
160
102
|
if (!fs.existsSync(filePath)) {
|
|
161
103
|
fs.writeFileSync(filePath, content, 'utf8');
|
|
162
|
-
console.log(`📄 Created file: ${
|
|
104
|
+
console.log(`📄 Created file: ${relPath}${description ? ` (${description})` : ''}`);
|
|
163
105
|
return true;
|
|
164
|
-
} else {
|
|
165
|
-
console.log(`⏭️ Skipped: ${path.relative(cwd, filePath)} already exists.`);
|
|
166
|
-
return false;
|
|
167
106
|
}
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
writeIfNotExists(files.featuresHistory, historyBoilerplate, 'History Table');
|
|
176
|
-
writeIfNotExists(files.auditPlan, '# Audit Plan\n\nStates: PENDING | ANALYZED | SKIPPED.\n\n| Percorso | Stato | Riferimento | Note |\n|---|---|---|---|\n| / | PENDING | - | Initial analysis |\n', 'Audit Plan');
|
|
177
|
-
|
|
178
|
-
// 5. Client Discovery and Configuration
|
|
107
|
+
console.log(`⏭️ Skipped: ${relPath} already exists.`);
|
|
108
|
+
return false;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
seedFiles.forEach(([relPath, content]) => writeIfNotExists(relPath, content));
|
|
112
|
+
|
|
113
|
+
// 6. Client discovery and protocol pointers
|
|
179
114
|
console.log('\n--- Environment Analysis ---');
|
|
180
115
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
116
|
+
const protocolFiles = {
|
|
117
|
+
claude: 'CLAUDE.md',
|
|
118
|
+
gemini: 'GEMINI.md',
|
|
119
|
+
codex: 'AGENTS.md',
|
|
120
|
+
};
|
|
185
121
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
122
|
+
for (const client of CLIENTS) {
|
|
123
|
+
if (clientDetected(client)) {
|
|
124
|
+
console.log(`✅ ${client.label} detected.`);
|
|
125
|
+
writeIfNotExists(protocolFiles[client.key], protocolContent, `${client.label} protocol pointer`);
|
|
126
|
+
}
|
|
189
127
|
}
|
|
190
128
|
|
|
191
|
-
if (checkCommand('codex')) {
|
|
192
|
-
console.log('✅ Codex AI detected.');
|
|
193
|
-
writeIfNotExists(files.codexAgents, protocolContent, 'Codex AGENTS.md');
|
|
194
|
-
}
|
|
195
|
-
|
|
196
129
|
// Cursor/Windsurf (always recommended)
|
|
197
|
-
writeIfNotExists(
|
|
130
|
+
writeIfNotExists('.cursorrules', protocolContent, 'Cursor/Windsurf rules');
|
|
131
|
+
|
|
132
|
+
// 7. Generate ai_docs/INDEX.md so the very first `validate` is already clean.
|
|
133
|
+
// The manifest is generated, never seeded: delegate to the validator if Python is available.
|
|
134
|
+
const validator = path.join(SKILL_SOURCE, 'scripts', 'sdlc_check.py');
|
|
135
|
+
let indexed = false;
|
|
136
|
+
for (const py of ['python', 'python3', 'py']) {
|
|
137
|
+
try {
|
|
138
|
+
execSync(`${py} "${validator}" index --root "${cwd}"`, { stdio: 'ignore' });
|
|
139
|
+
console.log('📇 Generated ai_docs/INDEX.md (document manifest).');
|
|
140
|
+
indexed = true;
|
|
141
|
+
break;
|
|
142
|
+
} catch (e) { /* try the next interpreter */ }
|
|
143
|
+
}
|
|
144
|
+
if (!indexed) {
|
|
145
|
+
console.log('ℹ️ Python not found: generate the manifest later with '
|
|
146
|
+
+ '"python <skill_dir>/scripts/sdlc_check.py index" (validate reports it until then).');
|
|
147
|
+
}
|
|
198
148
|
|
|
199
149
|
console.log('\n✅ Setup completed successfully!');
|
|
200
150
|
console.log('💡 Next steps:');
|
|
201
|
-
console.log(' 1.
|
|
202
|
-
console.log(' 2.
|
|
203
|
-
console.log(' 3.
|
|
204
|
-
console.log(' 4. Start analyzing the codebase following ai_docs/audit/audit_plan.md.');
|
|
151
|
+
console.log(' 1. Make sure the agentic-sdlc skill is installed (agentic-sdlc-install-skill).');
|
|
152
|
+
console.log(' 2. Restart/open the project in your AI client so it reads the protocol pointer.');
|
|
153
|
+
console.log(' 3. Start with an audit following ai_docs/audit/audit_plan.md.');
|
package/scripts/lib.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// Shared helpers for the Agentic SDLC npm scripts (init / postinstall / preuninstall).
|
|
2
|
+
// Single source for client detection and skill-target paths: init and postinstall
|
|
3
|
+
// must never disagree on what "Claude Code is installed" means.
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const os = require('os');
|
|
8
|
+
const { execSync } = require('child_process');
|
|
9
|
+
|
|
10
|
+
const PACKAGE_ROOT = path.resolve(__dirname, '..');
|
|
11
|
+
const SKILL_SOURCE = path.join(PACKAGE_ROOT, 'skills', 'agentic-sdlc-skill');
|
|
12
|
+
const TEMPLATES_PATH = path.join(SKILL_SOURCE, 'templates.md');
|
|
13
|
+
|
|
14
|
+
// One entry per supported AI client. `home` may be overridden by an env var
|
|
15
|
+
// (Claude Desktop / portable installs); presence of the home dir counts as
|
|
16
|
+
// detection even when the CLI is not on PATH.
|
|
17
|
+
const CLIENTS = [
|
|
18
|
+
{
|
|
19
|
+
key: 'claude',
|
|
20
|
+
label: 'Claude Code',
|
|
21
|
+
cmd: 'claude',
|
|
22
|
+
home: process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), '.claude'),
|
|
23
|
+
envVar: 'CLAUDE_CONFIG_DIR',
|
|
24
|
+
reload: 'Restart Claude Code to load it. Invoke via Skill tool as "agentic-sdlc".',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
key: 'gemini',
|
|
28
|
+
label: 'Gemini CLI',
|
|
29
|
+
cmd: 'gemini',
|
|
30
|
+
home: process.env.GEMINI_HOME || path.join(os.homedir(), '.gemini'),
|
|
31
|
+
envVar: 'GEMINI_HOME',
|
|
32
|
+
reload: 'Run "gemini skills reload" or restart Gemini CLI to load it.',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
key: 'codex',
|
|
36
|
+
label: 'Codex AI',
|
|
37
|
+
cmd: 'codex',
|
|
38
|
+
home: process.env.CODEX_HOME || path.join(os.homedir(), '.codex'),
|
|
39
|
+
envVar: 'CODEX_HOME',
|
|
40
|
+
reload: 'Restart Codex to load it. Invoke it as "$agentic-sdlc" or by asking for Agentic SDLC.',
|
|
41
|
+
},
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
function commandExists(cmd) {
|
|
45
|
+
try {
|
|
46
|
+
execSync(`${cmd} --version`, { stdio: 'ignore' });
|
|
47
|
+
return true;
|
|
48
|
+
} catch (e) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function clientDetected(client) {
|
|
54
|
+
return commandExists(client.cmd)
|
|
55
|
+
|| Boolean(process.env[client.envVar])
|
|
56
|
+
|| fs.existsSync(client.home);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function skillTarget(client) {
|
|
60
|
+
return path.join(client.home, 'skills', 'agentic-sdlc');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function copyRecursive(src, dest) {
|
|
64
|
+
if (typeof fs.cpSync === 'function') {
|
|
65
|
+
fs.cpSync(src, dest, { recursive: true, force: true });
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
// Fallback for Node < 16.7
|
|
69
|
+
if (!fs.existsSync(dest)) fs.mkdirSync(dest, { recursive: true });
|
|
70
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
71
|
+
const s = path.join(src, entry.name);
|
|
72
|
+
const d = path.join(dest, entry.name);
|
|
73
|
+
if (entry.isDirectory()) copyRecursive(s, d);
|
|
74
|
+
else fs.copyFileSync(s, d);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Parse templates.md into { headingText: [fencedBlock, ...] }.
|
|
80
|
+
* Templates are single-sourced there: the init script must extract them
|
|
81
|
+
* instead of carrying its own inline copies (which historically drifted).
|
|
82
|
+
*/
|
|
83
|
+
function loadTemplates() {
|
|
84
|
+
const text = fs.readFileSync(TEMPLATES_PATH, 'utf8');
|
|
85
|
+
const lines = text.split(/\r?\n/);
|
|
86
|
+
const sections = {};
|
|
87
|
+
let heading = null;
|
|
88
|
+
let block = null;
|
|
89
|
+
for (const line of lines) {
|
|
90
|
+
const h = line.match(/^##\s+(.*)$/);
|
|
91
|
+
if (h && block === null) {
|
|
92
|
+
heading = h[1].trim();
|
|
93
|
+
sections[heading] = sections[heading] || [];
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (/^```/.test(line)) {
|
|
97
|
+
if (block === null) {
|
|
98
|
+
block = [];
|
|
99
|
+
} else {
|
|
100
|
+
if (heading) sections[heading].push(block.join('\n') + '\n');
|
|
101
|
+
block = null;
|
|
102
|
+
}
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (block !== null) block.push(line);
|
|
106
|
+
}
|
|
107
|
+
return sections;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Return the Nth fenced block of the section whose heading contains `needle`.
|
|
112
|
+
* Throws with a clear message when missing: writing a wrong or empty
|
|
113
|
+
* boilerplate silently would be worse than failing the init.
|
|
114
|
+
*/
|
|
115
|
+
function templateFor(sections, needle, index = 0) {
|
|
116
|
+
const heading = Object.keys(sections).find((h) => h.includes(needle));
|
|
117
|
+
const blocks = heading ? sections[heading] : undefined;
|
|
118
|
+
if (!blocks || !blocks[index]) {
|
|
119
|
+
throw new Error(
|
|
120
|
+
`Template section containing "${needle}" (block ${index}) not found in ${TEMPLATES_PATH}. ` +
|
|
121
|
+
'The package is corrupted or templates.md was restructured: fix templates.md, do not improvise content.'
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
return blocks[index];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
module.exports = {
|
|
128
|
+
PACKAGE_ROOT,
|
|
129
|
+
SKILL_SOURCE,
|
|
130
|
+
TEMPLATES_PATH,
|
|
131
|
+
CLIENTS,
|
|
132
|
+
commandExists,
|
|
133
|
+
clientDetected,
|
|
134
|
+
skillTarget,
|
|
135
|
+
copyRecursive,
|
|
136
|
+
loadTemplates,
|
|
137
|
+
templateFor,
|
|
138
|
+
};
|