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