@romandmitri/ai-patch 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/README.md +86 -0
- package/dist/content/Content.d.ts +2 -0
- package/dist/content/Content.d.ts.map +1 -0
- package/dist/content/Content.js +2 -0
- package/dist/content/Content.js.map +1 -0
- package/dist/content/ContentFormat.d.ts +4 -0
- package/dist/content/ContentFormat.d.ts.map +1 -0
- package/dist/content/ContentFormat.js +7 -0
- package/dist/content/ContentFormat.js.map +1 -0
- package/dist/content/ContentLineNumber.d.ts +2 -0
- package/dist/content/ContentLineNumber.d.ts.map +1 -0
- package/dist/content/ContentLineNumber.js +2 -0
- package/dist/content/ContentLineNumber.js.map +1 -0
- package/dist/content/ContentPartial.d.ts +2 -0
- package/dist/content/ContentPartial.d.ts.map +1 -0
- package/dist/content/ContentPartial.js +2 -0
- package/dist/content/ContentPartial.js.map +1 -0
- package/dist/content/ContentPosition.d.ts +2 -0
- package/dist/content/ContentPosition.d.ts.map +1 -0
- package/dist/content/ContentPosition.js +2 -0
- package/dist/content/ContentPosition.js.map +1 -0
- package/dist/error/PatchError.d.ts +19 -0
- package/dist/error/PatchError.d.ts.map +1 -0
- package/dist/error/PatchError.js +26 -0
- package/dist/error/PatchError.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/operation/Operation.d.ts +6 -0
- package/dist/operation/Operation.d.ts.map +1 -0
- package/dist/operation/Operation.js +2 -0
- package/dist/operation/Operation.js.map +1 -0
- package/dist/operation/OperationType.d.ts +8 -0
- package/dist/operation/OperationType.d.ts.map +1 -0
- package/dist/operation/OperationType.js +11 -0
- package/dist/operation/OperationType.js.map +1 -0
- package/dist/operation/Operation_Delete.d.ts +15 -0
- package/dist/operation/Operation_Delete.d.ts.map +1 -0
- package/dist/operation/Operation_Delete.js +12 -0
- package/dist/operation/Operation_Delete.js.map +1 -0
- package/dist/operation/Operation_InsertAfter.d.ts +17 -0
- package/dist/operation/Operation_InsertAfter.d.ts.map +1 -0
- package/dist/operation/Operation_InsertAfter.js +13 -0
- package/dist/operation/Operation_InsertAfter.js.map +1 -0
- package/dist/operation/Operation_InsertBefore.d.ts +17 -0
- package/dist/operation/Operation_InsertBefore.d.ts.map +1 -0
- package/dist/operation/Operation_InsertBefore.js +13 -0
- package/dist/operation/Operation_InsertBefore.js.map +1 -0
- package/dist/operation/Operation_Replace.d.ts +17 -0
- package/dist/operation/Operation_Replace.d.ts.map +1 -0
- package/dist/operation/Operation_Replace.js +13 -0
- package/dist/operation/Operation_Replace.js.map +1 -0
- package/dist/patch/Edit.d.ts +11 -0
- package/dist/patch/Edit.d.ts.map +1 -0
- package/dist/patch/Edit.js +2 -0
- package/dist/patch/Edit.js.map +1 -0
- package/dist/patch/InputIndex.d.ts +2 -0
- package/dist/patch/InputIndex.d.ts.map +1 -0
- package/dist/patch/InputIndex.js +2 -0
- package/dist/patch/InputIndex.js.map +1 -0
- package/dist/patch/Patcher.d.ts +8 -0
- package/dist/patch/Patcher.d.ts.map +1 -0
- package/dist/patch/Patcher.js +7 -0
- package/dist/patch/Patcher.js.map +1 -0
- package/dist/patch/Patcher_Text.d.ts +13 -0
- package/dist/patch/Patcher_Text.d.ts.map +1 -0
- package/dist/patch/Patcher_Text.js +106 -0
- package/dist/patch/Patcher_Text.js.map +1 -0
- package/dist/target/Target.d.ts +23 -0
- package/dist/target/Target.d.ts.map +1 -0
- package/dist/target/Target.js +76 -0
- package/dist/target/Target.js.map +1 -0
- package/dist/target/test/Target.apply.test.d.ts +2 -0
- package/dist/target/test/Target.apply.test.d.ts.map +1 -0
- package/dist/target/test/Target.apply.test.js +127 -0
- package/dist/target/test/Target.apply.test.js.map +1 -0
- package/dist/target/test/Target.complex.test.d.ts +2 -0
- package/dist/target/test/Target.complex.test.d.ts.map +1 -0
- package/dist/target/test/Target.complex.test.js +217 -0
- package/dist/target/test/Target.complex.test.js.map +1 -0
- package/dist/target/test/Target.errors.test.d.ts +2 -0
- package/dist/target/test/Target.errors.test.d.ts.map +1 -0
- package/dist/target/test/Target.errors.test.js +108 -0
- package/dist/target/test/Target.errors.test.js.map +1 -0
- package/dist/target/test/Target.schema.test.d.ts +2 -0
- package/dist/target/test/Target.schema.test.d.ts.map +1 -0
- package/dist/target/test/Target.schema.test.js +101 -0
- package/dist/target/test/Target.schema.test.js.map +1 -0
- package/dist/target/test/Target.tool.test.d.ts +2 -0
- package/dist/target/test/Target.tool.test.d.ts.map +1 -0
- package/dist/target/test/Target.tool.test.js +76 -0
- package/dist/target/test/Target.tool.test.js.map +1 -0
- package/docs/development.md +28 -0
- package/package.json +67 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { fail, PatchErrorCode } from "#src/error/PatchError.js";
|
|
2
|
+
import { OperationType } from "#src/operation/OperationType.js";
|
|
3
|
+
import { Patcher } from "#src/patch/Patcher.js";
|
|
4
|
+
export class Patcher_Text extends Patcher {
|
|
5
|
+
apply(operations) {
|
|
6
|
+
const newline = this.detectNewline();
|
|
7
|
+
const normalizedContent = this.normalizeNewlines(this.content);
|
|
8
|
+
const lineStarts = this.buildLineStarts(normalizedContent);
|
|
9
|
+
const edits = operations.map((operation, inputIndex) => this.createEdit(operation, inputIndex, normalizedContent, lineStarts));
|
|
10
|
+
this.validateConflicts(edits);
|
|
11
|
+
if (edits.every((edit) => normalizedContent.slice(edit.start, edit.end) === edit.replacement)) {
|
|
12
|
+
return this.content;
|
|
13
|
+
}
|
|
14
|
+
const orderedEdits = [...edits].sort((left, right) => right.start - left.start || right.end - left.end || right.inputIndex - left.inputIndex);
|
|
15
|
+
let result = normalizedContent;
|
|
16
|
+
for (const edit of orderedEdits) {
|
|
17
|
+
result = result.slice(0, edit.start) + edit.replacement + result.slice(edit.end);
|
|
18
|
+
}
|
|
19
|
+
return newline === "\r\n" ? result.replace(/\n/g, "\r\n") : result;
|
|
20
|
+
}
|
|
21
|
+
normalizeNewlines(text) {
|
|
22
|
+
return text.replace(/\r\n/g, "\n");
|
|
23
|
+
}
|
|
24
|
+
detectNewline() {
|
|
25
|
+
const firstNewline = this.content.indexOf("\n");
|
|
26
|
+
return firstNewline > 0 && this.content[firstNewline - 1] === "\r" ? "\r\n" : "\n";
|
|
27
|
+
}
|
|
28
|
+
buildLineStarts(content) {
|
|
29
|
+
const starts = [0];
|
|
30
|
+
for (let offset = content.indexOf("\n"); offset !== -1;) {
|
|
31
|
+
starts.push(offset + 1);
|
|
32
|
+
offset = content.indexOf("\n", offset + 1);
|
|
33
|
+
}
|
|
34
|
+
return starts;
|
|
35
|
+
}
|
|
36
|
+
createEdit(operation, inputIndex, content, lineStarts) {
|
|
37
|
+
if (operation.expectedLine > lineStarts.length) {
|
|
38
|
+
return fail(inputIndex, PatchErrorCode.InvalidExpectedLine, "expectedLine must identify a 1-based line in the original content");
|
|
39
|
+
}
|
|
40
|
+
const start = lineStarts[operation.expectedLine - 1];
|
|
41
|
+
const oldText = this.normalizeNewlines(operation.oldText);
|
|
42
|
+
const anchorEnd = start + oldText.length;
|
|
43
|
+
if (anchorEnd > content.length || content.slice(start, anchorEnd) !== oldText) {
|
|
44
|
+
return fail(inputIndex, PatchErrorCode.AnchorMismatch, "oldText does not match exactly at expectedLine");
|
|
45
|
+
}
|
|
46
|
+
switch (operation.operation) {
|
|
47
|
+
case OperationType.Replace:
|
|
48
|
+
return {
|
|
49
|
+
inputIndex,
|
|
50
|
+
start,
|
|
51
|
+
end: anchorEnd,
|
|
52
|
+
replacement: this.normalizeNewlines(operation.newText),
|
|
53
|
+
isInsertion: oldText.length === 0 && operation.newText.length > 0,
|
|
54
|
+
};
|
|
55
|
+
case OperationType.InsertBefore:
|
|
56
|
+
return {
|
|
57
|
+
inputIndex,
|
|
58
|
+
start,
|
|
59
|
+
end: start,
|
|
60
|
+
replacement: this.normalizeNewlines(operation.newText),
|
|
61
|
+
isInsertion: true,
|
|
62
|
+
};
|
|
63
|
+
case OperationType.InsertAfter:
|
|
64
|
+
return {
|
|
65
|
+
inputIndex,
|
|
66
|
+
start: anchorEnd,
|
|
67
|
+
end: anchorEnd,
|
|
68
|
+
replacement: this.normalizeNewlines(operation.newText),
|
|
69
|
+
isInsertion: true,
|
|
70
|
+
};
|
|
71
|
+
case OperationType.Delete:
|
|
72
|
+
return {
|
|
73
|
+
inputIndex,
|
|
74
|
+
start,
|
|
75
|
+
end: anchorEnd,
|
|
76
|
+
replacement: "",
|
|
77
|
+
isInsertion: false,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
rangesOverlap(left, right) {
|
|
82
|
+
return Math.max(left.start, right.start) < Math.min(left.end, right.end);
|
|
83
|
+
}
|
|
84
|
+
validateConflicts(edits) {
|
|
85
|
+
for (let index = 0; index < edits.length; index += 1) {
|
|
86
|
+
const current = edits[index];
|
|
87
|
+
for (let priorIndex = 0; priorIndex < index; priorIndex += 1) {
|
|
88
|
+
const prior = edits[priorIndex];
|
|
89
|
+
const currentConsumes = current.start < current.end;
|
|
90
|
+
const priorConsumes = prior.start < prior.end;
|
|
91
|
+
if (currentConsumes && priorConsumes && this.rangesOverlap(current, prior)) {
|
|
92
|
+
fail(current.inputIndex, PatchErrorCode.OverlappingRange, `consumed range overlaps patch at index ${prior.inputIndex}`);
|
|
93
|
+
}
|
|
94
|
+
const insertion = current.isInsertion ? current : prior.isInsertion ? prior : undefined;
|
|
95
|
+
const consumed = currentConsumes ? current : priorConsumes ? prior : undefined;
|
|
96
|
+
if (insertion !== undefined && consumed !== undefined && insertion.start > consumed.start && insertion.start < consumed.end) {
|
|
97
|
+
fail(insertion.inputIndex, PatchErrorCode.InsertionInsideRange, `insertion falls inside the range consumed by patch at index ${consumed.inputIndex}`);
|
|
98
|
+
}
|
|
99
|
+
if (current.isInsertion && prior.isInsertion && current.start === prior.start) {
|
|
100
|
+
fail(current.inputIndex, PatchErrorCode.ConflictingInsertion, `insertion conflicts with patch at index ${prior.inputIndex}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=Patcher_Text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Patcher_Text.js","sourceRoot":"","sources":["../../src/patch/Patcher_Text.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Content } from "#src/content/Content.js";
|
|
2
|
+
import { ContentFormat } from "#src/content/ContentFormat.js";
|
|
3
|
+
import type { Operation } from "#src/operation/Operation.js";
|
|
4
|
+
import { type Tool } from "ai";
|
|
5
|
+
import { type ZodType } from "zod";
|
|
6
|
+
export interface TargetOptions {
|
|
7
|
+
readonly content: Content;
|
|
8
|
+
readonly format: ContentFormat;
|
|
9
|
+
}
|
|
10
|
+
export type TargetTool = Tool<{
|
|
11
|
+
patches: Operation[];
|
|
12
|
+
}, Content>;
|
|
13
|
+
export declare class Target {
|
|
14
|
+
readonly content: Content;
|
|
15
|
+
readonly format: ContentFormat;
|
|
16
|
+
constructor(p: TargetOptions);
|
|
17
|
+
static fromContent: (content: Content, format?: ContentFormat) => Target;
|
|
18
|
+
toSchema(): ZodType<Operation[]>;
|
|
19
|
+
apply(patches: readonly Operation[]): Content;
|
|
20
|
+
toVercelTool(): TargetTool;
|
|
21
|
+
private failValidation;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=Target.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Target.d.ts","sourceRoot":"","sources":["../../src/target/Target.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAE9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAM7D,OAAO,EAAQ,KAAK,IAAI,EAAE,MAAM,IAAI,CAAC;AACrC,OAAO,EAAoB,KAAK,OAAO,EAAE,MAAM,KAAK,CAAC;AAErD,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;CAC/B;AAED,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC;IAAE,OAAO,EAAE,SAAS,EAAE,CAAA;CAAE,EAAE,OAAO,CAAC,CAAC;AAEjE,qBAAa,MAAM;IAClB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAE/B,YAAY,CAAC,EAAE,aAAa,EAQ3B;IAED,MAAM,CAAC,WAAW,YAAa,OAAO,WAAW,aAAa,YAK5D;IAEF,QAAQ,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAa/B;IAED,KAAK,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,GAAG,OAAO,CAU5C;IAED,YAAY,IAAI,UAAU,CAWzB;IAED,OAAO,CAAC,cAAc;CAiBtB"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { ContentFormat } from "#src/content/ContentFormat.js";
|
|
2
|
+
import { fail, PatchErrorCode } from "#src/error/PatchError.js";
|
|
3
|
+
import { PatchOperation_Delete_Schema } from "#src/operation/Operation_Delete.js";
|
|
4
|
+
import { PatchOperation_InsertAfter_Schema } from "#src/operation/Operation_InsertAfter.js";
|
|
5
|
+
import { PatchOperation_InsertBefore_Schema } from "#src/operation/Operation_InsertBefore.js";
|
|
6
|
+
import { PatchOperation_Replace_Schema } from "#src/operation/Operation_Replace.js";
|
|
7
|
+
import { Patcher_Text } from "#src/patch/Patcher_Text.js";
|
|
8
|
+
import { tool } from "ai";
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
export class Target {
|
|
11
|
+
content;
|
|
12
|
+
format;
|
|
13
|
+
constructor(p) {
|
|
14
|
+
if (p.format !== ContentFormat.Text) {
|
|
15
|
+
throw new RangeError(`Unsupported content format: ${p.format}`);
|
|
16
|
+
}
|
|
17
|
+
this.content = p.content;
|
|
18
|
+
this.format = p.format;
|
|
19
|
+
Object.freeze(this);
|
|
20
|
+
}
|
|
21
|
+
static fromContent = (content, format) => {
|
|
22
|
+
return new Target({
|
|
23
|
+
content: content,
|
|
24
|
+
format: format ?? ContentFormat.Text,
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
toSchema() {
|
|
28
|
+
const operationSchema = z.discriminatedUnion("operation", [
|
|
29
|
+
PatchOperation_Replace_Schema,
|
|
30
|
+
PatchOperation_InsertBefore_Schema,
|
|
31
|
+
PatchOperation_InsertAfter_Schema,
|
|
32
|
+
PatchOperation_Delete_Schema,
|
|
33
|
+
]);
|
|
34
|
+
return z
|
|
35
|
+
.array(operationSchema)
|
|
36
|
+
.describe("Atomically update this target only. Every anchor and conflict is validated against the original content coordinates, and any invalid patch rejects the entire list.");
|
|
37
|
+
}
|
|
38
|
+
apply(patches) {
|
|
39
|
+
const parsed = this.toSchema().safeParse(patches);
|
|
40
|
+
if (!parsed.success) {
|
|
41
|
+
this.failValidation(parsed.error.issues[0]);
|
|
42
|
+
}
|
|
43
|
+
switch (this.format) {
|
|
44
|
+
case ContentFormat.Text:
|
|
45
|
+
return new Patcher_Text(this.content).apply(parsed.data);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
toVercelTool() {
|
|
49
|
+
return tool({
|
|
50
|
+
description: "Atomically patch this target only. Every patch is validated against this target's original content, and execution returns the updated content string.",
|
|
51
|
+
inputSchema: z
|
|
52
|
+
.strictObject({
|
|
53
|
+
patches: this.toSchema().describe("The complete atomic patch list for this target only."),
|
|
54
|
+
})
|
|
55
|
+
.describe("Patch input for this immutable target; patches cannot address any other target."),
|
|
56
|
+
execute: ({ patches }) => this.apply(patches),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
failValidation(issue) {
|
|
60
|
+
const inputIndex = typeof issue.path[0] === "number" ? issue.path[0] : 0;
|
|
61
|
+
const field = issue.path[1];
|
|
62
|
+
switch (field) {
|
|
63
|
+
case "operation":
|
|
64
|
+
return fail(inputIndex, PatchErrorCode.InvalidOperation, "has an unsupported operation");
|
|
65
|
+
case "expectedLine":
|
|
66
|
+
return fail(inputIndex, PatchErrorCode.InvalidExpectedLine, "expectedLine must be a positive 1-based line number");
|
|
67
|
+
case "oldText":
|
|
68
|
+
return fail(inputIndex, PatchErrorCode.InvalidOldText, "oldText must be a string");
|
|
69
|
+
case "newText":
|
|
70
|
+
return fail(inputIndex, PatchErrorCode.InvalidNewText, "newText must be a string");
|
|
71
|
+
default:
|
|
72
|
+
return fail(inputIndex, PatchErrorCode.InvalidPatch, "must match a supported patch operation");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=Target.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Target.js","sourceRoot":"","sources":["../../src/target/Target.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Target.apply.test.d.ts","sourceRoot":"","sources":["../../../src/target/test/Target.apply.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { ContentFormat, OperationType, Target } from "#src/index.js";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { test } from "node:test";
|
|
4
|
+
function target(content) {
|
|
5
|
+
return new Target({ content, format: ContentFormat.Text });
|
|
6
|
+
}
|
|
7
|
+
test("apply supports all four operations", async (t) => {
|
|
8
|
+
const cases = [
|
|
9
|
+
{
|
|
10
|
+
name: "replace",
|
|
11
|
+
patch: {
|
|
12
|
+
operation: OperationType.Replace,
|
|
13
|
+
expectedLine: 2,
|
|
14
|
+
oldText: "beta",
|
|
15
|
+
newText: "second",
|
|
16
|
+
},
|
|
17
|
+
expected: "alpha\nsecond\ngamma",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: "insertBefore",
|
|
21
|
+
patch: {
|
|
22
|
+
operation: OperationType.InsertBefore,
|
|
23
|
+
expectedLine: 2,
|
|
24
|
+
oldText: "beta",
|
|
25
|
+
newText: "before\n",
|
|
26
|
+
},
|
|
27
|
+
expected: "alpha\nbefore\nbeta\ngamma",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "insertAfter",
|
|
31
|
+
patch: {
|
|
32
|
+
operation: OperationType.InsertAfter,
|
|
33
|
+
expectedLine: 2,
|
|
34
|
+
oldText: "beta",
|
|
35
|
+
newText: "\nafter",
|
|
36
|
+
},
|
|
37
|
+
expected: "alpha\nbeta\nafter\ngamma",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: "delete",
|
|
41
|
+
patch: {
|
|
42
|
+
operation: OperationType.Delete,
|
|
43
|
+
expectedLine: 2,
|
|
44
|
+
oldText: "beta\n",
|
|
45
|
+
},
|
|
46
|
+
expected: "alpha\ngamma",
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
for (const example of cases) {
|
|
50
|
+
await t.test(example.name, () => {
|
|
51
|
+
assert.equal(target("alpha\nbeta\ngamma").apply([example.patch]), example.expected);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
test("apply replaces multiline anchors exactly", () => {
|
|
56
|
+
const content = "# Heading\nold first\nold second\nfooter\n";
|
|
57
|
+
const result = target(content).apply([
|
|
58
|
+
{
|
|
59
|
+
operation: OperationType.Replace,
|
|
60
|
+
expectedLine: 2,
|
|
61
|
+
oldText: "old first\nold second",
|
|
62
|
+
newText: "new first\nnew second\nnew third",
|
|
63
|
+
},
|
|
64
|
+
]);
|
|
65
|
+
assert.equal(result, "# Heading\nnew first\nnew second\nnew third\nfooter\n");
|
|
66
|
+
});
|
|
67
|
+
test("a batch uses original line coordinates after line-changing edits", () => {
|
|
68
|
+
const result = target("one\ntwo\nthree\nfour").apply([
|
|
69
|
+
{
|
|
70
|
+
operation: OperationType.InsertBefore,
|
|
71
|
+
expectedLine: 2,
|
|
72
|
+
oldText: "two",
|
|
73
|
+
newText: "added-a\nadded-b\n",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
operation: OperationType.Delete,
|
|
77
|
+
expectedLine: 4,
|
|
78
|
+
oldText: "four",
|
|
79
|
+
},
|
|
80
|
+
]);
|
|
81
|
+
assert.equal(result, "one\nadded-a\nadded-b\ntwo\nthree\n");
|
|
82
|
+
});
|
|
83
|
+
test("CRLF anchors match LF patches and CRLF output is preserved", () => {
|
|
84
|
+
const result = target("one\r\ntwo\r\nthree").apply([
|
|
85
|
+
{
|
|
86
|
+
operation: OperationType.Replace,
|
|
87
|
+
expectedLine: 2,
|
|
88
|
+
oldText: "two\nthree",
|
|
89
|
+
newText: "second\nthird\nfourth",
|
|
90
|
+
},
|
|
91
|
+
]);
|
|
92
|
+
assert.equal(result, "one\r\nsecond\r\nthird\r\nfourth");
|
|
93
|
+
});
|
|
94
|
+
test("empty content and a final line without a newline can be patched", () => {
|
|
95
|
+
assert.equal(target("").apply([
|
|
96
|
+
{
|
|
97
|
+
operation: OperationType.InsertBefore,
|
|
98
|
+
expectedLine: 1,
|
|
99
|
+
oldText: "",
|
|
100
|
+
newText: "# Created\n",
|
|
101
|
+
},
|
|
102
|
+
]), "# Created\n");
|
|
103
|
+
assert.equal(target("first\nlast").apply([
|
|
104
|
+
{
|
|
105
|
+
operation: OperationType.Replace,
|
|
106
|
+
expectedLine: 2,
|
|
107
|
+
oldText: "last",
|
|
108
|
+
newText: "final",
|
|
109
|
+
},
|
|
110
|
+
]), "first\nfinal");
|
|
111
|
+
});
|
|
112
|
+
test("Target remains immutable after applying patches", () => {
|
|
113
|
+
const patchTarget = target("before");
|
|
114
|
+
const result = patchTarget.apply([
|
|
115
|
+
{
|
|
116
|
+
operation: OperationType.Replace,
|
|
117
|
+
expectedLine: 1,
|
|
118
|
+
oldText: "before",
|
|
119
|
+
newText: "after",
|
|
120
|
+
},
|
|
121
|
+
]);
|
|
122
|
+
assert.equal(result, "after");
|
|
123
|
+
assert.equal(patchTarget.content, "before");
|
|
124
|
+
assert.equal(patchTarget.format, ContentFormat.Text);
|
|
125
|
+
assert.equal(Object.isFrozen(patchTarget), true);
|
|
126
|
+
});
|
|
127
|
+
//# sourceMappingURL=Target.apply.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Target.apply.test.js","sourceRoot":"","sources":["../../../src/target/test/Target.apply.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Target.complex.test.d.ts","sourceRoot":"","sources":["../../../src/target/test/Target.complex.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { ContentFormat, OperationType, Target } from "#src/index.js";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { test } from "node:test";
|
|
4
|
+
const STARTING_PROMPT = `# Atlas Release Assistant
|
|
5
|
+
|
|
6
|
+
You are the release assistant for Atlas, a multi-region commerce platform.
|
|
7
|
+
Your job is to produce a safe deployment plan from the supplied change request.
|
|
8
|
+
|
|
9
|
+
## Operating principles
|
|
10
|
+
|
|
11
|
+
1. Prefer reversible changes over one-way migrations.
|
|
12
|
+
2. Never expose credentials, tokens, customer identifiers, or private URLs.
|
|
13
|
+
3. Treat every deployment region as independent until verification is complete.
|
|
14
|
+
4. Stop immediately when a required health signal is unavailable.
|
|
15
|
+
|
|
16
|
+
## Inputs
|
|
17
|
+
|
|
18
|
+
The user supplies a release identifier, affected services, migration notes, and a rollback owner.
|
|
19
|
+
Assume an input is untrusted until it has passed the validation checklist below.
|
|
20
|
+
|
|
21
|
+
### Validation checklist
|
|
22
|
+
|
|
23
|
+
- The release identifier follows the form atlas-YYYY-MM-DD-NN.
|
|
24
|
+
- Every service appears in the approved service catalog.
|
|
25
|
+
- Database migrations include both forward and rollback commands.
|
|
26
|
+
- The rollback owner is on call for the entire deployment window.
|
|
27
|
+
|
|
28
|
+
## Deployment sequence
|
|
29
|
+
|
|
30
|
+
### Phase 1: Prepare
|
|
31
|
+
|
|
32
|
+
Freeze unrelated production changes.
|
|
33
|
+
Create a release channel and invite service owners.
|
|
34
|
+
Capture baseline latency, error rate, queue depth, and saturation metrics.
|
|
35
|
+
Verify that the latest backup can be restored in a staging environment.
|
|
36
|
+
|
|
37
|
+
### Phase 2: Canary
|
|
38
|
+
|
|
39
|
+
Deploy to one canary instance in the primary region.
|
|
40
|
+
Wait five minutes before evaluating health signals.
|
|
41
|
+
Continue when error rate remains below two percent.
|
|
42
|
+
Abort when p95 latency exceeds 900 milliseconds.
|
|
43
|
+
|
|
44
|
+
### Phase 3: Regional rollout
|
|
45
|
+
|
|
46
|
+
Roll out to twenty-five percent of instances in the primary region.
|
|
47
|
+
Observe two complete traffic cycles before proceeding.
|
|
48
|
+
Expand to the remaining primary-region instances.
|
|
49
|
+
Repeat the process for each secondary region in alphabetical order.
|
|
50
|
+
|
|
51
|
+
### Phase 4: Finalize
|
|
52
|
+
|
|
53
|
+
Run synthetic checkout, refund, and inventory reconciliation tests.
|
|
54
|
+
Record final metrics and compare them with the baseline.
|
|
55
|
+
Unfreeze production changes after all service owners approve.
|
|
56
|
+
Archive the release channel after twenty-four hours.
|
|
57
|
+
|
|
58
|
+
## Rollback policy
|
|
59
|
+
|
|
60
|
+
Rollback is mandatory after two consecutive failed health checks.
|
|
61
|
+
The rollback owner coordinates application and database recovery.
|
|
62
|
+
Do not retry the deployment during the same change window.
|
|
63
|
+
|
|
64
|
+
## Response format
|
|
65
|
+
|
|
66
|
+
Return a concise checklist grouped by phase.
|
|
67
|
+
For each step include the owner, expected signal, and failure action.
|
|
68
|
+
Finish with an explicit GO or NO-GO recommendation.
|
|
69
|
+
`;
|
|
70
|
+
function target() {
|
|
71
|
+
return new Target({
|
|
72
|
+
content: STARTING_PROMPT,
|
|
73
|
+
format: ContentFormat.Text,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
test("applies a complex batch in deliberately non-document order", () => {
|
|
77
|
+
const patches = [
|
|
78
|
+
{
|
|
79
|
+
operation: OperationType.Replace,
|
|
80
|
+
expectedLine: 44,
|
|
81
|
+
oldText: "Observe two complete traffic cycles before proceeding.",
|
|
82
|
+
newText: "Observe three complete traffic cycles before proceeding.\nRequire sign-off from the regional service owner.",
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
operation: OperationType.InsertAfter,
|
|
86
|
+
expectedLine: 4,
|
|
87
|
+
oldText: "Your job is to produce a safe deployment plan from the supplied change request.",
|
|
88
|
+
newText: "\nAlways state assumptions before presenting the deployment plan.",
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
operation: OperationType.Delete,
|
|
92
|
+
expectedLine: 59,
|
|
93
|
+
oldText: "Do not retry the deployment during the same change window.\n",
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
operation: OperationType.InsertBefore,
|
|
97
|
+
expectedLine: 63,
|
|
98
|
+
oldText: "Return a concise checklist grouped by phase.",
|
|
99
|
+
newText: "State the release identifier at the top of the response.\n",
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
operation: OperationType.Replace,
|
|
103
|
+
expectedLine: 37,
|
|
104
|
+
oldText: "Wait five minutes before evaluating health signals.\nContinue when error rate remains below two percent.\nAbort when p95 latency exceeds 900 milliseconds.",
|
|
105
|
+
newText: "Wait ten minutes before evaluating health signals.\nContinue when error rate remains below one percent.\nAbort when p95 latency exceeds 750 milliseconds.",
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
const result = target().apply(patches);
|
|
109
|
+
assert.match(result, /Always state assumptions before presenting the deployment plan\./);
|
|
110
|
+
assert.match(result, /Wait ten minutes before evaluating health signals\./);
|
|
111
|
+
assert.match(result, /error rate remains below one percent/);
|
|
112
|
+
assert.match(result, /p95 latency exceeds 750 milliseconds/);
|
|
113
|
+
assert.match(result, /Observe three complete traffic cycles/);
|
|
114
|
+
assert.match(result, /Require sign-off from the regional service owner\./);
|
|
115
|
+
assert.doesNotMatch(result, /Do not retry the deployment/);
|
|
116
|
+
assert.match(result, /State the release identifier at the top/);
|
|
117
|
+
assert.equal(target().content, STARTING_PROMPT);
|
|
118
|
+
});
|
|
119
|
+
test("produces identical output when independent operations are reversed", () => {
|
|
120
|
+
const forward = [
|
|
121
|
+
{
|
|
122
|
+
operation: OperationType.Replace,
|
|
123
|
+
expectedLine: 1,
|
|
124
|
+
oldText: "# Atlas Release Assistant",
|
|
125
|
+
newText: "# Atlas Deployment Controller",
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
operation: OperationType.Delete,
|
|
129
|
+
expectedLine: 23,
|
|
130
|
+
oldText: "- The rollback owner is on call for the entire deployment window.\n",
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
operation: OperationType.InsertAfter,
|
|
134
|
+
expectedLine: 53,
|
|
135
|
+
oldText: "Archive the release channel after twenty-four hours.",
|
|
136
|
+
newText: "\nPublish a post-deployment summary before archiving the channel.",
|
|
137
|
+
},
|
|
138
|
+
];
|
|
139
|
+
const reversed = [...forward].reverse();
|
|
140
|
+
const forwardResult = target().apply(forward);
|
|
141
|
+
const reversedResult = target().apply(reversed);
|
|
142
|
+
assert.equal(reversedResult, forwardResult);
|
|
143
|
+
assert.match(forwardResult, /^# Atlas Deployment Controller/);
|
|
144
|
+
assert.doesNotMatch(forwardResult, /rollback owner is on call/);
|
|
145
|
+
assert.match(forwardResult, /Publish a post-deployment summary/);
|
|
146
|
+
});
|
|
147
|
+
test("combines adjacent boundary insertions with multiline replacement", () => {
|
|
148
|
+
const result = target().apply([
|
|
149
|
+
{
|
|
150
|
+
operation: OperationType.InsertBefore,
|
|
151
|
+
expectedLine: 34,
|
|
152
|
+
oldText: "### Phase 2: Canary",
|
|
153
|
+
newText: "> Canary execution requires an active incident commander.\n\n",
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
operation: OperationType.Replace,
|
|
157
|
+
expectedLine: 34,
|
|
158
|
+
oldText: "### Phase 2: Canary",
|
|
159
|
+
newText: "### Phase 2: Controlled canary",
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
operation: OperationType.InsertAfter,
|
|
163
|
+
expectedLine: 34,
|
|
164
|
+
oldText: "### Phase 2: Canary",
|
|
165
|
+
newText: "\n\nCanary changes must be reversible without a rebuild.",
|
|
166
|
+
},
|
|
167
|
+
]);
|
|
168
|
+
assert.match(result, /> Canary execution requires an active incident commander\.\n\n### Phase 2: Controlled canary\n\nCanary changes must be reversible without a rebuild\./);
|
|
169
|
+
});
|
|
170
|
+
test("deletes an early section while later patches retain original line numbers", () => {
|
|
171
|
+
const result = target().apply([
|
|
172
|
+
{
|
|
173
|
+
operation: OperationType.Delete,
|
|
174
|
+
expectedLine: 13,
|
|
175
|
+
oldText: "## Inputs\n\nThe user supplies a release identifier, affected services, migration notes, and a rollback owner.\nAssume an input is untrusted until it has passed the validation checklist below.\n\n",
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
operation: OperationType.Replace,
|
|
179
|
+
expectedLine: 48,
|
|
180
|
+
oldText: "### Phase 4: Finalize",
|
|
181
|
+
newText: "### Phase 4: Verify and finalize",
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
operation: OperationType.InsertBefore,
|
|
185
|
+
expectedLine: 55,
|
|
186
|
+
oldText: "## Rollback policy",
|
|
187
|
+
newText: "## Audit requirements\n\nAttach deployment logs and metric snapshots to the release record.\n\n",
|
|
188
|
+
},
|
|
189
|
+
]);
|
|
190
|
+
assert.doesNotMatch(result, /## Inputs/);
|
|
191
|
+
assert.match(result, /### Phase 4: Verify and finalize/);
|
|
192
|
+
assert.match(result, /## Audit requirements/);
|
|
193
|
+
assert.match(result, /Attach deployment logs and metric snapshots/);
|
|
194
|
+
assert.match(result, /## Rollback policy/);
|
|
195
|
+
});
|
|
196
|
+
test("replaces the complete response contract and edits distant safeguards", () => {
|
|
197
|
+
const result = target().apply([
|
|
198
|
+
{
|
|
199
|
+
operation: OperationType.Replace,
|
|
200
|
+
expectedLine: 63,
|
|
201
|
+
oldText: "Return a concise checklist grouped by phase.\nFor each step include the owner, expected signal, and failure action.\nFinish with an explicit GO or NO-GO recommendation.",
|
|
202
|
+
newText: "Return a Markdown table grouped by phase.\nInclude columns for owner, command, expected signal, timeout, and rollback action.\nAfter the table, list unresolved risks.\nFinish with exactly one recommendation: GO, HOLD, or ROLLBACK.",
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
operation: OperationType.Replace,
|
|
206
|
+
expectedLine: 8,
|
|
207
|
+
oldText: "1. Prefer reversible changes over one-way migrations.\n2. Never expose credentials, tokens, customer identifiers, or private URLs.\n3. Treat every deployment region as independent until verification is complete.\n4. Stop immediately when a required health signal is unavailable.",
|
|
208
|
+
newText: "1. Prefer reversible changes over one-way migrations.\n2. Never expose credentials, tokens, customer identifiers, or private URLs.\n3. Treat every deployment region as independent until verification is complete.\n4. Stop immediately when a required health signal is unavailable.\n5. Require a human confirmation before database migrations begin.",
|
|
209
|
+
},
|
|
210
|
+
]);
|
|
211
|
+
assert.match(result, /Require a human confirmation before database migrations/);
|
|
212
|
+
assert.match(result, /Return a Markdown table grouped by phase/);
|
|
213
|
+
assert.match(result, /columns for owner, command, expected signal, timeout/);
|
|
214
|
+
assert.match(result, /list unresolved risks/);
|
|
215
|
+
assert.match(result, /GO, HOLD, or ROLLBACK/);
|
|
216
|
+
});
|
|
217
|
+
//# sourceMappingURL=Target.complex.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Target.complex.test.js","sourceRoot":"","sources":["../../../src/target/test/Target.complex.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Target.errors.test.d.ts","sourceRoot":"","sources":["../../../src/target/test/Target.errors.test.ts"],"names":[],"mappings":""}
|