create-sdd-project 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -107
- package/lib/config.js +1 -1
- package/lib/init-generator.js +24 -2
- package/lib/init-wizard.js +1 -0
- package/lib/scanner.js +16 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,18 +1,67 @@
|
|
|
1
1
|
# SDD DevFlow
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/create-sdd-project)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](package.json)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
**Spec-Driven Development workflow for AI-assisted coding.**
|
|
8
|
+
|
|
9
|
+
A complete development methodology for Claude Code and Gemini that combines specialized AI agents, workflow orchestration with human checkpoints, and institutional memory. Works with new and existing TypeScript/JavaScript projects.
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### New Project
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx create-sdd-project my-app
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The interactive wizard asks about your stack, AI tools, and autonomy level. For defaults (fullstack Express+Next.js):
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx create-sdd-project my-app --yes
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Existing Project
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cd your-existing-project
|
|
29
|
+
npx create-sdd-project --init
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Scans your project, detects your stack and architecture, and installs SDD files adapted to your project. Never modifies existing code or overwrites existing files.
|
|
33
|
+
|
|
34
|
+
### After Setup
|
|
35
|
+
|
|
36
|
+
Open in your AI coding tool and run:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
init sprint 0
|
|
40
|
+
start task B0.1
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The workflow skill guides you through each step with checkpoints based on your autonomy level.
|
|
44
|
+
|
|
45
|
+
---
|
|
6
46
|
|
|
7
47
|
## What is SDD?
|
|
8
48
|
|
|
9
49
|
SDD DevFlow combines three proven practices:
|
|
10
50
|
|
|
11
51
|
1. **Spec-Driven Development** — Write specifications before code. Specs are the contract between planning and implementation.
|
|
12
|
-
2. **Test-Driven Development** — Red-Green-Refactor cycle for every feature.
|
|
13
|
-
3. **Human-in-the-Loop** — Strategic checkpoints
|
|
52
|
+
2. **Test-Driven Development** — Red-Green-Refactor cycle for every feature.
|
|
53
|
+
3. **Human-in-the-Loop** — Strategic checkpoints with configurable autonomy levels that reduce human intervention as trust increases.
|
|
54
|
+
|
|
55
|
+
### Why use SDD DevFlow?
|
|
56
|
+
|
|
57
|
+
- **AI agents work better with structure.** Without guardrails, AI coding assistants produce inconsistent results. SDD provides the methodology, standards, and workflow that make AI output predictable and high-quality.
|
|
58
|
+
- **Institutional memory across sessions.** Sprint trackers, bug logs, and decision records survive context compaction and session boundaries.
|
|
59
|
+
- **Scales from solo to team.** Start at L1 (full control) while learning, scale to L4 (full auto) for repetitive tasks.
|
|
60
|
+
- **Works with your stack.** Not opinionated about frameworks — detects and adapts to Express, Fastify, NestJS, Next.js, Nuxt, Vue, Angular, and many more.
|
|
61
|
+
|
|
62
|
+
---
|
|
14
63
|
|
|
15
|
-
## What's
|
|
64
|
+
## What's Included
|
|
16
65
|
|
|
17
66
|
### 9 Specialized Agents
|
|
18
67
|
|
|
@@ -26,35 +75,33 @@ SDD DevFlow combines three proven practices:
|
|
|
26
75
|
| `qa-engineer` | Edge cases, spec verification | 5 |
|
|
27
76
|
| `database-architect` | Schema design, optimization | Any |
|
|
28
77
|
|
|
78
|
+
### 3 Skills (Slash Commands)
|
|
79
|
+
|
|
80
|
+
| Skill | Trigger | What it does |
|
|
81
|
+
|-------|---------|-------------|
|
|
82
|
+
| `development-workflow` | `start task B0.1`, `next task`, `init sprint N` | Orchestrates the complete 7-step workflow |
|
|
83
|
+
| `bug-workflow` | `report bug`, `fix bug`, `hotfix needed` | Bug triage, investigation, and resolution |
|
|
84
|
+
| `project-memory` | `set up project memory`, `log a bug fix` | Maintains institutional knowledge |
|
|
85
|
+
|
|
29
86
|
### Workflow (Steps 0–6)
|
|
30
87
|
|
|
31
88
|
```
|
|
32
|
-
0. SPEC → spec-creator drafts specs → Spec Approval
|
|
33
|
-
1. SETUP → Branch, ticket, sprint tracker → Ticket Approval
|
|
34
|
-
2. PLAN → Planner creates implementation plan → Plan Approval
|
|
89
|
+
0. SPEC → spec-creator drafts specs → Spec Approval
|
|
90
|
+
1. SETUP → Branch, ticket, sprint tracker → Ticket Approval
|
|
91
|
+
2. PLAN → Planner creates implementation plan → Plan Approval
|
|
35
92
|
3. IMPLEMENT → Developer agent, TDD
|
|
36
93
|
4. FINALIZE → Tests/lint/build, validator → Commit Approval
|
|
37
94
|
5. REVIEW → PR, code review, QA → Merge Approval
|
|
38
95
|
6. COMPLETE → Clean up, update tracker
|
|
39
96
|
```
|
|
40
97
|
|
|
41
|
-
**
|
|
42
|
-
- **Simple
|
|
43
|
-
- **Standard
|
|
44
|
-
- **Complex
|
|
45
|
-
|
|
46
|
-
### 3 Complexity Tiers
|
|
47
|
-
|
|
48
|
-
| Tier | Spec | Ticket | Plan | QA |
|
|
49
|
-
|------|:----:|:------:|:----:|:--:|
|
|
50
|
-
| Simple | Skip | Skip | Skip | Skip |
|
|
51
|
-
| Standard | Yes | Yes | Yes | Yes |
|
|
52
|
-
| Complex | Yes | Yes + ADR | Yes | Yes |
|
|
98
|
+
**By complexity:**
|
|
99
|
+
- **Simple** (bug fixes, small tweaks): 1 → 3 → 4 → 5 → 6
|
|
100
|
+
- **Standard** (features): 0 → 1 → 2 → 3 → 4 → 5 (+QA) → 6
|
|
101
|
+
- **Complex** (architectural changes): 0 → 1 (+ADR) → 2 → 3 → 4 → 5 (+QA) → 6
|
|
53
102
|
|
|
54
103
|
### 4 Autonomy Levels
|
|
55
104
|
|
|
56
|
-
Control how many human approval checkpoints are active:
|
|
57
|
-
|
|
58
105
|
| Level | Name | Human Checkpoints | Best For |
|
|
59
106
|
|-------|------|-------------------|----------|
|
|
60
107
|
| L1 | Full Control | All 5 | First sprint, learning SDD |
|
|
@@ -64,13 +111,6 @@ Control how many human approval checkpoints are active:
|
|
|
64
111
|
|
|
65
112
|
Quality gates (tests, lint, build, validators) **always run** regardless of level.
|
|
66
113
|
|
|
67
|
-
### Branching Strategy
|
|
68
|
-
|
|
69
|
-
Configurable per-project in `key_facts.md`:
|
|
70
|
-
|
|
71
|
-
- **GitHub Flow** (default): `main` + `feature/*` + `hotfix/*`. Best for MVPs.
|
|
72
|
-
- **GitFlow** (scaled): `main` + `develop` + `feature/*` + `release/*` + `hotfix/*`. For larger projects.
|
|
73
|
-
|
|
74
114
|
### Project Memory
|
|
75
115
|
|
|
76
116
|
Tracks institutional knowledge across sessions in `docs/project_notes/`:
|
|
@@ -82,70 +122,39 @@ Tracks institutional knowledge across sessions in `docs/project_notes/`:
|
|
|
82
122
|
|
|
83
123
|
### Automated Hooks (Claude Code)
|
|
84
124
|
|
|
85
|
-
- **Quick Scan** — After developer agents finish, a fast grep-based scan (~2s, no API calls) checks for debug code, secrets, and TODOs
|
|
86
|
-
- **Compaction Recovery** — After context compaction, injects a reminder to read the sprint tracker for context recovery
|
|
87
|
-
- **Notifications** — Personal notification hooks (macOS/Linux) in `.claude/settings.local.json`.
|
|
125
|
+
- **Quick Scan** — After developer agents finish, a fast grep-based scan (~2s, no API calls) checks for debug code, secrets, and TODOs
|
|
126
|
+
- **Compaction Recovery** — After context compaction, injects a reminder to read the sprint tracker for context recovery
|
|
88
127
|
|
|
89
128
|
### Multi-Tool Support
|
|
90
129
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
130
|
+
| Tool | Support Level |
|
|
131
|
+
|------|--------------|
|
|
132
|
+
| **Claude Code** | Full — agents, skills, hooks, settings (`.claude/`) |
|
|
133
|
+
| **Gemini** | Full — agents, skills, commands, settings (`.gemini/`) |
|
|
134
|
+
| **Other AI tools** | `AGENTS.md` provides universal instructions (Cursor, Copilot, Windsurf, etc.) |
|
|
94
135
|
|
|
95
|
-
|
|
136
|
+
---
|
|
96
137
|
|
|
97
|
-
|
|
138
|
+
## `--init` Stack Detection
|
|
98
139
|
|
|
99
|
-
|
|
100
|
-
npx create-sdd-project my-app
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
The interactive wizard guides you through:
|
|
140
|
+
When running `--init` on an existing project, the scanner automatically detects:
|
|
104
141
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
```bash
|
|
119
|
-
cd your-existing-project
|
|
120
|
-
npx create-sdd-project --init
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
The `--init` flag:
|
|
124
|
-
- **Scans** your project: detects stack (Express, Next.js, Prisma, etc.), architecture (MVC, DDD, feature-based), tests, and existing docs
|
|
125
|
-
- **Adapts** standards files to match your real architecture (not generic DDD defaults)
|
|
126
|
-
- **Imports** existing OpenAPI/Swagger specs and references Prisma schemas
|
|
127
|
-
- **Audits** test coverage and suggests retrofit testing tasks if coverage is low
|
|
128
|
-
- **Never** modifies your existing code or overwrites existing files
|
|
129
|
-
|
|
130
|
-
### After setup
|
|
131
|
-
|
|
132
|
-
```
|
|
133
|
-
# Open in your AI coding tool and run:
|
|
134
|
-
init sprint 0
|
|
135
|
-
start task B0.1
|
|
136
|
-
```
|
|
142
|
+
| Category | Detected |
|
|
143
|
+
|----------|----------|
|
|
144
|
+
| **Backend frameworks** | Express, Fastify, Koa, NestJS, Hapi, AdonisJS |
|
|
145
|
+
| **ORMs** | Prisma, Mongoose, TypeORM, Sequelize, Drizzle, Knex, MikroORM, Objection.js |
|
|
146
|
+
| **Databases** | PostgreSQL, MySQL, SQLite, MongoDB, SQL Server, CockroachDB (from Prisma schema, `.env`, or dependencies) |
|
|
147
|
+
| **Frontend frameworks** | Next.js, Nuxt, Remix, Astro, SolidJS, React, Vue, Angular, Svelte |
|
|
148
|
+
| **Styling** | Tailwind CSS, styled-components, Emotion, Sass |
|
|
149
|
+
| **Component libraries** | Radix UI, Headless UI, Material UI, Chakra UI, Ant Design |
|
|
150
|
+
| **State management** | Zustand, Redux, Jotai, TanStack Query, Recoil, Pinia, MobX |
|
|
151
|
+
| **Testing** | Jest, Vitest, Mocha (unit) + Playwright, Cypress (e2e) |
|
|
152
|
+
| **Architecture** | MVC, DDD, feature-based, handler-based, flat |
|
|
153
|
+
| **Project type** | Monorepo (workspaces, Lerna, Turbo, pnpm) or single-package |
|
|
137
154
|
|
|
138
|
-
|
|
155
|
+
Standards files are adapted to match your actual architecture — not generic defaults.
|
|
139
156
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
If you prefer manual configuration, copy the template directly:
|
|
143
|
-
|
|
144
|
-
```bash
|
|
145
|
-
cp -r template/ /path/to/your-project/
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
Then look for `<!-- CONFIG: ... -->` comments in the files to customize.
|
|
157
|
+
---
|
|
149
158
|
|
|
150
159
|
## Template Structure
|
|
151
160
|
|
|
@@ -155,7 +164,6 @@ project/
|
|
|
155
164
|
├── CLAUDE.md # Claude Code config (autonomy, recovery)
|
|
156
165
|
├── GEMINI.md # Gemini config (autonomy)
|
|
157
166
|
├── .env.example # Environment variables template
|
|
158
|
-
├── .gitignore # Git ignore with secrets protection
|
|
159
167
|
│
|
|
160
168
|
├── .claude/
|
|
161
169
|
│ ├── agents/ # 9 specialized agents
|
|
@@ -165,45 +173,37 @@ project/
|
|
|
165
173
|
│ │ ├── bug-workflow/ # Bug triage and resolution
|
|
166
174
|
│ │ └── project-memory/ # Memory system setup
|
|
167
175
|
│ ├── hooks/quick-scan.sh # Post-developer quality scan
|
|
168
|
-
│
|
|
169
|
-
│ └── settings.local.json # Personal hooks (gitignored)
|
|
176
|
+
│ └── settings.json # Shared hooks (git-tracked)
|
|
170
177
|
│
|
|
171
178
|
├── .gemini/
|
|
172
179
|
│ ├── agents/ # 9 agents (Gemini format)
|
|
173
|
-
│ ├── skills/
|
|
174
|
-
│ │ ├── development-workflow/ # Main task workflow (Steps 0-6)
|
|
175
|
-
│ │ │ └── references/ # Templates, guides, examples
|
|
176
|
-
│ │ ├── bug-workflow/ # Bug triage and resolution
|
|
177
|
-
│ │ └── project-memory/ # Memory system setup
|
|
180
|
+
│ ├── skills/ # Same 3 skills
|
|
178
181
|
│ ├── commands/ # Slash command shortcuts
|
|
179
|
-
│
|
|
180
|
-
│ └── styles/default.md # Response style
|
|
182
|
+
│ └── settings.json # Gemini configuration
|
|
181
183
|
│
|
|
182
184
|
├── ai-specs/specs/
|
|
183
185
|
│ ├── base-standards.mdc # Constitution + methodology
|
|
184
|
-
│ ├── backend-standards.mdc # Backend patterns
|
|
185
|
-
│ ├── frontend-standards.mdc # Frontend patterns
|
|
186
|
-
│ └── documentation-standards.mdc # Documentation
|
|
186
|
+
│ ├── backend-standards.mdc # Backend patterns
|
|
187
|
+
│ ├── frontend-standards.mdc # Frontend patterns
|
|
188
|
+
│ └── documentation-standards.mdc # Documentation rules
|
|
187
189
|
│
|
|
188
190
|
└── docs/
|
|
189
191
|
├── project_notes/ # Project memory
|
|
190
|
-
│ ├── sprint-0-tracker.md
|
|
191
|
-
│ ├── key_facts.md
|
|
192
|
-
│ ├── bugs.md
|
|
193
|
-
│ └── decisions.md
|
|
194
|
-
├── specs/
|
|
195
|
-
|
|
196
|
-
│ └── ui-components.md # Component spec (frontend)
|
|
197
|
-
└── tickets/ # Task tickets (generated by workflow)
|
|
192
|
+
│ ├── sprint-0-tracker.md
|
|
193
|
+
│ ├── key_facts.md
|
|
194
|
+
│ ├── bugs.md
|
|
195
|
+
│ └── decisions.md
|
|
196
|
+
├── specs/ # API and UI specs
|
|
197
|
+
└── tickets/ # Task tickets (workflow-generated)
|
|
198
198
|
```
|
|
199
199
|
|
|
200
200
|
## Default Tech Stack
|
|
201
201
|
|
|
202
|
-
|
|
202
|
+
Configurable via the wizard or `<!-- CONFIG -->` comments in template files:
|
|
203
203
|
|
|
204
204
|
- **Backend**: Node.js + Express + Prisma + PostgreSQL
|
|
205
205
|
- **Frontend**: Next.js (App Router) + Tailwind CSS + Radix UI + Zustand
|
|
206
|
-
- **Shared Types**: Zod schemas
|
|
206
|
+
- **Shared Types**: Zod schemas with `z.infer<>` for TypeScript types
|
|
207
207
|
- **Testing**: Jest (unit) + Playwright (e2e)
|
|
208
208
|
- **Methodology**: TDD + DDD + Spec-Driven Development
|
|
209
209
|
|
|
@@ -224,6 +224,16 @@ These 6 principles apply to ALL tasks, ALL agents, ALL complexity levels:
|
|
|
224
224
|
- Node.js 18+
|
|
225
225
|
- `jq` (for quick-scan hook): `brew install jq` (macOS) or `apt install jq` (Linux)
|
|
226
226
|
|
|
227
|
+
## Manual Setup (Alternative)
|
|
228
|
+
|
|
229
|
+
If you prefer manual configuration over the CLI wizard:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
cp -r template/ /path/to/your-project/
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Then look for `<!-- CONFIG: ... -->` comments in the files to customize.
|
|
236
|
+
|
|
227
237
|
## Roadmap
|
|
228
238
|
|
|
229
239
|
- **Agent Teams**: Parallel execution of independent tasks (waiting for Claude Code Agent Teams to stabilize)
|
package/lib/config.js
CHANGED
|
@@ -79,7 +79,7 @@ const AI_TOOLS = [
|
|
|
79
79
|
|
|
80
80
|
const AUTONOMY_LEVELS = [
|
|
81
81
|
{ level: 1, name: 'Full Control', desc: 'Human approves every checkpoint (first sprint, learning SDD)' },
|
|
82
|
-
{ level: 2, name: 'Trusted', desc: 'Human reviews plans + merges only (
|
|
82
|
+
{ level: 2, name: 'Trusted', desc: 'Human reviews plans + merges only (normal development)', default: true },
|
|
83
83
|
{ level: 3, name: 'Autopilot', desc: 'Human only approves merges (well-defined, repetitive tasks)' },
|
|
84
84
|
{ level: 4, name: 'Full Auto', desc: 'No human checkpoints, CI/CD gates only (bulk simple tasks)' },
|
|
85
85
|
];
|
package/lib/init-generator.js
CHANGED
|
@@ -305,9 +305,10 @@ function adaptBackendStandards(template, scan) {
|
|
|
305
305
|
'<!-- TODO: Review and adjust the sections below to match your project\'s conventions. -->\n<!-- This file was generated from project analysis by create-sdd-project --init. -->'
|
|
306
306
|
);
|
|
307
307
|
|
|
308
|
-
// Update globs in frontmatter
|
|
308
|
+
// Update globs in frontmatter — only include tsx/jsx if frontend detected
|
|
309
309
|
const srcRoot = findSrcRootName(scan);
|
|
310
|
-
const
|
|
310
|
+
const exts = scan.frontend.detected ? 'ts,js,tsx,jsx' : 'ts,js';
|
|
311
|
+
const globPattern = srcRoot ? `${srcRoot}/**/*.{${exts}}` : `**/*.{${exts}}`;
|
|
311
312
|
content = content.replace(
|
|
312
313
|
/globs: \[.*?\]/,
|
|
313
314
|
`globs: ["${globPattern}"]`
|
|
@@ -373,6 +374,21 @@ function adaptBackendStandards(template, scan) {
|
|
|
373
374
|
);
|
|
374
375
|
}
|
|
375
376
|
|
|
377
|
+
// Adapt Validation section based on detected validation library
|
|
378
|
+
if (scan.backend.validation && scan.backend.validation !== 'Zod') {
|
|
379
|
+
// Has a validator, but not Zod — replace with detected library name
|
|
380
|
+
content = content.replace(
|
|
381
|
+
/## Validation\n\n[\s\S]*?(?=\n## Database Patterns)/,
|
|
382
|
+
`## Validation\n\n- Validate all inputs at the application layer using ${scan.backend.validation}\n- Validate before executing business logic\n- Return descriptive validation errors\n\n<!-- TODO: Add ${scan.backend.validation} validation patterns for your project. -->\n\n`
|
|
383
|
+
);
|
|
384
|
+
} else if (!scan.backend.validation) {
|
|
385
|
+
// No validation library detected — generic guidance
|
|
386
|
+
content = content.replace(
|
|
387
|
+
/## Validation\n\n[\s\S]*?(?=\n## Database Patterns)/,
|
|
388
|
+
`## Validation\n\n- Validate all inputs at the application layer\n- Validate before executing business logic\n- Return descriptive validation errors\n\n<!-- TODO: Add validation patterns for your project (e.g., Zod, Joi, class-validator). -->\n\n`
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
|
|
376
392
|
// Replace Prisma-specific references in Security and Performance sections
|
|
377
393
|
if (scan.backend.orm !== 'Prisma') {
|
|
378
394
|
content = content.replace(
|
|
@@ -499,6 +515,12 @@ function adaptAgentsMd(template, config, scan) {
|
|
|
499
515
|
'Frontend patterns (Next.js, Tailwind, Radix)',
|
|
500
516
|
`Frontend patterns (${parts.join(', ')})`
|
|
501
517
|
);
|
|
518
|
+
} else {
|
|
519
|
+
// Remove frontend-standards reference for backend-only projects
|
|
520
|
+
content = content.replace(
|
|
521
|
+
/- \[Frontend Standards\].*\n/,
|
|
522
|
+
''
|
|
523
|
+
);
|
|
502
524
|
}
|
|
503
525
|
|
|
504
526
|
return content;
|
package/lib/init-wizard.js
CHANGED
|
@@ -33,6 +33,7 @@ function formatScanSummary(scanResult) {
|
|
|
33
33
|
const patternLabels = {
|
|
34
34
|
mvc: 'MVC',
|
|
35
35
|
ddd: 'DDD (Domain-Driven Design)',
|
|
36
|
+
layered: 'Layered (controllers + handlers + managers)',
|
|
36
37
|
'feature-based': 'Feature-based',
|
|
37
38
|
'handler-based': 'Handler-based',
|
|
38
39
|
flat: 'Flat structure',
|
package/lib/scanner.js
CHANGED
|
@@ -121,6 +121,22 @@ function detectBackend(dir, pkg) {
|
|
|
121
121
|
// Port detection
|
|
122
122
|
result.port = detectPort(dir, pkg);
|
|
123
123
|
|
|
124
|
+
// Validation library detection
|
|
125
|
+
const validators = [
|
|
126
|
+
{ dep: 'zod', label: 'Zod' },
|
|
127
|
+
{ dep: 'joi', label: 'Joi' },
|
|
128
|
+
{ dep: 'class-validator', label: 'class-validator' },
|
|
129
|
+
{ dep: 'yup', label: 'Yup' },
|
|
130
|
+
{ dep: 'ajv', label: 'Ajv' },
|
|
131
|
+
];
|
|
132
|
+
result.validation = null;
|
|
133
|
+
for (const v of validators) {
|
|
134
|
+
if (deps[v.dep]) {
|
|
135
|
+
result.validation = v.label;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
124
140
|
// If no framework but has a server-like structure, still mark as detected
|
|
125
141
|
if (!result.detected && (result.orm || result.db)) {
|
|
126
142
|
result.detected = true;
|