Skip to content

Commit be4913d

Browse files
authored
Merge pull request #57 from gpolanco/feat/v2-bridge-refactor
feat: dev-workflows v2 — multi-file compilation, .agents/ distribution, global scope, visual overhaul, registry
2 parents a61e15b + 35efaa9 commit be4913d

60 files changed

Lines changed: 5826 additions & 849 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Generate Registry
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- content/**
9+
paths-ignore:
10+
- content/registry.json
11+
12+
permissions:
13+
contents: write
14+
15+
jobs:
16+
generate-registry:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v4
21+
22+
- name: Setup Node
23+
uses: actions/setup-node@v4
24+
with:
25+
node-version: 22
26+
27+
- name: Generate registry artifact
28+
run: node scripts/generate-registry.js
29+
30+
- name: Commit registry updates
31+
run: |
32+
if git diff --quiet -- content/registry.json; then
33+
echo "No registry changes detected"
34+
exit 0
35+
fi
36+
37+
git config user.name "github-actions[bot]"
38+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
39+
git add content/registry.json
40+
git commit -m "chore: regenerate registry.json"
41+
git push

content/registry.json

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
{
2+
"version": 1,
3+
"generated_at": "2026-04-12T15:46:19.045Z",
4+
"rules": [
5+
{
6+
"path": "css/tailwind",
7+
"name": "tailwind",
8+
"description": "Utility-first Tailwind CSS conventions and design tokens",
9+
"version": "0.1.0",
10+
"scope": "conventions",
11+
"tags": [
12+
"tailwind",
13+
"css",
14+
"styling"
15+
],
16+
"size_bytes": 874
17+
},
18+
{
19+
"path": "frontend/accessibility",
20+
"name": "accessibility",
21+
"description": "Accessibility best practices for AI coding agents",
22+
"version": "0.1.0",
23+
"scope": "conventions",
24+
"tags": [
25+
"frontend",
26+
"accessibility",
27+
"a11y",
28+
"html"
29+
],
30+
"size_bytes": 2781
31+
},
32+
{
33+
"path": "frontend/design-guidelines",
34+
"name": "design-guidelines",
35+
"description": "UI design principles for AI coding agents",
36+
"version": "0.1.0",
37+
"scope": "design",
38+
"tags": [
39+
"frontend",
40+
"design",
41+
"ui",
42+
"ux"
43+
],
44+
"size_bytes": 3476
45+
},
46+
{
47+
"path": "frontend/performance",
48+
"name": "performance",
49+
"description": "Frontend performance optimization rules",
50+
"version": "0.1.0",
51+
"scope": "performance",
52+
"tags": [
53+
"frontend",
54+
"performance",
55+
"core-web-vitals"
56+
],
57+
"size_bytes": 2558
58+
},
59+
{
60+
"path": "javascript/nextjs",
61+
"name": "nextjs",
62+
"description": "Next.js App Router patterns and React Server Components",
63+
"version": "0.1.0",
64+
"scope": "architecture",
65+
"tags": [
66+
"nextjs",
67+
"react",
68+
"app-router",
69+
"rsc"
70+
],
71+
"size_bytes": 1250
72+
},
73+
{
74+
"path": "javascript/react",
75+
"name": "react",
76+
"description": "React conventions and best practices for AI coding agents",
77+
"version": "0.1.0",
78+
"scope": "conventions",
79+
"tags": [
80+
"react",
81+
"frontend",
82+
"components",
83+
"hooks"
84+
],
85+
"size_bytes": 1314
86+
},
87+
{
88+
"path": "security/auth-patterns",
89+
"name": "auth-patterns",
90+
"description": "Authentication and authorization best practices",
91+
"version": "0.1.0",
92+
"scope": "security",
93+
"tags": [
94+
"security",
95+
"auth",
96+
"authentication",
97+
"authorization"
98+
],
99+
"size_bytes": 2762
100+
},
101+
{
102+
"path": "security/supabase-rls",
103+
"name": "supabase-rls",
104+
"description": "Supabase Row-Level Security enforcement and auth patterns",
105+
"version": "0.1.0",
106+
"scope": "security",
107+
"tags": [
108+
"supabase",
109+
"rls",
110+
"security",
111+
"database"
112+
],
113+
"size_bytes": 958
114+
},
115+
{
116+
"path": "testing/vitest",
117+
"name": "vitest",
118+
"description": "Vitest testing patterns and best practices",
119+
"version": "0.1.0",
120+
"scope": "testing",
121+
"tags": [
122+
"vitest",
123+
"testing",
124+
"unit-tests"
125+
],
126+
"size_bytes": 1174
127+
},
128+
{
129+
"path": "typescript/strict",
130+
"name": "strict",
131+
"description": "Strict TypeScript conventions for professional codebases",
132+
"version": "0.1.0",
133+
"scope": "conventions",
134+
"tags": [
135+
"typescript",
136+
"strict",
137+
"types"
138+
],
139+
"size_bytes": 1124
140+
},
141+
{
142+
"path": "workflow/debugging",
143+
"name": "debugging",
144+
"description": "Systematic debugging methodology for AI coding agents",
145+
"version": "0.1.0",
146+
"scope": "workflow",
147+
"tags": [
148+
"workflow",
149+
"debugging",
150+
"methodology"
151+
],
152+
"size_bytes": 2464
153+
},
154+
{
155+
"path": "workflow/git-conventions",
156+
"name": "git-conventions",
157+
"description": "Git workflow and commit conventions",
158+
"version": "0.1.0",
159+
"scope": "workflow",
160+
"tags": [
161+
"git",
162+
"workflow",
163+
"conventions"
164+
],
165+
"size_bytes": 2010
166+
},
167+
{
168+
"path": "workflow/spec-driven",
169+
"name": "spec-driven",
170+
"description": "Spec-driven development workflow: spec, plan, build, ship",
171+
"version": "0.1.0",
172+
"scope": "workflow",
173+
"tags": [
174+
"workflow",
175+
"spec-driven",
176+
"methodology"
177+
],
178+
"size_bytes": 1441
179+
}
180+
],
181+
"assets": {
182+
"commands": [],
183+
"templates": [],
184+
"hooks": [],
185+
"presets": []
186+
}
187+
}

packages/cli/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@
5252
"test:e2e": "tsc && tsc -p tsconfig.test.json && find .test-build/tests/e2e -name '*.test.js' -exec node --test {} +"
5353
},
5454
"dependencies": {
55-
"@inquirer/prompts": "^7.0.0",
55+
"@clack/prompts": "^0.9.0",
5656
"chokidar": "^3.6.0",
5757
"commander": "^13.0.0",
5858
"yaml": "^2.7.0",
59-
"chalk": "^5.4.0"
59+
"picocolors": "^1.1.0"
6060
},
6161
"devDependencies": {
6262
"typescript": "^5.7.0",

packages/cli/src/bridges/claude.ts

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,51 @@
1-
import type { Bridge, Rule, ProjectConfig } from './types.js';
1+
import type { DirectoryBridge, Rule, ProjectConfig, ScopeMetadata } from './types.js';
22
import { filterRules, groupByScope, formatScopeHeading } from '../core/helpers.js';
3+
import { scopeToFilename } from '../core/scope-filename.js';
4+
5+
const GENERATED_COMMENT = '<!-- Generated by dev-workflows. Do not edit manually. -->';
6+
7+
function buildFrontmatter(metadata?: ScopeMetadata): string {
8+
if (!metadata?.paths || metadata.paths.length === 0) {
9+
return '';
10+
}
311

4-
function buildMarkdown(rules: Rule[]): string {
512
const lines: string[] = [
6-
'# Project Rules',
13+
'---',
14+
'paths:',
715
];
16+
for (const p of metadata.paths) {
17+
lines.push(` - "${p}"`);
18+
}
19+
lines.push('---');
820

9-
const filtered = filterRules(rules);
10-
const grouped = groupByScope(filtered);
11-
12-
for (const [scope, scopeRules] of grouped) {
13-
lines.push('', `## ${formatScopeHeading(scope)}`);
14-
lines.push('');
15-
for (const rule of scopeRules) {
16-
const contentLines = rule.content.split('\n');
17-
const first = contentLines[0];
18-
if (first !== undefined) {
19-
lines.push(`- ${first}`);
20-
}
21-
for (let i = 1; i < contentLines.length; i++) {
22-
const line = contentLines[i];
23-
if (line !== undefined) {
24-
lines.push(` ${line}`);
25-
}
21+
return lines.join('\n');
22+
}
23+
24+
function buildScopeMarkdown(scope: string, rules: Rule[]): string {
25+
const lines: string[] = [];
26+
27+
// Get metadata from the first rule in the scope (all rules in a scope share metadata)
28+
const metadata = rules[0]?.metadata;
29+
const frontmatter = buildFrontmatter(metadata);
30+
31+
if (frontmatter) {
32+
lines.push(frontmatter);
33+
}
34+
35+
lines.push(GENERATED_COMMENT);
36+
lines.push(`# ${formatScopeHeading(scope)}`);
37+
lines.push('');
38+
39+
for (const rule of rules) {
40+
const contentLines = rule.content.split('\n');
41+
const first = contentLines[0];
42+
if (first !== undefined) {
43+
lines.push(`- ${first}`);
44+
}
45+
for (let i = 1; i < contentLines.length; i++) {
46+
const line = contentLines[i];
47+
if (line !== undefined) {
48+
lines.push(` ${line}`);
2649
}
2750
}
2851
}
@@ -31,14 +54,25 @@ function buildMarkdown(rules: Rule[]): string {
3154
return lines.join('\n');
3255
}
3356

34-
export const claudeBridge: Bridge = {
57+
export const claudeBridge: DirectoryBridge = {
3558
id: 'claude',
36-
outputPaths: ['CLAUDE.md'],
37-
usesMarkers: true,
59+
kind: 'directory',
60+
outputDir: '.claude/rules',
61+
filePrefix: 'dwf-',
62+
fileExtension: '.md',
3863

3964
compile(rules: Rule[], _config: ProjectConfig): Map<string, string> {
4065
const output = new Map<string, string>();
41-
output.set('CLAUDE.md', buildMarkdown(rules));
66+
67+
const filtered = filterRules(rules);
68+
const grouped = groupByScope(filtered);
69+
70+
for (const [scope, scopeRules] of grouped) {
71+
const filename = scopeToFilename(scope, 'dwf-', '.md');
72+
const key = `.claude/rules/${filename}`;
73+
output.set(key, buildScopeMarkdown(scope, scopeRules));
74+
}
75+
4276
return output;
4377
},
4478
};

packages/cli/src/bridges/copilot.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Bridge, Rule, ProjectConfig } from './types.js';
1+
import type { MarkerBridge, Rule, ProjectConfig } from './types.js';
22
import { filterRules, groupByScope, formatScopeHeading } from '../core/helpers.js';
33

44
function buildMarkdown(rules: Rule[]): string {
@@ -31,8 +31,9 @@ function buildMarkdown(rules: Rule[]): string {
3131
return lines.join('\n');
3232
}
3333

34-
export const copilotBridge: Bridge = {
34+
export const copilotBridge: MarkerBridge = {
3535
id: 'copilot',
36+
kind: 'marker',
3637
outputPaths: ['.github/copilot-instructions.md'],
3738
usesMarkers: true,
3839

0 commit comments

Comments
 (0)