dev-workflows 0.1.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.
Files changed (80) hide show
  1. package/bin/devw.js +2 -0
  2. package/content/blocks/nextjs-approuter.yml +37 -0
  3. package/content/blocks/react-conventions.yml +36 -0
  4. package/content/blocks/supabase-rls.yml +30 -0
  5. package/content/blocks/tailwind.yml +28 -0
  6. package/content/blocks/testing-basics.yml +36 -0
  7. package/content/blocks/typescript-strict.yml +33 -0
  8. package/dist/blocks/installer.d.ts +4 -0
  9. package/dist/blocks/installer.d.ts.map +1 -0
  10. package/dist/blocks/installer.js +119 -0
  11. package/dist/blocks/installer.js.map +1 -0
  12. package/dist/blocks/registry.d.ts +18 -0
  13. package/dist/blocks/registry.d.ts.map +1 -0
  14. package/dist/blocks/registry.js +85 -0
  15. package/dist/blocks/registry.js.map +1 -0
  16. package/dist/bridges/claude.d.ts +3 -0
  17. package/dist/bridges/claude.d.ts.map +1 -0
  18. package/dist/bridges/claude.js +54 -0
  19. package/dist/bridges/claude.js.map +1 -0
  20. package/dist/bridges/cursor.d.ts +3 -0
  21. package/dist/bridges/cursor.d.ts.map +1 -0
  22. package/dist/bridges/cursor.js +61 -0
  23. package/dist/bridges/cursor.js.map +1 -0
  24. package/dist/bridges/gemini.d.ts +3 -0
  25. package/dist/bridges/gemini.d.ts.map +1 -0
  26. package/dist/bridges/gemini.js +54 -0
  27. package/dist/bridges/gemini.js.map +1 -0
  28. package/dist/bridges/types.d.ts +25 -0
  29. package/dist/bridges/types.d.ts.map +1 -0
  30. package/dist/bridges/types.js +2 -0
  31. package/dist/bridges/types.js.map +1 -0
  32. package/dist/commands/add.d.ts +7 -0
  33. package/dist/commands/add.d.ts.map +1 -0
  34. package/dist/commands/add.js +64 -0
  35. package/dist/commands/add.js.map +1 -0
  36. package/dist/commands/compile.d.ts +9 -0
  37. package/dist/commands/compile.d.ts.map +1 -0
  38. package/dist/commands/compile.js +130 -0
  39. package/dist/commands/compile.js.map +1 -0
  40. package/dist/commands/doctor.d.ts +16 -0
  41. package/dist/commands/doctor.d.ts.map +1 -0
  42. package/dist/commands/doctor.js +229 -0
  43. package/dist/commands/doctor.js.map +1 -0
  44. package/dist/commands/init.d.ts +8 -0
  45. package/dist/commands/init.d.ts.map +1 -0
  46. package/dist/commands/init.js +159 -0
  47. package/dist/commands/init.js.map +1 -0
  48. package/dist/commands/list.d.ts +3 -0
  49. package/dist/commands/list.d.ts.map +1 -0
  50. package/dist/commands/list.js +106 -0
  51. package/dist/commands/list.js.map +1 -0
  52. package/dist/commands/remove.d.ts +3 -0
  53. package/dist/commands/remove.d.ts.map +1 -0
  54. package/dist/commands/remove.js +40 -0
  55. package/dist/commands/remove.js.map +1 -0
  56. package/dist/core/hash.d.ts +5 -0
  57. package/dist/core/hash.d.ts.map +1 -0
  58. package/dist/core/hash.js +24 -0
  59. package/dist/core/hash.js.map +1 -0
  60. package/dist/core/markers.d.ts +4 -0
  61. package/dist/core/markers.d.ts.map +1 -0
  62. package/dist/core/markers.js +18 -0
  63. package/dist/core/markers.js.map +1 -0
  64. package/dist/core/parser.d.ts +4 -0
  65. package/dist/core/parser.d.ts.map +1 -0
  66. package/dist/core/parser.js +82 -0
  67. package/dist/core/parser.js.map +1 -0
  68. package/dist/index.d.ts +4 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.js +21 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/utils/detect-tools.d.ts +8 -0
  73. package/dist/utils/detect-tools.d.ts.map +1 -0
  74. package/dist/utils/detect-tools.js +28 -0
  75. package/dist/utils/detect-tools.js.map +1 -0
  76. package/dist/utils/prompt.d.ts +3 -0
  77. package/dist/utils/prompt.d.ts.map +1 -0
  78. package/dist/utils/prompt.js +21 -0
  79. package/dist/utils/prompt.js.map +1 -0
  80. package/package.json +42 -0
