@dewtech/dare-cli 3.6.0 → 3.7.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 (91) hide show
  1. package/dist/__tests__/ide-command-parity.test.js +1 -0
  2. package/dist/__tests__/ide-command-parity.test.js.map +1 -1
  3. package/dist/__tests__/patterns-no-llm.test.d.ts +2 -0
  4. package/dist/__tests__/patterns-no-llm.test.d.ts.map +1 -0
  5. package/dist/__tests__/patterns-no-llm.test.js +31 -0
  6. package/dist/__tests__/patterns-no-llm.test.js.map +1 -0
  7. package/dist/__tests__/patterns-path-confinement.test.d.ts +2 -0
  8. package/dist/__tests__/patterns-path-confinement.test.d.ts.map +1 -0
  9. package/dist/__tests__/patterns-path-confinement.test.js +58 -0
  10. package/dist/__tests__/patterns-path-confinement.test.js.map +1 -0
  11. package/dist/__tests__/patterns.test.d.ts +2 -0
  12. package/dist/__tests__/patterns.test.d.ts.map +1 -0
  13. package/dist/__tests__/patterns.test.js +102 -0
  14. package/dist/__tests__/patterns.test.js.map +1 -0
  15. package/dist/bin/dare.js +2 -0
  16. package/dist/bin/dare.js.map +1 -1
  17. package/dist/commands/__tests__/design-interactive.test.d.ts +2 -0
  18. package/dist/commands/__tests__/design-interactive.test.d.ts.map +1 -0
  19. package/dist/commands/__tests__/design-interactive.test.js +44 -0
  20. package/dist/commands/__tests__/design-interactive.test.js.map +1 -0
  21. package/dist/commands/__tests__/patterns.test.d.ts +2 -0
  22. package/dist/commands/__tests__/patterns.test.d.ts.map +1 -0
  23. package/dist/commands/__tests__/patterns.test.js +55 -0
  24. package/dist/commands/__tests__/patterns.test.js.map +1 -0
  25. package/dist/commands/design.d.ts.map +1 -1
  26. package/dist/commands/design.js +38 -8
  27. package/dist/commands/design.js.map +1 -1
  28. package/dist/commands/graph.d.ts.map +1 -1
  29. package/dist/commands/graph.js +1 -0
  30. package/dist/commands/graph.js.map +1 -1
  31. package/dist/commands/patterns.d.ts +3 -0
  32. package/dist/commands/patterns.d.ts.map +1 -0
  33. package/dist/commands/patterns.js +124 -0
  34. package/dist/commands/patterns.js.map +1 -0
  35. package/dist/graphrag/__tests__/pattern-ingest.test.d.ts +2 -0
  36. package/dist/graphrag/__tests__/pattern-ingest.test.d.ts.map +1 -0
  37. package/dist/graphrag/__tests__/pattern-ingest.test.js +49 -0
  38. package/dist/graphrag/__tests__/pattern-ingest.test.js.map +1 -0
  39. package/dist/graphrag/__tests__/types.test.js +5 -2
  40. package/dist/graphrag/__tests__/types.test.js.map +1 -1
  41. package/dist/graphrag/pattern-ingest.d.ts +10 -0
  42. package/dist/graphrag/pattern-ingest.d.ts.map +1 -0
  43. package/dist/graphrag/pattern-ingest.js +77 -0
  44. package/dist/graphrag/pattern-ingest.js.map +1 -0
  45. package/dist/graphrag/types.d.ts +15 -4
  46. package/dist/graphrag/types.d.ts.map +1 -1
  47. package/dist/graphrag/types.js +3 -0
  48. package/dist/graphrag/types.js.map +1 -1
  49. package/dist/index.d.ts +1 -0
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +1 -0
  52. package/dist/index.js.map +1 -1
  53. package/dist/steering/__tests__/loader.test.js +15 -0
  54. package/dist/steering/__tests__/loader.test.js.map +1 -1
  55. package/dist/steering/loader.d.ts.map +1 -1
  56. package/dist/steering/loader.js +11 -0
  57. package/dist/steering/loader.js.map +1 -1
  58. package/dist/utils/__tests__/design-questionnaire.test.d.ts +2 -0
  59. package/dist/utils/__tests__/design-questionnaire.test.d.ts.map +1 -0
  60. package/dist/utils/__tests__/design-questionnaire.test.js +72 -0
  61. package/dist/utils/__tests__/design-questionnaire.test.js.map +1 -0
  62. package/dist/utils/__tests__/pattern-detector.test.d.ts +2 -0
  63. package/dist/utils/__tests__/pattern-detector.test.d.ts.map +1 -0
  64. package/dist/utils/__tests__/pattern-detector.test.js +81 -0
  65. package/dist/utils/__tests__/pattern-detector.test.js.map +1 -0
  66. package/dist/utils/__tests__/pattern-facts.test.d.ts +2 -0
  67. package/dist/utils/__tests__/pattern-facts.test.d.ts.map +1 -0
  68. package/dist/utils/__tests__/pattern-facts.test.js +55 -0
  69. package/dist/utils/__tests__/pattern-facts.test.js.map +1 -0
  70. package/dist/utils/design-questionnaire.d.ts +22 -0
  71. package/dist/utils/design-questionnaire.d.ts.map +1 -0
  72. package/dist/utils/design-questionnaire.js +151 -0
  73. package/dist/utils/design-questionnaire.js.map +1 -0
  74. package/dist/utils/pattern-detector.d.ts +39 -0
  75. package/dist/utils/pattern-detector.d.ts.map +1 -0
  76. package/dist/utils/pattern-detector.js +291 -0
  77. package/dist/utils/pattern-detector.js.map +1 -0
  78. package/dist/utils/pattern-facts.d.ts +7 -0
  79. package/dist/utils/pattern-facts.d.ts.map +1 -0
  80. package/dist/utils/pattern-facts.js +86 -0
  81. package/dist/utils/pattern-facts.js.map +1 -0
  82. package/package.json +1 -1
  83. package/templates/ide/antigravity/.agents/skills/dare-blueprint/SKILL.md +4 -0
  84. package/templates/ide/antigravity/.agents/skills/dare-design/SKILL.md +11 -0
  85. package/templates/ide/antigravity/.agents/skills/dare-patterns/SKILL.md +9 -0
  86. package/templates/ide/claude/.claude/commands/dare-blueprint.md +4 -0
  87. package/templates/ide/claude/.claude/commands/dare-design.md +10 -0
  88. package/templates/ide/claude/.claude/commands/dare-patterns.md +12 -0
  89. package/templates/ide/cursor/.cursor/commands/dare-blueprint.md +4 -2
  90. package/templates/ide/cursor/.cursor/commands/dare-design.md +9 -3
  91. package/templates/ide/cursor/.cursor/commands/dare-patterns.md +12 -0
