@oh-my-pi/pi-coding-agent 15.8.3 → 15.9.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/CHANGELOG.md +74 -31
- package/dist/types/capability/skill.d.ts +7 -0
- package/dist/types/config/settings-schema.d.ts +36 -22
- package/dist/types/debug/protocol-probe.d.ts +38 -0
- package/dist/types/debug/terminal-info.d.ts +34 -0
- package/dist/types/export/html/template.generated.d.ts +1 -1
- package/dist/types/extensibility/custom-tools/types.d.ts +1 -1
- package/dist/types/extensibility/extensions/types.d.ts +11 -0
- package/dist/types/extensibility/shared-events.d.ts +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/mcp/transports/stdio.d.ts +16 -7
- package/dist/types/modes/components/assistant-message.d.ts +3 -2
- package/dist/types/modes/components/hook-selector.d.ts +11 -0
- package/dist/types/modes/components/todo-reminder.d.ts +1 -1
- package/dist/types/modes/components/transcript-container.d.ts +36 -0
- package/dist/types/modes/interactive-mode.d.ts +2 -1
- package/dist/types/modes/rpc/rpc-types.d.ts +1 -1
- package/dist/types/modes/theme/theme.d.ts +20 -1
- package/dist/types/plan-mode/plan-handoff.d.ts +20 -0
- package/dist/types/session/agent-session.d.ts +1 -1
- package/dist/types/session/indexed-session-storage.d.ts +59 -0
- package/dist/types/session/redis-session-storage.d.ts +12 -85
- package/dist/types/session/session-manager.d.ts +20 -0
- package/dist/types/session/session-storage.d.ts +5 -7
- package/dist/types/session/sql-session-storage.d.ts +16 -85
- package/dist/types/task/executor.d.ts +9 -0
- package/dist/types/task/index.d.ts +3 -1
- package/dist/types/telemetry-export.d.ts +19 -0
- package/dist/types/tiny/compiled-runtime.d.ts +35 -0
- package/dist/types/tools/ask.d.ts +1 -0
- package/dist/types/tools/index.d.ts +4 -2
- package/dist/types/tools/path-utils.d.ts +1 -1
- package/dist/types/tools/search.d.ts +2 -2
- package/dist/types/tools/{todo-write.d.ts → todo.d.ts} +18 -18
- package/dist/types/utils/session-color.d.ts +7 -2
- package/dist/types/web/search/index.d.ts +1 -1
- package/dist/types/web/search/provider.d.ts +2 -2
- package/dist/types/web/search/types.d.ts +65 -1
- package/package.json +15 -9
- package/scripts/build-binary.ts +12 -0
- package/src/capability/skill.ts +7 -0
- package/src/cli/args.ts +1 -1
- package/src/config/settings-schema.ts +22 -55
- package/src/debug/index.ts +67 -1
- package/src/debug/protocol-probe.ts +267 -0
- package/src/debug/terminal-info.ts +127 -0
- package/src/export/html/template.generated.ts +1 -1
- package/src/export/html/template.js +3 -3
- package/src/extensibility/custom-tools/types.ts +1 -1
- package/src/extensibility/extensions/types.ts +11 -0
- package/src/extensibility/shared-events.ts +1 -1
- package/src/extensibility/skills.ts +3 -3
- package/src/index.ts +1 -0
- package/src/internal-urls/docs-index.generated.ts +7 -7
- package/src/main.ts +12 -0
- package/src/mcp/transports/stdio.ts +37 -12
- package/src/modes/acp/acp-event-mapper.ts +7 -7
- package/src/modes/components/assistant-message.ts +3 -2
- package/src/modes/components/hook-selector.ts +149 -14
- package/src/modes/components/session-selector.ts +36 -5
- package/src/modes/components/status-line/segments.ts +2 -1
- package/src/modes/components/status-line.ts +1 -1
- package/src/modes/components/tips.txt +1 -1
- package/src/modes/components/todo-reminder.ts +1 -1
- package/src/modes/components/tool-execution.ts +9 -4
- package/src/modes/components/transcript-container.ts +91 -0
- package/src/modes/controllers/event-controller.ts +12 -7
- package/src/modes/controllers/extension-ui-controller.ts +3 -0
- package/src/modes/controllers/todo-command-controller.ts +1 -1
- package/src/modes/interactive-mode.ts +18 -6
- package/src/modes/print-mode.ts +5 -0
- package/src/modes/rpc/rpc-types.ts +1 -1
- package/src/modes/theme/theme.ts +48 -8
- package/src/modes/utils/ui-helpers.ts +1 -0
- package/src/plan-mode/plan-handoff.ts +37 -0
- package/src/priority.json +4 -0
- package/src/prompts/goals/goal-continuation.md +1 -1
- package/src/prompts/system/eager-todo.md +3 -3
- package/src/prompts/system/orchestrate-notice.md +5 -5
- package/src/prompts/system/plan-mode-approved.md +14 -17
- package/src/prompts/system/plan-mode-reference.md +3 -6
- package/src/prompts/system/subagent-system-prompt.md +11 -0
- package/src/prompts/system/workflow-notice.md +1 -1
- package/src/prompts/tools/browser.md +5 -2
- package/src/prompts/tools/search.md +1 -1
- package/src/prompts/tools/task.md +3 -1
- package/src/prompts/tools/{todo-write.md → todo.md} +5 -5
- package/src/sdk.ts +1 -0
- package/src/session/agent-session.ts +14 -14
- package/src/session/indexed-session-storage.ts +430 -0
- package/src/session/redis-session-storage.ts +66 -377
- package/src/session/session-manager.ts +102 -22
- package/src/session/session-storage.ts +148 -68
- package/src/session/sql-session-storage.ts +131 -382
- package/src/slash-commands/helpers/todo.ts +2 -2
- package/src/task/executor.ts +9 -1
- package/src/task/index.ts +51 -1
- package/src/telemetry-export.ts +126 -0
- package/src/tiny/compiled-runtime.ts +179 -0
- package/src/tiny/worker.ts +24 -2
- package/src/tools/ask.ts +133 -87
- package/src/tools/fetch.ts +17 -4
- package/src/tools/find.ts +2 -2
- package/src/tools/index.ts +6 -4
- package/src/tools/path-utils.ts +16 -7
- package/src/tools/renderers.ts +2 -2
- package/src/tools/search.ts +6 -3
- package/src/tools/{todo-write.ts → todo.ts} +32 -35
- package/src/utils/session-color.ts +39 -14
- package/src/web/search/index.ts +1 -1
- package/src/web/search/provider.ts +18 -34
- package/src/web/search/types.ts +73 -32
|
@@ -15,7 +15,7 @@ import type { ExecOptions, ExecResult } from "../../exec/exec";
|
|
|
15
15
|
import type { HookUIContext } from "../../extensibility/hooks/types";
|
|
16
16
|
import type { Theme } from "../../modes/theme/theme";
|
|
17
17
|
import type { ReadonlySessionManager } from "../../session/session-manager";
|
|
18
|
-
import type { TodoItem } from "../../tools/todo
|
|
18
|
+
import type { TodoItem } from "../../tools/todo";
|
|
19
19
|
/** Alias for clarity */
|
|
20
20
|
export type CustomToolUIContext = HookUIContext;
|
|
21
21
|
export type { ExecOptions, ExecResult } from "../../exec/exec";
|
|
@@ -59,6 +59,17 @@ export interface ExtensionUIDialogOptions {
|
|
|
59
59
|
onExternalEditor?: () => void;
|
|
60
60
|
/** Optional footer hint text rendered by interactive selector */
|
|
61
61
|
helpText?: string;
|
|
62
|
+
/** Render a leading radio/checkbox marker before each markable option in
|
|
63
|
+
* select dialogs (matches the ask transcript). "radio" fills the cursor row
|
|
64
|
+
* for single-choice; "checkbox" reflects `checkedIndices` per row for
|
|
65
|
+
* multi-select. Options beyond `markableCount` keep the plain cursor. */
|
|
66
|
+
selectionMarker?: "radio" | "checkbox";
|
|
67
|
+
/** For `selectionMarker: "checkbox"`: option indices currently checked. */
|
|
68
|
+
checkedIndices?: readonly number[];
|
|
69
|
+
/** Number of leading options that receive a selection marker; the remaining
|
|
70
|
+
* trailing options (e.g. "Other"/"Done" actions) keep the plain cursor.
|
|
71
|
+
* Defaults to all options when `selectionMarker` is set. */
|
|
72
|
+
markableCount?: number;
|
|
62
73
|
}
|
|
63
74
|
/** Raw terminal input listener for extensions. */
|
|
64
75
|
export type TerminalInputHandler = (data: string) => {
|
|
@@ -18,7 +18,7 @@ import type { ImageContent, TextContent, ToolResultMessage } from "@oh-my-pi/pi-
|
|
|
18
18
|
import type { Rule } from "../capability/rule";
|
|
19
19
|
import type { Goal, GoalModeState } from "../goals/state";
|
|
20
20
|
import type { BranchSummaryEntry, CompactionEntry, SessionEntry } from "../session/session-manager";
|
|
21
|
-
import type { TodoItem } from "../tools/todo
|
|
21
|
+
import type { TodoItem } from "../tools/todo";
|
|
22
22
|
/** Fired on initial session load */
|
|
23
23
|
export interface SessionStartEvent {
|
|
24
24
|
type: "session_start";
|
package/dist/types/index.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export * from "./modes/theme/theme";
|
|
|
22
22
|
export * from "./sdk";
|
|
23
23
|
export * from "./session/agent-session";
|
|
24
24
|
export * from "./session/auth-storage";
|
|
25
|
+
export * from "./session/indexed-session-storage";
|
|
25
26
|
export * from "./session/messages";
|
|
26
27
|
export * from "./session/redis-session-storage";
|
|
27
28
|
export * from "./session/session-dump-format";
|
|
@@ -12,15 +12,24 @@ interface FrameSink {
|
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* Write a newline-delimited JSON-RPC frame to the subprocess's stdin sink,
|
|
15
|
-
* swallowing synchronous
|
|
15
|
+
* swallowing both synchronous throws and asynchronous rejections so the caller
|
|
16
|
+
* can decide how to react.
|
|
16
17
|
*
|
|
17
|
-
* Bun's `FileSink`
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* Bun's `FileSink.write()`/`flush()` can fail two ways once the read end of the
|
|
19
|
+
* pipe has been closed by a subprocess that exited between read-loop ticks:
|
|
20
|
+
* - a synchronous throw (most reliably observed on Windows), and
|
|
21
|
+
* - a *rejected Promise* returned from `write()`/`flush()`, i.e. the EPIPE is
|
|
22
|
+
* surfaced asynchronously (note the `processTicksAndRejections` frame in the
|
|
23
|
+
* stack traces on #1710 and the follow-up report).
|
|
21
24
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
25
|
+
* A sibling `async` method's `try/catch` only catches the synchronous case; an
|
|
26
|
+
* un-awaited rejected Promise escapes as a fatal unhandled rejection. So we both
|
|
27
|
+
* catch the throw and neutralize any returned promise's rejection.
|
|
28
|
+
*
|
|
29
|
+
* Returns `true` when the frame was accepted synchronously, `false` when the
|
|
30
|
+
* sink threw — callers signal transport closure on `false`. An asynchronous
|
|
31
|
+
* failure cannot be reflected in the return value; it is neutralized here and
|
|
32
|
+
* the dead transport is detected by the read loop / request timeout instead.
|
|
24
33
|
*/
|
|
25
34
|
export declare function writeFrame(stdin: FrameSink, frame: string): boolean;
|
|
26
35
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AssistantMessage, ImageContent, Usage } from "@oh-my-pi/pi-ai";
|
|
2
|
-
import { Container } from "@oh-my-pi/pi-tui";
|
|
2
|
+
import { Container, type ImageBudget } from "@oh-my-pi/pi-tui";
|
|
3
3
|
import type { AssistantThinkingRenderer } from "../../extensibility/extensions/types";
|
|
4
4
|
/**
|
|
5
5
|
* Component that renders a complete assistant message
|
|
@@ -9,7 +9,8 @@ export declare class AssistantMessageComponent extends Container {
|
|
|
9
9
|
private hideThinkingBlock;
|
|
10
10
|
private readonly onImageUpdate?;
|
|
11
11
|
private readonly thinkingRenderers;
|
|
12
|
-
|
|
12
|
+
private readonly imageBudget?;
|
|
13
|
+
constructor(message?: AssistantMessage, hideThinkingBlock?: boolean, onImageUpdate?: (() => void) | undefined, thinkingRenderers?: readonly AssistantThinkingRenderer[], imageBudget?: ImageBudget | undefined);
|
|
13
14
|
invalidate(): void;
|
|
14
15
|
setHideThinkingBlock(hide: boolean): void;
|
|
15
16
|
setToolResultImages(toolCallId: string, images: ImageContent[]): void;
|
|
@@ -44,6 +44,17 @@ export interface HookSelectorOptions {
|
|
|
44
44
|
/** Indices into the original options that cannot be selected: they render
|
|
45
45
|
* dimmed, are skipped during navigation, and reject enter/timeout. */
|
|
46
46
|
disabledIndices?: readonly number[];
|
|
47
|
+
/** Render a leading radio/checkbox marker before each markable option,
|
|
48
|
+
* matching the ask transcript. "radio" fills the marker on the cursor row
|
|
49
|
+
* (single-choice); "checkbox" reflects {@link checkedIndices} per row
|
|
50
|
+
* (multi-select). Options at or beyond {@link markableCount} keep the plain
|
|
51
|
+
* cursor prefix — used for trailing control rows like "Other"/"Done". */
|
|
52
|
+
selectionMarker?: "radio" | "checkbox";
|
|
53
|
+
/** For `selectionMarker: "checkbox"`: original-indices currently checked. */
|
|
54
|
+
checkedIndices?: readonly number[];
|
|
55
|
+
/** Number of leading options (original order) that receive a selection
|
|
56
|
+
* marker. Defaults to every option when {@link selectionMarker} is set. */
|
|
57
|
+
markableCount?: number;
|
|
47
58
|
}
|
|
48
59
|
export interface HookSelectorOption {
|
|
49
60
|
label: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Container } from "@oh-my-pi/pi-tui";
|
|
2
|
-
import type { TodoItem } from "../../tools/todo
|
|
2
|
+
import type { TodoItem } from "../../tools/todo";
|
|
3
3
|
/**
|
|
4
4
|
* Component that renders a todo completion reminder notification.
|
|
5
5
|
* Shows when the agent stops with incomplete todos.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Container } from "@oh-my-pi/pi-tui";
|
|
2
|
+
/**
|
|
3
|
+
* Transcript container that freezes the rendered output of every block except
|
|
4
|
+
* the bottom-most (live) one on terminals where committed native scrollback is
|
|
5
|
+
* immutable.
|
|
6
|
+
*
|
|
7
|
+
* On ED3-risk terminals with an unobservable viewport (ghostty/kitty/iTerm2/…)
|
|
8
|
+
* the renderer cannot clear saved lines (`\x1b[3J` may yank a reader) or query
|
|
9
|
+
* whether the user has scrolled, so any block that re-lays-out *after* it has
|
|
10
|
+
* scrolled past the viewport leaves a stale duplicate above the live region
|
|
11
|
+
* (a finalized assistant message re-wrapping, a tool preview collapsing to its
|
|
12
|
+
* compact result, a late async tool completion). The renderer's only safe move
|
|
13
|
+
* for such an offscreen edit is to not repaint — which is correct only if the
|
|
14
|
+
* committed region never changes underneath it.
|
|
15
|
+
*
|
|
16
|
+
* This container provides that guarantee: a block's render is snapshotted while
|
|
17
|
+
* it is the live (bottom-most) block, and once a newer block is appended it
|
|
18
|
+
* replays the snapshot instead of recomputing. Mutations after a block leaves
|
|
19
|
+
* live are intentionally deferred until the next checkpoint {@link thaw} (prompt
|
|
20
|
+
* submit → native-scrollback rebuild), where the whole transcript is replayed
|
|
21
|
+
* and any drift reconciles safely. On terminals that can rebuild history this
|
|
22
|
+
* freezing is unnecessary, so it renders every block live for full fidelity.
|
|
23
|
+
*/
|
|
24
|
+
export declare class TranscriptContainer extends Container {
|
|
25
|
+
#private;
|
|
26
|
+
invalidate(): void;
|
|
27
|
+
clear(): void;
|
|
28
|
+
/**
|
|
29
|
+
* Retire all frozen snapshots so the next render reflects each block's current
|
|
30
|
+
* state. Call at reconciliation checkpoints (prompt submit) where the whole
|
|
31
|
+
* transcript is replayed into native scrollback and any drift a frozen block
|
|
32
|
+
* accumulated is reconciled.
|
|
33
|
+
*/
|
|
34
|
+
thaw(): void;
|
|
35
|
+
render(width: number): string[];
|
|
36
|
+
}
|
|
@@ -23,6 +23,7 @@ import type { HookInputComponent } from "./components/hook-input";
|
|
|
23
23
|
import type { HookSelectorComponent, HookSelectorSlider } from "./components/hook-selector";
|
|
24
24
|
import { StatusLineComponent } from "./components/status-line";
|
|
25
25
|
import type { ToolExecutionHandle } from "./components/tool-execution";
|
|
26
|
+
import { TranscriptContainer } from "./components/transcript-container";
|
|
26
27
|
import { type LoopLimitRuntime } from "./loop-limit";
|
|
27
28
|
import { OAuthManualInputManager } from "./oauth-manual-input";
|
|
28
29
|
import type { Theme } from "./theme/theme";
|
|
@@ -49,7 +50,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
|
|
|
49
50
|
agent: Agent;
|
|
50
51
|
historyStorage?: HistoryStorage;
|
|
51
52
|
ui: TUI;
|
|
52
|
-
chatContainer:
|
|
53
|
+
chatContainer: TranscriptContainer;
|
|
53
54
|
pendingMessagesContainer: Container;
|
|
54
55
|
statusContainer: Container;
|
|
55
56
|
todoContainer: Container;
|
|
@@ -10,7 +10,7 @@ import type { Effort, ImageContent, Model } from "@oh-my-pi/pi-ai";
|
|
|
10
10
|
import type { BashResult } from "../../exec/bash-executor";
|
|
11
11
|
import type { ContextUsage } from "../../extensibility/extensions/types";
|
|
12
12
|
import type { SessionStats } from "../../session/agent-session";
|
|
13
|
-
import type { TodoPhase } from "../../tools/todo
|
|
13
|
+
import type { TodoPhase } from "../../tools/todo";
|
|
14
14
|
export type RpcCommand = {
|
|
15
15
|
id?: string;
|
|
16
16
|
type: "prompt";
|
|
@@ -6,7 +6,7 @@ export type SymbolPreset = "unicode" | "nerd" | "ascii";
|
|
|
6
6
|
/**
|
|
7
7
|
* All available symbol keys organized by category.
|
|
8
8
|
*/
|
|
9
|
-
export type SymbolKey = "status.success" | "status.error" | "status.warning" | "status.info" | "status.pending" | "status.disabled" | "status.enabled" | "status.running" | "status.shadowed" | "status.aborted" | "nav.cursor" | "nav.selected" | "nav.expand" | "nav.collapse" | "nav.back" | "tree.branch" | "tree.last" | "tree.vertical" | "tree.horizontal" | "tree.hook" | "boxRound.topLeft" | "boxRound.topRight" | "boxRound.bottomLeft" | "boxRound.bottomRight" | "boxRound.horizontal" | "boxRound.vertical" | "boxSharp.topLeft" | "boxSharp.topRight" | "boxSharp.bottomLeft" | "boxSharp.bottomRight" | "boxSharp.horizontal" | "boxSharp.vertical" | "boxSharp.cross" | "boxSharp.teeDown" | "boxSharp.teeUp" | "boxSharp.teeRight" | "boxSharp.teeLeft" | "sep.powerline" | "sep.powerlineThin" | "sep.powerlineLeft" | "sep.powerlineRight" | "sep.powerlineThinLeft" | "sep.powerlineThinRight" | "sep.block" | "sep.space" | "sep.asciiLeft" | "sep.asciiRight" | "sep.dot" | "sep.slash" | "sep.pipe" | "icon.model" | "icon.plan" | "icon.goal" | "icon.pause" | "icon.loop" | "icon.folder" | "icon.scratchFolder" | "icon.file" | "icon.git" | "icon.branch" | "icon.pr" | "icon.tokens" | "icon.context" | "icon.cost" | "icon.time" | "icon.pi" | "icon.agents" | "icon.cache" | "icon.input" | "icon.output" | "icon.host" | "icon.session" | "icon.package" | "icon.warning" | "icon.rewind" | "icon.auto" | "icon.fast" | "icon.extensionSkill" | "icon.extensionTool" | "icon.extensionSlashCommand" | "icon.extensionMcp" | "icon.extensionRule" | "icon.extensionHook" | "icon.extensionPrompt" | "icon.extensionContextFile" | "icon.extensionInstruction" | "icon.mic" | "thinking.minimal" | "thinking.low" | "thinking.medium" | "thinking.high" | "thinking.xhigh" | "thinking.autoPending" | "checkbox.checked" | "checkbox.unchecked" | "format.bullet" | "format.dash" | "format.bracketLeft" | "format.bracketRight" | "md.quoteBorder" | "md.hrChar" | "md.bullet" | "md.colorSwatch" | "lang.default" | "lang.typescript" | "lang.javascript" | "lang.python" | "lang.rust" | "lang.go" | "lang.java" | "lang.c" | "lang.cpp" | "lang.csharp" | "lang.ruby" | "lang.php" | "lang.swift" | "lang.kotlin" | "lang.shell" | "lang.html" | "lang.css" | "lang.json" | "lang.yaml" | "lang.markdown" | "lang.sql" | "lang.docker" | "lang.lua" | "lang.text" | "lang.env" | "lang.toml" | "lang.xml" | "lang.ini" | "lang.conf" | "lang.log" | "lang.csv" | "lang.tsv" | "lang.image" | "lang.pdf" | "lang.archive" | "lang.binary" | "tab.appearance" | "tab.model" | "tab.interaction" | "tab.context" | "tab.editing" | "tab.tools" | "tab.memory" | "tab.tasks" | "tab.providers";
|
|
9
|
+
export type SymbolKey = "status.success" | "status.error" | "status.warning" | "status.info" | "status.pending" | "status.disabled" | "status.enabled" | "status.running" | "status.shadowed" | "status.aborted" | "nav.cursor" | "nav.selected" | "nav.expand" | "nav.collapse" | "nav.back" | "tree.branch" | "tree.last" | "tree.vertical" | "tree.horizontal" | "tree.hook" | "boxRound.topLeft" | "boxRound.topRight" | "boxRound.bottomLeft" | "boxRound.bottomRight" | "boxRound.horizontal" | "boxRound.vertical" | "boxSharp.topLeft" | "boxSharp.topRight" | "boxSharp.bottomLeft" | "boxSharp.bottomRight" | "boxSharp.horizontal" | "boxSharp.vertical" | "boxSharp.cross" | "boxSharp.teeDown" | "boxSharp.teeUp" | "boxSharp.teeRight" | "boxSharp.teeLeft" | "sep.powerline" | "sep.powerlineThin" | "sep.powerlineLeft" | "sep.powerlineRight" | "sep.powerlineThinLeft" | "sep.powerlineThinRight" | "sep.block" | "sep.space" | "sep.asciiLeft" | "sep.asciiRight" | "sep.dot" | "sep.slash" | "sep.pipe" | "icon.model" | "icon.plan" | "icon.goal" | "icon.pause" | "icon.loop" | "icon.folder" | "icon.scratchFolder" | "icon.file" | "icon.git" | "icon.branch" | "icon.pr" | "icon.tokens" | "icon.context" | "icon.cost" | "icon.time" | "icon.pi" | "icon.agents" | "icon.cache" | "icon.input" | "icon.output" | "icon.host" | "icon.session" | "icon.package" | "icon.warning" | "icon.rewind" | "icon.auto" | "icon.fast" | "icon.extensionSkill" | "icon.extensionTool" | "icon.extensionSlashCommand" | "icon.extensionMcp" | "icon.extensionRule" | "icon.extensionHook" | "icon.extensionPrompt" | "icon.extensionContextFile" | "icon.extensionInstruction" | "icon.mic" | "thinking.minimal" | "thinking.low" | "thinking.medium" | "thinking.high" | "thinking.xhigh" | "thinking.autoPending" | "checkbox.checked" | "checkbox.unchecked" | "radio.selected" | "radio.unselected" | "format.bullet" | "format.dash" | "format.bracketLeft" | "format.bracketRight" | "md.quoteBorder" | "md.hrChar" | "md.bullet" | "md.colorSwatch" | "lang.default" | "lang.typescript" | "lang.javascript" | "lang.python" | "lang.rust" | "lang.go" | "lang.java" | "lang.c" | "lang.cpp" | "lang.csharp" | "lang.ruby" | "lang.php" | "lang.swift" | "lang.kotlin" | "lang.shell" | "lang.html" | "lang.css" | "lang.json" | "lang.yaml" | "lang.markdown" | "lang.sql" | "lang.docker" | "lang.lua" | "lang.text" | "lang.env" | "lang.toml" | "lang.xml" | "lang.ini" | "lang.conf" | "lang.log" | "lang.csv" | "lang.tsv" | "lang.image" | "lang.pdf" | "lang.archive" | "lang.binary" | "tab.appearance" | "tab.model" | "tab.interaction" | "tab.context" | "tab.editing" | "tab.tools" | "tab.memory" | "tab.tasks" | "tab.providers";
|
|
10
10
|
export type SpinnerType = "status" | "activity";
|
|
11
11
|
export type ThemeColor = "accent" | "border" | "borderAccent" | "borderMuted" | "success" | "error" | "warning" | "muted" | "dim" | "text" | "thinkingText" | "userMessageText" | "customMessageText" | "customMessageLabel" | "toolTitle" | "toolOutput" | "mdHeading" | "mdLink" | "mdLinkUrl" | "mdCode" | "mdCodeBlock" | "mdCodeBlockBorder" | "mdQuote" | "mdQuoteBorder" | "mdHr" | "mdListBullet" | "toolDiffAdded" | "toolDiffRemoved" | "toolDiffContext" | "syntaxComment" | "syntaxKeyword" | "syntaxFunction" | "syntaxVariable" | "syntaxString" | "syntaxNumber" | "syntaxType" | "syntaxOperator" | "syntaxPunctuation" | "thinkingOff" | "thinkingMinimal" | "thinkingLow" | "thinkingMedium" | "thinkingHigh" | "thinkingXhigh" | "bashMode" | "pythonMode" | "statusLineSep" | "statusLineModel" | "statusLinePath" | "statusLineGitClean" | "statusLineGitDirty" | "statusLineContext" | "statusLineSpend" | "statusLineStaged" | "statusLineDirty" | "statusLineUntracked" | "statusLineOutput" | "statusLineCost" | "statusLineSubagents";
|
|
12
12
|
/** Check if a string is a valid ThemeColor value */
|
|
@@ -17,7 +17,22 @@ export declare class Theme {
|
|
|
17
17
|
#private;
|
|
18
18
|
private readonly mode;
|
|
19
19
|
private readonly symbolPreset;
|
|
20
|
+
/**
|
|
21
|
+
* Perceptual luma (0..1) of the status-line background — used to classify the
|
|
22
|
+
* theme light/dark. Undefined when it can't be resolved. Classified against the
|
|
23
|
+
* status line (the surface session accents render on) rather than the chat bubble
|
|
24
|
+
* (`userMessageBg`), which some themes (e.g. `porcelain`) style dark on an
|
|
25
|
+
* otherwise-light theme.
|
|
26
|
+
*/
|
|
27
|
+
readonly statusLineLuminance: number | undefined;
|
|
20
28
|
constructor(fgColors: Record<ThemeColor, string | number>, bgColors: Record<ThemeBg, string | number>, mode: ColorMode, symbolPreset: SymbolPreset, symbolOverrides: Partial<Record<SymbolKey, string>>, spinnerFramesOverrides?: Partial<Record<SpinnerType, string[]>>);
|
|
29
|
+
/** True when the active theme has a light status-line background. */
|
|
30
|
+
get isLight(): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Surface luminance to size session accents against on light themes; undefined on
|
|
33
|
+
* dark themes so accents stay vivid. Pass straight to `getSessionAccentHex`.
|
|
34
|
+
*/
|
|
35
|
+
get accentSurfaceLuminance(): number | undefined;
|
|
21
36
|
fg(color: ThemeColor, text: string): string;
|
|
22
37
|
bg(color: ThemeBg, text: string): string;
|
|
23
38
|
bold(text: string): string;
|
|
@@ -167,6 +182,10 @@ export declare class Theme {
|
|
|
167
182
|
checked: string;
|
|
168
183
|
unchecked: string;
|
|
169
184
|
};
|
|
185
|
+
get radio(): {
|
|
186
|
+
selected: string;
|
|
187
|
+
unselected: string;
|
|
188
|
+
};
|
|
170
189
|
get format(): {
|
|
171
190
|
bullet: string;
|
|
172
191
|
dash: string;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type LocalProtocolOptions } from "../internal-urls";
|
|
2
|
+
/** The session's active plan, resolved for handoff into a subagent's context. */
|
|
3
|
+
export interface OverallPlanReference {
|
|
4
|
+
/** The `local://` reference path (e.g. `local://my-feature.md`), kept for display. */
|
|
5
|
+
path: string;
|
|
6
|
+
/** The full plan markdown, as written to disk. */
|
|
7
|
+
content: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Load the session's active overall plan for subagent handoff.
|
|
11
|
+
*
|
|
12
|
+
* Returns the plan referenced by `planReferencePath` when it exists on disk with
|
|
13
|
+
* non-empty content, or `undefined` when there is no plan (the file is absent or
|
|
14
|
+
* empty). This mirrors `AgentSession.#buildPlanReferenceMessage`'s gating so a
|
|
15
|
+
* subagent sees exactly the plan the main agent treats as its active reference.
|
|
16
|
+
*
|
|
17
|
+
* Callers MUST skip this during plan mode itself — read-only plan exploration
|
|
18
|
+
* uses a different prompt and a draft plan should not be handed off as approved.
|
|
19
|
+
*/
|
|
20
|
+
export declare function loadOverallPlanReference(planReferencePath: string, localProtocolOptions: LocalProtocolOptions): Promise<OverallPlanReference | undefined>;
|
|
@@ -43,7 +43,7 @@ import { type SecretObfuscator } from "../secrets/obfuscator";
|
|
|
43
43
|
import { type ConfiguredThinkingLevel } from "../thinking";
|
|
44
44
|
import { type DiscoverableTool, type DiscoverableToolSearchIndex } from "../tool-discovery/tool-index";
|
|
45
45
|
import type { CheckpointState } from "../tools/checkpoint";
|
|
46
|
-
import { type TodoItem, type TodoPhase } from "../tools/todo
|
|
46
|
+
import { type TodoItem, type TodoPhase } from "../tools/todo";
|
|
47
47
|
import type { ClientBridge } from "./client-bridge";
|
|
48
48
|
import { type CustomMessage } from "./messages";
|
|
49
49
|
import type { BranchSummaryEntry, NewSessionOptions, SessionContext, SessionManager } from "./session-manager";
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { SessionStorage, SessionStorageStat, SessionStorageWriter } from "./session-storage";
|
|
2
|
+
export interface SessionStorageIndexEntry {
|
|
3
|
+
path: string;
|
|
4
|
+
size: number;
|
|
5
|
+
mtimeMs: number;
|
|
6
|
+
}
|
|
7
|
+
export interface SessionStorageBackend {
|
|
8
|
+
init(): Promise<void>;
|
|
9
|
+
loadIndex(): Promise<Iterable<SessionStorageIndexEntry>>;
|
|
10
|
+
readFull(path: string): Promise<string | null>;
|
|
11
|
+
readSlices(path: string, prefixBytes: number, suffixBytes: number): Promise<[string, string]>;
|
|
12
|
+
writeFull(path: string, content: string, mtimeMs: number): Promise<void>;
|
|
13
|
+
append(path: string, line: string, mtimeMs: number): Promise<void>;
|
|
14
|
+
truncate(path: string, mtimeMs: number): Promise<void>;
|
|
15
|
+
remove(paths: string[]): Promise<void>;
|
|
16
|
+
move(src: string, dst: string, mtimeMs: number): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
export declare class IndexedSessionStorage implements SessionStorage {
|
|
19
|
+
#private;
|
|
20
|
+
constructor(backend: SessionStorageBackend);
|
|
21
|
+
initialize(): Promise<void>;
|
|
22
|
+
refresh(): Promise<void>;
|
|
23
|
+
drain(): Promise<void>;
|
|
24
|
+
ensureDirSync(_dir: string): void;
|
|
25
|
+
existsSync(path: string): boolean;
|
|
26
|
+
writeTextSync(path: string, content: string): void;
|
|
27
|
+
statSync(path: string): SessionStorageStat;
|
|
28
|
+
listFilesSync(dir: string, pattern: string): string[];
|
|
29
|
+
exists(path: string): Promise<boolean>;
|
|
30
|
+
readText(path: string): Promise<string>;
|
|
31
|
+
readTextSlices(path: string, prefixBytes: number, suffixBytes: number): Promise<[string, string]>;
|
|
32
|
+
writeText(path: string, content: string): Promise<void>;
|
|
33
|
+
rename(src: string, dst: string): Promise<void>;
|
|
34
|
+
unlink(path: string): Promise<void>;
|
|
35
|
+
deleteSessionWithArtifacts(sessionPath: string): Promise<void>;
|
|
36
|
+
openWriter(path: string, options?: {
|
|
37
|
+
flags?: "a" | "w";
|
|
38
|
+
onError?: (err: Error) => void;
|
|
39
|
+
}): SessionStorageWriter;
|
|
40
|
+
_writerClosed(writer: IndexedSessionStorageWriter): void;
|
|
41
|
+
_truncateForWriter(path: string): number;
|
|
42
|
+
_queueTruncate(path: string, mtimeMs: number, getError?: () => Error | undefined): Promise<void>;
|
|
43
|
+
_appendForWriter(path: string, line: string): number;
|
|
44
|
+
_queueAppend(path: string, line: string, mtimeMs: number, getError?: () => Error | undefined): Promise<void>;
|
|
45
|
+
}
|
|
46
|
+
declare class IndexedSessionStorageWriter implements SessionStorageWriter {
|
|
47
|
+
#private;
|
|
48
|
+
constructor(storage: IndexedSessionStorage, path: string, options?: {
|
|
49
|
+
flags?: "a" | "w";
|
|
50
|
+
onError?: (err: Error) => void;
|
|
51
|
+
});
|
|
52
|
+
writeLineSync(line: string): void;
|
|
53
|
+
writeLine(line: string): Promise<void>;
|
|
54
|
+
flush(): Promise<void>;
|
|
55
|
+
fsync(): Promise<void>;
|
|
56
|
+
close(): Promise<void>;
|
|
57
|
+
getError(): Error | undefined;
|
|
58
|
+
}
|
|
59
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { IndexedSessionStorage } from "./indexed-session-storage";
|
|
2
2
|
/**
|
|
3
3
|
* Minimal subset of the `bun:redis` `RedisClient` surface used by
|
|
4
4
|
* {@link RedisSessionStorage}. Keeping the contract narrow (and accepting any
|
|
@@ -7,6 +7,8 @@ import type { SessionStorage, SessionStorageStat, SessionStorageWriter } from ".
|
|
|
7
7
|
*/
|
|
8
8
|
export interface RedisSessionStorageClient {
|
|
9
9
|
get(key: string): Promise<string | null>;
|
|
10
|
+
getrange(key: string, start: number, end: number): Promise<string>;
|
|
11
|
+
strlen(key: string): Promise<number>;
|
|
10
12
|
set(key: string, value: string): Promise<unknown>;
|
|
11
13
|
append(key: string, value: string): Promise<number>;
|
|
12
14
|
del(...keys: string[]): Promise<number>;
|
|
@@ -26,7 +28,7 @@ export interface RedisSessionStorageOptions {
|
|
|
26
28
|
*/
|
|
27
29
|
prefix?: string;
|
|
28
30
|
/**
|
|
29
|
-
* Maximum number of keys returned per SCAN batch when warming the
|
|
31
|
+
* Maximum number of keys returned per SCAN batch when warming the metadata index.
|
|
30
32
|
* Default 500.
|
|
31
33
|
*/
|
|
32
34
|
scanCount?: number;
|
|
@@ -34,91 +36,16 @@ export interface RedisSessionStorageOptions {
|
|
|
34
36
|
/**
|
|
35
37
|
* Redis-backed implementation of {@link SessionStorage}. Each session JSONL
|
|
36
38
|
* file maps to a Redis STRING key, with per-key metadata (mtime) tracked in a
|
|
37
|
-
* single sibling HASH.
|
|
38
|
-
*
|
|
39
|
-
* `
|
|
40
|
-
* is async only, and the persist hot path (`writer.writeLineSync`) cannot
|
|
41
|
-
* wait on a network round-trip.
|
|
42
|
-
*
|
|
43
|
-
* Trade-offs vs `FileSessionStorage`:
|
|
44
|
-
* - Mirror state is process-local. Two processes writing the same session key
|
|
45
|
-
* will diverge until one of them reloads via {@link refresh}. This matches
|
|
46
|
-
* `FileSessionStorage`'s existing single-writer assumption.
|
|
47
|
-
* - `writeLineSync` updates the mirror synchronously and queues an async
|
|
48
|
-
* `APPEND`. The promise is awaited by `flush()` / `close()` / {@link drain}.
|
|
49
|
-
* A SIGKILL landing between the sync mirror update and the network round
|
|
50
|
-
* trip loses the last line; the file-backed implementation survives that
|
|
51
|
-
* window because bytes are handed to the kernel page cache before
|
|
52
|
-
* returning.
|
|
53
|
-
* - Blobs (image data) and tool artifact files still live on disk via
|
|
54
|
-
* `BlobStore` / `ArtifactManager`. Those are out of scope for this storage.
|
|
39
|
+
* single sibling HASH. This process keeps only a metadata index (`size`,
|
|
40
|
+
* `mtimeMs`) in memory so synchronous `existsSync` / `statSync` /
|
|
41
|
+
* `listFilesSync` calls remain available without mirroring full content.
|
|
55
42
|
*/
|
|
56
|
-
export declare class RedisSessionStorage
|
|
57
|
-
#private;
|
|
58
|
-
private constructor();
|
|
43
|
+
export declare class RedisSessionStorage extends IndexedSessionStorage {
|
|
59
44
|
/**
|
|
60
|
-
* Warm the
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* the existing keyspace.
|
|
45
|
+
* Warm the metadata index with every existing session key under the configured
|
|
46
|
+
* prefix and return the ready-to-use storage. Must be awaited before passing
|
|
47
|
+
* the storage into `SessionManager.create()` so synchronous lookups (session
|
|
48
|
+
* resume, recent sessions, EPERM-backup recovery) see the existing keyspace.
|
|
65
49
|
*/
|
|
66
50
|
static create(options: RedisSessionStorageOptions): Promise<RedisSessionStorage>;
|
|
67
|
-
/**
|
|
68
|
-
* Re-scan Redis and replace the mirror's contents. Call this from a
|
|
69
|
-
* different process that took over a session keyspace, or after an
|
|
70
|
-
* out-of-band write made by another agent.
|
|
71
|
-
*/
|
|
72
|
-
refresh(): Promise<void>;
|
|
73
|
-
/**
|
|
74
|
-
* Resolve once every pending background write (issued via `writeTextSync`
|
|
75
|
-
* or `writer.writeLineSync`) has been acknowledged by Redis. Throws if any
|
|
76
|
-
* background write failed since the last drain.
|
|
77
|
-
*
|
|
78
|
-
* Call this on graceful shutdown to avoid losing the last unflushed line.
|
|
79
|
-
* The session-manager's own `flush()` / `close()` already drain through
|
|
80
|
-
* the writer chain — this method exists for callers (test harnesses,
|
|
81
|
-
* subprocess-style consumers) that bypass the writer.
|
|
82
|
-
*/
|
|
83
|
-
drain(): Promise<void>;
|
|
84
|
-
ensureDirSync(_dir: string): void;
|
|
85
|
-
existsSync(path: string): boolean;
|
|
86
|
-
writeTextSync(path: string, content: string): void;
|
|
87
|
-
readTextSync(path: string): string;
|
|
88
|
-
statSync(path: string): SessionStorageStat;
|
|
89
|
-
listFilesSync(dir: string, pattern: string): string[];
|
|
90
|
-
exists(path: string): Promise<boolean>;
|
|
91
|
-
readText(path: string): Promise<string>;
|
|
92
|
-
readTextPrefix(path: string, maxBytes: number): Promise<string>;
|
|
93
|
-
writeText(path: string, content: string): Promise<void>;
|
|
94
|
-
rename(src: string, dst: string): Promise<void>;
|
|
95
|
-
unlink(path: string): Promise<void>;
|
|
96
|
-
deleteSessionWithArtifacts(sessionPath: string): Promise<void>;
|
|
97
|
-
openWriter(path: string, options?: {
|
|
98
|
-
flags?: "a" | "w";
|
|
99
|
-
onError?: (err: Error) => void;
|
|
100
|
-
}): SessionStorageWriter;
|
|
101
|
-
_writerClosed(writer: RedisSessionStorageWriter): void;
|
|
102
|
-
/** Mirror-only mutation, no Redis call. Used by writers to update local state synchronously. */
|
|
103
|
-
_mirrorAppend(path: string, line: string): void;
|
|
104
|
-
/** Mirror-only mutation, no Redis call. Used by writers opened with `flags: "w"` to truncate. */
|
|
105
|
-
_mirrorTruncate(path: string): void;
|
|
106
|
-
_remoteTruncate(path: string): Promise<void>;
|
|
107
|
-
_remoteAppend(path: string, line: string): Promise<void>;
|
|
108
|
-
/** Record a writer's pending promise on the storage-level tail so `drain()` waits for it. */
|
|
109
|
-
_attachPending(promise: Promise<void>): void;
|
|
110
|
-
}
|
|
111
|
-
declare class RedisSessionStorageWriter implements SessionStorageWriter {
|
|
112
|
-
#private;
|
|
113
|
-
constructor(storage: RedisSessionStorage, path: string, options?: {
|
|
114
|
-
flags?: "a" | "w";
|
|
115
|
-
onError?: (err: Error) => void;
|
|
116
|
-
});
|
|
117
|
-
writeLineSync(line: string): void;
|
|
118
|
-
writeLine(line: string): Promise<void>;
|
|
119
|
-
flush(): Promise<void>;
|
|
120
|
-
fsync(): Promise<void>;
|
|
121
|
-
close(): Promise<void>;
|
|
122
|
-
getError(): Error | undefined;
|
|
123
51
|
}
|
|
124
|
-
export {};
|
|
@@ -171,6 +171,21 @@ export interface SessionContext {
|
|
|
171
171
|
}
|
|
172
172
|
/** Lists session model strings to try when restoring, in fallback order. */
|
|
173
173
|
export declare function getRestorableSessionModels(models: Readonly<Record<string, string>>, lastModelChangeRole: string | undefined): string[];
|
|
174
|
+
/**
|
|
175
|
+
* Coarse lifecycle status of a session, derived from its last persisted message.
|
|
176
|
+
*
|
|
177
|
+
* - `complete` — the last assistant turn ended with no unanswered tool calls, i.e.
|
|
178
|
+
* the agent yielded control back to the user.
|
|
179
|
+
* - `interrupted` — work was cut off mid-flight: a trailing assistant turn with
|
|
180
|
+
* pending tool calls, a trailing tool result the agent never continued from, or
|
|
181
|
+
* a length-truncated turn.
|
|
182
|
+
* - `aborted` — the last assistant turn was cancelled by the user.
|
|
183
|
+
* - `error` — the last assistant turn ended in an error.
|
|
184
|
+
* - `pending` — a trailing user message with no assistant reply persisted after it.
|
|
185
|
+
* - `unknown` — status could not be determined (empty/header-only session, or the
|
|
186
|
+
* final message was larger than the tail window that was read).
|
|
187
|
+
*/
|
|
188
|
+
export type SessionStatus = "complete" | "interrupted" | "aborted" | "error" | "pending" | "unknown";
|
|
174
189
|
export interface SessionInfo {
|
|
175
190
|
path: string;
|
|
176
191
|
id: string;
|
|
@@ -186,6 +201,11 @@ export interface SessionInfo {
|
|
|
186
201
|
size: number;
|
|
187
202
|
firstMessage: string;
|
|
188
203
|
allMessagesText: string;
|
|
204
|
+
/**
|
|
205
|
+
* Coarse lifecycle status from the session's last persisted message. Optional:
|
|
206
|
+
* synthesized {@link SessionInfo}s (cross-project stubs, tests) leave it unset.
|
|
207
|
+
*/
|
|
208
|
+
status?: SessionStatus;
|
|
189
209
|
}
|
|
190
210
|
export type ReadonlySessionManager = Pick<SessionManager, "getCwd" | "getSessionDir" | "getSessionId" | "getSessionFile" | "getSessionName" | "getArtifactsDir" | "getArtifactManager" | "allocateArtifactPath" | "saveArtifact" | "getArtifactPath" | "getLeafId" | "getLeafEntry" | "getEntry" | "getLabel" | "getBranch" | "getHeader" | "getEntries" | "getTree" | "getUsageStatistics" | "putBlob">;
|
|
191
211
|
/** Exported for testing */
|
|
@@ -22,12 +22,12 @@ export interface SessionStorage {
|
|
|
22
22
|
ensureDirSync(dir: string): void;
|
|
23
23
|
existsSync(path: string): boolean;
|
|
24
24
|
writeTextSync(path: string, content: string): void;
|
|
25
|
-
readTextSync(path: string): string;
|
|
26
25
|
statSync(path: string): SessionStorageStat;
|
|
27
26
|
listFilesSync(dir: string, pattern: string): string[];
|
|
28
27
|
exists(path: string): Promise<boolean>;
|
|
29
28
|
readText(path: string): Promise<string>;
|
|
30
|
-
|
|
29
|
+
/** Read the requested UTF-8 byte windows from the head and tail of the file. */
|
|
30
|
+
readTextSlices(path: string, prefixBytes: number, suffixBytes: number): Promise<[string, string]>;
|
|
31
31
|
writeText(path: string, content: string): Promise<void>;
|
|
32
32
|
rename(path: string, nextPath: string): Promise<void>;
|
|
33
33
|
unlink(path: string): Promise<void>;
|
|
@@ -41,12 +41,11 @@ export declare class FileSessionStorage implements SessionStorage {
|
|
|
41
41
|
ensureDirSync(dir: string): void;
|
|
42
42
|
existsSync(path: string): boolean;
|
|
43
43
|
writeTextSync(fpath: string, content: string): void;
|
|
44
|
-
readTextSync(fpath: string): string;
|
|
45
44
|
statSync(path: string): SessionStorageStat;
|
|
46
45
|
listFilesSync(dir: string, pattern: string): string[];
|
|
47
46
|
exists(path: string): Promise<boolean>;
|
|
48
47
|
readText(path: string): Promise<string>;
|
|
49
|
-
|
|
48
|
+
readTextSlices(path: string, prefixBytes: number, suffixBytes: number): Promise<[string, string]>;
|
|
50
49
|
writeText(path: string, content: string): Promise<void>;
|
|
51
50
|
rename(path: string, nextPath: string): Promise<void>;
|
|
52
51
|
unlink(path: string): Promise<void>;
|
|
@@ -70,13 +69,12 @@ export declare class MemorySessionStorage implements SessionStorage {
|
|
|
70
69
|
* creates the entry. External callers should go through `openWriter()`
|
|
71
70
|
* rather than touching the mirror directly.
|
|
72
71
|
*/
|
|
73
|
-
|
|
74
|
-
readTextSync(path: string): string;
|
|
72
|
+
appendSync(path: string, chunk: string): void;
|
|
75
73
|
statSync(path: string): SessionStorageStat;
|
|
76
74
|
listFilesSync(dir: string, pattern: string): string[];
|
|
77
75
|
exists(path: string): Promise<boolean>;
|
|
78
76
|
readText(path: string): Promise<string>;
|
|
79
|
-
|
|
77
|
+
readTextSlices(path: string, prefixBytes: number, suffixBytes: number): Promise<[string, string]>;
|
|
80
78
|
writeText(path: string, content: string): Promise<void>;
|
|
81
79
|
rename(path: string, nextPath: string): Promise<void>;
|
|
82
80
|
unlink(path: string): Promise<void>;
|