package/bin/devw.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import '../dist/index.js';
@@ -0,0 +1,37 @@
1
+ id: nextjs-approuter
2
+ name: "Next.js App Router"
3
+ description: "App Router patterns, RSC, and server actions"
4
+ version: "0.1.0"
5
+
6
+ rules:
7
+ - id: nextjs-use-client-minimal
8
+ scope: architecture
9
+ severity: error
10
+ content: |
11
+ Minimize "use client" directives. Default to Server Components.
12
+ Only add "use client" when the component needs browser APIs,
13
+ event handlers, or React hooks that require client state.
14
+
15
+ - id: nextjs-server-actions
16
+ scope: architecture
17
+ severity: warning
18
+ content: |
19
+ Prefer server actions for form submissions and data mutations.
20
+ Define them with "use server" in a separate file or at the
21
+ top of an async function.
22
+
23
+ - id: nextjs-route-segments
24
+ scope: architecture
25
+ severity: error
26
+ content: |
27
+ Follow the App Router file conventions: page.tsx, layout.tsx,
28
+ loading.tsx, error.tsx, not-found.tsx. Do not create custom
29
+ routing abstractions.
30
+
31
+ - id: nextjs-no-client-fetch
32
+ scope: architecture
33
+ severity: warning
34
+ content: |
35
+ Fetch data in Server Components or server actions, not in
36
+ client components with useEffect. Use React Suspense for
37
+ loading states.
@@ -0,0 +1,36 @@
1
+ id: react-conventions
2
+ name: "React Conventions"
3
+ description: "Hooks rules, component patterns, and naming conventions"
4
+ version: "0.1.0"
5
+
6
+ rules:
7
+ - id: react-hooks-rules
8
+ scope: conventions
9
+ severity: error
10
+ content: |
11
+ Follow the Rules of Hooks: only call hooks at the top level,
12
+ never inside conditions or loops. Custom hooks must start
13
+ with "use".
14
+
15
+ - id: react-component-naming
16
+ scope: conventions
17
+ severity: error
18
+ content: |
19
+ Use PascalCase for component names and their files.
20
+ Use camelCase for hook files prefixed with "use"
21
+ (e.g. useAuth.ts).
22
+
23
+ - id: react-prefer-composition
24
+ scope: conventions
25
+ severity: warning
26
+ content: |
27
+ Prefer composition over prop drilling. Use children,
28
+ render props, or context for shared behavior rather than
29
+ deeply nested prop chains.
30
+
31
+ - id: react-no-inline-styles
32
+ scope: conventions
33
+ severity: warning
34
+ content: |
35
+ Avoid inline styles. Use CSS modules, Tailwind classes,
36
+ or styled-components for styling.
@@ -0,0 +1,30 @@
1
+ id: supabase-rls
2
+ name: "Supabase RLS"
3
+ description: "Row-Level Security enforcement and auth patterns"
4
+ version: "0.1.0"
5
+
6
+ rules:
7
+ - id: supabase-rls-required
8
+ scope: security
9
+ severity: error
10
+ content: |
11
+ Every new table must have RLS policies before merging.
12
+ Enable RLS with ALTER TABLE ... ENABLE ROW LEVEL SECURITY
13
+ and create at least one policy per operation (SELECT, INSERT,
14
+ UPDATE, DELETE) as needed.
15
+
16
+ - id: supabase-auth-context
17
+ scope: security
18
+ severity: error
19
+ content: |
20
+ Always use auth.uid() in RLS policies to scope data to
21
+ the authenticated user. Never rely on client-provided
22
+ user IDs in queries.
23
+
24
+ - id: supabase-no-service-role-client
25
+ scope: security
26
+ severity: error
27
+ content: |
28
+ Never expose the service_role key to the client.
29
+ Use the anon key in browser code and the service_role key
30
+ only in server-side or admin contexts.
@@ -0,0 +1,28 @@
1
+ id: tailwind
2
+ name: "Tailwind CSS"
3
+ description: "Utility-first CSS conventions and design tokens"
4
+ version: "0.1.0"
5
+
6
+ rules:
7
+ - id: tailwind-utility-first
8
+ scope: conventions
9
+ severity: error
10
+ content: |
11
+ Use Tailwind utility classes for all styling. Do not write
12
+ custom CSS unless absolutely necessary (e.g. complex
13
+ animations or third-party overrides).
14
+
15
+ - id: tailwind-design-tokens
16
+ scope: conventions
17
+ severity: warning
18
+ content: |
19
+ Use Tailwind's design tokens (spacing, colors, typography)
20
+ from the theme config. Avoid arbitrary values like
21
+ w-[137px]; prefer the closest token.
22
+
23
+ - id: tailwind-no-apply
24
+ scope: conventions
25
+ severity: warning
26
+ content: |
27
+ Avoid @apply in CSS files. Extract reusable patterns into
28
+ React components instead of creating CSS abstractions.
@@ -0,0 +1,36 @@
1
+ id: testing-basics
2
+ name: "Testing Basics"
3
+ description: "Test naming, coverage expectations, and mock patterns"
4
+ version: "0.1.0"
5
+
6
+ rules:
7
+ - id: testing-descriptive-names
8
+ scope: testing
9
+ severity: error
10
+ content: |
11
+ Use descriptive test names that explain the expected behavior.
12
+ Follow the pattern: "should [expected behavior] when [condition]".
13
+
14
+ - id: testing-arrange-act-assert
15
+ scope: testing
16
+ severity: warning
17
+ content: |
18
+ Structure tests with Arrange-Act-Assert (AAA) pattern.
19
+ Separate setup, execution, and verification into distinct
20
+ sections for readability.
21
+
22
+ - id: testing-no-implementation-details
23
+ scope: testing
24
+ severity: warning
25
+ content: |
26
+ Test behavior, not implementation details. Avoid asserting
27
+ on internal state, private methods, or specific function calls
28
+ unless testing integration points.
29
+
30
+ - id: testing-mock-boundaries
31
+ scope: testing
32
+ severity: warning
33
+ content: |
34
+ Only mock at system boundaries: network requests, databases,
35
+ file system, and third-party services. Do not mock internal
36
+ modules or utility functions.
@@ -0,0 +1,33 @@
1
+ id: typescript-strict
2
+ name: "TypeScript Strict"
3
+ description: "Strict TypeScript conventions for professional codebases"
4
+ version: "0.1.0"
5
+
6
+ rules:
7
+ - id: ts-strict-no-any
8
+ scope: conventions
9
+ severity: error
10
+ content: |
11
+ Never use `any`. Use `unknown` when the type is truly unknown,
12
+ then narrow with type guards.
13
+
14
+ - id: ts-strict-explicit-returns
15
+ scope: conventions
16
+ severity: warning
17
+ content: |
18
+ Always declare explicit return types on exported functions.
19
+ Inferred types are fine for internal/private functions.
20
+
21
+ - id: ts-strict-no-enums
22
+ scope: conventions
23
+ severity: warning
24
+ content: |
25
+ Prefer union types over enums.
26
+ Use `as const` objects when you need runtime values.
27
+
28
+ - id: ts-strict-no-non-null-assertion
29
+ scope: conventions
30
+ severity: error
31
+ content: |
32
+ Never use non-null assertion (!). Handle null/undefined explicitly
33
+ with optional chaining, nullish coalescing, or type guards.
@@ -0,0 +1,4 @@
1
+ import type { BlockDefinition } from './registry.js';
2
+ export declare function installBlock(cwd: string, block: BlockDefinition): Promise<number>;
3
+ export declare function uninstallBlock(cwd: string, blockId: string): Promise<number>;
4
+ //# sourceMappingURL=installer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/blocks/installer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAmCrD,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CA8CvF;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgClF"}
@@ -0,0 +1,119 @@
1
+ import { readFile, writeFile, mkdir } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { parse, stringify } from 'yaml';
4
+ async function readRuleFile(filePath) {
5
+ try {
6
+ const raw = await readFile(filePath, 'utf-8');
7
+ const parsed = parse(raw);
8
+ if (!parsed || typeof parsed !== 'object')
9
+ return null;
10
+ const doc = parsed;
11
+ return {
12
+ scope: typeof doc['scope'] === 'string' ? doc['scope'] : '',
13
+ rules: Array.isArray(doc['rules']) ? doc['rules'] : [],
14
+ };
15
+ }
16
+ catch {
17
+ return null;
18
+ }
19
+ }
20
+ function writeRuleFile(doc) {
21
+ return stringify(doc, { lineWidth: 0 });
22
+ }
23
+ export async function installBlock(cwd, block) {
24
+ const rulesDir = join(cwd, '.dwf', 'rules');
25
+ await mkdir(rulesDir, { recursive: true });
26
+ // Group block rules by scope
27
+ const byScope = new Map();
28
+ for (const rule of block.rules) {
29
+ const existing = byScope.get(rule.scope);
30
+ if (existing) {
31
+ existing.push(rule);
32
+ }
33
+ else {
34
+ byScope.set(rule.scope, [rule]);
35
+ }
36
+ }
37
+ let rulesAdded = 0;
38
+ for (const [scope, blockRules] of byScope) {
39
+ const filePath = join(rulesDir, `${scope}.yml`);
40
+ let doc = await readRuleFile(filePath);
41
+ if (!doc) {
42
+ doc = { scope, rules: [] };
43
+ }
44
+ // Remove any existing rules from this block to avoid duplicates on re-add
45
+ doc.rules = doc.rules.filter((r) => r.sourceBlock !== block.id);
46
+ // Append new rules
47
+ for (const rule of blockRules) {
48
+ doc.rules.push({
49
+ id: rule.id,
50
+ severity: rule.severity,
51
+ content: rule.content,
52
+ sourceBlock: block.id,
53
+ });
54
+ rulesAdded++;
55
+ }
56
+ await writeFile(filePath, writeRuleFile(doc), 'utf-8');
57
+ }
58
+ // Update config.yml blocks array
59
+ await addBlockToConfig(cwd, block.id);
60
+ return rulesAdded;
61
+ }
62
+ export async function uninstallBlock(cwd, blockId) {
63
+ const rulesDir = join(cwd, '.dwf', 'rules');
64
+ let entries;
65
+ try {
66
+ const { readdir } = await import('node:fs/promises');
67
+ entries = await readdir(rulesDir);
68
+ }
69
+ catch {
70
+ return 0;
71
+ }
72
+ const ymlFiles = entries.filter((f) => f.endsWith('.yml') || f.endsWith('.yaml'));
73
+ let rulesRemoved = 0;
74
+ for (const file of ymlFiles) {
75
+ const filePath = join(rulesDir, file);
76
+ const doc = await readRuleFile(filePath);
77
+ if (!doc)
78
+ continue;
79
+ const before = doc.rules.length;
80
+ doc.rules = doc.rules.filter((r) => r.sourceBlock !== blockId);
81
+ const removed = before - doc.rules.length;
82
+ if (removed > 0) {
83
+ rulesRemoved += removed;
84
+ await writeFile(filePath, writeRuleFile(doc), 'utf-8');
85
+ }
86
+ }
87
+ // Update config.yml blocks array
88
+ await removeBlockFromConfig(cwd, blockId);
89
+ return rulesRemoved;
90
+ }
91
+ async function readRawConfig(cwd) {
92
+ const configPath = join(cwd, '.dwf', 'config.yml');
93
+ const raw = await readFile(configPath, 'utf-8');
94
+ const parsed = parse(raw);
95
+ if (!parsed || typeof parsed !== 'object') {
96
+ throw new Error('Invalid config.yml');
97
+ }
98
+ return parsed;
99
+ }
100
+ async function writeRawConfig(cwd, doc) {
101
+ const configPath = join(cwd, '.dwf', 'config.yml');
102
+ await writeFile(configPath, stringify(doc, { lineWidth: 0 }), 'utf-8');
103
+ }
104
+ async function addBlockToConfig(cwd, blockId) {
105
+ const doc = await readRawConfig(cwd);
106
+ const blocks = Array.isArray(doc['blocks']) ? doc['blocks'] : [];
107
+ if (!blocks.includes(blockId)) {
108
+ blocks.push(blockId);
109
+ }
110
+ doc['blocks'] = blocks;
111
+ await writeRawConfig(cwd, doc);
112
+ }
113
+ async function removeBlockFromConfig(cwd, blockId) {
114
+ const doc = await readRawConfig(cwd);
115
+ const blocks = Array.isArray(doc['blocks']) ? doc['blocks'] : [];
116
+ doc['blocks'] = blocks.filter((b) => b !== blockId);
117
+ await writeRawConfig(cwd, doc);
118
+ }
119
+ //# sourceMappingURL=installer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/blocks/installer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { Rule } from '../bridges/types.js';
2
+ export interface BlockDefinition {
3
+ id: string;
4
+ name: string;
5
+ description: string;
6
+ version: string;
7
+ rules: BlockRule[];
8
+ }
9
+ export interface BlockRule {
10
+ id: string;
11
+ scope: string;
12
+ severity: 'error' | 'warning' | 'info';
13
+ content: string;
14
+ }
15
+ export declare function loadAllBlocks(blocksDir?: string): Promise<BlockDefinition[]>;
16
+ export declare function loadBlock(blockId: string, blocksDir?: string): Promise<BlockDefinition | null>;
17
+ export declare function blockRulesToRules(block: BlockDefinition): Rule[];
18
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/blocks/registry.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;CACjB;AAuDD,wBAAsB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAuBlF;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAGpG;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,EAAE,CAShE"}
@@ -0,0 +1,85 @@
1
+ import { readFile, readdir } from 'node:fs/promises';
2
+ import { join, dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { parse } from 'yaml';
5
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
+ function defaultBlocksDir() {
7
+ // From dist/blocks/ → packages/cli/ (2 up), then content/blocks
8
+ return join(__dirname, '..', '..', 'content', 'blocks');
9
+ }
10
+ function normalizeBlockRule(raw) {
11
+ if (!raw.id || !raw.scope || !raw.content)
12
+ return null;
13
+ const severity = raw.severity ?? 'error';
14
+ if (severity !== 'error' && severity !== 'warning' && severity !== 'info')
15
+ return null;
16
+ return {
17
+ id: raw.id,
18
+ scope: raw.scope,
19
+ severity,
20
+ content: raw.content.trimEnd(),
21
+ };
22
+ }
23
+ function parseBlock(raw) {
24
+ const parsed = parse(raw);
25
+ if (!parsed || typeof parsed !== 'object')
26
+ return null;
27
+ const doc = parsed;
28
+ const id = typeof doc['id'] === 'string' ? doc['id'] : null;
29
+ const name = typeof doc['name'] === 'string' ? doc['name'] : null;
30
+ const description = typeof doc['description'] === 'string' ? doc['description'] : '';
31
+ const version = typeof doc['version'] === 'string' ? doc['version'] : '0.1.0';
32
+ if (!id || !name)
33
+ return null;
34
+ const rulesRaw = doc['rules'];
35
+ if (!Array.isArray(rulesRaw))
36
+ return null;
37
+ const rules = [];
38
+ for (const rawRule of rulesRaw) {
39
+ if (!rawRule || typeof rawRule !== 'object')
40
+ continue;
41
+ const rule = normalizeBlockRule(rawRule);
42
+ if (rule)
43
+ rules.push(rule);
44
+ }
45
+ return { id, name, description, version, rules };
46
+ }
47
+ export async function loadAllBlocks(blocksDir) {
48
+ const dir = blocksDir ?? defaultBlocksDir();
49
+ let entries;
50
+ try {
51
+ entries = await readdir(dir);
52
+ }
53
+ catch {
54
+ return [];
55
+ }
56
+ const ymlFiles = entries.filter((f) => f.endsWith('.yml') || f.endsWith('.yaml'));
57
+ const blocks = [];
58
+ for (const file of ymlFiles) {
59
+ try {
60
+ const raw = await readFile(join(dir, file), 'utf-8');
61
+ const block = parseBlock(raw);
62
+ if (block)
63
+ blocks.push(block);
64
+ }
65
+ catch {
66
+ // Skip files that can't be read or parsed
67
+ }
68
+ }
69
+ return blocks;
70
+ }
71
+ export async function loadBlock(blockId, blocksDir) {
72
+ const all = await loadAllBlocks(blocksDir);
73
+ return all.find((b) => b.id === blockId) ?? null;
74
+ }
75
+ export function blockRulesToRules(block) {
76
+ return block.rules.map((r) => ({
77
+ id: r.id,
78
+ scope: r.scope,
79
+ severity: r.severity,
80
+ content: r.content,
81
+ enabled: true,
82
+ sourceBlock: block.id,
83
+ }));
84
+ }
85
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/blocks/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Bridge } from './types.js';
2
+ export declare const claudeBridge: Bridge;
3
+ //# sourceMappingURL=claude.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/bridges/claude.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAuB,MAAM,YAAY,CAAC;AAoD9D,eAAO,MAAM,YAAY,EAAE,MAS1B,CAAC"}
@@ -0,0 +1,54 @@
1
+ function filterRules(rules) {
2
+ return rules.filter((r) => r.enabled && r.severity !== 'info');
3
+ }
4
+ function groupByScope(rules) {
5
+ const groups = new Map();
6
+ for (const rule of rules) {
7
+ const existing = groups.get(rule.scope);
8
+ if (existing) {
9
+ existing.push(rule);
10
+ }
11
+ else {
12
+ groups.set(rule.scope, [rule]);
13
+ }
14
+ }
15
+ return groups;
16
+ }
17
+ function capitalize(s) {
18
+ return s.charAt(0).toUpperCase() + s.slice(1);
19
+ }
20
+ function buildMarkdown(rules) {
21
+ const lines = [
22
+ '# Project Rules',
23
+ ];
24
+ const filtered = filterRules(rules);
25
+ const grouped = groupByScope(filtered);
26
+ for (const [scope, scopeRules] of grouped) {
27
+ lines.push('', `## ${capitalize(scope)}`);
28
+ for (const rule of scopeRules) {
29
+ const contentLines = rule.content.split('\n');
30
+ const first = contentLines[0];
31
+ if (first !== undefined) {
32
+ lines.push('', `- ${first}`);
33
+ }
34
+ for (let i = 1; i < contentLines.length; i++) {
35
+ const line = contentLines[i];
36
+ if (line !== undefined) {
37
+ lines.push(` ${line}`);
38
+ }
39
+ }
40
+ }
41
+ }
42
+ lines.push('');
43
+ return lines.join('\n');
44
+ }
45
+ export const claudeBridge = {
46
+ id: 'claude',
47
+ outputPaths: ['CLAUDE.md'],
48
+ compile(rules, _config) {
49
+ const output = new Map();
50
+ output.set('CLAUDE.md', buildMarkdown(rules));
51
+ return output;
52
+ },
53
+ };
54
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/bridges/claude.ts"],"names":[],"mappings":"AAEA,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxC,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,MAAM,KAAK,GAAa;QACtB,iBAAiB;KAClB,CAAC;IAEF,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IAEvC,KAAK,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,OAAO,EAAE,CAAC;QAC1C,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC1C,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC9C,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;YAC9B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,KAAK,EAAE,CAAC,CAAC;YAC/B,CAAC;YACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7C,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;gBAC7B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBACvB,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAW;IAClC,EAAE,EAAE,QAAQ;IACZ,WAAW,EAAE,CAAC,WAAW,CAAC;IAE1B,OAAO,CAAC,KAAa,EAAE,OAAsB;QAC3C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;QACzC,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9C,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Bridge } from './types.js';
2
+ export declare const cursorBridge: Bridge;
3
+ //# sourceMappingURL=cursor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/bridges/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAuB,MAAM,YAAY,CAAC;AA4D9D,eAAO,MAAM,YAAY,EAAE,MAS1B,CAAC"}
@@ -0,0 +1,61 @@
1
+ function filterRules(rules) {
2
+ return rules.filter((r) => r.enabled && r.severity !== 'info');
3
+ }
4
+ function groupByScope(rules) {
5
+ const groups = new Map();
6
+ for (const rule of rules) {
7
+ const existing = groups.get(rule.scope);
8
+ if (existing) {
9
+ existing.push(rule);
10
+ }
11
+ else {
12
+ groups.set(rule.scope, [rule]);
13
+ }
14
+ }
15
+ return groups;
16
+ }
17
+ function capitalize(s) {
18
+ return s.charAt(0).toUpperCase() + s.slice(1);
19
+ }
20
+ const FRONTMATTER = `---
21
+ description: Project rules generated by dev-workflows
22
+ globs:
23
+ alwaysApply: true
24
+ ---`;
25
+ function buildMdc(rules) {
26
+ const lines = [
27
+ FRONTMATTER,
28
+ '',
29
+ '<!-- Generated by dev-workflows. Do not edit manually. -->',
30
+ ];
31
+ const filtered = filterRules(rules);
32
+ const grouped = groupByScope(filtered);
33
+ for (const [scope, scopeRules] of grouped) {
34
+ lines.push('', `## ${capitalize(scope)}`);
35
+ for (const rule of scopeRules) {
36
+ const contentLines = rule.content.split('\n');
37
+ const first = contentLines[0];
38
+ if (first !== undefined) {
39
+ lines.push('', `- ${first}`);
40
+ }
41
+ for (let i = 1; i < contentLines.length; i++) {
42
+ const line = contentLines[i];
43
+ if (line !== undefined) {
44
+ lines.push(` ${line}`);
45
+ }
46
+ }
47
+ }
48
+ }
49
+ lines.push('');
50
+ return lines.join('\n');
51
+ }
52
+ export const cursorBridge = {
53
+ id: 'cursor',
54
+ outputPaths: ['.cursor/rules/devworkflows.mdc'],
55
+ compile(rules, _config) {
56
+ const output = new Map();
57
+ output.set('.cursor/rules/devworkflows.mdc', buildMdc(rules));
58
+ return output;
59
+ },
60
+ };
61
+ //# sourceMappingURL=cursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/bridges/cursor.ts"],"names":[],"mappings":"AAEA,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxC,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,WAAW,GAAG;;;;IAIhB,CAAC;AAEL,SAAS,QAAQ,CAAC,KAAa;IAC7B,MAAM,KAAK,GAAa;QACtB,WAAW;QACX,EAAE;QACF,4DAA4D;KAC7D,CAAC;IAEF,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IAEvC,KAAK,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,OAAO,EAAE,CAAC;QAC1C,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC1C,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC9C,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;YAC9B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,KAAK,EAAE,CAAC,CAAC;YAC/B,CAAC;YACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7C,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;gBAC7B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBACvB,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAW;IAClC,EAAE,EAAE,QAAQ;IACZ,WAAW,EAAE,CAAC,gCAAgC,CAAC;IAE/C,OAAO,CAAC,KAAa,EAAE,OAAsB;QAC3C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;QACzC,MAAM,CAAC,GAAG,CAAC,gCAAgC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9D,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Bridge } from './types.js';
2
+ export declare const geminiBridge: Bridge;
3
+ //# sourceMappingURL=gemini.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/bridges/gemini.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAuB,MAAM,YAAY,CAAC;AAoD9D,eAAO,MAAM,YAAY,EAAE,MAS1B,CAAC"}