dsh-hashline-edit 0.1.1 → 0.2.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.
Files changed (130) hide show
  1. package/README.md +70 -69
  2. package/cordis.patch.yml +1 -1
  3. package/lib/index.js +4143 -4518
  4. package/lib/types/dsh/contracts.d.ts +69 -6
  5. package/lib/types/dsh/fs.d.ts +38 -3
  6. package/lib/types/dsh/guidance.d.ts +5 -5
  7. package/lib/types/dsh/hide.d.ts +78 -0
  8. package/lib/types/dsh/host-compat.d.ts +7 -78
  9. package/lib/types/dsh/index.d.ts +17 -7
  10. package/lib/types/dsh/metrics/events.d.ts +8 -1
  11. package/lib/types/dsh/metrics/instrument.d.ts +20 -14
  12. package/lib/types/dsh/metrics/observer.d.ts +28 -0
  13. package/lib/types/dsh/sandbox.d.ts +2 -2
  14. package/lib/types/dsh/shell-hook.d.ts +17 -8
  15. package/lib/types/dsh/shell-view.d.ts +52 -0
  16. package/lib/types/dsh/tools/apply-patch.d.ts +38 -0
  17. package/lib/types/dsh/tools/context.d.ts +19 -1
  18. package/lib/types/dsh/tools/output.d.ts +32 -4
  19. package/lib/types/dsh/tools/read.d.ts +12 -15
  20. package/lib/types/dsh/tools/undo.d.ts +5 -0
  21. package/lib/types/dsh/write-hook.d.ts +8 -22
  22. package/lib/types/src/apply-patch/commit.d.ts +49 -0
  23. package/lib/types/src/apply-patch/grammar.d.ts +29 -0
  24. package/lib/types/src/apply-patch/lifecycle.d.ts +32 -0
  25. package/lib/types/src/apply-patch/plan.d.ts +50 -0
  26. package/lib/types/src/apply-patch/render.d.ts +51 -0
  27. package/lib/types/src/apply-patch/resolve.d.ts +129 -0
  28. package/lib/types/src/apply-patch/tool.d.ts +54 -0
  29. package/lib/types/src/apply-patch/types.d.ts +362 -0
  30. package/lib/types/src/domain-errors.d.ts +16 -2
  31. package/lib/types/src/edit-undo.d.ts +11 -2
  32. package/lib/types/src/file-content/detection.d.ts +17 -0
  33. package/lib/types/src/file-content/index.d.ts +2 -2
  34. package/lib/types/src/file-content/preview.d.ts +1 -1
  35. package/lib/types/src/fs-lifecycle.d.ts +44 -0
  36. package/lib/types/src/hashline/resolve.d.ts +6 -0
  37. package/lib/types/src/host-utils.d.ts +63 -0
  38. package/lib/types/src/mutation-engine/batch-span-gate.d.ts +6 -0
  39. package/lib/types/src/mutation-engine/edit-request.d.ts +34 -0
  40. package/lib/types/src/mutation-engine/pipeline.d.ts +18 -3
  41. package/lib/types/src/mutation-engine/types.d.ts +50 -58
  42. package/lib/types/src/read-expansion/grammar-manifest.d.ts +4 -2
  43. package/lib/types/src/read-expansion/java-decoration.d.ts +21 -0
  44. package/lib/types/src/read-expansion/span-expansion.d.ts +6 -2
  45. package/lib/types/src/read-expansion/span-kind.d.ts +3 -2
  46. package/lib/types/src/read-expansion/vue-decoration.d.ts +14 -0
  47. package/lib/types/src/served-session/serve-render.d.ts +9 -3
  48. package/lib/types/src/undo-store.d.ts +17 -1
  49. package/package.json +10 -22
  50. package/prompts/apply-patch-guidelines.md +10 -0
  51. package/prompts/apply-patch.md +1 -0
  52. package/prompts/read-guidelines.md +5 -5
  53. package/prompts/read.md +1 -1
  54. package/prompts/undo-last-edit-guidelines.md +2 -2
  55. package/prompts/undo-last-edit-snippet.md +1 -1
  56. package/prompts/undo-last-edit.md +1 -1
  57. package/src/apply-patch/commit.ts +190 -0
  58. package/src/apply-patch/grammar.ts +620 -0
  59. package/src/apply-patch/index.ts +17 -0
  60. package/src/apply-patch/lifecycle.ts +195 -0
  61. package/src/apply-patch/plan.ts +800 -0
  62. package/src/apply-patch/render.ts +137 -0
  63. package/src/apply-patch/resolve.ts +470 -0
  64. package/src/apply-patch/tool.ts +257 -0
  65. package/src/apply-patch/types.ts +387 -0
  66. package/src/cut-repair.ts +77 -11
  67. package/src/domain-errors.ts +58 -10
  68. package/src/edit-undo.ts +379 -25
  69. package/src/file-content/detection.ts +34 -0
  70. package/src/file-content/index.ts +2 -2
  71. package/src/file-content/preview.ts +1 -1
  72. package/src/file-content/served-header.ts +1 -1
  73. package/src/fs-lifecycle.ts +201 -0
  74. package/src/hash-store.ts +18 -1
  75. package/src/hashline/lease-resolve.ts +14 -8
  76. package/src/hashline/resolve.ts +30 -27
  77. package/src/host-utils.ts +224 -0
  78. package/src/mutation-engine/batch-span-gate.ts +17 -4
  79. package/src/mutation-engine/edit-request.ts +39 -0
  80. package/src/mutation-engine/pipeline.ts +535 -63
  81. package/src/mutation-engine/types.ts +49 -65
  82. package/src/mutation-queue.ts +1 -1
  83. package/src/prompts.ts +0 -28
  84. package/src/read-expansion/ast-provider.ts +4 -0
  85. package/src/read-expansion/grammar-manifest.ts +21 -2
  86. package/src/read-expansion/java-decoration.ts +34 -0
  87. package/src/read-expansion/span-expansion.ts +6 -2
  88. package/src/read-expansion/span-kind.ts +3 -1
  89. package/src/read-expansion/vue-decoration.ts +43 -0
  90. package/src/served-session/serve-render.ts +5 -5
  91. package/src/undo-store.ts +74 -5
  92. package/lib/types/dsh/encoding-bridge.d.ts +0 -25
  93. package/lib/types/dsh/encoding.d.ts +0 -144
  94. package/lib/types/dsh/tools/edit.d.ts +0 -10
  95. package/lib/types/src/edit-tool.d.ts +0 -41
  96. package/lib/types/src/mutation-engine/engine.d.ts +0 -31
  97. package/lib/types/src/payload-contract.d.ts +0 -124
  98. package/prompts/edit-guidelines.md +0 -10
  99. package/prompts/edit-snippet.md +0 -1
  100. package/prompts/edit.md +0 -1
  101. package/src/bash-classifier.ts +0 -1626
  102. package/src/bash-conversion/decide.ts +0 -812
  103. package/src/bash-display-transform.ts +0 -50
  104. package/src/bash-multifile-config.ts +0 -239
  105. package/src/bash-view-config.ts +0 -158
  106. package/src/edit-normalize.ts +0 -8
  107. package/src/edit-render.ts +0 -161
  108. package/src/edit-tool.ts +0 -116
  109. package/src/edit.ts +0 -136
  110. package/src/integrations/pi-lens/command.ts +0 -712
  111. package/src/integrations/pi-lens/config.ts +0 -148
  112. package/src/integrations/pi-lens/io-bridge-adapter.ts +0 -234
  113. package/src/integrations/pi-lens/io-bridge.ts +0 -112
  114. package/src/integrations/pi-lens/settings-overlay.ts +0 -272
  115. package/src/lifecycle-hooks/index.ts +0 -1992
  116. package/src/lifecycle-hooks/types.ts +0 -64
  117. package/src/mutated-files.ts +0 -75
  118. package/src/mutation-engine/engine.ts +0 -173
  119. package/src/mutation-engine/index.ts +0 -17
  120. package/src/payload-contract.ts +0 -637
  121. package/src/preview-controller.ts +0 -84
  122. package/src/read.ts +0 -865
  123. package/src/search-hook.ts +0 -41
  124. package/src/store-config.ts +0 -73
  125. package/src/store-janitor-warning.ts +0 -169
  126. package/src/store-janitor.ts +0 -539
  127. package/src/store-kernel/settings.ts +0 -233
  128. package/src/store.ts +0 -154
  129. package/src/tui-presenter.ts +0 -134
  130. 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
+ }