azcodr 2.3.0 → 2.5.1
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/.agents/hooks.json +15 -0
- package/.agents/hooks.json.example +15 -0
- package/.agents/lib/agent-guard-command.js +103 -0
- package/.agents/lib/agent-guard-file.js +77 -0
- package/.agents/lib/agent-guard-tdd.js +77 -0
- package/.agents/lib/agent-guard.js +80 -0
- package/.agents/scripts/agent_guard.js +35 -3
- package/.agents/skills/clean-code-refactor/SKILL.md +1 -0
- package/.agents/skills/lets-build/SKILL.md +3 -2
- package/.agents/skills/lets-build/scripts/bootstrap_workspace.sh +159 -0
- package/.agents/skills/relentless-questioner/SKILL.md +1 -1
- package/.github/workflows/ci.yml +13 -0
- package/.github/workflows/publish.yml +7 -0
- package/AGENTS.md +3 -3
- package/CODE_OF_CONDUCT.md +122 -0
- package/CONTRIBUTING.md +16 -4
- package/README.md +77 -4
- package/docs/generated-enforcement-analysis.md +141 -0
- package/docs/rules/clean_code.md +3 -2
- package/docs/rules/test_driven_development.md +8 -5
- package/lib/cli-boundaries.d.ts +18 -0
- package/lib/cli-boundaries.d.ts.map +1 -0
- package/lib/cli-boundaries.js +46 -0
- package/lib/cli-boundaries.js.map +1 -0
- package/lib/cli-parse.d.ts +2 -1
- package/lib/cli-parse.d.ts.map +1 -1
- package/lib/cli-parse.js +15 -3
- package/lib/cli-parse.js.map +1 -1
- package/lib/cli.d.ts +3 -0
- package/lib/cli.d.ts.map +1 -1
- package/lib/cli.js +18 -4
- package/lib/cli.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/scaffold.js +1 -1
- package/lib/scaffold.js.map +1 -1
- package/memory.md +32 -0
- package/package.json +9 -3
- package/scripts/validate/toolchain.js +60 -0
- package/scripts/validate.js +12 -2
- package/src/cli-boundaries.ts +67 -0
- package/src/cli-parse.ts +19 -5
- package/src/cli.ts +20 -4
- package/src/index.ts +1 -1
- package/src/scaffold.ts +1 -1
|
@@ -43,6 +43,13 @@ jobs:
|
|
|
43
43
|
node --version
|
|
44
44
|
npm --version
|
|
45
45
|
|
|
46
|
+
- name: Verify TypeScript Compilation & lib/ Parity
|
|
47
|
+
shell: bash
|
|
48
|
+
run: |
|
|
49
|
+
npm run build
|
|
50
|
+
git diff --exit-code lib/
|
|
51
|
+
npm run typecheck
|
|
52
|
+
|
|
46
53
|
# Re-run the full gate on the exact release tag. prepublishOnly also runs
|
|
47
54
|
# on `npm publish`, but failing fast here avoids building a tarball at all.
|
|
48
55
|
- name: Run Syntax & Lint Checks
|
package/AGENTS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AGENTS.md
|
|
2
2
|
|
|
3
|
-
> **azcodr:
|
|
3
|
+
> **azcodr: Architecture governance toolkit, with an optional starter**
|
|
4
4
|
> **Workspace Mission:** Problem-first, topology-aligned production architectures governed by strict systemic atomicity, 100% open-source standards, true incremental TDD nano-cycles, and zero speculative bloat.
|
|
5
5
|
> **Runtime & Tools:** Node.js (`>=22.8.0`), npm (`>=10.0.0`) | `npm test` (test runner), `npm run test:coverage` (coverage gate), `npm run lint`, `npm run validate`.
|
|
6
6
|
> **Node floor rationale:** `>=22.8.0` satisfies Jest native ESM requirements (`--experimental-vm-modules`) and modern LTS security baselines. Node 18 (EOL 2025-04-30) and 20 (EOL 2026-04-30) no longer receive security patches.
|
|
@@ -48,7 +48,7 @@ Progress all tasks systematically through the unified **Agent Cognitive & Agile
|
|
|
48
48
|
2. INTERROGATE / DOMAIN ──► Relentless questioning; Ubiquitous Language, Aggregate invariants & state machines.
|
|
49
49
|
3. PLAN / OUTER TDD ──► Minimal blast radius; failing Outer Acceptance Test (UI/API RED).
|
|
50
50
|
4. EXECUTE / INNER TDD ──► Incremental nano-cycles (Uncle Bob's 3 Laws: 1 micro-assertion RED ➔ MINIMAL pass GREEN ➔ REFACTOR).
|
|
51
|
-
5. VERIFY / DoD & PROOF ──► Outer test turns GREEN; boundary smoke tests & 100
|
|
51
|
+
5. VERIFY / DoD & PROOF ──► Outer test turns GREEN; boundary smoke tests & 100% coverage on all metrics + mutation gate.
|
|
52
52
|
```
|
|
53
53
|
---
|
|
54
54
|
|
|
@@ -58,7 +58,7 @@ To prevent context bloat and keep prompt overhead minimal, detailed engineering
|
|
|
58
58
|
|
|
59
59
|
| Domain | Rule Reference File | When to Consult |
|
|
60
60
|
|---|---|---|
|
|
61
|
-
| **TDD & Isolation** | [docs/rules/test_driven_development.md](./docs/rules/test_driven_development.md) | Outside-In TDD, Uncle Bob's 3 Laws, 100% coverage, test isolation & DB rollback. |
|
|
61
|
+
| **TDD & Isolation** | [docs/rules/test_driven_development.md](./docs/rules/test_driven_development.md) | Outside-In TDD, Uncle Bob's 3 Laws, 100% coverage on all metrics + mutation gate, test isolation & DB rollback. |
|
|
62
62
|
| **Clean Code** | [docs/rules/clean_code.md](./docs/rules/clean_code.md) | Naming, small functions, CQS, SLAP, DRY, DbC, zero side-effects. |
|
|
63
63
|
| **Design Patterns** | [docs/rules/design_patterns.md](./docs/rules/design_patterns.md) | Adapter, Factory, Strategy, Result `<T, E>`, and GoF pattern catalog. |
|
|
64
64
|
| **Type Safety** | [docs/rules/type_safety.md](./docs/rules/type_safety.md) | Compiler strictness, branded nominal types, type discriminators across polyglot languages. |
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our
|
|
6
|
+
community a harassment-free experience for everyone, regardless of age, body
|
|
7
|
+
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
|
8
|
+
identity and expression, level of experience, education, socio-economic status,
|
|
9
|
+
nationality, personal appearance, race, caste, color, religion, or sexual identity
|
|
10
|
+
and orientation.
|
|
11
|
+
|
|
12
|
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
13
|
+
diverse, inclusive, and healthy community.
|
|
14
|
+
|
|
15
|
+
## Our Standards
|
|
16
|
+
|
|
17
|
+
Examples of behavior that contributes to a positive environment for our
|
|
18
|
+
community include:
|
|
19
|
+
|
|
20
|
+
* Demonstrating empathy and kindness toward other people
|
|
21
|
+
* Being respectful of differing opinions, viewpoints, and experiences
|
|
22
|
+
* Giving and gracefully accepting constructive feedback
|
|
23
|
+
* Accepting responsibility and apologizing to those affected by our mistakes,
|
|
24
|
+
and learning from the experience
|
|
25
|
+
* Focusing on what is best not just for us as individuals, but for the
|
|
26
|
+
overall community
|
|
27
|
+
|
|
28
|
+
Examples of unacceptable behavior include:
|
|
29
|
+
|
|
30
|
+
* The use of sexualized language or imagery, and sexual attention or advances of
|
|
31
|
+
any kind
|
|
32
|
+
* Trolling, insulting or derogatory comments, and personal or political attacks
|
|
33
|
+
* Public or private harassment
|
|
34
|
+
* Publishing others' private information, such as a physical or email
|
|
35
|
+
address, without their explicit permission
|
|
36
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
|
37
|
+
professional setting
|
|
38
|
+
|
|
39
|
+
## Enforcement Responsibilities
|
|
40
|
+
|
|
41
|
+
Community leaders are responsible for clarifying and enforcing our standards of
|
|
42
|
+
acceptable behavior and will take appropriate and fair corrective action in
|
|
43
|
+
response to any behavior that they deem inappropriate, threatening, offensive,
|
|
44
|
+
or harmful.
|
|
45
|
+
|
|
46
|
+
Community leaders have the right and responsibility to remove, edit, or reject
|
|
47
|
+
comments, commits, code, wiki edits, issues, and other contributions that are
|
|
48
|
+
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
|
49
|
+
decisions when appropriate.
|
|
50
|
+
|
|
51
|
+
## Scope
|
|
52
|
+
|
|
53
|
+
This Code of Conduct applies within all community spaces, and also applies when
|
|
54
|
+
an individual is officially representing the community in public spaces.
|
|
55
|
+
Examples of representing our community include using an official e-mail address,
|
|
56
|
+
posting via an official social media account, or acting as an appointed
|
|
57
|
+
representative at an online or offline event.
|
|
58
|
+
|
|
59
|
+
## Enforcement
|
|
60
|
+
|
|
61
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
62
|
+
reported to the community leaders responsible for enforcement at
|
|
63
|
+
[prosubodh+conduct@gmail.com](mailto:prosubodh+conduct@gmail.com).
|
|
64
|
+
All complaints will be reviewed and investigated promptly and fairly.
|
|
65
|
+
|
|
66
|
+
All community leaders are obligated to respect the privacy and security of the
|
|
67
|
+
reporter of any incident.
|
|
68
|
+
|
|
69
|
+
## Enforcement Guidelines
|
|
70
|
+
|
|
71
|
+
Community leaders will follow these Community Impact Guidelines in determining
|
|
72
|
+
the consequences for any action they deem in violation of this Code of Conduct:
|
|
73
|
+
|
|
74
|
+
### 1. Correction
|
|
75
|
+
|
|
76
|
+
**Community Impact**: Use of inappropriate language or other behavior deemed
|
|
77
|
+
unprofessional or unwelcome in the community.
|
|
78
|
+
|
|
79
|
+
**Consequence**: A private, written warning from community leaders, providing
|
|
80
|
+
clarity around the nature of the violation and an explanation of why the
|
|
81
|
+
behavior was inappropriate. A public apology may be requested.
|
|
82
|
+
|
|
83
|
+
### 2. Warning
|
|
84
|
+
|
|
85
|
+
**Community Impact**: A violation through a single incident or series of
|
|
86
|
+
actions.
|
|
87
|
+
|
|
88
|
+
**Consequence**: A warning with consequences for continued behavior. No
|
|
89
|
+
interaction with the people involved, including unsolicited interaction with
|
|
90
|
+
those enforcing the Code of Conduct, for a specified period of time. This
|
|
91
|
+
includes avoiding interactions in community spaces as well as external channels
|
|
92
|
+
like social media. Violating these terms may lead to a temporary or
|
|
93
|
+
permanent ban.
|
|
94
|
+
|
|
95
|
+
### 3. Temporary Ban
|
|
96
|
+
|
|
97
|
+
**Community Impact**: A serious violation of community standards, including
|
|
98
|
+
sustained inappropriate behavior.
|
|
99
|
+
|
|
100
|
+
**Consequence**: A temporary ban from any sort of interaction or public
|
|
101
|
+
communication with the community for a specified period of time. No public or
|
|
102
|
+
private interaction with the people involved, including unsolicited interaction
|
|
103
|
+
with those enforcing the Code of Conduct, is allowed during this period.
|
|
104
|
+
Violating these terms may lead to a permanent ban.
|
|
105
|
+
|
|
106
|
+
### 4. Permanent Ban
|
|
107
|
+
|
|
108
|
+
**Community Impact**: Demonstrating a pattern of violation of community
|
|
109
|
+
standards, including sustained inappropriate behavior, harassment of an
|
|
110
|
+
individual, or aggression toward or disparagement of classes of individuals.
|
|
111
|
+
|
|
112
|
+
**Consequence**: A permanent ban from any sort of public interaction within the
|
|
113
|
+
community.
|
|
114
|
+
|
|
115
|
+
## Attribution
|
|
116
|
+
|
|
117
|
+
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org),
|
|
118
|
+
version 2.1, available at
|
|
119
|
+
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html).
|
|
120
|
+
|
|
121
|
+
Community Impact Guidelines were inspired by
|
|
122
|
+
[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
|
package/CONTRIBUTING.md
CHANGED
|
@@ -49,15 +49,21 @@ Before submitting any code changes, all 5 quality gates must pass with zero erro
|
|
|
49
49
|
npm test
|
|
50
50
|
npm run test:coverage
|
|
51
51
|
```
|
|
52
|
-
*Coverage gates enforced:*
|
|
52
|
+
*Coverage gates enforced (CI fails below 100% on any metric):*
|
|
53
53
|
- **100% lines coverage**
|
|
54
|
-
- **
|
|
55
|
-
- **
|
|
54
|
+
- **100% functions coverage**
|
|
55
|
+
- **100% branches coverage**
|
|
56
|
+
- **100% statements coverage**
|
|
57
|
+
- Plus **100% mutant-kill on guards** (`npm run test:mutation`) and rejection of assertion-free tests.
|
|
56
58
|
5. **Agentic Architecture Validation:**
|
|
57
59
|
```bash
|
|
58
60
|
npm run validate
|
|
59
61
|
```
|
|
60
|
-
Validates root harness parity, progressive disclosure rules, skill formats, markdown links,
|
|
62
|
+
Validates root harness parity, progressive disclosure rules, skill formats, markdown links, ADR ledger consistency, and toolchain gate presence.
|
|
63
|
+
6. **Vendored Guard Sync:** after any change under `src/agent-guard*.ts` and `npm run build`, re-copy the four compiled engine files into `.agents/lib/` (byte-equality is enforced by `tests/agent-guard.test.ts`):
|
|
64
|
+
```bash
|
|
65
|
+
node -e "const fs=require('fs');for(const f of['agent-guard.js','agent-guard-command.js','agent-guard-file.js','agent-guard-tdd.js'])fs.copyFileSync('lib/'+f,'.agents/lib/'+f)"
|
|
66
|
+
```
|
|
61
67
|
|
|
62
68
|
---
|
|
63
69
|
|
|
@@ -77,3 +83,9 @@ Every contribution must preserve these core invariants:
|
|
|
77
83
|
2. Follow Conventional Commits: `feat(...)`, `fix(...)`, `docs(...)`, `test(...)`.
|
|
78
84
|
3. Ensure all tests and validation pass locally (`npm run prepublishOnly`).
|
|
79
85
|
4. Submit your pull request with a concise summary and verification evidence.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 📜 Code of Conduct
|
|
90
|
+
|
|
91
|
+
All contributors and maintainers are expected to abide by our [Code of Conduct](./CODE_OF_CONDUCT.md). Please report any violations to `prosubodh+conduct@gmail.com`.
|
package/README.md
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
# azcodr:
|
|
1
|
+
# azcodr: Architecture governance toolkit, with an optional starter
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/azcodr)
|
|
4
|
+
[](https://jsr.io/@azcodr/azcodr)
|
|
5
|
+
[](https://github.com/prosubodh/azcodr/actions/workflows/ci.yml)
|
|
6
|
+
[](https://github.com/prosubodh/azcodr/actions/workflows/ci.yml)
|
|
7
|
+
[](https://github.com/prosubodh/azcodr/blob/main/benchmark/RESULTS.md)
|
|
8
|
+
[](https://www.npmjs.com/package/azcodr)
|
|
9
|
+
[](./LICENSE)
|
|
10
|
+
|
|
11
|
+
> CI-enforced 100% gate (lines / branches / functions / statements) + 100% mutant kill on guards; the public report is the `coverage-report` artifact on every CI run.
|
|
12
|
+
[](https://www.npmjs.com/package/azcodr)
|
|
13
|
+
[](./LICENSE)
|
|
2
14
|
|
|
3
15
|
> **Production-oriented architecture governance and topology-scoped scaffolding for AI-assisted development (early release).**
|
|
4
16
|
> *AI agents move fast. Architecture drifts. Azcodr turns architectural intent into executable constraints your agent cannot skip.*
|
|
@@ -24,6 +36,67 @@
|
|
|
24
36
|
|
|
25
37
|
---
|
|
26
38
|
|
|
39
|
+
## ⚡ 60-Second Demo: See Drift Prevention in Action
|
|
40
|
+
|
|
41
|
+
Azcodr turns architectural philosophy into machine-checked constraints your agent cannot skip.
|
|
42
|
+
|
|
43
|
+
### 1. Standalone Architectural Check
|
|
44
|
+
Run the validator on any repository without scaffolding:
|
|
45
|
+
```bash
|
|
46
|
+
npx azcodr check
|
|
47
|
+
```
|
|
48
|
+
```text
|
|
49
|
+
🔍 Validating Architecture & Agent Invariants in: ./
|
|
50
|
+
--------------------------------------------------------------
|
|
51
|
+
1. Root Config & Symlinks -> PASS
|
|
52
|
+
2. Progressive Disclosure Rules -> PASS (28 rules verified)
|
|
53
|
+
3. Specialized Skills (.agents) -> PASS (6 skills active)
|
|
54
|
+
4. Markdown Cross-References -> PASS (0 broken links)
|
|
55
|
+
5. Memory & ADR Ledger -> PASS (16 ADRs verified)
|
|
56
|
+
6. ADR Index Consistency -> PASS
|
|
57
|
+
🎉 SUCCESS: All architectural invariants are healthy! (0 warnings)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 2. Real-Time PreToolUse Guard: Refactor-Before-Add
|
|
61
|
+
When an AI coding agent attempts to dump new logic into a file already exceeding 300 lines, Azcodr's agent hook intercepts the tool call at runtime before it touches the disk:
|
|
62
|
+
```text
|
|
63
|
+
🚨 TOOL USE BLOCKED: Refactor-Before-Add Violation
|
|
64
|
+
File 'src/auth.ts' has 315 lines (limit: 300).
|
|
65
|
+
Mutations that add code are blocked.
|
|
66
|
+
Extract strategy classes or helper modules to reduce file size before adding new features.
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 3. Zero-Dependency Boundary & Cycle Enforcement
|
|
70
|
+
Inspect dependency cycles and layer boundaries on demand without third-party linters:
|
|
71
|
+
```bash
|
|
72
|
+
npx azcodr boundaries [directory]
|
|
73
|
+
```
|
|
74
|
+
```text
|
|
75
|
+
🔍 Inspecting Architectural Boundaries in: ./src
|
|
76
|
+
--------------------------------------------------------------
|
|
77
|
+
🚨 ARCHITECTURAL VIOLATIONS DETECTED (2):
|
|
78
|
+
- Circular Dependency: src/billing.ts -> src/tenant.ts -> src/billing.ts
|
|
79
|
+
- Layer Boundary Breach: src/domain/payment.ts illegally imports src/infrastructure/db.ts (domain -> infrastructure)
|
|
80
|
+
Action Required: Invert dependencies via Ports or extract shared modules.
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 4. Empirical Benchmark Proof (3 Arms, 10 Sequential Tickets)
|
|
84
|
+
In an automated empirical trial across 10 sequential tickets with 3 architectural traps ([`benchmark/RESULTS.md`](https://github.com/prosubodh/azcodr/blob/main/benchmark/RESULTS.md)):
|
|
85
|
+
|
|
86
|
+
| Metric | Arm A (Control) | Arm B (Hooks Only) | Arm C (Full Azcodr) |
|
|
87
|
+
|---|:---:|:---:|:---:|
|
|
88
|
+
| **Files >300 Lines** | 1 (365 lines in `auth.ts`) | **0** (Modularized) | **0** (Modularized) |
|
|
89
|
+
| **Circular Dependency Cycles** | 1 (`billing <-> tenant`) | 1 (`billing <-> tenant`) | **0** (Decoupled Port) |
|
|
90
|
+
| **Layer Boundary Breaches** | 1 (`domain -> infra`) | 1 (`domain -> infra`) | **0** (Hexagonal Port) |
|
|
91
|
+
| **Overall Drift Reduction** | ❌ FAILED | ❌ FAILED | ✅ **100% DRIFT-FREE** |
|
|
92
|
+
|
|
93
|
+
Run the empirical benchmark yourself:
|
|
94
|
+
```bash
|
|
95
|
+
node benchmark/run-benchmark.js
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
27
100
|
## 🗂️ Workspace Architecture
|
|
28
101
|
|
|
29
102
|
```
|
|
@@ -58,7 +131,7 @@ The architecture enforces 28 cohesive, single-responsibility domain rules. Read
|
|
|
58
131
|
|
|
59
132
|
| Domain | Rule Reference File | Key Focus & Invariants |
|
|
60
133
|
|---|---|---|
|
|
61
|
-
| **TDD & Isolation** | [`test_driven_development.md`](./docs/rules/test_driven_development.md) | Outside-In TDD, Uncle Bob's 3 Laws, 100% coverage, test isolation & DB rollback. |
|
|
134
|
+
| **TDD & Isolation** | [`test_driven_development.md`](./docs/rules/test_driven_development.md) | Outside-In TDD, Uncle Bob's 3 Laws, 100% coverage on all metrics + mutation gate, test isolation & DB rollback. |
|
|
62
135
|
| **Clean Code** | [`clean_code.md`](./docs/rules/clean_code.md) | Naming, small functions, CQS, SLAP, DRY, DbC, zero side-effects. |
|
|
63
136
|
| **Design Patterns** | [`design_patterns.md`](./docs/rules/design_patterns.md) | Adapter, Factory, Strategy, Result `<T, E>`, and GoF pattern catalog. |
|
|
64
137
|
| **Type Safety** | [`type_safety.md`](./docs/rules/type_safety.md) | Compiler strictness, branded nominal types, type discriminators across polyglot languages. |
|
|
@@ -102,10 +175,10 @@ The architecture enforces 28 cohesive, single-responsibility domain rules. Read
|
|
|
102
175
|
|
|
103
176
|
## 🚀 Starting a New Project with `/lets-build`
|
|
104
177
|
|
|
105
|
-
This repository serves as an **
|
|
178
|
+
This repository serves as an **architecture governance toolkit, with an optional starter**. When beginning a new software project:
|
|
106
179
|
|
|
107
180
|
### Step 1: Initialize Workspace with npx
|
|
108
|
-
Pull and scaffold the complete
|
|
181
|
+
Pull and scaffold the complete architecture governance toolkit into your project directory using `npx`:
|
|
109
182
|
```bash
|
|
110
183
|
npx azcodr my-new-project
|
|
111
184
|
cd my-new-project
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Generated-Project Enforcement Analysis: What a Scaffolded Project Actually Gets
|
|
2
|
+
|
|
3
|
+
> **Status:** evidence, not prose. Every claim below was produced by running the
|
|
4
|
+
> scaffolder on 2026-10-08, not by reading the skills docs.
|
|
5
|
+
> **Answers the plan's open question:** which linters does a non-TypeScript
|
|
6
|
+
> project actually get — and whether the "executable architecture" promise holds
|
|
7
|
+
> outside azcodr's own repo.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Method
|
|
12
|
+
|
|
13
|
+
1. Ran `scaffold({ force: true, noGit: true })` from compiled `lib/` into a clean
|
|
14
|
+
temp dir; inventoried every emitted file.
|
|
15
|
+
2. Ran `bootstrap_workspace.sh . <topology> <language>` under Git Bash for
|
|
16
|
+
`backend+typescript`, `backend+python`, `cli+go`, `extension+typescript`,
|
|
17
|
+
`systems-library+c`; diffed the file lists.
|
|
18
|
+
3. Executed the scaffolded project's `.agents/scripts/agent_guard.js` with a
|
|
19
|
+
must-block payload (`rm -rf /`), with the azcodr repo itself as control.
|
|
20
|
+
|
|
21
|
+
## Finding 1: No deterministic linter in any generated project
|
|
22
|
+
|
|
23
|
+
The scaffolded project contains exactly one toolchain-adjacent file:
|
|
24
|
+
`.editorconfig`. Its `package.json` lint script is:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
"lint": "echo \"No linter configured yet. Run /lets-build to configure toolchain.\""
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The polyglot fitness-function table (`docs/rules/clean_code.md`, § Polyglot
|
|
31
|
+
Fitness Function Standards: ESLint / ruff / clippy / golangci-lint /
|
|
32
|
+
Checkstyle / Roslyn) ships as **documentation only**. Phase 4 step 3 of
|
|
33
|
+
`lets-build/SKILL.md` instructs the *agent* to "generate … deterministic
|
|
34
|
+
linter configurations" — i.e. enforcement in a user's project is agent-authored
|
|
35
|
+
and non-deterministic, exactly the gap the plan flagged. **A non-TypeScript
|
|
36
|
+
project gets no linter at all unless the agent writes one.**
|
|
37
|
+
|
|
38
|
+
## Finding 2: LANGUAGE does not change generated output
|
|
39
|
+
|
|
40
|
+
`backend+typescript` and `backend+python` produce byte-identical file lists
|
|
41
|
+
(18 files each: `.gitkeep` dirs, `tokens.json`, `smoke_test.sh`,
|
|
42
|
+
`workspace-profile.env`). `LANGUAGE` is validated and recorded but never
|
|
43
|
+
branches generation. Topology *does* scope directories (7–18 files by
|
|
44
|
+
topology). So: topology-scoping is deterministic; language support is a
|
|
45
|
+
recorded intention, not a generated artifact.
|
|
46
|
+
|
|
47
|
+
## Finding 3: The shipped runtime guard is inert in generated projects (fail-open)
|
|
48
|
+
|
|
49
|
+
`TEMPLATE_ITEMS` (`src/scaffold.ts`) ships `docs`, `.agents`, `scripts`,
|
|
50
|
+
`.github` — but **not** `src/`, `lib/`, or `bin/`. Consequences, all verified:
|
|
51
|
+
|
|
52
|
+
| Check | azcodr repo (control) | Scaffolded project |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| `.agents/scripts/agent_guard.js` vs `rm -rf /` payload | **BLOCKED** (exit 1) | **ALLOWED** (exit 0) |
|
|
55
|
+
| `lib/agent-guard.js` present | yes | **missing** — the guard's dynamic import rejects, and `main().catch(() => process.exit(0))` fails open |
|
|
56
|
+
| `.agents/hooks.json` references `agent_guard.js` | no | no |
|
|
57
|
+
| All hook blocks in `hooks.json` | `enabled: false` | `enabled: false` (shipped copy) |
|
|
58
|
+
|
|
59
|
+
The flagship "agent cannot skip" control therefore degrades, in a generated
|
|
60
|
+
project, to: an unwired hook script, with its engine missing, configured off,
|
|
61
|
+
that permits on error. The `boundaries` engine (`npx azcodr boundaries`)
|
|
62
|
+
likewise does not ship — only `scripts/validate-cli.js` (config/ledger/link
|
|
63
|
+
checks) is present.
|
|
64
|
+
|
|
65
|
+
## What *does* transfer deterministically
|
|
66
|
+
|
|
67
|
+
- 28 rule docs, 6 skills, `AGENTS.md` parity pointers, empty ADR ledger
|
|
68
|
+
(`data/memory.template`), `safety_guard.sh` + `verify_completion.sh` (present
|
|
69
|
+
but disabled in `hooks.json`), `smoke_test.sh` placeholder, topology-scoped
|
|
70
|
+
directories, `tokens.json` (backend/web only), `.azcodr/workspace-profile.env`.
|
|
71
|
+
|
|
72
|
+
## Recommendations (product decisions, not taken here)
|
|
73
|
+
|
|
74
|
+
1. **Either ship the engine or stop implying it ships.** Options: (a) add a
|
|
75
|
+
dependency on the published `azcodr` package + `lib/`- backed guard entry in
|
|
76
|
+
the starter `package.json`; (b) vendor a self-contained guard bundle into
|
|
77
|
+
`.agents/scripts/` with no `../../lib` import; (c) reword SKILL.md Phase 4
|
|
78
|
+
step 3 from "generate deterministic linter configurations" to an explicit
|
|
79
|
+
agent-authored checklist with verification (`npm run lint` must fail before
|
|
80
|
+
configs land, not echo).
|
|
81
|
+
2. **Fail closed, and wire the hook.** `agent_guard.js`'s catch-all `exit(0)`
|
|
82
|
+
is the wrong default for a security boundary; and `hooks.json` should ship
|
|
83
|
+
with at least the safety guard enabled plus a setup step that proves the
|
|
84
|
+
harness honors it (harnesses ignore unknown/unenabled hooks silently).
|
|
85
|
+
3. **Make LANGUAGE generative or say it isn't.** Either branch
|
|
86
|
+
`bootstrap_workspace.sh` per language (build manifests + pinned linter
|
|
87
|
+
configs per `clean_code.md` table) or change the skill wording to record the
|
|
88
|
+
language decision for the agent to implement in Phase 4.
|
|
89
|
+
4. **Close the benchmark gap this reveals.** `benchmark/RESULTS.md` Arm B/C
|
|
90
|
+
assume working hooks + boundary engine; in a real scaffolded project neither
|
|
91
|
+
is present. A fourth arm — *raw scaffolded project, no agent-authored
|
|
92
|
+
additions* — would measure the actual out-of-box enforcement: expect 0/3
|
|
93
|
+
traps caught.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Addendum (2026-10-08): findings fixed — verify, don't trust
|
|
98
|
+
|
|
99
|
+
The three findings above are closed by the enforcement change set; each fix
|
|
100
|
+
names the test that locks it:
|
|
101
|
+
|
|
102
|
+
1. **No deterministic linter → per-language gate configs emitted.**
|
|
103
|
+
`bootstrap_workspace.sh` now writes the pinned config for the recorded
|
|
104
|
+
language (`eslint.config.js`, `ruff.toml`, `clippy.toml`, `.golangci.yml`,
|
|
105
|
+
`checkstyle.xml`, `.editorconfig` CA block, `.clang-tidy`; `generic` emits
|
|
106
|
+
none). Locked by `tests/bootstrap-toolchain.test.ts` (9 tests); presence is
|
|
107
|
+
re-checked on every `validate` run by the new phase 7
|
|
108
|
+
(`scripts/validate/toolchain.js`, 100% covered).
|
|
109
|
+
2. **LANGUAGE decorative → generative for toolchain.**
|
|
110
|
+
`backend+typescript` and `backend+python` still share directory trees
|
|
111
|
+
(topology-scoping, by design) but now differ in emitted gate configs; the
|
|
112
|
+
profile feed (`readProfileLanguage`) drives the validator. The agent still
|
|
113
|
+
owns build manifests (naming decisions) plus tool install and the Phase 5
|
|
114
|
+
live-block proof (`lets-build/SKILL.md`).
|
|
115
|
+
3. **Fail-open guard → vendored engine + fail-closed install.**
|
|
116
|
+
The guard engine ships inside `.agents/` (`.agents/lib/`, byte-locked to
|
|
117
|
+
`lib/` output by test), `agent_guard.js` resolves vendored-first, and a
|
|
118
|
+
missing engine exits 2 naming every path tried. Unparseable *payloads*
|
|
119
|
+
still fail open inside `inspectPreTool` per ADR-005 (ambiguous input, not a
|
|
120
|
+
broken install). `hooks.json` (+`.example`) wires an `architectural-guard`
|
|
121
|
+
PreToolUse entry. Locked by the three new `tests/agent-guard.test.ts` cases.
|
|
122
|
+
4. **Benchmark assumes working hooks → Arm D measures the scaffold.**
|
|
123
|
+
`runArmD()` + `auditScaffoldEnforcement()` score a real scaffold before and
|
|
124
|
+
after bootstrap; `benchmark/RESULTS.md` §5 carries the scorecard.
|
|
125
|
+
5. **Echo lint placeholder → rewired for Node profiles.** `bootstrap` points
|
|
126
|
+
the starter `lint` script at the emitted `eslint.config.js` (placeholder
|
|
127
|
+
only, never agent-wired entries; skipped when node is unavailable), so
|
|
128
|
+
`npm run lint` fails until the pinned tool lands instead of echoing
|
|
129
|
+
success.
|
|
130
|
+
|
|
131
|
+
## Reproduce
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# 1. Scaffold inventory
|
|
135
|
+
node -e "const {scaffold}=require('./lib/scaffold.js'); scaffold({targetDir:'<tmp>',force:true,noGit:true})"
|
|
136
|
+
# 2. Topology x language matrix (Git Bash)
|
|
137
|
+
bash .agents/skills/lets-build/scripts/bootstrap_workspace.sh <tmp> backend python
|
|
138
|
+
# 3. Guard fail-open proof
|
|
139
|
+
echo '{"tool_name":"run_command","tool_input":{"command":"rm -rf /"}}' \
|
|
140
|
+
| node <scaffold>/.agents/scripts/agent_guard.js; echo "exit=$?"
|
|
141
|
+
```
|
package/docs/rules/clean_code.md
CHANGED
|
@@ -57,13 +57,13 @@ Before writing production code for any new feature or user story, the agent must
|
|
|
57
57
|
Prevent AI-generated code rot using automated fitness functions integrated into linting and continuous verification:
|
|
58
58
|
- **File Length Gates**: Maximum 250–300 lines per file (ESLint `max-lines`).
|
|
59
59
|
- **Function Length Gates**: Maximum 20–30 lines per function (ESLint `max-lines-per-function`).
|
|
60
|
-
- **Dependency Direction Gates**: Enforce unidirectional import rules (
|
|
60
|
+
- **Dependency Direction & Boundary Gates**: Enforce unidirectional import rules and cycle prevention natively with Azcodr's zero-dependency boundary linter (`npx azcodr boundaries [dir]`) or polyglot equivalents (ArchUnit, dependency-cruiser) ensuring domain core never imports infrastructure or transport adapters, and circular dependencies are forbidden.
|
|
61
61
|
- **Complexity Budgets**: Enforce cyclomatic complexity limits (maximum 10 per function).
|
|
62
62
|
If an AI attempt to add code violates any fitness function, the build fails immediately, blocking completion until the architecture is refactored.
|
|
63
63
|
|
|
64
64
|
### Polyglot Fitness Function Standards
|
|
65
65
|
|
|
66
|
-
When bootstrapping
|
|
66
|
+
When bootstrapping projects via `/lets-build`, `bootstrap_workspace.sh` emits the pinned gate configuration for the recorded language (never invented, never absent); the agent then installs the named tool, wires the project's lint entry to it, and proves the gate in Phase 5. Gates must match these exact rules:
|
|
67
67
|
|
|
68
68
|
| Language | Linter / Static Tool | Max File Lines (300) | Max Function Lines (30) | Max Complexity (10) | Max Arguments (3) |
|
|
69
69
|
|---|---|---|---|---|---|
|
|
@@ -73,3 +73,4 @@ When bootstrapping non-TypeScript projects via `/lets-build`, the agent must ins
|
|
|
73
73
|
| **Go** | `golangci-lint` | `maintidx: 300` | `funlen: lines = 30` | `gocyclo: min-complexity = 10` | `funlen: statements = 25` |
|
|
74
74
|
| **Java** | `Checkstyle` + `ArchUnit` | `FileLength: max 300` | `MethodLength: max 30` | `CyclomaticComplexity: max 10` | `ParameterNumber: max 3` |
|
|
75
75
|
| **C# / .NET** | `.editorconfig` + Roslyn | `file_length = 300:error` | `method_length = 30:error` | `CA1502: Avoid excessive complexity <= 10` | `CA1501: max 3 params` |
|
|
76
|
+
| **C / C++** | `clang-tidy` | project lint entry (no native check) | `readability-function-size LineThreshold = 30` | `readability-function-cognitive-complexity Threshold = 10` | `readability-function-size ParameterThreshold = 3` |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Test-Driven Development (London School TDD) & Test Isolation Standards
|
|
2
2
|
|
|
3
|
-
> **Core Mandate:** Drive all features through the non-negotiable 5-Phase Agile Domain Lifecycle (Outside-In Double-Loop TDD, Uncle Bob's 3 Laws), enforcing transactional database rollback per test, zero-sleep determinism, and
|
|
3
|
+
> **Core Mandate:** Drive all features through the non-negotiable 5-Phase Agile Domain Lifecycle (Outside-In Double-Loop TDD, Uncle Bob's 3 Laws), enforcing transactional database rollback per test, zero-sleep determinism, and CI-enforced 100% coverage on all metrics plus mutation floor (assertion-free tests rejected).
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -14,7 +14,7 @@ flowchart TD
|
|
|
14
14
|
P2["Phase 2: Tactical Domain Analysis<br/>• Ubiquitous Language & Bounded Contexts<br/>• Aggregate Roots & Business Invariants"]
|
|
15
15
|
P3["Phase 3: Outer Acceptance Test (RED)<br/>• Failing UI component or API route test<br/>• Verifies failure for expected reason"]
|
|
16
16
|
P4["Phase 4: Inner TDD & Collaborator Discovery (RED-GREEN-REFACTOR)<br/>• Discovers Use Cases & Ports<br/>• Nano-cycles with Uncle Bob's 3 Laws"]
|
|
17
|
-
P5["Phase 5: Outer Verification & Proof (GREEN)<br/>• Outer test passes with zero regressions<br/>• 100
|
|
17
|
+
P5["Phase 5: Outer Verification & Proof (GREEN)<br/>• Outer test passes with zero regressions<br/>• 100% coverage on all metrics + mutation gate & boundary smoke verification"]
|
|
18
18
|
|
|
19
19
|
P1 --> P2 --> P3 --> P4 --> P5
|
|
20
20
|
```
|
|
@@ -125,10 +125,13 @@ sequenceDiagram
|
|
|
125
125
|
|
|
126
126
|
---
|
|
127
127
|
|
|
128
|
-
## 7. Mandatory 100
|
|
128
|
+
## 7. Mandatory 100% Coverage on All Metrics + Mutation Floor (No Assertion-Free Tests)
|
|
129
129
|
|
|
130
|
-
- **Strict
|
|
131
|
-
- **
|
|
130
|
+
- **Strict 100% thresholds:** CI fails unless line, function, branch, AND statement coverage are all 100% (`jest.config.js`: lines 100 / functions 100 / branches 100 / statements 100). Generated projects must hold the same 100% bar in their own stack via the per-language gates in `docs/rules/clean_code.md`. Lowering any metric requires an ADR.
|
|
131
|
+
- **Mutation floor on guards:** line coverage alone proves little. Behavioral guards (`agent-guard-*`, `boundaries.ts`, protected-target checks) must hold a 100% mutant-kill gate (`npm run test:mutation`, `benchmark/mutation-test.js`). A green suite that lets a `blocked: true → false` or `return cycles → return []` mutant survive is a failure, even at 100% lines.
|
|
132
|
+
- **Assertion-density check:** agents asked to hit a line number write assertion-free tests to cover lines. Reject that explicitly: every new behavioral test must contain at least one behavior-asserting expectation (no `expect(true).toBe(true)`, no tests without assertions). Prefer `benchmark/evaluate.js --strict-tests` style checks (assertions per test ≥ 1, critical paths ≥ 2) over raising the line percentage.
|
|
133
|
+
- **What this repo enforces vs what users get:** this repo's exact thresholds live in `jest.config.js` (100% lines, branches, functions, statements) and are locked by `tests/coverage-config.test.ts`. Generated polyglot projects get the equivalent per-language fitness gates in `docs/rules/clean_code.md` (ESLint / ruff / clippy / golangci-lint / Checkstyle / Roslyn) at the same 100% bar — the tooling differs by stack, the bar must not.
|
|
134
|
+
- **Exhaustive status codes & error branches:** explicitly test all HTTP/gRPC response codes:
|
|
132
135
|
- Success: `200 OK`, `201 Created`, `204 No Content`
|
|
133
136
|
- Client Errors: `400 Bad Request`, `401 Unauthorized`, `403 Forbidden`, `404 Not Found`, `409 Conflict`, `422 Unprocessable Entity`, `429 Too Many Requests`
|
|
134
137
|
- Server Failures: `500 Internal Server Error`, `503 Service Unavailable`
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { BoundaryReport } from './boundaries.js';
|
|
2
|
+
import type { CliParsedOptions } from './cli-parse.js';
|
|
3
|
+
export interface BoundaryIo {
|
|
4
|
+
out: (msg: string) => void;
|
|
5
|
+
err: (msg: string) => void;
|
|
6
|
+
exit: (code: number) => void | number;
|
|
7
|
+
cwd: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function resolveBoundaryTarget(targetDir: string | null, cwd: string): string;
|
|
10
|
+
export declare function formatBoundaryReport(targetDir: string, report: BoundaryReport, out: (msg: string) => void): void;
|
|
11
|
+
export declare function handleBoundariesCommand(parsed: CliParsedOptions, io: BoundaryIo): Promise<void | number>;
|
|
12
|
+
declare const _default: {
|
|
13
|
+
resolveBoundaryTarget: typeof resolveBoundaryTarget;
|
|
14
|
+
formatBoundaryReport: typeof formatBoundaryReport;
|
|
15
|
+
handleBoundariesCommand: typeof handleBoundariesCommand;
|
|
16
|
+
};
|
|
17
|
+
export default _default;
|
|
18
|
+
//# sourceMappingURL=cli-boundaries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-boundaries.d.ts","sourceRoot":"","sources":["../src/cli-boundaries.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3B,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3B,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,CAAC;IACtC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAMnF;AAcD,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GACzB,IAAI,CASN;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,gBAAgB,EACxB,EAAE,EAAE,UAAU,GACb,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CASxB;;;;;;AAED,wBAIE"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import { inspectBoundaries } from './boundaries.js';
|
|
4
|
+
export function resolveBoundaryTarget(targetDir, cwd) {
|
|
5
|
+
if (targetDir) {
|
|
6
|
+
return path.resolve(cwd, targetDir);
|
|
7
|
+
}
|
|
8
|
+
const defaultSrc = path.join(cwd, 'src');
|
|
9
|
+
return fs.existsSync(defaultSrc) ? defaultSrc : cwd;
|
|
10
|
+
}
|
|
11
|
+
function printViolations(report, out) {
|
|
12
|
+
const total = report.cycles.length + report.violations.length;
|
|
13
|
+
out(`🚨 ARCHITECTURAL VIOLATIONS DETECTED (${total}):`);
|
|
14
|
+
for (const cycle of report.cycles) {
|
|
15
|
+
out(` - Circular Dependency: ${cycle.join(' -> ')}`);
|
|
16
|
+
}
|
|
17
|
+
for (const v of report.violations) {
|
|
18
|
+
out(` - Layer Boundary Breach: ${v.file} illegally imports ${v.importedFile} (${v.fromLayer} -> ${v.toLayer})`);
|
|
19
|
+
}
|
|
20
|
+
out(' Action Required: Invert dependencies via Ports or extract shared modules.\n');
|
|
21
|
+
}
|
|
22
|
+
export function formatBoundaryReport(targetDir, report, out) {
|
|
23
|
+
out(`\n🔍 Inspecting Architectural Boundaries in: ${targetDir}`);
|
|
24
|
+
out('--------------------------------------------------------------');
|
|
25
|
+
if (report.ok) {
|
|
26
|
+
out(`✅ Analyzed ${report.moduleCount} modules: 0 circular cycles, 0 boundary violations.`);
|
|
27
|
+
out('🎉 SUCCESS: Architecture is clean and drift-free! (0 violations)\n');
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
printViolations(report, out);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export async function handleBoundariesCommand(parsed, io) {
|
|
34
|
+
const targetDir = resolveBoundaryTarget(parsed.targetDir, io.cwd);
|
|
35
|
+
const report = inspectBoundaries(targetDir);
|
|
36
|
+
if (!parsed.silent) {
|
|
37
|
+
formatBoundaryReport(targetDir, report, io.out);
|
|
38
|
+
}
|
|
39
|
+
return io.exit(report.ok ? 0 : 1);
|
|
40
|
+
}
|
|
41
|
+
export default {
|
|
42
|
+
resolveBoundaryTarget,
|
|
43
|
+
formatBoundaryReport,
|
|
44
|
+
handleBoundariesCommand
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=cli-boundaries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-boundaries.js","sourceRoot":"","sources":["../src/cli-boundaries.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAWpD,MAAM,UAAU,qBAAqB,CAAC,SAAwB,EAAE,GAAW;IACzE,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACtC,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACzC,OAAO,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;AACtD,CAAC;AAED,SAAS,eAAe,CAAC,MAAsB,EAAE,GAA0B;IACzE,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;IAC9D,GAAG,CAAC,yCAAyC,KAAK,IAAI,CAAC,CAAC;IACxD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,GAAG,CAAC,6BAA6B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAClC,GAAG,CAAC,+BAA+B,CAAC,CAAC,IAAI,sBAAsB,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,SAAS,OAAO,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC;IACpH,CAAC;IACD,GAAG,CAAC,gFAAgF,CAAC,CAAC;AACxF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,SAAiB,EACjB,MAAsB,EACtB,GAA0B;IAE1B,GAAG,CAAC,gDAAgD,SAAS,EAAE,CAAC,CAAC;IACjE,GAAG,CAAC,gEAAgE,CAAC,CAAC;IACtE,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;QACd,GAAG,CAAC,cAAc,MAAM,CAAC,WAAW,qDAAqD,CAAC,CAAC;QAC3F,GAAG,CAAC,oEAAoE,CAAC,CAAC;IAC5E,CAAC;SAAM,CAAC;QACN,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,MAAwB,EACxB,EAAc;IAEd,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAE5C,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,eAAe;IACb,qBAAqB;IACrB,oBAAoB;IACpB,uBAAuB;CACxB,CAAC"}
|
package/lib/cli-parse.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Table-driven: every boolean flag is one Map entry, so adding a flag cannot
|
|
5
5
|
* raise the complexity of the parser itself.
|
|
6
6
|
*/
|
|
7
|
-
export type CliCommand = 'scaffold' | 'check';
|
|
7
|
+
export type CliCommand = 'scaffold' | 'check' | 'boundaries';
|
|
8
8
|
export interface CliParsedOptions {
|
|
9
9
|
command: CliCommand;
|
|
10
10
|
targetDir: string | null;
|
|
@@ -18,6 +18,7 @@ export interface CliParsedOptions {
|
|
|
18
18
|
export type BooleanFlagKey = 'force' | 'noGit' | 'dryRun' | 'silent';
|
|
19
19
|
export declare function emptyOptions(): Omit<CliParsedOptions, 'terminal' | 'message'>;
|
|
20
20
|
export declare const CHECK_COMMANDS: Set<string>;
|
|
21
|
+
export declare const BOUNDARY_COMMANDS: Set<string>;
|
|
21
22
|
export declare const BOOLEAN_FLAGS: Map<string, BooleanFlagKey>;
|
|
22
23
|
export interface ArgOutcome {
|
|
23
24
|
terminal: 'help' | 'version' | 'unknown-flag' | 'extra-arg' | null;
|
package/lib/cli-parse.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-parse.d.ts","sourceRoot":"","sources":["../src/cli-parse.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"cli-parse.d.ts","sourceRoot":"","sources":["../src/cli-parse.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,OAAO,GAAG,YAAY,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,UAAU,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,GAAG,WAAW,GAAG,IAAI,CAAC;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAErE,wBAAgB,YAAY,IAAI,IAAI,CAAC,gBAAgB,EAAE,UAAU,GAAG,SAAS,CAAC,CAS7E;AAED,eAAO,MAAM,cAAc,aAA0C,CAAC;AACtE,eAAO,MAAM,iBAAiB,aAAgD,CAAC;AAE/E,eAAO,MAAM,aAAa,6BAQxB,CAAC;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,GAAG,WAAW,GAAG,IAAI,CAAC;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAwBD,wBAAgB,QAAQ,CACtB,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,GAAG,SAAS,CAAC,EACrD,GAAG,EAAE,MAAM,GACV,UAAU,CAuBZ;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,CAStE;;;;;;;;AAED,wBAAoF"}
|