@brunosps00/dev-workflow 0.8.1 → 0.10.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/README.md +30 -27
- package/bin/dev-workflow.js +1 -1
- package/lib/constants.js +6 -8
- package/lib/init.js +6 -0
- package/lib/install-deps.js +0 -5
- package/lib/migrate-gsd.js +164 -0
- package/lib/uninstall.js +2 -2
- package/package.json +1 -1
- package/scaffold/en/commands/dw-analyze-project.md +6 -11
- package/scaffold/en/commands/dw-autopilot.md +10 -17
- package/scaffold/en/commands/dw-brainstorm.md +2 -2
- package/scaffold/en/commands/dw-bugfix.md +1 -0
- package/scaffold/en/commands/dw-code-review.md +7 -5
- package/scaffold/en/commands/dw-commit.md +6 -0
- package/scaffold/en/commands/dw-create-prd.md +5 -4
- package/scaffold/en/commands/dw-create-techspec.md +7 -4
- package/scaffold/en/commands/dw-deep-research.md +6 -0
- package/scaffold/en/commands/dw-deps-audit.md +1 -0
- package/scaffold/en/commands/dw-find-skills.md +4 -4
- package/scaffold/en/commands/dw-fix-qa.md +1 -0
- package/scaffold/en/commands/dw-generate-pr.md +1 -0
- package/scaffold/en/commands/dw-help.md +10 -27
- package/scaffold/en/commands/dw-intel.md +99 -30
- package/scaffold/en/commands/dw-map-codebase.md +125 -0
- package/scaffold/en/commands/dw-new-project.md +1 -1
- package/scaffold/en/commands/dw-redesign-ui.md +5 -9
- package/scaffold/en/commands/dw-refactoring-analysis.md +8 -6
- package/scaffold/en/commands/dw-review-implementation.md +28 -2
- package/scaffold/en/commands/dw-run-plan.md +14 -20
- package/scaffold/en/commands/dw-run-task.md +5 -4
- package/scaffold/en/commands/dw-update.md +3 -1
- package/scaffold/en/templates/idea-onepager.md +2 -2
- package/scaffold/pt-br/commands/dw-analyze-project.md +6 -11
- package/scaffold/pt-br/commands/dw-autopilot.md +10 -17
- package/scaffold/pt-br/commands/dw-brainstorm.md +2 -2
- package/scaffold/pt-br/commands/dw-bugfix.md +1 -0
- package/scaffold/pt-br/commands/dw-code-review.md +7 -5
- package/scaffold/pt-br/commands/dw-commit.md +6 -0
- package/scaffold/pt-br/commands/dw-create-prd.md +5 -4
- package/scaffold/pt-br/commands/dw-create-techspec.md +7 -4
- package/scaffold/pt-br/commands/dw-deep-research.md +6 -0
- package/scaffold/pt-br/commands/dw-deps-audit.md +1 -0
- package/scaffold/pt-br/commands/dw-find-skills.md +4 -4
- package/scaffold/pt-br/commands/dw-fix-qa.md +1 -0
- package/scaffold/pt-br/commands/dw-generate-pr.md +1 -0
- package/scaffold/pt-br/commands/dw-help.md +10 -27
- package/scaffold/pt-br/commands/dw-intel.md +99 -30
- package/scaffold/pt-br/commands/dw-map-codebase.md +125 -0
- package/scaffold/pt-br/commands/dw-new-project.md +1 -1
- package/scaffold/pt-br/commands/dw-redesign-ui.md +5 -9
- package/scaffold/pt-br/commands/dw-refactoring-analysis.md +8 -6
- package/scaffold/pt-br/commands/dw-review-implementation.md +21 -2
- package/scaffold/pt-br/commands/dw-run-plan.md +16 -22
- package/scaffold/pt-br/commands/dw-run-task.md +5 -4
- package/scaffold/pt-br/commands/dw-update.md +3 -1
- package/scaffold/pt-br/templates/idea-onepager.md +2 -2
- package/scaffold/skills/dw-codebase-intel/SKILL.md +102 -0
- package/scaffold/skills/dw-codebase-intel/agents/intel-updater.md +318 -0
- package/scaffold/skills/dw-codebase-intel/references/api-design-discipline.md +138 -0
- package/scaffold/skills/dw-codebase-intel/references/incremental-update.md +79 -0
- package/scaffold/skills/dw-codebase-intel/references/intel-format.md +208 -0
- package/scaffold/skills/dw-codebase-intel/references/query-patterns.md +148 -0
- package/scaffold/skills/dw-debug-protocol/SKILL.md +106 -0
- package/scaffold/skills/dw-debug-protocol/references/error-categorization.md +127 -0
- package/scaffold/skills/dw-debug-protocol/references/non-reproducible-strategy.md +108 -0
- package/scaffold/skills/dw-debug-protocol/references/six-step-triage.md +139 -0
- package/scaffold/skills/dw-debug-protocol/references/stop-the-line.md +52 -0
- package/scaffold/skills/dw-execute-phase/SKILL.md +133 -0
- package/scaffold/skills/dw-execute-phase/agents/executor.md +264 -0
- package/scaffold/skills/dw-execute-phase/agents/plan-checker.md +215 -0
- package/scaffold/skills/dw-execute-phase/references/atomic-commits.md +143 -0
- package/scaffold/skills/dw-execute-phase/references/plan-verification.md +156 -0
- package/scaffold/skills/dw-execute-phase/references/wave-coordination.md +102 -0
- package/scaffold/skills/dw-git-discipline/SKILL.md +120 -0
- package/scaffold/skills/dw-git-discipline/references/atomic-commits-discipline.md +158 -0
- package/scaffold/skills/dw-git-discipline/references/branch-hygiene.md +150 -0
- package/scaffold/skills/dw-git-discipline/references/trunk-based-pattern.md +82 -0
- package/scaffold/skills/dw-memory/SKILL.md +1 -2
- package/scaffold/skills/dw-simplification/SKILL.md +142 -0
- package/scaffold/skills/dw-simplification/references/behavior-preserving.md +148 -0
- package/scaffold/skills/dw-simplification/references/chestertons-fence.md +152 -0
- package/scaffold/skills/dw-simplification/references/complexity-metrics.md +147 -0
- package/scaffold/skills/dw-source-grounding/SKILL.md +128 -0
- package/scaffold/skills/dw-source-grounding/references/citation-protocol.md +108 -0
- package/scaffold/skills/dw-source-grounding/references/freshness-check.md +108 -0
- package/scaffold/skills/dw-source-grounding/references/source-priority.md +146 -0
- package/scaffold/skills/dw-verify/SKILL.md +0 -1
- package/scaffold/skills/vercel-react-best-practices/SKILL.md +4 -0
- package/scaffold/skills/vercel-react-best-practices/references/perf-discipline.md +122 -0
- package/scaffold/skills/webapp-testing/SKILL.md +5 -0
- package/scaffold/skills/webapp-testing/references/security-boundary.md +115 -0
- package/scaffold/skills/webapp-testing/references/three-workflow-patterns.md +144 -0
- package/scaffold/en/commands/dw-quick.md +0 -85
- package/scaffold/en/commands/dw-resume.md +0 -82
- package/scaffold/pt-br/commands/dw-quick.md +0 -85
- package/scaffold/pt-br/commands/dw-resume.md +0 -82
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dw-intel-updater
|
|
3
|
+
description: Analyzes codebase and writes structured intel files to .dw/intel/.
|
|
4
|
+
tools: Read, Write, Bash, Glob, Grep
|
|
5
|
+
color: cyan
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
<required_reading>
|
|
9
|
+
CRITICAL: If your spawn prompt contains a required_reading block,
|
|
10
|
+
you MUST Read every listed file BEFORE any other action.
|
|
11
|
+
Skipping this causes hallucinated context and broken output.
|
|
12
|
+
</required_reading>
|
|
13
|
+
|
|
14
|
+
**Context budget:** Load project skills first (lightweight). Read implementation files incrementally — load only what each check requires, not the full codebase upfront.
|
|
15
|
+
|
|
16
|
+
**Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
|
|
17
|
+
1. List available skills (subdirectories)
|
|
18
|
+
2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
|
|
19
|
+
3. Load specific reference files as needed during analysis
|
|
20
|
+
4. Apply skill rules to ensure intel files reflect project skill-defined patterns and architecture.
|
|
21
|
+
|
|
22
|
+
This ensures project-specific patterns, conventions, and best practices are applied during execution.
|
|
23
|
+
|
|
24
|
+
> Default file: `.dw/intel/stack.json` (if exists) to understand current state before updating.
|
|
25
|
+
|
|
26
|
+
# dw-intel-updater
|
|
27
|
+
|
|
28
|
+
<role>
|
|
29
|
+
You are **dw-intel-updater**, the codebase intelligence agent for dev-workflow. You read project source files and write structured intel to `.dw/intel/`. Your output becomes the queryable knowledge base that other commands (`/dw-intel`, `/dw-create-prd`, `/dw-create-techspec`, `/dw-code-review`, etc.) use instead of doing expensive codebase exploration reads.
|
|
30
|
+
|
|
31
|
+
## Core Principle
|
|
32
|
+
|
|
33
|
+
Write machine-parseable, evidence-based intelligence. Every claim references actual file paths. Prefer structured JSON over prose.
|
|
34
|
+
|
|
35
|
+
- **Always include file paths.** Every claim must reference the actual code location.
|
|
36
|
+
- **Write current state only.** No temporal language ("recently added", "will be changed").
|
|
37
|
+
- **Evidence-based.** Read the actual files. Do not guess from file names or directory structures.
|
|
38
|
+
- **Cross-platform.** Use Glob, Read, and Grep tools — not Bash `ls`, `find`, or `cat`. Bash file commands fail on Windows.
|
|
39
|
+
- **ALWAYS use the Write tool to create files** — never use `Bash(cat << 'EOF')` or heredoc commands for file creation.
|
|
40
|
+
</role>
|
|
41
|
+
|
|
42
|
+
<upstream_input>
|
|
43
|
+
## Upstream Input
|
|
44
|
+
|
|
45
|
+
### From `/dw-map-codebase` Command
|
|
46
|
+
|
|
47
|
+
- **Spawned by:** `/dw-map-codebase` command
|
|
48
|
+
- **Receives:** Focus directive — either `full` (all 5 files) or `partial --files <paths>` (update specific file entries only)
|
|
49
|
+
- **Input format:** Spawn prompt with `focus: full|partial` directive and project root path
|
|
50
|
+
|
|
51
|
+
### Trigger gate
|
|
52
|
+
|
|
53
|
+
`/dw-map-codebase` confirms the command is enabled and the project has source files before spawning this agent. Proceed directly to Step 1.
|
|
54
|
+
</upstream_input>
|
|
55
|
+
|
|
56
|
+
## Project Scope
|
|
57
|
+
|
|
58
|
+
When analyzing a project, target the application source code under conventional roots (`src/`, `apps/`, `packages/`, `lib/` for libraries, language-specific roots like `app/` for FastAPI, `Pages/` for Razor, etc.). Use Glob to enumerate; do not assume a layout.
|
|
59
|
+
|
|
60
|
+
EXCLUDE from counts and analysis:
|
|
61
|
+
|
|
62
|
+
- `.dw/` — dev-workflow planning docs, not project code
|
|
63
|
+
- `.agents/`, `.claude/`, `.opencode/`, `.codex/` — agent harness configs
|
|
64
|
+
- `node_modules/`, `dist/`, `build/`, `.next/`, `target/`, `.git/`
|
|
65
|
+
- `coverage/`, `*.lock`, `*.log`
|
|
66
|
+
|
|
67
|
+
**Count accuracy:** When reporting component counts in `stack.json` or `arch.md`, always derive counts by running Glob on canonical locations, not from memory or `CLAUDE.md`. Example: `Glob("src/**/*.ts")`, `Glob("apps/*/package.json")`.
|
|
68
|
+
|
|
69
|
+
## Forbidden Files
|
|
70
|
+
|
|
71
|
+
When exploring, NEVER read or include in your output:
|
|
72
|
+
- `.env` files (except `.env.example` or `.env.template`)
|
|
73
|
+
- `*.key`, `*.pem`, `*.pfx`, `*.p12` — private keys and certificates
|
|
74
|
+
- Files containing `credential` or `secret` in their name
|
|
75
|
+
- `*.keystore`, `*.jks` — Java keystores
|
|
76
|
+
- `id_rsa`, `id_ed25519` — SSH keys
|
|
77
|
+
- `node_modules/`, `.git/`, `dist/`, `build/` directories
|
|
78
|
+
|
|
79
|
+
If encountered, skip silently. Do NOT include contents.
|
|
80
|
+
|
|
81
|
+
## Intel File Schemas
|
|
82
|
+
|
|
83
|
+
All JSON files include a `_meta` object with `updated_at` (ISO-8601 timestamp, UTC) and `version` (integer, start at 1, increment on update).
|
|
84
|
+
|
|
85
|
+
### `files.json` — File Graph
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"_meta": { "updated_at": "ISO-8601", "version": 1 },
|
|
90
|
+
"entries": {
|
|
91
|
+
"src/index.ts": {
|
|
92
|
+
"exports": ["main", "default"],
|
|
93
|
+
"imports": ["./config", "express"],
|
|
94
|
+
"type": "entry-point"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**`exports` constraint:** Array of ACTUAL exported symbol names extracted from `module.exports` or `export` statements. MUST be real identifiers (e.g., `"configLoad"`, `"stateUpdate"`), NOT descriptions (e.g., `"config operations"`). If an export string contains a space, it is wrong — extract the actual symbol name instead.
|
|
101
|
+
|
|
102
|
+
Types: `entry-point`, `module`, `config`, `test`, `script`, `type-def`, `style`, `template`, `data`.
|
|
103
|
+
|
|
104
|
+
### `apis.json` — API Surfaces
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"_meta": { "updated_at": "ISO-8601", "version": 1 },
|
|
109
|
+
"entries": {
|
|
110
|
+
"GET /api/users": {
|
|
111
|
+
"method": "GET",
|
|
112
|
+
"path": "/api/users",
|
|
113
|
+
"params": ["page", "limit"],
|
|
114
|
+
"file": "src/routes/users.ts",
|
|
115
|
+
"description": "List all users with pagination"
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
For non-HTTP API surfaces (CLI commands, message handlers, GraphQL resolvers, gRPC), use a representative key (e.g., `"CLI: dw-init"`, `"GraphQL: getUserById"`, `"Handler: order.created"`).
|
|
122
|
+
|
|
123
|
+
### `deps.json` — Dependency Chains
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"_meta": { "updated_at": "ISO-8601", "version": 1 },
|
|
128
|
+
"entries": {
|
|
129
|
+
"express": {
|
|
130
|
+
"version": "^4.18.0",
|
|
131
|
+
"type": "production",
|
|
132
|
+
"used_by": ["src/server.ts", "src/routes/"],
|
|
133
|
+
"invocation": "require"
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Types: `production`, `development`, `peer`, `optional`.
|
|
140
|
+
|
|
141
|
+
`invocation`: how the dep is exercised — an npm script command (`npm run lint`, `npm test`), `require` for direct imports, or `implicit` for framework runtime deps.
|
|
142
|
+
|
|
143
|
+
### `stack.json` — Tech Stack
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"_meta": { "updated_at": "ISO-8601", "version": 1 },
|
|
148
|
+
"languages": ["TypeScript", "JavaScript"],
|
|
149
|
+
"frameworks": ["Express", "React"],
|
|
150
|
+
"tools": ["ESLint", "Jest", "Docker"],
|
|
151
|
+
"build_system": "npm scripts",
|
|
152
|
+
"test_framework": "Jest",
|
|
153
|
+
"package_manager": "npm",
|
|
154
|
+
"content_formats": ["Markdown (skills, agents, commands)", "YAML (frontmatter config)", "EJS (templates)"]
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Identify non-code content formats that are structurally important to the project and include them in `content_formats`.
|
|
159
|
+
|
|
160
|
+
### `arch.md` — Architecture Summary
|
|
161
|
+
|
|
162
|
+
```markdown
|
|
163
|
+
---
|
|
164
|
+
updated_at: "ISO-8601"
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Architecture Overview
|
|
168
|
+
|
|
169
|
+
{pattern name and description}
|
|
170
|
+
|
|
171
|
+
## Key Components
|
|
172
|
+
|
|
173
|
+
| Component | Path | Responsibility |
|
|
174
|
+
|-----------|------|---------------|
|
|
175
|
+
|
|
176
|
+
## Data Flow
|
|
177
|
+
|
|
178
|
+
{entry point} -> {processing} -> {output}
|
|
179
|
+
|
|
180
|
+
## Conventions
|
|
181
|
+
|
|
182
|
+
{naming, file organization, import patterns}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
<execution_flow>
|
|
186
|
+
## Exploration Process
|
|
187
|
+
|
|
188
|
+
### Step 1: Orientation
|
|
189
|
+
|
|
190
|
+
Glob for project structure indicators:
|
|
191
|
+
- `**/package.json`, `**/tsconfig.json`, `**/pyproject.toml`, `**/*.csproj`, `**/Cargo.toml`
|
|
192
|
+
- `**/Dockerfile`, `**/.github/workflows/*`
|
|
193
|
+
- Entry points: `**/index.*`, `**/main.*`, `**/app.*`, `**/server.*`
|
|
194
|
+
|
|
195
|
+
### Step 2: Stack Detection
|
|
196
|
+
|
|
197
|
+
Read `package.json`, configs, and build files. Synthesize languages, frameworks, build/test tooling. Write `stack.json` with the current ISO-8601 UTC timestamp in `_meta.updated_at`.
|
|
198
|
+
|
|
199
|
+
### Step 3: File Graph
|
|
200
|
+
|
|
201
|
+
Glob source files (`**/*.ts`, `**/*.js`, `**/*.py`, `**/*.cs`, `**/*.rs`, etc., excluding `node_modules/`, `dist/`, `build/`, `.git/`).
|
|
202
|
+
|
|
203
|
+
Read key files (entry points, configs, core modules) for imports/exports. Focus on files that matter — entry points, core modules, configs. Skip test files and generated code unless they reveal architecture.
|
|
204
|
+
|
|
205
|
+
Write `files.json`.
|
|
206
|
+
|
|
207
|
+
### Step 4: API Surface
|
|
208
|
+
|
|
209
|
+
Grep for route definitions, endpoint declarations, CLI command registrations. Patterns to search:
|
|
210
|
+
- TS/JS: `app.get(`, `router.post(`, `fastify.route(`, `app.use(`, Next.js `route.ts`/`page.tsx`
|
|
211
|
+
- Python: `@app.get(`, `@router.post(`, `@view_config(`, FastAPI/Flask decorators
|
|
212
|
+
- C#: `[HttpGet]`, `[HttpPost]`, `app.MapGet(`, `app.MapPost(`
|
|
213
|
+
- Rust: `Router::new().route(`, `#[get(`, `#[post(`
|
|
214
|
+
|
|
215
|
+
Write `apis.json`. If no API endpoints found, write an empty `entries` object with the timestamped meta block.
|
|
216
|
+
|
|
217
|
+
### Step 5: Dependencies
|
|
218
|
+
|
|
219
|
+
Read `package.json` (dependencies, devDependencies), `requirements.txt`, `pyproject.toml`, `*.csproj`, `Cargo.toml`. Cross-reference with actual imports to populate `used_by`.
|
|
220
|
+
|
|
221
|
+
Write `deps.json`.
|
|
222
|
+
|
|
223
|
+
### Step 6: Architecture
|
|
224
|
+
|
|
225
|
+
Synthesize patterns from steps 2-5 into a human-readable summary. Identify:
|
|
226
|
+
- Architectural pattern (MVC, layered, clean architecture, hexagonal, microservices, etc.)
|
|
227
|
+
- Key components and their responsibilities
|
|
228
|
+
- Data flow from entry point to output
|
|
229
|
+
- Conventions (naming, file organization, import patterns)
|
|
230
|
+
|
|
231
|
+
Write `arch.md` with the timestamp in frontmatter.
|
|
232
|
+
|
|
233
|
+
### Step 7: Snapshot
|
|
234
|
+
|
|
235
|
+
Write `.last-refresh.json` with:
|
|
236
|
+
|
|
237
|
+
```json
|
|
238
|
+
{
|
|
239
|
+
"updated_at": "ISO-8601",
|
|
240
|
+
"files": {
|
|
241
|
+
"stack.json": "<sha256 of contents>",
|
|
242
|
+
"files.json": "<sha256>",
|
|
243
|
+
"apis.json": "<sha256>",
|
|
244
|
+
"deps.json": "<sha256>",
|
|
245
|
+
"arch.md": "<sha256>"
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Compute hashes inline using Node's `crypto` (via Bash if needed): `node -e "console.log(require('crypto').createHash('sha256').update(require('fs').readFileSync('.dw/intel/stack.json')).digest('hex'))"`.
|
|
251
|
+
</execution_flow>
|
|
252
|
+
|
|
253
|
+
## Partial Updates
|
|
254
|
+
|
|
255
|
+
When `focus: partial --files <paths>` is specified:
|
|
256
|
+
|
|
257
|
+
1. Only update entries in `files.json`/`apis.json`/`deps.json` that reference the given paths.
|
|
258
|
+
2. Do NOT rewrite `stack.json` or `arch.md` (these need full context).
|
|
259
|
+
3. Preserve existing entries not related to the specified paths.
|
|
260
|
+
4. Read existing intel files first, merge updates, write back.
|
|
261
|
+
5. Bump `_meta.version` by 1 and update `_meta.updated_at`.
|
|
262
|
+
|
|
263
|
+
## Output Budget
|
|
264
|
+
|
|
265
|
+
| File | Target | Hard Limit |
|
|
266
|
+
|------|--------|------------|
|
|
267
|
+
| `files.json` | ≤2000 tokens | 3000 tokens |
|
|
268
|
+
| `apis.json` | ≤1500 tokens | 2500 tokens |
|
|
269
|
+
| `deps.json` | ≤1000 tokens | 1500 tokens |
|
|
270
|
+
| `stack.json` | ≤500 tokens | 800 tokens |
|
|
271
|
+
| `arch.md` | ≤1500 tokens | 2000 tokens |
|
|
272
|
+
|
|
273
|
+
For large codebases, prioritize coverage of key files over exhaustive listing. Include the most important 50-100 source files in `files.json` rather than attempting to list every file.
|
|
274
|
+
|
|
275
|
+
<success_criteria>
|
|
276
|
+
- [ ] All 5 intel files written to `.dw/intel/`
|
|
277
|
+
- [ ] All JSON files are valid, parseable JSON
|
|
278
|
+
- [ ] All entries reference actual file paths verified by Glob/Read
|
|
279
|
+
- [ ] `.last-refresh.json` written with hashes
|
|
280
|
+
- [ ] Completion marker returned
|
|
281
|
+
</success_criteria>
|
|
282
|
+
|
|
283
|
+
<structured_returns>
|
|
284
|
+
## Completion Protocol
|
|
285
|
+
|
|
286
|
+
CRITICAL: Your final output MUST end with exactly one completion marker. Orchestrators pattern-match on these markers to route results. Omitting causes silent failures.
|
|
287
|
+
|
|
288
|
+
- `## INTEL UPDATE COMPLETE` — all intel files written successfully
|
|
289
|
+
- `## INTEL UPDATE FAILED` — could not complete analysis (disabled, empty project, errors)
|
|
290
|
+
</structured_returns>
|
|
291
|
+
|
|
292
|
+
<critical_rules>
|
|
293
|
+
|
|
294
|
+
### Context Quality Tiers
|
|
295
|
+
|
|
296
|
+
| Budget Used | Tier | Behavior |
|
|
297
|
+
|-------------|------|----------|
|
|
298
|
+
| 0-30% | PEAK | Explore freely, read broadly |
|
|
299
|
+
| 30-50% | GOOD | Be selective with reads |
|
|
300
|
+
| 50-70% | DEGRADING | Write incrementally, skip non-essential |
|
|
301
|
+
| 70%+ | POOR | Finish current file and return immediately |
|
|
302
|
+
|
|
303
|
+
</critical_rules>
|
|
304
|
+
|
|
305
|
+
<anti_patterns>
|
|
306
|
+
|
|
307
|
+
## Anti-Patterns
|
|
308
|
+
|
|
309
|
+
1. DO NOT guess or assume — read actual files for evidence
|
|
310
|
+
2. DO NOT use Bash for file listing — use Glob tool
|
|
311
|
+
3. DO NOT read files in `node_modules`, `.git`, `dist`, or `build` directories
|
|
312
|
+
4. DO NOT include secrets or credentials in intel output
|
|
313
|
+
5. DO NOT write placeholder data — every entry must be verified
|
|
314
|
+
6. DO NOT exceed output budget — prioritize key files over exhaustive listing
|
|
315
|
+
7. DO NOT commit the output — the orchestrator handles commits
|
|
316
|
+
8. DO NOT consume more than 50% context before producing output — write incrementally
|
|
317
|
+
|
|
318
|
+
</anti_patterns>
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# API design discipline — contract-first, convention-respecting
|
|
2
|
+
|
|
3
|
+
> Adapted from [`addyosmani/agent-skills/api-design`](https://github.com/addyosmani/agent-skills/tree/main/api-design) (MIT). Patterns adapted to dev-workflow's context where intel feeds techspec authoring; emphasis is on respecting the project's existing conventions over imposing external standards.
|
|
4
|
+
|
|
5
|
+
When designing or extending APIs, the goal is not "follow REST best practices" — it's "fit this project's contract and remain stable." This file frames the discipline.
|
|
6
|
+
|
|
7
|
+
## Hyrum's Law
|
|
8
|
+
|
|
9
|
+
> With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended on by somebody.
|
|
10
|
+
|
|
11
|
+
Practical consequence: any field returned, any header sent, any error format used, any timing characteristic — at least one consumer probably depends on it. Changing it breaks them. This is true even for behaviors you consider "implementation details."
|
|
12
|
+
|
|
13
|
+
Implications:
|
|
14
|
+
|
|
15
|
+
1. **Be deliberate about what you expose.** Returning `{ ok: true, data: ... }` instead of just `data` adds an observable that future consumers will couple to.
|
|
16
|
+
2. **Default to the smallest contract that satisfies known consumers.** Adding more later is easy; removing later is breaking.
|
|
17
|
+
3. **Treat the contract as load-bearing infrastructure.** Schema docs, type definitions, and OpenAPI/JSON Schema spec files are part of the contract, not metadata.
|
|
18
|
+
|
|
19
|
+
## Read project intel before designing
|
|
20
|
+
|
|
21
|
+
When intel is available (`.dw/intel/` populated), read it first:
|
|
22
|
+
|
|
23
|
+
- `apis.json` — what shapes already exist? Naming patterns? Pagination style?
|
|
24
|
+
- `arch.md` — how do existing endpoints group? Which layer owns what?
|
|
25
|
+
- `stack.json` — what's the framework? Schema validator? Serializer?
|
|
26
|
+
|
|
27
|
+
A new API should look LIKE existing APIs in the project. If the project uses snake_case in JSON, your new endpoint uses snake_case. If existing endpoints return `{ data, meta }`, yours does too. Imposing an external "best practice" that conflicts with existing patterns adds inconsistency for no payoff.
|
|
28
|
+
|
|
29
|
+
## Contract-first design
|
|
30
|
+
|
|
31
|
+
Before writing the handler, write the contract:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
// API contract (TypeScript-first; equivalent in OpenAPI/Zod/etc.)
|
|
35
|
+
interface CreateOrderRequest {
|
|
36
|
+
customer_id: string;
|
|
37
|
+
items: { sku: string; qty: number }[];
|
|
38
|
+
shipping_address: Address;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface CreateOrderResponse {
|
|
42
|
+
order_id: string;
|
|
43
|
+
status: 'pending' | 'confirmed';
|
|
44
|
+
estimated_ship_date: string; // ISO-8601
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface CreateOrderError {
|
|
48
|
+
code: 'invalid_input' | 'inventory_unavailable' | 'payment_declined';
|
|
49
|
+
message: string;
|
|
50
|
+
details?: Record<string, unknown>;
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The contract is reviewed BEFORE implementation. Errors caught here cost minutes; errors caught after release cost hours of migration.
|
|
55
|
+
|
|
56
|
+
## Error semantics
|
|
57
|
+
|
|
58
|
+
Errors are part of the contract. Common pitfalls:
|
|
59
|
+
|
|
60
|
+
- **Generic 500 with no body.** Caller can't differentiate transient from permanent → over-retries.
|
|
61
|
+
- **Different error shapes per endpoint.** Caller can't write a unified error handler.
|
|
62
|
+
- **Validation errors mixed with auth errors mixed with server errors.** Status codes alone aren't enough; codes must be discriminating.
|
|
63
|
+
|
|
64
|
+
Discipline:
|
|
65
|
+
|
|
66
|
+
- Pick one error shape (e.g., `{ code, message, details? }` or RFC 7807 ProblemDetails). Use it everywhere.
|
|
67
|
+
- Distinguish: validation (`400`/`422`), auth (`401`/`403`), not-found (`404`), conflict (`409`), rate-limit (`429`), retryable server error (`503`), permanent server error (`500`).
|
|
68
|
+
- Document error codes alongside the request/response shape. Callers code against codes, not English messages.
|
|
69
|
+
|
|
70
|
+
## Boundary validation
|
|
71
|
+
|
|
72
|
+
Validate at the API boundary, not deep inside.
|
|
73
|
+
|
|
74
|
+
- Use a schema validator (Zod, Joi, Pydantic, etc.) that matches the project's stack.
|
|
75
|
+
- Reject malformed input with a structured error before any business logic runs.
|
|
76
|
+
- Trust internal callers; validate external input.
|
|
77
|
+
|
|
78
|
+
The same principle applies on the response: type-check what you serialize. A handler returning `customer.email` when there's a possibility of `customer === null` produces a 500 in production — caught in development with strict typing.
|
|
79
|
+
|
|
80
|
+
## Versioning
|
|
81
|
+
|
|
82
|
+
When the contract changes incompatibly, version. Common strategies:
|
|
83
|
+
|
|
84
|
+
| Strategy | Trade-off |
|
|
85
|
+
|----------|-----------|
|
|
86
|
+
| URL versioning (`/v1/orders`, `/v2/orders`) | Visible, simple; URL clutter |
|
|
87
|
+
| Header versioning (`Accept: application/vnd.app.v2+json`) | Cleaner URLs; less discoverable |
|
|
88
|
+
| Body versioning (`{ version: 2, ... }`) | Flexible per-request; more parsing complexity |
|
|
89
|
+
|
|
90
|
+
Pick the project's existing strategy; don't introduce a second one. Changing strategy is itself a breaking change.
|
|
91
|
+
|
|
92
|
+
When deprecating a version:
|
|
93
|
+
|
|
94
|
+
1. Announce deprecation date in docs and response headers (`Deprecation: ...`, `Sunset: ...`).
|
|
95
|
+
2. Continue to serve the old version for the announced period.
|
|
96
|
+
3. Provide a migration guide for callers.
|
|
97
|
+
4. Remove ONLY after the deprecation period and confirmation no callers remain.
|
|
98
|
+
|
|
99
|
+
## Pagination
|
|
100
|
+
|
|
101
|
+
| Style | When |
|
|
102
|
+
|-------|------|
|
|
103
|
+
| Offset/limit (`?offset=20&limit=10`) | Small datasets, simple UIs. Breaks under concurrent inserts (skip/dup rows). |
|
|
104
|
+
| Cursor-based (`?cursor=abc&limit=10`) | Large datasets, infinite scroll. Stable under writes. |
|
|
105
|
+
| Page-based (`?page=3&per_page=10`) | UI-driven, equivalent to offset under the hood. |
|
|
106
|
+
|
|
107
|
+
Cursor is preferred for any list expected to grow large or change during browsing. Don't mix styles across the API.
|
|
108
|
+
|
|
109
|
+
## Idempotency
|
|
110
|
+
|
|
111
|
+
Operations that can be retried (POST creating something, PUT updating, DELETE removing) need idempotency guarantees:
|
|
112
|
+
|
|
113
|
+
- **Idempotency keys:** caller sends a unique key with each request; server deduplicates.
|
|
114
|
+
- **Conditional requests:** use ETags / `If-Match` headers for safe concurrent updates.
|
|
115
|
+
- **Replay-safe semantics:** the operation produces the same outcome regardless of how many times it's retried.
|
|
116
|
+
|
|
117
|
+
Without these, retries cause duplicates (orders, charges, emails) — common production bug.
|
|
118
|
+
|
|
119
|
+
## When the project has its own conventions
|
|
120
|
+
|
|
121
|
+
If `.dw/intel/apis.json` shows a strong existing pattern (e.g., all endpoints use `snake_case`, return `{ data, meta }`, use cursor pagination, error format `{ error: { code, message } }`):
|
|
122
|
+
|
|
123
|
+
- Follow it. Don't propose a "better" alternative without explicit user buy-in.
|
|
124
|
+
- Document the convention in the techspec so future contributors stay aligned.
|
|
125
|
+
- Inconsistency hurts more than imperfection.
|
|
126
|
+
|
|
127
|
+
## Anti-patterns
|
|
128
|
+
|
|
129
|
+
- Designing the handler before the contract — handler implementation forces awkward shapes.
|
|
130
|
+
- Returning different shapes for success and error (callers need bifurcating type guards everywhere).
|
|
131
|
+
- Stuffing multiple operations into one endpoint (`POST /process`) — opaque, hard to test, hard to monitor.
|
|
132
|
+
- Using HTTP status 200 with a body indicating failure — callers can't trust standard error handling.
|
|
133
|
+
- Breaking changes shipped without a version bump.
|
|
134
|
+
- Adding "nice to have" fields to the response that aren't documented — callers will couple to them anyway (Hyrum).
|
|
135
|
+
|
|
136
|
+
## Integration with dev-workflow
|
|
137
|
+
|
|
138
|
+
Use this discipline when authoring techspecs (`/dw-create-techspec`) or refactoring API surfaces. Cite `apis.json` evidence in the techspec — "existing endpoints use cursor pagination (apis.json:42); this endpoint follows the same pattern."
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Incremental update — keeping `.dw/intel/` fresh without re-scanning everything
|
|
2
|
+
|
|
3
|
+
A full scan of a 50K-line repo takes minutes and burns context. Incremental updates target only what changed, in seconds.
|
|
4
|
+
|
|
5
|
+
## When to run a full update
|
|
6
|
+
|
|
7
|
+
- First analysis (no `.dw/intel/` yet)
|
|
8
|
+
- After major restructuring (migration, framework change, large refactor)
|
|
9
|
+
- After 30+ days since last refresh (file structure has likely drifted)
|
|
10
|
+
- When `/dw-intel` queries return obviously stale results
|
|
11
|
+
|
|
12
|
+
Trigger via `/dw-map-codebase` (no flag) or `/dw-map-codebase --full`.
|
|
13
|
+
|
|
14
|
+
## When to run a partial update
|
|
15
|
+
|
|
16
|
+
- A single PR / feature branch touched 1-20 files
|
|
17
|
+
- After `/dw-run-task` completes (touched files are known via git)
|
|
18
|
+
- After `dw-deps-audit --execute` updates dependencies (only `deps.json` needs refresh)
|
|
19
|
+
|
|
20
|
+
Trigger via `/dw-map-codebase --files src/foo.ts src/bar.ts` (explicit list) or `/dw-map-codebase --since HEAD~5` (from git diff).
|
|
21
|
+
|
|
22
|
+
## Partial update protocol
|
|
23
|
+
|
|
24
|
+
The `intel-updater` agent receives `focus: partial --files <paths>` and:
|
|
25
|
+
|
|
26
|
+
1. **Read** the existing `.dw/intel/{files,apis,deps}.json`. Parse and keep entries for files NOT in the input list.
|
|
27
|
+
2. **For each file in the input list**:
|
|
28
|
+
- If the file no longer exists on disk → remove its entry from `files.json` and any references in `apis.json`.
|
|
29
|
+
- Otherwise → re-read the file, recompute imports/exports/type, replace the entry.
|
|
30
|
+
- For `apis.json`: re-grep the file for route definitions, replace any matching entries (key = `"<METHOD> <PATH>"`).
|
|
31
|
+
- For `deps.json`: re-cross-reference the file's imports. Update `used_by` arrays accordingly (add or remove the file from each affected dep's `used_by`).
|
|
32
|
+
3. **Skip** `stack.json` and `arch.md` — these need full context and are NOT updated by partial runs. They become stale until the next full run.
|
|
33
|
+
4. **Bump** `_meta.version` by 1, set `_meta.updated_at` to now.
|
|
34
|
+
5. **Update** `.last-refresh.json` with the new hashes for `files.json`, `apis.json`, `deps.json` (the three that were touched).
|
|
35
|
+
|
|
36
|
+
If you run a partial update on a project where `.dw/intel/` doesn't exist, abort with: `"No .dw/intel/ found. Run /dw-map-codebase first for a full scan."`
|
|
37
|
+
|
|
38
|
+
## How `intel-updater` knows what's "key" in a partial
|
|
39
|
+
|
|
40
|
+
The `--files` list is authoritative for `files.json`. For `apis.json`, the agent must broaden by 1 hop:
|
|
41
|
+
|
|
42
|
+
- If `src/routes/users.ts` was in `--files`, also re-grep `src/routes/index.ts` (because it likely re-exports the user routes).
|
|
43
|
+
- If `src/server.ts` was in `--files`, re-scan all `src/routes/**/*.ts` (because the route registration list may have changed).
|
|
44
|
+
|
|
45
|
+
Concretely: after re-reading the explicit files, re-grep the project for `app.use(`/`router.use(`/`@Module(`/etc. and re-extract the API map from those entry points. This catches indirect changes without doing a full scan.
|
|
46
|
+
|
|
47
|
+
For `deps.json`, only the explicit files matter — the `used_by` arrays are derived from imports, which are local to each file.
|
|
48
|
+
|
|
49
|
+
## Detecting drift before updating
|
|
50
|
+
|
|
51
|
+
Use `.last-refresh.json` to detect whether files changed since the last refresh:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
node -e "
|
|
55
|
+
const cur = require('crypto').createHash('sha256')
|
|
56
|
+
.update(require('fs').readFileSync('.dw/intel/stack.json'))
|
|
57
|
+
.digest('hex');
|
|
58
|
+
const last = require('./.dw/intel/.last-refresh.json').files['stack.json'];
|
|
59
|
+
console.log(cur === last ? 'unchanged' : 'changed');
|
|
60
|
+
"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
If everything matches `.last-refresh.json` AND no source file's mtime is newer than `_meta.updated_at`, the index is fully fresh and the update can be a no-op.
|
|
64
|
+
|
|
65
|
+
## Conflict resolution (full update overlapping with partial)
|
|
66
|
+
|
|
67
|
+
If a full update is triggered while a partial update is in flight (rare but possible in CI), the FULL update wins:
|
|
68
|
+
|
|
69
|
+
- The partial agent's writes are overwritten when the full agent finishes.
|
|
70
|
+
- Both agents use atomic write (write to `.dw/intel/<file>.json.tmp` then rename) to avoid leaving the index in a torn state.
|
|
71
|
+
|
|
72
|
+
## What incremental updates do NOT cover
|
|
73
|
+
|
|
74
|
+
- New `package.json` (e.g., user added `express` to deps but no source file imports it yet) — `deps.json` won't get the entry until that package is imported AND the importing file is in `--files`.
|
|
75
|
+
- Mitigation: when running `/dw-deps-audit --execute`, follow up with `/dw-map-codebase --full` to capture new deps.
|
|
76
|
+
- New file with a brand-new API route, when neither the new file nor any registration site was in `--files`.
|
|
77
|
+
- Mitigation: include `src/routes/index.ts` (or your project's route registration entry point) in every partial update that mentions any route file.
|
|
78
|
+
- Architectural changes (the kind that would update `arch.md`) — partial updates leave `arch.md` stale.
|
|
79
|
+
- Mitigation: run a full update after merging large architectural PRs.
|