@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.
- package/dist/__tests__/ide-command-parity.test.js +1 -0
- package/dist/__tests__/ide-command-parity.test.js.map +1 -1
- package/dist/__tests__/patterns-no-llm.test.d.ts +2 -0
- package/dist/__tests__/patterns-no-llm.test.d.ts.map +1 -0
- package/dist/__tests__/patterns-no-llm.test.js +31 -0
- package/dist/__tests__/patterns-no-llm.test.js.map +1 -0
- package/dist/__tests__/patterns-path-confinement.test.d.ts +2 -0
- package/dist/__tests__/patterns-path-confinement.test.d.ts.map +1 -0
- package/dist/__tests__/patterns-path-confinement.test.js +58 -0
- package/dist/__tests__/patterns-path-confinement.test.js.map +1 -0
- package/dist/__tests__/patterns.test.d.ts +2 -0
- package/dist/__tests__/patterns.test.d.ts.map +1 -0
- package/dist/__tests__/patterns.test.js +102 -0
- package/dist/__tests__/patterns.test.js.map +1 -0
- package/dist/bin/dare.js +2 -0
- package/dist/bin/dare.js.map +1 -1
- package/dist/commands/__tests__/design-interactive.test.d.ts +2 -0
- package/dist/commands/__tests__/design-interactive.test.d.ts.map +1 -0
- package/dist/commands/__tests__/design-interactive.test.js +44 -0
- package/dist/commands/__tests__/design-interactive.test.js.map +1 -0
- package/dist/commands/__tests__/patterns.test.d.ts +2 -0
- package/dist/commands/__tests__/patterns.test.d.ts.map +1 -0
- package/dist/commands/__tests__/patterns.test.js +55 -0
- package/dist/commands/__tests__/patterns.test.js.map +1 -0
- package/dist/commands/design.d.ts.map +1 -1
- package/dist/commands/design.js +38 -8
- package/dist/commands/design.js.map +1 -1
- package/dist/commands/graph.d.ts.map +1 -1
- package/dist/commands/graph.js +1 -0
- package/dist/commands/graph.js.map +1 -1
- package/dist/commands/patterns.d.ts +3 -0
- package/dist/commands/patterns.d.ts.map +1 -0
- package/dist/commands/patterns.js +124 -0
- package/dist/commands/patterns.js.map +1 -0
- package/dist/graphrag/__tests__/pattern-ingest.test.d.ts +2 -0
- package/dist/graphrag/__tests__/pattern-ingest.test.d.ts.map +1 -0
- package/dist/graphrag/__tests__/pattern-ingest.test.js +49 -0
- package/dist/graphrag/__tests__/pattern-ingest.test.js.map +1 -0
- package/dist/graphrag/__tests__/types.test.js +5 -2
- package/dist/graphrag/__tests__/types.test.js.map +1 -1
- package/dist/graphrag/pattern-ingest.d.ts +10 -0
- package/dist/graphrag/pattern-ingest.d.ts.map +1 -0
- package/dist/graphrag/pattern-ingest.js +77 -0
- package/dist/graphrag/pattern-ingest.js.map +1 -0
- package/dist/graphrag/types.d.ts +15 -4
- package/dist/graphrag/types.d.ts.map +1 -1
- package/dist/graphrag/types.js +3 -0
- package/dist/graphrag/types.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/steering/__tests__/loader.test.js +15 -0
- package/dist/steering/__tests__/loader.test.js.map +1 -1
- package/dist/steering/loader.d.ts.map +1 -1
- package/dist/steering/loader.js +11 -0
- package/dist/steering/loader.js.map +1 -1
- package/dist/utils/__tests__/design-questionnaire.test.d.ts +2 -0
- package/dist/utils/__tests__/design-questionnaire.test.d.ts.map +1 -0
- package/dist/utils/__tests__/design-questionnaire.test.js +72 -0
- package/dist/utils/__tests__/design-questionnaire.test.js.map +1 -0
- package/dist/utils/__tests__/pattern-detector.test.d.ts +2 -0
- package/dist/utils/__tests__/pattern-detector.test.d.ts.map +1 -0
- package/dist/utils/__tests__/pattern-detector.test.js +81 -0
- package/dist/utils/__tests__/pattern-detector.test.js.map +1 -0
- package/dist/utils/__tests__/pattern-facts.test.d.ts +2 -0
- package/dist/utils/__tests__/pattern-facts.test.d.ts.map +1 -0
- package/dist/utils/__tests__/pattern-facts.test.js +55 -0
- package/dist/utils/__tests__/pattern-facts.test.js.map +1 -0
- package/dist/utils/design-questionnaire.d.ts +22 -0
- package/dist/utils/design-questionnaire.d.ts.map +1 -0
- package/dist/utils/design-questionnaire.js +151 -0
- package/dist/utils/design-questionnaire.js.map +1 -0
- package/dist/utils/pattern-detector.d.ts +39 -0
- package/dist/utils/pattern-detector.d.ts.map +1 -0
- package/dist/utils/pattern-detector.js +291 -0
- package/dist/utils/pattern-detector.js.map +1 -0
- package/dist/utils/pattern-facts.d.ts +7 -0
- package/dist/utils/pattern-facts.d.ts.map +1 -0
- package/dist/utils/pattern-facts.js +86 -0
- package/dist/utils/pattern-facts.js.map +1 -0
- package/package.json +1 -1
- package/templates/ide/antigravity/.agents/skills/dare-blueprint/SKILL.md +4 -0
- package/templates/ide/antigravity/.agents/skills/dare-design/SKILL.md +11 -0
- package/templates/ide/antigravity/.agents/skills/dare-patterns/SKILL.md +9 -0
- package/templates/ide/claude/.claude/commands/dare-blueprint.md +4 -0
- package/templates/ide/claude/.claude/commands/dare-design.md +10 -0
- package/templates/ide/claude/.claude/commands/dare-patterns.md +12 -0
- package/templates/ide/cursor/.cursor/commands/dare-blueprint.md +4 -2
- package/templates/ide/cursor/.cursor/commands/dare-design.md +9 -3
- 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":"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"}
|
|
@@ -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 @@
|
|
|
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"}
|