@tienne/gestalt 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.
- package/CLAUDE.md +203 -0
- package/README.md +60 -0
- package/agents/closure-completer/AGENT.md +32 -0
- package/agents/continuity-judge/AGENT.md +40 -0
- package/agents/ground-mapper/AGENT.md +31 -0
- package/agents/proximity-worker/AGENT.md +33 -0
- package/agents/similarity-crystallizer/AGENT.md +34 -0
- package/dist/agents/closure-completer/AGENT.md +32 -0
- package/dist/agents/continuity-judge/AGENT.md +40 -0
- package/dist/agents/ground-mapper/AGENT.md +31 -0
- package/dist/agents/proximity-worker/AGENT.md +33 -0
- package/dist/agents/similarity-crystallizer/AGENT.md +34 -0
- package/dist/bin/gestalt.d.ts +3 -0
- package/dist/bin/gestalt.d.ts.map +1 -0
- package/dist/bin/gestalt.js +5 -0
- package/dist/bin/gestalt.js.map +1 -0
- package/dist/skills/execute/SKILL.md +84 -0
- package/dist/skills/interview/SKILL.md +82 -0
- package/dist/skills/seed/SKILL.md +92 -0
- package/dist/skills/spec/SKILL.md +92 -0
- package/dist/src/agent/figural-router.d.ts +48 -0
- package/dist/src/agent/figural-router.d.ts.map +1 -0
- package/dist/src/agent/figural-router.js +55 -0
- package/dist/src/agent/figural-router.js.map +1 -0
- package/dist/src/agent/parser.d.ts +3 -0
- package/dist/src/agent/parser.d.ts.map +1 -0
- package/dist/src/agent/parser.js +32 -0
- package/dist/src/agent/parser.js.map +1 -0
- package/dist/src/agent/prompt-resolver.d.ts +17 -0
- package/dist/src/agent/prompt-resolver.d.ts.map +1 -0
- package/dist/src/agent/prompt-resolver.js +31 -0
- package/dist/src/agent/prompt-resolver.js.map +1 -0
- package/dist/src/agent/registry.d.ts +9 -0
- package/dist/src/agent/registry.d.ts.map +1 -0
- package/dist/src/agent/registry.js +22 -0
- package/dist/src/agent/registry.js.map +1 -0
- package/dist/src/cli/commands/interview.d.ts +2 -0
- package/dist/src/cli/commands/interview.d.ts.map +1 -0
- package/dist/src/cli/commands/interview.js +67 -0
- package/dist/src/cli/commands/interview.js.map +1 -0
- package/dist/src/cli/commands/seed.d.ts +4 -0
- package/dist/src/cli/commands/seed.d.ts.map +1 -0
- package/dist/src/cli/commands/seed.js +34 -0
- package/dist/src/cli/commands/seed.js.map +1 -0
- package/dist/src/cli/commands/serve.d.ts +2 -0
- package/dist/src/cli/commands/serve.d.ts.map +1 -0
- package/dist/src/cli/commands/serve.js +5 -0
- package/dist/src/cli/commands/serve.js.map +1 -0
- package/dist/src/cli/commands/spec.d.ts +4 -0
- package/dist/src/cli/commands/spec.d.ts.map +1 -0
- package/dist/src/cli/commands/spec.js +34 -0
- package/dist/src/cli/commands/spec.js.map +1 -0
- package/dist/src/cli/commands/status.d.ts +2 -0
- package/dist/src/cli/commands/status.d.ts.map +1 -0
- package/dist/src/cli/commands/status.js +66 -0
- package/dist/src/cli/commands/status.js.map +1 -0
- package/dist/src/cli/index.d.ts +3 -0
- package/dist/src/cli/index.d.ts.map +1 -0
- package/dist/src/cli/index.js +39 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/core/config.d.ts +36 -0
- package/dist/src/core/config.d.ts.map +1 -0
- package/dist/src/core/config.js +65 -0
- package/dist/src/core/config.js.map +1 -0
- package/dist/src/core/constants.d.ts +34 -0
- package/dist/src/core/constants.d.ts.map +1 -0
- package/dist/src/core/constants.js +68 -0
- package/dist/src/core/constants.js.map +1 -0
- package/dist/src/core/errors.d.ts +50 -0
- package/dist/src/core/errors.d.ts.map +1 -0
- package/dist/src/core/errors.js +99 -0
- package/dist/src/core/errors.js.map +1 -0
- package/dist/src/core/log.d.ts +5 -0
- package/dist/src/core/log.d.ts.map +1 -0
- package/dist/src/core/log.js +7 -0
- package/dist/src/core/log.js.map +1 -0
- package/dist/src/core/result.d.ts +20 -0
- package/dist/src/core/result.d.ts.map +1 -0
- package/dist/src/core/result.js +43 -0
- package/dist/src/core/result.js.map +1 -0
- package/dist/src/core/types.d.ts +289 -0
- package/dist/src/core/types.d.ts.map +1 -0
- package/dist/src/core/types.js +15 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/events/store.d.ts +22 -0
- package/dist/src/events/store.d.ts.map +1 -0
- package/dist/src/events/store.js +130 -0
- package/dist/src/events/store.js.map +1 -0
- package/dist/src/events/types.d.ts +33 -0
- package/dist/src/events/types.d.ts.map +1 -0
- package/dist/src/events/types.js +35 -0
- package/dist/src/events/types.js.map +1 -0
- package/dist/src/execute/dag-validator.d.ts +7 -0
- package/dist/src/execute/dag-validator.d.ts.map +1 -0
- package/dist/src/execute/dag-validator.js +141 -0
- package/dist/src/execute/dag-validator.js.map +1 -0
- package/dist/src/execute/drift-detector.d.ts +11 -0
- package/dist/src/execute/drift-detector.d.ts.map +1 -0
- package/dist/src/execute/drift-detector.js +111 -0
- package/dist/src/execute/drift-detector.js.map +1 -0
- package/dist/src/execute/impact-identifier.d.ts +12 -0
- package/dist/src/execute/impact-identifier.d.ts.map +1 -0
- package/dist/src/execute/impact-identifier.js +60 -0
- package/dist/src/execute/impact-identifier.js.map +1 -0
- package/dist/src/execute/passthrough-engine.d.ts +181 -0
- package/dist/src/execute/passthrough-engine.d.ts.map +1 -0
- package/dist/src/execute/passthrough-engine.js +795 -0
- package/dist/src/execute/passthrough-engine.js.map +1 -0
- package/dist/src/execute/prompts.d.ts +19 -0
- package/dist/src/execute/prompts.d.ts.map +1 -0
- package/dist/src/execute/prompts.js +505 -0
- package/dist/src/execute/prompts.js.map +1 -0
- package/dist/src/execute/repository.d.ts +30 -0
- package/dist/src/execute/repository.d.ts.map +1 -0
- package/dist/src/execute/repository.js +248 -0
- package/dist/src/execute/repository.js.map +1 -0
- package/dist/src/execute/session.d.ts +34 -0
- package/dist/src/execute/session.d.ts.map +1 -0
- package/dist/src/execute/session.js +273 -0
- package/dist/src/execute/session.js.map +1 -0
- package/dist/src/execute/spec-patch-applier.d.ts +13 -0
- package/dist/src/execute/spec-patch-applier.d.ts.map +1 -0
- package/dist/src/execute/spec-patch-applier.js +83 -0
- package/dist/src/execute/spec-patch-applier.js.map +1 -0
- package/dist/src/execute/spec-patch-validator.d.ts +20 -0
- package/dist/src/execute/spec-patch-validator.d.ts.map +1 -0
- package/dist/src/execute/spec-patch-validator.js +60 -0
- package/dist/src/execute/spec-patch-validator.js.map +1 -0
- package/dist/src/execute/termination-detector.d.ts +20 -0
- package/dist/src/execute/termination-detector.d.ts.map +1 -0
- package/dist/src/execute/termination-detector.js +77 -0
- package/dist/src/execute/termination-detector.js.map +1 -0
- package/dist/src/gestalt/analyzer.d.ts +18 -0
- package/dist/src/gestalt/analyzer.d.ts.map +1 -0
- package/dist/src/gestalt/analyzer.js +59 -0
- package/dist/src/gestalt/analyzer.js.map +1 -0
- package/dist/src/gestalt/principles.d.ts +21 -0
- package/dist/src/gestalt/principles.d.ts.map +1 -0
- package/dist/src/gestalt/principles.js +66 -0
- package/dist/src/gestalt/principles.js.map +1 -0
- package/dist/src/index.d.ts +22 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +22 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/interview/ambiguity.d.ts +8 -0
- package/dist/src/interview/ambiguity.d.ts.map +1 -0
- package/dist/src/interview/ambiguity.js +69 -0
- package/dist/src/interview/ambiguity.js.map +1 -0
- package/dist/src/interview/brownfield.d.ts +7 -0
- package/dist/src/interview/brownfield.d.ts.map +1 -0
- package/dist/src/interview/brownfield.js +28 -0
- package/dist/src/interview/brownfield.js.map +1 -0
- package/dist/src/interview/engine.d.ts +31 -0
- package/dist/src/interview/engine.d.ts.map +1 -0
- package/dist/src/interview/engine.js +110 -0
- package/dist/src/interview/engine.js.map +1 -0
- package/dist/src/interview/passthrough-engine.d.ts +52 -0
- package/dist/src/interview/passthrough-engine.d.ts.map +1 -0
- package/dist/src/interview/passthrough-engine.js +174 -0
- package/dist/src/interview/passthrough-engine.js.map +1 -0
- package/dist/src/interview/questions.d.ts +12 -0
- package/dist/src/interview/questions.d.ts.map +1 -0
- package/dist/src/interview/questions.js +54 -0
- package/dist/src/interview/questions.js.map +1 -0
- package/dist/src/interview/repository.d.ts +25 -0
- package/dist/src/interview/repository.d.ts.map +1 -0
- package/dist/src/interview/repository.js +102 -0
- package/dist/src/interview/repository.js.map +1 -0
- package/dist/src/interview/session.d.ts +22 -0
- package/dist/src/interview/session.d.ts.map +1 -0
- package/dist/src/interview/session.js +120 -0
- package/dist/src/interview/session.js.map +1 -0
- package/dist/src/llm/adapter.d.ts +8 -0
- package/dist/src/llm/adapter.d.ts.map +1 -0
- package/dist/src/llm/adapter.js +42 -0
- package/dist/src/llm/adapter.js.map +1 -0
- package/dist/src/llm/openai-adapter.d.ts +8 -0
- package/dist/src/llm/openai-adapter.d.ts.map +1 -0
- package/dist/src/llm/openai-adapter.js +45 -0
- package/dist/src/llm/openai-adapter.js.map +1 -0
- package/dist/src/llm/prompts.d.ts +15 -0
- package/dist/src/llm/prompts.d.ts.map +1 -0
- package/dist/src/llm/prompts.js +83 -0
- package/dist/src/llm/prompts.js.map +1 -0
- package/dist/src/llm/types.d.ts +21 -0
- package/dist/src/llm/types.d.ts.map +1 -0
- package/dist/src/llm/types.js +2 -0
- package/dist/src/llm/types.js.map +1 -0
- package/dist/src/mcp/schemas.d.ts +799 -0
- package/dist/src/mcp/schemas.d.ts.map +1 -0
- package/dist/src/mcp/schemas.js +151 -0
- package/dist/src/mcp/schemas.js.map +1 -0
- package/dist/src/mcp/server.d.ts +13 -0
- package/dist/src/mcp/server.d.ts.map +1 -0
- package/dist/src/mcp/server.js +255 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/mcp/tools/execute-passthrough.d.ts +4 -0
- package/dist/src/mcp/tools/execute-passthrough.d.ts.map +1 -0
- package/dist/src/mcp/tools/execute-passthrough.js +349 -0
- package/dist/src/mcp/tools/execute-passthrough.js.map +1 -0
- package/dist/src/mcp/tools/index.d.ts +4 -0
- package/dist/src/mcp/tools/index.d.ts.map +1 -0
- package/dist/src/mcp/tools/index.js +4 -0
- package/dist/src/mcp/tools/index.js.map +1 -0
- package/dist/src/mcp/tools/interview-passthrough.d.ts +4 -0
- package/dist/src/mcp/tools/interview-passthrough.d.ts.map +1 -0
- package/dist/src/mcp/tools/interview-passthrough.js +96 -0
- package/dist/src/mcp/tools/interview-passthrough.js.map +1 -0
- package/dist/src/mcp/tools/interview.d.ts +4 -0
- package/dist/src/mcp/tools/interview.d.ts.map +1 -0
- package/dist/src/mcp/tools/interview.js +85 -0
- package/dist/src/mcp/tools/interview.js.map +1 -0
- package/dist/src/mcp/tools/seed-passthrough.d.ts +5 -0
- package/dist/src/mcp/tools/seed-passthrough.d.ts.map +1 -0
- package/dist/src/mcp/tools/seed-passthrough.js +29 -0
- package/dist/src/mcp/tools/seed-passthrough.js.map +1 -0
- package/dist/src/mcp/tools/seed.d.ts +5 -0
- package/dist/src/mcp/tools/seed.d.ts.map +1 -0
- package/dist/src/mcp/tools/seed.js +19 -0
- package/dist/src/mcp/tools/seed.js.map +1 -0
- package/dist/src/mcp/tools/spec-passthrough.d.ts +5 -0
- package/dist/src/mcp/tools/spec-passthrough.d.ts.map +1 -0
- package/dist/src/mcp/tools/spec-passthrough.js +29 -0
- package/dist/src/mcp/tools/spec-passthrough.js.map +1 -0
- package/dist/src/mcp/tools/spec.d.ts +5 -0
- package/dist/src/mcp/tools/spec.d.ts.map +1 -0
- package/dist/src/mcp/tools/spec.js +19 -0
- package/dist/src/mcp/tools/spec.js.map +1 -0
- package/dist/src/mcp/tools/status.d.ts +4 -0
- package/dist/src/mcp/tools/status.d.ts.map +1 -0
- package/dist/src/mcp/tools/status.js +45 -0
- package/dist/src/mcp/tools/status.js.map +1 -0
- package/dist/src/registry/base-registry.d.ts +26 -0
- package/dist/src/registry/base-registry.d.ts.map +1 -0
- package/dist/src/registry/base-registry.js +82 -0
- package/dist/src/registry/base-registry.js.map +1 -0
- package/dist/src/seed/extractor.d.ts +15 -0
- package/dist/src/seed/extractor.d.ts.map +1 -0
- package/dist/src/seed/extractor.js +88 -0
- package/dist/src/seed/extractor.js.map +1 -0
- package/dist/src/seed/generator.d.ts +12 -0
- package/dist/src/seed/generator.d.ts.map +1 -0
- package/dist/src/seed/generator.js +66 -0
- package/dist/src/seed/generator.js.map +1 -0
- package/dist/src/seed/passthrough-generator.d.ts +31 -0
- package/dist/src/seed/passthrough-generator.d.ts.map +1 -0
- package/dist/src/seed/passthrough-generator.js +80 -0
- package/dist/src/seed/passthrough-generator.js.map +1 -0
- package/dist/src/seed/schema.d.ts +145 -0
- package/dist/src/seed/schema.d.ts.map +1 -0
- package/dist/src/seed/schema.js +37 -0
- package/dist/src/seed/schema.js.map +1 -0
- package/dist/src/skills/executor.d.ts +14 -0
- package/dist/src/skills/executor.d.ts.map +1 -0
- package/dist/src/skills/executor.js +17 -0
- package/dist/src/skills/executor.js.map +1 -0
- package/dist/src/skills/parser.d.ts +3 -0
- package/dist/src/skills/parser.d.ts.map +1 -0
- package/dist/src/skills/parser.js +37 -0
- package/dist/src/skills/parser.js.map +1 -0
- package/dist/src/skills/registry.d.ts +8 -0
- package/dist/src/skills/registry.d.ts.map +1 -0
- package/dist/src/skills/registry.js +19 -0
- package/dist/src/skills/registry.js.map +1 -0
- package/dist/src/skills/types.d.ts +19 -0
- package/dist/src/skills/types.d.ts.map +1 -0
- package/dist/src/skills/types.js +2 -0
- package/dist/src/skills/types.js.map +1 -0
- package/dist/src/spec/extractor.d.ts +15 -0
- package/dist/src/spec/extractor.d.ts.map +1 -0
- package/dist/src/spec/extractor.js +88 -0
- package/dist/src/spec/extractor.js.map +1 -0
- package/dist/src/spec/generator.d.ts +12 -0
- package/dist/src/spec/generator.d.ts.map +1 -0
- package/dist/src/spec/generator.js +66 -0
- package/dist/src/spec/generator.js.map +1 -0
- package/dist/src/spec/passthrough-generator.d.ts +34 -0
- package/dist/src/spec/passthrough-generator.d.ts.map +1 -0
- package/dist/src/spec/passthrough-generator.js +86 -0
- package/dist/src/spec/passthrough-generator.js.map +1 -0
- package/dist/src/spec/schema.d.ts +145 -0
- package/dist/src/spec/schema.d.ts.map +1 -0
- package/dist/src/spec/schema.js +37 -0
- package/dist/src/spec/schema.js.map +1 -0
- package/package.json +53 -0
- package/skills/execute/SKILL.md +84 -0
- package/skills/interview/SKILL.md +82 -0
- package/skills/spec/SKILL.md +92 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spec Patch Applier — 검증 완료된 패치를 현재 Spec에 머지한다.
|
|
3
|
+
*
|
|
4
|
+
* 반환: { newSpec, delta }
|
|
5
|
+
* - newSpec: 패치 적용된 새 Spec (원본 불변)
|
|
6
|
+
* - delta: 변경 필드 목록 + Jaccard similarity
|
|
7
|
+
*/
|
|
8
|
+
export function applySpecPatch(currentSpec, patch, generation) {
|
|
9
|
+
const fieldsChanged = [];
|
|
10
|
+
const newSpec = structuredClone(currentSpec);
|
|
11
|
+
// L1: acceptanceCriteria
|
|
12
|
+
if (patch.acceptanceCriteria) {
|
|
13
|
+
newSpec.acceptanceCriteria = patch.acceptanceCriteria;
|
|
14
|
+
fieldsChanged.push('acceptanceCriteria');
|
|
15
|
+
}
|
|
16
|
+
// L2: constraints
|
|
17
|
+
if (patch.constraints) {
|
|
18
|
+
newSpec.constraints = patch.constraints;
|
|
19
|
+
fieldsChanged.push('constraints');
|
|
20
|
+
}
|
|
21
|
+
// L3: ontologySchema (add/modify only, validated upstream)
|
|
22
|
+
if (patch.ontologySchema) {
|
|
23
|
+
if (patch.ontologySchema.entities) {
|
|
24
|
+
newSpec.ontologySchema.entities = patch.ontologySchema.entities;
|
|
25
|
+
fieldsChanged.push('ontologySchema.entities');
|
|
26
|
+
}
|
|
27
|
+
if (patch.ontologySchema.relations) {
|
|
28
|
+
newSpec.ontologySchema.relations = patch.ontologySchema.relations;
|
|
29
|
+
fieldsChanged.push('ontologySchema.relations');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Update metadata generation timestamp
|
|
33
|
+
newSpec.metadata = {
|
|
34
|
+
...newSpec.metadata,
|
|
35
|
+
generatedAt: new Date().toISOString(),
|
|
36
|
+
};
|
|
37
|
+
const similarity = computeSpecSimilarity(currentSpec, newSpec);
|
|
38
|
+
return {
|
|
39
|
+
newSpec,
|
|
40
|
+
delta: {
|
|
41
|
+
fieldsChanged,
|
|
42
|
+
similarity,
|
|
43
|
+
generation,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Jaccard similarity between two Specs (token-level comparison of serialized content).
|
|
49
|
+
*/
|
|
50
|
+
function computeSpecSimilarity(a, b) {
|
|
51
|
+
const tokensA = tokenize(serializeComparable(a));
|
|
52
|
+
const tokensB = tokenize(serializeComparable(b));
|
|
53
|
+
if (tokensA.size === 0 && tokensB.size === 0)
|
|
54
|
+
return 1;
|
|
55
|
+
if (tokensA.size === 0 || tokensB.size === 0)
|
|
56
|
+
return 0;
|
|
57
|
+
let intersection = 0;
|
|
58
|
+
for (const t of tokensA) {
|
|
59
|
+
if (tokensB.has(t))
|
|
60
|
+
intersection++;
|
|
61
|
+
}
|
|
62
|
+
const union = tokensA.size + tokensB.size - intersection;
|
|
63
|
+
return union === 0 ? 1 : Math.round((intersection / union) * 1000) / 1000;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Serialize comparable fields (exclude metadata/timestamps).
|
|
67
|
+
*/
|
|
68
|
+
function serializeComparable(spec) {
|
|
69
|
+
return JSON.stringify({
|
|
70
|
+
goal: spec.goal,
|
|
71
|
+
constraints: spec.constraints,
|
|
72
|
+
acceptanceCriteria: spec.acceptanceCriteria,
|
|
73
|
+
ontologySchema: spec.ontologySchema,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function tokenize(text) {
|
|
77
|
+
return new Set(text
|
|
78
|
+
.toLowerCase()
|
|
79
|
+
.replace(/[^a-z0-9가-힣\s]/g, ' ')
|
|
80
|
+
.split(/\s+/)
|
|
81
|
+
.filter((t) => t.length > 1));
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=spec-patch-applier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-patch-applier.js","sourceRoot":"","sources":["../../../src/execute/spec-patch-applier.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,WAAiB,EACjB,KAAgB,EAChB,UAAkB;IAElB,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,MAAM,OAAO,GAAS,eAAe,CAAC,WAAW,CAAC,CAAC;IAEnD,yBAAyB;IACzB,IAAI,KAAK,CAAC,kBAAkB,EAAE,CAAC;QAC7B,OAAO,CAAC,kBAAkB,GAAG,KAAK,CAAC,kBAAkB,CAAC;QACtD,aAAa,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAC3C,CAAC;IAED,kBAAkB;IAClB,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACtB,OAAO,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;QACxC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACpC,CAAC;IAED,2DAA2D;IAC3D,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;QACzB,IAAI,KAAK,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;YAClC,OAAO,CAAC,cAAc,CAAC,QAAQ,GAAG,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC;YAChE,aAAa,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAChD,CAAC;QACD,IAAI,KAAK,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC;YACnC,OAAO,CAAC,cAAc,CAAC,SAAS,GAAG,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC;YAClE,aAAa,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,OAAO,CAAC,QAAQ,GAAG;QACjB,GAAG,OAAO,CAAC,QAAQ;QACnB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACtC,CAAC;IAEF,MAAM,UAAU,GAAG,qBAAqB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAE/D,OAAO;QACL,OAAO;QACP,KAAK,EAAE;YACL,aAAa;YACb,UAAU;YACV,UAAU;SACX;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,CAAO,EAAE,CAAO;IAC7C,MAAM,OAAO,GAAG,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjD,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACvD,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAEvD,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,YAAY,EAAE,CAAC;IACrC,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,GAAG,YAAY,CAAC;IACzD,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;AAC5E,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,IAAU;IACrC,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;QAC3C,cAAc,EAAE,IAAI,CAAC,cAAc;KACpC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,IAAI,GAAG,CACZ,IAAI;SACD,WAAW,EAAE;SACb,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC;SAC/B,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAC/B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { SpecPatch, Spec } from '../core/types.js';
|
|
2
|
+
export interface PatchValidationError {
|
|
3
|
+
field: string;
|
|
4
|
+
message: string;
|
|
5
|
+
}
|
|
6
|
+
export interface PatchValidationResult {
|
|
7
|
+
valid: boolean;
|
|
8
|
+
errors: PatchValidationError[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Spec Patch Validator — 패치 범위 제약을 검증한다.
|
|
12
|
+
*
|
|
13
|
+
* 허용 범위 (L1~L3):
|
|
14
|
+
* L1: acceptanceCriteria — 자유 수정 (추가/변경/삭제)
|
|
15
|
+
* L2: constraints — 자유 수정
|
|
16
|
+
* L3: ontologySchema — 선택적 (추가/변경만, entity/relation 삭제 불가)
|
|
17
|
+
* L4: goal — 변경 금지
|
|
18
|
+
*/
|
|
19
|
+
export declare function validateSpecPatch(patch: SpecPatch, currentSpec: Spec): PatchValidationResult;
|
|
20
|
+
//# sourceMappingURL=spec-patch-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-patch-validator.d.ts","sourceRoot":"","sources":["../../../src/execute/spec-patch-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,oBAAoB,EAAE,CAAC;CAChC;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,GAAG,qBAAqB,CA0D5F"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spec Patch Validator — 패치 범위 제약을 검증한다.
|
|
3
|
+
*
|
|
4
|
+
* 허용 범위 (L1~L3):
|
|
5
|
+
* L1: acceptanceCriteria — 자유 수정 (추가/변경/삭제)
|
|
6
|
+
* L2: constraints — 자유 수정
|
|
7
|
+
* L3: ontologySchema — 선택적 (추가/변경만, entity/relation 삭제 불가)
|
|
8
|
+
* L4: goal — 변경 금지
|
|
9
|
+
*/
|
|
10
|
+
export function validateSpecPatch(patch, currentSpec) {
|
|
11
|
+
const errors = [];
|
|
12
|
+
// goal 변경 시도 감지 (SpecPatch 타입에 goal이 없으므로 런타임 체크)
|
|
13
|
+
if ('goal' in patch) {
|
|
14
|
+
errors.push({
|
|
15
|
+
field: 'goal',
|
|
16
|
+
message: 'Goal modification is forbidden (L4). The goal must remain unchanged.',
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
// L1: acceptanceCriteria — 자유 수정, 단 비어있으면 안 됨
|
|
20
|
+
if (patch.acceptanceCriteria !== undefined) {
|
|
21
|
+
if (patch.acceptanceCriteria.length === 0) {
|
|
22
|
+
errors.push({
|
|
23
|
+
field: 'acceptanceCriteria',
|
|
24
|
+
message: 'acceptanceCriteria cannot be empty.',
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// L3: ontologySchema — 삭제 불가 검증
|
|
29
|
+
if (patch.ontologySchema) {
|
|
30
|
+
if (patch.ontologySchema.entities) {
|
|
31
|
+
const currentNames = new Set(currentSpec.ontologySchema.entities.map((e) => e.name));
|
|
32
|
+
const patchNames = new Set(patch.ontologySchema.entities.map((e) => e.name));
|
|
33
|
+
for (const name of currentNames) {
|
|
34
|
+
if (!patchNames.has(name)) {
|
|
35
|
+
errors.push({
|
|
36
|
+
field: 'ontologySchema.entities',
|
|
37
|
+
message: `Entity "${name}" cannot be deleted. L3 allows add/modify only.`,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (patch.ontologySchema.relations) {
|
|
43
|
+
const currentRelKeys = new Set(currentSpec.ontologySchema.relations.map((r) => `${r.from}->${r.to}:${r.type}`));
|
|
44
|
+
const patchRelKeys = new Set(patch.ontologySchema.relations.map((r) => `${r.from}->${r.to}:${r.type}`));
|
|
45
|
+
for (const key of currentRelKeys) {
|
|
46
|
+
if (!patchRelKeys.has(key)) {
|
|
47
|
+
errors.push({
|
|
48
|
+
field: 'ontologySchema.relations',
|
|
49
|
+
message: `Relation "${key}" cannot be deleted. L3 allows add/modify only.`,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
valid: errors.length === 0,
|
|
57
|
+
errors,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=spec-patch-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-patch-validator.js","sourceRoot":"","sources":["../../../src/execute/spec-patch-validator.ts"],"names":[],"mappings":"AAYA;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAgB,EAAE,WAAiB;IACnE,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,kDAAkD;IAClD,IAAI,MAAM,IAAK,KAAiC,EAAE,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC;YACV,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,sEAAsE;SAChF,CAAC,CAAC;IACL,CAAC;IAED,8CAA8C;IAC9C,IAAI,KAAK,CAAC,kBAAkB,KAAK,SAAS,EAAE,CAAC;QAC3C,IAAI,KAAK,CAAC,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1C,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,oBAAoB;gBAC3B,OAAO,EAAE,qCAAqC;aAC/C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;QACzB,IAAI,KAAK,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;YAClC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACrF,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7E,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;gBAChC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC1B,MAAM,CAAC,IAAI,CAAC;wBACV,KAAK,EAAE,yBAAyB;wBAChC,OAAO,EAAE,WAAW,IAAI,iDAAiD;qBAC1E,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,KAAK,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC;YACnC,MAAM,cAAc,GAAG,IAAI,GAAG,CAC5B,WAAW,CAAC,cAAc,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAChF,CAAC;YACF,MAAM,YAAY,GAAG,IAAI,GAAG,CAC1B,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAC1E,CAAC;YACF,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;gBACjC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC3B,MAAM,CAAC,IAAI,CAAC;wBACV,KAAK,EAAE,0BAA0B;wBACjC,OAAO,EAAE,aAAa,GAAG,iDAAiD;qBAC3E,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;QAC1B,MAAM;KACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { TerminationCondition, EvolutionGeneration } from '../core/types.js';
|
|
2
|
+
interface TerminationInput {
|
|
3
|
+
evolutionHistory: EvolutionGeneration[];
|
|
4
|
+
currentScore: number;
|
|
5
|
+
currentGoalAlignment: number;
|
|
6
|
+
structuralFixCount: number;
|
|
7
|
+
contextualCount: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Termination Detector — 진화 루프 종료 조건을 검사한다.
|
|
11
|
+
*
|
|
12
|
+
* 종료 조건 (우선순위 순):
|
|
13
|
+
* 1. Success: overallScore ≥ threshold AND goalAlignment ≥ threshold
|
|
14
|
+
* 2. Hard Cap: structural fix ≥ MAX_STRUCTURAL_FIX 또는 contextual ≥ MAX_CONTEXTUAL
|
|
15
|
+
* 3. Stagnation: 연속 N회 delta < threshold
|
|
16
|
+
* 4. Oscillation: 연속 N회 score가 오르내림 반복
|
|
17
|
+
*/
|
|
18
|
+
export declare function checkTermination(input: TerminationInput): TerminationCondition | null;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=termination-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"termination-detector.d.ts","sourceRoot":"","sources":["../../../src/execute/termination-detector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAWlF,UAAU,gBAAgB;IACxB,gBAAgB,EAAE,mBAAmB,EAAE,CAAC;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG,oBAAoB,GAAG,IAAI,CAuErF"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { EVOLVE_SUCCESS_THRESHOLD, EVOLVE_GOAL_ALIGNMENT_THRESHOLD, EVOLVE_STAGNATION_DELTA, EVOLVE_STAGNATION_COUNT, EVOLVE_OSCILLATION_COUNT, EVOLVE_MAX_STRUCTURAL_FIX, EVOLVE_MAX_CONTEXTUAL, } from '../core/constants.js';
|
|
2
|
+
/**
|
|
3
|
+
* Termination Detector — 진화 루프 종료 조건을 검사한다.
|
|
4
|
+
*
|
|
5
|
+
* 종료 조건 (우선순위 순):
|
|
6
|
+
* 1. Success: overallScore ≥ threshold AND goalAlignment ≥ threshold
|
|
7
|
+
* 2. Hard Cap: structural fix ≥ MAX_STRUCTURAL_FIX 또는 contextual ≥ MAX_CONTEXTUAL
|
|
8
|
+
* 3. Stagnation: 연속 N회 delta < threshold
|
|
9
|
+
* 4. Oscillation: 연속 N회 score가 오르내림 반복
|
|
10
|
+
*/
|
|
11
|
+
export function checkTermination(input) {
|
|
12
|
+
const { evolutionHistory, currentScore, currentGoalAlignment, structuralFixCount, contextualCount } = input;
|
|
13
|
+
const scoreHistory = [...evolutionHistory.map((g) => g.evaluationScore), currentScore];
|
|
14
|
+
// 1. Success
|
|
15
|
+
if (currentScore >= EVOLVE_SUCCESS_THRESHOLD && currentGoalAlignment >= EVOLVE_GOAL_ALIGNMENT_THRESHOLD) {
|
|
16
|
+
return {
|
|
17
|
+
reason: 'success',
|
|
18
|
+
scoreHistory,
|
|
19
|
+
stagnationDetected: false,
|
|
20
|
+
oscillationDetected: false,
|
|
21
|
+
hardCapReached: false,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
// 2. Hard Cap
|
|
25
|
+
if (structuralFixCount >= EVOLVE_MAX_STRUCTURAL_FIX || contextualCount >= EVOLVE_MAX_CONTEXTUAL) {
|
|
26
|
+
return {
|
|
27
|
+
reason: 'hard_cap',
|
|
28
|
+
scoreHistory,
|
|
29
|
+
stagnationDetected: false,
|
|
30
|
+
oscillationDetected: false,
|
|
31
|
+
hardCapReached: true,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
// 3. Stagnation: 연속 STAGNATION_COUNT회 이상 delta가 STAGNATION_DELTA 미만
|
|
35
|
+
if (scoreHistory.length >= EVOLVE_STAGNATION_COUNT + 1) {
|
|
36
|
+
const recentDeltas = [];
|
|
37
|
+
for (let i = scoreHistory.length - EVOLVE_STAGNATION_COUNT; i < scoreHistory.length; i++) {
|
|
38
|
+
recentDeltas.push(Math.abs(scoreHistory[i] - scoreHistory[i - 1]));
|
|
39
|
+
}
|
|
40
|
+
const isStagnant = recentDeltas.every((d) => d < EVOLVE_STAGNATION_DELTA);
|
|
41
|
+
if (isStagnant) {
|
|
42
|
+
return {
|
|
43
|
+
reason: 'stagnation',
|
|
44
|
+
scoreHistory,
|
|
45
|
+
stagnationDetected: true,
|
|
46
|
+
oscillationDetected: false,
|
|
47
|
+
hardCapReached: false,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// 4. Oscillation: 연속 OSCILLATION_COUNT회 score가 up/down 반복
|
|
52
|
+
if (scoreHistory.length >= EVOLVE_OSCILLATION_COUNT * 2 + 1) {
|
|
53
|
+
const tail = scoreHistory.slice(-(EVOLVE_OSCILLATION_COUNT * 2 + 1));
|
|
54
|
+
let oscillating = true;
|
|
55
|
+
for (let i = 1; i < tail.length - 1; i++) {
|
|
56
|
+
const prev = tail[i - 1];
|
|
57
|
+
const curr = tail[i];
|
|
58
|
+
const next = tail[i + 1];
|
|
59
|
+
// 각 중간점이 양쪽과 다른 방향이어야 oscillation
|
|
60
|
+
if (!((curr > prev && curr > next) || (curr < prev && curr < next))) {
|
|
61
|
+
oscillating = false;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (oscillating) {
|
|
66
|
+
return {
|
|
67
|
+
reason: 'oscillation',
|
|
68
|
+
scoreHistory,
|
|
69
|
+
stagnationDetected: false,
|
|
70
|
+
oscillationDetected: true,
|
|
71
|
+
hardCapReached: false,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return null; // 종료 조건 미충족 — 계속 진행
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=termination-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"termination-detector.js","sourceRoot":"","sources":["../../../src/execute/termination-detector.ts"],"names":[],"mappings":"AACA,OAAO,EACL,wBAAwB,EACxB,+BAA+B,EAC/B,uBAAuB,EACvB,uBAAuB,EACvB,wBAAwB,EACxB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAU9B;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAuB;IACtD,MAAM,EAAE,gBAAgB,EAAE,YAAY,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC;IAE5G,MAAM,YAAY,GAAG,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE,YAAY,CAAC,CAAC;IAEvF,aAAa;IACb,IAAI,YAAY,IAAI,wBAAwB,IAAI,oBAAoB,IAAI,+BAA+B,EAAE,CAAC;QACxG,OAAO;YACL,MAAM,EAAE,SAAS;YACjB,YAAY;YACZ,kBAAkB,EAAE,KAAK;YACzB,mBAAmB,EAAE,KAAK;YAC1B,cAAc,EAAE,KAAK;SACtB,CAAC;IACJ,CAAC;IAED,cAAc;IACd,IAAI,kBAAkB,IAAI,yBAAyB,IAAI,eAAe,IAAI,qBAAqB,EAAE,CAAC;QAChG,OAAO;YACL,MAAM,EAAE,UAAU;YAClB,YAAY;YACZ,kBAAkB,EAAE,KAAK;YACzB,mBAAmB,EAAE,KAAK;YAC1B,cAAc,EAAE,IAAI;SACrB,CAAC;IACJ,CAAC;IAED,oEAAoE;IACpE,IAAI,YAAY,CAAC,MAAM,IAAI,uBAAuB,GAAG,CAAC,EAAE,CAAC;QACvD,MAAM,YAAY,GAAa,EAAE,CAAC;QAClC,KAAK,IAAI,CAAC,GAAG,YAAY,CAAC,MAAM,GAAG,uBAAuB,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzF,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAE,GAAG,YAAY,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,uBAAuB,CAAC,CAAC;QAC1E,IAAI,UAAU,EAAE,CAAC;YACf,OAAO;gBACL,MAAM,EAAE,YAAY;gBACpB,YAAY;gBACZ,kBAAkB,EAAE,IAAI;gBACxB,mBAAmB,EAAE,KAAK;gBAC1B,cAAc,EAAE,KAAK;aACtB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,0DAA0D;IAC1D,IAAI,YAAY,CAAC,MAAM,IAAI,wBAAwB,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,wBAAwB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACrE,IAAI,WAAW,GAAG,IAAI,CAAC;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;YACtB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;YAC1B,kCAAkC;YAClC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC;gBACpE,WAAW,GAAG,KAAK,CAAC;gBACpB,MAAM;YACR,CAAC;QACH,CAAC;QACD,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO;gBACL,MAAM,EAAE,aAAa;gBACrB,YAAY;gBACZ,kBAAkB,EAAE,KAAK;gBACzB,mBAAmB,EAAE,IAAI;gBACzB,cAAc,EAAE,KAAK;aACtB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC,CAAC,oBAAoB;AACnC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type AmbiguityScore, type ProjectType } from '../core/types.js';
|
|
2
|
+
interface RawClarityScores {
|
|
3
|
+
/** 목표 명확도: 프로젝트의 목표가 얼마나 완전하게 정의되었는가 (Closure) */
|
|
4
|
+
goalClarity: number;
|
|
5
|
+
/** 제약사항 명확도: 제약사항이 얼마나 잘 구조화되고 그룹핑되었는가 (Proximity) */
|
|
6
|
+
constraintClarity: number;
|
|
7
|
+
/** 성공 기준 명확도: 성공 기준의 패턴이 일관적이고 측정 가능한가 (Similarity) */
|
|
8
|
+
successCriteria: number;
|
|
9
|
+
/** 우선순위 명확도: MVP와 후순위가 명확히 분리되었는가 (Figure-Ground) */
|
|
10
|
+
priorityClarity: number;
|
|
11
|
+
/** 맥락 명확도: 기존 시스템과의 일관성에 모순이 없는가 (Continuity, Brownfield 전용) */
|
|
12
|
+
contextClarity?: number;
|
|
13
|
+
/** 인터뷰 중 감지된 모순 목록 */
|
|
14
|
+
contradictions: string[];
|
|
15
|
+
}
|
|
16
|
+
export declare function computeAmbiguityScore(raw: RawClarityScores, projectType: ProjectType): AmbiguityScore;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../../src/gestalt/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EAEnB,KAAK,WAAW,EACjB,MAAM,kBAAkB,CAAC;AAS1B,UAAU,gBAAgB;IACxB,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,uDAAuD;IACvD,eAAe,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,eAAe,EAAE,MAAM,CAAC;IACxB,gEAAgE;IAChE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sBAAsB;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,gBAAgB,EACrB,WAAW,EAAE,WAAW,GACvB,cAAc,CAsDhB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { GestaltPrinciple, } from '../core/types.js';
|
|
2
|
+
import { GREENFIELD_WEIGHTS, BROWNFIELD_WEIGHTS, AMBIGUITY_THRESHOLD, CONTINUITY_PENALTY_MIN, CONTINUITY_PENALTY_MAX, } from '../core/constants.js';
|
|
3
|
+
export function computeAmbiguityScore(raw, projectType) {
|
|
4
|
+
const weights = projectType === 'greenfield' ? GREENFIELD_WEIGHTS : BROWNFIELD_WEIGHTS;
|
|
5
|
+
const dimensions = [
|
|
6
|
+
{
|
|
7
|
+
name: 'goalClarity',
|
|
8
|
+
clarity: clamp(raw.goalClarity),
|
|
9
|
+
weight: weights[GestaltPrinciple.CLOSURE],
|
|
10
|
+
gestaltPrinciple: GestaltPrinciple.CLOSURE,
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
name: 'constraintClarity',
|
|
14
|
+
clarity: clamp(raw.constraintClarity),
|
|
15
|
+
weight: weights[GestaltPrinciple.PROXIMITY],
|
|
16
|
+
gestaltPrinciple: GestaltPrinciple.PROXIMITY,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'successCriteria',
|
|
20
|
+
clarity: clamp(raw.successCriteria),
|
|
21
|
+
weight: weights[GestaltPrinciple.SIMILARITY],
|
|
22
|
+
gestaltPrinciple: GestaltPrinciple.SIMILARITY,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'priorityClarity',
|
|
26
|
+
clarity: clamp(raw.priorityClarity),
|
|
27
|
+
weight: weights[GestaltPrinciple.FIGURE_GROUND],
|
|
28
|
+
gestaltPrinciple: GestaltPrinciple.FIGURE_GROUND,
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
if (projectType === 'brownfield' && raw.contextClarity !== undefined) {
|
|
32
|
+
dimensions.push({
|
|
33
|
+
name: 'contextClarity',
|
|
34
|
+
clarity: clamp(raw.contextClarity),
|
|
35
|
+
weight: weights[GestaltPrinciple.CONTINUITY],
|
|
36
|
+
gestaltPrinciple: GestaltPrinciple.CONTINUITY,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
const weightedSum = dimensions.reduce((sum, d) => sum + d.clarity * d.weight, 0);
|
|
40
|
+
const continuityPenalty = computeContinuityPenalty(raw.contradictions);
|
|
41
|
+
const overall = clamp(1.0 - weightedSum + continuityPenalty);
|
|
42
|
+
return {
|
|
43
|
+
overall,
|
|
44
|
+
dimensions,
|
|
45
|
+
isReady: overall <= AMBIGUITY_THRESHOLD,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function computeContinuityPenalty(contradictions) {
|
|
49
|
+
if (contradictions.length === 0)
|
|
50
|
+
return 0;
|
|
51
|
+
const penalty = CONTINUITY_PENALTY_MIN +
|
|
52
|
+
(CONTINUITY_PENALTY_MAX - CONTINUITY_PENALTY_MIN) *
|
|
53
|
+
Math.min(contradictions.length / 3, 1);
|
|
54
|
+
return penalty;
|
|
55
|
+
}
|
|
56
|
+
function clamp(value, min = 0, max = 1) {
|
|
57
|
+
return Math.max(min, Math.min(max, value));
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../../src/gestalt/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,GAIjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAiB9B,MAAM,UAAU,qBAAqB,CACnC,GAAqB,EACrB,WAAwB;IAExB,MAAM,OAAO,GACX,WAAW,KAAK,YAAY,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,kBAAkB,CAAC;IAEzE,MAAM,UAAU,GAAyB;QACvC;YACE,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC;YAC/B,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC;YACzC,gBAAgB,EAAE,gBAAgB,CAAC,OAAO;SAC3C;QACD;YACE,IAAI,EAAE,mBAAmB;YACzB,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC;YACrC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC;YAC3C,gBAAgB,EAAE,gBAAgB,CAAC,SAAS;SAC7C;QACD;YACE,IAAI,EAAE,iBAAiB;YACvB,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC;YACnC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC;YAC5C,gBAAgB,EAAE,gBAAgB,CAAC,UAAU;SAC9C;QACD;YACE,IAAI,EAAE,iBAAiB;YACvB,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC;YACnC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,aAAa,CAAC;YAC/C,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;SACjD;KACF,CAAC;IAEF,IAAI,WAAW,KAAK,YAAY,IAAI,GAAG,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;QACrE,UAAU,CAAC,IAAI,CAAC;YACd,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC;YAClC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC;YAC5C,gBAAgB,EAAE,gBAAgB,CAAC,UAAU;SAC9C,CAAC,CAAC;IACL,CAAC;IAED,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CACnC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,MAAM,EACtC,CAAC,CACF,CAAC;IAEF,MAAM,iBAAiB,GAAG,wBAAwB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAEvE,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,GAAG,WAAW,GAAG,iBAAiB,CAAC,CAAC;IAE7D,OAAO;QACL,OAAO;QACP,UAAU;QACV,OAAO,EAAE,OAAO,IAAI,mBAAmB;KACxC,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAAC,cAAwB;IACxD,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,OAAO,GACX,sBAAsB;QACtB,CAAC,sBAAsB,GAAG,sBAAsB,CAAC;YAC/C,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,KAAK,CAAC,KAAa,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC;IAC5C,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { GestaltPrinciple, type AmbiguityDimension } from '../core/types.js';
|
|
2
|
+
interface PrincipleSelectionContext {
|
|
3
|
+
roundNumber: number;
|
|
4
|
+
dimensions: AmbiguityDimension[];
|
|
5
|
+
hasContradictions: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Selects the next Gestalt principle to focus on during an interview.
|
|
9
|
+
*
|
|
10
|
+
* Algorithm:
|
|
11
|
+
* - Continuity always overrides if contradictions are detected
|
|
12
|
+
* - Early rounds (1-3): Closure-first (goal definition)
|
|
13
|
+
* - Mid rounds (4-8): Proximity + Similarity (structuring)
|
|
14
|
+
* - Late rounds (9+): Figure-Ground (prioritization)
|
|
15
|
+
* - Dynamic: lowest clarity dimension gets priority
|
|
16
|
+
*/
|
|
17
|
+
export declare function selectNextPrinciple(context: PrincipleSelectionContext): GestaltPrinciple;
|
|
18
|
+
export declare function getPrinciplePhaseLabel(roundNumber: number): string;
|
|
19
|
+
export declare function getAllPrinciples(): GestaltPrinciple[];
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=principles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"principles.d.ts","sourceRoot":"","sources":["../../../src/gestalt/principles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE7E,UAAU,yBAAyB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,yBAAyB,GAAG,gBAAgB,CA0BxF;AAmBD,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAIlE;AAED,wBAAgB,gBAAgB,IAAI,gBAAgB,EAAE,CAQrD"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { GestaltPrinciple } from '../core/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Selects the next Gestalt principle to focus on during an interview.
|
|
4
|
+
*
|
|
5
|
+
* Algorithm:
|
|
6
|
+
* - Continuity always overrides if contradictions are detected
|
|
7
|
+
* - Early rounds (1-3): Closure-first (goal definition)
|
|
8
|
+
* - Mid rounds (4-8): Proximity + Similarity (structuring)
|
|
9
|
+
* - Late rounds (9+): Figure-Ground (prioritization)
|
|
10
|
+
* - Dynamic: lowest clarity dimension gets priority
|
|
11
|
+
*/
|
|
12
|
+
export function selectNextPrinciple(context) {
|
|
13
|
+
const { roundNumber, dimensions, hasContradictions } = context;
|
|
14
|
+
// Continuity always overrides when contradictions exist
|
|
15
|
+
if (hasContradictions) {
|
|
16
|
+
return GestaltPrinciple.CONTINUITY;
|
|
17
|
+
}
|
|
18
|
+
// If we have clarity data, target the weakest dimension
|
|
19
|
+
if (dimensions.length > 0) {
|
|
20
|
+
const weakest = findWeakestDimension(dimensions);
|
|
21
|
+
if (weakest && weakest.clarity < 0.5) {
|
|
22
|
+
return weakest.gestaltPrinciple;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// Phase-based defaults
|
|
26
|
+
if (roundNumber <= 3) {
|
|
27
|
+
return GestaltPrinciple.CLOSURE;
|
|
28
|
+
}
|
|
29
|
+
if (roundNumber <= 8) {
|
|
30
|
+
return roundNumber % 2 === 0
|
|
31
|
+
? GestaltPrinciple.PROXIMITY
|
|
32
|
+
: GestaltPrinciple.SIMILARITY;
|
|
33
|
+
}
|
|
34
|
+
return GestaltPrinciple.FIGURE_GROUND;
|
|
35
|
+
}
|
|
36
|
+
function findWeakestDimension(dimensions) {
|
|
37
|
+
if (dimensions.length === 0)
|
|
38
|
+
return null;
|
|
39
|
+
let weakest = dimensions[0];
|
|
40
|
+
for (const dim of dimensions) {
|
|
41
|
+
// Weight-adjusted: lower clarity in high-weight dimension is more critical
|
|
42
|
+
const currentImpact = (1 - dim.clarity) * dim.weight;
|
|
43
|
+
const weakestImpact = (1 - weakest.clarity) * weakest.weight;
|
|
44
|
+
if (currentImpact > weakestImpact) {
|
|
45
|
+
weakest = dim;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return weakest;
|
|
49
|
+
}
|
|
50
|
+
export function getPrinciplePhaseLabel(roundNumber) {
|
|
51
|
+
if (roundNumber <= 3)
|
|
52
|
+
return 'early (goal definition)';
|
|
53
|
+
if (roundNumber <= 8)
|
|
54
|
+
return 'mid (structuring)';
|
|
55
|
+
return 'late (prioritization)';
|
|
56
|
+
}
|
|
57
|
+
export function getAllPrinciples() {
|
|
58
|
+
return [
|
|
59
|
+
GestaltPrinciple.CLOSURE,
|
|
60
|
+
GestaltPrinciple.PROXIMITY,
|
|
61
|
+
GestaltPrinciple.SIMILARITY,
|
|
62
|
+
GestaltPrinciple.FIGURE_GROUND,
|
|
63
|
+
GestaltPrinciple.CONTINUITY,
|
|
64
|
+
];
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=principles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"principles.js","sourceRoot":"","sources":["../../../src/gestalt/principles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA2B,MAAM,kBAAkB,CAAC;AAQ7E;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAkC;IACpE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC;IAE/D,wDAAwD;IACxD,IAAI,iBAAiB,EAAE,CAAC;QACtB,OAAO,gBAAgB,CAAC,UAAU,CAAC;IACrC,CAAC;IAED,wDAAwD;IACxD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;QACjD,IAAI,OAAO,IAAI,OAAO,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC;YACrC,OAAO,OAAO,CAAC,gBAAgB,CAAC;QAClC,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;QACrB,OAAO,gBAAgB,CAAC,OAAO,CAAC;IAClC,CAAC;IACD,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;QACrB,OAAO,WAAW,GAAG,CAAC,KAAK,CAAC;YAC1B,CAAC,CAAC,gBAAgB,CAAC,SAAS;YAC5B,CAAC,CAAC,gBAAgB,CAAC,UAAU,CAAC;IAClC,CAAC;IACD,OAAO,gBAAgB,CAAC,aAAa,CAAC;AACxC,CAAC;AAED,SAAS,oBAAoB,CAC3B,UAAgC;IAEhC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzC,IAAI,OAAO,GAAG,UAAU,CAAC,CAAC,CAAE,CAAC;IAC7B,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,2EAA2E;QAC3E,MAAM,aAAa,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;QACrD,MAAM,aAAa,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7D,IAAI,aAAa,GAAG,aAAa,EAAE,CAAC;YAClC,OAAO,GAAG,GAAG,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,WAAmB;IACxD,IAAI,WAAW,IAAI,CAAC;QAAE,OAAO,yBAAyB,CAAC;IACvD,IAAI,WAAW,IAAI,CAAC;QAAE,OAAO,mBAAmB,CAAC;IACjD,OAAO,uBAAuB,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO;QACL,gBAAgB,CAAC,OAAO;QACxB,gBAAgB,CAAC,SAAS;QAC1B,gBAAgB,CAAC,UAAU;QAC3B,gBAAgB,CAAC,aAAa;QAC9B,gBAAgB,CAAC,UAAU;KAC5B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export * from './core/types.js';
|
|
2
|
+
export * from './core/errors.js';
|
|
3
|
+
export * from './core/result.js';
|
|
4
|
+
export * from './core/config.js';
|
|
5
|
+
export * from './core/constants.js';
|
|
6
|
+
export * from './events/types.js';
|
|
7
|
+
export * from './events/store.js';
|
|
8
|
+
export * from './gestalt/principles.js';
|
|
9
|
+
export * from './gestalt/analyzer.js';
|
|
10
|
+
export * from './interview/engine.js';
|
|
11
|
+
export * from './interview/session.js';
|
|
12
|
+
export * from './interview/ambiguity.js';
|
|
13
|
+
export * from './interview/questions.js';
|
|
14
|
+
export * from './interview/brownfield.js';
|
|
15
|
+
export * from './spec/generator.js';
|
|
16
|
+
export * from './spec/extractor.js';
|
|
17
|
+
export * from './spec/schema.js';
|
|
18
|
+
export * from './skills/registry.js';
|
|
19
|
+
export * from './skills/parser.js';
|
|
20
|
+
export * from './skills/executor.js';
|
|
21
|
+
export * from './mcp/server.js';
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export * from './core/types.js';
|
|
2
|
+
export * from './core/errors.js';
|
|
3
|
+
export * from './core/result.js';
|
|
4
|
+
export * from './core/config.js';
|
|
5
|
+
export * from './core/constants.js';
|
|
6
|
+
export * from './events/types.js';
|
|
7
|
+
export * from './events/store.js';
|
|
8
|
+
export * from './gestalt/principles.js';
|
|
9
|
+
export * from './gestalt/analyzer.js';
|
|
10
|
+
export * from './interview/engine.js';
|
|
11
|
+
export * from './interview/session.js';
|
|
12
|
+
export * from './interview/ambiguity.js';
|
|
13
|
+
export * from './interview/questions.js';
|
|
14
|
+
export * from './interview/brownfield.js';
|
|
15
|
+
export * from './spec/generator.js';
|
|
16
|
+
export * from './spec/extractor.js';
|
|
17
|
+
export * from './spec/schema.js';
|
|
18
|
+
export * from './skills/registry.js';
|
|
19
|
+
export * from './skills/parser.js';
|
|
20
|
+
export * from './skills/executor.js';
|
|
21
|
+
export * from './mcp/server.js';
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AmbiguityScore, InterviewRound, ProjectType } from '../core/types.js';
|
|
2
|
+
import type { LLMAdapter } from '../llm/types.js';
|
|
3
|
+
export declare class AmbiguityScorer {
|
|
4
|
+
private llm;
|
|
5
|
+
constructor(llm: LLMAdapter);
|
|
6
|
+
score(topic: string, rounds: InterviewRound[], projectType: ProjectType): Promise<AmbiguityScore>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=ambiguity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ambiguity.d.ts","sourceRoot":"","sources":["../../../src/interview/ambiguity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGpF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,qBAAa,eAAe;IACd,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,UAAU;IAE7B,KAAK,CACT,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,cAAc,EAAE,EACxB,WAAW,EAAE,WAAW,GACvB,OAAO,CAAC,cAAc,CAAC;CA4B3B"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { computeAmbiguityScore } from '../gestalt/analyzer.js';
|
|
2
|
+
import { buildAmbiguityPrompt, INTERVIEW_SYSTEM_PROMPT } from '../llm/prompts.js';
|
|
3
|
+
export class AmbiguityScorer {
|
|
4
|
+
llm;
|
|
5
|
+
constructor(llm) {
|
|
6
|
+
this.llm = llm;
|
|
7
|
+
}
|
|
8
|
+
async score(topic, rounds, projectType) {
|
|
9
|
+
const answeredRounds = rounds.filter((r) => r.userResponse);
|
|
10
|
+
if (answeredRounds.length === 0) {
|
|
11
|
+
return {
|
|
12
|
+
overall: 1.0,
|
|
13
|
+
dimensions: [],
|
|
14
|
+
isReady: false,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
const prompt = buildAmbiguityPrompt(topic, answeredRounds.map((r) => ({
|
|
18
|
+
question: r.question,
|
|
19
|
+
response: r.userResponse,
|
|
20
|
+
})), projectType);
|
|
21
|
+
const response = await this.llm.chat({
|
|
22
|
+
system: INTERVIEW_SYSTEM_PROMPT,
|
|
23
|
+
messages: [{ role: 'user', content: prompt }],
|
|
24
|
+
temperature: 0.3,
|
|
25
|
+
});
|
|
26
|
+
const raw = parseAmbiguityResponse(response.content, projectType);
|
|
27
|
+
return computeAmbiguityScore(raw, projectType);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function parseAmbiguityResponse(content, projectType) {
|
|
31
|
+
const jsonMatch = content.match(/\{[\s\S]*\}/);
|
|
32
|
+
if (!jsonMatch) {
|
|
33
|
+
return defaultScores(projectType);
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
37
|
+
return {
|
|
38
|
+
goalClarity: toNumber(parsed['goalClarity'], 0),
|
|
39
|
+
constraintClarity: toNumber(parsed['constraintClarity'], 0),
|
|
40
|
+
successCriteria: toNumber(parsed['successCriteria'], 0),
|
|
41
|
+
priorityClarity: toNumber(parsed['priorityClarity'], 0),
|
|
42
|
+
contextClarity: projectType === 'brownfield'
|
|
43
|
+
? toNumber(parsed['contextClarity'], 0)
|
|
44
|
+
: undefined,
|
|
45
|
+
contradictions: Array.isArray(parsed['contradictions'])
|
|
46
|
+
? parsed['contradictions']
|
|
47
|
+
: [],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return defaultScores(projectType);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function defaultScores(projectType) {
|
|
55
|
+
return {
|
|
56
|
+
goalClarity: 0,
|
|
57
|
+
constraintClarity: 0,
|
|
58
|
+
successCriteria: 0,
|
|
59
|
+
priorityClarity: 0,
|
|
60
|
+
contextClarity: projectType === 'brownfield' ? 0 : undefined,
|
|
61
|
+
contradictions: [],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function toNumber(value, fallback) {
|
|
65
|
+
if (typeof value === 'number' && !isNaN(value))
|
|
66
|
+
return value;
|
|
67
|
+
return fallback;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=ambiguity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ambiguity.js","sourceRoot":"","sources":["../../../src/interview/ambiguity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ProjectType } from '../core/types.js';
|
|
2
|
+
export interface BrownfieldResult {
|
|
3
|
+
projectType: ProjectType;
|
|
4
|
+
detectedFiles: string[];
|
|
5
|
+
}
|
|
6
|
+
export declare function detectProjectType(cwd?: string): BrownfieldResult;
|
|
7
|
+
//# sourceMappingURL=brownfield.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brownfield.d.ts","sourceRoot":"","sources":["../../../src/interview/brownfield.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAepD,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,WAAW,CAAC;IACzB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAgB,iBAAiB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAchE"}
|