@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 @@
|
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../src/spec/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { InterviewSession, Spec } from '../core/types.js';
|
|
2
|
+
import { AmbiguityThresholdError, SpecGenerationError } from '../core/errors.js';
|
|
3
|
+
import { type Result } from '../core/result.js';
|
|
4
|
+
import { EventStore } from '../events/store.js';
|
|
5
|
+
import type { AgentRegistry } from '../agent/registry.js';
|
|
6
|
+
export interface SpecContext {
|
|
7
|
+
systemPrompt: string;
|
|
8
|
+
specPrompt: string;
|
|
9
|
+
allRounds: {
|
|
10
|
+
roundNumber: number;
|
|
11
|
+
question: string;
|
|
12
|
+
response: string;
|
|
13
|
+
gestaltFocus: string;
|
|
14
|
+
}[];
|
|
15
|
+
activeAgents?: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface ExternalSpec {
|
|
18
|
+
goal: string;
|
|
19
|
+
constraints: string[];
|
|
20
|
+
acceptanceCriteria: string[];
|
|
21
|
+
ontologySchema: {
|
|
22
|
+
entities: unknown[];
|
|
23
|
+
relations: unknown[];
|
|
24
|
+
};
|
|
25
|
+
gestaltAnalysis: unknown[];
|
|
26
|
+
}
|
|
27
|
+
export declare class PassthroughSpecGenerator {
|
|
28
|
+
private eventStore;
|
|
29
|
+
private agentRegistry?;
|
|
30
|
+
constructor(eventStore: EventStore, agentRegistry?: AgentRegistry);
|
|
31
|
+
buildSpecContext(session: InterviewSession): SpecContext;
|
|
32
|
+
validateAndStore(session: InterviewSession, externalSpec: ExternalSpec, force?: boolean): Result<Spec, SpecGenerationError | AmbiguityThresholdError>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=passthrough-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passthrough-generator.d.ts","sourceRoot":"","sources":["../../../src/spec/passthrough-generator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAkB,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAEjF,OAAO,EAAE,KAAK,MAAM,EAAW,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAK1D,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC/F,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,cAAc,EAAE;QAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;QAAC,SAAS,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC;IAC9D,eAAe,EAAE,OAAO,EAAE,CAAC;CAC5B;AAID,qBAAa,wBAAwB;IAGvB,OAAO,CAAC,UAAU;IAF9B,OAAO,CAAC,aAAa,CAAC,CAAgB;gBAElB,UAAU,EAAE,UAAU,EAAE,aAAa,CAAC,EAAE,aAAa;IAIzE,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,WAAW;IA4BxD,gBAAgB,CACd,OAAO,EAAE,gBAAgB,EACzB,YAAY,EAAE,YAAY,EAC1B,KAAK,UAAQ,GACZ,MAAM,CAAC,IAAI,EAAE,mBAAmB,GAAG,uBAAuB,CAAC;CA6D/D"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { AmbiguityThresholdError, SpecGenerationError } from '../core/errors.js';
|
|
3
|
+
import { AMBIGUITY_THRESHOLD } from '../core/constants.js';
|
|
4
|
+
import { ok, err } from '../core/result.js';
|
|
5
|
+
import { specSchema } from './schema.js';
|
|
6
|
+
import { EventType } from '../events/types.js';
|
|
7
|
+
import { INTERVIEW_SYSTEM_PROMPT, buildSpecPrompt } from '../llm/prompts.js';
|
|
8
|
+
import { mergeSystemPrompt, getActiveAgentNames } from '../agent/prompt-resolver.js';
|
|
9
|
+
// ─── Generator ──────────────────────────────────────────────────
|
|
10
|
+
export class PassthroughSpecGenerator {
|
|
11
|
+
eventStore;
|
|
12
|
+
agentRegistry;
|
|
13
|
+
constructor(eventStore, agentRegistry) {
|
|
14
|
+
this.eventStore = eventStore;
|
|
15
|
+
this.agentRegistry = agentRegistry;
|
|
16
|
+
}
|
|
17
|
+
buildSpecContext(session) {
|
|
18
|
+
const answeredRounds = session.rounds
|
|
19
|
+
.filter((r) => r.userResponse !== null)
|
|
20
|
+
.map((r) => ({
|
|
21
|
+
question: r.question,
|
|
22
|
+
response: r.userResponse,
|
|
23
|
+
}));
|
|
24
|
+
const specPrompt = buildSpecPrompt(session.topic, answeredRounds, session.projectType);
|
|
25
|
+
const systemPrompt = mergeSystemPrompt(INTERVIEW_SYSTEM_PROMPT, this.agentRegistry, 'spec');
|
|
26
|
+
const activeAgents = getActiveAgentNames(this.agentRegistry, 'spec');
|
|
27
|
+
return {
|
|
28
|
+
systemPrompt,
|
|
29
|
+
specPrompt,
|
|
30
|
+
allRounds: session.rounds
|
|
31
|
+
.filter((r) => r.userResponse !== null)
|
|
32
|
+
.map((r) => ({
|
|
33
|
+
roundNumber: r.roundNumber,
|
|
34
|
+
question: r.question,
|
|
35
|
+
response: r.userResponse,
|
|
36
|
+
gestaltFocus: r.gestaltFocus,
|
|
37
|
+
})),
|
|
38
|
+
...(activeAgents.length > 0 && { activeAgents }),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
validateAndStore(session, externalSpec, force = false) {
|
|
42
|
+
// Validate ambiguity threshold
|
|
43
|
+
if (!force) {
|
|
44
|
+
const ambiguity = session.ambiguityScore?.overall ?? 1.0;
|
|
45
|
+
if (ambiguity > AMBIGUITY_THRESHOLD) {
|
|
46
|
+
return err(new AmbiguityThresholdError(ambiguity, AMBIGUITY_THRESHOLD));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (session.status !== 'completed') {
|
|
50
|
+
return err(new SpecGenerationError('Interview session must be completed before generating a spec'));
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
const spec = {
|
|
54
|
+
version: '1.0.0',
|
|
55
|
+
goal: externalSpec.goal,
|
|
56
|
+
constraints: externalSpec.constraints,
|
|
57
|
+
acceptanceCriteria: externalSpec.acceptanceCriteria,
|
|
58
|
+
ontologySchema: externalSpec.ontologySchema,
|
|
59
|
+
gestaltAnalysis: externalSpec.gestaltAnalysis,
|
|
60
|
+
metadata: {
|
|
61
|
+
specId: randomUUID(),
|
|
62
|
+
interviewSessionId: session.sessionId,
|
|
63
|
+
ambiguityScore: session.ambiguityScore?.overall ?? 1.0,
|
|
64
|
+
generatedAt: new Date().toISOString(),
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
// Validate against schema
|
|
68
|
+
const validation = specSchema.safeParse(spec);
|
|
69
|
+
if (!validation.success) {
|
|
70
|
+
return err(new SpecGenerationError(`Spec validation failed: ${validation.error.message}`));
|
|
71
|
+
}
|
|
72
|
+
this.eventStore.append('spec', spec.metadata.specId, EventType.SPEC_GENERATED, {
|
|
73
|
+
sessionId: session.sessionId,
|
|
74
|
+
goal: spec.goal,
|
|
75
|
+
constraintCount: spec.constraints.length,
|
|
76
|
+
criteriaCount: spec.acceptanceCriteria.length,
|
|
77
|
+
source: 'passthrough',
|
|
78
|
+
});
|
|
79
|
+
return ok(spec);
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
return err(new SpecGenerationError(`Failed to validate spec: ${e instanceof Error ? e.message : String(e)}`));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=passthrough-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passthrough-generator.js","sourceRoot":"","sources":["../../../src/spec/passthrough-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { GestaltPrinciple } from '../core/types.js';
|
|
3
|
+
export declare const specSchema: z.ZodObject<{
|
|
4
|
+
version: z.ZodString;
|
|
5
|
+
goal: z.ZodString;
|
|
6
|
+
constraints: z.ZodArray<z.ZodString, "many">;
|
|
7
|
+
acceptanceCriteria: z.ZodArray<z.ZodString, "many">;
|
|
8
|
+
ontologySchema: z.ZodObject<{
|
|
9
|
+
entities: z.ZodArray<z.ZodObject<{
|
|
10
|
+
name: z.ZodString;
|
|
11
|
+
description: z.ZodString;
|
|
12
|
+
attributes: z.ZodArray<z.ZodString, "many">;
|
|
13
|
+
}, "strip", z.ZodTypeAny, {
|
|
14
|
+
name: string;
|
|
15
|
+
description: string;
|
|
16
|
+
attributes: string[];
|
|
17
|
+
}, {
|
|
18
|
+
name: string;
|
|
19
|
+
description: string;
|
|
20
|
+
attributes: string[];
|
|
21
|
+
}>, "many">;
|
|
22
|
+
relations: z.ZodArray<z.ZodObject<{
|
|
23
|
+
from: z.ZodString;
|
|
24
|
+
to: z.ZodString;
|
|
25
|
+
type: z.ZodString;
|
|
26
|
+
}, "strip", z.ZodTypeAny, {
|
|
27
|
+
type: string;
|
|
28
|
+
from: string;
|
|
29
|
+
to: string;
|
|
30
|
+
}, {
|
|
31
|
+
type: string;
|
|
32
|
+
from: string;
|
|
33
|
+
to: string;
|
|
34
|
+
}>, "many">;
|
|
35
|
+
}, "strip", z.ZodTypeAny, {
|
|
36
|
+
entities: {
|
|
37
|
+
name: string;
|
|
38
|
+
description: string;
|
|
39
|
+
attributes: string[];
|
|
40
|
+
}[];
|
|
41
|
+
relations: {
|
|
42
|
+
type: string;
|
|
43
|
+
from: string;
|
|
44
|
+
to: string;
|
|
45
|
+
}[];
|
|
46
|
+
}, {
|
|
47
|
+
entities: {
|
|
48
|
+
name: string;
|
|
49
|
+
description: string;
|
|
50
|
+
attributes: string[];
|
|
51
|
+
}[];
|
|
52
|
+
relations: {
|
|
53
|
+
type: string;
|
|
54
|
+
from: string;
|
|
55
|
+
to: string;
|
|
56
|
+
}[];
|
|
57
|
+
}>;
|
|
58
|
+
gestaltAnalysis: z.ZodArray<z.ZodObject<{
|
|
59
|
+
principle: z.ZodNativeEnum<typeof GestaltPrinciple>;
|
|
60
|
+
finding: z.ZodString;
|
|
61
|
+
confidence: z.ZodNumber;
|
|
62
|
+
}, "strip", z.ZodTypeAny, {
|
|
63
|
+
principle: GestaltPrinciple;
|
|
64
|
+
finding: string;
|
|
65
|
+
confidence: number;
|
|
66
|
+
}, {
|
|
67
|
+
principle: GestaltPrinciple;
|
|
68
|
+
finding: string;
|
|
69
|
+
confidence: number;
|
|
70
|
+
}>, "many">;
|
|
71
|
+
metadata: z.ZodObject<{
|
|
72
|
+
specId: z.ZodString;
|
|
73
|
+
interviewSessionId: z.ZodString;
|
|
74
|
+
ambiguityScore: z.ZodNumber;
|
|
75
|
+
generatedAt: z.ZodString;
|
|
76
|
+
}, "strip", z.ZodTypeAny, {
|
|
77
|
+
specId: string;
|
|
78
|
+
interviewSessionId: string;
|
|
79
|
+
ambiguityScore: number;
|
|
80
|
+
generatedAt: string;
|
|
81
|
+
}, {
|
|
82
|
+
specId: string;
|
|
83
|
+
interviewSessionId: string;
|
|
84
|
+
ambiguityScore: number;
|
|
85
|
+
generatedAt: string;
|
|
86
|
+
}>;
|
|
87
|
+
}, "strip", z.ZodTypeAny, {
|
|
88
|
+
goal: string;
|
|
89
|
+
version: string;
|
|
90
|
+
constraints: string[];
|
|
91
|
+
acceptanceCriteria: string[];
|
|
92
|
+
ontologySchema: {
|
|
93
|
+
entities: {
|
|
94
|
+
name: string;
|
|
95
|
+
description: string;
|
|
96
|
+
attributes: string[];
|
|
97
|
+
}[];
|
|
98
|
+
relations: {
|
|
99
|
+
type: string;
|
|
100
|
+
from: string;
|
|
101
|
+
to: string;
|
|
102
|
+
}[];
|
|
103
|
+
};
|
|
104
|
+
gestaltAnalysis: {
|
|
105
|
+
principle: GestaltPrinciple;
|
|
106
|
+
finding: string;
|
|
107
|
+
confidence: number;
|
|
108
|
+
}[];
|
|
109
|
+
metadata: {
|
|
110
|
+
specId: string;
|
|
111
|
+
interviewSessionId: string;
|
|
112
|
+
ambiguityScore: number;
|
|
113
|
+
generatedAt: string;
|
|
114
|
+
};
|
|
115
|
+
}, {
|
|
116
|
+
goal: string;
|
|
117
|
+
version: string;
|
|
118
|
+
constraints: string[];
|
|
119
|
+
acceptanceCriteria: string[];
|
|
120
|
+
ontologySchema: {
|
|
121
|
+
entities: {
|
|
122
|
+
name: string;
|
|
123
|
+
description: string;
|
|
124
|
+
attributes: string[];
|
|
125
|
+
}[];
|
|
126
|
+
relations: {
|
|
127
|
+
type: string;
|
|
128
|
+
from: string;
|
|
129
|
+
to: string;
|
|
130
|
+
}[];
|
|
131
|
+
};
|
|
132
|
+
gestaltAnalysis: {
|
|
133
|
+
principle: GestaltPrinciple;
|
|
134
|
+
finding: string;
|
|
135
|
+
confidence: number;
|
|
136
|
+
}[];
|
|
137
|
+
metadata: {
|
|
138
|
+
specId: string;
|
|
139
|
+
interviewSessionId: string;
|
|
140
|
+
ambiguityScore: number;
|
|
141
|
+
generatedAt: string;
|
|
142
|
+
};
|
|
143
|
+
}>;
|
|
144
|
+
export type ValidatedSpec = z.infer<typeof specSchema>;
|
|
145
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/spec/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAgCpD,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQrB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { GestaltPrinciple } from '../core/types.js';
|
|
3
|
+
const ontologyEntitySchema = z.object({
|
|
4
|
+
name: z.string().min(1),
|
|
5
|
+
description: z.string(),
|
|
6
|
+
attributes: z.array(z.string()),
|
|
7
|
+
});
|
|
8
|
+
const ontologyRelationSchema = z.object({
|
|
9
|
+
from: z.string().min(1),
|
|
10
|
+
to: z.string().min(1),
|
|
11
|
+
type: z.string().min(1),
|
|
12
|
+
});
|
|
13
|
+
const ontologySchemaSchema = z.object({
|
|
14
|
+
entities: z.array(ontologyEntitySchema),
|
|
15
|
+
relations: z.array(ontologyRelationSchema),
|
|
16
|
+
});
|
|
17
|
+
const gestaltAnalysisSchema = z.object({
|
|
18
|
+
principle: z.nativeEnum(GestaltPrinciple),
|
|
19
|
+
finding: z.string(),
|
|
20
|
+
confidence: z.number().min(0).max(1),
|
|
21
|
+
});
|
|
22
|
+
const specMetadataSchema = z.object({
|
|
23
|
+
specId: z.string(),
|
|
24
|
+
interviewSessionId: z.string(),
|
|
25
|
+
ambiguityScore: z.number().min(0).max(1),
|
|
26
|
+
generatedAt: z.string(),
|
|
27
|
+
});
|
|
28
|
+
export const specSchema = z.object({
|
|
29
|
+
version: z.string(),
|
|
30
|
+
goal: z.string().min(1),
|
|
31
|
+
constraints: z.array(z.string()),
|
|
32
|
+
acceptanceCriteria: z.array(z.string()),
|
|
33
|
+
ontologySchema: ontologySchemaSchema,
|
|
34
|
+
gestaltAnalysis: z.array(gestaltAnalysisSchema),
|
|
35
|
+
metadata: specMetadataSchema,
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/spec/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CAChC,CAAC,CAAC;AAEH,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CACxB,CAAC,CAAC;AAEH,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC;IACvC,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC;CAC3C,CAAC,CAAC;AAEH,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC;IACzC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CACrC,CAAC,CAAC;AAEH,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC9B,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;CACxB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAChC,kBAAkB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACvC,cAAc,EAAE,oBAAoB;IACpC,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC;IAC/C,QAAQ,EAAE,kBAAkB;CAC7B,CAAC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tienne/gestalt",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "TypeScript AI Development Harness - Gestalt psychology-driven requirement clarification",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/src/index.js",
|
|
7
|
+
"types": "./dist/src/index.d.ts",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=20.0.0"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"gestalt": "./dist/bin/gestalt.js"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"agents",
|
|
17
|
+
"skills",
|
|
18
|
+
"CLAUDE.md"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"dev": "tsx bin/gestalt.ts",
|
|
22
|
+
"build": "tsc",
|
|
23
|
+
"postbuild": "cp -r agents dist/ && cp -r skills dist/",
|
|
24
|
+
"prepublishOnly": "pnpm build",
|
|
25
|
+
"test": "vitest run",
|
|
26
|
+
"test:watch": "vitest",
|
|
27
|
+
"serve": "tsx bin/gestalt.ts serve",
|
|
28
|
+
"lint": "tsc --noEmit"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@anthropic-ai/sdk": "^0.39.0",
|
|
32
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
33
|
+
"better-sqlite3": "^11.8.2",
|
|
34
|
+
"chokidar": "^4.0.3",
|
|
35
|
+
"commander": "^13.1.0",
|
|
36
|
+
"gray-matter": "^4.0.3",
|
|
37
|
+
"openai": "^6.27.0",
|
|
38
|
+
"zod": "^3.24.2"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
42
|
+
"@types/node": "^22.13.10",
|
|
43
|
+
"tsx": "^4.19.3",
|
|
44
|
+
"typescript": "^5.8.2",
|
|
45
|
+
"vitest": "^3.0.9"
|
|
46
|
+
},
|
|
47
|
+
"pnpm": {
|
|
48
|
+
"onlyBuiltDependencies": [
|
|
49
|
+
"better-sqlite3",
|
|
50
|
+
"esbuild"
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: execute
|
|
3
|
+
version: "1.0.0"
|
|
4
|
+
description: "Gestalt-driven execution planner that transforms a Spec into a validated ExecutionPlan"
|
|
5
|
+
triggers:
|
|
6
|
+
- "execute"
|
|
7
|
+
- "plan execution"
|
|
8
|
+
- "create execution plan"
|
|
9
|
+
inputs:
|
|
10
|
+
spec:
|
|
11
|
+
type: object
|
|
12
|
+
required: true
|
|
13
|
+
description: "A validated Spec specification from the spec generation step"
|
|
14
|
+
outputs:
|
|
15
|
+
- executionPlan
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# Execute Skill
|
|
19
|
+
|
|
20
|
+
This skill transforms a validated Spec specification into a concrete, dependency-aware Execution Plan by applying Gestalt psychology principles as a structured planning framework.
|
|
21
|
+
|
|
22
|
+
## Process
|
|
23
|
+
|
|
24
|
+
1. **Figure-Ground** (Step 1): Classify acceptance criteria as essential (figure) or supplementary (ground), assign priority levels
|
|
25
|
+
2. **Closure** (Step 2): Decompose ACs into atomic tasks, identify implicit sub-tasks not explicitly stated
|
|
26
|
+
3. **Proximity** (Step 3): Group related atomic tasks into logical task groups by domain
|
|
27
|
+
4. **Continuity** (Step 4): Validate the dependency DAG — ensure no cycles, no conflicts, clear execution order
|
|
28
|
+
|
|
29
|
+
## Passthrough Mode
|
|
30
|
+
|
|
31
|
+
API 키 없이 MCP 서버 실행 시 자동 활성화. LLM 작업을 caller가 직접 수행한다.
|
|
32
|
+
|
|
33
|
+
### Action별 사용법
|
|
34
|
+
|
|
35
|
+
**`start`** — 실행 계획 세션 시작
|
|
36
|
+
```json
|
|
37
|
+
{ "action": "start", "spec": { ... } }
|
|
38
|
+
```
|
|
39
|
+
→ `{ status, sessionId, specId, executeContext, message }`
|
|
40
|
+
|
|
41
|
+
**`plan_step`** — 각 계획 단계 결과 제출
|
|
42
|
+
```json
|
|
43
|
+
{ "action": "plan_step", "sessionId": "...", "stepResult": { "principle": "figure_ground", "classifiedACs": [...] } }
|
|
44
|
+
```
|
|
45
|
+
→ `{ status, sessionId, stepsCompleted, isLastStep, executeContext?, message }`
|
|
46
|
+
|
|
47
|
+
**`plan_complete`** — 최종 실행 계획 조립
|
|
48
|
+
```json
|
|
49
|
+
{ "action": "plan_complete", "sessionId": "..." }
|
|
50
|
+
```
|
|
51
|
+
→ `{ status, sessionId, executionPlan, message }`
|
|
52
|
+
|
|
53
|
+
**`status`** — 세션 상태 확인
|
|
54
|
+
```json
|
|
55
|
+
{ "action": "status", "sessionId": "..." }
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### ExecuteContext 필드
|
|
59
|
+
|
|
60
|
+
| 필드 | 타입 | 설명 |
|
|
61
|
+
|------|------|------|
|
|
62
|
+
| `systemPrompt` | string | 실행 계획 시스템 프롬프트 |
|
|
63
|
+
| `planningPrompt` | string | 현재 단계의 계획 프롬프트 |
|
|
64
|
+
| `currentPrinciple` | string | 현재 적용 중인 게슈탈트 원리 |
|
|
65
|
+
| `principleStrategy` | string | 해당 원리의 전략 설명 |
|
|
66
|
+
| `phase` | string | 현재 단계 (`planning`) |
|
|
67
|
+
| `stepNumber` | number | 현재 스텝 번호 (1-4) |
|
|
68
|
+
| `totalSteps` | number | 전체 스텝 수 (4) |
|
|
69
|
+
| `spec` | Spec | 원본 Spec 스펙 |
|
|
70
|
+
| `previousSteps` | array | 이전 단계 결과들 |
|
|
71
|
+
|
|
72
|
+
### Planning Principle 순서
|
|
73
|
+
|
|
74
|
+
1. `figure_ground` → ClassifiedAC 배열
|
|
75
|
+
2. `closure` → AtomicTask 배열
|
|
76
|
+
3. `proximity` → TaskGroup 배열
|
|
77
|
+
4. `continuity` → DAGValidation 객체
|
|
78
|
+
|
|
79
|
+
### 검증 규칙
|
|
80
|
+
|
|
81
|
+
- 순서가 강제됨: figure_ground → closure → proximity → continuity
|
|
82
|
+
- 각 단계 결과는 이전 단계 데이터와 교차 검증됨
|
|
83
|
+
- Continuity 단계에서는 서버 측 DAG 검증이 추가로 수행됨
|
|
84
|
+
- 모든 AC가 분류되어야 하고, 모든 Task가 그룹에 포함되어야 함
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: interview
|
|
3
|
+
version: "1.0.0"
|
|
4
|
+
description: "Gestalt-driven interview to clarify project requirements"
|
|
5
|
+
triggers:
|
|
6
|
+
- "interview"
|
|
7
|
+
- "clarify requirements"
|
|
8
|
+
- "start interview"
|
|
9
|
+
inputs:
|
|
10
|
+
topic:
|
|
11
|
+
type: string
|
|
12
|
+
required: true
|
|
13
|
+
description: "The topic or feature to interview about"
|
|
14
|
+
cwd:
|
|
15
|
+
type: string
|
|
16
|
+
required: false
|
|
17
|
+
description: "Working directory for brownfield detection"
|
|
18
|
+
outputs:
|
|
19
|
+
- session
|
|
20
|
+
- ambiguityScore
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# Interview Skill
|
|
24
|
+
|
|
25
|
+
This skill conducts a Gestalt psychology-driven interview to transform vague requirements into clear specifications.
|
|
26
|
+
|
|
27
|
+
## Process
|
|
28
|
+
|
|
29
|
+
1. **Start**: Create a session, detect project type (greenfield/brownfield), ask the first question
|
|
30
|
+
2. **Iterate**: Ask questions guided by Gestalt principles (Closure → Proximity → Similarity → Figure-Ground)
|
|
31
|
+
3. **Score**: Continuously assess ambiguity across multiple dimensions
|
|
32
|
+
4. **Complete**: When ambiguity score ≤ 0.2, the interview is ready for spec generation
|
|
33
|
+
|
|
34
|
+
## Gestalt Principles Applied
|
|
35
|
+
|
|
36
|
+
- **Closure**: Fill missing requirements
|
|
37
|
+
- **Proximity**: Group related features
|
|
38
|
+
- **Similarity**: Identify patterns
|
|
39
|
+
- **Figure-Ground**: Separate MVP from nice-to-have
|
|
40
|
+
- **Continuity**: Detect contradictions
|
|
41
|
+
|
|
42
|
+
## Passthrough Mode
|
|
43
|
+
|
|
44
|
+
API 키 없이 MCP 서버 실행 시 자동 활성화. LLM 작업을 caller가 직접 수행한다.
|
|
45
|
+
|
|
46
|
+
### 추가 Input 파라미터
|
|
47
|
+
|
|
48
|
+
| 파라미터 | 타입 | 필수 | 설명 |
|
|
49
|
+
|---------|------|------|------|
|
|
50
|
+
| `generatedQuestion` | string | respond 시 필수 | caller가 생성한 질문 텍스트 |
|
|
51
|
+
| `ambiguityScore` | object | 선택 | caller가 산출한 모호성 점수 |
|
|
52
|
+
| `ambiguityScore.goalClarity` | number (0-1) | 필수* | 목표 명확도 |
|
|
53
|
+
| `ambiguityScore.constraintClarity` | number (0-1) | 필수* | 제약조건 명확도 |
|
|
54
|
+
| `ambiguityScore.successCriteria` | number (0-1) | 필수* | 성공 기준 명확도 |
|
|
55
|
+
| `ambiguityScore.priorityClarity` | number (0-1) | 필수* | 우선순위 명확도 |
|
|
56
|
+
| `ambiguityScore.contextClarity` | number (0-1) | 선택 | 컨텍스트 명확도 |
|
|
57
|
+
| `ambiguityScore.contradictions` | string[] | 선택 | 발견된 모순 목록 |
|
|
58
|
+
|
|
59
|
+
\* ambiguityScore 객체를 제공할 경우 필수
|
|
60
|
+
|
|
61
|
+
### Action별 응답 구조 (Passthrough)
|
|
62
|
+
|
|
63
|
+
**`start`** → `{ status, sessionId, projectType, detectedFiles, gestaltContext, roundNumber, message }`
|
|
64
|
+
|
|
65
|
+
**`respond`** → `{ status, sessionId, roundNumber, gestaltContext, ambiguityScore, message }`
|
|
66
|
+
|
|
67
|
+
**`score`** (점수 미제공 시) → `{ status, ambiguityScore, scoringPrompt, message }`
|
|
68
|
+
**`score`** (점수 제공 시) → `{ status, ambiguityScore }`
|
|
69
|
+
|
|
70
|
+
**`complete`** → `{ status, sessionId, totalRounds, finalAmbiguityScore, message }`
|
|
71
|
+
|
|
72
|
+
### GestaltContext 필드
|
|
73
|
+
|
|
74
|
+
| 필드 | 타입 | 설명 |
|
|
75
|
+
|------|------|------|
|
|
76
|
+
| `systemPrompt` | string | 인터뷰어 시스템 프롬프트 |
|
|
77
|
+
| `currentPrinciple` | GestaltPrinciple | 현재 적용 중인 게슈탈트 원리 |
|
|
78
|
+
| `principleStrategy` | string | 해당 원리의 질문 전략 설명 |
|
|
79
|
+
| `phase` | string | 현재 인터뷰 단계 라벨 |
|
|
80
|
+
| `questionPrompt` | string | 다음 질문 생성용 프롬프트 |
|
|
81
|
+
| `scoringPrompt` | string? | 모호성 점수 산출용 프롬프트 (respond 후에만 포함) |
|
|
82
|
+
| `roundNumber` | number | 현재 라운드 번호 |
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec
|
|
3
|
+
version: "1.0.0"
|
|
4
|
+
description: "Generate a Spec specification from a completed interview"
|
|
5
|
+
triggers:
|
|
6
|
+
- "generate spec"
|
|
7
|
+
- "create spec"
|
|
8
|
+
- "build spec"
|
|
9
|
+
inputs:
|
|
10
|
+
sessionId:
|
|
11
|
+
type: string
|
|
12
|
+
required: true
|
|
13
|
+
description: "The interview session ID to generate a spec from"
|
|
14
|
+
force:
|
|
15
|
+
type: boolean
|
|
16
|
+
required: false
|
|
17
|
+
description: "Force generation even if ambiguity threshold is not met"
|
|
18
|
+
outputs:
|
|
19
|
+
- spec
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# Spec Generation Skill
|
|
23
|
+
|
|
24
|
+
This skill transforms completed interview data into a structured project specification (Spec).
|
|
25
|
+
|
|
26
|
+
## Output Structure
|
|
27
|
+
|
|
28
|
+
- **Goal**: Clear project objective
|
|
29
|
+
- **Constraints**: Technical and business constraints
|
|
30
|
+
- **Acceptance Criteria**: Measurable success conditions
|
|
31
|
+
- **Ontology Schema**: Entity-relationship model
|
|
32
|
+
- **Gestalt Analysis**: Findings from each principle applied
|
|
33
|
+
|
|
34
|
+
## Requirements
|
|
35
|
+
|
|
36
|
+
- Interview session must be in `completed` status
|
|
37
|
+
- Ambiguity score must be ≤ 0.2 (unless `force` is true)
|
|
38
|
+
|
|
39
|
+
## Passthrough Mode
|
|
40
|
+
|
|
41
|
+
API 키 없이 MCP 서버 실행 시 자동 활성화. Spec 생성을 caller가 직접 수행한다.
|
|
42
|
+
|
|
43
|
+
### 추가 Input 파라미터
|
|
44
|
+
|
|
45
|
+
| 파라미터 | 타입 | 필수 | 설명 |
|
|
46
|
+
|---------|------|------|------|
|
|
47
|
+
| `spec` | object | 2단계에서 필수 | caller가 생성한 Spec JSON |
|
|
48
|
+
| `spec.goal` | string | 필수 | 프로젝트 목표 |
|
|
49
|
+
| `spec.constraints` | string[] | 필수 | 기술/비즈니스 제약조건 |
|
|
50
|
+
| `spec.acceptanceCriteria` | string[] | 필수 | 수용 기준 |
|
|
51
|
+
| `spec.ontologySchema` | object | 필수 | 엔티티-관계 모델 |
|
|
52
|
+
| `spec.gestaltAnalysis` | array | 필수 | 게슈탈트 분석 결과 |
|
|
53
|
+
|
|
54
|
+
### 2단계 플로우
|
|
55
|
+
|
|
56
|
+
**1단계: SpecContext 요청**
|
|
57
|
+
```
|
|
58
|
+
ges_generate_spec({ sessionId: "<id>" })
|
|
59
|
+
```
|
|
60
|
+
→ `{ status: "prompt", specContext, message }` 반환
|
|
61
|
+
|
|
62
|
+
SpecContext 필드:
|
|
63
|
+
- `systemPrompt`: Spec 생성용 시스템 프롬프트
|
|
64
|
+
- `specPrompt`: 인터뷰 내용 기반 Spec 생성 프롬프트
|
|
65
|
+
- `allRounds[]`: `{ roundNumber, question, response, gestaltFocus }`
|
|
66
|
+
|
|
67
|
+
**2단계: Spec 제출 및 검증**
|
|
68
|
+
```
|
|
69
|
+
ges_generate_spec({
|
|
70
|
+
sessionId: "<id>",
|
|
71
|
+
spec: {
|
|
72
|
+
goal: "명확한 프로젝트 목표",
|
|
73
|
+
constraints: ["TypeScript 사용", "REST API"],
|
|
74
|
+
acceptanceCriteria: ["응답 시간 200ms 이하"],
|
|
75
|
+
ontologySchema: {
|
|
76
|
+
entities: [{ name: "User", description: "...", attributes: ["id", "email"] }],
|
|
77
|
+
relations: [{ from: "User", to: "Order", type: "has_many" }]
|
|
78
|
+
},
|
|
79
|
+
gestaltAnalysis: [
|
|
80
|
+
{ principle: "closure", finding: "인증 요구사항 완전히 파악됨", confidence: 0.9 }
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
```
|
|
85
|
+
→ `{ status: "generated", spec }` (metadata 자동 생성 포함) 또는 `{ error }` 반환
|
|
86
|
+
|
|
87
|
+
### Spec 검증 스키마 (Zod)
|
|
88
|
+
|
|
89
|
+
- `gestaltAnalysis[].principle`: `closure | proximity | similarity | figure_ground | continuity`
|
|
90
|
+
- `gestaltAnalysis[].confidence`: 0.0 ~ 1.0
|
|
91
|
+
- `ontologySchema.entities[]`: `{ name: string(min 1), description: string, attributes: string[] }`
|
|
92
|
+
- `ontologySchema.relations[]`: `{ from: string(min 1), to: string(min 1), type: string(min 1) }`
|