@novare-technologies/nvaid 0.2.1 → 0.2.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/dist/cli.js CHANGED
@@ -13,8 +13,9 @@ var AGENTS = [
13
13
  id: "claude",
14
14
  label: "Claude Code",
15
15
  skillsPath: ".claude/skills",
16
+ commandsPath: ".claude/commands",
17
+ // /nvaid:install resolves from .claude/commands/nvaid/install.md
16
18
  instructionsFile: "CLAUDE.md",
17
- format: "markdown",
18
19
  bespoke: true
19
20
  },
20
21
  {
@@ -22,68 +23,65 @@ var AGENTS = [
22
23
  label: "Kiro",
23
24
  skillsPath: ".kiro/skills",
24
25
  instructionsFile: ".kiro/steering/nvaid.md",
25
- format: "markdown",
26
26
  bespoke: true
27
27
  },
28
28
  {
29
29
  id: "cursor",
30
30
  label: "Cursor",
31
- skillsPath: ".cursor/rules",
32
- format: "mdc",
31
+ skillsPath: ".cursor/skills",
32
+ // cursor.com/docs/skills
33
33
  bespoke: true
34
34
  },
35
35
  {
36
36
  id: "copilot",
37
37
  label: "GitHub Copilot",
38
- skillsPath: ".github",
38
+ skillsPath: ".github/skills",
39
+ // docs.github.com — project skills in .github/skills
39
40
  instructionsFile: ".github/copilot-instructions.md",
40
- format: "markdown",
41
41
  bespoke: true
42
42
  },
43
43
  {
44
44
  id: "windsurf",
45
45
  label: "Windsurf",
46
- skillsPath: ".windsurf/rules",
47
- format: "markdown",
46
+ skillsPath: ".windsurf/skills",
47
+ // docs.windsurf.com/windsurf/cascade/skills
48
48
  bespoke: true
49
49
  },
50
50
  {
51
51
  id: "amazonq",
52
52
  label: "Amazon Q",
53
- skillsPath: ".amazonq/rules",
54
- format: "markdown",
53
+ skillsPath: ".amazonq/skills",
55
54
  bespoke: true
56
55
  },
57
56
  {
58
57
  id: "cline",
59
58
  label: "Cline",
60
- skillsPath: ".cline/rules",
59
+ skillsPath: ".cline/skills",
60
+ // docs.cline.bot/customization/skills
61
61
  instructionsFile: ".clinerules",
62
- format: "markdown",
63
62
  bespoke: true
64
63
  },
65
64
  {
66
65
  id: "gemini",
67
66
  label: "Gemini Code Assist",
68
- skillsPath: ".gemini",
69
- instructionsFile: ".gemini/styleguide.md",
70
- format: "markdown",
67
+ skillsPath: ".gemini/skills",
68
+ // geminicli.com/docs/cli/skills
71
69
  bespoke: true
72
70
  },
73
71
  {
74
72
  id: "aider",
75
73
  label: "Aider",
76
- skillsPath: ".nvaid/skills",
74
+ skillsPath: ".agents/skills",
75
+ // neutral cross-tool skills location
77
76
  instructionsFile: "AGENTS.md",
78
- format: "markdown",
79
77
  bespoke: true
80
78
  },
81
79
  {
82
80
  id: "agents-md",
83
- label: "Any AGENTS.md-compatible tool (catch-all)",
84
- skillsPath: ".nvaid/skills",
81
+ label: "Any Agent-Skills / AGENTS.md tool (catch-all)",
82
+ skillsPath: ".agents/skills",
83
+ // the emerging neutral standard (per GitHub Copilot docs)
85
84
  instructionsFile: "AGENTS.md",
86
- format: "markdown",
87
85
  bespoke: false
88
86
  }
89
87
  ];
@@ -120,11 +118,7 @@ function aidlcRootFor(agent) {
120
118
  void agent;
121
119
  return "nvaid/rules";
122
120
  }
