vibe-coding-master 0.8.0 → 0.8.1
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.
|
@@ -4,7 +4,7 @@ import { checkMarkdownArtifact, readArtifactSectionValue } from "../../shared/va
|
|
|
4
4
|
import { resolveRepoPath } from "../adapters/filesystem.js";
|
|
5
5
|
import { VcmError } from "../errors.js";
|
|
6
6
|
import { submitTerminalInput } from "../runtime/terminal-submit.js";
|
|
7
|
-
import { readVcmMemoryBlock, replaceVcmMemoryBlock } from "../templates/harness/memory-block.js";
|
|
7
|
+
import { readVcmMemoryHostFrame, readVcmMemoryBlock, replaceVcmMemoryBlock } from "../templates/harness/memory-block.js";
|
|
8
8
|
import { ARCHITECT_PLANNING_MEMORY_CANDIDATE_PATH, architectPlanningCandidateSnapshotPath, memoryReviewRoleDraftPath, MEMORY_REVIEW_RUNS_ROOT, MEMORY_REVIEW_STATE_PATH } from "./memory-review-paths.js";
|
|
9
9
|
import { parseMemoryProposal, validateMemoryProposal } from "./memory-proposal-validation.js";
|
|
10
10
|
const MEMORY_FILE_DEFINITIONS = [
|
|
@@ -101,15 +101,20 @@ export function createAutoMemoryService(deps) {
|
|
|
101
101
|
await deps.fs.writeText(resolveRepoPath(taskRepoRoot, memoryRunHostFilePath(runId, definition.path)), await deps.fs.readText(resolveRepoPath(taskRepoRoot, definition.path)));
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
|
-
async function assertOnlyMemoryBlocksChanged(taskRepoRoot, runId
|
|
104
|
+
async function assertOnlyMemoryBlocksChanged(taskRepoRoot, runId) {
|
|
105
105
|
for (const definition of MEMORY_FILE_DEFINITIONS) {
|
|
106
106
|
const beforeHost = await deps.fs.readText(resolveRepoPath(taskRepoRoot, memoryRunHostFilePath(runId, definition.path)));
|
|
107
107
|
const currentHost = await deps.fs.readText(resolveRepoPath(taskRepoRoot, definition.path));
|
|
108
|
-
const
|
|
109
|
-
|
|
108
|
+
const beforeFrame = readVcmMemoryHostFrame(beforeHost);
|
|
109
|
+
const currentFrame = readVcmMemoryHostFrame(currentHost);
|
|
110
|
+
if (!beforeFrame || !currentFrame) {
|
|
111
|
+
throw missingMemoryBlockError(definition.path);
|
|
112
|
+
}
|
|
113
|
+
const difference = describeMemoryHostDifference(beforeFrame, currentFrame);
|
|
114
|
+
if (difference) {
|
|
110
115
|
throw new VcmError({
|
|
111
116
|
code: "MEMORY_REVIEW_SCOPE_CHANGED",
|
|
112
|
-
message: `Harness Engineer changed content outside the VCM memory block: ${definition.path}
|
|
117
|
+
message: `Harness Engineer changed content outside the VCM memory block: ${definition.path} (${difference}).`,
|
|
113
118
|
statusCode: 409,
|
|
114
119
|
hint: "Restore non-memory content, keep only the reviewed <VCM-memory> edit, and commit the correction."
|
|
115
120
|
});
|
|
@@ -833,7 +838,7 @@ export function createAutoMemoryService(deps) {
|
|
|
833
838
|
}
|
|
834
839
|
const before = await readRunMemorySet(taskRepoRoot, state.runId, "before");
|
|
835
840
|
const after = await readMemorySet(taskRepoRoot);
|
|
836
|
-
await assertOnlyMemoryBlocksChanged(taskRepoRoot, state.runId
|
|
841
|
+
await assertOnlyMemoryBlocksChanged(taskRepoRoot, state.runId);
|
|
837
842
|
const memoryPaths = MEMORY_FILE_DEFINITIONS.map((definition) => definition.path);
|
|
838
843
|
const uncommittedMemoryDiff = await deps.git.getDiff(taskRepoRoot, "HEAD", null, memoryPaths);
|
|
839
844
|
if (uncommittedMemoryDiff.trim()) {
|
|
@@ -1621,6 +1626,27 @@ function memoryRunFilePath(runId, snapshot, memoryPath) {
|
|
|
1621
1626
|
function memoryRunHostFilePath(runId, memoryPath) {
|
|
1622
1627
|
return `${MEMORY_REVIEW_RUNS_ROOT}/${runId}/host-before/${memoryPath}`;
|
|
1623
1628
|
}
|
|
1629
|
+
function describeMemoryHostDifference(before, current) {
|
|
1630
|
+
if (before.beforeBlock !== current.beforeBlock) {
|
|
1631
|
+
return describeTextDifference("before-block content", before.beforeBlock, current.beforeBlock);
|
|
1632
|
+
}
|
|
1633
|
+
if (before.afterBlock !== current.afterBlock) {
|
|
1634
|
+
return describeTextDifference("after-block content", before.afterBlock, current.afterBlock);
|
|
1635
|
+
}
|
|
1636
|
+
return undefined;
|
|
1637
|
+
}
|
|
1638
|
+
function describeTextDifference(label, before, current) {
|
|
1639
|
+
const limit = Math.min(before.length, current.length);
|
|
1640
|
+
let offset = 0;
|
|
1641
|
+
while (offset < limit && before[offset] === current[offset]) {
|
|
1642
|
+
offset += 1;
|
|
1643
|
+
}
|
|
1644
|
+
const excerptStart = Math.max(0, offset - 20);
|
|
1645
|
+
const excerptEnd = offset + 40;
|
|
1646
|
+
const snapshotExcerpt = JSON.stringify(before.slice(excerptStart, excerptEnd));
|
|
1647
|
+
const currentExcerpt = JSON.stringify(current.slice(excerptStart, excerptEnd));
|
|
1648
|
+
return `${label} differs at character ${offset}; snapshot=${snapshotExcerpt}; current=${currentExcerpt}`;
|
|
1649
|
+
}
|
|
1624
1650
|
function missingMemoryBlockError(filePath) {
|
|
1625
1651
|
return new VcmError({
|
|
1626
1652
|
code: "MEMORY_BLOCK_MISSING",
|
|
@@ -20,6 +20,16 @@ export function replaceVcmMemoryBlock(fileContent, content) {
|
|
|
20
20
|
}
|
|
21
21
|
return `${fileContent.slice(0, range.start)}${renderVcmMemoryBlock(content)}${fileContent.slice(range.end)}`;
|
|
22
22
|
}
|
|
23
|
+
export function readVcmMemoryHostFrame(fileContent) {
|
|
24
|
+
const range = findMemoryBlockRange(fileContent);
|
|
25
|
+
if (!range) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
beforeBlock: fileContent.slice(0, range.start),
|
|
30
|
+
afterBlock: fileContent.slice(range.end)
|
|
31
|
+
};
|
|
32
|
+
}
|
|
23
33
|
export function ensureVcmMemoryBlock(fileContent) {
|
|
24
34
|
if (findMemoryBlockRange(fileContent)) {
|
|
25
35
|
return fileContent;
|