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
@@ -1 +1 @@
1
- Undo the last edit on the file at `path`, reverting it to its previous state. Use when an edit produced incorrect results (e.g., wrong content, duplicated lines, broken syntax). The file must be unchanged since that edit.
1
+ Undo the last `apply_patch` batch that touched the file at `path`, reverting the whole batch — every text hunk plus file lifecycle actions (add/delete/move) — to its previous state. Use when an `apply_patch` produced incorrect results (e.g., wrong content, duplicated lines, broken syntax). The file must be unchanged since that batch.
@@ -0,0 +1,190 @@
1
+ /**
2
+ * apply_patch v4 — commit seam.
3
+ *
4
+ * Commits a `PatchPlan` as ONE correlated transaction through the existing hashline machinery:
5
+ *
6
+ * - pre-mirror every written member (durable pre-images),
7
+ * - one undo row per member carrying the shared transaction id,
8
+ * - the durable intent record,
9
+ * - deterministic member order (primary first), lifecycle actions included,
10
+ * - best-effort rollback of every member on failure,
11
+ * - the per-file store commit and the new-anchor served rows.
12
+ *
13
+ * This module is deliberately thin: it maps `PlannedFile` onto the engine's
14
+ * `ProcessedEditFile`/`commitTransaction` skeleton and never re-implements hashing, leasing,
15
+ * snapshots or undo storage.
16
+ *
17
+ * @module dsh-hashline-edit/apply-patch/commit
18
+ */
19
+ import { SERVED_ROWS_CAP } from "../constants.js";
20
+ import { DomainError } from "../domain-errors.js";
21
+ import { genDiff } from "../edit-diff.js";
22
+ import type { HashStore } from "../hash-store.js";
23
+ import { commitTransaction } from "../mutation-engine/pipeline.js";
24
+ import type { ProcessedEditFile, TransactionRecoveryReport } from "../mutation-engine/types.js";
25
+ import { fmtServedRows, paginationHint } from "../served-session/serve-render.js";
26
+ import { visLines } from "../utils.js";
27
+ import { materializeMember, type MaterializedMember } from "./lifecycle.js";
28
+ import type { ApplyPatchFailure, PatchProblem, PatchPlan, ServedFileBlock } from "./types.js";
29
+
30
+ /** Options for {@link commitPlan}. */
31
+ export interface CommitPlanOptions {
32
+ readonly cwd: string;
33
+ readonly sessionKey: string;
34
+ readonly signal?: AbortSignal;
35
+ readonly store?: HashStore;
36
+ /** POSIX access-mode bitmask; defaults to read+write. */
37
+ readonly accessMode?: number;
38
+ /** TEST-ONLY: fires before the first rename, while the pre-images/undo rows are durable. */
39
+ readonly onBeforeFirstWrite?: () => void | Promise<void>;
40
+ /** TEST-ONLY: fires between two member renames, after the earlier one is durable. */
41
+ readonly onBetweenWrites?: (committedAbsolutePath: string) => void | Promise<void>;
42
+ /** TEST-ONLY: fires after a move rename and before the destination rewrite (mid-member failure). */
43
+ readonly onAfterMoveRename?: (toAbsolutePath: string) => void | Promise<void>;
44
+ }
45
+
46
+ /** One committed file's lifecycle status and line accounting. */
47
+ export interface CommittedFile {
48
+ readonly path: string;
49
+ readonly status: "A" | "M" | "R" | "D";
50
+ /** Original path for a rename (`R` only). */
51
+ readonly fromPath?: string;
52
+ readonly addedLines: number;
53
+ readonly removedLines: number;
54
+ /** New anchors for the changed lines; absent when the member wrote no content. */
55
+ readonly served?: ServedFileBlock;
56
+ }
57
+
58
+ /** Commit outcome: the per-file facts on success, the whole failure on rejection. */
59
+ export type CommitPlanResult =
60
+ | {
61
+ readonly ok: true;
62
+ readonly files: readonly CommittedFile[];
63
+ readonly diff: string;
64
+ readonly warnings: readonly string[];
65
+ }
66
+ | { readonly ok: false; readonly failure: ApplyPatchFailure };
67
+
68
+ /** Build the served block one committed member owes the model: only its actually changed lines. */
69
+ function servedBlockFor(member: ProcessedEditFile, path: string): ServedFileBlock | undefined {
70
+ if (member.resultHashes.length === 0) return undefined;
71
+ // WHY: a success result returns anchors for the changed lines only (§7); the whole-file projection
72
+ // WHY: made a one-line edit dump every unchanged line back at the model.
73
+ const diff = genDiff(
74
+ member.originalNormalized,
75
+ member.result,
76
+ 0,
77
+ member.resultHashes,
78
+ member.originalHashes,
79
+ );
80
+ let rows = diff.servedRows;
81
+ if (rows.length === 0) return undefined;
82
+ let text: string;
83
+ if (rows.length > SERVED_ROWS_CAP) {
84
+ const next = rows[SERVED_ROWS_CAP]!;
85
+ text =
86
+ fmtServedRows(rows.slice(0, SERVED_ROWS_CAP), visLines(member.result)) +
87
+ "\n" +
88
+ paginationHint(next.position + 1, rows.length - SERVED_ROWS_CAP);
89
+ rows = rows.slice(0, SERVED_ROWS_CAP);
90
+ } else {
91
+ text = fmtServedRows(rows, visLines(member.result));
92
+ }
93
+ return { path, rows, text };
94
+ }
95
+
96
+ /** Map a commit-stage thrown value onto the apply-patch failure shape. */
97
+ function failureOf(
98
+ error: unknown,
99
+ plan: PatchPlan,
100
+ recovery: TransactionRecoveryReport | undefined,
101
+ ): ApplyPatchFailure {
102
+ const code = error instanceof DomainError ? error.code : "E_UNKNOWN";
103
+ const baseMessage = error instanceof Error ? error.message : String(error);
104
+ const patchLine = plan.files[0]?.mutations[0]?.patchLine ?? 1;
105
+ const recoveryText =
106
+ recovery === undefined
107
+ ? ""
108
+ : "\nRecovery: restored [" +
109
+ recovery.restored.join(", ") +
110
+ "], remaining [" +
111
+ recovery.remaining.join(", ") +
112
+ "], uncertain [" +
113
+ recovery.uncertain.join(", ") +
114
+ "].";
115
+ const problem: PatchProblem = { code, patchLine, message: baseMessage + recoveryText };
116
+ return {
117
+ ok: false,
118
+ code,
119
+ message: "apply_patch commit failed: " + baseMessage + recoveryText,
120
+ problems: [problem],
121
+ served: [],
122
+ changedNothing: recovery === undefined || recovery.remaining.length === 0,
123
+ ...(recovery !== undefined ? { recovery } : {}),
124
+ };
125
+ }
126
+
127
+ /**
128
+ * Commit one plan atomically (one correlated transaction, one undo record set).
129
+ *
130
+ * The implementation reuses `commitTransaction` — the existing correlated skeleton — and extends
131
+ * its member shape with the plan's lifecycle action; the undo schema gains the matching action.
132
+ *
133
+ * @param plan - the fully resolved plan.
134
+ * @param options - cwd/session/store, cancellation and the test fault seams.
135
+ * @returns the committed facts, or a failure whose `changedNothing` reflects the rollback.
136
+ */
137
+ export async function commitPlan(
138
+ plan: PatchPlan,
139
+ options: CommitPlanOptions,
140
+ ): Promise<CommitPlanResult> {
141
+ const entries: MaterializedMember[] = [];
142
+ for (const planned of plan.files) {
143
+ if (planned.writes) entries.push(await materializeMember(planned, options.store));
144
+ }
145
+ if (entries.length === 0) return { ok: true, files: [], diff: "", warnings: [] };
146
+ const members = entries.map((entry) => entry.member);
147
+ try {
148
+ const outcome = await commitTransaction(
149
+ members,
150
+ members,
151
+ {
152
+ sessionKey: options.sessionKey,
153
+ workspaceRoot: options.cwd,
154
+ ...(options.signal !== undefined ? { signal: options.signal } : {}),
155
+ ...(options.store !== undefined ? { store: options.store } : {}),
156
+ ...(options.accessMode !== undefined ? { accessMode: options.accessMode } : {}),
157
+ ...(options.onBeforeFirstWrite !== undefined
158
+ ? { onBeforeFirstCutWrite: options.onBeforeFirstWrite }
159
+ : {}),
160
+ ...(options.onBetweenWrites !== undefined
161
+ ? { onCutBetweenWrites: options.onBetweenWrites }
162
+ : {}),
163
+ ...(options.onAfterMoveRename !== undefined
164
+ ? { onAfterMoveRename: options.onAfterMoveRename }
165
+ : {}),
166
+ },
167
+ options.sessionKey,
168
+ );
169
+ const files: CommittedFile[] = entries.map((entry) => {
170
+ const served = servedBlockFor(entry.member, entry.committedPath);
171
+ return {
172
+ path: entry.committedPath,
173
+ status: entry.status,
174
+ ...(entry.fromPath !== undefined ? { fromPath: entry.fromPath } : {}),
175
+ addedLines: entry.member.totalAddedLines,
176
+ removedLines: entry.member.totalRemovedLines,
177
+ ...(served !== undefined ? { served } : {}),
178
+ };
179
+ });
180
+ return {
181
+ ok: true,
182
+ files,
183
+ diff: outcome.toolResult.details.diff ?? "",
184
+ warnings: outcome.toolResult.details.warnings ?? [],
185
+ };
186
+ } catch (error) {
187
+ const recovery = (error as Error & { recovery?: TransactionRecoveryReport }).recovery;
188
+ return { ok: false, failure: failureOf(error, plan, recovery) };
189
+ }
190
+ }