opencode-skills-collection 3.0.46 → 3.0.47
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/bundled-skills/.antigravity-install-manifest.json +10 -1
- package/bundled-skills/2slides-ppt-generator/SKILL.md +1 -1
- package/bundled-skills/2slides-ppt-generator/scripts/create_pdf_slides.py +2 -1
- package/bundled-skills/2slides-ppt-generator/scripts/generate_narration.py +2 -1
- package/bundled-skills/2slides-ppt-generator/scripts/generate_slides.py +13 -7
- package/bundled-skills/android-dev/references/hybrid.md +7 -4
- package/bundled-skills/android-dev/references/react-native.md +5 -2
- package/bundled-skills/atlas-contract/SKILL.md +4 -4
- package/bundled-skills/atlas-ledger/SKILL.md +10 -7
- package/bundled-skills/bun-development/SKILL.md +1 -1
- package/bundled-skills/cloud-penetration-testing/SKILL.md +1 -1
- package/bundled-skills/codebase-to-wordpress-converter/SKILL.md +1 -0
- package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
- package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
- package/bundled-skills/docs/maintainers/repo-growth-seo.md +3 -3
- package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
- package/bundled-skills/docs/users/bundles.md +1 -1
- package/bundled-skills/docs/users/claude-code-skills.md +1 -1
- package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
- package/bundled-skills/docs/users/getting-started.md +1 -1
- package/bundled-skills/docs/users/kiro-integration.md +1 -1
- package/bundled-skills/docs/users/usage.md +4 -4
- package/bundled-skills/docs/users/visual-guide.md +4 -4
- package/bundled-skills/dos-verify-done-claims/SKILL.md +173 -0
- package/bundled-skills/ecl-harness-engineer/LICENSE +21 -0
- package/bundled-skills/ecl-harness-engineer/SKILL.md +714 -0
- package/bundled-skills/ecl-harness-engineer/agents/analyzer.md +119 -0
- package/bundled-skills/ecl-harness-engineer/agents/auditor.md +212 -0
- package/bundled-skills/ecl-harness-engineer/agents/creator-config.md +343 -0
- package/bundled-skills/ecl-harness-engineer/agents/creator-docs.md +201 -0
- package/bundled-skills/ecl-harness-engineer/agents/creator-linters.md +123 -0
- package/bundled-skills/ecl-harness-engineer/references/adapters/adapter-schema.md +204 -0
- package/bundled-skills/ecl-harness-engineer/references/adapters/generic.md +156 -0
- package/bundled-skills/ecl-harness-engineer/references/adapters/go.md +212 -0
- package/bundled-skills/ecl-harness-engineer/references/adapters/java.md +205 -0
- package/bundled-skills/ecl-harness-engineer/references/adapters/python.md +225 -0
- package/bundled-skills/ecl-harness-engineer/references/adapters/rust.md +220 -0
- package/bundled-skills/ecl-harness-engineer/references/adapters/typescript.md +245 -0
- package/bundled-skills/ecl-harness-engineer/references/architecture-diagrams.md +420 -0
- package/bundled-skills/ecl-harness-engineer/references/audit-templates.md +649 -0
- package/bundled-skills/ecl-harness-engineer/references/capability-registry.md +485 -0
- package/bundled-skills/ecl-harness-engineer/references/darwin-eval-prompts.md +373 -0
- package/bundled-skills/ecl-harness-engineer/references/documentation-templates.md +741 -0
- package/bundled-skills/ecl-harness-engineer/references/durability-patterns.md +423 -0
- package/bundled-skills/ecl-harness-engineer/references/ecl-harness.md +1431 -0
- package/bundled-skills/ecl-harness-engineer/references/environment-config-guide.md +534 -0
- package/bundled-skills/ecl-harness-engineer/references/environment-detection-guide.md +751 -0
- package/bundled-skills/ecl-harness-engineer/references/eval-templates.md +377 -0
- package/bundled-skills/ecl-harness-engineer/references/gc-templates.md +798 -0
- package/bundled-skills/ecl-harness-engineer/references/greenfield-templates.md +1385 -0
- package/bundled-skills/ecl-harness-engineer/references/linter-templates.md +448 -0
- package/bundled-skills/ecl-harness-engineer/references/observability-templates.md +315 -0
- package/bundled-skills/environment-setup-guide/SKILL.md +2 -2
- package/bundled-skills/evolution/SKILL.md +1 -1
- package/bundled-skills/gitops-workflow/SKILL.md +1 -1
- package/bundled-skills/linkerd-patterns/SKILL.md +1 -1
- package/bundled-skills/loki-mode/examples/todo-app-generated/frontend/package-lock.json +504 -1317
- package/bundled-skills/loki-mode/examples/todo-app-generated/frontend/package.json +2 -2
- package/bundled-skills/lovable-cleanup/SKILL.md +416 -0
- package/bundled-skills/monopoly/SKILL.md +397 -0
- package/bundled-skills/monopoly/patterns/SKILL.md +331 -0
- package/bundled-skills/monopoly/scale-benchmarks/SKILL.md +174 -0
- package/bundled-skills/monopoly/security-checklist/SKILL.md +69 -0
- package/bundled-skills/monopoly/tech-matrix/SKILL.md +268 -0
- package/bundled-skills/pagespeed-enhancer/SKILL.md +579 -0
- package/bundled-skills/polis-protocol/SKILL.md +6 -3
- package/bundled-skills/unship/SKILL.md +11 -5
- package/bundled-skills/uv-package-manager/resources/implementation-playbook.md +1 -1
- package/bundled-skills/varlock/SKILL.md +2 -2
- package/package.json +1 -1
- package/skills_index.json +204 -4
|
@@ -0,0 +1,1385 @@
|
|
|
1
|
+
# Greenfield Templates
|
|
2
|
+
|
|
3
|
+
Complete, ready-to-use templates for 0→1 project scaffolding. Each section provides real file contents — not placeholders — for bootstrapping a new project with core harness infrastructure.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Go CLI Tool](#go-cli-tool)
|
|
8
|
+
- [Go Web API](#go-web-api)
|
|
9
|
+
- [TypeScript/Node CLI](#typescriptnode-cli)
|
|
10
|
+
- [TypeScript/Node Web API](#typescriptnode-web-api)
|
|
11
|
+
- [Python CLI](#python-cli)
|
|
12
|
+
- [Python Web API](#python-web-api)
|
|
13
|
+
- [Shared Templates](#shared-templates) (docs, exec-plans, quality — same for all stacks)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Go CLI Tool
|
|
18
|
+
|
|
19
|
+
### go.mod
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
module {module-path}
|
|
23
|
+
|
|
24
|
+
go 1.22
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### main.go
|
|
28
|
+
|
|
29
|
+
```go
|
|
30
|
+
package main
|
|
31
|
+
|
|
32
|
+
import (
|
|
33
|
+
"fmt"
|
|
34
|
+
"os"
|
|
35
|
+
|
|
36
|
+
"{module-path}/cmd"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
func main() {
|
|
40
|
+
if err := cmd.Execute(); err != nil {
|
|
41
|
+
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
|
42
|
+
os.Exit(1)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### cmd/root.go
|
|
48
|
+
|
|
49
|
+
```go
|
|
50
|
+
package cmd
|
|
51
|
+
|
|
52
|
+
import (
|
|
53
|
+
"fmt"
|
|
54
|
+
"os"
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
func Execute() error {
|
|
58
|
+
if len(os.Args) < 2 {
|
|
59
|
+
fmt.Println("{project-name} - {description}")
|
|
60
|
+
fmt.Println("\nUsage:")
|
|
61
|
+
fmt.Println(" {project-name} <command> [arguments]")
|
|
62
|
+
fmt.Println("\nCommands:")
|
|
63
|
+
fmt.Println(" version Print version info")
|
|
64
|
+
return nil
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
switch os.Args[1] {
|
|
68
|
+
case "version":
|
|
69
|
+
fmt.Println("{project-name} v0.1.0")
|
|
70
|
+
default:
|
|
71
|
+
return fmt.Errorf("unknown command: %s", os.Args[1])
|
|
72
|
+
}
|
|
73
|
+
return nil
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### internal/types/types.go
|
|
78
|
+
|
|
79
|
+
```go
|
|
80
|
+
// Package types defines core types shared across the application.
|
|
81
|
+
// Layer 0: No internal dependencies allowed.
|
|
82
|
+
package types
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### internal/core/core.go
|
|
86
|
+
|
|
87
|
+
```go
|
|
88
|
+
// Package core contains the main business logic.
|
|
89
|
+
// Layer 1: May depend on types (Layer 0) only.
|
|
90
|
+
package core
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Makefile
|
|
94
|
+
|
|
95
|
+
```makefile
|
|
96
|
+
.PHONY: build test lint lint-arch clean
|
|
97
|
+
|
|
98
|
+
build:
|
|
99
|
+
go build -o bin/{project-name} .
|
|
100
|
+
|
|
101
|
+
test:
|
|
102
|
+
go test ./...
|
|
103
|
+
|
|
104
|
+
lint: lint-arch
|
|
105
|
+
@if command -v golangci-lint >/dev/null 2>&1; then \
|
|
106
|
+
golangci-lint run; \
|
|
107
|
+
else \
|
|
108
|
+
echo "golangci-lint not installed, skipping"; \
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
lint-arch:
|
|
112
|
+
@echo "Checking architecture constraints..."
|
|
113
|
+
@go run scripts/lint-deps.go
|
|
114
|
+
@go run scripts/lint-quality.go
|
|
115
|
+
@echo "✓ Architecture checks passed"
|
|
116
|
+
|
|
117
|
+
clean:
|
|
118
|
+
rm -rf bin/
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### scripts/lint-deps.go
|
|
122
|
+
|
|
123
|
+
Use the template from `references/linter-templates.md`, with:
|
|
124
|
+
- `modulePath` set to the project's module path
|
|
125
|
+
- `layers` configured for the project's directory structure:
|
|
126
|
+
```go
|
|
127
|
+
var layers = [][]string{
|
|
128
|
+
{"internal/types"}, // Layer 0
|
|
129
|
+
{"internal/core"}, // Layer 1
|
|
130
|
+
{"cmd"}, // Layer 2 (top)
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### scripts/lint-quality.go
|
|
135
|
+
|
|
136
|
+
Use the template from `references/linter-templates.md`, with file size limit set to 500 for new projects (can grow to 1000 later).
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Go Web API
|
|
141
|
+
|
|
142
|
+
Same as Go CLI Tool, with these additions/changes:
|
|
143
|
+
|
|
144
|
+
### main.go
|
|
145
|
+
|
|
146
|
+
```go
|
|
147
|
+
package main
|
|
148
|
+
|
|
149
|
+
import (
|
|
150
|
+
"log"
|
|
151
|
+
"net/http"
|
|
152
|
+
|
|
153
|
+
"{module-path}/internal/api"
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
func main() {
|
|
157
|
+
router := api.NewRouter()
|
|
158
|
+
log.Println("Starting server on :8080")
|
|
159
|
+
if err := http.ListenAndServe(":8080", router); err != nil {
|
|
160
|
+
log.Fatalf("Server failed: %v", err)
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### internal/api/router.go
|
|
166
|
+
|
|
167
|
+
```go
|
|
168
|
+
// Package api defines HTTP handlers and routing.
|
|
169
|
+
// Layer 2: May depend on core (Layer 1) and types (Layer 0).
|
|
170
|
+
package api
|
|
171
|
+
|
|
172
|
+
import "net/http"
|
|
173
|
+
|
|
174
|
+
func NewRouter() http.Handler {
|
|
175
|
+
mux := http.NewServeMux()
|
|
176
|
+
mux.HandleFunc("GET /health", handleHealth)
|
|
177
|
+
return mux
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
func handleHealth(w http.ResponseWriter, r *http.Request) {
|
|
181
|
+
w.Header().Set("Content-Type", "application/json")
|
|
182
|
+
w.Write([]byte(`{"status":"ok"}`))
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Layer hierarchy
|
|
187
|
+
|
|
188
|
+
```go
|
|
189
|
+
var layers = [][]string{
|
|
190
|
+
{"internal/types"}, // Layer 0
|
|
191
|
+
{"internal/core"}, // Layer 1
|
|
192
|
+
{"internal/api"}, // Layer 2
|
|
193
|
+
{"cmd"}, // Layer 3 (top)
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## TypeScript/Node CLI
|
|
200
|
+
|
|
201
|
+
### package.json
|
|
202
|
+
|
|
203
|
+
```json
|
|
204
|
+
{
|
|
205
|
+
"name": "{project-name}",
|
|
206
|
+
"version": "0.1.0",
|
|
207
|
+
"description": "{description}",
|
|
208
|
+
"main": "dist/index.js",
|
|
209
|
+
"scripts": {
|
|
210
|
+
"build": "tsc",
|
|
211
|
+
"start": "node dist/index.js",
|
|
212
|
+
"dev": "ts-node src/index.ts",
|
|
213
|
+
"test": "jest",
|
|
214
|
+
"lint": "npm run lint:arch && eslint src/",
|
|
215
|
+
"lint:arch": "ts-node scripts/lint-deps.ts && ts-node scripts/lint-quality.ts"
|
|
216
|
+
},
|
|
217
|
+
"devDependencies": {
|
|
218
|
+
"@types/node": "^20.0.0",
|
|
219
|
+
"eslint": "^8.0.0",
|
|
220
|
+
"jest": "^29.0.0",
|
|
221
|
+
"ts-node": "^10.0.0",
|
|
222
|
+
"typescript": "^5.0.0"
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### tsconfig.json
|
|
228
|
+
|
|
229
|
+
```json
|
|
230
|
+
{
|
|
231
|
+
"compilerOptions": {
|
|
232
|
+
"target": "ES2022",
|
|
233
|
+
"module": "commonjs",
|
|
234
|
+
"outDir": "dist",
|
|
235
|
+
"rootDir": "src",
|
|
236
|
+
"strict": true,
|
|
237
|
+
"esModuleInterop": true,
|
|
238
|
+
"skipLibCheck": true,
|
|
239
|
+
"resolveJsonModule": true,
|
|
240
|
+
"declaration": true
|
|
241
|
+
},
|
|
242
|
+
"include": ["src/**/*"],
|
|
243
|
+
"exclude": ["node_modules", "dist"]
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### src/index.ts
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
#!/usr/bin/env node
|
|
251
|
+
|
|
252
|
+
function main(): void {
|
|
253
|
+
const args = process.argv.slice(2);
|
|
254
|
+
const command = args[0];
|
|
255
|
+
|
|
256
|
+
switch (command) {
|
|
257
|
+
case "version":
|
|
258
|
+
console.log("{project-name} v0.1.0");
|
|
259
|
+
break;
|
|
260
|
+
default:
|
|
261
|
+
console.log("{project-name} - {description}");
|
|
262
|
+
console.log("\nUsage:");
|
|
263
|
+
console.log(" {project-name} <command>");
|
|
264
|
+
console.log("\nCommands:");
|
|
265
|
+
console.log(" version Print version info");
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
main();
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### src/types/index.ts
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
// Layer 0: Core types — no internal imports allowed
|
|
276
|
+
export interface Config {
|
|
277
|
+
// Add configuration types here
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### scripts/lint-deps.ts
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
#!/usr/bin/env ts-node
|
|
285
|
+
/**
|
|
286
|
+
* Validates that imports respect the layer hierarchy.
|
|
287
|
+
*
|
|
288
|
+
* Layer 0: src/types/ — No internal imports
|
|
289
|
+
* Layer 1: src/core/ — May import types only
|
|
290
|
+
* Layer 2: src/commands/ — May import core and types
|
|
291
|
+
* Layer 3: src/index.ts — May import anything
|
|
292
|
+
*/
|
|
293
|
+
import * as fs from "fs";
|
|
294
|
+
import * as path from "path";
|
|
295
|
+
|
|
296
|
+
interface LayerRule {
|
|
297
|
+
pattern: string;
|
|
298
|
+
layer: number;
|
|
299
|
+
forbiddenImports: string[];
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const rules: LayerRule[] = [
|
|
303
|
+
{
|
|
304
|
+
pattern: "src/types/",
|
|
305
|
+
layer: 0,
|
|
306
|
+
forbiddenImports: ["../core", "../commands"],
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
pattern: "src/core/",
|
|
310
|
+
layer: 1,
|
|
311
|
+
forbiddenImports: ["../commands"],
|
|
312
|
+
},
|
|
313
|
+
];
|
|
314
|
+
|
|
315
|
+
let violations = 0;
|
|
316
|
+
|
|
317
|
+
function checkFile(filePath: string): void {
|
|
318
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
319
|
+
const lines = content.split("\n");
|
|
320
|
+
|
|
321
|
+
for (const rule of rules) {
|
|
322
|
+
if (!filePath.includes(rule.pattern)) continue;
|
|
323
|
+
|
|
324
|
+
lines.forEach((line, i) => {
|
|
325
|
+
const importMatch = line.match(/from\s+['"]([^'"]+)['"]/);
|
|
326
|
+
if (!importMatch) return;
|
|
327
|
+
|
|
328
|
+
const importPath = importMatch[1];
|
|
329
|
+
for (const forbidden of rule.forbiddenImports) {
|
|
330
|
+
if (importPath.includes(forbidden)) {
|
|
331
|
+
console.error(
|
|
332
|
+
`✗ ${filePath}:${i + 1} — Layer ${rule.layer} cannot import "${importPath}"`,
|
|
333
|
+
);
|
|
334
|
+
console.error(
|
|
335
|
+
` Fix: Move this logic to a higher layer, or pass the dependency as a parameter.`,
|
|
336
|
+
);
|
|
337
|
+
violations++;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function walkDir(dir: string): void {
|
|
345
|
+
if (!fs.existsSync(dir)) return;
|
|
346
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
347
|
+
for (const entry of entries) {
|
|
348
|
+
const fullPath = path.join(dir, entry.name);
|
|
349
|
+
if (entry.isDirectory() && entry.name !== "node_modules") {
|
|
350
|
+
walkDir(fullPath);
|
|
351
|
+
} else if (entry.name.endsWith(".ts") && !entry.name.endsWith(".test.ts")) {
|
|
352
|
+
checkFile(fullPath);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
walkDir("src");
|
|
358
|
+
|
|
359
|
+
if (violations === 0) {
|
|
360
|
+
console.log("✓ All imports follow the layer hierarchy");
|
|
361
|
+
process.exit(0);
|
|
362
|
+
} else {
|
|
363
|
+
console.error(`\n✗ Found ${violations} layer violation(s)`);
|
|
364
|
+
process.exit(1);
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### scripts/lint-quality.ts
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
#!/usr/bin/env ts-node
|
|
372
|
+
/**
|
|
373
|
+
* Validates quality rules:
|
|
374
|
+
* - File size limits (max 500 lines)
|
|
375
|
+
* - No console.log in production code (use a logger)
|
|
376
|
+
*/
|
|
377
|
+
import * as fs from "fs";
|
|
378
|
+
import * as path from "path";
|
|
379
|
+
|
|
380
|
+
const MAX_FILE_LINES = 500;
|
|
381
|
+
let violations = 0;
|
|
382
|
+
|
|
383
|
+
function checkFile(filePath: string): void {
|
|
384
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
385
|
+
const lines = content.split("\n");
|
|
386
|
+
|
|
387
|
+
// Check file size
|
|
388
|
+
if (lines.length > MAX_FILE_LINES) {
|
|
389
|
+
console.error(
|
|
390
|
+
`✗ ${filePath} has ${lines.length} lines (max ${MAX_FILE_LINES})`,
|
|
391
|
+
);
|
|
392
|
+
console.error(
|
|
393
|
+
` Fix: Split this file into smaller, focused modules.`,
|
|
394
|
+
);
|
|
395
|
+
violations++;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Check for console.log in non-test, non-index files
|
|
399
|
+
if (!filePath.includes(".test.") && !filePath.endsWith("index.ts")) {
|
|
400
|
+
lines.forEach((line, i) => {
|
|
401
|
+
if (line.match(/console\.log\(/) && !line.trim().startsWith("//")) {
|
|
402
|
+
console.error(
|
|
403
|
+
`✗ ${filePath}:${i + 1} — Use structured logger instead of console.log`,
|
|
404
|
+
);
|
|
405
|
+
console.error(
|
|
406
|
+
` Fix: Import the logger from src/utils/logger.ts and use logger.info() instead.`,
|
|
407
|
+
);
|
|
408
|
+
violations++;
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
function walkDir(dir: string): void {
|
|
415
|
+
if (!fs.existsSync(dir)) return;
|
|
416
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
417
|
+
for (const entry of entries) {
|
|
418
|
+
const fullPath = path.join(dir, entry.name);
|
|
419
|
+
if (entry.isDirectory() && entry.name !== "node_modules") {
|
|
420
|
+
walkDir(fullPath);
|
|
421
|
+
} else if (entry.name.endsWith(".ts")) {
|
|
422
|
+
checkFile(fullPath);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
walkDir("src");
|
|
428
|
+
|
|
429
|
+
if (violations === 0) {
|
|
430
|
+
console.log("✓ All quality checks passed");
|
|
431
|
+
process.exit(0);
|
|
432
|
+
} else {
|
|
433
|
+
console.error(`\n✗ Found ${violations} quality violation(s)`);
|
|
434
|
+
process.exit(1);
|
|
435
|
+
}
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
## TypeScript/Node Web API
|
|
441
|
+
|
|
442
|
+
Same as TypeScript CLI, with these additions:
|
|
443
|
+
|
|
444
|
+
### src/index.ts
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
import http from "http";
|
|
448
|
+
import { router } from "./api/router";
|
|
449
|
+
|
|
450
|
+
const PORT = process.env.PORT || 8080;
|
|
451
|
+
|
|
452
|
+
const server = http.createServer(router);
|
|
453
|
+
|
|
454
|
+
server.listen(PORT, () => {
|
|
455
|
+
console.log(`Server running on port ${PORT}`);
|
|
456
|
+
});
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
### src/api/router.ts
|
|
460
|
+
|
|
461
|
+
```typescript
|
|
462
|
+
import http from "http";
|
|
463
|
+
|
|
464
|
+
export function router(
|
|
465
|
+
req: http.IncomingMessage,
|
|
466
|
+
res: http.ServerResponse,
|
|
467
|
+
): void {
|
|
468
|
+
if (req.url === "/health" && req.method === "GET") {
|
|
469
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
470
|
+
res.end(JSON.stringify({ status: "ok" }));
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
475
|
+
res.end(JSON.stringify({ error: "Not Found" }));
|
|
476
|
+
}
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
---
|
|
480
|
+
|
|
481
|
+
## Python CLI
|
|
482
|
+
|
|
483
|
+
### pyproject.toml
|
|
484
|
+
|
|
485
|
+
```toml
|
|
486
|
+
[build-system]
|
|
487
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
488
|
+
build-backend = "setuptools.backends._legacy:_Backend"
|
|
489
|
+
|
|
490
|
+
[project]
|
|
491
|
+
name = "{project-name}"
|
|
492
|
+
version = "0.1.0"
|
|
493
|
+
description = "{description}"
|
|
494
|
+
requires-python = ">=3.10"
|
|
495
|
+
dependencies = []
|
|
496
|
+
|
|
497
|
+
[project.optional-dependencies]
|
|
498
|
+
dev = ["pytest", "ruff", "mypy"]
|
|
499
|
+
|
|
500
|
+
[project.scripts]
|
|
501
|
+
{project-name} = "{package_name}.main:main"
|
|
502
|
+
|
|
503
|
+
[tool.ruff]
|
|
504
|
+
line-length = 100
|
|
505
|
+
target-version = "py310"
|
|
506
|
+
|
|
507
|
+
[tool.mypy]
|
|
508
|
+
strict = true
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
### requirements.txt
|
|
512
|
+
|
|
513
|
+
```
|
|
514
|
+
# Production dependencies
|
|
515
|
+
|
|
516
|
+
# Dev dependencies
|
|
517
|
+
pytest>=7.0
|
|
518
|
+
ruff>=0.1.0
|
|
519
|
+
mypy>=1.0
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
### src/{package_name}/__init__.py
|
|
523
|
+
|
|
524
|
+
```python
|
|
525
|
+
"""
|
|
526
|
+
{Project Name} - {description}
|
|
527
|
+
"""
|
|
528
|
+
|
|
529
|
+
__version__ = "0.1.0"
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
### src/{package_name}/main.py
|
|
533
|
+
|
|
534
|
+
```python
|
|
535
|
+
"""Entry point for {project-name}."""
|
|
536
|
+
import sys
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
def main() -> None:
|
|
540
|
+
"""Main entry point."""
|
|
541
|
+
args = sys.argv[1:]
|
|
542
|
+
|
|
543
|
+
if not args:
|
|
544
|
+
print("{project-name} - {description}")
|
|
545
|
+
print("\nUsage:")
|
|
546
|
+
print(" {project-name} <command>")
|
|
547
|
+
print("\nCommands:")
|
|
548
|
+
print(" version Print version info")
|
|
549
|
+
return
|
|
550
|
+
|
|
551
|
+
command = args[0]
|
|
552
|
+
if command == "version":
|
|
553
|
+
print("{project-name} v0.1.0")
|
|
554
|
+
else:
|
|
555
|
+
print(f"Unknown command: {command}", file=sys.stderr)
|
|
556
|
+
sys.exit(1)
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
if __name__ == "__main__":
|
|
560
|
+
main()
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### src/{package_name}/types.py
|
|
564
|
+
|
|
565
|
+
```python
|
|
566
|
+
"""
|
|
567
|
+
Core types shared across the application.
|
|
568
|
+
Layer 0: No internal imports allowed.
|
|
569
|
+
"""
|
|
570
|
+
from dataclasses import dataclass
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
@dataclass
|
|
574
|
+
class Config:
|
|
575
|
+
"""Application configuration."""
|
|
576
|
+
pass
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
### tests/__init__.py
|
|
580
|
+
|
|
581
|
+
```python
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
### tests/test_main.py
|
|
585
|
+
|
|
586
|
+
```python
|
|
587
|
+
"""Tests for main module."""
|
|
588
|
+
from {package_name}.main import main
|
|
589
|
+
|
|
590
|
+
|
|
591
|
+
def test_main_no_args(capsys, monkeypatch):
|
|
592
|
+
"""Test main with no arguments shows usage."""
|
|
593
|
+
monkeypatch.setattr("sys.argv", ["{project-name}"])
|
|
594
|
+
main()
|
|
595
|
+
captured = capsys.readouterr()
|
|
596
|
+
assert "{project-name}" in captured.out
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
### Makefile (Python)
|
|
600
|
+
|
|
601
|
+
```makefile
|
|
602
|
+
.PHONY: install test lint lint-arch format clean
|
|
603
|
+
|
|
604
|
+
install:
|
|
605
|
+
pip install -e ".[dev]"
|
|
606
|
+
|
|
607
|
+
test:
|
|
608
|
+
pytest tests/ -v
|
|
609
|
+
|
|
610
|
+
lint: lint-arch
|
|
611
|
+
ruff check src/ tests/
|
|
612
|
+
mypy src/
|
|
613
|
+
|
|
614
|
+
lint-arch:
|
|
615
|
+
@echo "Checking architecture constraints..."
|
|
616
|
+
@python scripts/lint_deps.py
|
|
617
|
+
@python scripts/lint_quality.py
|
|
618
|
+
@echo "✓ Architecture checks passed"
|
|
619
|
+
|
|
620
|
+
format:
|
|
621
|
+
ruff format src/ tests/
|
|
622
|
+
|
|
623
|
+
clean:
|
|
624
|
+
rm -rf dist/ build/ *.egg-info __pycache__
|
|
625
|
+
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### scripts/lint_deps.py
|
|
629
|
+
|
|
630
|
+
```python
|
|
631
|
+
#!/usr/bin/env python3
|
|
632
|
+
"""
|
|
633
|
+
Validates that imports respect the layer hierarchy.
|
|
634
|
+
|
|
635
|
+
Layer 0: src/{package}/types.py — No internal imports
|
|
636
|
+
Layer 1: src/{package}/core/ — May import types only
|
|
637
|
+
Layer 2: src/{package}/api/ — May import core and types
|
|
638
|
+
Layer 3: src/{package}/main.py — May import anything
|
|
639
|
+
"""
|
|
640
|
+
import ast
|
|
641
|
+
import sys
|
|
642
|
+
from pathlib import Path
|
|
643
|
+
|
|
644
|
+
PACKAGE_NAME = "{package_name}"
|
|
645
|
+
|
|
646
|
+
LAYER_MAP = {
|
|
647
|
+
"types": 0,
|
|
648
|
+
"core": 1,
|
|
649
|
+
"api": 2,
|
|
650
|
+
"main": 3,
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
violations = []
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
def get_layer(filepath: Path) -> int:
|
|
657
|
+
"""Determine the layer of a file based on its path."""
|
|
658
|
+
parts = filepath.parts
|
|
659
|
+
for part in parts:
|
|
660
|
+
if part in LAYER_MAP:
|
|
661
|
+
return LAYER_MAP[part]
|
|
662
|
+
# main.py at package root
|
|
663
|
+
if filepath.stem == "main":
|
|
664
|
+
return 3
|
|
665
|
+
return -1
|
|
666
|
+
|
|
667
|
+
|
|
668
|
+
def check_file(filepath: Path) -> None:
|
|
669
|
+
"""Check a single file for layer violations."""
|
|
670
|
+
source_layer = get_layer(filepath)
|
|
671
|
+
if source_layer < 0:
|
|
672
|
+
return
|
|
673
|
+
|
|
674
|
+
try:
|
|
675
|
+
tree = ast.parse(filepath.read_text())
|
|
676
|
+
except SyntaxError:
|
|
677
|
+
return
|
|
678
|
+
|
|
679
|
+
for node in ast.walk(tree):
|
|
680
|
+
if isinstance(node, (ast.Import, ast.ImportFrom)):
|
|
681
|
+
module = ""
|
|
682
|
+
if isinstance(node, ast.ImportFrom) and node.module:
|
|
683
|
+
module = node.module
|
|
684
|
+
elif isinstance(node, ast.Import):
|
|
685
|
+
for alias in node.names:
|
|
686
|
+
module = alias.name
|
|
687
|
+
|
|
688
|
+
if not module.startswith(PACKAGE_NAME):
|
|
689
|
+
continue
|
|
690
|
+
|
|
691
|
+
for target, target_layer in LAYER_MAP.items():
|
|
692
|
+
if target in module and target_layer >= source_layer and target != filepath.stem:
|
|
693
|
+
violations.append(
|
|
694
|
+
f" ✗ {filepath}:{node.lineno} — "
|
|
695
|
+
f"Layer {source_layer} imports '{module}' (layer {target_layer})\n"
|
|
696
|
+
f" Fix: Move this logic to a higher layer, "
|
|
697
|
+
f"or pass the dependency as a parameter."
|
|
698
|
+
)
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
def main() -> None:
|
|
702
|
+
src_dir = Path("src") / PACKAGE_NAME
|
|
703
|
+
if not src_dir.exists():
|
|
704
|
+
print(f"Source directory {src_dir} not found")
|
|
705
|
+
sys.exit(1)
|
|
706
|
+
|
|
707
|
+
for py_file in src_dir.rglob("*.py"):
|
|
708
|
+
if "__pycache__" in str(py_file):
|
|
709
|
+
continue
|
|
710
|
+
check_file(py_file)
|
|
711
|
+
|
|
712
|
+
if not violations:
|
|
713
|
+
print("✓ All imports follow the layer hierarchy")
|
|
714
|
+
sys.exit(0)
|
|
715
|
+
else:
|
|
716
|
+
print(f"✗ Found {len(violations)} layer violation(s):\n")
|
|
717
|
+
for v in violations:
|
|
718
|
+
print(v)
|
|
719
|
+
sys.exit(1)
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
if __name__ == "__main__":
|
|
723
|
+
main()
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
### scripts/lint_quality.py
|
|
727
|
+
|
|
728
|
+
```python
|
|
729
|
+
#!/usr/bin/env python3
|
|
730
|
+
"""
|
|
731
|
+
Validates quality rules:
|
|
732
|
+
- File size limits (max 500 lines)
|
|
733
|
+
- No print() in production code (use logging)
|
|
734
|
+
"""
|
|
735
|
+
import sys
|
|
736
|
+
from pathlib import Path
|
|
737
|
+
|
|
738
|
+
MAX_FILE_LINES = 500
|
|
739
|
+
violations = []
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
def check_file(filepath: Path) -> None:
|
|
743
|
+
"""Check a single file for quality violations."""
|
|
744
|
+
lines = filepath.read_text().splitlines()
|
|
745
|
+
|
|
746
|
+
# File size check
|
|
747
|
+
if len(lines) > MAX_FILE_LINES:
|
|
748
|
+
violations.append(
|
|
749
|
+
f" ✗ {filepath} has {len(lines)} lines (max {MAX_FILE_LINES})\n"
|
|
750
|
+
f" Fix: Split this file into smaller, focused modules."
|
|
751
|
+
)
|
|
752
|
+
|
|
753
|
+
# print() in non-test, non-main files
|
|
754
|
+
if "test_" not in filepath.name and filepath.stem != "main":
|
|
755
|
+
for i, line in enumerate(lines, 1):
|
|
756
|
+
stripped = line.strip()
|
|
757
|
+
if stripped.startswith("#"):
|
|
758
|
+
continue
|
|
759
|
+
if "print(" in stripped:
|
|
760
|
+
violations.append(
|
|
761
|
+
f" ✗ {filepath}:{i} — Use logging instead of print()\n"
|
|
762
|
+
f" Fix: import logging; logger = logging.getLogger(__name__); logger.info(...)"
|
|
763
|
+
)
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
def main() -> None:
|
|
767
|
+
src_dir = Path("src")
|
|
768
|
+
if not src_dir.exists():
|
|
769
|
+
print("src/ directory not found")
|
|
770
|
+
sys.exit(1)
|
|
771
|
+
|
|
772
|
+
for py_file in src_dir.rglob("*.py"):
|
|
773
|
+
if "__pycache__" in str(py_file):
|
|
774
|
+
continue
|
|
775
|
+
check_file(py_file)
|
|
776
|
+
|
|
777
|
+
if not violations:
|
|
778
|
+
print("✓ All quality checks passed")
|
|
779
|
+
sys.exit(0)
|
|
780
|
+
else:
|
|
781
|
+
print(f"✗ Found {len(violations)} quality violation(s):\n")
|
|
782
|
+
for v in violations:
|
|
783
|
+
print(v)
|
|
784
|
+
sys.exit(1)
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
if __name__ == "__main__":
|
|
788
|
+
main()
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
---
|
|
792
|
+
|
|
793
|
+
## Python Web API
|
|
794
|
+
|
|
795
|
+
Same as Python CLI, with these additions:
|
|
796
|
+
|
|
797
|
+
### src/{package_name}/main.py (Web API version)
|
|
798
|
+
|
|
799
|
+
```python
|
|
800
|
+
"""Entry point for {project-name} web API."""
|
|
801
|
+
from http.server import HTTPServer, BaseHTTPRequestHandler
|
|
802
|
+
import json
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
class APIHandler(BaseHTTPRequestHandler):
|
|
806
|
+
"""Simple HTTP request handler."""
|
|
807
|
+
|
|
808
|
+
def do_GET(self) -> None:
|
|
809
|
+
if self.path == "/health":
|
|
810
|
+
self._json_response(200, {"status": "ok"})
|
|
811
|
+
else:
|
|
812
|
+
self._json_response(404, {"error": "Not Found"})
|
|
813
|
+
|
|
814
|
+
def _json_response(self, status: int, body: dict) -> None:
|
|
815
|
+
self.send_response(status)
|
|
816
|
+
self.send_header("Content-Type", "application/json")
|
|
817
|
+
self.end_headers()
|
|
818
|
+
self.wfile.write(json.dumps(body).encode())
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
def main() -> None:
|
|
822
|
+
"""Start the HTTP server."""
|
|
823
|
+
port = 8080
|
|
824
|
+
server = HTTPServer(("", port), APIHandler)
|
|
825
|
+
print(f"Server running on port {port}")
|
|
826
|
+
server.serve_forever()
|
|
827
|
+
|
|
828
|
+
|
|
829
|
+
if __name__ == "__main__":
|
|
830
|
+
main()
|
|
831
|
+
```
|
|
832
|
+
|
|
833
|
+
---
|
|
834
|
+
|
|
835
|
+
## Shared Templates
|
|
836
|
+
|
|
837
|
+
These files are the same regardless of tech stack. All templates use:
|
|
838
|
+
- **Hierarchical numbering** (1, 1.1, 1.2...) for stable cross-references
|
|
839
|
+
- **Placeholder source citations** (`> Sources: [`file`]()`) pointing to files that will be created
|
|
840
|
+
- **Mermaid diagrams** showing the planned architecture
|
|
841
|
+
|
|
842
|
+
### AGENTS.md Template (DeepWiki-style)
|
|
843
|
+
|
|
844
|
+
```markdown
|
|
845
|
+
# {Project Name} Agent Guide
|
|
846
|
+
|
|
847
|
+
{One-sentence description}
|
|
848
|
+
|
|
849
|
+
## 1 Quick Start
|
|
850
|
+
|
|
851
|
+
- [Architecture Overview](docs/ARCHITECTURE.md) — System design, layers, data flow
|
|
852
|
+
- [Development Setup](docs/DEVELOPMENT.md) — Build, test, environment
|
|
853
|
+
|
|
854
|
+
## 2 Architecture
|
|
855
|
+
|
|
856
|
+
| Section | Document | Description |
|
|
857
|
+
|---------|----------|-------------|
|
|
858
|
+
| 2.1 | [System Architecture](docs/ARCHITECTURE.md) | Layer hierarchy, dependency graph, data flow |
|
|
859
|
+
| 2.2 | [Design Documents](docs/design-docs/index.md) | Component deep-dives (to be added) |
|
|
860
|
+
|
|
861
|
+
## 3 Quality & Standards
|
|
862
|
+
|
|
863
|
+
| Section | Document | Description |
|
|
864
|
+
|---------|----------|-------------|
|
|
865
|
+
| 3.1 | [Code Quality](docs/QUALITY.md) | Golden principles, linter rules |
|
|
866
|
+
| 3.2 | [Testing Standards](docs/TESTING.md) | Test patterns, coverage |
|
|
867
|
+
| 3.3 | [Security Policy](docs/SECURITY.md) | Security considerations |
|
|
868
|
+
| 3.4 | [Quality Score](docs/QUALITY_SCORE.md) | Per-domain quality grades |
|
|
869
|
+
|
|
870
|
+
## 4 Development
|
|
871
|
+
|
|
872
|
+
\`\`\`bash
|
|
873
|
+
{stack-specific build commands}
|
|
874
|
+
\`\`\`
|
|
875
|
+
|
|
876
|
+
See [Development Setup](docs/DEVELOPMENT.md) for complete reference.
|
|
877
|
+
|
|
878
|
+
## 5 Execution Plans
|
|
879
|
+
|
|
880
|
+
- [Active Plans](docs/exec-plans/active/) — Work in progress
|
|
881
|
+
- [Completed Plans](docs/exec-plans/completed/) — Historical record
|
|
882
|
+
- [Tech Debt Tracker](docs/exec-plans/tech-debt-tracker.md)
|
|
883
|
+
|
|
884
|
+
## 6 Key Directories
|
|
885
|
+
|
|
886
|
+
| Directory | Layer | Purpose |
|
|
887
|
+
|-----------|-------|---------|
|
|
888
|
+
| \`{main-source-dir}/\` | L2-L3 | Application code |
|
|
889
|
+
| \`{types-dir}/\` | L0 | Type definitions |
|
|
890
|
+
| \`docs/\` | — | All documentation |
|
|
891
|
+
| \`scripts/\` | — | Linters and tooling |
|
|
892
|
+
| \`harness/\` | — | Eval and quality |
|
|
893
|
+
|
|
894
|
+
---
|
|
895
|
+
|
|
896
|
+
**Note**: This file is a navigation map (~80 lines). Details live in linked documents.
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
### docs/ARCHITECTURE.md Template (DeepWiki-style, Greenfield)
|
|
900
|
+
|
|
901
|
+
For greenfield projects, the architecture document describes the **planned** structure, with
|
|
902
|
+
Mermaid diagrams showing the intended layer hierarchy. Source citations point to files that
|
|
903
|
+
will be created by the execution plan.
|
|
904
|
+
|
|
905
|
+
```markdown
|
|
906
|
+
# Architecture
|
|
907
|
+
|
|
908
|
+
> Project initialized: {today's date}
|
|
909
|
+
> Status: Greenfield — structure defined, implementation pending
|
|
910
|
+
|
|
911
|
+
## 1 Overview
|
|
912
|
+
|
|
913
|
+
{One paragraph: what this project will do, who will use it, and the architectural approach.}
|
|
914
|
+
|
|
915
|
+
## 2 System Architecture
|
|
916
|
+
|
|
917
|
+
### 2.1 Package Dependency Graph
|
|
918
|
+
|
|
919
|
+
\`\`\`mermaid
|
|
920
|
+
graph TD
|
|
921
|
+
subgraph "Layer 2 — Entry Points"
|
|
922
|
+
CMD[cmd/]
|
|
923
|
+
end
|
|
924
|
+
subgraph "Layer 1 — Business Logic"
|
|
925
|
+
CORE[internal/core/]
|
|
926
|
+
end
|
|
927
|
+
subgraph "Layer 0 — Types"
|
|
928
|
+
TYPES[internal/types/]
|
|
929
|
+
end
|
|
930
|
+
|
|
931
|
+
CMD --> CORE
|
|
932
|
+
CORE --> TYPES
|
|
933
|
+
|
|
934
|
+
style TYPES fill:#e8f5e9
|
|
935
|
+
style CORE fill:#fff3e0
|
|
936
|
+
style CMD fill:#f3e5f5
|
|
937
|
+
\`\`\`
|
|
938
|
+
|
|
939
|
+
> Planned structure. To be enforced by: [\`scripts/lint-deps.go\`]()
|
|
940
|
+
|
|
941
|
+
### 2.2 Layer Hierarchy
|
|
942
|
+
|
|
943
|
+
| Layer | Packages | Can Import | Cannot Import | Purpose |
|
|
944
|
+
|-------|----------|------------|---------------|---------|
|
|
945
|
+
| L0 | \`internal/types/\` | stdlib only | anything internal | Shared type definitions |
|
|
946
|
+
| L1 | \`internal/core/\` | L0 | L2 | Business logic |
|
|
947
|
+
| L2 | \`cmd/\` | L0, L1 | — | CLI commands, entry points |
|
|
948
|
+
|
|
949
|
+
> Will be enforced by: [\`scripts/lint-deps.go\`]()
|
|
950
|
+
|
|
951
|
+
### 2.3 Forbidden Dependencies
|
|
952
|
+
|
|
953
|
+
| From | To | Why Forbidden |
|
|
954
|
+
|------|----|---------------|
|
|
955
|
+
| \`internal/types/\` | any internal | Types must be dependency-free |
|
|
956
|
+
| \`internal/core/\` | \`cmd/\` | Core logic must not know about CLI |
|
|
957
|
+
|
|
958
|
+
## 3 Planned Components
|
|
959
|
+
|
|
960
|
+
### 3.1 Types Package
|
|
961
|
+
|
|
962
|
+
**Purpose**: Shared type definitions used across all layers
|
|
963
|
+
**Location**: \`internal/types/types.go\`
|
|
964
|
+
|
|
965
|
+
\`\`\`go
|
|
966
|
+
// Planned structure (to be implemented)
|
|
967
|
+
package types
|
|
968
|
+
|
|
969
|
+
type Config struct {
|
|
970
|
+
// Configuration fields
|
|
971
|
+
}
|
|
972
|
+
\`\`\`
|
|
973
|
+
|
|
974
|
+
> Source: [\`internal/types/types.go\`]() (to be created)
|
|
975
|
+
|
|
976
|
+
### 3.2 Core Package
|
|
977
|
+
|
|
978
|
+
**Purpose**: Main business logic
|
|
979
|
+
**Location**: \`internal/core/core.go\`
|
|
980
|
+
|
|
981
|
+
\`\`\`mermaid
|
|
982
|
+
classDiagram
|
|
983
|
+
class Core {
|
|
984
|
+
+Process(input) Result, error
|
|
985
|
+
+Validate(input) error
|
|
986
|
+
}
|
|
987
|
+
\`\`\`
|
|
988
|
+
|
|
989
|
+
> Source: [\`internal/core/core.go\`]() (to be created)
|
|
990
|
+
|
|
991
|
+
### 3.3 CLI Commands
|
|
992
|
+
|
|
993
|
+
**Purpose**: User-facing command interface
|
|
994
|
+
**Location**: \`cmd/root.go\`
|
|
995
|
+
|
|
996
|
+
> Source: [\`cmd/root.go\`]() (to be created)
|
|
997
|
+
|
|
998
|
+
## 4 Data Flow
|
|
999
|
+
|
|
1000
|
+
### 4.1 Primary Flow
|
|
1001
|
+
|
|
1002
|
+
\`\`\`mermaid
|
|
1003
|
+
sequenceDiagram
|
|
1004
|
+
participant User
|
|
1005
|
+
participant CLI as CLI (cmd/)
|
|
1006
|
+
participant Core as Core (internal/core/)
|
|
1007
|
+
|
|
1008
|
+
User->>CLI: command args
|
|
1009
|
+
CLI->>Core: Process(args)
|
|
1010
|
+
Core-->>CLI: Result
|
|
1011
|
+
CLI-->>User: Output
|
|
1012
|
+
\`\`\`
|
|
1013
|
+
|
|
1014
|
+
## 5 Key Design Decisions
|
|
1015
|
+
|
|
1016
|
+
| # | Decision | Rationale | Alternatives Considered |
|
|
1017
|
+
|---|----------|-----------|------------------------|
|
|
1018
|
+
| 1 | Layered architecture | Enforces clean dependencies, testable | Flat structure (rejected: harder to maintain) |
|
|
1019
|
+
| 2 | Types in L0 | Shared across all layers without cycles | Types in each package (rejected: duplication) |
|
|
1020
|
+
| 3 | internal/ packages | Prevents external imports | Public packages (rejected: not needed) |
|
|
1021
|
+
|
|
1022
|
+
## 6 Module & Dependencies
|
|
1023
|
+
|
|
1024
|
+
\`\`\`
|
|
1025
|
+
module {module-path}
|
|
1026
|
+
go {version}
|
|
1027
|
+
\`\`\`
|
|
1028
|
+
|
|
1029
|
+
**External Dependencies**: None initially (boring technology principle)
|
|
1030
|
+
|
|
1031
|
+
## See Also
|
|
1032
|
+
|
|
1033
|
+
- [Development Setup](DEVELOPMENT.md) — Build and test commands
|
|
1034
|
+
- [Quality Score](QUALITY_SCORE.md) — Quality tracking
|
|
1035
|
+
```
|
|
1036
|
+
|
|
1037
|
+
### docs/PRODUCT_SENSE.md
|
|
1038
|
+
|
|
1039
|
+
```markdown
|
|
1040
|
+
# Product Sense
|
|
1041
|
+
|
|
1042
|
+
## 1 What This Project Does
|
|
1043
|
+
|
|
1044
|
+
{description}
|
|
1045
|
+
|
|
1046
|
+
## 2 Business Context
|
|
1047
|
+
|
|
1048
|
+
[Why does this project exist? What problem does it solve?]
|
|
1049
|
+
|
|
1050
|
+
## 3 Key Priorities
|
|
1051
|
+
|
|
1052
|
+
| Priority | Level | Description |
|
|
1053
|
+
|----------|-------|-------------|
|
|
1054
|
+
| Correctness | [High/Medium/Low] | [How critical is data accuracy?] |
|
|
1055
|
+
| Performance | [High/Medium/Low] | [What are latency requirements?] |
|
|
1056
|
+
| Security | [High/Medium/Low] | [What data sensitivity level?] |
|
|
1057
|
+
| Reliability | [High/Medium/Low] | [What uptime is expected?] |
|
|
1058
|
+
|
|
1059
|
+
## 4 Target Users
|
|
1060
|
+
|
|
1061
|
+
[Who uses this? What do they care about?]
|
|
1062
|
+
|
|
1063
|
+
## 5 Non-Goals
|
|
1064
|
+
|
|
1065
|
+
[What is explicitly out of scope?]
|
|
1066
|
+
```
|
|
1067
|
+
|
|
1068
|
+
### docs/QUALITY_SCORE.md
|
|
1069
|
+
|
|
1070
|
+
```markdown
|
|
1071
|
+
# Quality Score
|
|
1072
|
+
|
|
1073
|
+
Last updated: {today's date}
|
|
1074
|
+
|
|
1075
|
+
## 1 Domain Grades
|
|
1076
|
+
|
|
1077
|
+
| Domain | Grade | Issues | Trend | Notes |
|
|
1078
|
+
|--------|-------|--------|-------|-------|
|
|
1079
|
+
| Core | N/A | 0 | — | New project |
|
|
1080
|
+
|
|
1081
|
+
## 2 Architectural Layers
|
|
1082
|
+
|
|
1083
|
+
| Layer | Coverage | Lint Pass | Doc Fresh |
|
|
1084
|
+
|-------|----------|-----------|-----------|
|
|
1085
|
+
| Types (L0) | N/A | ✓ | ✓ |
|
|
1086
|
+
| Core (L1) | N/A | ✓ | ✓ |
|
|
1087
|
+
| CLI (L2) | N/A | ✓ | ✓ |
|
|
1088
|
+
|
|
1089
|
+
## 3 Golden Principles
|
|
1090
|
+
|
|
1091
|
+
1. Structured logging over raw print/log statements
|
|
1092
|
+
2. Typed errors with context
|
|
1093
|
+
3. Files under 500 lines
|
|
1094
|
+
4. Layer hierarchy enforced by linters
|
|
1095
|
+
5. All public APIs documented
|
|
1096
|
+
|
|
1097
|
+
> Enforced by: [\`scripts/lint-quality.go\`]()
|
|
1098
|
+
|
|
1099
|
+
## 4 Quality Trend
|
|
1100
|
+
|
|
1101
|
+
| Date | Overall | Notes |
|
|
1102
|
+
|------|---------|-------|
|
|
1103
|
+
| {today} | Baseline | Project initialized |
|
|
1104
|
+
```
|
|
1105
|
+
|
|
1106
|
+
### docs/TESTING.md
|
|
1107
|
+
|
|
1108
|
+
```markdown
|
|
1109
|
+
# Testing Standards
|
|
1110
|
+
|
|
1111
|
+
## 1 Test Organization
|
|
1112
|
+
|
|
1113
|
+
\`\`\`
|
|
1114
|
+
tests/
|
|
1115
|
+
├── unit/ — Fast, isolated tests
|
|
1116
|
+
├── integration/ — Tests with real dependencies
|
|
1117
|
+
└── fixtures/ — Shared test data
|
|
1118
|
+
\`\`\`
|
|
1119
|
+
|
|
1120
|
+
## 2 Running Tests
|
|
1121
|
+
|
|
1122
|
+
{stack-specific commands}
|
|
1123
|
+
|
|
1124
|
+
## 3 Test Patterns
|
|
1125
|
+
|
|
1126
|
+
### 3.1 Unit Tests
|
|
1127
|
+
- Test one thing per test
|
|
1128
|
+
- Use descriptive names: \`test_<scenario>_<expected_result>\`
|
|
1129
|
+
- Mock external dependencies
|
|
1130
|
+
|
|
1131
|
+
### 3.2 Integration Tests
|
|
1132
|
+
- Test real interactions between components
|
|
1133
|
+
- Use test fixtures for reproducible state
|
|
1134
|
+
- Clean up after each test
|
|
1135
|
+
|
|
1136
|
+
## 4 Coverage Goals
|
|
1137
|
+
|
|
1138
|
+
| Component | Target | Current |
|
|
1139
|
+
|-----------|--------|---------|
|
|
1140
|
+
| Core logic | 80% | N/A |
|
|
1141
|
+
| CLI commands | 70% | N/A |
|
|
1142
|
+
| Utils | 60% | N/A |
|
|
1143
|
+
```
|
|
1144
|
+
|
|
1145
|
+
### docs/SECURITY.md
|
|
1146
|
+
|
|
1147
|
+
```markdown
|
|
1148
|
+
# Security Policy
|
|
1149
|
+
|
|
1150
|
+
## 1 Principles
|
|
1151
|
+
|
|
1152
|
+
1. Never commit secrets (API keys, passwords, tokens)
|
|
1153
|
+
2. Validate all external input
|
|
1154
|
+
3. Use parameterized queries for database access
|
|
1155
|
+
4. Log security-relevant events
|
|
1156
|
+
5. Keep dependencies updated
|
|
1157
|
+
|
|
1158
|
+
## 2 Sensitive Files
|
|
1159
|
+
|
|
1160
|
+
Never commit these:
|
|
1161
|
+
- \`.env\` files
|
|
1162
|
+
- \`credentials.json\`
|
|
1163
|
+
- Private keys (\`*.pem\`, \`*.key\`)
|
|
1164
|
+
- Database dumps
|
|
1165
|
+
|
|
1166
|
+
## 3 Input Validation
|
|
1167
|
+
|
|
1168
|
+
All user input must be validated before processing:
|
|
1169
|
+
- Type checking
|
|
1170
|
+
- Length limits
|
|
1171
|
+
- Character allowlists where appropriate
|
|
1172
|
+
|
|
1173
|
+
## 4 Dependency Management
|
|
1174
|
+
|
|
1175
|
+
- Review new dependencies before adding
|
|
1176
|
+
- Keep dependencies updated regularly
|
|
1177
|
+
- Audit for known vulnerabilities
|
|
1178
|
+
```
|
|
1179
|
+
|
|
1180
|
+
### docs/DEVELOPMENT.md (Go version)
|
|
1181
|
+
|
|
1182
|
+
```markdown
|
|
1183
|
+
# Development Setup
|
|
1184
|
+
|
|
1185
|
+
## 1 Prerequisites
|
|
1186
|
+
|
|
1187
|
+
- Go 1.22+
|
|
1188
|
+
- make
|
|
1189
|
+
|
|
1190
|
+
## 2 Quick Start
|
|
1191
|
+
|
|
1192
|
+
\`\`\`bash
|
|
1193
|
+
git clone {repo-url}
|
|
1194
|
+
cd {project-name}
|
|
1195
|
+
make build
|
|
1196
|
+
\`\`\`
|
|
1197
|
+
|
|
1198
|
+
## 3 Build Commands
|
|
1199
|
+
|
|
1200
|
+
| Command | Description | Duration |
|
|
1201
|
+
|---------|-------------|----------|
|
|
1202
|
+
| \`make build\` | Build the binary | ~5s |
|
|
1203
|
+
| \`make test\` | Run all tests | ~10s |
|
|
1204
|
+
| \`make lint\` | Run all linters | ~5s |
|
|
1205
|
+
| \`make lint-arch\` | Run architecture linters only | ~3s |
|
|
1206
|
+
| \`make clean\` | Remove build artifacts | ~1s |
|
|
1207
|
+
|
|
1208
|
+
## 4 Project Structure
|
|
1209
|
+
|
|
1210
|
+
\`\`\`
|
|
1211
|
+
.
|
|
1212
|
+
├── cmd/ — CLI commands (Layer 2)
|
|
1213
|
+
├── internal/ — Private packages
|
|
1214
|
+
│ ├── types/ — Core types (Layer 0)
|
|
1215
|
+
│ └── core/ — Business logic (Layer 1)
|
|
1216
|
+
├── docs/ — Documentation
|
|
1217
|
+
├── scripts/ — Linters and tools
|
|
1218
|
+
└── harness/ — Eval and quality
|
|
1219
|
+
\`\`\`
|
|
1220
|
+
|
|
1221
|
+
## 5 Environment Variables
|
|
1222
|
+
|
|
1223
|
+
| Variable | Default | Required | Description |
|
|
1224
|
+
|----------|---------|----------|-------------|
|
|
1225
|
+
| (none yet) | | | |
|
|
1226
|
+
```
|
|
1227
|
+
|
|
1228
|
+
### docs/design-docs/index.md
|
|
1229
|
+
|
|
1230
|
+
```markdown
|
|
1231
|
+
# Design Documents Index
|
|
1232
|
+
|
|
1233
|
+
| Document | Status | Last Updated | Description |
|
|
1234
|
+
|----------|--------|-------------|-------------|
|
|
1235
|
+
| (none yet) | | | |
|
|
1236
|
+
|
|
1237
|
+
## How to Add a Design Doc
|
|
1238
|
+
|
|
1239
|
+
1. Create a new file: `docs/design-docs/{component-name}.md`
|
|
1240
|
+
2. Use the template from the project's SKILL reference
|
|
1241
|
+
3. Add an entry to this index
|
|
1242
|
+
4. Link from AGENTS.md if it's a major component
|
|
1243
|
+
```
|
|
1244
|
+
|
|
1245
|
+
### docs/exec-plans/tech-debt-tracker.md
|
|
1246
|
+
|
|
1247
|
+
```markdown
|
|
1248
|
+
# Tech Debt Tracker
|
|
1249
|
+
|
|
1250
|
+
## Active Debt
|
|
1251
|
+
|
|
1252
|
+
| ID | Description | Priority | Owner | Created |
|
|
1253
|
+
|----|-------------|----------|-------|---------|
|
|
1254
|
+
| (none yet) | | | | |
|
|
1255
|
+
|
|
1256
|
+
## Resolved Debt
|
|
1257
|
+
|
|
1258
|
+
| ID | Description | Resolution | Date |
|
|
1259
|
+
|----|-------------|-----------|------|
|
|
1260
|
+
| (none yet) | | | |
|
|
1261
|
+
|
|
1262
|
+
## How to Track Debt
|
|
1263
|
+
|
|
1264
|
+
When you notice tech debt during development:
|
|
1265
|
+
1. Add a row to the Active Debt table
|
|
1266
|
+
2. Assign a priority (P0-P3)
|
|
1267
|
+
3. Reference it in the relevant execution plan if applicable
|
|
1268
|
+
```
|
|
1269
|
+
|
|
1270
|
+
### docs/references/index.md
|
|
1271
|
+
|
|
1272
|
+
```markdown
|
|
1273
|
+
# Reference Documents Index
|
|
1274
|
+
|
|
1275
|
+
| Document | Description | Last Updated |
|
|
1276
|
+
|----------|-------------|-------------|
|
|
1277
|
+
| (none yet) | | |
|
|
1278
|
+
|
|
1279
|
+
## Adding References
|
|
1280
|
+
|
|
1281
|
+
Reference documents provide agent-readable summaries of external dependencies, APIs, and schemas.
|
|
1282
|
+
|
|
1283
|
+
Format: `{dependency-name}-llms.txt` style — concise, focused on API surface and common patterns.
|
|
1284
|
+
```
|
|
1285
|
+
|
|
1286
|
+
### .github/workflows/ci.yml (Go version)
|
|
1287
|
+
|
|
1288
|
+
```yaml
|
|
1289
|
+
name: CI
|
|
1290
|
+
|
|
1291
|
+
on:
|
|
1292
|
+
push:
|
|
1293
|
+
branches: [main]
|
|
1294
|
+
pull_request:
|
|
1295
|
+
branches: [main]
|
|
1296
|
+
|
|
1297
|
+
jobs:
|
|
1298
|
+
build:
|
|
1299
|
+
runs-on: ubuntu-latest
|
|
1300
|
+
steps:
|
|
1301
|
+
- uses: actions/checkout@v4
|
|
1302
|
+
|
|
1303
|
+
- uses: actions/setup-go@v5
|
|
1304
|
+
with:
|
|
1305
|
+
go-version: '1.22'
|
|
1306
|
+
|
|
1307
|
+
- name: Build
|
|
1308
|
+
run: go build ./...
|
|
1309
|
+
|
|
1310
|
+
- name: Test
|
|
1311
|
+
run: go test ./...
|
|
1312
|
+
|
|
1313
|
+
- name: Lint Architecture
|
|
1314
|
+
run: |
|
|
1315
|
+
go run scripts/lint-deps.go
|
|
1316
|
+
go run scripts/lint-quality.go
|
|
1317
|
+
```
|
|
1318
|
+
|
|
1319
|
+
### .github/workflows/ci.yml (TypeScript version)
|
|
1320
|
+
|
|
1321
|
+
```yaml
|
|
1322
|
+
name: CI
|
|
1323
|
+
|
|
1324
|
+
on:
|
|
1325
|
+
push:
|
|
1326
|
+
branches: [main]
|
|
1327
|
+
pull_request:
|
|
1328
|
+
branches: [main]
|
|
1329
|
+
|
|
1330
|
+
jobs:
|
|
1331
|
+
build:
|
|
1332
|
+
runs-on: ubuntu-latest
|
|
1333
|
+
steps:
|
|
1334
|
+
- uses: actions/checkout@v4
|
|
1335
|
+
|
|
1336
|
+
- uses: actions/setup-node@v4
|
|
1337
|
+
with:
|
|
1338
|
+
node-version: '20'
|
|
1339
|
+
|
|
1340
|
+
- name: Install
|
|
1341
|
+
run: npm install
|
|
1342
|
+
|
|
1343
|
+
- name: Build
|
|
1344
|
+
run: npm run build
|
|
1345
|
+
|
|
1346
|
+
- name: Test
|
|
1347
|
+
run: npm test
|
|
1348
|
+
|
|
1349
|
+
- name: Lint
|
|
1350
|
+
run: npm run lint
|
|
1351
|
+
```
|
|
1352
|
+
|
|
1353
|
+
### .github/workflows/ci.yml (Python version)
|
|
1354
|
+
|
|
1355
|
+
```yaml
|
|
1356
|
+
name: CI
|
|
1357
|
+
|
|
1358
|
+
on:
|
|
1359
|
+
push:
|
|
1360
|
+
branches: [main]
|
|
1361
|
+
pull_request:
|
|
1362
|
+
branches: [main]
|
|
1363
|
+
|
|
1364
|
+
jobs:
|
|
1365
|
+
build:
|
|
1366
|
+
runs-on: ubuntu-latest
|
|
1367
|
+
steps:
|
|
1368
|
+
- uses: actions/checkout@v4
|
|
1369
|
+
|
|
1370
|
+
- uses: actions/setup-python@v5
|
|
1371
|
+
with:
|
|
1372
|
+
python-version: '3.12'
|
|
1373
|
+
|
|
1374
|
+
- name: Install
|
|
1375
|
+
run: pip install -e ".[dev]"
|
|
1376
|
+
|
|
1377
|
+
- name: Test
|
|
1378
|
+
run: pytest tests/ -v
|
|
1379
|
+
|
|
1380
|
+
- name: Lint
|
|
1381
|
+
run: |
|
|
1382
|
+
ruff check src/ tests/
|
|
1383
|
+
python scripts/lint_deps.py
|
|
1384
|
+
python scripts/lint_quality.py
|
|
1385
|
+
```
|