toc-ocra 0.2.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/LICENSE +21 -0
- package/README.md +70 -0
- package/assets/icon.svg +1 -0
- package/dist/plugin/renderer.css +2 -0
- package/dist/plugin/renderer.css.map +7 -0
- package/dist/plugin/renderer.js +2 -0
- package/dist/plugin/renderer.js.map +7 -0
- package/dist/src/config.d.ts +66 -0
- package/dist/src/config.js +173 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/control/pairing.d.ts +44 -0
- package/dist/src/control/pairing.js +99 -0
- package/dist/src/control/pairing.js.map +1 -0
- package/dist/src/exec/script-runner.d.ts +9 -0
- package/dist/src/exec/script-runner.js +110 -0
- package/dist/src/exec/script-runner.js.map +1 -0
- package/dist/src/health/server.d.ts +74 -0
- package/dist/src/health/server.js +248 -0
- package/dist/src/health/server.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +173 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/logging/diagnostic-log.d.ts +16 -0
- package/dist/src/logging/diagnostic-log.js +128 -0
- package/dist/src/logging/diagnostic-log.js.map +1 -0
- package/dist/src/providers/cli/claude.d.ts +2 -0
- package/dist/src/providers/cli/claude.js +48 -0
- package/dist/src/providers/cli/claude.js.map +1 -0
- package/dist/src/providers/cli/codex.d.ts +2 -0
- package/dist/src/providers/cli/codex.js +67 -0
- package/dist/src/providers/cli/codex.js.map +1 -0
- package/dist/src/providers/cli/gemini.d.ts +2 -0
- package/dist/src/providers/cli/gemini.js +30 -0
- package/dist/src/providers/cli/gemini.js.map +1 -0
- package/dist/src/providers/cli/grok.d.ts +2 -0
- package/dist/src/providers/cli/grok.js +29 -0
- package/dist/src/providers/cli/grok.js.map +1 -0
- package/dist/src/providers/cli/opencode.d.ts +2 -0
- package/dist/src/providers/cli/opencode.js +29 -0
- package/dist/src/providers/cli/opencode.js.map +1 -0
- package/dist/src/providers/detection.d.ts +11 -0
- package/dist/src/providers/detection.js +96 -0
- package/dist/src/providers/detection.js.map +1 -0
- package/dist/src/providers/model-catalog-collector.d.ts +22 -0
- package/dist/src/providers/model-catalog-collector.js +66 -0
- package/dist/src/providers/model-catalog-collector.js.map +1 -0
- package/dist/src/providers/model-catalog.d.ts +45 -0
- package/dist/src/providers/model-catalog.js +382 -0
- package/dist/src/providers/model-catalog.js.map +1 -0
- package/dist/src/providers/provider.d.ts +49 -0
- package/dist/src/providers/provider.js +63 -0
- package/dist/src/providers/provider.js.map +1 -0
- package/dist/src/providers/registry.d.ts +31 -0
- package/dist/src/providers/registry.js +60 -0
- package/dist/src/providers/registry.js.map +1 -0
- package/dist/src/runs/orphan-registry.d.ts +24 -0
- package/dist/src/runs/orphan-registry.js +63 -0
- package/dist/src/runs/orphan-registry.js.map +1 -0
- package/dist/src/runs/process-tree.d.ts +21 -0
- package/dist/src/runs/process-tree.js +95 -0
- package/dist/src/runs/process-tree.js.map +1 -0
- package/dist/src/runs/run-supervisor.d.ts +63 -0
- package/dist/src/runs/run-supervisor.js +285 -0
- package/dist/src/runs/run-supervisor.js.map +1 -0
- package/dist/src/runtime/agent-runtime.d.ts +68 -0
- package/dist/src/runtime/agent-runtime.js +340 -0
- package/dist/src/runtime/agent-runtime.js.map +1 -0
- package/dist/src/runtime/agent-service.d.ts +33 -0
- package/dist/src/runtime/agent-service.js +181 -0
- package/dist/src/runtime/agent-service.js.map +1 -0
- package/dist/src/runtime/cli/hydrate-shell-path.d.ts +33 -0
- package/dist/src/runtime/cli/hydrate-shell-path.js +173 -0
- package/dist/src/runtime/cli/hydrate-shell-path.js.map +1 -0
- package/dist/src/session/terminal-line-sanitizer.d.ts +7 -0
- package/dist/src/session/terminal-line-sanitizer.js +21 -0
- package/dist/src/session/terminal-line-sanitizer.js.map +1 -0
- package/dist/src/session/terminal-tail-buffer.d.ts +70 -0
- package/dist/src/session/terminal-tail-buffer.js +149 -0
- package/dist/src/session/terminal-tail-buffer.js.map +1 -0
- package/dist/src/shared/cli-detection-types.d.ts +19 -0
- package/dist/src/shared/cli-detection-types.js +2 -0
- package/dist/src/shared/cli-detection-types.js.map +1 -0
- package/dist/src/shared/node-cli-command-resolution.d.ts +19 -0
- package/dist/src/shared/node-cli-command-resolution.js +173 -0
- package/dist/src/shared/node-cli-command-resolution.js.map +1 -0
- package/dist/src/transport/gateway-client.d.ts +38 -0
- package/dist/src/transport/gateway-client.js +73 -0
- package/dist/src/transport/gateway-client.js.map +1 -0
- package/dist/src/types/protocol.d.ts +172 -0
- package/dist/src/types/protocol.js +55 -0
- package/dist/src/types/protocol.js.map +1 -0
- package/dist/src/workspace/directory-browser.d.ts +17 -0
- package/dist/src/workspace/directory-browser.js +47 -0
- package/dist/src/workspace/directory-browser.js.map +1 -0
- package/dist/src/workspace/workspace-manager.d.ts +41 -0
- package/dist/src/workspace/workspace-manager.js +436 -0
- package/dist/src/workspace/workspace-manager.js.map +1 -0
- package/locales/en.json +66 -0
- package/locales/zh-CN.json +66 -0
- package/package.json +90 -0
- package/scripts/service.mjs +174 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { delimiter } from 'node:path';
|
|
3
|
+
// Why: GUI-launched Electron on macOS/Linux inherits a minimal PATH from launchd
|
|
4
|
+
// that does not include dirs appended by the user's shell rc files (~/.zshrc,
|
|
5
|
+
// ~/.bashrc). Tools installed into ~/.opencode/bin, ~/.cargo/bin, pyenv/volta
|
|
6
|
+
// shims, and countless other user-local locations end up invisible to our
|
|
7
|
+
// `which` probe even though they work fine from Terminal (see stablyai/orca#829).
|
|
8
|
+
//
|
|
9
|
+
// Rather than play whack-a-mole adding every agent's install dir to a hardcoded
|
|
10
|
+
// list, we spawn the user's login shell once per app session and read the PATH
|
|
11
|
+
// it would export. This matches the behavior of every popular Electron app that
|
|
12
|
+
// handles this problem (Hyper, VS Code, Cursor, etc. via shell-env/fix-path) —
|
|
13
|
+
// we implement it inline to avoid adding a dependency.
|
|
14
|
+
const DELIMITER = '__ORCA_SHELL_PATH__';
|
|
15
|
+
const SPAWN_TIMEOUT_MS = 5000;
|
|
16
|
+
// ANSI escape sequences can leak into the captured output when the user's rc
|
|
17
|
+
// files print banners or set colored prompts. Strip them before parsing.
|
|
18
|
+
const ANSI_RE = /\x1b\[[0-9;?]*[A-Za-z]/g; // eslint-disable-line no-control-regex
|
|
19
|
+
let cached = null;
|
|
20
|
+
/** @internal - tests need a clean hydration cache between cases. */
|
|
21
|
+
export function _resetHydrateShellPathCache() {
|
|
22
|
+
cached = null;
|
|
23
|
+
}
|
|
24
|
+
function pickShell() {
|
|
25
|
+
if (process.platform === 'win32') {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const shell = process.env.SHELL;
|
|
29
|
+
if (shell && shell.length > 0) {
|
|
30
|
+
return shell;
|
|
31
|
+
}
|
|
32
|
+
return process.platform === 'darwin' ? '/bin/zsh' : '/bin/bash';
|
|
33
|
+
}
|
|
34
|
+
function parseCapturedPath(stdout) {
|
|
35
|
+
const cleaned = stdout.replace(ANSI_RE, '');
|
|
36
|
+
const first = cleaned.indexOf(DELIMITER);
|
|
37
|
+
if (first < 0) {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
const second = cleaned.indexOf(DELIMITER, first + DELIMITER.length);
|
|
41
|
+
if (second < 0) {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
const value = cleaned.slice(first + DELIMITER.length, second).trim();
|
|
45
|
+
if (!value) {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
// Why: Set preserves insertion order, and PATH resolution is first-match-wins,
|
|
49
|
+
// so de-duping this way keeps the user's rc-file ordering intact.
|
|
50
|
+
return [
|
|
51
|
+
...new Set(value
|
|
52
|
+
.split(delimiter)
|
|
53
|
+
.map((s) => s.trim())
|
|
54
|
+
.filter(Boolean))
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
function spawnShellAndReadPath(shell) {
|
|
58
|
+
return new Promise((resolve) => {
|
|
59
|
+
// Why: printing $PATH between delimiters is resilient to rc-file banners,
|
|
60
|
+
// MOTDs, and `echo` invocations that shells like fish print unprompted.
|
|
61
|
+
// `-ilc` runs the shell as a login+interactive so both .profile/.zprofile
|
|
62
|
+
// and .bashrc/.zshrc are sourced — matches what `which` in Terminal sees.
|
|
63
|
+
const command = `printf '%s' '${DELIMITER}'; printf '%s' "$PATH"; printf '%s' '${DELIMITER}'`;
|
|
64
|
+
let finished = false;
|
|
65
|
+
let stdout = '';
|
|
66
|
+
let timer = null;
|
|
67
|
+
const child = spawn(shell, ['-ilc', command], {
|
|
68
|
+
// Why: inherit current env so the shell sees the same baseline, then let
|
|
69
|
+
// it layer its own rc files on top. Do NOT forward stdio — some shells
|
|
70
|
+
// (oh-my-zsh setups, powerlevel10k) print a lot to stderr on startup,
|
|
71
|
+
// and we don't want that in Orca's console.
|
|
72
|
+
env: process.env,
|
|
73
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
74
|
+
detached: false
|
|
75
|
+
});
|
|
76
|
+
const cleanup = () => {
|
|
77
|
+
if (timer) {
|
|
78
|
+
clearTimeout(timer);
|
|
79
|
+
timer = null;
|
|
80
|
+
}
|
|
81
|
+
child.stdout.off('data', onStdoutData);
|
|
82
|
+
child.off('error', onError);
|
|
83
|
+
child.off('close', onClose);
|
|
84
|
+
};
|
|
85
|
+
const finish = (result) => {
|
|
86
|
+
if (finished) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
finished = true;
|
|
90
|
+
cleanup();
|
|
91
|
+
resolve(result);
|
|
92
|
+
};
|
|
93
|
+
timer = setTimeout(() => {
|
|
94
|
+
// Why: slow rc files (corporate env setup, nvm eager init) can exceed
|
|
95
|
+
// our budget. Kill the shell and fall back to process.env rather than
|
|
96
|
+
// blocking the Agents pane indefinitely.
|
|
97
|
+
try {
|
|
98
|
+
child.kill('SIGKILL');
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// ignore
|
|
102
|
+
}
|
|
103
|
+
finish({ segments: [], ok: false, failureReason: 'timeout' });
|
|
104
|
+
}, SPAWN_TIMEOUT_MS);
|
|
105
|
+
const onStdoutData = (chunk) => {
|
|
106
|
+
stdout += chunk.toString('utf8');
|
|
107
|
+
};
|
|
108
|
+
const onError = () => {
|
|
109
|
+
finish({ segments: [], ok: false, failureReason: 'spawn_error' });
|
|
110
|
+
};
|
|
111
|
+
const onClose = () => {
|
|
112
|
+
const segments = parseCapturedPath(stdout);
|
|
113
|
+
if (segments.length === 0) {
|
|
114
|
+
finish({ segments: [], ok: false, failureReason: 'empty_path' });
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
finish({ segments, ok: true, failureReason: 'none' });
|
|
118
|
+
};
|
|
119
|
+
child.stdout.on('data', onStdoutData);
|
|
120
|
+
child.on('error', onError);
|
|
121
|
+
child.on('close', onClose);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Spawn the user's login shell once and return the PATH it would export.
|
|
126
|
+
* Caches the promise for the lifetime of the process — call
|
|
127
|
+
* `_resetHydrateShellPathCache()` in tests or `hydrateShellPath({ force: true })`
|
|
128
|
+
* when the user asks to re-probe (e.g. after installing a new CLI).
|
|
129
|
+
*/
|
|
130
|
+
export function hydrateShellPath(options = {}) {
|
|
131
|
+
if (cached && !options.force) {
|
|
132
|
+
return cached;
|
|
133
|
+
}
|
|
134
|
+
const shell = options.shellOverride !== undefined ? options.shellOverride : pickShell();
|
|
135
|
+
if (!shell) {
|
|
136
|
+
// Windows uses cmd/PowerShell rather than a POSIX login shell — the
|
|
137
|
+
// `patchPackagedProcessPath` static list is sufficient there.
|
|
138
|
+
cached = Promise.resolve({ segments: [], ok: false, failureReason: 'no_shell' });
|
|
139
|
+
return cached;
|
|
140
|
+
}
|
|
141
|
+
cached = (options.spawner ?? spawnShellAndReadPath)(shell);
|
|
142
|
+
return cached;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Promote shell-discovered PATH segments to the front of process.env.PATH,
|
|
146
|
+
* preserving shell ordering and avoiding duplicates. Returns the segments that
|
|
147
|
+
* were newly added so callers can log/telemetry on nontrivial hydrations.
|
|
148
|
+
*/
|
|
149
|
+
export function mergePathSegments(segments) {
|
|
150
|
+
if (segments.length === 0) {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
const current = process.env.PATH ?? '';
|
|
154
|
+
const currentSegments = current.split(delimiter).filter(Boolean);
|
|
155
|
+
const shellSegments = [...new Set(segments)];
|
|
156
|
+
const shellSegmentSet = new Set(shellSegments);
|
|
157
|
+
const existing = new Set(currentSegments);
|
|
158
|
+
const added = shellSegments.filter((segment) => !existing.has(segment));
|
|
159
|
+
const merged = [
|
|
160
|
+
...shellSegments,
|
|
161
|
+
...currentSegments.filter((segment) => !shellSegmentSet.has(segment))
|
|
162
|
+
];
|
|
163
|
+
const next = merged.join(delimiter);
|
|
164
|
+
if (next === current) {
|
|
165
|
+
return [];
|
|
166
|
+
}
|
|
167
|
+
// Why: shell-provided entries must win over hardcoded packaged-app fallbacks.
|
|
168
|
+
// A seeded fallback can point at a stale CLI while the user's shell resolves
|
|
169
|
+
// a healthy one from the same directory list in a different order.
|
|
170
|
+
process.env.PATH = next;
|
|
171
|
+
return added;
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=hydrate-shell-path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydrate-shell-path.js","sourceRoot":"","sources":["../../../../src/runtime/cli/hydrate-shell-path.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal row sanitization. The escape, control-byte and credential patterns
|
|
3
|
+
* live here so there is a single place to audit what can leave the device when
|
|
4
|
+
* terminal text is read on demand.
|
|
5
|
+
*/
|
|
6
|
+
/** Strip escapes and control bytes, redact credential-shaped values, drop cell padding. */
|
|
7
|
+
export declare function sanitizeTerminalLine(line: string): string;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal row sanitization. The escape, control-byte and credential patterns
|
|
3
|
+
* live here so there is a single place to audit what can leave the device when
|
|
4
|
+
* terminal text is read on demand.
|
|
5
|
+
*/
|
|
6
|
+
// CSI (`ESC [ … final`), terminated OSC (`ESC ] … BEL/ST`) and two-character escapes.
|
|
7
|
+
const TERMINAL_ESCAPE = /\u001b(?:\][^\u0007]*?(?:\u0007|\u001b\\)|\[[0-?]*[ -/]*[@-~]|[@-Z\\-_])/g;
|
|
8
|
+
// Everything unprintable except tab.
|
|
9
|
+
const CONTROL_CHARACTER = /[\u0000-\u0008\u000b-\u001f\u007f]/g;
|
|
10
|
+
// A labeled key redacts to end of line: `Authorization: Bearer <token>` would
|
|
11
|
+
// otherwise stop at the scheme and leave the token itself in the output.
|
|
12
|
+
const SENSITIVE_VALUE = /\b(?:sk|rk|pk|ghp|github_pat)_[A-Za-z0-9._-]+|\bBearer\s+\S+|\b(?:api[_-]?key|token|authorization|x-mcp-token)\s*[:=]\s*\S[^\r\n]*/gi;
|
|
13
|
+
/** Strip escapes and control bytes, redact credential-shaped values, drop cell padding. */
|
|
14
|
+
export function sanitizeTerminalLine(line) {
|
|
15
|
+
return line
|
|
16
|
+
.replace(TERMINAL_ESCAPE, '')
|
|
17
|
+
.replace(CONTROL_CHARACTER, '')
|
|
18
|
+
.replace(SENSITIVE_VALUE, '[redacted]')
|
|
19
|
+
.replace(/\s+$/, '');
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=terminal-line-sanitizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-line-sanitizer.js","sourceRoot":"","sources":["../../../src/session/terminal-line-sanitizer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,sFAAsF;AACtF,MAAM,eAAe,GAAG,2EAA2E,CAAA;AACnG,qCAAqC;AACrC,MAAM,iBAAiB,GAAG,qCAAqC,CAAA;AAC/D,8EAA8E;AAC9E,yEAAyE;AACzE,MAAM,eAAe,GACnB,sIAAsI,CAAA;AAExI,2FAA2F;AAC3F,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO,IAAI;SACR,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC;SAC5B,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC;SAC9B,OAAO,CAAC,eAAe,EAAE,YAAY,CAAC;SACtC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;AACxB,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded terminal tail with absolute line cursors, so a client can read the
|
|
3
|
+
* newest rows and then page backwards without re-reading what it already has.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors Orca's split between a line-oriented tail and the still-unterminated
|
|
6
|
+
* partial line. Two properties matter for cost:
|
|
7
|
+
*
|
|
8
|
+
* - Appends are O(chunk). The naive `output = (output + chunk).slice(-N)` form
|
|
9
|
+
* re-materializes the whole retained tail on every PTY chunk, which is O(N)
|
|
10
|
+
* per write; a busy CLI turns that into a per-keystroke copy of 128 KiB.
|
|
11
|
+
* - Reads are O(requested lines). Escape stripping and redaction run on the
|
|
12
|
+
* returned rows only, never on the whole buffer.
|
|
13
|
+
*
|
|
14
|
+
* Retained rows are raw. Sanitizing on read keeps escape sequences that straddle
|
|
15
|
+
* a chunk boundary intact until the full sequence has arrived.
|
|
16
|
+
*/
|
|
17
|
+
/** Retained completed rows. Matches Orca's `MAX_TAIL_LINES`. */
|
|
18
|
+
export declare const MAX_TAIL_LINES = 2000;
|
|
19
|
+
/** Retained characters across completed rows. Matches Orca's `MAX_TAIL_CHARS`. */
|
|
20
|
+
export declare const MAX_TAIL_CHARS: number;
|
|
21
|
+
/** A CLI that redraws a spinner without ever emitting a newline cannot grow past this. */
|
|
22
|
+
export declare const MAX_TAIL_PARTIAL_CHARS = 4000;
|
|
23
|
+
/** Rows returned when the caller does not ask for a specific count. */
|
|
24
|
+
export declare const DEFAULT_TAIL_READ_LIMIT = 120;
|
|
25
|
+
export declare const MAX_TAIL_READ_LIMIT = 2000;
|
|
26
|
+
/** Character budget applied after the row limit, so wide rows cannot blow up a response. */
|
|
27
|
+
export declare const MAX_TAIL_READ_CHARS: number;
|
|
28
|
+
export type TerminalTailReadOptions = {
|
|
29
|
+
/** Rows to return, clamped to `MAX_TAIL_READ_LIMIT`. */
|
|
30
|
+
limit?: number;
|
|
31
|
+
/** Absolute cursor to read backwards from. Omit for the newest rows. */
|
|
32
|
+
beforeCursor?: number;
|
|
33
|
+
};
|
|
34
|
+
export type TerminalTailRead = {
|
|
35
|
+
lines: string[];
|
|
36
|
+
/** Absolute index of `lines[0]`. Pass it back as `beforeCursor` to page further up. */
|
|
37
|
+
startCursor: number;
|
|
38
|
+
/** Absolute index just past the last completed row returned. */
|
|
39
|
+
nextCursor: number;
|
|
40
|
+
/** Oldest absolute index still retained. `startCursor` cannot go below it. */
|
|
41
|
+
oldestCursor: number;
|
|
42
|
+
/** Absolute count of rows completed so far. */
|
|
43
|
+
latestCursor: number;
|
|
44
|
+
/** More retained rows exist above `startCursor`. */
|
|
45
|
+
hasMore: boolean;
|
|
46
|
+
/** Rows older than `oldestCursor` were dropped to stay within the caps. */
|
|
47
|
+
truncated: boolean;
|
|
48
|
+
/** The character budget clipped the response. */
|
|
49
|
+
limited: boolean;
|
|
50
|
+
/** Milliseconds since the CLI last wrote anything, or undefined if it never did. */
|
|
51
|
+
idleMs: number | undefined;
|
|
52
|
+
};
|
|
53
|
+
export declare class TerminalTailBuffer {
|
|
54
|
+
/** Completed rows, raw. Dropped head slots are blanked, then compacted in batches. */
|
|
55
|
+
private lines;
|
|
56
|
+
private head;
|
|
57
|
+
private chars;
|
|
58
|
+
/** Absolute count of completed rows, including dropped ones. Defines cursor space. */
|
|
59
|
+
private completedCount;
|
|
60
|
+
private partial;
|
|
61
|
+
private droppedRows;
|
|
62
|
+
private lastOutputAt;
|
|
63
|
+
get lastWriteAt(): number | undefined;
|
|
64
|
+
append(chunk: string, at?: number): void;
|
|
65
|
+
read(options?: TerminalTailReadOptions, now?: number): TerminalTailRead;
|
|
66
|
+
private appendPartial;
|
|
67
|
+
private commitPartial;
|
|
68
|
+
private trim;
|
|
69
|
+
private dropHead;
|
|
70
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { sanitizeTerminalLine } from './terminal-line-sanitizer.js';
|
|
2
|
+
/**
|
|
3
|
+
* Bounded terminal tail with absolute line cursors, so a client can read the
|
|
4
|
+
* newest rows and then page backwards without re-reading what it already has.
|
|
5
|
+
*
|
|
6
|
+
* Mirrors Orca's split between a line-oriented tail and the still-unterminated
|
|
7
|
+
* partial line. Two properties matter for cost:
|
|
8
|
+
*
|
|
9
|
+
* - Appends are O(chunk). The naive `output = (output + chunk).slice(-N)` form
|
|
10
|
+
* re-materializes the whole retained tail on every PTY chunk, which is O(N)
|
|
11
|
+
* per write; a busy CLI turns that into a per-keystroke copy of 128 KiB.
|
|
12
|
+
* - Reads are O(requested lines). Escape stripping and redaction run on the
|
|
13
|
+
* returned rows only, never on the whole buffer.
|
|
14
|
+
*
|
|
15
|
+
* Retained rows are raw. Sanitizing on read keeps escape sequences that straddle
|
|
16
|
+
* a chunk boundary intact until the full sequence has arrived.
|
|
17
|
+
*/
|
|
18
|
+
/** Retained completed rows. Matches Orca's `MAX_TAIL_LINES`. */
|
|
19
|
+
export const MAX_TAIL_LINES = 2_000;
|
|
20
|
+
/** Retained characters across completed rows. Matches Orca's `MAX_TAIL_CHARS`. */
|
|
21
|
+
export const MAX_TAIL_CHARS = 256 * 1024;
|
|
22
|
+
/** A CLI that redraws a spinner without ever emitting a newline cannot grow past this. */
|
|
23
|
+
export const MAX_TAIL_PARTIAL_CHARS = 4_000;
|
|
24
|
+
/** Rows returned when the caller does not ask for a specific count. */
|
|
25
|
+
export const DEFAULT_TAIL_READ_LIMIT = 120;
|
|
26
|
+
export const MAX_TAIL_READ_LIMIT = MAX_TAIL_LINES;
|
|
27
|
+
/** Character budget applied after the row limit, so wide rows cannot blow up a response. */
|
|
28
|
+
export const MAX_TAIL_READ_CHARS = 32 * 1024;
|
|
29
|
+
/** Empty head slots tolerated before the backing array is compacted. */
|
|
30
|
+
const HEAD_COMPACT_THRESHOLD = 1_024;
|
|
31
|
+
export class TerminalTailBuffer {
|
|
32
|
+
/** Completed rows, raw. Dropped head slots are blanked, then compacted in batches. */
|
|
33
|
+
lines = [];
|
|
34
|
+
head = 0;
|
|
35
|
+
chars = 0;
|
|
36
|
+
/** Absolute count of completed rows, including dropped ones. Defines cursor space. */
|
|
37
|
+
completedCount = 0;
|
|
38
|
+
partial = '';
|
|
39
|
+
droppedRows = false;
|
|
40
|
+
lastOutputAt;
|
|
41
|
+
get lastWriteAt() {
|
|
42
|
+
return this.lastOutputAt;
|
|
43
|
+
}
|
|
44
|
+
append(chunk, at = Date.now()) {
|
|
45
|
+
if (!chunk)
|
|
46
|
+
return;
|
|
47
|
+
this.lastOutputAt = at;
|
|
48
|
+
let index = 0;
|
|
49
|
+
for (;;) {
|
|
50
|
+
const newline = chunk.indexOf('\n', index);
|
|
51
|
+
if (newline === -1) {
|
|
52
|
+
this.appendPartial(chunk.slice(index));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// Trim the CR of a CRLF pair so it does not survive as a row rewrite.
|
|
56
|
+
const end = newline > index && chunk.charCodeAt(newline - 1) === 13 ? newline - 1 : newline;
|
|
57
|
+
this.appendPartial(chunk.slice(index, end));
|
|
58
|
+
this.commitPartial();
|
|
59
|
+
index = newline + 1;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
read(options = {}, now = Date.now()) {
|
|
63
|
+
const limit = clampLimit(options.limit);
|
|
64
|
+
const retained = this.lines.length - this.head;
|
|
65
|
+
const oldestCursor = this.completedCount - retained;
|
|
66
|
+
const latestCursor = this.completedCount;
|
|
67
|
+
// A preview read shows what the screen shows, including the row being written.
|
|
68
|
+
const includePartial = options.beforeCursor === undefined && this.partial.length > 0;
|
|
69
|
+
const endCursor = options.beforeCursor === undefined
|
|
70
|
+
? latestCursor
|
|
71
|
+
: Math.min(Math.max(options.beforeCursor, oldestCursor), latestCursor);
|
|
72
|
+
const rowBudget = Math.max(0, limit - (includePartial ? 1 : 0));
|
|
73
|
+
const startCursor = Math.max(oldestCursor, endCursor - rowBudget);
|
|
74
|
+
const rows = [];
|
|
75
|
+
for (let cursor = startCursor; cursor < endCursor; cursor += 1) {
|
|
76
|
+
rows.push(sanitizeTerminalLine(this.lines[this.head + (cursor - oldestCursor)] ?? ''));
|
|
77
|
+
}
|
|
78
|
+
if (includePartial)
|
|
79
|
+
rows.push(sanitizeTerminalLine(this.partial));
|
|
80
|
+
const clipped = clipToCharacterBudget(rows, MAX_TAIL_READ_CHARS);
|
|
81
|
+
return {
|
|
82
|
+
lines: clipped.lines,
|
|
83
|
+
startCursor,
|
|
84
|
+
nextCursor: endCursor,
|
|
85
|
+
oldestCursor,
|
|
86
|
+
latestCursor,
|
|
87
|
+
hasMore: startCursor > oldestCursor,
|
|
88
|
+
truncated: this.droppedRows,
|
|
89
|
+
limited: clipped.limited,
|
|
90
|
+
idleMs: this.lastOutputAt === undefined ? undefined : Math.max(0, now - this.lastOutputAt)
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
appendPartial(text) {
|
|
94
|
+
if (!text)
|
|
95
|
+
return;
|
|
96
|
+
const carriage = text.lastIndexOf('\r');
|
|
97
|
+
// A bare CR rewrites the current row on a real terminal; keep only what would stay visible.
|
|
98
|
+
const next = carriage === -1 ? `${this.partial}${text}` : text.slice(carriage + 1);
|
|
99
|
+
this.partial =
|
|
100
|
+
next.length > MAX_TAIL_PARTIAL_CHARS ? next.slice(-MAX_TAIL_PARTIAL_CHARS) : next;
|
|
101
|
+
}
|
|
102
|
+
commitPartial() {
|
|
103
|
+
const line = this.partial;
|
|
104
|
+
this.partial = '';
|
|
105
|
+
this.lines.push(line);
|
|
106
|
+
this.chars += line.length;
|
|
107
|
+
this.completedCount += 1;
|
|
108
|
+
this.trim();
|
|
109
|
+
}
|
|
110
|
+
trim() {
|
|
111
|
+
while (this.lines.length - this.head > MAX_TAIL_LINES)
|
|
112
|
+
this.dropHead();
|
|
113
|
+
while (this.head < this.lines.length && this.chars > MAX_TAIL_CHARS)
|
|
114
|
+
this.dropHead();
|
|
115
|
+
if (this.head >= HEAD_COMPACT_THRESHOLD) {
|
|
116
|
+
this.lines = this.lines.slice(this.head);
|
|
117
|
+
this.head = 0;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
dropHead() {
|
|
121
|
+
const line = this.lines[this.head];
|
|
122
|
+
if (line === undefined)
|
|
123
|
+
return;
|
|
124
|
+
this.chars -= line.length;
|
|
125
|
+
// Release the row before compaction so a large tail is not pinned by an empty slot.
|
|
126
|
+
this.lines[this.head] = '';
|
|
127
|
+
this.head += 1;
|
|
128
|
+
this.droppedRows = true;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
function clampLimit(limit) {
|
|
132
|
+
if (limit === undefined || !Number.isFinite(limit))
|
|
133
|
+
return DEFAULT_TAIL_READ_LIMIT;
|
|
134
|
+
return Math.max(1, Math.min(Math.floor(limit), MAX_TAIL_READ_LIMIT));
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Apply the character budget from the newest row backwards, so the rows closest
|
|
138
|
+
* to what the CLI is doing now are the ones that survive.
|
|
139
|
+
*/
|
|
140
|
+
function clipToCharacterBudget(rows, budget) {
|
|
141
|
+
let total = 0;
|
|
142
|
+
for (let index = rows.length - 1; index >= 0; index -= 1) {
|
|
143
|
+
total += rows[index].length + 1;
|
|
144
|
+
if (total > budget)
|
|
145
|
+
return { lines: rows.slice(index + 1), limited: true };
|
|
146
|
+
}
|
|
147
|
+
return { lines: rows, limited: false };
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=terminal-tail-buffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-tail-buffer.js","sourceRoot":"","sources":["../../../src/session/terminal-tail-buffer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ShellHydrationFailureReason } from '../runtime/cli/hydrate-shell-path.js';
|
|
2
|
+
export type CliProviderDetection = {
|
|
3
|
+
id: string;
|
|
4
|
+
installed: boolean;
|
|
5
|
+
available: boolean;
|
|
6
|
+
matchedDetectionCommand?: string;
|
|
7
|
+
resolvedPath?: string;
|
|
8
|
+
version?: string;
|
|
9
|
+
detail?: string;
|
|
10
|
+
};
|
|
11
|
+
export type CliDetectionSnapshot = {
|
|
12
|
+
providers: CliProviderDetection[];
|
|
13
|
+
detectedIds: string[];
|
|
14
|
+
addedPathSegments: string[];
|
|
15
|
+
shellHydrationOk: boolean;
|
|
16
|
+
pathSource: 'shell_hydrated' | 'process_path';
|
|
17
|
+
pathFailureReason: ShellHydrationFailureReason;
|
|
18
|
+
refreshedAt: string;
|
|
19
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-detection-types.js","sourceRoot":"","sources":["../../../src/shared/cli-detection-types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
type ResolveCommandOptions = {
|
|
2
|
+
pathEnv?: string | null;
|
|
3
|
+
platform?: NodeJS.Platform;
|
|
4
|
+
homePath?: string;
|
|
5
|
+
};
|
|
6
|
+
export type ResolvedCliCommand = {
|
|
7
|
+
command: string;
|
|
8
|
+
found: boolean;
|
|
9
|
+
path?: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function resolveCliCommand(commandName: string, options?: ResolveCommandOptions): string;
|
|
12
|
+
export declare function findCliCommand(commandName: string, options?: ResolveCommandOptions): string | null;
|
|
13
|
+
/** Resolve without conflating a launch fallback with an installed executable. */
|
|
14
|
+
export declare function resolveCliCommandDetailed(commandName: string, options?: ResolveCommandOptions): ResolvedCliCommand;
|
|
15
|
+
export declare function resolveCliCommands(commandNames: readonly string[], options?: ResolveCommandOptions): Map<string, string>;
|
|
16
|
+
export declare function resolveCodexCommand(options?: ResolveCommandOptions): string;
|
|
17
|
+
export declare function resolveClaudeCommand(options?: ResolveCommandOptions): string;
|
|
18
|
+
export declare function getVersionManagerBinPaths(options?: ResolveCommandOptions): string[];
|
|
19
|
+
export {};
|