@oh-my-pi/pi-ai 17.1.8 → 17.2.1
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 +66 -0
- package/dist/types/auth-broker/server.d.ts +5 -0
- package/dist/types/auth-broker/types.d.ts +4 -0
- package/dist/types/auth-storage.d.ts +38 -1
- package/dist/types/error/classes.d.ts +5 -1
- package/dist/types/error/rate-limit.d.ts +5 -4
- package/dist/types/providers/anthropic-client.d.ts +13 -1
- package/dist/types/providers/anthropic.d.ts +17 -11
- package/dist/types/providers/claude-code-fingerprint.d.ts +12 -8
- package/dist/types/providers/cowork-fetch.d.ts +3 -0
- package/dist/types/providers/cursor/exec-modern.d.ts +98 -0
- package/dist/types/providers/cursor-pi-args.d.ts +99 -0
- package/dist/types/providers/cursor.d.ts +53 -3
- package/dist/types/providers/error-message.d.ts +2 -4
- package/dist/types/providers/openai-codex-responses.d.ts +10 -0
- package/dist/types/providers/openai-responses-wire.d.ts +8 -0
- package/dist/types/providers/openai-shared.d.ts +13 -1
- package/dist/types/registry/exa.d.ts +8 -0
- package/dist/types/registry/registry.d.ts +7 -1
- package/dist/types/registry/xai.d.ts +4 -1
- package/dist/types/stream.d.ts +2 -0
- package/dist/types/types.d.ts +101 -1
- package/dist/types/usage/umans.d.ts +2 -0
- package/dist/types/utils/block-symbols.d.ts +11 -0
- package/dist/types/utils/harmony-leak.d.ts +15 -7
- package/dist/types/utils/proxy.d.ts +2 -0
- package/dist/types/utils/schema/normalize.d.ts +1 -0
- package/package.json +4 -4
- package/src/auth-broker/client.ts +5 -1
- package/src/auth-broker/server.ts +103 -9
- package/src/auth-broker/snapshot-cache.ts +12 -3
- package/src/auth-broker/types.ts +6 -0
- package/src/auth-storage.ts +466 -28
- package/src/error/classes.ts +98 -3
- package/src/error/flags.ts +6 -1
- package/src/error/rate-limit.ts +18 -12
- package/src/providers/amazon-bedrock.ts +3 -3
- package/src/providers/anthropic-client.ts +24 -2
- package/src/providers/anthropic.ts +80 -75
- package/src/providers/claude-code-fingerprint.ts +12 -11
- package/src/providers/cowork-fetch.ts +201 -0
- package/src/providers/cursor/exec-modern.ts +495 -0
- package/src/providers/cursor/proto/agent.proto +1007 -0
- package/src/providers/cursor-pi-args.ts +135 -0
- package/src/providers/cursor.ts +1138 -66
- package/src/providers/devin.ts +2 -1
- package/src/providers/error-message.ts +3 -1
- package/src/providers/openai-codex-responses.ts +106 -26
- package/src/providers/openai-completions.ts +19 -4
- package/src/providers/openai-responses-wire.ts +8 -0
- package/src/providers/openai-responses.ts +12 -1
- package/src/providers/openai-shared.ts +75 -12
- package/src/registry/api-key-validation.ts +18 -34
- package/src/registry/exa.ts +19 -0
- package/src/registry/novita.ts +6 -3
- package/src/registry/registry.ts +3 -1
- package/src/registry/xai.ts +17 -1
- package/src/stream.ts +13 -6
- package/src/types.ts +115 -0
- package/src/usage/umans.ts +192 -0
- package/src/utils/block-symbols.ts +12 -0
- package/src/utils/harmony-leak.ts +32 -0
- package/src/utils/idle-iterator.ts +2 -2
- package/src/utils/proxy.ts +6 -2
- package/src/utils/schema/normalize.ts +140 -38
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,72 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [17.2.1] - 2026-07-30
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added exact OAuth credential-row resolution by durable credential id. The targeted path refreshes only that row and never ranks, rotates, or falls back to sibling accounts.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Anthropic OAuth requests now reproduce Cowork's current `claude-desktop` request profile, including client/runtime metadata, beta selection, system and billing attestation, the 64K output cap, and stable HTTP/1.1 header ordering.
|
|
14
|
+
|
|
15
|
+
## [17.2.0] - 2026-07-30
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- Added first-class parentTurnId support for nested Codex requests, allowing stream options and metadata helpers to accept and safely propagate the initiating turn's ID.
|
|
20
|
+
- Added preservation of the Codex `encrypted_function_args` plaintext-collaboration marker on replayed function calls, keeping server-marked plaintext tool arguments from being reinterpreted as encrypted on subsequent turns.
|
|
21
|
+
- Added interactive Exa API-key login through `/login exa`, opening the official API-key dashboard and saving pasted keys to the credential store ([#1798](https://github.com/can1357/oh-my-pi/issues/1798)).
|
|
22
|
+
- Cursor's modern exec wire protocol is now handled end to end. `agent.proto` models the frames current Cursor CLI builds emit — the seven Pi tools (`ExecServerMessage` 45-51), hooks, subagents, allowlist prechecks, MCP state, smart-mode classification, canvas diagnostics, conversation search, agent-store conflicts and git diff — and every one of them gets a typed answer. The Pi frames run their local equivalents (`read`/`bash`/`edit`/`write`/`grep`/`glob`); the rest answer with the error, not-found or empty-but-valid variant that is actually true of this client. Frames this build cannot name at all now raise `ExecClientControlMessage.throw` with `unknown_exec_variant`, and recognised frames with no truthful answer (`git_diff_request`, whose `GetDiffResponse` has no error variant) raise `exec_variant_unsupported`, instead of a silent ack that leaves the server waiting.
|
|
23
|
+
- `lsp` is advertised in the MCP tool catalog again. It was filtered out as a Cursor-native tool, but the native `diagnostics` frame covers one of roughly ten LSP actions, so the other nine were unreachable.
|
|
24
|
+
- Added `pinSessionOAuthAccount` support for backdating the sticky's last-use timestamp (`options.lastUsedAtMs`), so pins restored from persisted sessions keep the provider's warm-window semantics: resumes inside the prompt-cache TTL reuse the account, stale resumes still re-rank.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- Codex turn metadata now reserves the codex-rs `code_mode_tool_names` key, preventing caller-supplied client metadata extras from colliding with the core-owned field.
|
|
29
|
+
- Codex SSE requests to the official endpoint now use zstd-compressed bodies by default to match the official client, which can be disabled with PI_CODEX_ZSTD=0.
|
|
30
|
+
- API-key validation now preserves provider HTTP status and retry headers, allowing authentication, rate-limit, and server failures to retain their original error classifications.
|
|
31
|
+
- The Cursor Pi arg translation (`piReadPath`, `piJoinPath`, `piLsPath`, `piEscapeRegexLiteral`, `piLimit`) moved to `providers/cursor-pi-args`, re-exported from `providers/cursor/exec-modern` so existing imports are unaffected. The legacy pi shim shares these helpers and is compiled into the bundled virtual module registry, where a nested `providers/<dir>/<mod>` specifier is unresolvable under bunfs — and importing them from the exec module would drag the whole protobuf graph in for two string functions.
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- Fixed Novita login rejecting valid API keys belonging to Developer and Basic team members by validating against the chat completions endpoint instead of the billing balance endpoint.
|
|
36
|
+
- Fixed Cursor resource_exhausted errors being incorrectly classified as QUOTA_EXHAUSTED (which caused 30-minute credential blocks), mapping them to MODEL_CAPACITY_EXHAUSTED with a shorter backoff instead.
|
|
37
|
+
- Fixed a crash in Amazon Bedrock and Devin providers when Context.systemPrompt is passed as a bare string.
|
|
38
|
+
- Fixed aborted usage-limit recovery incorrectly blocking credentials or waiting on local usage fetches after the session had already changed.
|
|
39
|
+
- Fixed Codex WebSocket sessions echoing stale or missing turn states by capturing x-codex-turn-state refreshes from response metadata event headers.
|
|
40
|
+
- Fixed Harmony-dialect models (e.g., gpt-5.x, openai-codex) failing with invalid_prompt or "Request blocked" errors by escaping reserved control tokens in untrusted user and tool-result text.
|
|
41
|
+
- Fixed named forced tool_choice not being enforced on string-only OpenAI-compatible hosts (such as llama.cpp and LM Studio) by narrowing the advertised tools to the forced tool.
|
|
42
|
+
- Fixed direct Anthropic Claude Opus requests failing with HTTP 400 when the endpoint rejects strict tool fields.
|
|
43
|
+
- Fixed usage-based credential ranking for Anthropic accounts where a missing long-window (7-day) metric was incorrectly treated as a short-window metric.
|
|
44
|
+
- Fixed legacy Codex usage blocks continuing to gate all models after per-meter backoff was introduced, splitting the old shared scope into independent chat and spark blocks while maintaining backward compatibility with older clients and database schemas.
|
|
45
|
+
- Fixed Anthropic retry loops ignoring `maxRetryDelayMs` for long server `retry-after` hints, so over-budget delays surface immediately without losing response details or abort cleanup ([#7003](https://github.com/can1357/oh-my-pi/issues/7003)).
|
|
46
|
+
- Added interactive xAI API-key login with key validation through the xAI models endpoint.
|
|
47
|
+
- Fixed Google Gemini and Vertex tool declarations carrying numeric, boolean, object-valued, or mixed `enum` arrays that the Google Schema wire type cannot represent. Unsupported enums are omitted while valid string enums remain constrained.
|
|
48
|
+
- Umans usage provider: fetches `GET /v1/usage` and surfaces the rolling 5h request window + concurrency limits in `/usage`, `omp usage`, and the TUI status bar.
|
|
49
|
+
- Fixed ranged legacy Cursor reads reporting the returned window byte length as the full file size.
|
|
50
|
+
- Updated the Cursor client build advertisement to activate the modern exec-frame protocol handled by this provider.
|
|
51
|
+
- Fixed a windowed Cursor `read` reporting the window's line count as the file's. `total_lines` and `file_size` were derived from the payload, which is the whole file only for an unranged read — a 20-line page of a 100-line file answered `total_lines: 20`, which a paginating server reads as the end of the file. The count now comes from the read's own record of the file (`details.meta.truncation.totalLines`), falling back to counting the payload when the read returned the file whole.
|
|
52
|
+
- Fixed a `pi_grep` that hit the native backend's internal match ceiling answering as an unqualified success. `GrepTool` folds that cap into the flat `details.truncated` alone, setting neither `details.truncation` nor `perFileLimitReached` — the two fields the Pi result was built from — so the one truncation a caller can neither detect nor page around was the one it was never told about. The flat flag is now translated into a `PiTruncation`, and only when no specific cap already reported itself.
|
|
53
|
+
- Fixed a `pi_grep` frame's `context` and `limit` vanishing from the transcript. The bridge honors both by building a scoped `grep`, but neither is expressible in the model-facing schema, so the synthesized block recorded a plain pattern/path search — replaying a context-widened or capped search as an ordinary grep sitting beside output no ordinary grep produces. Both are now recorded on the block.
|
|
54
|
+
- Fixed a Cursor MCP resource listing shrinking to a count in the transcript. The full URI/name/mime catalog goes out on the wire, but the paired local result recorded `Listed N MCP resource(s)` — and rebuilt history is serialized from that result, so one reload later the model knew it had seen N resources and could name none of them. The paired result now lists what the answer carried.
|
|
55
|
+
- Fixed the `pi_read` range translation padding the slice it asks for. `piReadPath` composed a plain `:N+K` selector, which the local `read` tool expands by one leading and three trailing context line — so a frame naming offset 5/limit 20 received lines 4-27. Ranged Pi reads now compose `:raw:N+K`; the wire result is an opaque output string, so the line-number gutter `raw` also drops carries nothing the contract needs.
|
|
56
|
+
- Fixed four Cursor exec frames answering with a result whose oneof was never set. In proto3 that is not an empty result — the server reads it as "the tool ran and produced nothing", indistinguishable from real success. `listMcpResourcesExecResult`, `readMcpResourceExecResult`, `recordScreenResult` and `computerUseResult` now send `ListMcpResourcesSuccess{resources: []}`, `ReadMcpResourceNotFound{uri}`, `RecordScreenFailure` and `ComputerUseError` respectively.
|
|
57
|
+
- The MCP resource frames now answer from the host instead of a fixed verdict. `CursorExecHandlers` gained `listMcpResources`/`readMcpResource`, so a host holding live MCP connections advertises them; the empty catalog and `not_found` above remain the answer when no handler is supplied. A handler that throws surfaces as `ListMcpResourcesError`/`ReadMcpResourceError` rather than collapsing into "none exist", which the model cannot retry. A read carrying `download_path` forwards it and answers with `ReadMcpResourceSuccess.download_path` and no content, which is what that mode means.
|
|
58
|
+
- Fixed Cursor `connect_scm` calls losing their repository and settling on a fabricated verdict. The target rides in the `ConnectScmArgs.target` oneof, so reading a flat `github` property always saw `undefined`; and the authoritative `success`/`error`/`rejected` result only arrives on the completion frame, so answering at the announcement persisted a fixed failure for every call — including the ones the server went on to accept. The block now opens on the start frame and settles from the completion's decoded result.
|
|
59
|
+
- Fixed interleaved Cursor tool calls corrupting each other. The stream decoder tracked a single "current" block and settled it on any `toolCallCompleted`, ignoring the envelope's `call_id`: a completion for one call closed whichever block happened to be open and paired it with the wrong result, and `start A, start B` orphaned A entirely so its own completion settled B while A was never paired — which strips the whole interaction from every rebuilt transcript. Open blocks are now retained per envelope `call_id`, and end-of-stream closes all of them rather than only the last.
|
|
60
|
+
- Fixed a Cursor `search_conversations` call leaving no transcript block. The frame is answered from a fixed verdict, so nothing downstream pairs a result for it, and an unpaired call takes its whole interaction out of every rebuilt transcript.
|
|
61
|
+
- Fixed a Cursor `read_mcp_resource` call leaving no transcript block. The frame runs locally — and in download mode writes a workspace file — but synthesized no tool call and paired no result, so the read was invisible in the UI and absent from every rebuilt history; a resource download could mutate the workspace with nothing on record. The frame now synthesizes a `read_mcp_resource` block (not `read`: it is a remote MCP operation, and the name drives rendering and prune semantics) and pairs a result on success, not-found and error alike. Frames answered without a handler still synthesize nothing, since nothing ran.
|
|
62
|
+
- Fixed a Cursor `list_mcp_resources` call leaving no transcript block. The model consumed the catalog, but the frame synthesized no tool call and paired no result — its streamed `ListMcpResourcesToolCall` announcement was equally unrecognized — so the listing was invisible in the UI and absent from every rebuilt history. Frames a handler answered now synthesize a `list_mcp_resources` block and pair a result derived from the same answer that went on the wire; frames answered from the fixed no-handler catalog still synthesize nothing, since nothing ran.
|
|
63
|
+
- Fixed an unavailable `pi_edit`/`pi_write` answering with the error variant. Both results model refusal and failure as separate oneof cases, and a denial reported as `error` reads as "the tool ran and broke" — inviting a retry of an operation that was never permitted. A frame whose tool is not granted, or whose handler produced nothing, now answers with `PiEditExecRejected`/`PiWriteExecRejected`; execution failures keep the error variant.
|
|
64
|
+
- Fixed a Cursor MCP approval probe actually running the tool. A modern `mcpArgs` frame carrying `smart_mode_approval_only` asks only whether a call would be permitted, not for the call itself. The decoder dropped the flag, so the frame ran a side-effecting MCP tool the user had not been asked about, then ran it again when the real call followed. The flag is now carried through and the probe is answered from the host's policy without executing: approved only for a definite allow, refused for a deny, for a mode that demands a prompt the frame cannot raise, and for a tool the session does not have. No transcript block is synthesized either, since nothing ran.
|
|
65
|
+
- Fixed the Cursor stream's end-of-transport cleanup erasing the arguments of every block still open. Blocks whose args arrive whole (todo, connect-SCM, MCP) never feed the streamed partial-JSON buffer, and reparsing an absent buffer yields `{}`, so a truncated or disconnected turn rebuilt those calls with no arguments at all. Only blocks that actually streamed their args are reparsed now.
|
|
66
|
+
- Fixed a Cursor stream dying mid-turn stranding the call it left open. `connect_scm` and native todo blocks are stamped resolved the moment they open, so the agent loop synthesizes no placeholder and only their completion frame pairs a result — a transport that closed first left the card animating and the call unpaired, which takes the whole interaction out of every rebuilt transcript. The terminal-error path now closes open blocks and pairs those server-owned calls with an interrupted result; the flush ran only on clean completion before, which is not the path a dying stream takes. Exec-settled MCP blocks are left alone, since the dispatch that ran them owns their result.
|
|
67
|
+
- Fixed the Pi exec frames displaying a different operation than the one they run. The provider synthesized its transcript block from a second, hand-rolled translation of the frame args, so `pi_read`'s `offset`/`limit` were shown as a whole-file read, `pi_grep`'s `literal` pattern as an unescaped regex, and `pi_find`'s path/glob join differed from the executed one. Both sides now share a single translation.
|
|
68
|
+
- Fixed the streamed `pi_*_tool_call` announcements that modern builds send alongside each exec frame being unrecognized. The exec channel already synthesizes those blocks when it runs the tool; the duplicate was avoided only because the decoder recognized none of the variants, which would have started double-rendering as soon as any one was added.
|
|
69
|
+
- Fixed `pi_bash` results reaching Cursor clipped with no truncation notice. Two truncation records exist locally: `read`/`grep` set `details.truncation`, which carries an explicit `truncated` flag, while `bash` sets `details.meta.truncation`, whose record has no such flag — its presence is the signal. `piTruncation` read only the first shape and required the flag, so every real Bash truncation was dropped and the server was told the clipped output was complete. Both shapes now translate, and an explicit `truncated: false` still suppresses the field.
|
|
70
|
+
|
|
5
71
|
## [17.1.8] - 2026-07-28
|
|
6
72
|
|
|
7
73
|
### Fixed
|
|
@@ -20,6 +20,11 @@ export interface AuthBrokerServerOptions {
|
|
|
20
20
|
* without long sleeps. Default {@link DEFAULT_STREAM_KEEPALIVE_MS}.
|
|
21
21
|
*/
|
|
22
22
|
streamKeepaliveMs?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Override cross-process SQLite change polling in milliseconds.
|
|
25
|
+
* Internal-only — tests use a short interval. Default 250ms.
|
|
26
|
+
*/
|
|
27
|
+
externalChangePollMs?: number;
|
|
23
28
|
}
|
|
24
29
|
export interface AuthBrokerServerHandle {
|
|
25
30
|
/** Bound URL (`http://host:port`). */
|
|
@@ -131,6 +131,10 @@ export type SnapshotStreamEvent = SnapshotStreamSnapshotEvent | SnapshotStreamEn
|
|
|
131
131
|
* unauthenticated for liveness probes; everything else requires a bearer.
|
|
132
132
|
*/
|
|
133
133
|
export declare const AUTH_BROKER_API_PREFIX = "/v1";
|
|
134
|
+
/** Request header used by clients to advertise optional auth-broker protocol features. */
|
|
135
|
+
export declare const AUTH_BROKER_CAPABILITIES_HEADER = "OMP-Auth-Broker-Capabilities";
|
|
136
|
+
/** Client understands independent Codex `chat` and `spark` credential-block scopes. */
|
|
137
|
+
export declare const AUTH_BROKER_CAPABILITY_CODEX_METER_BLOCK_SCOPES = "codex-meter-block-scopes";
|
|
134
138
|
/** Default port when none is configured. Loopback-only, no external exposure. */
|
|
135
139
|
export declare const DEFAULT_AUTH_BROKER_BIND = "127.0.0.1:8765";
|
|
136
140
|
/** Default broker→provider refresh skew. Refresh credentials this close to expiry. */
|
|
@@ -257,6 +257,13 @@ export interface CredentialRefreshLeaseFence {
|
|
|
257
257
|
}
|
|
258
258
|
export interface AuthCredentialStore {
|
|
259
259
|
close(): void;
|
|
260
|
+
/**
|
|
261
|
+
* Stateful probe for commits made by another process to the backing store.
|
|
262
|
+
* Returns true once per observed change.
|
|
263
|
+
*/
|
|
264
|
+
pollExternalChanges?(): boolean;
|
|
265
|
+
/** Record the current auth revision after a local mutation already notified consumers. */
|
|
266
|
+
acknowledgeLocalChanges?(): void;
|
|
260
267
|
/** Optional hook to notify the underlying store that usage report cache is stale. */
|
|
261
268
|
invalidateUsageCache?(signal?: AbortSignal): Promise<void>;
|
|
262
269
|
listAuthCredentials(provider?: string): StoredAuthCredential[];
|
|
@@ -711,6 +718,11 @@ export declare class AuthStorage {
|
|
|
711
718
|
*/
|
|
712
719
|
close(): void;
|
|
713
720
|
getGeneration(): number;
|
|
721
|
+
/**
|
|
722
|
+
* Reload state after another process commits to the backing store, then
|
|
723
|
+
* notify snapshot consumers even when only credential blocks changed.
|
|
724
|
+
*/
|
|
725
|
+
pollExternalChanges(): Promise<boolean>;
|
|
714
726
|
onGenerationChanged(listener: (generation: number) => void): () => void;
|
|
715
727
|
offGenerationChanged(listener: (generation: number) => void): void;
|
|
716
728
|
/**
|
|
@@ -1041,8 +1053,15 @@ export declare class AuthStorage {
|
|
|
1041
1053
|
* The durable credential id keeps the pin stable across credential refreshes,
|
|
1042
1054
|
* storage reordering, and process restarts. Normal auth retry and usage-limit
|
|
1043
1055
|
* handling may still route around an unavailable account.
|
|
1056
|
+
*
|
|
1057
|
+
* `options.lastUsedAtMs` backdates the sticky's last-use timestamp so a pin
|
|
1058
|
+
* restored from a persisted session keeps the provider's warm-window
|
|
1059
|
+
* semantics: a resume inside the prompt-cache TTL reuses the account, a
|
|
1060
|
+
* stale resume still re-ranks.
|
|
1044
1061
|
*/
|
|
1045
|
-
pinSessionOAuthAccount(provider: string, sessionId: string, credentialId: number
|
|
1062
|
+
pinSessionOAuthAccount(provider: string, sessionId: string, credentialId: number, options?: {
|
|
1063
|
+
lastUsedAtMs?: number;
|
|
1064
|
+
}): boolean;
|
|
1046
1065
|
/**
|
|
1047
1066
|
* Resolve every stored OAuth credential for `provider` independently.
|
|
1048
1067
|
*
|
|
@@ -1064,6 +1083,18 @@ export declare class AuthStorage {
|
|
|
1064
1083
|
* overrides have replaced OAuth with an explicit API key.
|
|
1065
1084
|
*/
|
|
1066
1085
|
getOAuthAccessAt(provider: string, position: number, options?: AuthApiKeyOptions): Promise<OAuthAccessResolution | undefined>;
|
|
1086
|
+
/**
|
|
1087
|
+
* Resolve one stored OAuth credential by its durable storage row id.
|
|
1088
|
+
*
|
|
1089
|
+
* Unlike the normal session resolver, this method never ranks, rotates, or
|
|
1090
|
+
* falls back to sibling credentials. A forced refresh re-mints only the
|
|
1091
|
+
* requested row, preserving exact-account affinity for operations whose
|
|
1092
|
+
* provenance and policy boundary are tied to one workspace.
|
|
1093
|
+
*
|
|
1094
|
+
* Returns `undefined` when the row does not exist for `provider` or an
|
|
1095
|
+
* explicit runtime/config API-key override suppresses OAuth.
|
|
1096
|
+
*/
|
|
1097
|
+
getOAuthAccessByCredentialId(provider: string, credentialId: number, options?: AuthApiKeyOptions): Promise<OAuthAccessResolution | undefined>;
|
|
1067
1098
|
/**
|
|
1068
1099
|
* List saved rate-limit resets for every stored OAuth account of `provider`
|
|
1069
1100
|
* (Codex), fetched LIVE from the dedicated `rate-limit-reset-credits` route.
|
|
@@ -1314,5 +1345,11 @@ export declare class SqliteAuthCredentialStore implements AuthCredentialStore {
|
|
|
1314
1345
|
* Delete all credentials for a provider.
|
|
1315
1346
|
*/
|
|
1316
1347
|
deleteProvider(provider: string): void;
|
|
1348
|
+
/**
|
|
1349
|
+
* SQLite increments `data_version` when another connection commits. Own
|
|
1350
|
+
* writes leave it unchanged and already notify AuthStorage directly.
|
|
1351
|
+
*/
|
|
1352
|
+
pollExternalChanges(): boolean;
|
|
1353
|
+
acknowledgeLocalChanges(): void;
|
|
1317
1354
|
close(): void;
|
|
1318
1355
|
}
|
|
@@ -31,12 +31,16 @@ export declare class OpenAIHttpError extends ProviderHttpError {
|
|
|
31
31
|
code: string | undefined;
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
|
+
/** Test-only control for the otherwise bounded Anthropic error-body drain. */
|
|
35
|
+
export declare const __anthropicApiErrorForTesting: {
|
|
36
|
+
setBodyReadTimeoutMs(timeoutMs: number | undefined): void;
|
|
37
|
+
};
|
|
34
38
|
/** Non-2xx response from the Anthropic API. */
|
|
35
39
|
export declare class AnthropicApiError extends ProviderHttpError {
|
|
36
40
|
readonly headers: Headers;
|
|
37
41
|
readonly requestId: string | null;
|
|
38
42
|
constructor(status: number, message: string, headers: Headers);
|
|
39
|
-
static fromResponse(response: Response): Promise<AnthropicApiError>;
|
|
43
|
+
static fromResponse(response: Response, signal?: AbortSignal): Promise<AnthropicApiError>;
|
|
40
44
|
}
|
|
41
45
|
/** Network-level failure (DNS, TLS, socket reset) after retries were exhausted. */
|
|
42
46
|
export declare class AnthropicConnectionError extends Error {
|
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
export type RateLimitReason = "QUOTA_EXHAUSTED" | "RATE_LIMIT_EXCEEDED" | "MODEL_CAPACITY_EXHAUSTED" | "SERVER_ERROR" | "UNKNOWN";
|
|
6
6
|
/**
|
|
7
7
|
* Classify a rate-limit error message into a reason category.
|
|
8
|
-
* Priority order:
|
|
9
|
-
*
|
|
8
|
+
* Priority order: explicit details in a resource-exhausted error > QUOTA
|
|
9
|
+
* (Antigravity "quota will reset") > MODEL_CAPACITY > QUOTA (account) >
|
|
10
|
+
* RATE_LIMIT > QUOTA (generic) > SERVER_ERROR > bare resource-exhausted > UNKNOWN.
|
|
10
11
|
*
|
|
11
|
-
* "resource exhausted" maps to MODEL_CAPACITY (transient, short wait)
|
|
12
|
-
*
|
|
12
|
+
* Bare "resource exhausted" / "resource_exhausted" maps to MODEL_CAPACITY (transient, short wait).
|
|
13
|
+
* Explicit details such as "quota exceeded" retain their normal classification.
|
|
13
14
|
*/
|
|
14
15
|
export declare function parseRateLimitReason(errorMessage: string): RateLimitReason;
|
|
15
16
|
/**
|
|
@@ -9,6 +9,12 @@ export interface AnthropicRequestOptions {
|
|
|
9
9
|
timeout?: number;
|
|
10
10
|
/** Per-request retry budget override. */
|
|
11
11
|
maxRetries?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Maximum delay in milliseconds to wait for a server-directed retry. If the
|
|
14
|
+
* server's `retry-after` hint exceeds this value, the retry is declined and
|
|
15
|
+
* the original error is surfaced. Non-positive values disable the cap. Defaults to 60000.
|
|
16
|
+
*/
|
|
17
|
+
maxRetryDelayMs?: number;
|
|
12
18
|
/** Per-request headers merged after client defaults. */
|
|
13
19
|
headers?: Record<string, string>;
|
|
14
20
|
}
|
|
@@ -38,6 +44,12 @@ export interface AnthropicClientOptions {
|
|
|
38
44
|
authToken?: string | null;
|
|
39
45
|
baseURL?: string | null;
|
|
40
46
|
maxRetries?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Maximum delay in milliseconds to wait for a server-directed retry. If the
|
|
49
|
+
* server's `retry-after` hint exceeds this value, the retry is declined and
|
|
50
|
+
* the original error is surfaced. Non-positive values disable the cap. Defaults to 60000.
|
|
51
|
+
*/
|
|
52
|
+
maxRetryDelayMs?: number;
|
|
41
53
|
/** Pre-response timeout in milliseconds. Defaults to 10 minutes. */
|
|
42
54
|
timeout?: number;
|
|
43
55
|
defaultHeaders?: Record<string, string>;
|
|
@@ -45,7 +57,7 @@ export interface AnthropicClientOptions {
|
|
|
45
57
|
fetchOptions?: AnthropicFetchOptions;
|
|
46
58
|
}
|
|
47
59
|
/** Server-suggested delay (`retry-after-ms`, then `retry-after` seconds or HTTP date). */
|
|
48
|
-
export declare function retryDelayFromHeaders(headers: Headers | undefined): number | undefined;
|
|
60
|
+
export declare function retryDelayFromHeaders(headers: Pick<Headers, "get"> | undefined): number | undefined;
|
|
49
61
|
export declare function calculateAnthropicRetryDelayMs(attempt: number): number;
|
|
50
62
|
/**
|
|
51
63
|
* Lazy in-flight request handle. The HTTP request starts on the first
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FetchImpl, Message, Model, ProviderSessionState, ServiceTier, SimpleStreamOptions, StreamFunction, StreamOptions, Usage } from "../types.js";
|
|
1
|
+
import type { Api, FetchImpl, Message, Model, ProviderSessionState, ServiceTier, SimpleStreamOptions, StreamFunction, StreamOptions, Usage } from "../types.js";
|
|
2
2
|
import { type AnthropicFetchOptions, type AnthropicMessagesClientLike } from "./anthropic-client.js";
|
|
3
3
|
import { type FallbackParam, type MessageParam, type TextBlockParam } from "./anthropic-wire.js";
|
|
4
4
|
export type AnthropicHeaderOptions = {
|
|
@@ -10,7 +10,7 @@ export type AnthropicHeaderOptions = {
|
|
|
10
10
|
modelHeaders?: Record<string, string>;
|
|
11
11
|
isCloudflareAiGateway?: boolean;
|
|
12
12
|
claudeCodeSessionId?: string;
|
|
13
|
-
|
|
13
|
+
coworkBetas?: readonly string[];
|
|
14
14
|
/** Allow explicit fingerprint headers to replace OAuth defaults on non-official endpoints. */
|
|
15
15
|
allowAnthropicHeaderOverrides?: boolean;
|
|
16
16
|
};
|
|
@@ -26,20 +26,24 @@ type AnthropicCacheControl = NonNullable<TextBlockParam["cache_control"]>;
|
|
|
26
26
|
* hasn't been materialized yet.
|
|
27
27
|
*/
|
|
28
28
|
export declare function clearAnthropicFastModeFallback(providerSessionState: Map<string, ProviderSessionState> | undefined): void;
|
|
29
|
+
/**
|
|
30
|
+
* Whether the direct Anthropic model's endpoint-scoped fast-mode fallback is
|
|
31
|
+
* currently active. Reading the map directly is intentional: inspection must
|
|
32
|
+
* not materialize a state entry for a model that has never streamed.
|
|
33
|
+
*/
|
|
34
|
+
export declare function isAnthropicFastModeFallbackDisabled(providerSessionState: Map<string, ProviderSessionState> | undefined, model: Model<Api>): boolean;
|
|
29
35
|
export * from "./claude-code-fingerprint.js";
|
|
30
|
-
export declare function mapStainlessOs(platform: string): "MacOS" | "Windows" | "Linux" | "FreeBSD" | `Other::${string}`;
|
|
31
36
|
export declare function mapStainlessArch(arch: string): "x64" | "arm64" | "x86" | `other::${string}`;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"X-Stainless-
|
|
37
|
+
/** Static headers emitted by Cowork's Linux Claude runtime. */
|
|
38
|
+
export declare const coworkHeaders: {
|
|
39
|
+
"X-Stainless-Arch": "arm64" | "x64" | "x86" | `other::${string}`;
|
|
40
|
+
"X-Stainless-Lang": string;
|
|
41
|
+
"X-Stainless-OS": string;
|
|
35
42
|
"X-Stainless-Package-Version": string;
|
|
43
|
+
"X-Stainless-Retry-Count": string;
|
|
36
44
|
"X-Stainless-Runtime": string;
|
|
37
|
-
"X-Stainless-
|
|
38
|
-
"X-Stainless-Arch": "arm64" | "x64" | "x86" | `other::${string}`;
|
|
39
|
-
"X-Stainless-OS": "FreeBSD" | "Linux" | "MacOS" | "Windows" | `Other::${string}`;
|
|
45
|
+
"X-Stainless-Runtime-Version": string;
|
|
40
46
|
"X-Stainless-Timeout": string;
|
|
41
|
-
"anthropic-client-platform": string;
|
|
42
|
-
"anthropic-client-version": string;
|
|
43
47
|
};
|
|
44
48
|
/**
|
|
45
49
|
* Wraps a fetch implementation to patch the Claude Code billing-header `cch`
|
|
@@ -156,6 +160,7 @@ export type AnthropicClientOptionsArgs = {
|
|
|
156
160
|
thinkingDisplay?: AnthropicThinkingDisplay;
|
|
157
161
|
disableStrictTools?: boolean;
|
|
158
162
|
fetch?: FetchImpl;
|
|
163
|
+
maxRetryDelayMs?: number;
|
|
159
164
|
claudeCodeSessionId?: string;
|
|
160
165
|
};
|
|
161
166
|
export type AnthropicClientOptionsResult = {
|
|
@@ -164,6 +169,7 @@ export type AnthropicClientOptionsResult = {
|
|
|
164
169
|
authToken?: string | null;
|
|
165
170
|
baseURL?: string;
|
|
166
171
|
maxRetries: number;
|
|
172
|
+
maxRetryDelayMs?: number;
|
|
167
173
|
defaultHeaders: Record<string, string>;
|
|
168
174
|
fetch?: FetchImpl;
|
|
169
175
|
fetchOptions?: AnthropicFetchOptions;
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Cowork inference-fingerprint constants, kept in a leaf module so consumers
|
|
3
|
+
* outside the provider (`registry/oauth/anthropic`, `usage/claude`) don't
|
|
4
|
+
* import the heavy `providers/anthropic` module.
|
|
5
|
+
*
|
|
5
6
|
* That import edge was a live init cycle: `providers/anthropic` → `stream` →
|
|
6
7
|
* `registry` → `registry/oauth/anthropic` → back into the still-initializing
|
|
7
|
-
* provider module
|
|
8
|
-
* `providers/anthropic` was the first module loaded.
|
|
8
|
+
* provider module.
|
|
9
9
|
*/
|
|
10
|
-
|
|
11
|
-
export declare const
|
|
12
|
-
|
|
10
|
+
/** Claude runtime version bundled by the current Cowork desktop release. */
|
|
11
|
+
export declare const claudeCodeVersion = "2.1.220";
|
|
12
|
+
/** User-Agent emitted by Cowork's `claude-desktop` inference entrypoint. */
|
|
13
|
+
export declare const coworkUserAgent = "claude-cli/2.1.220 (external, claude-desktop)";
|
|
14
|
+
/** Prefix used to isolate custom Anthropic OAuth tools from built-in tools. */
|
|
13
15
|
export declare const claudeToolPrefix: string;
|
|
16
|
+
/** Identity block prepended by Cowork's Claude runtime. */
|
|
14
17
|
export declare const claudeCodeSystemInstruction = "You are a Claude agent, built on Anthropic's Claude Agent SDK.";
|
|
18
|
+
/** Cowork's per-request output-token ceiling. */
|
|
15
19
|
export declare const CLAUDE_CODE_MAX_OUTPUT_TOKENS = 64000;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proto builders for the modern Cursor CLI exec frames (`ExecServerMessage`
|
|
3
|
+
* 27-31, 36-38, 40-55).
|
|
4
|
+
*
|
|
5
|
+
* Split out of `cursor.ts` because these are pure `create(...)` shapes with no
|
|
6
|
+
* transport, stream, or block-state coupling: the dispatcher decides *which*
|
|
7
|
+
* answer a frame gets, this module knows *what* that answer looks like on the
|
|
8
|
+
* wire. Every builder returns a result whose oneof case is set — an
|
|
9
|
+
* `ExecClientMessage` carrying a result with an unset oneof is a fake success
|
|
10
|
+
* the server reads as "the tool ran and produced nothing".
|
|
11
|
+
*/
|
|
12
|
+
import { type ExecuteHookRequest, type ExecuteHookResult, type McpStateExecResult, type McpToolDefinition, type PiBashExecResult, type PiEditExecResult, type PiFindExecResult, type PiGrepExecResult, type PiLsExecResult, type PiReadExecResult, type PiTruncation, type PiWriteExecResult } from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
|
13
|
+
import type { ToolResultMessage } from "../../types.js";
|
|
14
|
+
/**
|
|
15
|
+
* The pure arg translation lives in `../cursor-pi-args` so the legacy pi shim
|
|
16
|
+
* can share it without pulling this module's protobuf graph into the bundled
|
|
17
|
+
* virtual registry. Re-exported here because this is where the frame builders
|
|
18
|
+
* and their translation are consumed together.
|
|
19
|
+
*/
|
|
20
|
+
export { piEscapeRegexLiteral, piGrepSkip, piJoinPath, piLimit, piLsPath, piReadDisplayPath, piReadPath, piTimeout, } from "../cursor-pi-args.js";
|
|
21
|
+
/** Flatten a tool result's content into the single `output` string the Pi frames carry. */
|
|
22
|
+
export declare function piOutputText(toolResult: ToolResultMessage): string;
|
|
23
|
+
/**
|
|
24
|
+
* Translate a local tool's truncation summary into `PiTruncation`.
|
|
25
|
+
*
|
|
26
|
+
* Two shapes reach here. `read`/`grep` set `details.truncation`
|
|
27
|
+
* (`TruncationResult`), which carries an explicit `truncated` boolean. `bash`
|
|
28
|
+
* sets `details.meta.truncation` (`TruncationMeta`), which has **no** such
|
|
29
|
+
* flag — its presence *is* the signal, and requiring the boolean silently
|
|
30
|
+
* dropped every Bash truncation, handing Cursor clipped output with no notice
|
|
31
|
+
* that it was clipped.
|
|
32
|
+
*
|
|
33
|
+
* Returns `undefined` when nothing was truncated: the field is `optional` on
|
|
34
|
+
* every Pi success message, and emitting a zeroed `PiTruncation` would tell the
|
|
35
|
+
* server the output was trimmed to nothing.
|
|
36
|
+
*/
|
|
37
|
+
export declare function piTruncation(toolResult: ToolResultMessage): PiTruncation | undefined;
|
|
38
|
+
export declare function buildPiReadResult(toolResult: ToolResultMessage): PiReadExecResult;
|
|
39
|
+
export declare function buildPiReadError(error: string): PiReadExecResult;
|
|
40
|
+
export declare function buildPiBashResult(toolResult: ToolResultMessage): PiBashExecResult;
|
|
41
|
+
export declare function buildPiBashError(error: string): PiBashExecResult;
|
|
42
|
+
/**
|
|
43
|
+
* `PiEditExecSuccess` requires `diff` and `patch` alongside `output`. The local
|
|
44
|
+
* `edit` tool reports them under `details`; when it does not, the strings stay
|
|
45
|
+
* empty rather than being faked from the output text.
|
|
46
|
+
*/
|
|
47
|
+
export declare function buildPiEditResult(toolResult: ToolResultMessage): PiEditExecResult;
|
|
48
|
+
export declare function buildPiEditError(error: string): PiEditExecResult;
|
|
49
|
+
/**
|
|
50
|
+
* A refusal is not an execution failure: `PiEditExecResult` models them as
|
|
51
|
+
* separate variants, and answering a denied call with `error` reads as "the
|
|
52
|
+
* edit ran and broke", which invites a retry of an operation that was never
|
|
53
|
+
* permitted.
|
|
54
|
+
*/
|
|
55
|
+
export declare function buildPiEditRejected(reason: string): PiEditExecResult;
|
|
56
|
+
export declare function buildPiWriteResult(toolResult: ToolResultMessage): PiWriteExecResult;
|
|
57
|
+
export declare function buildPiWriteError(error: string): PiWriteExecResult;
|
|
58
|
+
/** Same variant split as {@link buildPiEditRejected}. */
|
|
59
|
+
export declare function buildPiWriteRejected(reason: string): PiWriteExecResult;
|
|
60
|
+
export declare function buildPiGrepResult(toolResult: ToolResultMessage): PiGrepExecResult;
|
|
61
|
+
export declare function buildPiGrepError(error: string): PiGrepExecResult;
|
|
62
|
+
export declare function buildPiFindResult(toolResult: ToolResultMessage): PiFindExecResult;
|
|
63
|
+
export declare function buildPiFindError(error: string): PiFindExecResult;
|
|
64
|
+
export declare function buildPiLsResult(toolResult: ToolResultMessage): PiLsExecResult;
|
|
65
|
+
export declare function buildPiLsError(error: string): PiLsExecResult;
|
|
66
|
+
/**
|
|
67
|
+
* Answer `mcpStateExecArgs` (frame 36) from the catalog already advertised in
|
|
68
|
+
* `RequestContext.tools`.
|
|
69
|
+
*
|
|
70
|
+
* This client hosts no MCP servers of its own: every forwarded tool is a local
|
|
71
|
+
* pi-agent tool published under a synthetic `providerIdentifier`. Regrouping
|
|
72
|
+
* the same list keeps the server's view of "which servers exist and what do
|
|
73
|
+
* they expose" consistent with what it was told at context time, instead of
|
|
74
|
+
* claiming zero servers while tool calls for them keep arriving.
|
|
75
|
+
*
|
|
76
|
+
* `serverIdentifiers` filters the answer when the server asks about specific
|
|
77
|
+
* servers. `kickOnly` is a restart request — there is nothing to restart, so it
|
|
78
|
+
* is answered with the same state rather than an error.
|
|
79
|
+
*/
|
|
80
|
+
export declare function buildMcpStateResult(tools: McpToolDefinition[], serverIdentifiers: readonly string[]): McpStateExecResult;
|
|
81
|
+
/**
|
|
82
|
+
* Build the neutral response for a hook query: the matching response case with
|
|
83
|
+
* every field unset.
|
|
84
|
+
*
|
|
85
|
+
* This client runs no Cursor hooks, and every field of every response variant
|
|
86
|
+
* is `optional` — so an empty response of the right case means "no hook had
|
|
87
|
+
* anything to say", which is exactly true. It is NOT the unset-oneof fake
|
|
88
|
+
* success: the case itself is set, only the payload is empty.
|
|
89
|
+
*
|
|
90
|
+
* `ExecuteHookRequest` and `ExecuteHookResponse` are parallel oneofs whose case
|
|
91
|
+
* names line up, but the two unions are unrelated to the compiler: a `switch`
|
|
92
|
+
* is what makes each pairing individually type-checked, and it forces a
|
|
93
|
+
* deliberate branch when a future regen adds a request case.
|
|
94
|
+
*
|
|
95
|
+
* Returns `null` for a request case this build does not model, which the
|
|
96
|
+
* dispatcher answers with `ExecClientThrow` rather than guessing a case.
|
|
97
|
+
*/
|
|
98
|
+
export declare function buildNeutralHookResult(request: ExecuteHookRequest | undefined): ExecuteHookResult | null;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Translate a Pi frame's args into the local tool kwargs that run it.
|
|
3
|
+
*
|
|
4
|
+
* Shared deliberately by three consumers: the provider synthesizes a display
|
|
5
|
+
* block from these, the coding-agent bridge executes with them, and the legacy
|
|
6
|
+
* pi shim performs the identical translation for the old wire. Separate
|
|
7
|
+
* hand-rolled copies drift, and the drift is invisible — the transcript shows
|
|
8
|
+
* one operation while a different one runs.
|
|
9
|
+
*
|
|
10
|
+
* Kept apart from `cursor/exec-modern.ts` on purpose: these are pure
|
|
11
|
+
* string/path functions with no protobuf coupling, while that module pulls in
|
|
12
|
+
* `@bufbuild/protobuf` and the generated `agent_pb` graph. The legacy shim is
|
|
13
|
+
* compiled into the bundled virtual module registry, so importing it from a
|
|
14
|
+
* nested path would drag the whole exec implementation in with it — and
|
|
15
|
+
* `./providers/*` is a single-segment wildcard export that cannot serve a
|
|
16
|
+
* nested specifier under bunfs (issue #3442).
|
|
17
|
+
*
|
|
18
|
+
* Every `optional int32` here is presence-sensitive: `0` is a supplied value,
|
|
19
|
+
* not "unset", so it must never be folded into a default.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* A `pi_read` range composed onto the path as `read`'s inline `:raw:N+K`
|
|
23
|
+
* selector.
|
|
24
|
+
*
|
|
25
|
+
* `read` exposes no range kwargs, so an uncomposed range reads the whole file.
|
|
26
|
+
* `offset` is a 1-indexed start clamped like the reference's
|
|
27
|
+
* `Math.max(0, offset - 1)` over 0-indexed lines; `limit` is a line count.
|
|
28
|
+
* `null` marks a present `limit: 0` — zero lines, which no selector expresses
|
|
29
|
+
* and which must not degrade into a whole-file read.
|
|
30
|
+
*
|
|
31
|
+
* The range is `raw` because a plain `:N+K` deliberately pads with one leading
|
|
32
|
+
* and three trailing context lines: helpful for a human reading a snippet,
|
|
33
|
+
* wrong for a caller that asked for exactly `limit` lines from `offset`. The
|
|
34
|
+
* wire result is an opaque `output` string, so the hashline and line-number
|
|
35
|
+
* gutter that `raw` also drops carry nothing the frame's contract needs.
|
|
36
|
+
* A range-free read keeps the ordinary form — whole-file reads want them.
|
|
37
|
+
*/
|
|
38
|
+
export declare function piReadPath(readPath: string, offset?: number, limit?: number): string | null;
|
|
39
|
+
/**
|
|
40
|
+
* The same range as {@link piReadPath}, rendered for a transcript block rather
|
|
41
|
+
* than for execution.
|
|
42
|
+
*
|
|
43
|
+
* Differs only at `limit: 0`, where `piReadPath` returns `null` because no
|
|
44
|
+
* selector reads zero lines and the frame is answered with empty output
|
|
45
|
+
* directly. The block still has to say so: falling back to the bare path there
|
|
46
|
+
* would record a whole-file read whose result is empty, which is the widest
|
|
47
|
+
* possible gap between what a rebuilt transcript shows and what happened.
|
|
48
|
+
* `+0` is never executed — it exists to be read.
|
|
49
|
+
*/
|
|
50
|
+
export declare function piReadDisplayPath(readPath: string, offset?: number, limit?: number): string;
|
|
51
|
+
/**
|
|
52
|
+
* A legacy `grep` frame's pagination `offset` as the local tool's file `skip`.
|
|
53
|
+
*
|
|
54
|
+
* `grep` paginates by file and reports "use skip=N for the next page" in that
|
|
55
|
+
* same unit, so the offset maps across directly. A present `0` means "start at
|
|
56
|
+
* the beginning", which is the unskipped search rather than a skip of zero.
|
|
57
|
+
*
|
|
58
|
+
* Shared because both the executing bridge and the provider's transcript
|
|
59
|
+
* synthesis need it: a block showing an unskipped search beside a result from
|
|
60
|
+
* a later file window misreports what was searched.
|
|
61
|
+
*/
|
|
62
|
+
export declare function piGrepSkip(offset?: number): number | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Join a Pi frame's optional `path` with the `glob`/`pattern` it scopes.
|
|
65
|
+
*
|
|
66
|
+
* The local `grep`/`glob` tools take one combined path spec. An absolute
|
|
67
|
+
* pattern ignores the path, and an absent or `.` path leaves the pattern
|
|
68
|
+
* standing alone rather than building a `./`- or `//`-prefixed spec.
|
|
69
|
+
*
|
|
70
|
+
* Uses `node:path` rather than string surgery so Windows absolutes (`C:\…`,
|
|
71
|
+
* UNC) are recognised and separators stay normalized.
|
|
72
|
+
*/
|
|
73
|
+
export declare function piJoinPath(basePath: string | undefined, pattern: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* The path a `pi_ls` frame lists.
|
|
76
|
+
*
|
|
77
|
+
* The frame's `limit` is deliberately NOT mapped. It caps directory *entries*
|
|
78
|
+
* (the reference does a flat `readdir` and slices the entry array), while the
|
|
79
|
+
* local `read` tool renders a depth-2 tree with per-directory caps and elision
|
|
80
|
+
* summaries and applies a selector as a *rendered line* slice. Nested rows,
|
|
81
|
+
* headers and "N more" lines all count toward that slice, so `:1+K` would cap
|
|
82
|
+
* a different unit while looking honored — worse than leaving it unset, which
|
|
83
|
+
* at least reports the local listing's own truncation faithfully.
|
|
84
|
+
*/
|
|
85
|
+
export declare function piLsPath(basePath: string | undefined): string;
|
|
86
|
+
/** Escape a literal string so the regex-only local `grep` tool matches it verbatim. */
|
|
87
|
+
export declare function piEscapeRegexLiteral(value: string): string;
|
|
88
|
+
/** Clamp a present `optional int32` result cap the way the reference does; `undefined` stays unset. */
|
|
89
|
+
export declare function piLimit(limit: number | undefined): number | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* A `pi_bash` frame's timeout as the local `bash` tool's kwarg.
|
|
92
|
+
*
|
|
93
|
+
* Presence-sensitive like every other `optional int32` here, and unusually
|
|
94
|
+
* load-bearing: `bash` documents `timeout: 0` as "disables the command
|
|
95
|
+
* deadline", so folding a supplied `0` into `undefined` applies the 300s
|
|
96
|
+
* default and kills exactly the long-running command that asked not to be.
|
|
97
|
+
* Negative values have no local meaning and fall back to the default.
|
|
98
|
+
*/
|
|
99
|
+
export declare function piTimeout(timeout: number | undefined): number | undefined;
|