@tienne/gestalt 0.84.2 → 0.86.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 +4 -4
- package/README.ko.md +72 -22
- package/README.md +73 -23
- package/dist/benchmarks/runners/passthrough-benchmark-runner.d.ts.map +1 -1
- package/dist/benchmarks/runners/passthrough-benchmark-runner.js +8 -7
- package/dist/benchmarks/runners/passthrough-benchmark-runner.js.map +1 -1
- package/dist/bin/gestalt.js +2 -2
- package/dist/package.json +4 -3
- package/dist/plugin/review-agents/harness-reviewer/AGENT.md +21 -1
- package/dist/plugin/skills/dispatch/SKILL.md +14 -2
- package/dist/plugin/skills/execute/SKILL.md +219 -52
- package/dist/plugin/skills/interview/SKILL.md +15 -2
- package/dist/plugin/skills/solve/SKILL.md +20 -5
- package/dist/plugin/skills/spec/SKILL.md +2 -0
- package/dist/src/cli/commands/interview.d.ts.map +1 -1
- package/dist/src/cli/commands/interview.js +16 -4
- package/dist/src/cli/commands/interview.js.map +1 -1
- package/dist/src/cli/commands/memory-merge.d.ts +2 -0
- package/dist/src/cli/commands/memory-merge.d.ts.map +1 -0
- package/dist/src/cli/commands/memory-merge.js +13 -0
- package/dist/src/cli/commands/memory-merge.js.map +1 -0
- package/dist/src/cli/index.d.ts.map +1 -1
- package/dist/src/cli/index.js +7 -0
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/core/constants.d.ts +4 -0
- package/dist/src/core/constants.d.ts.map +1 -1
- package/dist/src/core/constants.js +8 -0
- package/dist/src/core/constants.js.map +1 -1
- package/dist/src/core/errors.d.ts +3 -0
- package/dist/src/core/errors.d.ts.map +1 -1
- package/dist/src/core/errors.js +7 -0
- package/dist/src/core/errors.js.map +1 -1
- package/dist/src/core/file-lock.d.ts +37 -0
- package/dist/src/core/file-lock.d.ts.map +1 -0
- package/dist/src/core/file-lock.js +143 -0
- package/dist/src/core/file-lock.js.map +1 -0
- package/dist/src/core/json-file.d.ts +40 -0
- package/dist/src/core/json-file.d.ts.map +1 -0
- package/dist/src/core/json-file.js +82 -0
- package/dist/src/core/json-file.js.map +1 -0
- package/dist/src/core/types.d.ts +86 -9
- package/dist/src/core/types.d.ts.map +1 -1
- package/dist/src/events/store.d.ts +6 -0
- package/dist/src/events/store.d.ts.map +1 -1
- package/dist/src/events/store.js +12 -0
- package/dist/src/events/store.js.map +1 -1
- package/dist/src/events/types.d.ts +7 -0
- package/dist/src/events/types.d.ts.map +1 -1
- package/dist/src/events/types.js +7 -0
- package/dist/src/events/types.js.map +1 -1
- package/dist/src/execute/artifact-verifier.d.ts +12 -0
- package/dist/src/execute/artifact-verifier.d.ts.map +1 -0
- package/dist/src/execute/artifact-verifier.js +211 -0
- package/dist/src/execute/artifact-verifier.js.map +1 -0
- package/dist/src/execute/drift-detector.d.ts +2 -0
- package/dist/src/execute/drift-detector.d.ts.map +1 -1
- package/dist/src/execute/drift-detector.js +9 -13
- package/dist/src/execute/drift-detector.js.map +1 -1
- package/dist/src/execute/orchestrators/evaluation.d.ts +5 -1
- package/dist/src/execute/orchestrators/evaluation.d.ts.map +1 -1
- package/dist/src/execute/orchestrators/evaluation.js +48 -41
- package/dist/src/execute/orchestrators/evaluation.js.map +1 -1
- package/dist/src/execute/orchestrators/evolution.d.ts +17 -3
- package/dist/src/execute/orchestrators/evolution.d.ts.map +1 -1
- package/dist/src/execute/orchestrators/evolution.js +102 -53
- package/dist/src/execute/orchestrators/evolution.js.map +1 -1
- package/dist/src/execute/orchestrators/execution.d.ts +17 -2
- package/dist/src/execute/orchestrators/execution.d.ts.map +1 -1
- package/dist/src/execute/orchestrators/execution.js +99 -3
- package/dist/src/execute/orchestrators/execution.js.map +1 -1
- package/dist/src/execute/orchestrators/planning.d.ts +18 -4
- package/dist/src/execute/orchestrators/planning.d.ts.map +1 -1
- package/dist/src/execute/orchestrators/planning.js +62 -21
- package/dist/src/execute/orchestrators/planning.js.map +1 -1
- package/dist/src/execute/orchestrators/types.d.ts +12 -1
- package/dist/src/execute/orchestrators/types.d.ts.map +1 -1
- package/dist/src/execute/passthrough-engine.d.ts +12 -5
- package/dist/src/execute/passthrough-engine.d.ts.map +1 -1
- package/dist/src/execute/passthrough-engine.js +10 -4
- package/dist/src/execute/passthrough-engine.js.map +1 -1
- package/dist/src/execute/repository.d.ts +11 -1
- package/dist/src/execute/repository.d.ts.map +1 -1
- package/dist/src/execute/repository.js +138 -19
- package/dist/src/execute/repository.js.map +1 -1
- package/dist/src/execute/session.d.ts +26 -4
- package/dist/src/execute/session.d.ts.map +1 -1
- package/dist/src/execute/session.js +165 -48
- package/dist/src/execute/session.js.map +1 -1
- package/dist/src/execute/structural-commands.d.ts +23 -0
- package/dist/src/execute/structural-commands.d.ts.map +1 -0
- package/dist/src/execute/structural-commands.js +139 -0
- package/dist/src/execute/structural-commands.js.map +1 -0
- package/dist/src/harness-review/collect.d.ts +1 -1
- package/dist/src/harness-review/collect.d.ts.map +1 -1
- package/dist/src/harness-review/collect.js +6 -1
- package/dist/src/harness-review/collect.js.map +1 -1
- package/dist/src/harness-review/rule-overlap.d.ts +3 -0
- package/dist/src/harness-review/rule-overlap.d.ts.map +1 -0
- package/dist/src/harness-review/rule-overlap.js +78 -0
- package/dist/src/harness-review/rule-overlap.js.map +1 -0
- package/dist/src/harness-review/types.d.ts +1 -1
- package/dist/src/harness-review/types.d.ts.map +1 -1
- package/dist/src/harness-review/types.js +1 -0
- package/dist/src/harness-review/types.js.map +1 -1
- package/dist/src/humanize/overlap.d.ts +116 -0
- package/dist/src/humanize/overlap.d.ts.map +1 -0
- package/dist/src/humanize/overlap.js +680 -0
- package/dist/src/humanize/overlap.js.map +1 -0
- package/dist/src/interview/engine.d.ts +1 -1
- package/dist/src/interview/engine.d.ts.map +1 -1
- package/dist/src/interview/engine.js +3 -3
- package/dist/src/interview/engine.js.map +1 -1
- package/dist/src/interview/passthrough-engine.d.ts +1 -1
- package/dist/src/interview/passthrough-engine.d.ts.map +1 -1
- package/dist/src/interview/passthrough-engine.js +20 -3
- package/dist/src/interview/passthrough-engine.js.map +1 -1
- package/dist/src/interview/repository.d.ts +8 -0
- package/dist/src/interview/repository.d.ts.map +1 -1
- package/dist/src/interview/repository.js +16 -1
- package/dist/src/interview/repository.js.map +1 -1
- package/dist/src/interview/session.d.ts +15 -2
- package/dist/src/interview/session.d.ts.map +1 -1
- package/dist/src/interview/session.js +67 -23
- package/dist/src/interview/session.js.map +1 -1
- package/dist/src/knowledge-base/embedding.d.ts +6 -1
- package/dist/src/knowledge-base/embedding.d.ts.map +1 -1
- package/dist/src/knowledge-base/embedding.js +19 -6
- package/dist/src/knowledge-base/embedding.js.map +1 -1
- package/dist/src/local-pr/registry.d.ts +1 -21
- package/dist/src/local-pr/registry.d.ts.map +1 -1
- package/dist/src/local-pr/registry.js +7 -113
- package/dist/src/local-pr/registry.js.map +1 -1
- package/dist/src/mcp/input-guard.d.ts +17 -0
- package/dist/src/mcp/input-guard.d.ts.map +1 -1
- package/dist/src/mcp/input-guard.js +1 -1
- package/dist/src/mcp/input-guard.js.map +1 -1
- package/dist/src/mcp/schemas.d.ts +62 -7
- package/dist/src/mcp/schemas.d.ts.map +1 -1
- package/dist/src/mcp/schemas.js +28 -1
- package/dist/src/mcp/schemas.js.map +1 -1
- package/dist/src/mcp/server.d.ts.map +1 -1
- package/dist/src/mcp/server.js +26 -40
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/mcp/tools/execute/evaluate.d.ts.map +1 -1
- package/dist/src/mcp/tools/execute/evaluate.js +15 -9
- package/dist/src/mcp/tools/execute/evaluate.js.map +1 -1
- package/dist/src/mcp/tools/execute/evolve.d.ts +1 -0
- package/dist/src/mcp/tools/execute/evolve.d.ts.map +1 -1
- package/dist/src/mcp/tools/execute/evolve.js +102 -37
- package/dist/src/mcp/tools/execute/evolve.js.map +1 -1
- package/dist/src/mcp/tools/execute/execution.d.ts.map +1 -1
- package/dist/src/mcp/tools/execute/execution.js +66 -7
- package/dist/src/mcp/tools/execute/execution.js.map +1 -1
- package/dist/src/mcp/tools/execute/planning.d.ts.map +1 -1
- package/dist/src/mcp/tools/execute/planning.js +34 -2
- package/dist/src/mcp/tools/execute/planning.js.map +1 -1
- package/dist/src/mcp/tools/execute/roles.d.ts.map +1 -1
- package/dist/src/mcp/tools/execute/roles.js +13 -5
- package/dist/src/mcp/tools/execute/roles.js.map +1 -1
- package/dist/src/mcp/tools/execute/utility.d.ts.map +1 -1
- package/dist/src/mcp/tools/execute/utility.js +26 -0
- package/dist/src/mcp/tools/execute/utility.js.map +1 -1
- package/dist/src/mcp/tools/execute/utils.d.ts +1 -0
- package/dist/src/mcp/tools/execute/utils.d.ts.map +1 -1
- package/dist/src/mcp/tools/execute/utils.js +15 -0
- package/dist/src/mcp/tools/execute/utils.js.map +1 -1
- package/dist/src/mcp/tools/execute-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/execute-passthrough.js +21 -1
- package/dist/src/mcp/tools/execute-passthrough.js.map +1 -1
- package/dist/src/mcp/tools/interview-passthrough.d.ts +2 -1
- package/dist/src/mcp/tools/interview-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/interview-passthrough.js +4 -3
- package/dist/src/mcp/tools/interview-passthrough.js.map +1 -1
- package/dist/src/mcp/tools/interview.d.ts.map +1 -1
- package/dist/src/mcp/tools/interview.js +2 -1
- package/dist/src/mcp/tools/interview.js.map +1 -1
- package/dist/src/mcp/tools/review-passthrough.js +15 -19
- package/dist/src/mcp/tools/review-passthrough.js.map +1 -1
- package/dist/src/mcp/tools/spec-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/spec-passthrough.js +16 -8
- package/dist/src/mcp/tools/spec-passthrough.js.map +1 -1
- package/dist/src/mcp/tools/status.d.ts.map +1 -1
- package/dist/src/mcp/tools/status.js +4 -0
- package/dist/src/mcp/tools/status.js.map +1 -1
- package/dist/src/memory/memory-context-injector.d.ts +22 -8
- package/dist/src/memory/memory-context-injector.d.ts.map +1 -1
- package/dist/src/memory/memory-context-injector.js +85 -13
- package/dist/src/memory/memory-context-injector.js.map +1 -1
- package/dist/src/memory/memory-merge.d.ts +19 -0
- package/dist/src/memory/memory-merge.d.ts.map +1 -0
- package/dist/src/memory/memory-merge.js +120 -0
- package/dist/src/memory/memory-merge.js.map +1 -0
- package/dist/src/memory/project-memory-store.d.ts +15 -11
- package/dist/src/memory/project-memory-store.d.ts.map +1 -1
- package/dist/src/memory/project-memory-store.js +97 -120
- package/dist/src/memory/project-memory-store.js.map +1 -1
- package/dist/src/memory/semantic-search.d.ts +4 -1
- package/dist/src/memory/semantic-search.d.ts.map +1 -1
- package/dist/src/memory/semantic-search.js +66 -19
- package/dist/src/memory/semantic-search.js.map +1 -1
- package/dist/src/resilience/lateral.d.ts +8 -1
- package/dist/src/resilience/lateral.d.ts.map +1 -1
- package/dist/src/resilience/lateral.js +52 -4
- package/dist/src/resilience/lateral.js.map +1 -1
- package/package.json +4 -3
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/.mcp.json +1 -1
- package/plugin/mcp.json +1 -1
- package/plugin/review-agents/harness-reviewer/AGENT.md +21 -1
- package/plugin/skills/dispatch/SKILL.md +14 -2
- package/plugin/skills/execute/SKILL.md +219 -52
- package/plugin/skills/interview/SKILL.md +15 -2
- package/plugin/skills/solve/SKILL.md +20 -5
- package/plugin/skills/spec/SKILL.md +2 -0
- package/dist/src/interview/mini-interview-engine.d.ts +0 -33
- package/dist/src/interview/mini-interview-engine.d.ts.map +0 -1
- package/dist/src/interview/mini-interview-engine.js +0 -102
- package/dist/src/interview/mini-interview-engine.js.map +0 -1
- package/dist/src/memory/user-profile-store.d.ts +0 -13
- package/dist/src/memory/user-profile-store.d.ts.map +0 -1
- package/dist/src/memory/user-profile-store.js +0 -85
- package/dist/src/memory/user-profile-store.js.map +0 -1
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { existsSync
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
2
|
import { join, dirname } from 'node:path';
|
|
3
|
+
import { withFileLock } from '../core/file-lock.js';
|
|
4
|
+
import { isPlainObject, readJsonOrQuarantine, writeJsonAtomic } from '../core/json-file.js';
|
|
5
|
+
import { log } from '../core/log.js';
|
|
3
6
|
const MEMORY_FILENAME = '.gestalt/memory.json';
|
|
4
7
|
const MEMORY_VERSION = '1.0.0';
|
|
5
8
|
function detectRepoRoot(startDir) {
|
|
@@ -33,139 +36,113 @@ export class ProjectMemoryStore {
|
|
|
33
36
|
this.repoRoot = detectRepoRoot(cwd ?? process.cwd());
|
|
34
37
|
this.memoryPath = join(this.repoRoot, MEMORY_FILENAME);
|
|
35
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* 메모리를 읽는다. 읽기 자체가 실패하면 빈 메모리를 돌려준다.
|
|
41
|
+
*
|
|
42
|
+
* 인터뷰에 맥락을 끼워 넣는 자리라 여기서 던지면 인터뷰가 멈춘다. 고쳐 쓰는 경로는
|
|
43
|
+
* 이 메서드 대신 `load()`를 직접 불러, 못 읽은 채로 빈 메모리를 덮어쓰지 않는다.
|
|
44
|
+
* 잠금 없이 읽으므로 깨진 파일을 옮기지 않는다. 옮기는 건 잠금을 쥔 `update()`만 한다.
|
|
45
|
+
*/
|
|
36
46
|
read() {
|
|
37
|
-
if (!existsSync(this.memoryPath)) {
|
|
38
|
-
return createEmptyMemory(this.repoRoot);
|
|
39
|
-
}
|
|
40
47
|
try {
|
|
41
|
-
|
|
42
|
-
const parsed = JSON.parse(raw);
|
|
43
|
-
// v1 → v2 자동 마이그레이션: architectureDecisions string[] → ArchitectureDecision[]
|
|
44
|
-
if (Array.isArray(parsed.architectureDecisions)) {
|
|
45
|
-
parsed.architectureDecisions = parsed.architectureDecisions.map((item) => {
|
|
46
|
-
if (typeof item === 'string') {
|
|
47
|
-
return {
|
|
48
|
-
decision: item,
|
|
49
|
-
rationale: '',
|
|
50
|
-
specId: '',
|
|
51
|
-
timestamp: new Date().toISOString(),
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
return item;
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
return parsed;
|
|
48
|
+
return this.load({ quarantine: false });
|
|
58
49
|
}
|
|
59
|
-
catch {
|
|
50
|
+
catch (e) {
|
|
51
|
+
log(`${this.memoryPath}를 읽지 못했어요:`, e);
|
|
60
52
|
return createEmptyMemory(this.repoRoot);
|
|
61
53
|
}
|
|
62
54
|
}
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
if (
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
memory
|
|
69
|
-
|
|
55
|
+
load(options) {
|
|
56
|
+
const raw = readJsonOrQuarantine(this.memoryPath, isPlainObject, options);
|
|
57
|
+
if (raw === undefined)
|
|
58
|
+
return createEmptyMemory(this.repoRoot);
|
|
59
|
+
const parsed = raw;
|
|
60
|
+
const memory = {
|
|
61
|
+
...createEmptyMemory(this.repoRoot),
|
|
62
|
+
...parsed,
|
|
63
|
+
specHistory: Array.isArray(parsed.specHistory) ? parsed.specHistory : [],
|
|
64
|
+
executionHistory: Array.isArray(parsed.executionHistory) ? parsed.executionHistory : [],
|
|
65
|
+
architectureDecisions: Array.isArray(parsed.architectureDecisions)
|
|
66
|
+
? parsed.architectureDecisions
|
|
67
|
+
: [],
|
|
68
|
+
compressedContexts: Array.isArray(parsed.compressedContexts)
|
|
69
|
+
? parsed.compressedContexts
|
|
70
|
+
: undefined,
|
|
71
|
+
};
|
|
72
|
+
// v1 → v2 자동 마이그레이션: architectureDecisions string[] → ArchitectureDecision[]
|
|
73
|
+
memory.architectureDecisions = memory.architectureDecisions.map((item) => {
|
|
74
|
+
if (typeof item === 'string') {
|
|
75
|
+
return {
|
|
76
|
+
decision: item,
|
|
77
|
+
rationale: '',
|
|
78
|
+
specId: '',
|
|
79
|
+
timestamp: new Date().toISOString(),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return item;
|
|
83
|
+
});
|
|
84
|
+
return memory;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* 잠금을 쥔 채 읽고 고쳐 쓴다.
|
|
88
|
+
*
|
|
89
|
+
* 워크트리나 프로세스 여럿이 같은 메모리에 동시에 기록하면, 잠금 없이는 늦게 쓴 쪽이
|
|
90
|
+
* 먼저 쓴 쪽의 항목을 덮는다.
|
|
91
|
+
*/
|
|
92
|
+
update(mutate) {
|
|
93
|
+
return withFileLock(`${this.memoryPath}.lock`, ({ stillMine }) => {
|
|
94
|
+
const memory = this.load({ quarantine: true });
|
|
95
|
+
mutate(memory);
|
|
96
|
+
if (!stillMine()) {
|
|
97
|
+
throw new Error('메모리 잠금을 뺏겨서 안 썼어요. 다시 불러주세요');
|
|
98
|
+
}
|
|
99
|
+
memory.lastUpdated = new Date().toISOString();
|
|
100
|
+
writeJsonAtomic(this.memoryPath, memory);
|
|
101
|
+
return memory;
|
|
102
|
+
}, { busyMessage: '메모리 파일이 잠겨 있어서 못 고쳤어요' });
|
|
70
103
|
}
|
|
71
104
|
addSpec(entry) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return memory;
|
|
105
|
+
return this.update((memory) => {
|
|
106
|
+
// Prevent duplicate specId entries
|
|
107
|
+
const exists = memory.specHistory.some((s) => s.specId === entry.specId);
|
|
108
|
+
if (!exists) {
|
|
109
|
+
memory.specHistory.push(entry);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
80
112
|
}
|
|
81
113
|
addExecution(record) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return memory;
|
|
114
|
+
return this.update((memory) => {
|
|
115
|
+
// Prevent duplicate executeSessionId entries
|
|
116
|
+
const exists = memory.executionHistory.some((e) => e.executeSessionId === record.executeSessionId);
|
|
117
|
+
if (!exists) {
|
|
118
|
+
memory.executionHistory.push(record);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
90
121
|
}
|
|
91
122
|
addArchitectureDecision(decision) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return memory;
|
|
123
|
+
return this.update((memory) => {
|
|
124
|
+
// decision 내용 기준 중복 방지 (같은 결정을 중복 기록하지 않음)
|
|
125
|
+
const exists = memory.architectureDecisions.some((d) => d.decision === decision.decision);
|
|
126
|
+
if (!exists) {
|
|
127
|
+
memory.architectureDecisions.push(decision);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
100
130
|
}
|
|
101
131
|
addCompressedContext(sessionId, summary) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return memory;
|
|
117
|
-
}
|
|
118
|
-
async searchSimilarSpecs(query, topK = 3) {
|
|
119
|
-
const { searchSimilarSpecs } = await import('./semantic-search.js');
|
|
120
|
-
const memory = this.read();
|
|
121
|
-
return searchSimilarSpecs(query, memory, topK);
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* local과 remote ProjectMemory를 머지한다.
|
|
125
|
-
*
|
|
126
|
-
* - specHistory: specId 기준 dedupe (remote에 없는 local 항목 추가)
|
|
127
|
-
* - executionHistory: executeSessionId 기준 dedupe (동일 방식)
|
|
128
|
-
* - architectureDecisions: timestamp+decision 기준 dedupe
|
|
129
|
-
* - 그 외 스칼라 필드: local 값 우선, lastUpdated는 최신값
|
|
130
|
-
*/
|
|
131
|
-
mergeMemory(local, remote) {
|
|
132
|
-
// specHistory: specId 기준 dedupe — remote 기준에서 local에만 있는 항목 추가
|
|
133
|
-
const remoteSpecIds = new Set(remote.specHistory.map((s) => s.specId));
|
|
134
|
-
const mergedSpecHistory = [
|
|
135
|
-
...remote.specHistory,
|
|
136
|
-
...local.specHistory.filter((s) => !remoteSpecIds.has(s.specId)),
|
|
137
|
-
];
|
|
138
|
-
// executionHistory: executeSessionId 기준 dedupe
|
|
139
|
-
const remoteExecIds = new Set(remote.executionHistory.map((e) => e.executeSessionId));
|
|
140
|
-
const mergedExecutionHistory = [
|
|
141
|
-
...remote.executionHistory,
|
|
142
|
-
...local.executionHistory.filter((e) => !remoteExecIds.has(e.executeSessionId)),
|
|
143
|
-
];
|
|
144
|
-
// architectureDecisions: timestamp+decision 기준 dedupe
|
|
145
|
-
const remoteDecisionKeys = new Set(remote.architectureDecisions.map((d) => `${d.timestamp}::${d.decision}`));
|
|
146
|
-
const mergedArchitectureDecisions = [
|
|
147
|
-
...remote.architectureDecisions,
|
|
148
|
-
...local.architectureDecisions.filter((d) => !remoteDecisionKeys.has(`${d.timestamp}::${d.decision}`)),
|
|
149
|
-
];
|
|
150
|
-
// compressedContexts: sessionId 기준 dedupe (remote 우선)
|
|
151
|
-
const localContexts = local.compressedContexts ?? [];
|
|
152
|
-
const remoteContexts = remote.compressedContexts ?? [];
|
|
153
|
-
const remoteContextIds = new Set(remoteContexts.map((c) => c.sessionId));
|
|
154
|
-
const mergedContexts = [
|
|
155
|
-
...remoteContexts,
|
|
156
|
-
...localContexts.filter((c) => !remoteContextIds.has(c.sessionId)),
|
|
157
|
-
];
|
|
158
|
-
// lastUpdated: 더 최신 값 사용
|
|
159
|
-
const lastUpdated = local.lastUpdated > remote.lastUpdated ? local.lastUpdated : remote.lastUpdated;
|
|
160
|
-
return {
|
|
161
|
-
version: local.version,
|
|
162
|
-
repoRoot: local.repoRoot,
|
|
163
|
-
specHistory: mergedSpecHistory,
|
|
164
|
-
executionHistory: mergedExecutionHistory,
|
|
165
|
-
architectureDecisions: mergedArchitectureDecisions,
|
|
166
|
-
compressedContexts: mergedContexts.length > 0 ? mergedContexts : undefined,
|
|
167
|
-
lastUpdated,
|
|
168
|
-
};
|
|
132
|
+
return this.update((memory) => {
|
|
133
|
+
if (!memory.compressedContexts) {
|
|
134
|
+
memory.compressedContexts = [];
|
|
135
|
+
}
|
|
136
|
+
// Replace existing entry for same sessionId
|
|
137
|
+
const idx = memory.compressedContexts.findIndex((c) => c.sessionId === sessionId);
|
|
138
|
+
const entry = { sessionId, summary, compressedAt: new Date().toISOString() };
|
|
139
|
+
if (idx >= 0) {
|
|
140
|
+
memory.compressedContexts[idx] = entry;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
memory.compressedContexts.push(entry);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
169
146
|
}
|
|
170
147
|
getRepoRoot() {
|
|
171
148
|
return this.repoRoot;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-memory-store.js","sourceRoot":"","sources":["../../../src/memory/project-memory-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"project-memory-store.js","sourceRoot":"","sources":["../../../src/memory/project-memory-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { ProjectMemory, SpecHistoryEntry } from '../core/types.js';
|
|
2
|
+
/** @internal 테스트에서 모듈 상태를 비운다 */
|
|
3
|
+
export declare function resetSemanticSearchState(): void;
|
|
2
4
|
/**
|
|
3
5
|
* ProjectMemory의 specHistory에서 query와 시맨틱으로 유사한 상위 K개를 반환한다.
|
|
4
6
|
*
|
|
5
7
|
* @param query 검색 쿼리 문자열
|
|
6
8
|
* @param memory ProjectMemory 인스턴스
|
|
7
9
|
* @param topK 반환할 최대 항목 수 (기본값: 3)
|
|
10
|
+
* @param minScore 이 값보다 유사도가 낮은 항목은 버린다 (기본값: 0)
|
|
8
11
|
* @returns cosine similarity 내림차순으로 정렬된 SpecHistoryEntry[]
|
|
9
12
|
*/
|
|
10
|
-
export declare function searchSimilarSpecs(query: string, memory: ProjectMemory, topK?: number): Promise<SpecHistoryEntry[]>;
|
|
13
|
+
export declare function searchSimilarSpecs(query: string, memory: ProjectMemory, topK?: number, minScore?: number): Promise<SpecHistoryEntry[]>;
|
|
11
14
|
//# sourceMappingURL=semantic-search.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semantic-search.d.ts","sourceRoot":"","sources":["../../../src/memory/semantic-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"semantic-search.d.ts","sourceRoot":"","sources":["../../../src/memory/semantic-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAuExE,iCAAiC;AACjC,wBAAgB,wBAAwB,IAAI,IAAI,CAM/C;AAID;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,aAAa,EACrB,IAAI,SAAI,EACR,QAAQ,SAAI,GACX,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAqB7B"}
|
|
@@ -15,40 +15,87 @@ function cosineSimilarity(a, b) {
|
|
|
15
15
|
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
16
16
|
return denom === 0 ? 0 : dot / denom;
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
// EmbeddingService의 all-MiniLM-L6-v2는 영어로만 학습됐다. 한글 문장끼리는 주제가 달라도
|
|
19
|
+
// 0.6~0.8이 나와 엉뚱한 스펙이 상위로 올라온다. 한글로 확인했고 같은 이유로 가나와 한자도 뺀다.
|
|
20
|
+
// 틀린 맥락을 넣느니 아예 안 넣는다
|
|
21
|
+
const UNSUPPORTED_SCRIPT = /[\u1100-\u11FF\u3040-\u30FF\u3130-\u318F\u4E00-\u9FFF\uAC00-\uD7AF]/;
|
|
22
|
+
// 모델을 못 받는 환경에서 start마다 다시 받으려 들지 않게, 로딩에 실패하면 이 시간 동안 재시도하지 않는다
|
|
23
|
+
const RETRY_AFTER_FAILURE_MS = 5 * 60 * 1000;
|
|
24
|
+
let servicePromise = null;
|
|
25
|
+
let modelReady = false;
|
|
26
|
+
let modelLoading = false;
|
|
27
|
+
let lastFailureAt = 0;
|
|
28
|
+
// goal 벡터는 스펙이 바뀌지 않는 한 같으므로 start마다 다시 임베딩하지 않는다
|
|
29
|
+
const goalVectors = new Map();
|
|
30
|
+
function getEmbeddingService() {
|
|
31
|
+
servicePromise ??= import('../knowledge-base/embedding.js').then(({ EmbeddingService }) => new EmbeddingService(), (e) => {
|
|
32
|
+
servicePromise = null;
|
|
33
|
+
throw e;
|
|
34
|
+
});
|
|
35
|
+
return servicePromise;
|
|
36
|
+
}
|
|
37
|
+
// 모델이 아직 안 올라왔으면 한 번에 하나만 받게 한다. 로딩 중에 들어온 호출은 기다리지 않고
|
|
38
|
+
// 실패로 돌려 호출부가 바로 폴백하게 한다 — 기다려 봐야 호출부 제한 시간에 걸린다.
|
|
39
|
+
// 재시도 대기(RETRY_AFTER_FAILURE_MS)는 로딩 실패에만 건다. 올라온 뒤의 임베딩 실패는 다음 호출에서 그냥 다시 해본다
|
|
40
|
+
async function embedTexts(texts) {
|
|
41
|
+
const service = await getEmbeddingService();
|
|
42
|
+
if (!modelReady) {
|
|
43
|
+
if (modelLoading)
|
|
44
|
+
throw new Error('embedding model is still loading');
|
|
45
|
+
if (Date.now() - lastFailureAt < RETRY_AFTER_FAILURE_MS) {
|
|
46
|
+
throw new Error('embedding model failed to load recently');
|
|
47
|
+
}
|
|
48
|
+
modelLoading = true;
|
|
49
|
+
try {
|
|
50
|
+
await service.ensureLoaded();
|
|
51
|
+
modelReady = true;
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
lastFailureAt = Date.now();
|
|
55
|
+
throw e;
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
modelLoading = false;
|
|
59
|
+
}
|
|
27
60
|
}
|
|
28
|
-
return
|
|
61
|
+
return service.embedBatch(texts);
|
|
29
62
|
}
|
|
63
|
+
/** @internal 테스트에서 모듈 상태를 비운다 */
|
|
64
|
+
export function resetSemanticSearchState() {
|
|
65
|
+
servicePromise = null;
|
|
66
|
+
modelReady = false;
|
|
67
|
+
modelLoading = false;
|
|
68
|
+
lastFailureAt = 0;
|
|
69
|
+
goalVectors.clear();
|
|
70
|
+
}
|
|
71
|
+
const vectorKey = (e) => `${e.specId}\0${e.goal}`;
|
|
30
72
|
/**
|
|
31
73
|
* ProjectMemory의 specHistory에서 query와 시맨틱으로 유사한 상위 K개를 반환한다.
|
|
32
74
|
*
|
|
33
75
|
* @param query 검색 쿼리 문자열
|
|
34
76
|
* @param memory ProjectMemory 인스턴스
|
|
35
77
|
* @param topK 반환할 최대 항목 수 (기본값: 3)
|
|
78
|
+
* @param minScore 이 값보다 유사도가 낮은 항목은 버린다 (기본값: 0)
|
|
36
79
|
* @returns cosine similarity 내림차순으로 정렬된 SpecHistoryEntry[]
|
|
37
80
|
*/
|
|
38
|
-
export async function searchSimilarSpecs(query, memory, topK = 3) {
|
|
39
|
-
|
|
81
|
+
export async function searchSimilarSpecs(query, memory, topK = 3, minScore = 0) {
|
|
82
|
+
if (UNSUPPORTED_SCRIPT.test(query))
|
|
83
|
+
return [];
|
|
84
|
+
const entries = memory.specHistory.filter((e) => !UNSUPPORTED_SCRIPT.test(e.goal));
|
|
40
85
|
if (entries.length === 0)
|
|
41
86
|
return [];
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const vectors = await service.embedBatch(texts);
|
|
87
|
+
const uncached = entries.filter((e) => !goalVectors.has(vectorKey(e)));
|
|
88
|
+
const vectors = await embedTexts([query, ...uncached.map((e) => e.goal)]);
|
|
89
|
+
uncached.forEach((e, idx) => goalVectors.set(vectorKey(e), vectors[idx + 1]));
|
|
46
90
|
const queryVec = vectors[0];
|
|
47
|
-
const scored = entries.map((entry
|
|
91
|
+
const scored = entries.map((entry) => ({
|
|
48
92
|
entry,
|
|
49
|
-
score: cosineSimilarity(queryVec,
|
|
93
|
+
score: cosineSimilarity(queryVec, goalVectors.get(vectorKey(entry))),
|
|
50
94
|
}));
|
|
51
95
|
scored.sort((a, b) => b.score - a.score);
|
|
52
|
-
return scored
|
|
96
|
+
return scored
|
|
97
|
+
.filter((s) => s.score >= minScore)
|
|
98
|
+
.slice(0, topK)
|
|
99
|
+
.map((s) => s.entry);
|
|
53
100
|
}
|
|
54
101
|
//# sourceMappingURL=semantic-search.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semantic-search.js","sourceRoot":"","sources":["../../../src/memory/semantic-search.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,SAAS,gBAAgB,CAAC,CAAW,EAAE,CAAW;IAChD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;QACrB,KAAK,IAAI,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;QACvB,KAAK,IAAI,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;IACzB,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC;AACvC,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"semantic-search.js","sourceRoot":"","sources":["../../../src/memory/semantic-search.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Spec, EvaluationResult, EvolutionGeneration } from '../core/types.js';
|
|
1
|
+
import type { Spec, EvaluationResult, EvolutionGeneration, HumanGate, HumanGateOptionId } from '../core/types.js';
|
|
2
2
|
import type { StagnationPattern, LateralPersonaName, LateralContext, EscalationContext } from './types.js';
|
|
3
3
|
/**
|
|
4
4
|
* pattern에 매핑된 1순위 persona를 먼저 시도하고,
|
|
@@ -17,4 +17,11 @@ export declare function buildEscalationContext(triedPersonas: LateralPersonaName
|
|
|
17
17
|
taskId: string;
|
|
18
18
|
title: string;
|
|
19
19
|
}): EscalationContext;
|
|
20
|
+
/**
|
|
21
|
+
* escalation을 사람이 답할 게이트로 바꾼다. 선택지는 recommendedSolutions의 세 방향에 abort를 더한 것이고
|
|
22
|
+
* 세션을 이어가는 쪽을 앞에 둔다.
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildEscalationGate(escalation: EscalationContext): HumanGate;
|
|
25
|
+
/** 이 선택지로 해소하면 세션이 이어지는가. 아니면 세션을 종료한다 */
|
|
26
|
+
export declare function gateOptionResumesSession(optionId: HumanGateOptionId): boolean;
|
|
20
27
|
//# sourceMappingURL=lateral.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lateral.d.ts","sourceRoot":"","sources":["../../../src/resilience/lateral.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lateral.d.ts","sourceRoot":"","sources":["../../../src/resilience/lateral.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,IAAI,EACJ,gBAAgB,EAChB,mBAAmB,EACnB,SAAS,EACT,iBAAiB,EAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAYpB;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,iBAAiB,EAC1B,aAAa,EAAE,kBAAkB,EAAE,GAClC,kBAAkB,GAAG,IAAI,CAiB3B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,iBAAiB,EAC1B,IAAI,EAAE,IAAI,EACV,gBAAgB,EAAE,gBAAgB,EAClC,gBAAgB,EAAE,mBAAmB,EAAE,EACvC,aAAa,EAAE,MAAM,GACpB,cAAc,CAkBhB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,kBAAkB,EAAE,EACnC,gBAAgB,EAAE,gBAAgB,EAClC,gBAAgB,EAAE,mBAAmB,EAAE,EACvC,WAAW,CAAC,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC9C,iBAAiB,CA+BnB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,iBAAiB,GAAG,SAAS,CAsC5E;AAED,0CAA0C;AAC1C,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAE7E"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
1
2
|
import { STAGNATION_PERSONA_MAP } from './types.js';
|
|
2
3
|
import { getLateralSystemPrompt, buildLateralPrompt } from './prompts.js';
|
|
3
4
|
/** 모든 persona 이름 (순회 순서) */
|
|
@@ -53,11 +54,11 @@ export function buildEscalationContext(triedPersonas, evaluationResult, evolutio
|
|
|
53
54
|
.map((v) => `AC[${v.acIndex}]: ${v.gaps.join(', ')}`);
|
|
54
55
|
const firstUnsatisfiedAC = unsatisfiedACs[0];
|
|
55
56
|
const recommendedSolutions = [
|
|
56
|
-
'태스크를 더 작은 단위로 분해한 뒤 새 스펙으로 `execute start`를 재시작하세요.',
|
|
57
|
+
'태스크를 더 작은 단위로 분해한 뒤 새 스펙으로 `execute start`를 재시작하세요. (`gate_resolve` optionId=restart)',
|
|
57
58
|
firstUnsatisfiedAC
|
|
58
|
-
? `"${firstUnsatisfiedAC}" — 해당 acceptance criteria를 수정한 뒤 \`evolve_patch\`로
|
|
59
|
-
: '해당 acceptance criteria를 수정한 뒤 `evolve_patch`로 재실행하세요.',
|
|
60
|
-
'이 태스크를 수동으로 처리한 뒤 `
|
|
59
|
+
? `"${firstUnsatisfiedAC}" — 해당 acceptance criteria를 수정한 뒤 \`evolve_patch\`로 재실행하세요. (\`gate_resolve\` optionId=patch_spec)`
|
|
60
|
+
: '해당 acceptance criteria를 수정한 뒤 `evolve_patch`로 재실행하세요. (`gate_resolve` optionId=patch_spec)',
|
|
61
|
+
'이 태스크를 수동으로 처리한 뒤 `evaluate`로 다시 검증하세요. (`gate_resolve` optionId=manual_task)',
|
|
61
62
|
];
|
|
62
63
|
return {
|
|
63
64
|
phase: 'evolving',
|
|
@@ -74,4 +75,51 @@ export function buildEscalationContext(triedPersonas, evaluationResult, evolutio
|
|
|
74
75
|
recommendedSolutions,
|
|
75
76
|
};
|
|
76
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* escalation을 사람이 답할 게이트로 바꾼다. 선택지는 recommendedSolutions의 세 방향에 abort를 더한 것이고
|
|
80
|
+
* 세션을 이어가는 쪽을 앞에 둔다.
|
|
81
|
+
*/
|
|
82
|
+
export function buildEscalationGate(escalation) {
|
|
83
|
+
const where = escalation.blockedTask
|
|
84
|
+
? `"${escalation.blockedTask.title}" 태스크에서`
|
|
85
|
+
: '평가 단계에서';
|
|
86
|
+
return {
|
|
87
|
+
gateId: `gate-${randomUUID()}`,
|
|
88
|
+
question: `${where} lateral persona ${escalation.triedPersonas.length}개를 다 써도 성공 기준에 못 닿았어요 (최고 점수 ${escalation.bestScore.toFixed(2)}). 어떻게 진행할까요?`,
|
|
89
|
+
options: [
|
|
90
|
+
{
|
|
91
|
+
id: 'patch_spec',
|
|
92
|
+
label: 'acceptance criteria나 제약을 고쳐 evolve_patch로 다시 돌린다',
|
|
93
|
+
nextAction: 'evolve_patch',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
id: 'manual_task',
|
|
97
|
+
label: '막힌 태스크를 사람이 직접 처리하고 evaluate로 다시 검증한다',
|
|
98
|
+
nextAction: 'evaluate',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
id: 'restart',
|
|
102
|
+
label: '태스크를 더 잘게 쪼갠 새 스펙으로 다시 시작한다 (이 세션은 종료된다)',
|
|
103
|
+
nextAction: 'start',
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: 'abort',
|
|
107
|
+
label: '여기서 멈춘다 (이 세션은 실패로 종료된다)',
|
|
108
|
+
nextAction: null,
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
context: {
|
|
112
|
+
blockedTask: escalation.blockedTask,
|
|
113
|
+
triedPersonas: escalation.triedPersonas,
|
|
114
|
+
bestScore: escalation.bestScore,
|
|
115
|
+
unresolved: escalation.suggestions,
|
|
116
|
+
},
|
|
117
|
+
status: 'open',
|
|
118
|
+
openedAt: new Date().toISOString(),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/** 이 선택지로 해소하면 세션이 이어지는가. 아니면 세션을 종료한다 */
|
|
122
|
+
export function gateOptionResumesSession(optionId) {
|
|
123
|
+
return optionId === 'patch_spec' || optionId === 'manual_task';
|
|
124
|
+
}
|
|
77
125
|
//# sourceMappingURL=lateral.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lateral.js","sourceRoot":"","sources":["../../../src/resilience/lateral.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lateral.js","sourceRoot":"","sources":["../../../src/resilience/lateral.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tienne/gestalt",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.86.0",
|
|
4
4
|
"description": "TypeScript AI Development Harness - Gestalt psychology-driven requirement clarification",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"scripts": {
|
|
29
29
|
"dev": "tsx bin/gestalt.ts",
|
|
30
30
|
"build": "tsc -p tsconfig.build.json",
|
|
31
|
-
"postbuild": "rm -rf dist/plugin && mkdir -p dist/plugin && cp -r plugin/agents plugin/role-agents plugin/review-agents plugin/personas plugin/skills dist/plugin/ && cp -r schemas dist/ && cp package.json dist/ && chmod +x dist/bin/gestalt.js && pnpm run verify:plugin && pnpm run verify:rules && pnpm run verify:output-style",
|
|
31
|
+
"postbuild": "rm -rf dist/plugin && mkdir -p dist/plugin && cp -r plugin/agents plugin/role-agents plugin/review-agents plugin/personas plugin/skills dist/plugin/ && cp -r schemas dist/ && cp package.json dist/ && chmod +x dist/bin/gestalt.js && pnpm run verify:plugin && pnpm run verify:rules && pnpm run verify:rule-overlap && pnpm run verify:output-style",
|
|
32
32
|
"verify:plugin": "tsx scripts/verify-plugin-assets.ts",
|
|
33
33
|
"prepublishOnly": "pnpm build",
|
|
34
34
|
"test": "vitest run",
|
|
@@ -43,7 +43,8 @@
|
|
|
43
43
|
"version:sync": "tsx scripts/sync-version.ts",
|
|
44
44
|
"postversion": "pnpm run version:sync && pnpm run build:output-style",
|
|
45
45
|
"verify:rules": "tsx scripts/verify-rule-refs.ts",
|
|
46
|
-
"
|
|
46
|
+
"verify:rule-overlap": "tsx scripts/verify-rule-overlap.ts",
|
|
47
|
+
"gate": "pnpm typecheck && pnpm verify:rules && pnpm verify:rule-overlap && pnpm lint && pnpm format:check && pnpm build && pnpm test",
|
|
47
48
|
"humanize:baseline": "tsx scripts/humanize-baseline.ts",
|
|
48
49
|
"build:output-style": "tsx scripts/build-output-style.ts",
|
|
49
50
|
"verify:output-style": "tsx scripts/build-output-style.ts --dry-run"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gestalt",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.86.0",
|
|
4
4
|
"description": "Gestalt psychology-driven AI development harness. Transforms scattered requirements into structured, validated specifications through interactive interviews.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tienne"
|
package/plugin/.mcp.json
CHANGED