dsh-hashline-edit 0.2.0 → 0.2.2
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 +59 -55
- package/cordis.patch.yml +1 -1
- package/lib/index.js +7225 -6445
- package/lib/types/dsh/contracts.d.ts +3 -12
- package/lib/types/dsh/fs.d.ts +0 -3
- package/lib/types/dsh/guidance.d.ts +5 -5
- package/lib/types/dsh/host-compat.d.ts +78 -7
- package/lib/types/dsh/index.d.ts +7 -17
- 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/edit.d.ts +10 -0
- package/lib/types/dsh/tools/read.d.ts +3 -3
- package/lib/types/src/domain-errors.d.ts +2 -16
- package/lib/types/src/edit-tool.d.ts +41 -0
- package/lib/types/src/edit-undo.d.ts +2 -11
- 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/hash-store.d.ts +2 -2
- package/lib/types/src/hashline/alphabet.d.ts +16 -1
- package/lib/types/src/hashline/hash-identity.d.ts +10 -4
- package/lib/types/src/mutation-engine/engine.d.ts +31 -0
- package/lib/types/src/mutation-engine/pipeline.d.ts +1 -8
- package/lib/types/src/mutation-engine/types.d.ts +50 -40
- package/lib/types/src/payload-contract.d.ts +135 -0
- package/lib/types/src/served-session/serve-render.d.ts +0 -6
- package/lib/types/src/undo-store.d.ts +1 -17
- package/package.json +21 -10
- package/prompts/edit-guidelines.md +10 -0
- package/prompts/edit-snippet.md +1 -0
- package/prompts/edit.md +1 -0
- package/prompts/read-guidelines.md +4 -4
- 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/src/bash-classifier.ts +1626 -0
- package/src/bash-conversion/decide.ts +812 -0
- package/src/bash-display-transform.ts +50 -0
- package/src/bash-multifile-config.ts +239 -0
- package/src/bash-view-config.ts +158 -0
- package/src/cut-repair.ts +11 -77
- package/src/domain-errors.ts +3 -35
- package/src/edit-normalize.ts +8 -0
- package/src/edit-render.ts +161 -0
- package/src/edit-tool.ts +118 -0
- package/src/edit-undo.ts +25 -379
- package/src/edit.ts +136 -0
- 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/hash-store.ts +1 -18
- package/src/hashline/alphabet.ts +42 -1
- package/src/hashline/hash-identity.ts +12 -3
- package/src/integrations/pi-lens/command.ts +712 -0
- package/src/integrations/pi-lens/config.ts +148 -0
- package/src/integrations/pi-lens/io-bridge-adapter.ts +234 -0
- package/src/integrations/pi-lens/io-bridge.ts +112 -0
- package/src/integrations/pi-lens/settings-overlay.ts +272 -0
- package/src/lifecycle-hooks/index.ts +1992 -0
- package/src/lifecycle-hooks/types.ts +64 -0
- package/src/mutated-files.ts +75 -0
- package/src/mutation-engine/engine.ts +239 -0
- package/src/mutation-engine/index.ts +17 -0
- package/src/mutation-engine/pipeline.ts +27 -198
- package/src/mutation-engine/types.ts +57 -39
- package/src/mutation-queue.ts +1 -1
- package/src/payload-contract.ts +685 -0
- package/src/preview-controller.ts +84 -0
- package/src/prompts.ts +43 -10
- package/src/read.ts +865 -0
- package/src/search-hook.ts +41 -0
- package/src/served-session/serve-render.ts +2 -2
- package/src/store-config.ts +73 -0
- package/src/store-janitor-warning.ts +169 -0
- package/src/store-janitor.ts +539 -0
- package/src/store-kernel/settings.ts +233 -0
- package/src/store.ts +154 -0
- package/src/tui-presenter.ts +134 -0
- package/src/undo-store.ts +5 -74
- package/src/write-hook.ts +130 -0
- package/lib/types/dsh/hide.d.ts +0 -78
- package/lib/types/dsh/tools/apply-patch.d.ts +0 -38
- package/lib/types/src/apply-patch/commit.d.ts +0 -49
- package/lib/types/src/apply-patch/grammar.d.ts +0 -29
- package/lib/types/src/apply-patch/lifecycle.d.ts +0 -32
- package/lib/types/src/apply-patch/plan.d.ts +0 -50
- package/lib/types/src/apply-patch/render.d.ts +0 -51
- package/lib/types/src/apply-patch/resolve.d.ts +0 -129
- package/lib/types/src/apply-patch/tool.d.ts +0 -54
- package/lib/types/src/apply-patch/types.d.ts +0 -362
- package/lib/types/src/fs-lifecycle.d.ts +0 -44
- package/lib/types/src/host-utils.d.ts +0 -63
- package/lib/types/src/mutation-engine/edit-request.d.ts +0 -34
- package/prompts/apply-patch-guidelines.md +0 -10
- package/prompts/apply-patch.md +0 -1
- package/src/apply-patch/commit.ts +0 -190
- package/src/apply-patch/grammar.ts +0 -620
- package/src/apply-patch/index.ts +0 -17
- package/src/apply-patch/lifecycle.ts +0 -195
- package/src/apply-patch/plan.ts +0 -800
- package/src/apply-patch/render.ts +0 -137
- package/src/apply-patch/resolve.ts +0 -470
- package/src/apply-patch/tool.ts +0 -257
- package/src/apply-patch/types.ts +0 -387
- package/src/fs-lifecycle.ts +0 -201
- package/src/host-utils.ts +0 -224
- package/src/mutation-engine/edit-request.ts +0 -39
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Hash-anchored file editing for [DeepSeek Harness](https://github.com/deepseek-ai) (dsh) on Windows.
|
|
4
4
|
|
|
5
|
-
`dsh-hashline-edit` is a dsh bundle that shadows the host's built-in `read`
|
|
5
|
+
`dsh-hashline-edit` is a dsh bundle that shadows the host's built-in `read` and `edit` tools with hashline equivalents and adds `undo_last_edit`. Every line a served read shows carries a stable 3- or 4-character base62 anchor (`A–Z`, `a–z`, `0–9`) derived from the file's canonical path and the line's content (the width is a runtime setting; see [Anchor width](#anchor-width)). An edit names two anchors and new text; it never re-types existing code. Anchors for unchanged lines stay stable across edits, and every successful edit returns fresh anchors for the changed lines, so chained edits need no re-read.
|
|
6
6
|
|
|
7
|
-
The semantic core is the [pi-better-edit](https://github.com/Rianico/pi-better-edit) v2.16.0 hashline engine (MIT)
|
|
7
|
+
The semantic core is the [pi-better-edit](https://github.com/Rianico/pi-better-edit) v2.16.0 hashline engine (MIT). The `dsh/` tree is this repository's DeepSeek Harness host layer: tool registration, filesystem bridge, UTF-8-only admission, prompt guidance, shell integration, write integration and telemetry. See [`dsh/README.md`](dsh/README.md) for the host-layer map.
|
|
8
8
|
|
|
9
9
|
## Requirements
|
|
10
10
|
|
|
@@ -13,7 +13,23 @@ The semantic core is the [pi-better-edit](https://github.com/Rianico/pi-better-e
|
|
|
13
13
|
| OS | Windows — this branch targets Windows only (see [`dsh/UPSTREAM.md`](dsh/UPSTREAM.md)) |
|
|
14
14
|
| Node.js | ≥ 24.0.0 |
|
|
15
15
|
| pnpm | 12.x |
|
|
16
|
-
| DeepSeek Harness | plugin-capable build; the repository is developed against `@deepseek-ai/dsh-*@0.2.
|
|
16
|
+
| DeepSeek Harness | plugin-capable build; the repository is developed against `@deepseek-ai/dsh-*@0.2.1-rc.2` |
|
|
17
|
+
|
|
18
|
+
### Anchor width (3 or 4)
|
|
19
|
+
|
|
20
|
+
The anchor width is baked into the build. Set `PI_BETTER_EDIT_ANCHOR_WIDTH` when you build or pack:
|
|
21
|
+
|
|
22
|
+
- `PI_BETTER_EDIT_ANCHOR_WIDTH=3 pnpm run build` (or `pnpm pack` / install) produces a fully 3-char artifact.
|
|
23
|
+
- unset or `4` builds the 4-char default.
|
|
24
|
+
|
|
25
|
+
| Value | Anchor width | Usable space | Anchor generation |
|
|
26
|
+
| --- | --- | --- | --- |
|
|
27
|
+
| unset or `4` (default) | 4 chars | 14,766,336 | 1 |
|
|
28
|
+
| `3` | 3 chars | 237,328 | 2 |
|
|
29
|
+
|
|
30
|
+
The value is inlined into the bundle at build time (`esbuild define`), so the installed plugin never reads an environment variable at runtime — a 3-char build stays 3-char. The persisted store is keyed by the anchor generation, so changing the build width is a hard cache miss (served rows are simply re-read), never a cross-width hit. Width 4 keeps generation 1, so existing stores keep working unchanged.
|
|
31
|
+
|
|
32
|
+
Measured on the DeepSeek-V4.1 tokenizer, a 3-char anchor averages ~2.3 tokens and a 4-char anchor ~3.0 tokens per served line, and neither collapses to one token (see [ADR-0020](docs/adr/0020-configurable-anchor-width-3-4.md)). The default stays 4 to preserve the existing persisted contract; build with `PI_BETTER_EDIT_ANCHOR_WIDTH=3` to ship 3-char.
|
|
17
33
|
|
|
18
34
|
## Install
|
|
19
35
|
|
|
@@ -36,7 +52,7 @@ For a tarball, pack first and add the archive:
|
|
|
36
52
|
|
|
37
53
|
```sh
|
|
38
54
|
pnpm pack
|
|
39
|
-
dsh plugin add ./dsh-hashline-edit-0.
|
|
55
|
+
dsh plugin add ./dsh-hashline-edit-0.1.0.tgz
|
|
40
56
|
```
|
|
41
57
|
|
|
42
58
|
The bundle ships `lib/index.js` plus `lib/types/**`; `prompts/` must sit next to `lib/` in the installed package (it is in `files`). Guidance override files are materialized under `<DSH_HOME>/plugins/dsh-hashline-edit/guidance/` and are shared between profiles.
|
|
@@ -55,7 +71,7 @@ p9rX│ return total;
|
|
|
55
71
|
a1bX│}
|
|
56
72
|
```
|
|
57
73
|
|
|
58
|
-
Copy only the 4 characters before `│` into `anchor_from` / `anchor_to`. An
|
|
74
|
+
Copy only the 4 characters before `│` into `anchor_from` / `anchor_to`. An edit targets an inclusive range and returns a diff whose modified and context rows carry fresh anchors:
|
|
59
75
|
|
|
60
76
|
```text
|
|
61
77
|
- szJx│ let total = 0;
|
|
@@ -84,58 +100,48 @@ read({
|
|
|
84
100
|
})
|
|
85
101
|
```
|
|
86
102
|
|
|
87
|
-
- **Served mode** returns one `HASH│content` row per line and records every shown row as a lease for this session. A windowed read also includes a `[Lines A-B of N total]` page header. Every row shown is usable by one subsequent
|
|
88
|
-
- **Verbatim mode** returns the same page as plain text with no anchors and serves nothing; an
|
|
103
|
+
- **Served mode** returns one `HASH│content` row per line and records every shown row as a lease for this session. A windowed read also includes a `[Lines A-B of N total]` page header. Every row shown is usable by one subsequent edit, even when the windows are far apart.
|
|
104
|
+
- **Verbatim mode** returns the same page as plain text with no anchors and serves nothing; an edit cannot target those lines.
|
|
89
105
|
- A small requested window — up to 61 lines after folding — may widen to its enclosing function, method, class, section or paragraph; a `[widened …]` note names the block that was served. Expansion applies in both modes. Languages: TypeScript/TSX, Python, Go, Rust, Java and Vue through pinned tree-sitter wasm grammars (fetched lazily and verified against a committed SHA-256), plus Bash through the existing `unbash` parser (no wasm). Vue widens a top-level `template`/`script`/`style` block without parsing embedded JS/TS. SQL is not supported: real migrations largely fail to parse and `.tql` is a Java template, not SQL (see [`docs/spec/sql-vue-feasibility-gate.md`](docs/spec/sql-vue-feasibility-gate.md)).
|
|
90
|
-
- `offset`/`limit` and `windows` are page requests, not anchors: only `served` output grants
|
|
106
|
+
- `offset`/`limit` and `windows` are page requests, not anchors: only `served` output grants edit leases.
|
|
91
107
|
|
|
92
|
-
### `
|
|
108
|
+
### `edit`
|
|
93
109
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
110
|
+
```ts
|
|
111
|
+
edit({
|
|
112
|
+
file: string, // default target for items that omit `file`
|
|
113
|
+
edits: [{
|
|
114
|
+
file?: string, // optional per-item target; falls back to the call's `file`
|
|
115
|
+
anchor_from: string, // bare 4-char anchor of the first range line (inclusive)
|
|
116
|
+
anchor_to: string, // bare 4-char anchor of the last range line (inclusive)
|
|
117
|
+
text?: string, // by-value content; "" deletes an in-place range
|
|
118
|
+
text_ref?: { // by-reference content from a served span
|
|
119
|
+
anchor_from: string,
|
|
120
|
+
anchor_to: string,
|
|
121
|
+
file?: string, // another served file (foreign-source copy/cut)
|
|
122
|
+
mode: "copy" | "cut", // required: copy keeps the source, cut retires the span
|
|
123
|
+
},
|
|
124
|
+
at?: "in-place" | "before" | "after", // default "in-place"
|
|
125
|
+
}],
|
|
126
|
+
mode?: "general" | "literal", // "general" refuses served-row echoes; "literal" declares them intended
|
|
127
|
+
})
|
|
107
128
|
```
|
|
108
129
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
` ` (context), `-` (remove) and `+` (add). Matching is byte-exact and must be unique: zero or
|
|
114
|
-
multiple matches reject the whole call and serve the candidate rows back.
|
|
115
|
-
- **Identity hunks** use the `@@<a>` / `@@<a>-<b>` extension: two inclusive 4-char anchors from rows
|
|
116
|
-
this session served. The body is `+` lines only; an empty body deletes the span. A stale, unknown
|
|
117
|
-
or foreign anchor is rejected with the file's current rows served.
|
|
118
|
-
- **Reference hunks** `*** Copy From: <path> <a>-<b>` / `*** Cut From: <path> <a>-<b>` take the
|
|
119
|
-
bytes of another served span; a cut also retires the source span in the same transaction.
|
|
120
|
-
- **Lifecycle** `*** Add File:`, `*** Delete File:` and `*** Move to:` join text edits in the same
|
|
121
|
-
transaction and the same undo record. `*** End of File` pins a hunk to the file tail.
|
|
122
|
-
|
|
123
|
-
`@@` followed by a space is Codex's context mode; `@@` immediately followed by four anchor
|
|
124
|
-
characters is identity mode. Any rejection leaves every file byte-identical and reports every
|
|
125
|
-
independent problem with its patch line number and `[E_*`] code. Success returns a file-level summary
|
|
126
|
-
(A/M/R/D) followed by fresh `HASH│content` anchors for every changed line, so the next call can chain
|
|
127
|
-
without a `read`. The host's built-in `write` remains for whole-file rewrites.
|
|
130
|
+
Each item carries exactly one of `text` or `text_ref`; supplying both or neither is refused. An item without `file` targets the call's top-level file; an item that names one may target another served file, so one call may edit several files. The whole call commits as one correlated transaction (pre-mirror, undo rows, ordered renames, all-or-nothing rollback, then per-file store commits) and a refusal leaves every file untouched. `before`/`after` insert at the range boundary and require a single-line resolved target. A foreign-source `cut` writes both files as one correlated transaction; `undo_last_edit` reverts both members. An edit never silently rewrites submitted text — a refused edit writes nothing.
|
|
131
|
+
|
|
132
|
+
The result is the core's unified diff with fresh anchors for the changed lines, so the next edit can chain from them without a `read`. The host's built-in `write` is not replaced: the plugin guards it against served-row echoes and appends an anchored auto-read so following edits can use its output.
|
|
133
|
+
|
|
128
134
|
### `undo_last_edit`
|
|
129
135
|
|
|
130
136
|
```ts
|
|
131
137
|
undo_last_edit({ path: string })
|
|
132
138
|
```
|
|
133
139
|
|
|
134
|
-
Restores the previous file content, BOM, line endings and original anchors from a snapshot-pinned undo record. The record survives agent restarts. A file changed externally after the
|
|
140
|
+
Restores the previous file content, BOM, line endings and original anchors from a snapshot-pinned undo record. The record survives agent restarts. A file changed externally after the edit is refused with `[E_UNDO_STALE]`. A correlated cut's undo restores every member of the transaction, not only the named path.
|
|
135
141
|
|
|
136
142
|
## Shell view
|
|
137
143
|
|
|
138
|
-
The plugin installs a `tools/post-execute` listener for the host's `pwsh`, `bash` and built-in `grep` tools. When the command is a whitelisted read-only file view, the captured stdout is replaced with the aligned file's `HASH│content` rows, and those rows are served (leased) exactly like a read — a following `
|
|
144
|
+
The plugin installs a `tools/post-execute` listener for the host's `pwsh`, `bash` and built-in `grep` tools. When the command is a whitelisted read-only file view, the captured stdout is replaced with the aligned file's `HASH│content` rows, and those rows are served (leased) exactly like a read — a following `edit` can use them with no re-read. A built-in grep result whose matches are proven against disk is served the same way (see the table below).
|
|
139
145
|
|
|
140
146
|
| Command shape | Served as |
|
|
141
147
|
| --- | --- |
|
|
@@ -161,7 +167,7 @@ A file that is not valid UTF-8 is refused with `[E_UNSUPPORTED_FILE]` naming the
|
|
|
161
167
|
The built-in `write` integration and `undo_last_edit` speak the same contract: they write UTF-8, and every file this plugin serves is UTF-8.
|
|
162
168
|
## Sandbox behavior
|
|
163
169
|
|
|
164
|
-
`
|
|
170
|
+
`edit` and `undo_last_edit` carry the host's optional escalation fields `sandbox_permissions` and `justification` only when a confining filesystem backend is mounted. `dsh/sandbox.ts` mirrors the built-in `@deepseek-ai/dsh-tool-fs` controller: it validates the field pairing, repeats the standing mode without approval, and resolves a strictly wider mode through the host's approval channel before touching the filesystem. A provider `FS_SANDBOX_DENIED` error is mapped to the standard model-facing denial marker plus escalation hint; other errors pass through unchanged.
|
|
165
171
|
|
|
166
172
|
### Host-side `0xC0000142` workspace-write finding
|
|
167
173
|
|
|
@@ -182,7 +188,7 @@ The M3/M4 smoke runs therefore used `DSH_PERMISSION_MODE=danger-full-access`; th
|
|
|
182
188
|
| `pnpm run lint` | `oxlint .` + `knip --max-issues 0` |
|
|
183
189
|
| `pnpm run verify` | lint + format + typecheck + Windows coverage |
|
|
184
190
|
|
|
185
|
-
The build enforces its own packaging contract: host packages stay external, the
|
|
191
|
+
The build enforces its own packaging contract: host packages stay external, the pi utility package is aliased to `dsh/host-compat.ts` (the bundle must not reference pi), and no bare import outside the allowlist can slip in. See [`dsh/README.md`](dsh/README.md#build-and-packaging).
|
|
186
192
|
|
|
187
193
|
## Error and warning codes
|
|
188
194
|
|
|
@@ -193,7 +199,7 @@ Every refusal carries a bracketed code; `src/domain-errors.ts` is the source of
|
|
|
193
199
|
| `[E_ACCESS]` | The filesystem denied access to the target path. |
|
|
194
200
|
| `[E_BAD_PAYLOAD]` | Malformed or unknown tool payload; nothing is written. |
|
|
195
201
|
| `[E_BATCH_ABORT]` | A batch item failed; the whole batch was not applied. |
|
|
196
|
-
| `[E_EMPTY_RANGE]` | The
|
|
202
|
+
| `[E_EMPTY_RANGE]` | The edit would empty a non-empty file; use `write`. |
|
|
197
203
|
| `[E_FOREIGN_ANCHOR]` | The anchor belongs to a different file. |
|
|
198
204
|
| `[E_INTERNAL_INVARIANT]` | An internal invariant was violated. |
|
|
199
205
|
| `[E_LARGE_FILE]` | The file exceeds the served line or byte budget. |
|
|
@@ -201,23 +207,21 @@ Every refusal carries a bracketed code; `src/domain-errors.ts` is the source of
|
|
|
201
207
|
| `[E_MALFORMED_ANCHOR]` | The anchor token cannot be parsed. |
|
|
202
208
|
| `[E_NOOP_LOOP]` | Repeated identical no-op edits; refused with the current range served. |
|
|
203
209
|
| `[E_NOT_FOUND]` | The target file does not exist or is unreachable. |
|
|
204
|
-
| `[E_PATCH_SYNTAX]` | The apply_patch text is not valid syntax; nothing is written. |
|
|
205
210
|
| `[E_STALE_ANCHOR]` | A boundary anchor no longer resolves against the file. |
|
|
206
|
-
| `[E_STALE_RANGE]` | The served range changed between serve and
|
|
211
|
+
| `[E_STALE_RANGE]` | The served range changed between serve and edit. |
|
|
207
212
|
| `[E_SUSPICIOUS_TEXT]` | The replacement reproduces served anchor text (a copied `HASH│` echo). |
|
|
208
213
|
| `[E_TARGET_LOST]` | The target line identity can no longer be resolved. |
|
|
209
214
|
| `[E_UNDO_REVERT_FAILED]` | A correlated revert failed mid-way; a repair run finishes it. |
|
|
210
215
|
| `[E_UNDO_STALE]` | The undo record is stale relative to the file. |
|
|
211
216
|
| `[E_UNDO_UNAVAILABLE]` | There is no undo history for the path. |
|
|
212
|
-
| `[E_UNIQUE_MATCH]` | A fragment hunk matched zero or multiple places; candidates are served back. |
|
|
213
217
|
| `[E_UNKNOWN]` | An unclassified failure; the message carries the cause. |
|
|
214
218
|
| `[E_UNKNOWN_ANCHOR]` | The anchor was never served in this session. |
|
|
215
219
|
| `[E_UNSUPPORTED_FILE]` | Binary, image or directory targets are not editable text; a non-UTF-8 file is refused with its path and an instruction to ask the user how to handle it. |
|
|
216
220
|
| `[E_UNVERIFIED_RANGE]` | The range interior cannot be verified (never served). |
|
|
217
|
-
| `[W_LITERAL_BYPASS]` | Literal `HASH│` bytes were written through `
|
|
218
|
-
| `[W_NEVER_SERVED_SHAPE]` | A never-served hint was attached to an accepted
|
|
219
|
-
| `[W_NOOP]` | The
|
|
220
|
-
| `[W_NOOP_INSERT]` | An insert-shaped
|
|
221
|
+
| `[W_LITERAL_BYPASS]` | Literal `HASH│` bytes were written through `edit` and accepted with a warning. |
|
|
222
|
+
| `[W_NEVER_SERVED_SHAPE]` | A never-served hint was attached to an accepted edit. |
|
|
223
|
+
| `[W_NOOP]` | The edit produced no content change and was accepted as a no-op. |
|
|
224
|
+
| `[W_NOOP_INSERT]` | An insert-shaped edit produced no change. |
|
|
221
225
|
| `[W_REVERSED_ANCHORS]` | Boundaries were reversed and healed. |
|
|
222
226
|
| `[W_SERVED_PREFIX_MISMATCH]` | A served prefix does not match; fresh rows were served. |
|
|
223
227
|
| `[W_UNICODE_LITERAL]` | A Unicode literal in the payload looks like a copied anchor. |
|
|
@@ -226,7 +230,7 @@ Range-family rejections render their current-row evidence exactly once: the head
|
|
|
226
230
|
|
|
227
231
|
## Current limitations
|
|
228
232
|
|
|
229
|
-
- **Mutation stays on the local `node:fs` seam.** The read path consumes a `CoreReadIo` port (local or mounted `ctx.fs`), but `writeAtomic`, the
|
|
233
|
+
- **Mutation stays on the local `node:fs` seam.** The read path consumes a `CoreReadIo` port (local or mounted `ctx.fs`), but `writeAtomic`, the edit engine and undo remain local-only. `edit` and `undo_last_edit` fail closed with `E_NOT_FOUND` when the target is reachable only through `ctx.fs`. A full mutation bridge needs target-keyed store state: the host's `ctx.fs` already exposes versioned `writeText`/`editText` in `0.2.1-rc.2`, but the snapshot/lease store still keys on absolute paths and local stat identity (M6, see [`dsh/README.md`](dsh/README.md#ctxfs-deferral-m6)).
|
|
230
234
|
- **UTF-8 only.** Non-UTF-8 files are refused on read and must be converted with an external tool; the plugin does not decode legacy code pages, does not re-encode on save, and keeps no encoding state.
|
|
231
235
|
- **Windows-only.** The branch targets Windows; POSIX-only suites are excluded in `vitest.config.windows.ts`, and that exclusion list must shrink, never grow (see [`dsh/UPSTREAM.md`](dsh/UPSTREAM.md)).
|
|
232
236
|
|
|
@@ -234,7 +238,7 @@ Range-family rejections render their current-row evidence exactly once: the head
|
|
|
234
238
|
|
|
235
239
|
| Path | Role |
|
|
236
240
|
| --- | --- |
|
|
237
|
-
| `src/` |
|
|
241
|
+
| `src/` | upstream pi-better-edit core (semantic source; upstream fixes are picked selectively, see [`dsh/UPSTREAM.md`](dsh/UPSTREAM.md)) |
|
|
238
242
|
| `dsh/` | DeepSeek Harness host layer — the only code that differs from upstream; map in [`dsh/README.md`](dsh/README.md) |
|
|
239
243
|
| `dsh/UPSTREAM.md` | upstream sync cursor, policy and Windows adaptation patches |
|
|
240
244
|
| `dsh/baseline/` | milestone measurement baselines (M0–M5) |
|
package/cordis.patch.yml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# dsh-hashline-edit bundle patch: mount the host-plane plugin row.
|
|
2
2
|
# Installed via `dsh plugin --profile <name> add dsh-hashline-edit` (or a
|
|
3
3
|
# profile's bundle list). The plugin hooks agent/created and shadows the
|
|
4
|
-
# built-in read
|
|
4
|
+
# built-in read/edit tools on each agent's own scope layer, so no preset
|
|
5
5
|
# editing or user config is needed.
|
|
6
6
|
- insert:
|
|
7
7
|
- id: dsh-hashline-edit
|