123
- function withHeader(body, format) {
124
- if (format === "mdc") {
125
- return `${DO_NOT_EDIT}
126
- ${body}`;
127
- }
121
+ function withHeader(body) {
128
122
  return `${DO_NOT_EDIT}
129
123
 
130
124
  ${body}`;
@@ -140,16 +134,17 @@ async function listCommandFiles() {
140
134
  async function renderTemplate(srcFile, agent) {
141
135
  const raw = await readFile(srcFile, "utf8");
142
136
  const substituted = raw.split(AIDLC_ROOT_TOKEN).join(aidlcRootFor(agent));
143
- return withHeader(substituted, agent.format);
137
+ return withHeader(substituted);
144
138
  }
145
139
  function skillTarget(projectRoot, agent, skill) {
146
- const ext = agent.format === "mdc" ? "mdc" : "md";
147
- return join(projectRoot, agent.skillsPath, `${skill}.${ext}`);
140
+ return join(projectRoot, agent.skillsPath, skill, "SKILL.md");
148
141
  }
149
142
  function commandTarget(projectRoot, agent, cmdFile) {
150
143
  const base = cmdFile.replace(/\.md$/, "");
151
- const ext = agent.format === "mdc" ? "mdc" : "md";
152
- return join(projectRoot, agent.skillsPath, `commands`, `nvaid-${base}.${ext}`);
144
+ if (agent.commandsPath) {
145
+ return join(projectRoot, agent.commandsPath, "nvaid", `${base}.md`);
146
+ }
147
+ return join(projectRoot, agent.skillsPath, `nvaid-${base}`, "SKILL.md");
153
148
  }
154
149
  async function writeFileEnsuringDir(path, body, force, result) {
155
150
  if (!force && existsSync(path)) {
@@ -186,15 +181,14 @@ async function diffAgentFiles(opts) {
186
181
  for (const agent of opts.agents) {
187
182
  for (const skill of skills) {
188
183
  const src = join(SKILLS_SRC, skill, "SKILL.md");
189
- if (existsSync(src)) checks.push({ target: skillTarget(opts.projectRoot, agent, skill), src });
184
+ if (existsSync(src)) checks.push({ target: skillTarget(opts.projectRoot, agent, skill), src, agent });
190
185
  }
191
186
  for (const cmd of commands) {
192
- checks.push({ target: commandTarget(opts.projectRoot, agent, cmd), src: join(COMMANDS_SRC, cmd) });
187
+ checks.push({ target: commandTarget(opts.projectRoot, agent, cmd), src: join(COMMANDS_SRC, cmd), agent });
193
188
  }
194
189
  }
195
- for (const { target, src } of checks) {
196
- const agent = opts.agents.find((a) => target.includes(a.skillsPath.replace(/^\.\//, "")));
197
- const expected = await renderTemplate(src, agent ?? opts.agents[0]);
190
+ for (const { target, src, agent } of checks) {
191
+ const expected = await renderTemplate(src, agent);
198
192
  if (!existsSync(target)) {
199
193
  drift.push(`${relative(opts.projectRoot, target)} (missing)`);
200
194
  continue;
@@ -205,12 +199,22 @@ async function diffAgentFiles(opts) {
205
199
  return drift;
206
200
  }
207
201
  async function cleanAgentDirs(projectRoot, agents) {
202
+ const skills = await listSkillDirs().catch(() => []);
208
203
  for (const agent of agents) {
209
- const dir = join(projectRoot, agent.skillsPath);
210
- const commandsDir = join(dir, "commands");
211
- if (existsSync(commandsDir)) await rm(commandsDir, { recursive: true, force: true });
204
+ if (agent.commandsPath) {
205
+ await rmIfExists(join(projectRoot, agent.commandsPath, "nvaid"));
206
+ }
207
+ await rmIfExists(join(projectRoot, agent.skillsPath, "commands"));
208
+ await rmIfExists(join(projectRoot, agent.skillsPath, "nvaid-commands"));
209
+ for (const skill of skills) {
210
+ await rmIfExists(join(projectRoot, agent.skillsPath, `${skill}.md`));
211
+ await rmIfExists(join(projectRoot, agent.skillsPath, `${skill}.mdc`));
212
+ }
212
213
  }
213
214
  }
215
+ async function rmIfExists(path) {
216
+ if (existsSync(path)) await rm(path, { recursive: true, force: true });
217
+ }
214
218
 
215
219
  // src/scaffold.ts
216
220
  import { cp, mkdir as mkdir2, readdir as readdir2 } from "fs/promises";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@novare-technologies/nvaid",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "nvaid — one CLI that installs an AI-DLC skills-and-workflow toolkit into any coding agent, and houses intents, config, and the design-code dictionary in a single nvaid/ folder.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,7 +16,7 @@
16
16
  "scripts": {
17
17
  "build": "tsup src/cli.ts --format esm --clean",
18
18
  "dev": "tsx src/cli.ts",
19
- "test": "vitest run --passWithNoTests",
19
+ "test": "vitest run",
20
20
  "typecheck": "tsc --noEmit",
21
21
  "prepublishOnly": "npm run build"
22
22
  },
@@ -47,13 +47,48 @@ not a file-scan's. This skill does that reading. A human reviews before it's mar
47
47
  narrative derived from reading the code; §1 references `config.yml`'s `tech_stack`
48
48
  rather than repeating it. Be honest in the "not yet mapped" section about coverage.
49
49
 
50
- 5. **Human review.** Present all three for review. Per propose-don't-dispose, you draft;
51
- a human confirms. Do not self-approve.
50
+ 5. **Set up ADRs (Architecture Decision Records) — the project's decision anchors.**
51
+ ADRs are where a significant decision is justified and preserved, so the project (and
52
+ any future agent) can trace *why* a choice was made and revisit it later. Create them
53
+ on demand, not as empty ceremony:
54
+ - If authoring PROJECT-RULES (step 3) surfaced genuine, non-obvious decisions — an
55
+ approved-stack choice, a deliberate constraint, something a reviewer might otherwise
56
+ question — **create `nvaid/adr/`** and seed one ADR per such decision, numbered
57
+ `ADR-001`, `ADR-002`, … using the template below. These are the decisions the project
58
+ has already made, now anchored.
59
+ - If the project is simple enough that no decision needs anchoring yet, **do not create
60
+ an empty `adr/` folder** — just tell the user ADRs will be added when the first real
61
+ decision arises (e.g. via the `solutions` skill flagging "needs a new ADR"). The
62
+ folder appears when there's a decision to put in it.
63
+ - Each ADR follows this shape:
64
+ ```markdown
65
+ ---
66
+ adr: ADR-NNN
67
+ title: "<the decision, stated as a choice>"
68
+ status: accepted # proposed | accepted | superseded by ADR-XXX
69
+ date: "<YYYY-MM-DD>"
70
+ ---
71
+ # ADR-NNN — <title>
72
+ ## Context
73
+ <the forces at play: what problem/constraint prompted this decision>
74
+ ## Decision
75
+ <what was decided, stated plainly>
76
+ ## Consequences
77
+ <what this makes easier, what it makes harder, what it rules out>
78
+ ## Alternatives considered
79
+ <options weighed and why they lost — so the decision can be revisited with the same context>
80
+ ```
81
+ - A decision anchored in an ADR must not contradict `PROJECT-RULES.md`; if it does,
82
+ reconcile them (an ADR can *drive* a rules change, recorded in the rules change log).
52
83
 
53
- 6. **Flip the gate.** Only after the user confirms each document is genuinely filled (not
84
+ 6. **Human review.** Present all documents (config, PROJECT-RULES, dictionary, any ADRs)
85
+ for review. Per propose-don't-dispose, you draft; a human confirms. Do not self-approve.
86
+
87
+ 7. **Flip the gate.** Only after the user confirms each document is genuinely filled (not
54
88
  placeholder text), set the matching flag in `config.yml`'s `install:` block to `true`:
55
89
  `config`, `project_rules`, `design_code_dictionary`. When all three are true, the
56
- workflow commands unblock.
90
+ workflow commands unblock. (ADRs are not a gate flag — they are created as decisions
91
+ warrant, not required for the install to be complete.)
57
92
 
58
93
  ## Boundaries
59
94
 
@@ -61,3 +96,5 @@ not a file-scan's. This skill does that reading. A human reviews before it's mar
61
96
  don't fabricate.
62
97
  - Never set an `install:` flag to `true` on a document that still contains template
63
98
  `<placeholder>` text or that the user hasn't confirmed.
99
+ - **Create `nvaid/adr/` only when there is a real decision to anchor** — never an empty
100
+ folder for its own sake.
@@ -84,4 +84,4 @@ context: ""
84
84
 
85
85
  # nvaid version this repo was last generated against. `nvaid validate` compares the
86
86
  # installed CLI version to this and flags drift.
87
- generated_with: "0.2.1"
87
+ generated_with: "0.2.3"
@@ -2,13 +2,13 @@
2
2
  name: customer-experience
3
3
  description: Drafts the Customer Experience Contract for an Intent, per customer-experience-contract-generation-rules.md. Use when asked to run the Customer Experience Skill or draft a Customer Experience contract during Mob Elaboration.
4
4
  invoked_by: Mob Elaboration (Ceremony 1), Phases 2–5
5
- output: file — intents/<INTENT-ID>/contracts/customer-experience-contract.md
5
+ output: file — nvaid/intents/<INTENT-ID>/contracts/customer-experience-contract.md
6
6
  ---
7
7
 
8
8
  # Customer Experience Skill
9
9
 
10
10
  Drafts the Customer Experience Contract for an Intent, per
11
- `docs/templates/customer-experience-contract-generation-rules.md` — reconciling what the
11
+ `{{AIDLC_ROOT}}/customer-experience-contract-generation-rules.md` — reconciling what the
12
12
  room actually committed to against what `intent.md` originally asked for.
13
13
 
14
14
  ## Steps
@@ -18,7 +18,7 @@ room actually committed to against what `intent.md` originally asked for.
18
18
  2. Write the Final Acceptance Criteria: the Intent's Success Criteria, incorporating
19
19
  what the other contracts actually committed to, not a verbatim restatement.
20
20
  3. Tie "done" to a concrete validation scenario, never just "the code merged."
21
- 4. Write `intents/<INTENT-ID>/contracts/customer-experience-contract.md`.
21
+ 4. Write `nvaid/intents/<INTENT-ID>/contracts/customer-experience-contract.md`.
22
22
 
23
23
  ## Boundaries
24
24
 
@@ -2,13 +2,13 @@
2
2
  name: frontend
3
3
  description: Drafts the Frontend Architecture Contract for an Intent, per frontend-architecture-contract-generation-rules.md. Use when asked to run the Frontend Skill or draft a Frontend contract during Mob Elaboration.
4
4
  invoked_by: Mob Elaboration (Ceremony 1), Phases 2–5
5
- output: file — intents/<INTENT-ID>/contracts/frontend-architecture-contract.md
5
+ output: file — nvaid/intents/<INTENT-ID>/contracts/frontend-architecture-contract.md
6
6
  ---
7
7
 
8
8
  # Frontend Skill
9
9
 
10
10
  Drafts the Frontend Architecture Contract for an Intent, per
11
- `docs/templates/frontend-architecture-contract-generation-rules.md` — consuming the
11
+ `{{AIDLC_ROOT}}/frontend-architecture-contract-generation-rules.md` — consuming the
12
12
  Backend contract's shapes verbatim rather than reinterpreting them.
13
13
 
14
14
  ## Steps
@@ -22,7 +22,7 @@ Backend contract's shapes verbatim rather than reinterpreting them.
22
22
  4. State Identity/Access implications explicitly, even when "none for this Intent" —
23
23
  never left implicit.
24
24
  5. List components touched (Design-Code Dictionary impact).
25
- 6. Write `intents/<INTENT-ID>/contracts/frontend-architecture-contract.md`.
25
+ 6. Write `nvaid/intents/<INTENT-ID>/contracts/frontend-architecture-contract.md`.
26
26
 
27
27
  ## Boundaries
28
28
 
@@ -7,13 +7,13 @@ output: link — a Jira or GitHub Projects ticket
7
7
 
8
8
  # Project Ticketing Skill
9
9
 
10
- Creates and updates Epics, Stories, and Bugs per `docs/templates/ISSUE-TRACKER-TEMPLATE.md`
10
+ Creates and updates Epics, Stories, and Bugs per `{{AIDLC_ROOT}}/ISSUE-TRACKER-TEMPLATE.md`
11
11
  — so ticket shape never drifts from one Intent to the next.
12
12
 
13
13
  ## Steps
14
14
 
15
15
  1. On Unit Breakdown (Mob Elaboration Phase 5), create one Story or Bug per Unit,
16
- classified per `docs/templates/unit-breakdown-rules.md` §3.
16
+ classified per `{{AIDLC_ROOT}}/unit-breakdown-rules.md` §3.
17
17
  2. Attach each ticket's Acceptance Criteria verbatim from the Unit's own design doc —
18
18
  never re-worded independently.
19
19
  3. As Mob Construction moves a Unit through Design → Building → Gates → Merged, update
@@ -2,13 +2,13 @@
2
2
  name: quality
3
3
  description: Drafts the Quality Architecture Contract for an Intent, per quality-architecture-contract-generation-rules.md. Use when asked to run the Quality Skill or draft a Quality contract during Mob Elaboration.
4
4
  invoked_by: Mob Elaboration (Ceremony 1), Phases 2–5
5
- output: file — intents/<INTENT-ID>/contracts/quality-architecture-contract.md
5
+ output: file — nvaid/intents/<INTENT-ID>/contracts/quality-architecture-contract.md
6
6
  ---
7
7
 
8
8
  # Quality Skill
9
9
 
10
10
  Drafts the Quality Architecture Contract for an Intent, per
11
- `docs/templates/quality-architecture-contract-generation-rules.md` — the Required Test
11
+ `{{AIDLC_ROOT}}/quality-architecture-contract-generation-rules.md` — the Required Test
12
12
  Coverage table the Unit Test and Integration Test gates run against.
13
13
 
14
14
  ## Steps
@@ -20,12 +20,12 @@ Coverage table the Unit Test and Integration Test gates run against.
20
20
  3. State which existing SRS NFRs this Intent's Units are held to, beyond the standing
21
21
  baseline; say "none beyond baseline" explicitly when true.
22
22
  4. Log any Known Gap the room consciously accepted, flagged rather than dropped.
23
- 5. Write `intents/<INTENT-ID>/contracts/quality-architecture-contract.md`.
23
+ 5. Write `nvaid/intents/<INTENT-ID>/contracts/quality-architecture-contract.md`.
24
24
 
25
25
  ## Boundaries
26
26
 
27
27
  - Never define Solution-Specific gates (Build, Code Coverage, Code Quality,
28
- Reusability, Regression Test, SAST) — those are fixed in `docs/templates/PROJECT-RULES.md`
28
+ Reusability, Regression Test, SAST) — those are fixed in `nvaid/PROJECT-RULES.md`
29
29
  §5.2, not something any Intent's contract opts into or out of.
30
30
  - A draft, not a verdict — flag it awaiting the Quality Architect's Sign-Off; never
31
31
  present it as final.
@@ -2,26 +2,28 @@
2
2
  name: solutions
3
3
  description: Drafts the Solutions Architecture Contract for an Intent, per solutions-architecture-contract-generation-rules.md. Use when asked to run the Solutions Skill or draft a Solutions contract during Mob Elaboration.
4
4
  invoked_by: Mob Elaboration (Ceremony 1), Phases 2–5
5
- output: file — intents/<INTENT-ID>/contracts/solutions-architecture-contract.md
5
+ output: file — nvaid/intents/<INTENT-ID>/contracts/solutions-architecture-contract.md
6
6
  ---
7
7
 
8
8
  # Solutions Skill
9
9
 
10
10
  Drafts the Solutions Architecture Contract for an Intent, per
11
- `docs/templates/solutions-architecture-contract-generation-rules.md` — the cross-role
11
+ `{{AIDLC_ROOT}}/solutions-architecture-contract-generation-rules.md` — the cross-role
12
12
  boundary and consistency check every other contract this session has to fit inside.
13
13
 
14
14
  ## Steps
15
15
 
16
- 1. Assess whether this Intent introduces a new system container, crosses an SRS System
17
- Container boundary, or needs a new ADR — state the answer even when it's "no" on
18
- every count.
16
+ 1. Assess whether this Intent introduces a new system container, crosses an architectural
17
+ boundary, or **needs a new ADR** — state the answer even when it's "no" on every count.
18
+ If a new ADR is warranted, record it as `nvaid/adr/ADR-NNN-<slug>.md` (next free number)
19
+ using the ADR shape from the `/nvaid:install` skill: Context, Decision, Consequences,
20
+ Alternatives considered. An ADR is a decision anchor — it must not contradict
21
+ `nvaid/PROJECT-RULES.md`; if it would, reconcile them.
19
22
  2. State explicitly what this Intent is and isn't allowed to touch.
20
- 3. Flag any unsupervised-action surface `docs/templates/PROJECT-RULES.md` §7 doesn't
21
- already cover.
23
+ 3. Flag any unsupervised-action surface `nvaid/PROJECT-RULES.md` §7 doesn't already cover.
22
24
  4. Cross-check the other contracts drafted this session for contradictions — the
23
25
  Consistency Gate, recorded in writing.
24
- 5. Write `intents/<INTENT-ID>/contracts/solutions-architecture-contract.md`.
26
+ 5. Write `nvaid/intents/<INTENT-ID>/contracts/solutions-architecture-contract.md`.
25
27
 
26
28
  ## Boundaries
27
29
 
@@ -2,7 +2,7 @@
2
2
  name: unit-breakdown
3
3
  description: Cuts an Intent into Units of Work, each with its own Acceptance Criteria, per unit-breakdown-rules.md. Use when asked to run the Unit Breakdown Skill, break down an Intent into Units, or produce a Unit Breakdown during Mob Elaboration Phase 5.
4
4
  invoked_by: Mob Elaboration (Ceremony 1), Phase 5
5
- output: file — intents/<INTENT-ID>/unit-breakdown.md
5
+ output: file — nvaid/intents/<INTENT-ID>/unit-breakdown.md
6
6
  ---
7
7
 
8
8
  # Unit Breakdown Skill
@@ -12,14 +12,14 @@ a first-cut proposal the room then critiques, not the decomposition of record.
12
12
 
13
13
  ## Steps
14
14
 
15
- 1. Read the Intent file (`intents/<INTENT-ID>/intent.md`) and its stated success
15
+ 1. Read the Intent file (`nvaid/intents/<INTENT-ID>/intent.md`) and its stated success
16
16
  criteria.
17
17
  2. Propose a decomposition into Units, each with its own Acceptance Criteria narrowed
18
- from the Intent's success criteria, per `docs/templates/unit-breakdown-rules.md` §2.
18
+ from the Intent's success criteria, per `{{AIDLC_ROOT}}/unit-breakdown-rules.md` §2.
19
19
  3. Classify each Unit as a Story or Bug (§3), and size it per the file's decomposition
20
20
  heuristics (§4).
21
21
  4. Number Units per §5.
22
- 5. Write `intents/<INTENT-ID>/unit-breakdown.md` — the contract index every
22
+ 5. Write `nvaid/intents/<INTENT-ID>/unit-breakdown.md` — the contract index every
23
23
  Architecture Contract Skill downstream reads from.
24
24
 
25
25
  ## Boundaries
@@ -27,5 +27,5 @@ a first-cut proposal the room then critiques, not the decomposition of record.
27
27
  - This is a proposal, not the decomposition of record. Mob Elaboration Phase 3
28
28
  ("Mark it up alone") and Phase 4 ("Negotiate live") are where the room actually owns
29
29
  the cut — flag this file as a draft awaiting that review, never as final.
30
- - Read `docs/templates/unit-breakdown-rules.md` in full before drafting; don't rely on
30
+ - Read `{{AIDLC_ROOT}}/unit-breakdown-rules.md` in full before drafting; don't rely on
31
31
  this summary alone for the numbering and classification rules.