dsh-hashline-edit 0.2.2 → 0.3.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 +57 -45
- package/cordis.patch.yml +9 -3
- package/lib/client.js +231 -0
- package/lib/index.js +3298 -3957
- package/lib/types/dsh/contracts.d.ts +12 -3
- package/lib/types/dsh/fs.d.ts +3 -0
- package/lib/types/dsh/guidance.d.ts +12 -6
- package/lib/types/dsh/hide.d.ts +79 -0
- package/lib/types/dsh/host-compat.d.ts +7 -78
- package/lib/types/dsh/index.d.ts +53 -10
- package/lib/types/dsh/metrics/events.d.ts +1 -1
- package/lib/types/dsh/metrics/observer.d.ts +1 -1
- package/lib/types/dsh/sandbox.d.ts +2 -2
- package/lib/types/dsh/shell-hook.d.ts +1 -1
- package/lib/types/dsh/tools/apply-patch.d.ts +38 -0
- package/lib/types/dsh/tools/read.d.ts +3 -3
- package/lib/types/src/apply-patch/commit.d.ts +49 -0
- package/lib/types/src/apply-patch/grammar.d.ts +29 -0
- package/lib/types/src/apply-patch/lifecycle.d.ts +32 -0
- package/lib/types/src/apply-patch/plan.d.ts +50 -0
- package/lib/types/src/apply-patch/render.d.ts +51 -0
- package/lib/types/src/apply-patch/resolve.d.ts +129 -0
- package/lib/types/src/apply-patch/tool.d.ts +54 -0
- package/lib/types/src/apply-patch/types.d.ts +362 -0
- package/lib/types/src/domain-errors.d.ts +16 -2
- package/lib/types/src/edit-undo.d.ts +11 -2
- package/lib/types/src/file-content/index.d.ts +1 -1
- package/lib/types/src/file-content/preview.d.ts +1 -1
- package/lib/types/src/fs-lifecycle.d.ts +44 -0
- package/lib/types/src/hashline/alphabet.d.ts +4 -3
- package/lib/types/src/hashline/hash-identity.d.ts +12 -7
- package/lib/types/src/host-utils.d.ts +63 -0
- package/lib/types/src/mutation-engine/edit-request.d.ts +34 -0
- package/lib/types/src/mutation-engine/pipeline.d.ts +8 -1
- package/lib/types/src/mutation-engine/types.d.ts +40 -50
- package/lib/types/src/served-session/serve-render.d.ts +6 -0
- package/lib/types/src/undo-store.d.ts +17 -1
- package/package.json +37 -21
- package/prompts/apply-patch-guidelines.md +4 -0
- package/prompts/apply-patch.md +1 -0
- package/prompts/read-guidelines.md +6 -6
- package/prompts/read.md +1 -1
- package/prompts/undo-last-edit-guidelines.md +2 -2
- package/prompts/undo-last-edit-snippet.md +1 -1
- package/prompts/undo-last-edit.md +1 -1
- package/prompts/zh/apply-patch-guidelines.md +4 -0
- package/prompts/zh/apply-patch.md +1 -0
- package/prompts/zh/read-guidelines.md +6 -0
- package/prompts/zh/read-snippet.md +1 -0
- package/prompts/zh/read.md +1 -0
- package/prompts/zh/undo-last-edit-guidelines.md +2 -0
- package/prompts/zh/undo-last-edit-snippet.md +1 -0
- package/prompts/zh/undo-last-edit.md +1 -0
- package/src/apply-patch/commit.ts +190 -0
- package/src/apply-patch/grammar.ts +620 -0
- package/src/apply-patch/index.ts +17 -0
- package/src/apply-patch/lifecycle.ts +195 -0
- package/src/apply-patch/plan.ts +800 -0
- package/src/apply-patch/render.ts +137 -0
- package/src/apply-patch/resolve.ts +470 -0
- package/src/apply-patch/tool.ts +257 -0
- package/src/apply-patch/types.ts +387 -0
- package/src/cut-repair.ts +77 -11
- package/src/domain-errors.ts +35 -3
- package/src/edit-undo.ts +379 -25
- package/src/file-content/index.ts +1 -1
- package/src/file-content/preview.ts +1 -1
- package/src/file-content/served-header.ts +1 -1
- package/src/fs-lifecycle.ts +201 -0
- package/src/hash-store.ts +18 -1
- package/src/hashline/alphabet.ts +7 -7
- package/src/hashline/hash-identity.ts +12 -7
- package/src/host-utils.ts +224 -0
- package/src/mutation-engine/edit-request.ts +39 -0
- package/src/mutation-engine/pipeline.ts +198 -27
- package/src/mutation-engine/types.ts +39 -57
- package/src/mutation-queue.ts +1 -1
- package/src/prompts.ts +3 -30
- package/src/served-session/serve-render.ts +2 -2
- package/src/undo-store.ts +74 -5
- package/lib/types/dsh/tools/edit.d.ts +0 -10
- package/lib/types/src/edit-tool.d.ts +0 -41
- package/lib/types/src/mutation-engine/engine.d.ts +0 -31
- package/lib/types/src/payload-contract.d.ts +0 -135
- package/prompts/edit-guidelines.md +0 -10
- package/prompts/edit-snippet.md +0 -1
- package/prompts/edit.md +0 -1
- package/prompts/read-snippet.md +0 -1
- package/src/bash-classifier.ts +0 -1626
- package/src/bash-conversion/decide.ts +0 -812
- package/src/bash-display-transform.ts +0 -50
- package/src/bash-multifile-config.ts +0 -239
- package/src/bash-view-config.ts +0 -158
- package/src/edit-normalize.ts +0 -8
- package/src/edit-render.ts +0 -161
- package/src/edit-tool.ts +0 -118
- package/src/edit.ts +0 -136
- package/src/integrations/pi-lens/command.ts +0 -712
- package/src/integrations/pi-lens/config.ts +0 -148
- package/src/integrations/pi-lens/io-bridge-adapter.ts +0 -234
- package/src/integrations/pi-lens/io-bridge.ts +0 -112
- package/src/integrations/pi-lens/settings-overlay.ts +0 -272
- package/src/lifecycle-hooks/index.ts +0 -1992
- package/src/lifecycle-hooks/types.ts +0 -64
- package/src/mutated-files.ts +0 -75
- package/src/mutation-engine/engine.ts +0 -239
- package/src/mutation-engine/index.ts +0 -17
- package/src/payload-contract.ts +0 -685
- package/src/preview-controller.ts +0 -84
- package/src/read.ts +0 -865
- package/src/search-hook.ts +0 -41
- package/src/store-config.ts +0 -73
- package/src/store-janitor-warning.ts +0 -169
- package/src/store-janitor.ts +0 -539
- package/src/store-kernel/settings.ts +0 -233
- package/src/store.ts +0 -154
- package/src/tui-presenter.ts +0 -134
- package/src/write-hook.ts +0 -130
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { splitLines } from "../utils.js";
|
|
2
|
+
import { lineHashes } from "../hashline/hash-identity.js";
|
|
3
|
+
import { snapshotIOFor } from "../snapshot-store";
|
|
4
|
+
import { loadHashStore, type HashStore } from "../hash-store.js";
|
|
5
|
+
import type { ProcessedEditFile, MemberLifecycle } from "../mutation-engine/types.js";
|
|
6
|
+
import type { FileBaseline, PatchPath, PlannedFile, PlannedMutation } from "./types.js";
|
|
7
|
+
import { applyPlannedMutations, mutationDelta } from "./plan.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* apply_patch lifecycle materialization — the plan-to-engine adapter.
|
|
11
|
+
*
|
|
12
|
+
* The planner resolves every mutation against a pre-call baseline; this module turns that plan
|
|
13
|
+
* into the mutation engine's `ProcessedEditFile` member shape (plus the engine-local lifecycle
|
|
14
|
+
* action). It never writes: the correlated transaction in `mutation-engine/pipeline.ts` owns the
|
|
15
|
+
* one commit path. Pure text application (splice at baseline coordinates) is the only work here,
|
|
16
|
+
* and the resulting anchors are always derived under the member's COMMITTED path.
|
|
17
|
+
*
|
|
18
|
+
* @module dsh-hashline-edit/apply-patch/lifecycle
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/** One materialized member: the plan facts plus the engine member the commit consumes. */
|
|
22
|
+
export interface MaterializedMember {
|
|
23
|
+
readonly planned: PlannedFile;
|
|
24
|
+
readonly member: ProcessedEditFile;
|
|
25
|
+
readonly status: "A" | "M" | "R" | "D";
|
|
26
|
+
/** The committed display path (destination for a move; the pre path otherwise). */
|
|
27
|
+
readonly committedPath: PatchPath;
|
|
28
|
+
/** The pre-transaction display path (move only). */
|
|
29
|
+
readonly fromPath?: PatchPath;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** The union of baseline anchors whose lines this file's mutations retire. */
|
|
33
|
+
function removedHashesOf(
|
|
34
|
+
baseline: FileBaseline,
|
|
35
|
+
mutations: readonly PlannedMutation[],
|
|
36
|
+
): Set<string> {
|
|
37
|
+
const removed = new Set<string>();
|
|
38
|
+
for (const mutation of mutations) {
|
|
39
|
+
if (mutation.range.startLine > mutation.range.endLine) continue;
|
|
40
|
+
for (let line = mutation.range.startLine; line <= mutation.range.endLine; line++) {
|
|
41
|
+
const hash = baseline.hashes[line - 1];
|
|
42
|
+
if (hash !== undefined) removed.add(hash);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return removed;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Sum the semantic line counts one materialized member reports (context lines excluded). */
|
|
49
|
+
function countMutationLines(
|
|
50
|
+
baselineLines: readonly string[],
|
|
51
|
+
mutations: readonly PlannedMutation[],
|
|
52
|
+
): {
|
|
53
|
+
added: number;
|
|
54
|
+
removed: number;
|
|
55
|
+
} {
|
|
56
|
+
let added = 0;
|
|
57
|
+
let removed = 0;
|
|
58
|
+
for (const mutation of mutations) {
|
|
59
|
+
const delta = mutationDelta(baselineLines, mutation);
|
|
60
|
+
added += delta.added;
|
|
61
|
+
removed += delta.removed;
|
|
62
|
+
}
|
|
63
|
+
return { added, removed };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** The engine lifecycle action for one planned file. */
|
|
67
|
+
function lifecycleOf(planned: PlannedFile): MemberLifecycle {
|
|
68
|
+
switch (planned.lifecycle.kind) {
|
|
69
|
+
case "keep":
|
|
70
|
+
return { kind: "keep" };
|
|
71
|
+
case "add":
|
|
72
|
+
return { kind: "add", createdDirs: [] };
|
|
73
|
+
case "delete":
|
|
74
|
+
return { kind: "delete" };
|
|
75
|
+
case "move":
|
|
76
|
+
return {
|
|
77
|
+
kind: "move",
|
|
78
|
+
fromAbsolutePath: planned.absolutePath,
|
|
79
|
+
toAbsolutePath: planned.lifecycle.toAbsolutePath,
|
|
80
|
+
createdDirs: [],
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** The absolute path a member commits to (a move commits at its destination). */
|
|
86
|
+
function committedAbsolutePath(planned: PlannedFile): string {
|
|
87
|
+
return planned.lifecycle.kind === "move"
|
|
88
|
+
? planned.lifecycle.toAbsolutePath
|
|
89
|
+
: planned.absolutePath;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** The display path a member commits to. */
|
|
93
|
+
function committedDisplayPath(planned: PlannedFile): PatchPath {
|
|
94
|
+
return planned.lifecycle.kind === "move" ? planned.lifecycle.to : planned.path;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Derive the member's result anchors under its COMMITTED path.
|
|
99
|
+
*
|
|
100
|
+
* Anchors are file-scoped (the path seeds the derivation), so a move must re-derive at the
|
|
101
|
+
* destination instead of carrying the source's anchors across. An in-place edit keeps the
|
|
102
|
+
* baseline's surviving anchors through the engine's prior-identity seam.
|
|
103
|
+
*/
|
|
104
|
+
async function resultHashesFor(
|
|
105
|
+
planned: PlannedFile,
|
|
106
|
+
result: string,
|
|
107
|
+
store?: HashStore,
|
|
108
|
+
): Promise<string[]> {
|
|
109
|
+
if (planned.lifecycle.kind === "delete") return [];
|
|
110
|
+
const resolvedStore = store ?? (await loadHashStore());
|
|
111
|
+
const path = committedAbsolutePath(planned);
|
|
112
|
+
const previous =
|
|
113
|
+
planned.lifecycle.kind === "keep"
|
|
114
|
+
? {
|
|
115
|
+
content: planned.baseline.text,
|
|
116
|
+
hashes: [...planned.baseline.hashes],
|
|
117
|
+
removedHashes: removedHashesOf(planned.baseline, planned.mutations),
|
|
118
|
+
}
|
|
119
|
+
: undefined;
|
|
120
|
+
return lineHashes(result, path, previous, snapshotIOFor(resolvedStore), false);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** The status letter one member reports in the success summary. */
|
|
124
|
+
function statusOf(planned: PlannedFile): "A" | "M" | "R" | "D" {
|
|
125
|
+
switch (planned.lifecycle.kind) {
|
|
126
|
+
case "add":
|
|
127
|
+
return "A";
|
|
128
|
+
case "delete":
|
|
129
|
+
return "D";
|
|
130
|
+
case "move":
|
|
131
|
+
return "R";
|
|
132
|
+
case "keep":
|
|
133
|
+
return "M";
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Materialize one planned file into the engine's member shape.
|
|
139
|
+
*
|
|
140
|
+
* The result text is produced by applying the plan's baseline-coordinate mutations; the anchors
|
|
141
|
+
* are then derived under the committed path. No file is read or written here — the plan already
|
|
142
|
+
* carries every baseline byte the commit needs.
|
|
143
|
+
*/
|
|
144
|
+
export async function materializeMember(
|
|
145
|
+
planned: PlannedFile,
|
|
146
|
+
store?: HashStore,
|
|
147
|
+
): Promise<MaterializedMember> {
|
|
148
|
+
const lifecycle = planned.lifecycle;
|
|
149
|
+
const isDelete = lifecycle.kind === "delete";
|
|
150
|
+
const isEmptyBaseline = planned.baseline.text === "" && planned.baseline.hashes.length === 0;
|
|
151
|
+
const baselineLines = isEmptyBaseline ? [] : splitLines(planned.baseline.text);
|
|
152
|
+
const resultLines = isDelete ? [] : applyPlannedMutations(baselineLines, planned.mutations);
|
|
153
|
+
const result = isDelete
|
|
154
|
+
? ""
|
|
155
|
+
: isEmptyBaseline
|
|
156
|
+
? resultLines.length === 0
|
|
157
|
+
? ""
|
|
158
|
+
: resultLines.join("\n") + "\n"
|
|
159
|
+
: resultLines.join("\n") + (planned.baseline.text.endsWith("\n") ? "\n" : "");
|
|
160
|
+
const resultHashes = isDelete ? [] : await resultHashesFor(planned, result, store);
|
|
161
|
+
const { added, removed } = isDelete
|
|
162
|
+
? { added: 0, removed: baselineLines.length }
|
|
163
|
+
: countMutationLines(baselineLines, planned.mutations);
|
|
164
|
+
const member: ProcessedEditFile = {
|
|
165
|
+
path: planned.path,
|
|
166
|
+
absolutePath: committedAbsolutePath(planned),
|
|
167
|
+
originalNormalized: lifecycle.kind === "add" ? "" : planned.baseline.text,
|
|
168
|
+
result,
|
|
169
|
+
bom: planned.baseline.bom,
|
|
170
|
+
originalEnding: planned.baseline.ending,
|
|
171
|
+
warnings: [],
|
|
172
|
+
originalHashes: [...planned.baseline.hashes],
|
|
173
|
+
resultHashes,
|
|
174
|
+
resultLineIds: [],
|
|
175
|
+
removedHashes: removedHashesOf(planned.baseline, planned.mutations),
|
|
176
|
+
appliedCount: 1,
|
|
177
|
+
noopCount: 0,
|
|
178
|
+
totalAddedLines: added,
|
|
179
|
+
totalRemovedLines: removed,
|
|
180
|
+
driftNotice: undefined,
|
|
181
|
+
range: { startLine: 1, endLine: 1, startHash: "", endHash: "", delta: 0 },
|
|
182
|
+
editedIntervals: [],
|
|
183
|
+
literalDeclarations: 0,
|
|
184
|
+
foreignCuts: [],
|
|
185
|
+
lifecycle: lifecycleOf(planned),
|
|
186
|
+
};
|
|
187
|
+
const fromPath = lifecycle.kind === "move" ? planned.path : undefined;
|
|
188
|
+
return {
|
|
189
|
+
planned,
|
|
190
|
+
member,
|
|
191
|
+
status: statusOf(planned),
|
|
192
|
+
committedPath: committedDisplayPath(planned),
|
|
193
|
+
...(fromPath !== undefined ? { fromPath } : {}),
|
|
194
|
+
};
|
|
195
|
+
}
|