@@ -0,0 +1,72 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { buildDesignQuestionnaire, buildBlueprintQuestionnaire, } from '../design-questionnaire.js';
3
+ const DNA = {
4
+ generatedAt: '2026-06-07T12:00:00.000Z',
5
+ fileInventorySource: 'module-detector',
6
+ tooling: { linters: [], formatters: [] },
7
+ naming: [],
8
+ architecture: { detectedLayers: ['a', 'b', 'c', 'd'], guess: 'unknown layered' },
9
+ testing: { testFiles: 1, prodFiles: 5, ratio: 0.2 },
10
+ libraries: { orm: 'prisma', http: 'express' },
11
+ commits: null,
12
+ };
13
+ const PATTERNS = {
14
+ generatedAt: '2026-06-07T12:00:00.000Z',
15
+ fileInventorySource: 'module-detector',
16
+ patterns: [
17
+ {
18
+ id: 'naming-idiom:service-suffix',
19
+ kind: 'naming-idiom',
20
+ description: '3 arquivos usam sufixo .service.ts',
21
+ frequency: 3,
22
+ coverage: 0.75,
23
+ evidence: [{ file: 'src/x.service.ts' }],
24
+ modules: ['src'],
25
+ marker: 'confirmed',
26
+ },
27
+ {
28
+ id: 'call-idiom:schema-validation',
29
+ kind: 'call-idiom',
30
+ description: '2 arquivos usam validação',
31
+ frequency: 2,
32
+ coverage: 0.2,
33
+ evidence: [{ file: 'src/validate.ts', line: 2 }],
34
+ modules: ['src'],
35
+ marker: 'confirmed',
36
+ },
37
+ {
38
+ id: 'implicit-decision:orm-prisma',
39
+ kind: 'implicit-decision',
40
+ description: 'ORM prisma em 2 arquivos',
41
+ frequency: 2,
42
+ coverage: 0.4,
43
+ evidence: [{ file: 'src/db.ts' }],
44
+ modules: ['src'],
45
+ marker: 'confirmed',
46
+ },
47
+ ],
48
+ };
49
+ describe('design-questionnaire', () => {
50
+ it('buildDesignQuestionnaire produces gap questions for low coverage', () => {
51
+ const art = buildDesignQuestionnaire(DNA, PATTERNS);
52
+ const gaps = art.questions.filter((q) => q.kind === 'gap');
53
+ expect(gaps.length).toBeGreaterThan(0);
54
+ expect(gaps.some((q) => q.anchoredOn.includes('call-idiom:schema-validation'))).toBe(true);
55
+ });
56
+ it('is deterministic (ignoring generatedAt)', () => {
57
+ const a = buildDesignQuestionnaire(DNA, PATTERNS);
58
+ const b = buildDesignQuestionnaire(DNA, PATTERNS);
59
+ expect(a.questions.map((q) => q.id)).toEqual(b.questions.map((q) => q.id));
60
+ });
61
+ it('returns empty when both inputs null', () => {
62
+ const art = buildDesignQuestionnaire(null, null);
63
+ expect(art.questions).toEqual([]);
64
+ });
65
+ it('buildBlueprintQuestionnaire anchors architect tradeoffs', () => {
66
+ const art = buildBlueprintQuestionnaire(PATTERNS);
67
+ expect(art.phase).toBe('blueprint');
68
+ expect(art.questions.some((q) => q.persona === 'architect' && q.kind === 'tradeoff')).toBe(true);
69
+ expect(art.questions.every((q) => q.anchoredOn.length >= 1)).toBe(true);
70
+ });
71
+ });
72
+ //# sourceMappingURL=design-questionnaire.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design-questionnaire.test.js","sourceRoot":"","sources":["../../../src/utils/__tests__/design-questionnaire.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,4BAA4B,CAAC;AAIpC,MAAM,GAAG,GAAa;IACpB,WAAW,EAAE,0BAA0B;IACvC,mBAAmB,EAAE,iBAAiB;IACtC,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;IACxC,MAAM,EAAE,EAAE;IACV,YAAY,EAAE,EAAE,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE;IAChF,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE;IACnD,SAAS,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE;IAC7C,OAAO,EAAE,IAAI;CACd,CAAC;AAEF,MAAM,QAAQ,GAAkB;IAC9B,WAAW,EAAE,0BAA0B;IACvC,mBAAmB,EAAE,iBAAiB;IACtC,QAAQ,EAAE;QACR;YACE,EAAE,EAAE,6BAA6B;YACjC,IAAI,EAAE,cAAc;YACpB,WAAW,EAAE,oCAAoC;YACjD,SAAS,EAAE,CAAC;YACZ,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC;YACxC,OAAO,EAAE,CAAC,KAAK,CAAC;YAChB,MAAM,EAAE,WAAW;SACpB;QACD;YACE,EAAE,EAAE,8BAA8B;YAClC,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,2BAA2B;YACxC,SAAS,EAAE,CAAC;YACZ,QAAQ,EAAE,GAAG;YACb,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YAChD,OAAO,EAAE,CAAC,KAAK,CAAC;YAChB,MAAM,EAAE,WAAW;SACpB;QACD;YACE,EAAE,EAAE,8BAA8B;YAClC,IAAI,EAAE,mBAAmB;YACzB,WAAW,EAAE,0BAA0B;YACvC,SAAS,EAAE,CAAC;YACZ,QAAQ,EAAE,GAAG;YACb,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;YACjC,OAAO,EAAE,CAAC,KAAK,CAAC;YAChB,MAAM,EAAE,WAAW;SACpB;KACF;CACF,CAAC;AAEF,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,MAAM,GAAG,GAAG,wBAAwB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;QAC3D,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,8BAA8B,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,CAAC,GAAG,wBAAwB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAClD,MAAM,CAAC,GAAG,wBAAwB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAClD,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,GAAG,GAAG,wBAAwB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACjD,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,GAAG,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACpC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,WAAW,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CACxF,IAAI,CACL,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pattern-detector.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-detector.test.d.ts","sourceRoot":"","sources":["../../../src/utils/__tests__/pattern-detector.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,81 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import fs from 'fs-extra';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { detectPatterns, PATTERN_RULES } from '../pattern-detector.js';
6
+ async function writeFixture(root) {
7
+ await fs.ensureDir(path.join(root, 'src', 'auth'));
8
+ await fs.ensureDir(path.join(root, 'src', 'users'));
9
+ const files = [
10
+ ['src/auth/auth.service.ts', 'export class AuthService {}'],
11
+ ['src/auth/auth.controller.ts', 'import { AuthService } from "./auth.service";'],
12
+ ['src/users/users.service.ts', 'export class UsersService {}'],
13
+ ['src/users/users.controller.ts', 'import { UsersService } from "./users.service";'],
14
+ ['src/index.ts', 'export * from "./auth/auth.service";\nexport * from "./users/users.service";'],
15
+ ['src/validate.ts', 'import { z } from "zod";\nexport const s = z.string();'],
16
+ ['src/parse.ts', 'import { z } from "zod";\nexport const s = z.number();'],
17
+ ['src/db.ts', 'import { PrismaClient } from "@prisma/client";\nexport const db = new PrismaClient();'],
18
+ ['src/repo.ts', 'import { PrismaClient } from "@prisma/client";\nexport const db2 = new PrismaClient();'],
19
+ ];
20
+ for (const [rel, body] of files) {
21
+ await fs.ensureDir(path.dirname(path.join(root, rel)));
22
+ await fs.writeFile(path.join(root, rel), body);
23
+ }
24
+ }
25
+ describe('pattern-detector', () => {
26
+ let projectRoot;
27
+ beforeEach(async () => {
28
+ projectRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'pattern-det-'));
29
+ await writeFixture(projectRoot);
30
+ });
31
+ afterEach(async () => {
32
+ await fs.remove(projectRoot).catch(() => undefined);
33
+ });
34
+ const dna = {
35
+ generatedAt: '2026-06-07T12:00:00.000Z',
36
+ fileInventorySource: 'module-detector',
37
+ tooling: { linters: [], formatters: [] },
38
+ naming: [],
39
+ architecture: { detectedLayers: [], guess: '' },
40
+ testing: { testFiles: 0, prodFiles: 9, ratio: 0 },
41
+ libraries: { orm: 'prisma' },
42
+ commits: null,
43
+ };
44
+ it('exports at least 5 pattern rules covering each PatternKind', () => {
45
+ expect(PATTERN_RULES.length).toBeGreaterThanOrEqual(5);
46
+ const kinds = new Set(PATTERN_RULES.map((r) => r.kind));
47
+ expect(kinds.has('naming-idiom')).toBe(true);
48
+ expect(kinds.has('inferred-layer')).toBe(true);
49
+ expect(kinds.has('structural-idiom')).toBe(true);
50
+ expect(kinds.has('call-idiom')).toBe(true);
51
+ expect(kinds.has('implicit-decision')).toBe(true);
52
+ });
53
+ it('detects naming, call and implicit patterns on fixture', async () => {
54
+ const facts = await detectPatterns(projectRoot, dna);
55
+ expect(facts.patterns.length).toBeGreaterThan(0);
56
+ const kinds = facts.patterns.map((p) => p.kind);
57
+ expect(kinds).toContain('naming-idiom');
58
+ expect(kinds).toContain('call-idiom');
59
+ for (const p of facts.patterns) {
60
+ expect(p.evidence.length).toBeGreaterThanOrEqual(1);
61
+ expect(p.frequency).toBeGreaterThanOrEqual(1);
62
+ expect(p.coverage).toBeGreaterThanOrEqual(0);
63
+ expect(p.coverage).toBeLessThanOrEqual(1);
64
+ expect(p.marker).toBe('confirmed');
65
+ }
66
+ });
67
+ it('is deterministic (same input => identical JSON)', async () => {
68
+ const a = await detectPatterns(projectRoot, dna);
69
+ const b = await detectPatterns(projectRoot, dna);
70
+ expect(JSON.stringify(a)).toBe(JSON.stringify(b));
71
+ });
72
+ it('sorts patterns by kind then id', async () => {
73
+ const facts = await detectPatterns(projectRoot, dna);
74
+ const sorted = [...facts.patterns].sort((x, y) => {
75
+ const k = x.kind.localeCompare(y.kind);
76
+ return k !== 0 ? k : x.id.localeCompare(y.id);
77
+ });
78
+ expect(facts.patterns.map((p) => p.id)).toEqual(sorted.map((p) => p.id));
79
+ });
80
+ });
81
+ //# sourceMappingURL=pattern-detector.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-detector.test.js","sourceRoot":"","sources":["../../../src/utils/__tests__/pattern-detector.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pattern-facts.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-facts.test.d.ts","sourceRoot":"","sources":["../../../src/utils/__tests__/pattern-facts.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,55 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { renderPatternsSkeleton } from '../pattern-facts.js';
3
+ const FIXTURE = {
4
+ generatedAt: '2026-06-07T12:00:00.000Z',
5
+ fileInventorySource: 'module-detector',
6
+ patterns: [
7
+ {
8
+ id: 'naming-idiom:service-suffix',
9
+ kind: 'naming-idiom',
10
+ description: '3 arquivos usam sufixo .service.ts',
11
+ frequency: 3,
12
+ coverage: 0.75,
13
+ evidence: [{ file: 'src/auth/auth.service.ts' }, { file: 'src/users/users.service.ts', line: 1 }],
14
+ modules: ['auth', 'users'],
15
+ marker: 'confirmed',
16
+ },
17
+ {
18
+ id: 'call-idiom:schema-validation',
19
+ kind: 'call-idiom',
20
+ description: '2 arquivos usam validação z./schema.parse',
21
+ frequency: 2,
22
+ coverage: 0.25,
23
+ evidence: [{ file: 'src/validate.ts', line: 2 }],
24
+ modules: ['src'],
25
+ marker: 'confirmed',
26
+ },
27
+ ],
28
+ };
29
+ describe('renderPatternsSkeleton', () => {
30
+ it('is deterministic for fixed input', () => {
31
+ const a = renderPatternsSkeleton(FIXTURE);
32
+ const b = renderPatternsSkeleton(FIXTURE);
33
+ expect(a).toBe(b);
34
+ expect(a).toMatchSnapshot();
35
+ });
36
+ it('includes all PatternKind sections even when empty', () => {
37
+ const md = renderPatternsSkeleton(FIXTURE);
38
+ expect(md).toContain('## Camadas inferidas');
39
+ expect(md).toContain('## Idiomas estruturais');
40
+ expect(md).toContain('_(nenhum detectado)_');
41
+ });
42
+ it('lists low-coverage patterns in Incertezas', () => {
43
+ const md = renderPatternsSkeleton(FIXTURE);
44
+ expect(md).toContain('## ⚠️ Incertezas');
45
+ expect(md).toContain('call-idiom:schema-validation');
46
+ expect(md).toContain('cobertura baixa');
47
+ });
48
+ it('uses factual claims and AGENT placeholders only', () => {
49
+ const md = renderPatternsSkeleton(FIXTURE);
50
+ expect(md).toContain('🟢 3 arquivos usam sufixo');
51
+ expect(md).toContain('<!-- AGENT:');
52
+ expect(md).not.toMatch(/\b(probably|likely|seems)\b/i);
53
+ });
54
+ });
55
+ //# sourceMappingURL=pattern-facts.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-facts.test.js","sourceRoot":"","sources":["../../../src/utils/__tests__/pattern-facts.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAG7D,MAAM,OAAO,GAAkB;IAC7B,WAAW,EAAE,0BAA0B;IACvC,mBAAmB,EAAE,iBAAiB;IACtC,QAAQ,EAAE;QACR;YACE,EAAE,EAAE,6BAA6B;YACjC,IAAI,EAAE,cAAc;YACpB,WAAW,EAAE,oCAAoC;YACjD,SAAS,EAAE,CAAC;YACZ,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,0BAA0B,EAAE,EAAE,EAAE,IAAI,EAAE,4BAA4B,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YACjG,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;YAC1B,MAAM,EAAE,WAAW;SACpB;QACD;YACE,EAAE,EAAE,8BAA8B;YAClC,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,2CAA2C;YACxD,SAAS,EAAE,CAAC;YACZ,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YAChD,OAAO,EAAE,CAAC,KAAK,CAAC;YAChB,MAAM,EAAE,WAAW;SACpB;KACF;CACF,CAAC;AAEF,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,MAAM,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,EAAE,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAC7C,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;QAC/C,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,EAAE,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QACzC,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC;QACrD,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,EAAE,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,2BAA2B,CAAC,CAAC;QAClD,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACpC,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { PatternsFacts } from './pattern-detector.js';
2
+ import type { DnaFacts } from './dna-detector.js';
3
+ /** Persona que origina a pergunta. NÃO executa nada — rótulo p/ a skill conduzir (A-8/A-9). */
4
+ export type PlannerPersona = 'analyst' | 'pm' | 'architect';
5
+ export interface PlanningQuestion {
6
+ readonly id: string;
7
+ readonly persona: PlannerPersona;
8
+ readonly phase: 'design' | 'blueprint';
9
+ readonly prompt: string;
10
+ readonly anchoredOn: readonly string[];
11
+ readonly kind: 'gap' | 'ambiguity' | 'tradeoff' | 'scope';
12
+ }
13
+ export interface PlanningArtifact {
14
+ readonly generatedAt: string;
15
+ readonly phase: 'design' | 'blueprint';
16
+ readonly questions: readonly PlanningQuestion[];
17
+ }
18
+ export declare function buildDesignQuestionnaire(dna: DnaFacts | null, patterns: PatternsFacts | null): PlanningArtifact;
19
+ export declare function buildBlueprintQuestionnaire(patterns: PatternsFacts | null): PlanningArtifact;
20
+ /** Markdown block for DESIGN.md (deterministic; CLI does not answer — skill conducts 1 passagem). */
21
+ export declare function renderDesignQuestionnaireBlock(artifact: PlanningArtifact): string;
22
+ //# sourceMappingURL=design-questionnaire.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design-questionnaire.d.ts","sourceRoot":"","sources":["../../src/utils/design-questionnaire.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAkC,MAAM,uBAAuB,CAAC;AAC3F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD,+FAA+F;AAC/F,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,IAAI,GAAG,WAAW,CAAC;AAE5D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,WAAW,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;CAC3D;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,WAAW,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,SAAS,gBAAgB,EAAE,CAAC;CACjD;AA0CD,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,QAAQ,GAAG,IAAI,EACpB,QAAQ,EAAE,aAAa,GAAG,IAAI,GAC7B,gBAAgB,CAqFlB;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,aAAa,GAAG,IAAI,GAC7B,gBAAgB,CAyBlB;AAED,qGAAqG;AACrG,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAsBjF"}
@@ -0,0 +1,151 @@
1
+ const KIND_ORDER = [
2
+ 'inferred-layer',
3
+ 'naming-idiom',
4
+ 'structural-idiom',
5
+ 'call-idiom',
6
+ 'implicit-decision',
7
+ ];
8
+ function sortQuestions(questions) {
9
+ return [...questions].sort((a, b) => a.id.localeCompare(b.id));
10
+ }
11
+ function counterKey(persona, kind) {
12
+ return `${persona}-${kind}`;
13
+ }
14
+ function nextId(counters, persona, kind) {
15
+ const key = counterKey(persona, kind);
16
+ const n = (counters.get(key) ?? 0) + 1;
17
+ counters.set(key, n);
18
+ return `${persona}-${kind}-${String(n).padStart(2, '0')}`;
19
+ }
20
+ function patternsByKind(patterns) {
21
+ const map = new Map();
22
+ for (const kind of KIND_ORDER)
23
+ map.set(kind, []);
24
+ for (const p of patterns) {
25
+ const list = map.get(p.kind) ?? [];
26
+ list.push(p);
27
+ map.set(p.kind, list);
28
+ }
29
+ return map;
30
+ }
31
+ export function buildDesignQuestionnaire(dna, patterns) {
32
+ if (!dna && !patterns) {
33
+ return { generatedAt: '1970-01-01T00:00:00.000Z', phase: 'design', questions: [] };
34
+ }
35
+ const counters = new Map();
36
+ const questions = [];
37
+ const generatedAt = patterns?.generatedAt ?? dna?.generatedAt ?? '1970-01-01T00:00:00.000Z';
38
+ if (dna) {
39
+ const layers = dna.architecture.detectedLayers;
40
+ if (layers.length > 3 || dna.architecture.guess.toLowerCase().includes('unknown')) {
41
+ questions.push({
42
+ id: nextId(counters, 'analyst', 'ambiguity'),
43
+ persona: 'analyst',
44
+ phase: 'design',
45
+ prompt: `Arquitetura detectada: "${dna.architecture.guess}" com camadas [${layers.join(', ')}]. Confirmar o padrão dominante?`,
46
+ anchoredOn: ['dna:architecture'],
47
+ kind: 'ambiguity',
48
+ });
49
+ }
50
+ if (!dna.libraries.validation && (dna.libraries.http || dna.libraries.orm)) {
51
+ questions.push({
52
+ id: nextId(counters, 'analyst', 'scope'),
53
+ persona: 'analyst',
54
+ phase: 'design',
55
+ prompt: 'Biblioteca de validação não detectada no DNA, mas há HTTP/ORM. Qual estratégia de validação o projeto usa?',
56
+ anchoredOn: ['dna:libraries'],
57
+ kind: 'scope',
58
+ });
59
+ }
60
+ }
61
+ if (patterns) {
62
+ const byKind = patternsByKind(patterns.patterns);
63
+ for (const kind of KIND_ORDER) {
64
+ const list = byKind.get(kind) ?? [];
65
+ if (list.length === 0) {
66
+ questions.push({
67
+ id: nextId(counters, 'analyst', 'gap'),
68
+ persona: 'analyst',
69
+ phase: 'design',
70
+ prompt: `Nenhum padrão detectado na categoria "${kind}". Confirmar se esta categoria se aplica ao projeto?`,
71
+ anchoredOn: [`patterns:kind:${kind}`],
72
+ kind: 'gap',
73
+ });
74
+ }
75
+ }
76
+ for (const p of patterns.patterns) {
77
+ if (p.marker === 'gap' || p.coverage < 0.5) {
78
+ questions.push({
79
+ id: nextId(counters, 'analyst', 'gap'),
80
+ persona: 'analyst',
81
+ phase: 'design',
82
+ prompt: `${p.description} (cobertura ${(p.coverage * 100).toFixed(0)}%). Confirmar relevância deste padrão?`,
83
+ anchoredOn: [p.id],
84
+ kind: 'gap',
85
+ });
86
+ }
87
+ if ((p.kind === 'naming-idiom' || p.kind === 'call-idiom') &&
88
+ p.frequency >= 2) {
89
+ questions.push({
90
+ id: nextId(counters, 'pm', 'scope'),
91
+ persona: 'pm',
92
+ phase: 'design',
93
+ prompt: `Padrão "${p.id}" (${p.frequency} ocorrências): quais critérios de aceite devem preservar este idioma?`,
94
+ anchoredOn: [p.id],
95
+ kind: 'scope',
96
+ });
97
+ }
98
+ }
99
+ }
100
+ return {
101
+ generatedAt,
102
+ phase: 'design',
103
+ questions: sortQuestions(questions),
104
+ };
105
+ }
106
+ export function buildBlueprintQuestionnaire(patterns) {
107
+ if (!patterns || patterns.patterns.length === 0) {
108
+ return { generatedAt: '1970-01-01T00:00:00.000Z', phase: 'blueprint', questions: [] };
109
+ }
110
+ const counters = new Map();
111
+ const questions = [];
112
+ for (const p of patterns.patterns) {
113
+ if (p.kind !== 'implicit-decision' && p.kind !== 'structural-idiom')
114
+ continue;
115
+ questions.push({
116
+ id: nextId(counters, 'architect', 'tradeoff'),
117
+ persona: 'architect',
118
+ phase: 'blueprint',
119
+ prompt: `${p.description} — manter como padrão ou abstrair para nova feature?`,
120
+ anchoredOn: [p.id],
121
+ kind: 'tradeoff',
122
+ });
123
+ }
124
+ return {
125
+ generatedAt: patterns.generatedAt,
126
+ phase: 'blueprint',
127
+ questions: sortQuestions(questions),
128
+ };
129
+ }
130
+ /** Markdown block for DESIGN.md (deterministic; CLI does not answer — skill conducts 1 passagem). */
131
+ export function renderDesignQuestionnaireBlock(artifact) {
132
+ const lines = [
133
+ '## Perguntas de Planejamento (Analyst/PM)',
134
+ '',
135
+ '> Questionário determinístico (fatos+gaps). O CLI não responde — a skill `/dare-design` conduz **1 passagem sequencial**.',
136
+ '',
137
+ ];
138
+ if (artifact.questions.length === 0) {
139
+ lines.push('_Nenhuma pergunta gerada — execute `dare dna` e `dare patterns` primeiro._', '');
140
+ return lines.join('\n');
141
+ }
142
+ for (const q of artifact.questions) {
143
+ const anchor = q.anchoredOn.map((a) => `\`${a}\``).join(', ');
144
+ lines.push(`### ${q.id} (${q.persona} · ${q.kind})`);
145
+ lines.push(`- **Ancorado em:** ${anchor}`);
146
+ lines.push(`- **Pergunta:** ${q.prompt}`);
147
+ lines.push('');
148
+ }
149
+ return lines.join('\n');
150
+ }
151
+ //# sourceMappingURL=design-questionnaire.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design-questionnaire.js","sourceRoot":"","sources":["../../src/utils/design-questionnaire.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { Marker } from './confidence.js';
2
+ import type { DnaFacts } from './dna-detector.js';
3
+ import { type ModuleInfo } from './module-detector.js';
4
+ export type PatternKind = 'inferred-layer' | 'naming-idiom' | 'structural-idiom' | 'call-idiom' | 'implicit-decision';
5
+ export interface PatternEvidence {
6
+ readonly file: string;
7
+ readonly line?: number;
8
+ }
9
+ export interface DiscoveredPattern {
10
+ readonly id: string;
11
+ readonly kind: PatternKind;
12
+ readonly description: string;
13
+ readonly frequency: number;
14
+ readonly coverage: number;
15
+ readonly evidence: readonly PatternEvidence[];
16
+ readonly modules: readonly string[];
17
+ readonly marker: Marker;
18
+ }
19
+ export interface PatternsFacts {
20
+ readonly generatedAt: string;
21
+ readonly fileInventorySource: DnaFacts['fileInventorySource'];
22
+ readonly patterns: readonly DiscoveredPattern[];
23
+ }
24
+ export interface PatternRuleInput {
25
+ readonly files: readonly string[];
26
+ readonly modules: readonly ModuleInfo[];
27
+ readonly dna: DnaFacts | null;
28
+ readonly readFile: (rel: string) => string | null;
29
+ }
30
+ export interface PatternRule {
31
+ readonly kind: PatternKind;
32
+ readonly minFrequency: number;
33
+ detect(input: PatternRuleInput): DiscoveredPattern[];
34
+ }
35
+ export declare const PATTERN_RULES: readonly PatternRule[];
36
+ export declare function detectPatterns(root: string, dna: DnaFacts | null, opts?: {
37
+ modulesOnly?: readonly string[];
38
+ }): Promise<PatternsFacts>;
39
+ //# sourceMappingURL=pattern-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-detector.d.ts","sourceRoot":"","sources":["../../src/utils/pattern-detector.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEtE,MAAM,MAAM,WAAW,GACnB,gBAAgB,GAChB,cAAc,GACd,kBAAkB,GAClB,YAAY,GACZ,mBAAmB,CAAC;AAExB,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,mBAAmB,EAAE,QAAQ,CAAC,qBAAqB,CAAC,CAAC;IAC9D,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACjD;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IACxC,QAAQ,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACnD;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,MAAM,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,EAAE,CAAC;CACtD;AAqRD,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAM/C,CAAC;AA2DF,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,QAAQ,GAAG,IAAI,EACpB,IAAI,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GACzC,OAAO,CAAC,aAAa,CAAC,CAmBxB"}