@oh-my-pi/pi-coding-agent 15.5.3 → 15.5.6
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/CHANGELOG.md +55 -0
- package/dist/types/config/settings-schema.d.ts +27 -0
- package/dist/types/config.d.ts +31 -5
- package/dist/types/edit/file-snapshot-store.d.ts +18 -0
- package/dist/types/edit/hashline/diff.d.ts +35 -0
- package/dist/types/edit/hashline/execute.d.ts +28 -0
- package/dist/types/edit/hashline/filesystem.d.ts +57 -0
- package/dist/types/edit/hashline/index.d.ts +4 -0
- package/dist/types/edit/hashline/params.d.ts +11 -0
- package/dist/types/edit/index.d.ts +4 -3
- package/dist/types/edit/normalize.d.ts +4 -16
- package/dist/types/extensibility/legacy-pi-ai-shim.d.ts +23 -0
- package/dist/types/index.d.ts +0 -1
- package/dist/types/tools/fetch.d.ts +3 -0
- package/dist/types/tools/find.d.ts +7 -0
- package/dist/types/tools/index.d.ts +6 -5
- package/dist/types/tools/path-utils.d.ts +18 -0
- package/dist/types/utils/changelog.d.ts +8 -3
- package/package.json +8 -15
- package/scripts/build-binary.ts +11 -0
- package/src/config/settings-schema.ts +32 -0
- package/src/config.ts +42 -15
- package/src/edit/diff.ts +5 -3
- package/src/edit/file-snapshot-store.ts +22 -0
- package/src/edit/hashline/diff.ts +95 -0
- package/src/edit/hashline/execute.ts +181 -0
- package/src/edit/hashline/filesystem.ts +129 -0
- package/src/edit/hashline/index.ts +4 -0
- package/src/edit/hashline/params.ts +18 -0
- package/src/edit/index.ts +16 -27
- package/src/edit/normalize.ts +11 -41
- package/src/edit/renderer.ts +15 -8
- package/src/edit/streaming.ts +20 -134
- package/src/extensibility/legacy-pi-ai-shim.ts +24 -0
- package/src/extensibility/plugins/legacy-pi-compat.ts +47 -3
- package/src/index.ts +0 -1
- package/src/internal-urls/docs-index.generated.ts +1 -1
- package/src/main.ts +2 -1
- package/src/modes/rpc/rpc-client.ts +3 -1
- package/src/prompts/tools/find.md +3 -2
- package/src/sdk.ts +8 -1
- package/src/session/agent-session.ts +18 -2
- package/src/tools/ast-edit.ts +1 -1
- package/src/tools/ast-grep.ts +3 -3
- package/src/tools/fetch.ts +93 -50
- package/src/tools/find.ts +38 -6
- package/src/tools/index.ts +6 -5
- package/src/tools/path-utils.ts +81 -0
- package/src/tools/read.ts +71 -75
- package/src/tools/search.ts +136 -17
- package/src/tools/write.ts +3 -3
- package/src/utils/changelog.ts +11 -3
- package/src/utils/file-mentions.ts +1 -1
- package/dist/types/edit/file-read-cache.d.ts +0 -36
- package/dist/types/hashline/anchors.d.ts +0 -26
- package/dist/types/hashline/apply.d.ts +0 -14
- package/dist/types/hashline/constants.d.ts +0 -48
- package/dist/types/hashline/diff-preview.d.ts +0 -2
- package/dist/types/hashline/diff.d.ts +0 -16
- package/dist/types/hashline/execute.d.ts +0 -4
- package/dist/types/hashline/executor.d.ts +0 -56
- package/dist/types/hashline/hash.d.ts +0 -76
- package/dist/types/hashline/index.d.ts +0 -14
- package/dist/types/hashline/input.d.ts +0 -4
- package/dist/types/hashline/prefixes.d.ts +0 -7
- package/dist/types/hashline/recovery.d.ts +0 -21
- package/dist/types/hashline/stream.d.ts +0 -2
- package/dist/types/hashline/tokenizer.d.ts +0 -94
- package/dist/types/hashline/types.d.ts +0 -75
- package/src/edit/file-read-cache.ts +0 -138
- package/src/hashline/anchors.ts +0 -104
- package/src/hashline/apply.ts +0 -790
- package/src/hashline/bigrams.json +0 -649
- package/src/hashline/constants.ts +0 -60
- package/src/hashline/diff-preview.ts +0 -42
- package/src/hashline/diff.ts +0 -82
- package/src/hashline/execute.ts +0 -334
- package/src/hashline/executor.ts +0 -347
- package/src/hashline/grammar.lark +0 -22
- package/src/hashline/hash.ts +0 -131
- package/src/hashline/index.ts +0 -14
- package/src/hashline/input.ts +0 -137
- package/src/hashline/prefixes.ts +0 -111
- package/src/hashline/recovery.ts +0 -139
- package/src/hashline/stream.ts +0 -123
- package/src/hashline/tokenizer.ts +0 -473
- package/src/hashline/types.ts +0 -66
- package/src/prompts/tools/hashline.md +0 -83
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,61 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [15.5.6] - 2026-05-27
|
|
6
|
+
### Added
|
|
7
|
+
|
|
8
|
+
- Support for multi-range line selectors on URLs (e.g., `:5-10,20-30`) to fetch and display multiple non-contiguous sections
|
|
9
|
+
- Support for combining `:raw` mode with line range selectors on URLs (e.g., `:raw:1-120` or `:1-120:raw`)
|
|
10
|
+
- Support for line range selectors on directory listings (e.g., `:30-40` to view lines 30–40 of a directory tree)
|
|
11
|
+
- Clear error message when requesting a line offset beyond the end of a directory listing
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- URL selector parsing now supports multiple trailing selector tokens (e.g., `:raw:N-M`), applying them left-to-right
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Fixed `:raw` selector being ignored for JSON and feed URLs, causing them to be pretty-printed or converted to markdown instead of returning raw content
|
|
20
|
+
- Fixed directory listing line selectors silently dropping the offset parameter and only applying the limit
|
|
21
|
+
|
|
22
|
+
## [15.5.5] - 2026-05-27
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- Removed the model-facing `path` property from hashline edit tool parameters; hashline edit targets now come from `¶PATH` headers in `input`.
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- Fixed legacy pi-* extension loading regression where `import { Type } from "@(scope)/pi-ai"` (e.g. `@earendil-works/pi-ai` used by `@plannotator/pi-extension`) failed with `Export named 'Type' not found` after pi-ai 15.1.0 removed the root `Type` runtime export; the legacy-pi compat layer now redirects bare `@oh-my-pi/pi-ai` root imports through a sibling shim that re-exports the canonical pi-ai surface plus the Zod-backed `Type` runtime from the same TypeBox shim served to `@sinclair/typebox` imports ([#1437](https://github.com/can1357/oh-my-pi/issues/1437))
|
|
31
|
+
|
|
32
|
+
## [15.5.4] - 2026-05-27
|
|
33
|
+
|
|
34
|
+
### Breaking Changes
|
|
35
|
+
- Removed the package root `hashline` export so imports from the top-level entrypoint can no longer access `hashline` helpers directly
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
|
|
39
|
+
- Added `read.summarize.minTotalLines` setting (default 100) to set the minimum file length that triggers read summarization
|
|
40
|
+
- Added `<file>:<lines>` support to `search` `paths`, allowing file-scoped constraints such as `:N-M`, `:N+K`, and comma-separated ranges
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
|
|
44
|
+
- Changed multi-section hashline `edit` execution to defer LSP diagnostics flushing until the final section is written
|
|
45
|
+
- Changed read to return verbatim contents for files shorter than `read.summarize.minTotalLines` instead of summarizing them
|
|
46
|
+
- Changed `search` path line-range filtering to include only matches and context lines that fall inside the requested ranges
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
- Fixed multi-section hashline edits to reject duplicate canonical targets and preflight write guards before any section is committed
|
|
51
|
+
|
|
52
|
+
### Fixed
|
|
53
|
+
|
|
54
|
+
- Fixed `createAgentSession()` dropping the hidden `resolve` tool from the registry when no active tool sets `deferrable: true`, even though plan mode dispatches the plan-approval `resolve { action: "apply", ... }` call through a standing handler. Read-only plan-mode toolsets (e.g. `read`, `search`, `find`, `web_search`) silently activated plan mode without `resolve`, leaving the agent unable to submit the finalized plan and forcing the user to exit plan mode manually. `resolve` is now kept whenever `plan.enabled` is true, so the standing handler always has a callable tool ([#1428](https://github.com/can1357/oh-my-pi/issues/1428))
|
|
55
|
+
|
|
56
|
+
### Fixed
|
|
57
|
+
|
|
58
|
+
- Fixed `omp` startup and `/changelog` reading the host project's `CHANGELOG.md` as omp's — `getPackageDir()` no longer falls back to the user's `cwd` when no owning `package.json` is locatable, preventing spurious `lastChangelogVersion` writes ([#1423](https://github.com/can1357/oh-my-pi/issues/1423))
|
|
59
|
+
|
|
5
60
|
## [15.5.3] - 2026-05-27
|
|
6
61
|
### Breaking Changes
|
|
7
62
|
|
|
@@ -2015,6 +2015,33 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
2015
2015
|
readonly description: "Minimum multiline block comment length before read summaries collapse it";
|
|
2016
2016
|
};
|
|
2017
2017
|
};
|
|
2018
|
+
readonly "read.summarize.minTotalLines": {
|
|
2019
|
+
readonly type: "number";
|
|
2020
|
+
readonly default: 100;
|
|
2021
|
+
readonly ui: {
|
|
2022
|
+
readonly tab: "editing";
|
|
2023
|
+
readonly label: "Read Summary Minimum File Length";
|
|
2024
|
+
readonly description: "Files with fewer total lines are read verbatim instead of structurally summarized";
|
|
2025
|
+
};
|
|
2026
|
+
};
|
|
2027
|
+
readonly "read.summarize.unfoldUntil": {
|
|
2028
|
+
readonly type: "number";
|
|
2029
|
+
readonly default: 50;
|
|
2030
|
+
readonly ui: {
|
|
2031
|
+
readonly tab: "editing";
|
|
2032
|
+
readonly label: "Read Summary Unfold Target";
|
|
2033
|
+
readonly description: "BFS-unfold elidable spans until the summary is at least this many visible lines. 0 keeps only the outermost elisions.";
|
|
2034
|
+
};
|
|
2035
|
+
};
|
|
2036
|
+
readonly "read.summarize.unfoldLimit": {
|
|
2037
|
+
readonly type: "number";
|
|
2038
|
+
readonly default: 100;
|
|
2039
|
+
readonly ui: {
|
|
2040
|
+
readonly tab: "editing";
|
|
2041
|
+
readonly label: "Read Summary Unfold Ceiling";
|
|
2042
|
+
readonly description: "Hard ceiling on summary size while BFS-unfolding. An unfold that would exceed this is reverted and unfolding stops.";
|
|
2043
|
+
};
|
|
2044
|
+
};
|
|
2018
2045
|
readonly "read.toolResultPreview": {
|
|
2019
2046
|
readonly type: "boolean";
|
|
2020
2047
|
readonly default: false;
|
package/dist/types/config.d.ts
CHANGED
|
@@ -1,11 +1,37 @@
|
|
|
1
1
|
export * from "./config/config-file";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Walk up from `startDir` looking for a `package.json`. Returns the directory
|
|
4
|
+
* containing the marker, or `undefined` when the walk hits the filesystem root
|
|
5
|
+
* without finding one.
|
|
6
|
+
*
|
|
7
|
+
* Exported for unit-testing the resolution contract from arbitrary start
|
|
8
|
+
* directories (notably the `bun --compile` case where `import.meta.dir`
|
|
9
|
+
* resolves to `/$bunfs/root` and no owning package is locatable — issue
|
|
10
|
+
* #1423). Production callers should use {@link getPackageDir} instead.
|
|
11
|
+
*/
|
|
12
|
+
export declare function walkUpForPackageDir(startDir: string): string | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Get the base directory for resolving optional package assets (docs, examples, CHANGELOG.md).
|
|
15
|
+
*
|
|
16
|
+
* Honors the `PI_PACKAGE_DIR` override (useful for Nix/Guix store paths);
|
|
17
|
+
* otherwise walks up from `import.meta.dir` looking for a `package.json`.
|
|
18
|
+
* Returns `undefined` when no owning package is locatable — notably inside
|
|
19
|
+
* `bun --compile` binaries where `import.meta.dir` resolves to `/$bunfs/root`
|
|
20
|
+
* and the walk hits the filesystem root with nothing found.
|
|
21
|
+
*
|
|
22
|
+
* Callers MUST treat `undefined` as "no package assets available" and skip the
|
|
23
|
+
* lookup. NEVER fall back to the user's `cwd` here: that conflates the host
|
|
24
|
+
* project with omp's own assets and was the source of issue #1423 (the host
|
|
25
|
+
* project's `CHANGELOG.md` rendered as omp's startup changelog).
|
|
26
|
+
*/
|
|
27
|
+
export declare function getPackageDir(): string | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Path to omp's own `CHANGELOG.md`, or `undefined` when the package directory
|
|
30
|
+
* cannot be resolved (e.g. inside `bun --compile` binaries that don't bundle
|
|
31
|
+
* package assets). Callers MUST skip changelog parsing when this is undefined;
|
|
32
|
+
* see issue #1423.
|
|
5
33
|
*/
|
|
6
|
-
export declare function
|
|
7
|
-
/** Get path to CHANGELOG.md (optional, may not exist in binary) */
|
|
8
|
-
export declare function getChangelogPath(): string;
|
|
34
|
+
export declare function getChangelogPath(): string | undefined;
|
|
9
35
|
export interface ConfigDirEntry {
|
|
10
36
|
path: string;
|
|
11
37
|
source: string;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-bound file snapshot store.
|
|
3
|
+
*
|
|
4
|
+
* Used by `read` and `search` to record exactly what the model saw, and by
|
|
5
|
+
* the hashline patcher to recover from stale section hashes (file changed
|
|
6
|
+
* externally between read and edit, or a prior in-session edit advanced
|
|
7
|
+
* the hash). The store is the {@link InMemorySnapshotStore} implementation
|
|
8
|
+
* from `@oh-my-pi/hashline`; the only coding-agent-specific concern here
|
|
9
|
+
* is wiring it onto the per-session {@link ToolSession} object.
|
|
10
|
+
*/
|
|
11
|
+
import { InMemorySnapshotStore } from "@oh-my-pi/hashline";
|
|
12
|
+
import type { ToolSession } from "../tools";
|
|
13
|
+
/**
|
|
14
|
+
* Look up (or lazily create) the file snapshot store attached to a session.
|
|
15
|
+
* Storage lives on `session.fileSnapshotStore` so it ages out exactly with
|
|
16
|
+
* the session itself.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getFileSnapshotStore(session: ToolSession): InMemorySnapshotStore;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-only hashline diff preview helpers used by the streaming edit
|
|
3
|
+
* renderer. Reads the target file, parses + applies the section's edits in
|
|
4
|
+
* memory (no FS write, no LSP writethrough), then hands the before/after
|
|
5
|
+
* pair to {@link generateDiffString} so the renderer can show the diff
|
|
6
|
+
* while the tool call is still streaming.
|
|
7
|
+
*
|
|
8
|
+
* Validation is intentionally light: only the section file hash is checked
|
|
9
|
+
* (so the preview goes red when anchors are stale), no plan-mode guards
|
|
10
|
+
* and no auto-generated-file refusal — those belong on the write path.
|
|
11
|
+
*/
|
|
12
|
+
import { type PatchSection } from "@oh-my-pi/hashline";
|
|
13
|
+
export interface HashlineDiffOptions {
|
|
14
|
+
autoDropPureInsertDuplicates?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Use the streaming-tolerant applier ({@link PatchSection.applyPartialTo})
|
|
17
|
+
* so trailing in-flight ops do not throw or emit phantom edits. Streaming
|
|
18
|
+
* preview path only.
|
|
19
|
+
*/
|
|
20
|
+
streaming?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export declare function computeHashlineSectionDiff(section: PatchSection, cwd: string, options?: HashlineDiffOptions): Promise<{
|
|
23
|
+
diff: string;
|
|
24
|
+
firstChangedLine: number | undefined;
|
|
25
|
+
} | {
|
|
26
|
+
error: string;
|
|
27
|
+
}>;
|
|
28
|
+
export declare function computeHashlineDiff(input: {
|
|
29
|
+
input: string;
|
|
30
|
+
}, cwd: string, options?: HashlineDiffOptions): Promise<{
|
|
31
|
+
diff: string;
|
|
32
|
+
firstChangedLine: number | undefined;
|
|
33
|
+
} | {
|
|
34
|
+
error: string;
|
|
35
|
+
}>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coding-agent runner that drives the hashline {@link Patcher} on behalf of
|
|
3
|
+
* the `edit` tool. Converts a `{input}` tool-call payload into a
|
|
4
|
+
* fully-applied patch, wraps the result in the agent's
|
|
5
|
+
* {@link AgentToolResult} shape, and attaches LSP diagnostics + `outputMeta`
|
|
6
|
+
* for the renderer.
|
|
7
|
+
*
|
|
8
|
+
* Multi-section patches are preflighted up front via {@link Patcher.prepare}
|
|
9
|
+
* so a partial batch never lands; the commit loop then narrows the LSP
|
|
10
|
+
* batch's `flush` flag to true only for the final write so diagnostics
|
|
11
|
+
* round-trip once.
|
|
12
|
+
*/
|
|
13
|
+
import { MismatchError as HashlineMismatchError } from "@oh-my-pi/hashline";
|
|
14
|
+
import type { AgentToolResult } from "@oh-my-pi/pi-agent-core";
|
|
15
|
+
import type { WritethroughCallback, WritethroughDeferredHandle } from "../../lsp";
|
|
16
|
+
import type { ToolSession } from "../../tools";
|
|
17
|
+
import type { EditToolDetails, LspBatchRequest } from "../renderer";
|
|
18
|
+
import { type HashlineParams, hashlineEditParamsSchema } from "./params";
|
|
19
|
+
export interface ExecuteHashlineSingleOptions {
|
|
20
|
+
session: ToolSession;
|
|
21
|
+
input: string;
|
|
22
|
+
signal?: AbortSignal;
|
|
23
|
+
batchRequest?: LspBatchRequest;
|
|
24
|
+
writethrough: WritethroughCallback;
|
|
25
|
+
beginDeferredDiagnosticsForPath: (path: string) => WritethroughDeferredHandle;
|
|
26
|
+
}
|
|
27
|
+
export declare function executeHashlineSingle(options: ExecuteHashlineSingleOptions): Promise<AgentToolResult<EditToolDetails, typeof hashlineEditParamsSchema>>;
|
|
28
|
+
export { HashlineMismatchError, type HashlineParams, hashlineEditParamsSchema };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coding-agent specific {@link Filesystem} adapter for the hashline patcher.
|
|
3
|
+
*
|
|
4
|
+
* Wires hashline's storage abstraction to the agent runtime:
|
|
5
|
+
*
|
|
6
|
+
* - Section paths are resolved through the plan-mode redirect so a bare
|
|
7
|
+
* `PLAN.md` lands at the canonical session artifact location.
|
|
8
|
+
* - Reads go through `readEditFileText` (notebook-aware) and the
|
|
9
|
+
* auto-generated-file guard.
|
|
10
|
+
* - Writes go through `serializeEditFileText` (notebook-aware) and the
|
|
11
|
+
* LSP writethrough, with FS-scan cache invalidation on success. The
|
|
12
|
+
* resulting `FileDiagnosticsResult` is captured per-path so the
|
|
13
|
+
* orchestrator can attach it to the tool result.
|
|
14
|
+
*
|
|
15
|
+
* Construct one per `executeHashlineSingle` call: per-section state
|
|
16
|
+
* (batch request, diagnostics) lives on the instance and isn't safe to
|
|
17
|
+
* share across concurrent edit tools.
|
|
18
|
+
*/
|
|
19
|
+
import { Filesystem, type WriteResult } from "@oh-my-pi/hashline";
|
|
20
|
+
import type { FileDiagnosticsResult, WritethroughCallback, WritethroughDeferredHandle } from "../../lsp";
|
|
21
|
+
import type { ToolSession } from "../../tools";
|
|
22
|
+
import type { LspBatchRequest } from "../renderer";
|
|
23
|
+
export interface HashlineFilesystemOptions {
|
|
24
|
+
session: ToolSession;
|
|
25
|
+
writethrough: WritethroughCallback;
|
|
26
|
+
beginDeferredDiagnosticsForPath: (path: string) => WritethroughDeferredHandle;
|
|
27
|
+
signal?: AbortSignal;
|
|
28
|
+
/**
|
|
29
|
+
* Outer LSP batch request inherited from the tool-call context. The
|
|
30
|
+
* orchestrator narrows this per-section (flush only on the final write)
|
|
31
|
+
* via {@link HashlineFilesystem.setBatchRequest}.
|
|
32
|
+
*/
|
|
33
|
+
batchRequest?: LspBatchRequest;
|
|
34
|
+
}
|
|
35
|
+
export declare class HashlineFilesystem extends Filesystem {
|
|
36
|
+
#private;
|
|
37
|
+
readonly session: ToolSession;
|
|
38
|
+
constructor(options: HashlineFilesystemOptions);
|
|
39
|
+
/**
|
|
40
|
+
* Set the LSP batch request used for the next {@link writeText} call.
|
|
41
|
+
* Multi-section orchestrators flip the `flush` flag to true before the
|
|
42
|
+
* final section so LSP diagnostics flush in one round-trip.
|
|
43
|
+
*/
|
|
44
|
+
setBatchRequest(batchRequest: LspBatchRequest | undefined): void;
|
|
45
|
+
/**
|
|
46
|
+
* Look up (and clear) the diagnostics captured by the most-recent
|
|
47
|
+
* {@link writeText} call for `path`. Returns `undefined` if no write
|
|
48
|
+
* has happened or the writethrough returned no diagnostics.
|
|
49
|
+
*/
|
|
50
|
+
consumeDiagnostics(path: string): FileDiagnosticsResult | undefined;
|
|
51
|
+
resolveAbsolute(relativePath: string): string;
|
|
52
|
+
canonicalPath(relativePath: string): string;
|
|
53
|
+
readText(relativePath: string): Promise<string>;
|
|
54
|
+
preflightWrite(relativePath: string): Promise<void>;
|
|
55
|
+
writeText(relativePath: string, content: string): Promise<WriteResult>;
|
|
56
|
+
exists(relativePath: string): Promise<boolean>;
|
|
57
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schema for the `edit` tool's hashline mode payload. The schema is
|
|
3
|
+
* deliberately permissive (`.passthrough()`) so providers can attach extra
|
|
4
|
+
* keys without rejection; only `input` is required. `_input` is accepted as a
|
|
5
|
+
* provider-emitted alias for `input`.
|
|
6
|
+
*/
|
|
7
|
+
import * as z from "zod/v4";
|
|
8
|
+
export declare const hashlineEditParamsSchema: z.ZodPreprocess<z.ZodObject<{
|
|
9
|
+
input: z.ZodString;
|
|
10
|
+
}, z.core.$loose>>;
|
|
11
|
+
export type HashlineParams = z.infer<typeof hashlineEditParamsSchema>;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
2
|
-
import { type HashlineParams, hashlineEditParamsSchema } from "../hashline";
|
|
3
2
|
import type { ToolSession } from "../tools";
|
|
4
3
|
import { type EditMode } from "../utils/edit-mode";
|
|
4
|
+
import { type HashlineParams, hashlineEditParamsSchema } from "./hashline";
|
|
5
5
|
import { type ApplyPatchParams, applyPatchSchema } from "./modes/apply-patch";
|
|
6
6
|
import { type PatchParams, patchEditSchema } from "./modes/patch";
|
|
7
7
|
import { type ReplaceParams, replaceEditSchema } from "./modes/replace";
|
|
8
8
|
import { type EditToolDetails } from "./renderer";
|
|
9
|
+
export * from "@oh-my-pi/hashline";
|
|
9
10
|
export { DEFAULT_EDIT_MODE, type EditMode, normalizeEditMode } from "../utils/edit-mode";
|
|
10
11
|
export * from "./apply-patch";
|
|
11
12
|
export * from "./diff";
|
|
12
|
-
export * from "./file-
|
|
13
|
-
export * from "
|
|
13
|
+
export * from "./file-snapshot-store";
|
|
14
|
+
export * from "./hashline";
|
|
14
15
|
export * from "./modes/apply-patch";
|
|
15
16
|
export * from "./modes/patch";
|
|
16
17
|
export * from "./modes/replace";
|
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Text normalization utilities for the edit tool.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Whitespace, Unicode, and indentation helpers. Line-ending and BOM
|
|
5
|
+
* primitives live in `@oh-my-pi/hashline` and are re-exported here so
|
|
6
|
+
* existing consumers see one stable surface.
|
|
5
7
|
*/
|
|
6
|
-
export type LineEnding
|
|
7
|
-
/** Detect the predominant line ending in content */
|
|
8
|
-
export declare function detectLineEnding(content: string): LineEnding;
|
|
9
|
-
/** Normalize all line endings to LF */
|
|
10
|
-
export declare function normalizeToLF(text: string): string;
|
|
11
|
-
/** Restore line endings to the specified type */
|
|
12
|
-
export declare function restoreLineEndings(text: string, ending: LineEnding): string;
|
|
13
|
-
export interface BomResult {
|
|
14
|
-
/** The BOM character if present, empty string otherwise */
|
|
15
|
-
bom: string;
|
|
16
|
-
/** The text without the BOM */
|
|
17
|
-
text: string;
|
|
18
|
-
}
|
|
19
|
-
/** Strip UTF-8 BOM if present */
|
|
20
|
-
export declare function stripBom(content: string): BomResult;
|
|
8
|
+
export { type BomResult, detectLineEnding, type LineEnding, normalizeToLF, restoreLineEndings, stripBom, } from "@oh-my-pi/hashline";
|
|
21
9
|
/** Count leading whitespace characters in a line */
|
|
22
10
|
export declare function countLeadingWhitespace(line: string): number;
|
|
23
11
|
/** Get the leading whitespace string from a line */
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compatibility shim for legacy extensions importing the package root of
|
|
3
|
+
* `@oh-my-pi/pi-ai` (or one of its aliased scopes like `@earendil-works/pi-ai`
|
|
4
|
+
* or `@mariozechner/pi-ai`).
|
|
5
|
+
*
|
|
6
|
+
* pi-ai 15.1.0 removed the historical TypeBox root exports (`Type`, plus the
|
|
7
|
+
* runtime-relevant half of the `Static`/`TSchema` pair) from the package
|
|
8
|
+
* entrypoint. Legacy extensions still author parameter schemas as
|
|
9
|
+
* `Type.Object({ ... })`, so this file is served by `legacy-pi-compat.ts` in
|
|
10
|
+
* place of the real pi-ai entrypoint whenever a legacy extension imports the
|
|
11
|
+
* bare package root. Subpath imports (`@oh-my-pi/pi-ai/utils/oauth`, etc.)
|
|
12
|
+
* continue to resolve directly against the bundled pi-ai package.
|
|
13
|
+
*
|
|
14
|
+
* The `Type` runtime is borrowed from the Zod-backed TypeBox shim that
|
|
15
|
+
* already serves bare `@sinclair/typebox` imports for the same extension
|
|
16
|
+
* class, keeping the legacy-compat surface internally consistent.
|
|
17
|
+
*
|
|
18
|
+
* Type-level `Static` and `TSchema` continue to come from pi-ai's own
|
|
19
|
+
* `types.ts` via the `export *` below — pi-ai still exports both as types,
|
|
20
|
+
* only the runtime `Type` builder was removed.
|
|
21
|
+
*/
|
|
22
|
+
export * from "@oh-my-pi/pi-ai";
|
|
23
|
+
export { Type } from "./typebox";
|
package/dist/types/index.d.ts
CHANGED
|
@@ -14,7 +14,6 @@ export type * from "./extensibility/extensions";
|
|
|
14
14
|
export * from "./extensibility/extensions";
|
|
15
15
|
export * from "./extensibility/skills";
|
|
16
16
|
export { type FileSlashCommand, loadSlashCommands as discoverSlashCommands } from "./extensibility/slash-commands";
|
|
17
|
-
export * from "./hashline";
|
|
18
17
|
export type * from "./lsp";
|
|
19
18
|
export * from "./main";
|
|
20
19
|
export * from "./modes";
|
|
@@ -4,12 +4,15 @@ import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
|
4
4
|
import { type Theme } from "../modes/theme/theme";
|
|
5
5
|
import type { ToolSession } from "../sdk";
|
|
6
6
|
import { type OutputMeta } from "./output-meta";
|
|
7
|
+
import { type LineRange } from "./path-utils";
|
|
7
8
|
export declare function isReadableUrlPath(value: string): boolean;
|
|
8
9
|
export interface ParsedReadUrlTarget {
|
|
9
10
|
path: string;
|
|
10
11
|
raw: boolean;
|
|
11
12
|
offset?: number;
|
|
12
13
|
limit?: number;
|
|
14
|
+
/** Populated only when the selector carries 2+ ranges. Single-range stays on offset/limit. */
|
|
15
|
+
ranges?: readonly LineRange[];
|
|
13
16
|
}
|
|
14
17
|
export declare function parseReadUrlTarget(readPath: string): ParsedReadUrlTarget | null;
|
|
15
18
|
interface FetchImagePayload {
|
|
@@ -23,6 +23,13 @@ export type FindToolInput = z.infer<typeof findSchema>;
|
|
|
23
23
|
* must pass through.
|
|
24
24
|
*/
|
|
25
25
|
export declare function validateFindPathInputs(paths: readonly string[]): void;
|
|
26
|
+
/**
|
|
27
|
+
* Group find matches by their directory so the model doesn't pay repeated
|
|
28
|
+
* tokens for shared path prefixes. Preserves the input order: groups appear in
|
|
29
|
+
* the order their first member was emitted (mtime-desc for native glob), and
|
|
30
|
+
* within a group entries keep their relative order.
|
|
31
|
+
*/
|
|
32
|
+
export declare function formatFindGroupedOutput(paths: readonly string[]): string;
|
|
26
33
|
export interface FindToolDetails {
|
|
27
34
|
truncation?: TruncationResult;
|
|
28
35
|
resultLimitReached?: number;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { InMemorySnapshotStore } from "@oh-my-pi/hashline";
|
|
1
2
|
import type { AgentTelemetryConfig, AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
2
3
|
import type { ToolChoice } from "@oh-my-pi/pi-ai";
|
|
3
4
|
import type { PromptTemplate } from "../config/prompt-templates";
|
|
@@ -188,11 +189,11 @@ export interface ToolSession {
|
|
|
188
189
|
getCheckpointState?: () => CheckpointState | undefined;
|
|
189
190
|
/** Set or clear active checkpoint state. */
|
|
190
191
|
setCheckpointState?: (state: CheckpointState | null) => void;
|
|
191
|
-
/** Per-session
|
|
192
|
-
* `read`/`search`. Used by hashline anchor-stale recovery to
|
|
193
|
-
* the version the model authored anchors against when the
|
|
194
|
-
* out-of-band. Lazily initialized by `
|
|
195
|
-
|
|
192
|
+
/** Per-session snapshot store of file contents as last shown to the model
|
|
193
|
+
* by `read`/`search`. Used by hashline anchor-stale recovery to
|
|
194
|
+
* reconstruct the version the model authored anchors against when the
|
|
195
|
+
* file changed out-of-band. Lazily initialized by `getFileSnapshotStore`. */
|
|
196
|
+
fileSnapshotStore?: InMemorySnapshotStore;
|
|
196
197
|
/** Per-session log of unresolved git merge conflict regions surfaced by
|
|
197
198
|
* `read`. Each entry gets a stable id N referenced by `write conflict://N`
|
|
198
199
|
* to splice the recorded region with replacement content. Lazily initialized
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
export declare function expandTilde(filePath: string, home?: string): string;
|
|
2
2
|
export declare function expandPath(filePath: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* Inclusive line range describing one selector segment (e.g. `50-100`,
|
|
5
|
+
* `301-`, or `50+10`). `endLine` is `undefined` for open-ended ranges.
|
|
6
|
+
*/
|
|
7
|
+
export interface LineRange {
|
|
8
|
+
startLine: number;
|
|
9
|
+
endLine: number | undefined;
|
|
10
|
+
}
|
|
11
|
+
/** Parse a single `N`, `N-M`, `N-`, or `N+K` chunk. Throws via {@link ToolError} on invalid bounds. */
|
|
12
|
+
export declare function parseLineRangeChunk(sel: string): LineRange | null;
|
|
13
|
+
/**
|
|
14
|
+
* Parse a comma-separated list of line ranges (e.g. `5-16,960-973`). Returns
|
|
15
|
+
* the ranges in ascending order with overlapping/adjacent ranges merged so
|
|
16
|
+
* downstream consumers can stream the file in a single forward pass per range.
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseLineRanges(sel: string): [LineRange, ...LineRange[]] | null;
|
|
19
|
+
/** Return `true` when `lineNumber` (1-indexed) falls in any of the supplied ranges. */
|
|
20
|
+
export declare function isLineInRanges(lineNumber: number, ranges: readonly LineRange[]): boolean;
|
|
3
21
|
export declare function splitPathAndSel(rawPath: string): {
|
|
4
22
|
path: string;
|
|
5
23
|
sel?: string;
|
|
@@ -5,10 +5,15 @@ export interface ChangelogEntry {
|
|
|
5
5
|
content: string;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
|
-
* Parse changelog entries from
|
|
9
|
-
*
|
|
8
|
+
* Parse changelog entries from the file at `changelogPath`. Scans for `## [x.y.z]`
|
|
9
|
+
* headings and collects each block until the next heading or EOF.
|
|
10
|
+
*
|
|
11
|
+
* Returns `[]` when `changelogPath` is `undefined` (package directory not
|
|
12
|
+
* resolvable — see `getChangelogPath`) or the file is missing. Callers MUST NOT
|
|
13
|
+
* synthesize a fallback path from the host project's cwd; doing so caused issue
|
|
14
|
+
* #1423 (the host project's `CHANGELOG.md` was rendered as omp's).
|
|
10
15
|
*/
|
|
11
|
-
export declare function parseChangelog(changelogPath: string): Promise<ChangelogEntry[]>;
|
|
16
|
+
export declare function parseChangelog(changelogPath: string | undefined): Promise<ChangelogEntry[]>;
|
|
12
17
|
/**
|
|
13
18
|
* Compare versions. Returns: -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2
|
|
14
19
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
4
|
-
"version": "15.5.
|
|
4
|
+
"version": "15.5.6",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -47,12 +47,13 @@
|
|
|
47
47
|
"@agentclientprotocol/sdk": "0.21.0",
|
|
48
48
|
"@babel/parser": "^7.29.3",
|
|
49
49
|
"@mozilla/readability": "^0.6.0",
|
|
50
|
-
"@oh-my-pi/
|
|
51
|
-
"@oh-my-pi/
|
|
52
|
-
"@oh-my-pi/pi-
|
|
53
|
-
"@oh-my-pi/pi-
|
|
54
|
-
"@oh-my-pi/pi-
|
|
55
|
-
"@oh-my-pi/pi-
|
|
50
|
+
"@oh-my-pi/hashline": "15.5.6",
|
|
51
|
+
"@oh-my-pi/omp-stats": "15.5.6",
|
|
52
|
+
"@oh-my-pi/pi-agent-core": "15.5.6",
|
|
53
|
+
"@oh-my-pi/pi-ai": "15.5.6",
|
|
54
|
+
"@oh-my-pi/pi-natives": "15.5.6",
|
|
55
|
+
"@oh-my-pi/pi-tui": "15.5.6",
|
|
56
|
+
"@oh-my-pi/pi-utils": "15.5.6",
|
|
56
57
|
"@puppeteer/browsers": "^2.13.0",
|
|
57
58
|
"@types/turndown": "5.0.6",
|
|
58
59
|
"@xterm/headless": "^6.0.0",
|
|
@@ -227,14 +228,6 @@
|
|
|
227
228
|
"types": "./dist/types/edit/modes/*.d.ts",
|
|
228
229
|
"import": "./src/edit/modes/*.ts"
|
|
229
230
|
},
|
|
230
|
-
"./hashline": {
|
|
231
|
-
"types": "./dist/types/hashline/index.d.ts",
|
|
232
|
-
"import": "./src/hashline/index.ts"
|
|
233
|
-
},
|
|
234
|
-
"./hashline/*": {
|
|
235
|
-
"types": "./dist/types/hashline/*.d.ts",
|
|
236
|
-
"import": "./src/hashline/*.ts"
|
|
237
|
-
},
|
|
238
231
|
"./exa": {
|
|
239
232
|
"types": "./dist/types/exa/index.d.ts",
|
|
240
233
|
"import": "./src/exa/index.ts"
|
package/scripts/build-binary.ts
CHANGED
|
@@ -56,6 +56,17 @@ async function main(): Promise<void> {
|
|
|
56
56
|
"../stats/src/sync-worker.ts",
|
|
57
57
|
"./src/tools/browser/tab-worker-entry.ts",
|
|
58
58
|
"./src/eval/js/worker-entry.ts",
|
|
59
|
+
// Legacy pi-* extension compat shims served by `legacy-pi-compat.ts`.
|
|
60
|
+
// Both are reached only via the computed `TYPEBOX_SHIM_PATH` /
|
|
61
|
+
// `LEGACY_PI_AI_SHIM_PATH` constants (which `--compile`'s static
|
|
62
|
+
// analyzer cannot trace), so each shim must be listed here to land
|
|
63
|
+
// in bunfs alongside the workers above. The bunfs entry path is
|
|
64
|
+
// `--root`-relative with a `.js` extension, e.g.
|
|
65
|
+
// `/$bunfs/root/packages/coding-agent/src/extensibility/typebox.js`,
|
|
66
|
+
// which is what the `isCompiledBinary()` branch in
|
|
67
|
+
// `legacy-pi-compat.ts` resolves to at runtime.
|
|
68
|
+
"./src/extensibility/typebox.ts",
|
|
69
|
+
"./src/extensibility/legacy-pi-ai-shim.ts",
|
|
59
70
|
"--outfile",
|
|
60
71
|
"dist/omp",
|
|
61
72
|
],
|
|
@@ -1666,6 +1666,38 @@ export const SETTINGS_SCHEMA = {
|
|
|
1666
1666
|
},
|
|
1667
1667
|
},
|
|
1668
1668
|
|
|
1669
|
+
"read.summarize.minTotalLines": {
|
|
1670
|
+
type: "number",
|
|
1671
|
+
default: 100,
|
|
1672
|
+
ui: {
|
|
1673
|
+
tab: "editing",
|
|
1674
|
+
label: "Read Summary Minimum File Length",
|
|
1675
|
+
description: "Files with fewer total lines are read verbatim instead of structurally summarized",
|
|
1676
|
+
},
|
|
1677
|
+
},
|
|
1678
|
+
|
|
1679
|
+
"read.summarize.unfoldUntil": {
|
|
1680
|
+
type: "number",
|
|
1681
|
+
default: 50,
|
|
1682
|
+
ui: {
|
|
1683
|
+
tab: "editing",
|
|
1684
|
+
label: "Read Summary Unfold Target",
|
|
1685
|
+
description:
|
|
1686
|
+
"BFS-unfold elidable spans until the summary is at least this many visible lines. 0 keeps only the outermost elisions.",
|
|
1687
|
+
},
|
|
1688
|
+
},
|
|
1689
|
+
|
|
1690
|
+
"read.summarize.unfoldLimit": {
|
|
1691
|
+
type: "number",
|
|
1692
|
+
default: 100,
|
|
1693
|
+
ui: {
|
|
1694
|
+
tab: "editing",
|
|
1695
|
+
label: "Read Summary Unfold Ceiling",
|
|
1696
|
+
description:
|
|
1697
|
+
"Hard ceiling on summary size while BFS-unfolding. An unfold that would exceed this is reverted and unfolding stops.",
|
|
1698
|
+
},
|
|
1699
|
+
},
|
|
1700
|
+
|
|
1669
1701
|
"read.toolResultPreview": {
|
|
1670
1702
|
type: "boolean",
|
|
1671
1703
|
default: false,
|