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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Shared host contracts for the dsh adapter.
|
|
3
3
|
*
|
|
4
4
|
* The `dsh/` tree is the DeepSeek Harness host layer over the host-agnostic
|
|
5
|
-
* hashline core in `src/`. Every lane (host, read,
|
|
5
|
+
* hashline core in `src/`. Every lane (host, read, apply-patch, platform) compiles
|
|
6
6
|
* against this file; renaming or reshaping an export here is a cross-lane
|
|
7
7
|
* breaking change.
|
|
8
8
|
*
|
|
@@ -67,6 +67,15 @@ export interface FileIO {
|
|
|
67
67
|
stat(path: string, signal?: AbortSignal): Promise<FileStat | undefined>;
|
|
68
68
|
/** Direct child names of a directory, sorted lexicographically. */
|
|
69
69
|
readdir(path: string, signal?: AbortSignal): Promise<string[]>;
|
|
70
|
+
/**
|
|
71
|
+
* Delete one regular file. A lifecycle delete targets a file; a directory at the same path is
|
|
72
|
+
* a caller bug that must surface (never a recursive removal).
|
|
73
|
+
*/
|
|
74
|
+
remove?(path: string, signal?: AbortSignal): Promise<void>;
|
|
75
|
+
/** Rename one regular file. The destination must not exist and its parent is created first. */
|
|
76
|
+
rename?(from: string, to: string, signal?: AbortSignal): Promise<void>;
|
|
77
|
+
/** Create one directory and missing parents. */
|
|
78
|
+
mkdir?(path: string, signal?: AbortSignal): Promise<void>;
|
|
70
79
|
}
|
|
71
80
|
/** The two sandbox-escalation arguments a mutating tool may carry. */
|
|
72
81
|
export interface SandboxArgs {
|
|
@@ -124,7 +133,7 @@ export interface SandboxController {
|
|
|
124
133
|
*
|
|
125
134
|
* The host's observation policy fills its per-session state exclusively from
|
|
126
135
|
* `fs/observed`, and that state is what lets a built-in `write` replace an
|
|
127
|
-
* existing file. Shadowed `read`/`
|
|
136
|
+
* existing file. Shadowed `read`/`apply_patch` calls never touch the provider's own
|
|
128
137
|
* write path, so without this channel a file this plugin served stays
|
|
129
138
|
* "unobserved" and the built-in overwrite is refused forever.
|
|
130
139
|
*
|
|
@@ -190,7 +199,7 @@ export interface ToolDependencies {
|
|
|
190
199
|
* factories at registration time. The fixed names are part of the lane
|
|
191
200
|
* contract:
|
|
192
201
|
* - `dsh/tools/read.ts` → `buildReadTool` (tool name `read`)
|
|
193
|
-
* - `dsh/tools/
|
|
202
|
+
* - `dsh/tools/apply-patch.ts` → `buildApplyPatchTool` (tool name `apply_patch`)
|
|
194
203
|
* - `dsh/tools/undo.ts` → `buildUndoTool` (tool name `undo_last_edit`)
|
|
195
204
|
*/
|
|
196
205
|
export type ToolDefinitionFactory = (deps: ToolDependencies) => ToolDefinition;
|
package/lib/types/dsh/fs.d.ts
CHANGED
|
@@ -41,6 +41,9 @@ export declare class LocalFileIO implements FileIO {
|
|
|
41
41
|
write(path: string, data: Uint8Array | string, signal?: AbortSignal): Promise<void>;
|
|
42
42
|
stat(path: string, signal?: AbortSignal): Promise<FileStat | undefined>;
|
|
43
43
|
readdir(path: string, signal?: AbortSignal): Promise<string[]>;
|
|
44
|
+
remove(path: string, signal?: AbortSignal): Promise<void>;
|
|
45
|
+
rename(from: string, to: string, signal?: AbortSignal): Promise<void>;
|
|
46
|
+
mkdir(path: string, signal?: AbortSignal): Promise<void>;
|
|
44
47
|
}
|
|
45
48
|
/** Create the M1 local filesystem seam. */
|
|
46
49
|
export declare function createLocalFileIO(): FileIO;
|
|
@@ -26,20 +26,20 @@ export declare function parseSectionFile(content: string): ParsedSection;
|
|
|
26
26
|
export declare function isBlankOverride(content: string): boolean;
|
|
27
27
|
/** One overridable tool section. */
|
|
28
28
|
export interface GuidanceSection {
|
|
29
|
-
/** Registry section name, e.g. `tool:
|
|
29
|
+
/** Registry section name, e.g. `tool:apply_patch`. */
|
|
30
30
|
readonly name: string;
|
|
31
|
-
/** Override file name inside a preset directory, e.g. `
|
|
31
|
+
/** Override file name inside a preset directory, e.g. `apply-patch.md`. */
|
|
32
32
|
readonly file: string;
|
|
33
33
|
/** Order used when the harness registry names no slot for this section. */
|
|
34
34
|
readonly defaultOrder: number;
|
|
35
35
|
/** The `systemPrompt.getSectionOrder` slot this section shadows, when one exists. */
|
|
36
|
-
readonly orderName?: "TOOL_READ" | "TOOL_EDIT";
|
|
36
|
+
readonly orderName?: "TOOL_READ" | "TOOL_EDIT" | "TOOL_APPLY_PATCH";
|
|
37
37
|
/** The compiled default text. */
|
|
38
38
|
renderDefault(): string;
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
|
-
* The three sections, in default-order sequence.
|
|
42
|
-
*
|
|
41
|
+
* The three sections, in default-order sequence. Read and undo reuse the pi
|
|
42
|
+
* host's prompt sources; apply_patch owns the v4 mutation guidance.
|
|
43
43
|
*/
|
|
44
44
|
export declare const GUIDANCE_SECTIONS: readonly GuidanceSection[];
|
|
45
45
|
/** Render the compiled default text for one section. */
|
|
@@ -116,4 +116,10 @@ export declare function guidanceHomeDir(env?: Record<string, string | undefined>
|
|
|
116
116
|
* come from the shared prompt sources, so the plugin package must ship
|
|
117
117
|
* `prompts/` for them to load.
|
|
118
118
|
*/
|
|
119
|
-
|
|
119
|
+
/** Which feature tools are enabled, so a disabled tool's guidance section is not registered. */
|
|
120
|
+
export interface GuidanceToggles {
|
|
121
|
+
readonly read: boolean;
|
|
122
|
+
readonly applyPatch: boolean;
|
|
123
|
+
readonly undo: boolean;
|
|
124
|
+
}
|
|
125
|
+
export declare function registerGuidanceSections(rootCtx: Context, agentCtx: Context, enabled?: GuidanceToggles): () => void;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hide the native file-mutation tools so every text change goes through
|
|
3
|
+
* `apply_patch` — the one mutation entry point of the v4 surface.
|
|
4
|
+
*
|
|
5
|
+
* DSH 0.2.2-rc.1 owns tool declarations in the tool registry, not in the
|
|
6
|
+
* `system-prompt/assemble` waterfall: the waterfall receives sections, contexts
|
|
7
|
+
* and variables only. The authoritative schema filter is therefore the
|
|
8
|
+
* per-agent registry restriction (`tools.restrict({ deny })`), which removes a
|
|
9
|
+
* global tool from both the native schema list and the PTC `tools:sdk` section
|
|
10
|
+
* because both are rendered from `tools.definitions(scope, toolSet)`.
|
|
11
|
+
*
|
|
12
|
+
* Three seams still back that up, because a restriction only governs the
|
|
13
|
+
* registry view and a stale session or a hand-rolled section could carry a
|
|
14
|
+
* residual binding:
|
|
15
|
+
*
|
|
16
|
+
* 1. `tools.restrict({ deny })` drops the hidden schemas for this agent;
|
|
17
|
+
* 2. `system-prompt/assemble` empties the `tool:edit` guidance section (its
|
|
18
|
+
* text is prose, never a tool mention) and deletes the hidden tools' member
|
|
19
|
+
* blocks from any rendered PTC `tools:sdk` section;
|
|
20
|
+
* 3. `tools.guard` is the monotonic execution backstop for a stale schema or
|
|
21
|
+
* any residual binding.
|
|
22
|
+
*
|
|
23
|
+
* `write` is hidden with `edit`/`str_replace_editor`. A whole-file replacement
|
|
24
|
+
* is one `*** Update File:` identity hunk spanning every served line with `+`
|
|
25
|
+
* lines for the new content, so no native mutation tool has to stay visible.
|
|
26
|
+
* The native `apply_patch` name is also denied in the inherited/preset layer
|
|
27
|
+
* when it exists; the plugin's own scoped registration shadows it otherwise.
|
|
28
|
+
*
|
|
29
|
+
* The layer is installed only when `apply_patch` actually registered: hiding
|
|
30
|
+
* the native mutation tools while owning no replacement would leave the
|
|
31
|
+
* profile with no way to change a file.
|
|
32
|
+
*
|
|
33
|
+
* @module dsh-hashline-edit/hide
|
|
34
|
+
*/
|
|
35
|
+
/** A boolean config value, or a live getter (used when a host exposes volatile config). */
|
|
36
|
+
type BooleanSource = boolean | (() => boolean);
|
|
37
|
+
/** The hide-layer configuration after the plugin-level defaults are applied. */
|
|
38
|
+
export interface NativeHideConfig {
|
|
39
|
+
/** The registered replacement tool name, protected from `hiddenToolNames`. */
|
|
40
|
+
readonly toolName: string;
|
|
41
|
+
/** Hide `write`/`edit`/`str_replace_editor`; defaults to true. */
|
|
42
|
+
readonly hideNativeWriteTools?: BooleanSource;
|
|
43
|
+
/** Extra global tool names to hide alongside the native set. */
|
|
44
|
+
readonly hiddenToolNames?: readonly string[];
|
|
45
|
+
/** The Agent scope key used for the agent-view probe; absent keeps the global probe. */
|
|
46
|
+
readonly scope?: unknown;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Delete the hidden tools' member blocks from one rendered `tools:sdk` text.
|
|
50
|
+
*
|
|
51
|
+
* Structural, renderer-specific parsing — never a mention match:
|
|
52
|
+
* - TypeScript: a member starts at ` name: type` (2-space indent) inside
|
|
53
|
+
* `ToolArgsMap`/`ToolOutputMap`, may open braces on the same line, and ends
|
|
54
|
+
* at the first line that closes every opened brace and ends with `;`. Its
|
|
55
|
+
* optional single-line JSDoc comment directly above goes with it.
|
|
56
|
+
* - Python: a `Tools` protocol member starts at an indented `async def` line
|
|
57
|
+
* and spans until the next line at that member indent or shallower.
|
|
58
|
+
* @param text - the rendered SDK section text.
|
|
59
|
+
* @param hidden - the tool names to remove.
|
|
60
|
+
* @returns the text with every hidden member block removed.
|
|
61
|
+
*/
|
|
62
|
+
export declare function stripSdkMembers(text: string, hidden: ReadonlySet<string>): string;
|
|
63
|
+
interface LoggerLike {
|
|
64
|
+
warn?(message: string): void;
|
|
65
|
+
}
|
|
66
|
+
declare function warn(rootCtx: {
|
|
67
|
+
logger?: LoggerLike;
|
|
68
|
+
}, message: string): void;
|
|
69
|
+
/**
|
|
70
|
+
* Install the hide layer for one agent. Only call this after `apply_patch`
|
|
71
|
+
* registered successfully.
|
|
72
|
+
*
|
|
73
|
+
* @param rootCtx - the plugin/root scope, used for the global-name probe and warnings.
|
|
74
|
+
* @param agentCtx - the agent scope whose tool view is restricted.
|
|
75
|
+
* @param config - the resolved hide configuration.
|
|
76
|
+
* @returns the exact disposer; disposing lifts the restriction and every listener.
|
|
77
|
+
*/
|
|
78
|
+
export declare function registerNativeToolHiding(rootCtx: Parameters<typeof warn>[0], agentCtx: unknown, config: NativeHideConfig): () => void;
|
|
79
|
+
export {};
|
|
@@ -1,82 +1,11 @@
|
|
|
1
|
-
/** Retained line budget, matching pi's `DEFAULT_MAX_LINES`. */
|
|
2
|
-
export declare const DEFAULT_MAX_LINES = 2000;
|
|
3
|
-
/** Retained byte budget, matching pi's `DEFAULT_MAX_BYTES` (50KB). */
|
|
4
|
-
export declare const DEFAULT_MAX_BYTES: number;
|
|
5
|
-
/** The truncation report the core's read page renders. */
|
|
6
|
-
export interface TruncationResult {
|
|
7
|
-
/** The truncated content. */
|
|
8
|
-
content: string;
|
|
9
|
-
/** Whether truncation occurred. */
|
|
10
|
-
truncated: boolean;
|
|
11
|
-
/** Which limit was hit: `"lines"`, `"bytes"`, or `null` when nothing was cut. */
|
|
12
|
-
truncatedBy: "lines" | "bytes" | null;
|
|
13
|
-
/** Total number of lines in the original content. */
|
|
14
|
-
totalLines: number;
|
|
15
|
-
/** Total number of bytes in the original content. */
|
|
16
|
-
totalBytes: number;
|
|
17
|
-
/** Number of complete lines in the truncated output. */
|
|
18
|
-
outputLines: number;
|
|
19
|
-
/** Number of bytes in the truncated output. */
|
|
20
|
-
outputBytes: number;
|
|
21
|
-
/** Whether the last line was partially truncated (tail truncation only). */
|
|
22
|
-
lastLinePartial: boolean;
|
|
23
|
-
/** Whether the first line exceeded the byte limit (head truncation only). */
|
|
24
|
-
firstLineExceedsLimit: boolean;
|
|
25
|
-
/** The line limit that was applied. */
|
|
26
|
-
maxLines: number;
|
|
27
|
-
/** The byte limit that was applied. */
|
|
28
|
-
maxBytes: number;
|
|
29
|
-
}
|
|
30
|
-
/** The two independent limits a truncation call applies. */
|
|
31
|
-
export interface TruncationOptions {
|
|
32
|
-
/** Maximum number of lines; defaults to {@link DEFAULT_MAX_LINES}. */
|
|
33
|
-
maxLines?: number;
|
|
34
|
-
/** Maximum number of bytes; defaults to {@link DEFAULT_MAX_BYTES}. */
|
|
35
|
-
maxBytes?: number;
|
|
36
|
-
}
|
|
37
1
|
/**
|
|
38
|
-
*
|
|
2
|
+
* dsh host shim for the host-neutral utilities the core uses.
|
|
39
3
|
*
|
|
40
|
-
* WHY:
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*/
|
|
45
|
-
export interface ExtensionAPI {
|
|
46
|
-
/**
|
|
47
|
-
* Register one pi tool definition. The argument is intentionally structural and loose: the dsh
|
|
48
|
-
* program only needs the registration to compile, never to execute, and the loose `execute`
|
|
49
|
-
* signature keeps the pi adapter's untyped callback out of the dsh build's implicit-any checks.
|
|
50
|
-
*/
|
|
51
|
-
registerTool(definition: {
|
|
52
|
-
execute: (...args: any[]) => unknown;
|
|
53
|
-
[key: string]: unknown;
|
|
54
|
-
}): void;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Format bytes as a human-readable size (`512B`, `1.5KB`, `2.0MB`).
|
|
58
|
-
* @param bytes - the byte count to render.
|
|
59
|
-
* @returns the pi-compatible size label.
|
|
60
|
-
*/
|
|
61
|
-
export declare function formatSize(bytes: number): string;
|
|
62
|
-
/**
|
|
63
|
-
* Truncate content from the head (keep the first N lines / bytes).
|
|
4
|
+
* WHY: the dsh bundle must not ship the pi agent package. The core's utility
|
|
5
|
+
* surface lives in `src/host-utils.ts`; this module keeps the historical
|
|
6
|
+
* `dsh/host-compat` import path (and the `@earendil-works/pi-coding-agent`
|
|
7
|
+
* esbuild/tsconfig alias) working for the dsh build.
|
|
64
8
|
*
|
|
65
|
-
*
|
|
66
|
-
* implementation the rest of the contract was written against, so this is a
|
|
67
|
-
* faithful port including its two edge rules: complete lines only, and an
|
|
68
|
-
* over-long first line yields empty content with `firstLineExceedsLimit`.
|
|
69
|
-
* @param content - the text to truncate.
|
|
70
|
-
* @param options - the line and byte limits.
|
|
71
|
-
* @returns the truncation report.
|
|
72
|
-
*/
|
|
73
|
-
export declare function truncateHead(content: string, options?: TruncationOptions): TruncationResult;
|
|
74
|
-
/**
|
|
75
|
-
* Serialize file mutation operations that target the same file; different files still run
|
|
76
|
-
* in parallel. A faithful port of pi's queue so the core's cut transaction keeps its
|
|
77
|
-
* lock ordering guarantees under the dsh host.
|
|
78
|
-
* @param filePath - the file the mutation targets.
|
|
79
|
-
* @param run - the critical section to run once the path is free.
|
|
80
|
-
* @returns the critical section's result.
|
|
9
|
+
* @module dsh-hashline-edit/host-compat
|
|
81
10
|
*/
|
|
82
|
-
export
|
|
11
|
+
export * from "../src/host-utils.js";
|
package/lib/types/dsh/index.d.ts
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* dsh-hashline-edit host plugin entry.
|
|
3
3
|
*
|
|
4
|
-
* On every `agent/created`, install the
|
|
5
|
-
* own scope layer so they shadow the preset's built-in `read
|
|
4
|
+
* On every `agent/created`, install the hashline tools on the AGENT's
|
|
5
|
+
* own scope layer so they shadow the preset's built-in `read` for that
|
|
6
6
|
* agent (nearest layer wins in dsh's tool registry) and unwind automatically
|
|
7
|
-
* when the agent is disposed. The
|
|
8
|
-
*
|
|
7
|
+
* when the agent is disposed. The native `write`, `edit` and
|
|
8
|
+
* `str_replace_editor` schemas are hidden on the same scope so `apply_patch`
|
|
9
|
+
* is the only file-mutation entry point; the write hook still integrates a
|
|
10
|
+
* built-in `write` when a profile chooses to keep it visible.
|
|
9
11
|
*
|
|
10
|
-
* `inject` deliberately lists only `tools` and `systemPrompt`: M1 has no
|
|
11
12
|
* `inject` deliberately lists only `tools` and `systemPrompt`: the read-path
|
|
12
13
|
* `ctx.fs` bridge is optional and resolved with `ctx.get`, so a minimal
|
|
13
|
-
* composition still loads with the local `node:fs` fallback.
|
|
14
|
-
* local-only (the M5 bridge covers reads; M6 owns mutation).
|
|
14
|
+
* composition still loads with the local `node:fs` fallback. apply_patch and
|
|
15
|
+
* undo stay local-only (the M5 bridge covers reads; M6 owns mutation).
|
|
15
16
|
* @module dsh-hashline-edit
|
|
16
17
|
*/
|
|
17
18
|
import type { Context } from "@deepseek-ai/cordis";
|
|
18
19
|
import type { Agent } from "@deepseek-ai/dsh-agent";
|
|
20
|
+
import Schema from "@deepseek-ai/schemastery";
|
|
19
21
|
import { type ToolMetrics } from "./metrics/instrument.js";
|
|
20
22
|
/** Cordis plugin name used by loader diagnostics. */
|
|
21
23
|
export declare const name = "dsh-hashline-edit";
|
|
@@ -24,6 +26,47 @@ export declare const name = "dsh-hashline-edit";
|
|
|
24
26
|
* services are resolved with `ctx.get` inside `dsh/sandbox.ts` instead.
|
|
25
27
|
*/
|
|
26
28
|
export declare const inject: string[];
|
|
29
|
+
/**
|
|
30
|
+
* The row's editable config schema. Exporting `Config` is what makes the host
|
|
31
|
+
* expose `dsh-hashline-edit#dsh-hashline-edit` as a writable settings namespace,
|
|
32
|
+
* so the Plugins-page card can render its three switches and write them back.
|
|
33
|
+
*/
|
|
34
|
+
export declare const Config: Schema<Schemastery.ObjectS<NoInfer<{
|
|
35
|
+
read: Schema<boolean, boolean, "volatile-defined">;
|
|
36
|
+
applyPatch: Schema<boolean, boolean, "volatile-defined">;
|
|
37
|
+
undo: Schema<boolean, boolean, "volatile-defined">;
|
|
38
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
39
|
+
read: Schema<boolean, boolean, "volatile-defined">;
|
|
40
|
+
applyPatch: Schema<boolean, boolean, "volatile-defined">;
|
|
41
|
+
undo: Schema<boolean, boolean, "volatile-defined">;
|
|
42
|
+
}>>, "plain">;
|
|
43
|
+
/** The plugin configuration the loader passes as the second `apply` argument. */
|
|
44
|
+
export interface PluginConfig {
|
|
45
|
+
/**
|
|
46
|
+
* Expose the hashline `read` tool, shadowing the host's native `read`.
|
|
47
|
+
* Defaults to true; off leaves the native `read` in place.
|
|
48
|
+
*/
|
|
49
|
+
read?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Expose the hashline `apply_patch` tool and hide the native
|
|
52
|
+
* `edit`/`write`/`apply_patch`/`str_replace_editor` tools. Defaults to true;
|
|
53
|
+
* off keeps every native mutation tool.
|
|
54
|
+
*/
|
|
55
|
+
applyPatch?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Expose the `undo_last_edit` tool. Defaults to false. The undo snapshot row is
|
|
58
|
+
* still written on every commit; only the model-facing tool is opt-in.
|
|
59
|
+
*/
|
|
60
|
+
undo?: boolean;
|
|
61
|
+
}
|
|
62
|
+
/** The three feature switches after the shipped defaults are applied. */
|
|
63
|
+
export interface ResolvedSwitches {
|
|
64
|
+
readonly read: boolean;
|
|
65
|
+
readonly applyPatch: boolean;
|
|
66
|
+
readonly undo: boolean;
|
|
67
|
+
}
|
|
68
|
+
/** Resolve the plugin's three switches with the shipped defaults: read and apply_patch on, undo off. */
|
|
69
|
+
export declare function resolveSwitches(config?: PluginConfig): ResolvedSwitches;
|
|
27
70
|
/**
|
|
28
71
|
* Install the hashline toolset for one agent inside its own effect, so the
|
|
29
72
|
* registrations are disposed in reverse order when the agent scope unwinds.
|
|
@@ -31,6 +74,6 @@ export declare const inject: string[];
|
|
|
31
74
|
* Exported separately from {@link apply} so the host test can drive one fake
|
|
32
75
|
* agent directly and integration probes can reuse the exact install path.
|
|
33
76
|
*/
|
|
34
|
-
export declare function installAgentTools(rootCtx: Context, agent: Agent, metrics?: ToolMetrics): void;
|
|
35
|
-
/** Mount the plugin
|
|
36
|
-
export declare function apply(rootCtx: Context): void;
|
|
77
|
+
export declare function installAgentTools(rootCtx: Context, agent: Agent, metrics?: ToolMetrics, config?: PluginConfig): () => void;
|
|
78
|
+
/** Mount the plugin and reconcile live agents on every (re)apply. */
|
|
79
|
+
export declare function apply(rootCtx: Context, config?: PluginConfig): void;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* lets the global observer record any other host tool — the built-in `write`,
|
|
6
6
|
* `pwsh`, `grep`, … — without widening this union once per tool.
|
|
7
7
|
*/
|
|
8
|
-
type ToolName = "read" | "
|
|
8
|
+
type ToolName = "read" | "apply_patch" | "undo_last_edit" | "write" | "shell_view" | (string & {});
|
|
9
9
|
/** One tool call, as written to the JSONL file. Character counts are exact; the
|
|
10
10
|
* token estimate belongs to the summarizer so the ratio stays a reporting
|
|
11
11
|
* choice instead of being frozen into the event stream. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Global tool-call telemetry for the dsh host layer.
|
|
3
3
|
*
|
|
4
4
|
* Before this observer the adapter measured only its own surface: `read`,
|
|
5
|
-
* `
|
|
5
|
+
* `apply_patch` and `undo_last_edit` from the tool boundaries, plus `shell_view` from
|
|
6
6
|
* the shell hook when it rewrites a result. Every other call the host
|
|
7
7
|
* dispatched — the built-in `write` that sits next to this plugin's shadowed
|
|
8
8
|
* tools, `pwsh`, `grep`, … — left no event at all, so no baseline could say
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Mirrors the built-in `@deepseek-ai/dsh-tool-fs` controller (same
|
|
5
5
|
* vocabulary, same fail-closed approval sequence, shared
|
|
6
|
-
* `@deepseek-ai/dsh-sandbox` pieces) so `
|
|
6
|
+
* `@deepseek-ai/dsh-sandbox` pieces) so `apply_patch`/`undo_last_edit` ask for wider
|
|
7
7
|
* access exactly like the built-in `write`/`edit`. The differences are
|
|
8
8
|
* deliberate M1 facts:
|
|
9
9
|
*
|
|
@@ -21,7 +21,7 @@ import type { ToolExecution } from "@deepseek-ai/dsh-tools";
|
|
|
21
21
|
import type { SandboxMode } from "@deepseek-ai/dsh-sandbox";
|
|
22
22
|
import type { SandboxArgs, SandboxController, SandboxDecision } from "./contracts.js";
|
|
23
23
|
/**
|
|
24
|
-
* The filesystem escalation controller shared by `
|
|
24
|
+
* The filesystem escalation controller shared by `apply_patch` and `undo_last_edit`
|
|
25
25
|
* for one agent install.
|
|
26
26
|
*/
|
|
27
27
|
export declare class FsSandboxController implements SandboxController {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* foreground stdout channel, or a shell view that refuses (not whitelisted /
|
|
8
8
|
* ambiguous alignment) all pass the decision through untouched. Only a
|
|
9
9
|
* successful, uniquely aligned view is rewritten, and its rows are served
|
|
10
|
-
* through the read tool's seam so a following `
|
|
10
|
+
* through the read tool's seam so a following `apply_patch` hunk resolves the anchors.
|
|
11
11
|
*
|
|
12
12
|
* Both foreground value shapes the host may project are understood:
|
|
13
13
|
* `{ kind: "foreground", stdout: { text, truncated } }` (the canonical
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { FileDiff, ToolDefinition } from "@deepseek-ai/dsh-tools";
|
|
2
|
+
import { APPLY_PATCH_TOOL_NAME } from "../../src/apply-patch/tool.js";
|
|
3
|
+
import type { ApplyPatchTool } from "../../src/apply-patch/tool.js";
|
|
4
|
+
/** Public tool name re-exported for host registration and surface tests. */
|
|
5
|
+
export { APPLY_PATCH_TOOL_NAME };
|
|
6
|
+
import type { ToolDependencies } from "../contracts.js";
|
|
7
|
+
/** One call's intended file diffs, parsed from the patch headers for the pending card. */
|
|
8
|
+
interface PatchPreview {
|
|
9
|
+
readonly diffs: FileDiff[];
|
|
10
|
+
readonly locations: string[];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Scan the patch headers for the pending card. This is a presentation-only
|
|
14
|
+
* projection: it never decides whether the patch is valid (the grammar and
|
|
15
|
+
* planner do), and it never throws on malformed text.
|
|
16
|
+
* @param input - the raw patch text.
|
|
17
|
+
* @returns the intended additions and every path the patch names.
|
|
18
|
+
*/
|
|
19
|
+
export declare function previewPatch(input: string): PatchPreview;
|
|
20
|
+
/** Every path this patch writes, including a Cut From source; Copy From sources are read-only. */
|
|
21
|
+
export declare function writtenPatchPaths(input: string): string[];
|
|
22
|
+
/** Options for {@link buildApplyPatchTool}; the factory seam is for tests. */
|
|
23
|
+
export interface ApplyPatchToolOptions {
|
|
24
|
+
/** Test seam: build the use case without touching the real engine/store. */
|
|
25
|
+
readonly create?: () => ApplyPatchTool;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build the dsh 'apply_patch' tool for one agent install.
|
|
29
|
+
*
|
|
30
|
+
* The use case is created lazily: building a tool definition must not touch the
|
|
31
|
+
* engine or the store, and a composition where 'apply_patch' is skipped must
|
|
32
|
+
* still install the rest of the toolset.
|
|
33
|
+
*
|
|
34
|
+
* @param deps - the host seams this tool may touch; 'sandbox' advertises and resolves escalation.
|
|
35
|
+
* @param options - test seam for the use case.
|
|
36
|
+
* @returns a registry-ready dsh tool definition named 'apply_patch'.
|
|
37
|
+
*/
|
|
38
|
+
export declare function buildApplyPatchTool(deps: ToolDependencies, options?: ApplyPatchToolOptions): ToolDefinition;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The dsh `read` tool: hash-anchored reads (`HASH│content` rows) that shadow
|
|
3
3
|
* the built-in `read` on the agent's own scope layer. In the default `served`
|
|
4
|
-
* mode every shown row is recorded as served, so a later `
|
|
4
|
+
* mode every shown row is recorded as served, so a later `apply_patch` identity hunk can verify the
|
|
5
5
|
* model was actually shown the lines it targets; `verbatim` mode is a plain
|
|
6
6
|
* reference read that grants no anchor and leaves served state untouched.
|
|
7
7
|
*
|
|
@@ -54,7 +54,7 @@ export declare function createDefaultReadSpanProvider(io?: CoreReadIo): SpanProv
|
|
|
54
54
|
export interface ServedFileLine {
|
|
55
55
|
/** 1-based line number the anchor addresses. */
|
|
56
56
|
readonly line: number;
|
|
57
|
-
/** The line's
|
|
57
|
+
/** The line's served anchor, usable by `apply_patch`. */
|
|
58
58
|
readonly hash: string;
|
|
59
59
|
/** The line's decoded text, without the anchor prefix. */
|
|
60
60
|
readonly text: string;
|
|
@@ -84,7 +84,7 @@ export declare function decodeFileLines(deps: ToolDependencies, request: ServeFi
|
|
|
84
84
|
*
|
|
85
85
|
* WHY a separate seam: the shell view must turn already-aligned disk lines into
|
|
86
86
|
* editable anchors without re-implementing the read pipeline, and those anchors
|
|
87
|
-
* must be leased to the session the following `
|
|
87
|
+
* must be leased to the session the following `apply_patch` hunk uses.
|
|
88
88
|
*/
|
|
89
89
|
export declare function serveFileLines(deps: ToolDependencies, request: ServeFileLinesRequest): Promise<ServedFileLine[]>;
|
|
90
90
|
/**
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { HashStore } from "../hash-store.js";
|
|
2
|
+
import type { ApplyPatchFailure, PatchPlan, ServedFileBlock } from "./types.js";
|
|
3
|
+
/** Options for {@link commitPlan}. */
|
|
4
|
+
export interface CommitPlanOptions {
|
|
5
|
+
readonly cwd: string;
|
|
6
|
+
readonly sessionKey: string;
|
|
7
|
+
readonly signal?: AbortSignal;
|
|
8
|
+
readonly store?: HashStore;
|
|
9
|
+
/** POSIX access-mode bitmask; defaults to read+write. */
|
|
10
|
+
readonly accessMode?: number;
|
|
11
|
+
/** TEST-ONLY: fires before the first rename, while the pre-images/undo rows are durable. */
|
|
12
|
+
readonly onBeforeFirstWrite?: () => void | Promise<void>;
|
|
13
|
+
/** TEST-ONLY: fires between two member renames, after the earlier one is durable. */
|
|
14
|
+
readonly onBetweenWrites?: (committedAbsolutePath: string) => void | Promise<void>;
|
|
15
|
+
/** TEST-ONLY: fires after a move rename and before the destination rewrite (mid-member failure). */
|
|
16
|
+
readonly onAfterMoveRename?: (toAbsolutePath: string) => void | Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
/** One committed file's lifecycle status and line accounting. */
|
|
19
|
+
export interface CommittedFile {
|
|
20
|
+
readonly path: string;
|
|
21
|
+
readonly status: "A" | "M" | "R" | "D";
|
|
22
|
+
/** Original path for a rename (`R` only). */
|
|
23
|
+
readonly fromPath?: string;
|
|
24
|
+
readonly addedLines: number;
|
|
25
|
+
readonly removedLines: number;
|
|
26
|
+
/** New anchors for the changed lines; absent when the member wrote no content. */
|
|
27
|
+
readonly served?: ServedFileBlock;
|
|
28
|
+
}
|
|
29
|
+
/** Commit outcome: the per-file facts on success, the whole failure on rejection. */
|
|
30
|
+
export type CommitPlanResult = {
|
|
31
|
+
readonly ok: true;
|
|
32
|
+
readonly files: readonly CommittedFile[];
|
|
33
|
+
readonly diff: string;
|
|
34
|
+
readonly warnings: readonly string[];
|
|
35
|
+
} | {
|
|
36
|
+
readonly ok: false;
|
|
37
|
+
readonly failure: ApplyPatchFailure;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Commit one plan atomically (one correlated transaction, one undo record set).
|
|
41
|
+
*
|
|
42
|
+
* The implementation reuses `commitTransaction` — the existing correlated skeleton — and extends
|
|
43
|
+
* its member shape with the plan's lifecycle action; the undo schema gains the matching action.
|
|
44
|
+
*
|
|
45
|
+
* @param plan - the fully resolved plan.
|
|
46
|
+
* @param options - cwd/session/store, cancellation and the test fault seams.
|
|
47
|
+
* @returns the committed facts, or a failure whose `changedNothing` reflects the rollback.
|
|
48
|
+
*/
|
|
49
|
+
export declare function commitPlan(plan: PatchPlan, options: CommitPlanOptions): Promise<CommitPlanResult>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { AnchorSpan, ParsePatchResult } from "./types.js";
|
|
2
|
+
/** Hard cap on one patch input (bytes), mirroring the host request budget. */
|
|
3
|
+
export declare const PATCH_MAX_BYTES: number;
|
|
4
|
+
/** Options for {@link parseApplyPatch}. */
|
|
5
|
+
export interface ParsePatchOptions {
|
|
6
|
+
/** Maximum accepted input size in bytes; defaults to {@link PATCH_MAX_BYTES}. */
|
|
7
|
+
readonly maxBytes?: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Parse one patch document.
|
|
11
|
+
*
|
|
12
|
+
* Success returns the AST defined in `types.ts`; failure returns every syntax
|
|
13
|
+
* problem the parser could diagnose in one pass (never a throw for malformed
|
|
14
|
+
* user input). Rejections use `E_PATCH_SYNTAX` with the offending patch line.
|
|
15
|
+
*
|
|
16
|
+
* @param input - the raw `*** Begin Patch` … `*** End Patch` text.
|
|
17
|
+
* @param options - size guard knobs.
|
|
18
|
+
* @returns the parsed document or the collected problems.
|
|
19
|
+
*/
|
|
20
|
+
export declare function parseApplyPatch(input: string, options?: ParsePatchOptions): ParsePatchResult;
|
|
21
|
+
/**
|
|
22
|
+
* Parse an anchor token: `<a>` (single line) or `<a>-<b>` (closed span).
|
|
23
|
+
* Returns `undefined` when the token is not a valid anchor pair; the
|
|
24
|
+
* grammar layer turns that into an `E_PATCH_SYNTAX` problem at the patch line.
|
|
25
|
+
*
|
|
26
|
+
* @param token - the text after `@@` (no leading space).
|
|
27
|
+
* @returns the closed span, or undefined for a malformed token.
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseAnchorSpan(token: string): AnchorSpan | undefined;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type HashStore } from "../hash-store.js";
|
|
2
|
+
import type { ProcessedEditFile } from "../mutation-engine/types.js";
|
|
3
|
+
import type { PatchPath, PlannedFile } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* apply_patch lifecycle materialization — the plan-to-engine adapter.
|
|
6
|
+
*
|
|
7
|
+
* The planner resolves every mutation against a pre-call baseline; this module turns that plan
|
|
8
|
+
* into the mutation engine's `ProcessedEditFile` member shape (plus the engine-local lifecycle
|
|
9
|
+
* action). It never writes: the correlated transaction in `mutation-engine/pipeline.ts` owns the
|
|
10
|
+
* one commit path. Pure text application (splice at baseline coordinates) is the only work here,
|
|
11
|
+
* and the resulting anchors are always derived under the member's COMMITTED path.
|
|
12
|
+
*
|
|
13
|
+
* @module dsh-hashline-edit/apply-patch/lifecycle
|
|
14
|
+
*/
|
|
15
|
+
/** One materialized member: the plan facts plus the engine member the commit consumes. */
|
|
16
|
+
export interface MaterializedMember {
|
|
17
|
+
readonly planned: PlannedFile;
|
|
18
|
+
readonly member: ProcessedEditFile;
|
|
19
|
+
readonly status: "A" | "M" | "R" | "D";
|
|
20
|
+
/** The committed display path (destination for a move; the pre path otherwise). */
|
|
21
|
+
readonly committedPath: PatchPath;
|
|
22
|
+
/** The pre-transaction display path (move only). */
|
|
23
|
+
readonly fromPath?: PatchPath;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Materialize one planned file into the engine's member shape.
|
|
27
|
+
*
|
|
28
|
+
* The result text is produced by applying the plan's baseline-coordinate mutations; the anchors
|
|
29
|
+
* are then derived under the committed path. No file is read or written here — the plan already
|
|
30
|
+
* carries every baseline byte the commit needs.
|
|
31
|
+
*/
|
|
32
|
+
export declare function materializeMember(planned: PlannedFile, store?: HashStore): Promise<MaterializedMember>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { LeaseSpanSource } from "../hashline/resolve.js";
|
|
2
|
+
import { type HashStore } from "../hash-store.js";
|
|
3
|
+
import { type ServedAnchors } from "./resolve.js";
|
|
4
|
+
import type { ApplyPatchEngineOptions, FileBaseline, PatchDocument, PatchPath, PlannedMutation, PlanPatchResult } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* The baseline/served loader port.
|
|
7
|
+
*
|
|
8
|
+
* Production wires `readBaseline` to the file-content decode path,
|
|
9
|
+
* `readServed` to `createSessionHandle(...).load()` and `readLeaseSource` to
|
|
10
|
+
* the read-only lease identity source. Tests inject a pure in-memory
|
|
11
|
+
* implementation, which is what makes the planner testable without a store.
|
|
12
|
+
*/
|
|
13
|
+
export interface PlanFileLoader {
|
|
14
|
+
/** Load one file's baseline (LF-normalized text + anchors + BOM + ending). */
|
|
15
|
+
readBaseline(path: PatchPath, absolutePath: string, signal?: AbortSignal): Promise<FileBaseline>;
|
|
16
|
+
/** Load this session's served anchors for one file, parallel to its lines. */
|
|
17
|
+
readServed(absolutePath: string, sessionKey: string, store?: HashStore): Promise<ServedAnchors>;
|
|
18
|
+
/** Session-wide anchor homes, for foreign-anchor diagnosis (optional legacy port). */
|
|
19
|
+
anchorHomes?(anchor: string, sessionKey: string, store?: HashStore): readonly PatchPath[];
|
|
20
|
+
/** Build the read-only lease identity source for one file's baseline content. */
|
|
21
|
+
readLeaseSource?(absolutePath: string, sessionKey: string, content: string, store?: HashStore): Promise<LeaseSpanSource>;
|
|
22
|
+
}
|
|
23
|
+
/** Options for {@link planApplyPatch}; `loader` is the test seam. */
|
|
24
|
+
export interface PlanApplyPatchOptions extends ApplyPatchEngineOptions {
|
|
25
|
+
readonly loader?: PlanFileLoader;
|
|
26
|
+
}
|
|
27
|
+
/** A baseline for a file that does not exist yet (Add File / missing target). */
|
|
28
|
+
export declare function absentBaseline(path: PatchPath, absolutePath: string): FileBaseline;
|
|
29
|
+
/** The production loader over node:fs, the file-content decoder and the hash store. */
|
|
30
|
+
export declare function createDefaultPlanFileLoader(): PlanFileLoader;
|
|
31
|
+
/** Apply resolved baseline-coordinate mutations to a line array (descending, so coordinates stay valid). */
|
|
32
|
+
export declare function applyPlannedMutations(lines: readonly string[], mutations: readonly PlannedMutation[]): string[];
|
|
33
|
+
export declare function mutationDelta(baselineLines: readonly string[], mutation: PlannedMutation): {
|
|
34
|
+
added: number;
|
|
35
|
+
removed: number;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Plan one apply_patch call without writing anything.
|
|
39
|
+
*
|
|
40
|
+
* All hunks resolve against the pre-call baseline (never chained application);
|
|
41
|
+
* a later hunk's fragment window begins after the previous hunk's end. Any
|
|
42
|
+
* problem aborts the whole call: the returned list is every independently
|
|
43
|
+
* diagnosable problem, not just the first, together with the current rows of
|
|
44
|
+
* every named file (reject-and-serve).
|
|
45
|
+
*
|
|
46
|
+
* @param document - the parsed patch AST.
|
|
47
|
+
* @param options - cwd/session/store plus the optional baseline loader.
|
|
48
|
+
* @returns the plan, or every problem found plus the rows to serve.
|
|
49
|
+
*/
|
|
50
|
+
export declare function planApplyPatch(document: PatchDocument, options: PlanApplyPatchOptions): Promise<PlanPatchResult>;
|