@cydm/pie 2.7.12 → 2.7.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -14
- package/dist/builtin/extensions/ask-user/index.js +3 -3
- package/dist/builtin/extensions/plan-mode/index.js +3 -3
- package/dist/builtin/extensions/subagent/index.js +4 -4
- package/dist/builtin/extensions/todo/index.js +3 -3
- package/dist/builtin/skills/computer-use-axi/computer-use-axi-broker.js +13 -11
- package/dist/builtin/skills/computer-use-axi/computer-use-axi-runtime.js +1 -1
- package/dist/chunks/{chunk-AFPRX5XI.js → chunk-CIFC6QVB.js} +37 -17
- package/dist/chunks/{chunk-YI3CSQGD.js → chunk-D7RMNFVM.js} +2 -2
- package/dist/chunks/{chunk-2NBUFVUQ.js → chunk-HGUYS5SF.js} +24 -1
- package/dist/chunks/{chunk-EN47TIBG.js → chunk-R46YPPTU.js} +11 -11
- package/dist/chunks/{src-XDNJ3PHL.js → src-5JJZZ5H7.js} +6 -2
- package/dist/chunks/{test-stream-LUUGOJMP.js → test-stream-ZBTSPU7J.js} +1 -1
- package/dist/cli.js +232 -109
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -211,11 +211,14 @@ Main key bindings:
|
|
|
211
211
|
- `Enter` submit message
|
|
212
212
|
- `Shift+Enter` insert a new line
|
|
213
213
|
- `\` + `Enter` insert a new line in terminals without modified-enter support
|
|
214
|
-
- `Ctrl+C` exit
|
|
215
|
-
- `Ctrl+D` exit
|
|
214
|
+
- `Ctrl+C` clear the editor; press twice within 500 ms to exit
|
|
215
|
+
- `Ctrl+D` exit when the editor is empty; forward-delete otherwise
|
|
216
|
+
- `Ctrl+V` / `Alt+V` / `Cmd+V` paste an image from the clipboard when the main chat editor owns focus (terminal clipboard first, OS helper fallback). Plan refinement, extension input/editor/custom UI, visible overlays, and the mention picker retain their own paste keys.
|
|
216
217
|
- `Ctrl+O` expand or collapse tool output
|
|
217
218
|
- `/` open the slash command menu
|
|
218
219
|
|
|
220
|
+
OS clipboard images are staged in per-read private temporary directories (0700 directories and exclusively reserved 0600 files on POSIX), including subprocess output, and removed after staging or on failure. Windows uses the user's temporary directory and inherited OS access controls. Terminal OSC 5522 frames and CSI 5522 support replies are incrementally framed, size-bounded, and never flushed as keyboard input while recognized: the default inter-chunk deadline is 1s, with a 10s absolute frame deadline. Failed frames discard their tails through the terminator or until 1s of idle recovery. An ambiguous lone Escape keeps its normal keyboard timeout unless a clipboard request is active; even then it is eventually delivered as Escape. After idle recovery, arbitrarily late bare payload bytes cannot be distinguished from new typing.
|
|
221
|
+
|
|
219
222
|
Direct shell mode:
|
|
220
223
|
|
|
221
224
|
```text
|
|
@@ -333,17 +336,13 @@ Run `pie doctor` to check whether chrome-devtools-axi and a Chrome browser are d
|
|
|
333
336
|
|
|
334
337
|
## Terminal UI Automation
|
|
335
338
|
|
|
336
|
-
The built-in `tui-use` skill drives interactive terminal programs - REPLs, pdb/gdb debugger sessions, and full-screen TUI apps - through Pie's packaged PTY runtime. Run `node <skill-baseDir>/tui-use-cli.js --help`; no first-use dependency download or global CLI is required. Windows uses native PowerShell and ConPTY. State lives in `~/.pie/tui-use`, or a dedicated `PIE_TUI_USE_STATE_DIR`. Always target sessions with `--session <id>`, confirm termination with `wait --exit`, and clean up only sessions and daemons you own. Use
|
|
339
|
+
The built-in `tui-use` skill drives interactive terminal programs - REPLs, pdb/gdb debugger sessions, and full-screen TUI apps - through Pie's packaged PTY runtime. Run `node <skill-baseDir>/tui-use-cli.js --help`; no first-use dependency download or global CLI is required. Windows uses native PowerShell and ConPTY. State lives in `~/.pie/tui-use`, or a dedicated `PIE_TUI_USE_STATE_DIR`. Always target sessions with `--session <id>`, confirm termination with `wait --exit`, and clean up only sessions and daemons you own. Use the `shell` tool for non-interactive commands.
|
|
337
340
|
|
|
338
341
|
## Desktop Control (computer-use)
|
|
339
342
|
|
|
340
|
-
The built-in `computer-use`
|
|
341
|
-
|
|
342
|
-
Tools are tiered:
|
|
343
|
+
The built-in `computer-use-axi` skill controls real desktop applications on macOS, Windows, and Linux through a native accessibility helper. Desktop control is a last resort - prefer API, CLI, or web tools whenever they can accomplish the task. Invoke the skill's CLI through the `shell` tool (`node <skill-baseDir>/computer-use-axi-cli.js <command>`); observation commands read UI state, while `act` synthesizes real input. These are CLI operations, not a separate model-visible extension tool tier, so normal shell confirmation policy applies.
|
|
343
344
|
|
|
344
|
-
-
|
|
345
|
-
- **Browser tier (default)** - `launch_browser`, `navigate_browser`, `evaluate_browser` control a managed CDP context. Navigation and JavaScript evaluation can have side effects; these are not read-only tools.
|
|
346
|
-
- **Act tier (first-use confirmation)** - `act_ui` synthesizes real input (click, type, scroll, keypress, drag). The first `act_ui` call in each session asks for confirmation (class `computer_use_act`); YOLO mode bypasses it, and non-interactive hosts block it deterministically.
|
|
345
|
+
Read `builtin/skills/computer-use-axi/SKILL.md` for `roots`, bounded observation, checked actions and browser workflows. On macOS, run the CLI's `permissions setup` and then `permissions recheck` after granting Accessibility and Screen Recording; starting Pie interactively is not a substitute for that setup flow.
|
|
347
346
|
|
|
348
347
|
Platform notes:
|
|
349
348
|
|
|
@@ -351,7 +350,7 @@ Platform notes:
|
|
|
351
350
|
- **Windows**: the helper installs to `~/.pie/helpers/computer-use/windows-bridge.exe` and needs an interactive desktop session.
|
|
352
351
|
- **Linux**: the helper installs to `~/.pie/helpers/computer-use/linux-bridge` and needs an AT-SPI2 bus (a running desktop session; headless servers are not supported).
|
|
353
352
|
|
|
354
|
-
Config: `~/.pie/extensions/computer-use.json` (user) or `.pie/computer-use.json` (project) with `browser_use`, `headless`, `cursor_overlay`, `managed_browser`; env overrides `PIE_COMPUTER_USE_BROWSER_USE` / `PIE_COMPUTER_USE_HEADLESS` / `PIE_COMPUTER_USE_CURSOR_OVERLAY` / `PIE_COMPUTER_USE_MANAGED_BROWSER`.
|
|
353
|
+
Config: `~/.pie/extensions/computer-use.json` (user) or `.pie/computer-use.json` (project) with `browser_use`, `headless`, `cursor_overlay`, `managed_browser`; env overrides `PIE_COMPUTER_USE_BROWSER_USE` / `PIE_COMPUTER_USE_HEADLESS` / `PIE_COMPUTER_USE_CURSOR_OVERLAY` / `PIE_COMPUTER_USE_MANAGED_BROWSER`. Run `pie doctor` for helper install status.
|
|
355
354
|
|
|
356
355
|
## Web Research
|
|
357
356
|
|
|
@@ -363,13 +362,13 @@ Pie exposes one default model-visible web tool: `web_research`. Use it for publi
|
|
|
363
362
|
|
|
364
363
|
## Permissions
|
|
365
364
|
|
|
366
|
-
Pie's default tools operate from the current workspace. File tools are workspace-scoped, `~/.pie` is allowlisted for Pie configuration/session support, and shell commands return structured timeout/truncation/error details. The canonical
|
|
365
|
+
Pie's default tools operate from the current workspace. File tools are workspace-scoped, `~/.pie` is allowlisted for Pie configuration/session support, and shell commands return structured timeout/truncation/error details. The canonical executable tool is named `shell`; `bash` remains only a historical replay/rendering and policy identifier, not a second executable alias. On Windows `shell:auto` uses PowerShell, and callers can explicitly request the `bash`, `powershell`, or `cmd` dialect. High-risk shell commands require confirmation outside YOLO mode; the confirmation dialog also offers a time-boxed `Yolo (5 min)` option that suppresses further high-risk prompts for five minutes without enabling full YOLO mode. Explicitly turning `/settings/yolo off` revokes both persistent YOLO and any live temporary grant; status reports a remaining grant separately. `/settings/yolo` relaxes filesystem sandbox directory restrictions and should only be used in trusted workspaces. `pie permissions` prints the current policy-derived safety summary.
|
|
367
366
|
|
|
368
|
-
In interactive Plan mode (`/tools/plan`), workspace editing tools are unavailable. The `
|
|
367
|
+
In interactive Plan mode (`/tools/plan`), workspace editing tools are unavailable. The Plan-mode `shell` guard accepts simple read commands and read-only pipelines such as `rg 'TODO' . | head -20`; it blocks redirects, command substitution, and write-capable subcommands. Use `plan_scratch` to write, read, or list temporary text drafts in a directory dedicated to the current session. Shell redirection to `/tmp` remains blocked in Plan mode. When the plan is ready, the agent submits the ordered steps with `plan_submit` and you choose to execute immediately (progress is tracked through `[DONE:n]` markers in responses), keep planning, or refine the plan in a prefilled editor; a plan written as plain text under a `Plan:`/`计划:` heading is still detected as a fallback. Leave Plan mode before changing workspace files.
|
|
369
368
|
|
|
370
369
|
## Code Intelligence
|
|
371
370
|
|
|
372
|
-
`code_intel`
|
|
371
|
+
The CLI's former TypeScript-service `code_intel` tool has been retired. Unity currently exposes a lightweight provider for read-only JS/TS diagnostics, definition, references, symbols, and hover; do not infer a CLI TypeScript worker or a Unity Node sidecar from the old documentation.
|
|
373
372
|
|
|
374
373
|
## Diagnostics
|
|
375
374
|
|
|
@@ -405,7 +404,7 @@ Every management command (`sessions`, `doctor`, `models`, `extensions`, `permiss
|
|
|
405
404
|
- Errors are structured on stdout: `{"v":1,"ok":false,"kind":"...","error":{"code":"session_not_found","message":"...","hint":"..."}}`.
|
|
406
405
|
- Exit codes: `0` success, `1` business failure, `2` usage error. Unknown flags fail loudly; every subcommand supports `--help`.
|
|
407
406
|
- `sessions list --json` defaults to the current project (`--all` lists every project). Rows are minimal (`id`, `name`, `updatedAt`, `count`) with `--fields` and `--full` opt-ins; `sessions read` truncates content by default with the same opt-ins.
|
|
408
|
-
- JSONL protocol mode (`--json-events`) identifies entries by `entryId` only (the legacy `checkpointId` alias is gone) and caps large tool results and turn summaries by default; pass `--event-detail full` for
|
|
407
|
+
- JSONL protocol mode (`--json-events`) identifies entries by `entryId` only (the legacy `checkpointId` alias is gone) and caps large tool results and turn summaries by default; pass `--event-detail full` for larger but still bounded payloads (including a 4,000-character string cap, depth/item/key limits). Affected tool-result strings carry `truncated`/`fullLength`; other bounded structures may use only `truncated`.
|
|
409
408
|
|
|
410
409
|
Run `pie capabilities --json` to discover the full command surface, flags, and exit-code contract programmatically.
|
|
411
410
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
createAskUserCapability
|
|
4
|
-
} from "../../../chunks/chunk-
|
|
5
|
-
import "../../../chunks/chunk-
|
|
6
|
-
import "../../../chunks/chunk-
|
|
4
|
+
} from "../../../chunks/chunk-CIFC6QVB.js";
|
|
5
|
+
import "../../../chunks/chunk-HGUYS5SF.js";
|
|
6
|
+
import "../../../chunks/chunk-R46YPPTU.js";
|
|
7
7
|
import "../../../chunks/chunk-XXGYUYXI.js";
|
|
8
8
|
import "../../../chunks/chunk-LZQXQOPJ.js";
|
|
9
9
|
|
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
extractPlanTodoItems,
|
|
7
7
|
markCompletedPlanSteps,
|
|
8
8
|
restoreExecutionState
|
|
9
|
-
} from "../../../chunks/chunk-
|
|
10
|
-
import "../../../chunks/chunk-
|
|
11
|
-
import "../../../chunks/chunk-
|
|
9
|
+
} from "../../../chunks/chunk-CIFC6QVB.js";
|
|
10
|
+
import "../../../chunks/chunk-HGUYS5SF.js";
|
|
11
|
+
import "../../../chunks/chunk-R46YPPTU.js";
|
|
12
12
|
import {
|
|
13
13
|
Type
|
|
14
14
|
} from "../../../chunks/chunk-XXGYUYXI.js";
|
|
@@ -6,15 +6,15 @@ import {
|
|
|
6
6
|
formatTransportLifecycle,
|
|
7
7
|
getConfigDir,
|
|
8
8
|
logTransportLifecycle
|
|
9
|
-
} from "../../../chunks/chunk-
|
|
9
|
+
} from "../../../chunks/chunk-D7RMNFVM.js";
|
|
10
10
|
import {
|
|
11
11
|
SUBAGENT_SESSION_RECORD_VERSION,
|
|
12
12
|
createPolicyEnforcedTools,
|
|
13
13
|
createSharedFileSystemTools,
|
|
14
14
|
createSubagentCapability
|
|
15
|
-
} from "../../../chunks/chunk-
|
|
16
|
-
import "../../../chunks/chunk-
|
|
17
|
-
import "../../../chunks/chunk-
|
|
15
|
+
} from "../../../chunks/chunk-CIFC6QVB.js";
|
|
16
|
+
import "../../../chunks/chunk-HGUYS5SF.js";
|
|
17
|
+
import "../../../chunks/chunk-R46YPPTU.js";
|
|
18
18
|
import "../../../chunks/chunk-XXGYUYXI.js";
|
|
19
19
|
import "../../../chunks/chunk-LZQXQOPJ.js";
|
|
20
20
|
|
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
executeManageTodoList,
|
|
9
9
|
executionStateToTodos,
|
|
10
10
|
restoreExecutionState
|
|
11
|
-
} from "../../../chunks/chunk-
|
|
12
|
-
import "../../../chunks/chunk-
|
|
13
|
-
import "../../../chunks/chunk-
|
|
11
|
+
} from "../../../chunks/chunk-CIFC6QVB.js";
|
|
12
|
+
import "../../../chunks/chunk-HGUYS5SF.js";
|
|
13
|
+
import "../../../chunks/chunk-R46YPPTU.js";
|
|
14
14
|
import "../../../chunks/chunk-XXGYUYXI.js";
|
|
15
15
|
import "../../../chunks/chunk-LZQXQOPJ.js";
|
|
16
16
|
|
|
@@ -5022,17 +5022,19 @@ function validateRequest(value) {
|
|
|
5022
5022
|
const params = validateCommandParams(command, value.params);
|
|
5023
5023
|
const cwd = value.cwd === void 0 ? process.cwd() : boundedString(value.cwd, "cwd", 4096);
|
|
5024
5024
|
if (!path3.isAbsolute(cwd)) throw new BrokerProtocolError("invalid_request", "cwd must be absolute.");
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5025
|
+
let environment = {};
|
|
5026
|
+
if (command !== "stop") {
|
|
5027
|
+
const rawEnvironment = value.environment ?? {};
|
|
5028
|
+
assertPlainRecord(rawEnvironment, "environment");
|
|
5029
|
+
assertKeys(rawEnvironment, "environment", REQUEST_ENV_KEYS);
|
|
5030
|
+
for (const entry of Object.values(rawEnvironment)) {
|
|
5031
|
+
if (typeof entry !== "string") throw new BrokerProtocolError("invalid_request", "environment values must be strings.");
|
|
5032
|
+
}
|
|
5033
|
+
try {
|
|
5034
|
+
environment = captureComputerUseEnvironment(rawEnvironment);
|
|
5035
|
+
} catch (error) {
|
|
5036
|
+
throw new BrokerProtocolError("invalid_request", String(error));
|
|
5037
|
+
}
|
|
5036
5038
|
}
|
|
5037
5039
|
const budgetMs = value.budgetMs === void 0 ? BROKER_DEFAULT_REQUEST_BUDGET_MS : Math.trunc(boundedNumber(value.budgetMs, "budgetMs", BROKER_MIN_REQUEST_BUDGET_MS, BROKER_MAX_REQUEST_BUDGET_MS));
|
|
5038
5040
|
return {
|
|
@@ -378,7 +378,7 @@ function isBrokerResponse(value) {
|
|
|
378
378
|
}
|
|
379
379
|
async function callBroker(options) {
|
|
380
380
|
if (options.command !== "stop") resolveTestOnlyBackend();
|
|
381
|
-
const environment = captureComputerUseEnvironment();
|
|
381
|
+
const environment = options.command === "stop" ? {} : captureComputerUseEnvironment();
|
|
382
382
|
const endpoint = resolveBrokerEndpoint();
|
|
383
383
|
const budgetMs = Math.min(Math.max(options.budgetMs ?? BROKER_DEFAULT_REQUEST_BUDGET_MS, 100), 15 * 6e4);
|
|
384
384
|
const spawnState = { spawned: false };
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
Agent,
|
|
4
|
+
createAgentOperationError,
|
|
5
|
+
getAgentFailureMetadata,
|
|
4
6
|
getToolCallerIdentity
|
|
5
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-HGUYS5SF.js";
|
|
6
8
|
import {
|
|
7
9
|
AssistantMessageEventStream,
|
|
8
10
|
FileSystemGateway,
|
|
@@ -12,7 +14,7 @@ import {
|
|
|
12
14
|
getPlatformConfig,
|
|
13
15
|
hashText,
|
|
14
16
|
streamSimple
|
|
15
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-R46YPPTU.js";
|
|
16
18
|
import {
|
|
17
19
|
Type
|
|
18
20
|
} from "./chunk-XXGYUYXI.js";
|
|
@@ -1001,7 +1003,7 @@ var PLAN_POWERSHELL_READ_COMMANDS = new Set([
|
|
|
1001
1003
|
"Compare-Object",
|
|
1002
1004
|
"Test-Path"
|
|
1003
1005
|
].map((name) => name.toLowerCase()));
|
|
1004
|
-
var PLAN_POWERSHELL_READ_ALIASES = /* @__PURE__ */ new Set(["cat", "ls", "pwd", "echo"
|
|
1006
|
+
var PLAN_POWERSHELL_READ_ALIASES = /* @__PURE__ */ new Set(["cat", "ls", "pwd", "echo"]);
|
|
1005
1007
|
var PLAN_POWERSHELL_SAFE_PARAMETERS = /^(?:-(?:Raw|TotalCount|Head|Tail|First|Last|Wait|LiteralPath|Path|Name|Pattern|Recurse|Filter|Include|Exclude|SimpleMatch|CaseSensitive|Quiet|Word|Line|Character|Encoding|ErrorAction|WarningAction))$/i;
|
|
1006
1008
|
var PLAN_POWERSHELL_SEPARATORS = /[;\n\r\t&<>|]/;
|
|
1007
1009
|
var PLAN_POWERSHELL_NON_ASCII = /[^\x20-\x7E]/;
|
|
@@ -1698,12 +1700,7 @@ Return a text-only successor handoff. Do not call any tools.` }],
|
|
|
1698
1700
|
).result();
|
|
1699
1701
|
throwIfAborted();
|
|
1700
1702
|
if (response.stopReason === "error" && (!response.content.some((block) => block.type === "toolCall") || classifyRemoteFailure(response.remoteFailure, response.errorMessage ?? "") !== void 0)) {
|
|
1701
|
-
|
|
1702
|
-
const explicitRetryable = response.retryable;
|
|
1703
|
-
if (typeof explicitRetryable === "boolean") providerError.retryable = explicitRetryable;
|
|
1704
|
-
if (response.replayEligible === true) providerError.replayEligible = true;
|
|
1705
|
-
providerError.remoteFailure = response.remoteFailure;
|
|
1706
|
-
throw providerError;
|
|
1703
|
+
throw Object.assign(new Error(response.errorMessage || "Compaction provider error"), getAgentFailureMetadata(response));
|
|
1707
1704
|
}
|
|
1708
1705
|
} catch (error) {
|
|
1709
1706
|
throwIfAborted();
|
|
@@ -5208,7 +5205,11 @@ async function runPreRequestAutoCompact(params) {
|
|
|
5208
5205
|
try {
|
|
5209
5206
|
await params.runAutoCompact();
|
|
5210
5207
|
} catch (error) {
|
|
5211
|
-
if (boundary) throw error
|
|
5208
|
+
if (boundary) throw createAgentOperationError(error, {
|
|
5209
|
+
origin: "tool-continuation",
|
|
5210
|
+
operation: "compaction",
|
|
5211
|
+
terminal: true
|
|
5212
|
+
});
|
|
5212
5213
|
if (params.isCurrent?.() !== false) params.setRecoveryState("none");
|
|
5213
5214
|
}
|
|
5214
5215
|
}
|
|
@@ -5517,7 +5518,8 @@ function isAssistantTerminalCompletion(message) {
|
|
|
5517
5518
|
return !message.content.some((block) => block.type === "toolCall");
|
|
5518
5519
|
}
|
|
5519
5520
|
function createFailureClassification(context, retry, classifyFailure) {
|
|
5520
|
-
|
|
5521
|
+
const terminalOperation = context.message?.role === "assistant" && context.message.operationFailure?.terminal === true;
|
|
5522
|
+
if (!terminalOperation && context.message?.role === "assistant" && context.message.replayEligible === true && context.message.stopReason === "error") {
|
|
5521
5523
|
return {
|
|
5522
5524
|
kind: "provider_transient",
|
|
5523
5525
|
retryable: true,
|
|
@@ -5528,7 +5530,7 @@ function createFailureClassification(context, retry, classifyFailure) {
|
|
|
5528
5530
|
replayExempt: true
|
|
5529
5531
|
};
|
|
5530
5532
|
}
|
|
5531
|
-
if (context.message?.role === "assistant" && context.message.retryable === false) {
|
|
5533
|
+
if (context.message?.role === "assistant" && (terminalOperation || context.message.retryable === false)) {
|
|
5532
5534
|
return { kind: "unknown", retryable: false, compactable: false, userAbort: context.message.stopReason === "aborted", terminal: true, message: context.errorMessage };
|
|
5533
5535
|
}
|
|
5534
5536
|
const remote = context.message?.role === "assistant" && context.message.stopReason === "error" ? classifyRemoteFailure(context.message.remoteFailure, context.errorMessage) : void 0;
|
|
@@ -6311,7 +6313,8 @@ async function handleAgentSessionTurnEndRuntimePolicies(params) {
|
|
|
6311
6313
|
params.emit({ type: "turn_settled" });
|
|
6312
6314
|
return;
|
|
6313
6315
|
}
|
|
6314
|
-
const
|
|
6316
|
+
const recoveryClosed = failure?.terminal && params.message?.role === "assistant" && (params.message.retryable === false || params.message.operationFailure?.terminal === true);
|
|
6317
|
+
const compactDecision = recoveryClosed ? void 0 : params.getAutoCompactDecision?.({
|
|
6315
6318
|
agent: params.agent,
|
|
6316
6319
|
sessionManager: params.sessionManager,
|
|
6317
6320
|
cwd: params.cwd,
|
|
@@ -9565,6 +9568,22 @@ function createAgentInstance(deps, systemPrompt, tools, model, apiKey, thinkingL
|
|
|
9565
9568
|
agentRunHooks.set(agent, hooks);
|
|
9566
9569
|
return agent;
|
|
9567
9570
|
}
|
|
9571
|
+
function inFlightRequestSummary(observation, now) {
|
|
9572
|
+
const transport = observation?.transport;
|
|
9573
|
+
if (!transport || transport.length === 0) return void 0;
|
|
9574
|
+
const lastStartIndex = transport.map((event) => event.phase).lastIndexOf("request_start");
|
|
9575
|
+
if (lastStartIndex < 0) return void 0;
|
|
9576
|
+
const start = transport[lastStartIndex];
|
|
9577
|
+
const after = transport.slice(lastStartIndex + 1);
|
|
9578
|
+
const terminal = after.find((event) => event.phase === "terminal_accepted");
|
|
9579
|
+
if (terminal) {
|
|
9580
|
+
const gapMs = Math.max(0, now - terminal.at);
|
|
9581
|
+
return `last model response completed ${Math.round(gapMs / 100) / 10}s before the deadline; no request in flight at abort`;
|
|
9582
|
+
}
|
|
9583
|
+
const sawFirst = after.some((event) => event.phase === "first_application_message");
|
|
9584
|
+
const ageMs = Math.max(0, now - start.at);
|
|
9585
|
+
return `a model request was still in flight at abort (${Math.round(ageMs / 100) / 10}s old, ${sawFirst ? "receiving stream events" : "no application message yet"}) \u2014 the deadline cut an unfinished response, which usually means the budget is too small for this reasoning level, not a transport stall`;
|
|
9586
|
+
}
|
|
9568
9587
|
function isParentHandoffRequired(task) {
|
|
9569
9588
|
return task.report?.availability !== "available" || task.mode === "edit" || task.status === "timeout" || task.status === "failed" || task.confidenceSignals.some((signal) => signal.type === "tool_error" || signal.type === "no_tool_use" || signal.type === "no_text_report");
|
|
9570
9589
|
}
|
|
@@ -10069,7 +10088,8 @@ ${DELEGATION_REPORT_INSTRUCTION}`;
|
|
|
10069
10088
|
task.status = timedOut ? "timeout" : signal?.aborted ? "cancelled" : "failed";
|
|
10070
10089
|
observeDelegationPhase(task.observation, timedOut ? "deadline" : signal?.aborted ? "cancelled" : "failed");
|
|
10071
10090
|
phaseProgress(task.observation.phase);
|
|
10072
|
-
|
|
10091
|
+
const deadlineDetail = timedOut ? inFlightRequestSummary(task.observation, Date.now()) : void 0;
|
|
10092
|
+
task.error = `${errorMessage.slice(0, 2e3)}${deadlineDetail ? `; ${deadlineDetail}` : ""}`.slice(0, 2e3);
|
|
10073
10093
|
const failureCarrier = error;
|
|
10074
10094
|
if (failureCarrier?.subagentFailure) {
|
|
10075
10095
|
task.failure = failureCarrier.subagentFailure;
|
|
@@ -10086,7 +10106,7 @@ ${DELEGATION_REPORT_INSTRUCTION}`;
|
|
|
10086
10106
|
task.report ??= parseDelegationReport(void 0, task.id);
|
|
10087
10107
|
task.parentHandoffRequired = isParentHandoffRequired(task);
|
|
10088
10108
|
task.completedAt = Date.now();
|
|
10089
|
-
report({ message: `[${task.name}] Failed: ${errorMessage.slice(0,
|
|
10109
|
+
report({ message: `[${task.name}] Failed: ${(errorMessage + (deadlineDetail ? `; ${deadlineDetail}` : "")).slice(0, 160)}`, increment: 100 });
|
|
10090
10110
|
} finally {
|
|
10091
10111
|
if (heartbeat) {
|
|
10092
10112
|
clearInterval(heartbeat);
|
|
@@ -10181,7 +10201,7 @@ function buildParallelResult(tasks, totalDuration) {
|
|
|
10181
10201
|
`;
|
|
10182
10202
|
}
|
|
10183
10203
|
if (task.sessionId) {
|
|
10184
|
-
resultText += task.sessionBusy ? `Session: ${task.sessionId} (busy \u2014 previous run is still settling; recall will fail until it settles` : `Session: ${task.sessionId} (resumable \u2014 pass as "sessionId" in a later spawn to continue this subagent with its accumulated context`;
|
|
10204
|
+
resultText += task.sessionBusy ? `Session: ${task.sessionId} (busy \u2014 previous run is still settling; recall will fail until it settles` : `Session: ${task.sessionId} (resumable \u2014 pass as "sessionId" in a later spawn to continue this subagent with its accumulated context; add resumeMode:"report" to reuse only its last report`;
|
|
10185
10205
|
if (task.sessionRunCount) resultText += `; run ${task.sessionRunCount}`;
|
|
10186
10206
|
if (task.sessionPersisted) resultText += "; persisted to disk, survives restarts";
|
|
10187
10207
|
resultText += ")\n";
|
|
@@ -10357,7 +10377,7 @@ Default mode="read" is for investigation, search, review, or triage and cannot e
|
|
|
10357
10377
|
priority: Type.Optional(Type.Union([Type.Literal("fast"), Type.Literal("thorough")], { description: "fast uses lower-cost defaults; thorough raises model class when needed." })),
|
|
10358
10378
|
model: Type.Optional(Type.String({ description: 'Explicit model override, e.g. "provider/model-id". Only when the user names a specific model; otherwise automatic.' })),
|
|
10359
10379
|
thinkingLevel: Type.Optional(Type.Union([Type.Literal("off"), Type.Literal("minimal"), Type.Literal("low"), Type.Literal("medium"), Type.Literal("high"), Type.Literal("xhigh")], { description: "off|minimal|low|medium|high|xhigh. Default medium; override only when the user asks or for cheap lookups (off)." })),
|
|
10360
|
-
timeout: Type.Optional(Type.Number({ description: "Seconds. Default 1200; set higher for long tasks." })),
|
|
10380
|
+
timeout: Type.Optional(Type.Number({ description: "Seconds. Default 1200; set higher for long tasks. Note: high/xhigh reasoning tasks can spend minutes per response on thinking alone \u2014 budget accordingly or the deadline will cut an in-flight response mid-thought." })),
|
|
10361
10381
|
resumeMode: Type.Optional(Type.Union([Type.Literal("full"), Type.Literal("report")], { description: "Default full retains prior transcript. Explicit report rebuilds with current tools/model/credentials and only the latest valid historical report as data plus the new task; fails if unavailable." })),
|
|
10362
10382
|
sessionId: Type.Optional(Type.String({ description: "Continue a previous subagent session by id (from an earlier result's Session line); full mode retains historical input with unknown cost. Optional mode/model/thinkingLevel reconfigure it; one task at a time; recalls never replay on failure and must target an idle session; prefer a fresh task for independent reviews." }))
|
|
10363
10383
|
}
|
|
@@ -7,12 +7,12 @@ import {
|
|
|
7
7
|
defaultShellKindForPlatform,
|
|
8
8
|
interpretShellExit,
|
|
9
9
|
requestInteraction
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-CIFC6QVB.js";
|
|
11
11
|
import {
|
|
12
12
|
EMPTY_ASSISTANT_CONTENT_ERROR,
|
|
13
13
|
OPENAI_COMPAT_PROTOCOL_ERROR_CODE,
|
|
14
14
|
getLogger
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-R46YPPTU.js";
|
|
16
16
|
import {
|
|
17
17
|
Type
|
|
18
18
|
} from "./chunk-XXGYUYXI.js";
|
|
@@ -4,7 +4,27 @@ import {
|
|
|
4
4
|
disposeModelTransports,
|
|
5
5
|
streamSimple,
|
|
6
6
|
validateToolArguments
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-R46YPPTU.js";
|
|
8
|
+
|
|
9
|
+
// ../../packages/agent-core/src/failure.ts
|
|
10
|
+
function getAgentFailureMetadata(error) {
|
|
11
|
+
if (!error || typeof error !== "object") return {};
|
|
12
|
+
const source = error;
|
|
13
|
+
return {
|
|
14
|
+
...source.retryable === false ? { retryable: false } : {},
|
|
15
|
+
...source.remoteFailure ? { remoteFailure: source.remoteFailure } : {},
|
|
16
|
+
...source.replayEligible === true ? { replayEligible: true } : {},
|
|
17
|
+
...typeof source.replayClass === "string" ? { replayClass: source.replayClass } : {},
|
|
18
|
+
...source.operationFailure ? { operationFailure: source.operationFailure } : {}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function createAgentOperationError(error, failure) {
|
|
22
|
+
return Object.assign(
|
|
23
|
+
new Error(error instanceof Error ? error.message : String(error), { cause: error }),
|
|
24
|
+
getAgentFailureMetadata(error),
|
|
25
|
+
{ operationFailure: failure }
|
|
26
|
+
);
|
|
27
|
+
}
|
|
8
28
|
|
|
9
29
|
// ../../packages/agent-core/src/agent-loop.ts
|
|
10
30
|
function createLoopErrorMessage(error, config, signal) {
|
|
@@ -25,6 +45,7 @@ function createLoopErrorMessage(error, config, signal) {
|
|
|
25
45
|
},
|
|
26
46
|
stopReason: signal?.aborted ? "aborted" : "error",
|
|
27
47
|
errorMessage: message,
|
|
48
|
+
...getAgentFailureMetadata(error),
|
|
28
49
|
timestamp: Date.now()
|
|
29
50
|
};
|
|
30
51
|
}
|
|
@@ -1132,6 +1153,8 @@ var Agent = class {
|
|
|
1132
1153
|
};
|
|
1133
1154
|
|
|
1134
1155
|
export {
|
|
1156
|
+
getAgentFailureMetadata,
|
|
1157
|
+
createAgentOperationError,
|
|
1135
1158
|
agentLoop,
|
|
1136
1159
|
agentLoopContinue,
|
|
1137
1160
|
createToolCallerIdentity,
|
|
@@ -3408,33 +3408,33 @@ function isPuertsReparsePoint(path) {
|
|
|
3408
3408
|
}
|
|
3409
3409
|
function containsPuertsReparsePoint(directory) {
|
|
3410
3410
|
const slashed = directory.replace(/\\/g, "/");
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
const unc = /^\/\/([^/]+)\/([^/]+)/.exec(trimmed);
|
|
3411
|
+
if (!slashed) return false;
|
|
3412
|
+
const unc = /^\/\/([^/]+)\/([^/]+)/.exec(slashed);
|
|
3414
3413
|
let prefix;
|
|
3415
3414
|
let rest;
|
|
3416
3415
|
if (unc) {
|
|
3417
3416
|
prefix = unc[0];
|
|
3418
|
-
rest =
|
|
3417
|
+
rest = slashed.slice(prefix.length);
|
|
3419
3418
|
} else {
|
|
3420
|
-
const driveRoot = /^([a-zA-Z]:)\//.exec(
|
|
3419
|
+
const driveRoot = /^([a-zA-Z]:)\//.exec(slashed);
|
|
3421
3420
|
if (driveRoot) {
|
|
3422
3421
|
prefix = `${driveRoot[1]}/`;
|
|
3423
|
-
rest =
|
|
3422
|
+
rest = slashed.slice(prefix.length);
|
|
3424
3423
|
} else {
|
|
3425
|
-
const bareDrive = /^[a-zA-Z]:$/.test(
|
|
3424
|
+
const bareDrive = /^[a-zA-Z]:$/.test(slashed);
|
|
3426
3425
|
if (bareDrive) {
|
|
3427
|
-
return isPuertsReparsePoint(
|
|
3426
|
+
return isPuertsReparsePoint(slashed);
|
|
3428
3427
|
}
|
|
3429
|
-
if (
|
|
3428
|
+
if (slashed.startsWith("/")) {
|
|
3430
3429
|
prefix = "/";
|
|
3431
|
-
rest =
|
|
3430
|
+
rest = slashed.slice(1);
|
|
3432
3431
|
} else {
|
|
3433
3432
|
prefix = "";
|
|
3434
|
-
rest =
|
|
3433
|
+
rest = slashed;
|
|
3435
3434
|
}
|
|
3436
3435
|
}
|
|
3437
3436
|
}
|
|
3437
|
+
if (prefix && isPuertsReparsePoint(prefix)) return true;
|
|
3438
3438
|
let current = prefix;
|
|
3439
3439
|
for (const part of rest.split("/").filter((segment) => segment.length > 0 && segment !== ".")) {
|
|
3440
3440
|
current = current ? current.endsWith("/") ? `${current}${part}` : `${current}/${part}` : part;
|
|
@@ -4,10 +4,12 @@ import {
|
|
|
4
4
|
agentLoop,
|
|
5
5
|
agentLoopContinue,
|
|
6
6
|
bindToolCallerIdentity,
|
|
7
|
+
createAgentOperationError,
|
|
7
8
|
createToolCallerIdentity,
|
|
9
|
+
getAgentFailureMetadata,
|
|
8
10
|
getToolCallerIdentity
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-HGUYS5SF.js";
|
|
12
|
+
import "./chunk-R46YPPTU.js";
|
|
11
13
|
import "./chunk-XXGYUYXI.js";
|
|
12
14
|
import "./chunk-LZQXQOPJ.js";
|
|
13
15
|
export {
|
|
@@ -15,6 +17,8 @@ export {
|
|
|
15
17
|
agentLoop,
|
|
16
18
|
agentLoopContinue,
|
|
17
19
|
bindToolCallerIdentity,
|
|
20
|
+
createAgentOperationError,
|
|
18
21
|
createToolCallerIdentity,
|
|
22
|
+
getAgentFailureMetadata,
|
|
19
23
|
getToolCallerIdentity
|
|
20
24
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
EventStream
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-R46YPPTU.js";
|
|
5
5
|
import "./chunk-XXGYUYXI.js";
|
|
6
6
|
import "./chunk-LZQXQOPJ.js";
|
|
7
7
|
|
package/dist/cli.js
CHANGED
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
migrateConfigFromAgentDir,
|
|
30
30
|
setYoloGrantListener,
|
|
31
31
|
truncateHeadTail
|
|
32
|
-
} from "./chunks/chunk-
|
|
32
|
+
} from "./chunks/chunk-D7RMNFVM.js";
|
|
33
33
|
import {
|
|
34
34
|
resolveCliProjectRoot
|
|
35
35
|
} from "./chunks/chunk-WLFOBECN.js";
|
|
@@ -94,8 +94,8 @@ import {
|
|
|
94
94
|
shouldPreserveExecutionStateForUserText,
|
|
95
95
|
supersedeExecutionState,
|
|
96
96
|
verifyPreparedCompactionCommit
|
|
97
|
-
} from "./chunks/chunk-
|
|
98
|
-
import "./chunks/chunk-
|
|
97
|
+
} from "./chunks/chunk-CIFC6QVB.js";
|
|
98
|
+
import "./chunks/chunk-HGUYS5SF.js";
|
|
99
99
|
import {
|
|
100
100
|
Deref,
|
|
101
101
|
Errors,
|
|
@@ -118,7 +118,7 @@ import {
|
|
|
118
118
|
sortToolModelCandidatesByCapability,
|
|
119
119
|
streamSimple,
|
|
120
120
|
type_exports
|
|
121
|
-
} from "./chunks/chunk-
|
|
121
|
+
} from "./chunks/chunk-R46YPPTU.js";
|
|
122
122
|
import {
|
|
123
123
|
IsArray,
|
|
124
124
|
IsBigInt,
|
|
@@ -52611,18 +52611,18 @@ function validateRemoteModel(profileId, model) {
|
|
|
52611
52611
|
validateWebSearchCapability(model.webSearch, `Remote profile "${profileId}" model "${model.id}" webSearch`);
|
|
52612
52612
|
validateFileCapabilities(model.fileCapabilities, `Remote profile "${profileId}" model "${model.id}" fileCapabilities`);
|
|
52613
52613
|
}
|
|
52614
|
-
function assertHeadersShape(
|
|
52615
|
-
if (
|
|
52616
|
-
if (!isPlainRecord(
|
|
52617
|
-
for (const [name, value] of Object.entries(
|
|
52614
|
+
function assertHeadersShape(headers2, label) {
|
|
52615
|
+
if (headers2 === void 0) return;
|
|
52616
|
+
if (!isPlainRecord(headers2)) throw new Error(`${label} headers must be an object`);
|
|
52617
|
+
for (const [name, value] of Object.entries(headers2)) {
|
|
52618
52618
|
if (!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(name)) throw new Error(`${label} header name ${name || "(empty)"} is invalid`);
|
|
52619
52619
|
if (typeof value !== "string") throw new Error(`${label} header ${name} must be a string`);
|
|
52620
52620
|
if (/[\0-\x08\x0A-\x1F\x7F]/.test(value)) throw new Error(`${label} header ${name} contains an invalid control character`);
|
|
52621
52621
|
}
|
|
52622
52622
|
}
|
|
52623
|
-
function assertRemoteHeadersSafe(
|
|
52624
|
-
assertHeadersShape(
|
|
52625
|
-
for (const name of Object.keys(
|
|
52623
|
+
function assertRemoteHeadersSafe(headers2, label) {
|
|
52624
|
+
assertHeadersShape(headers2, label);
|
|
52625
|
+
for (const name of Object.keys(headers2 || {})) {
|
|
52626
52626
|
if (/(?:authorization|cookie|api[-_]?key|token|secret|credential)/i.test(name)) {
|
|
52627
52627
|
throw new Error(`${label} must not provide credential-bearing header ${name}`);
|
|
52628
52628
|
}
|
|
@@ -53252,10 +53252,10 @@ var ModelRegistry = class {
|
|
|
53252
53252
|
let payload = cached?.payload;
|
|
53253
53253
|
let response;
|
|
53254
53254
|
try {
|
|
53255
|
-
const
|
|
53256
|
-
if (cached?.etag)
|
|
53255
|
+
const headers2 = { Authorization: `Bearer ${apiKey}` };
|
|
53256
|
+
if (cached?.etag) headers2["If-None-Match"] = cached.etag;
|
|
53257
53257
|
response = await fetch(url, {
|
|
53258
|
-
headers,
|
|
53258
|
+
headers: headers2,
|
|
53259
53259
|
redirect: "manual",
|
|
53260
53260
|
signal: AbortSignal.timeout(3e3)
|
|
53261
53261
|
});
|
|
@@ -63659,10 +63659,37 @@ var Spacer = class {
|
|
|
63659
63659
|
|
|
63660
63660
|
// ../../packages/tui/src/stdin-buffer.ts
|
|
63661
63661
|
import { EventEmitter } from "events";
|
|
63662
|
+
|
|
63663
|
+
// ../../packages/tui/src/clipboard-framing.ts
|
|
63664
|
+
var headers = [
|
|
63665
|
+
{ kind: "osc", prefix: "\x1B]5522" },
|
|
63666
|
+
{ kind: "csi", prefix: "\x1B[?5522" }
|
|
63667
|
+
];
|
|
63668
|
+
function clipboardFrameEnd(data, kind) {
|
|
63669
|
+
const match = kind === "osc" ? /\x07|\x1b\\/.exec(data) : /[\x40-\x7e]/.exec(data);
|
|
63670
|
+
return match ? match.index + match[0].length : void 0;
|
|
63671
|
+
}
|
|
63672
|
+
function classifyClipboardFragment(data, pending = false) {
|
|
63673
|
+
if (!data) return void 0;
|
|
63674
|
+
for (const { kind, prefix } of headers) {
|
|
63675
|
+
if (prefix.startsWith(data)) {
|
|
63676
|
+
const ambiguous = data === "\x1B" || data === "\x1B[";
|
|
63677
|
+
if (!ambiguous || pending) return { kind, valid: false };
|
|
63678
|
+
} else if (data.startsWith(prefix)) {
|
|
63679
|
+
const end = clipboardFrameEnd(data.slice(2), kind);
|
|
63680
|
+
const length = end === void 0 ? void 0 : end + 2;
|
|
63681
|
+
const frame = length === void 0 ? data : data.slice(0, length);
|
|
63682
|
+
const valid = kind === "osc" ? frame.startsWith(`${prefix};`) : /^\x1b\[\?5522;[0-4]\$y$/.test(frame);
|
|
63683
|
+
return { kind, length, valid };
|
|
63684
|
+
}
|
|
63685
|
+
}
|
|
63686
|
+
return void 0;
|
|
63687
|
+
}
|
|
63688
|
+
|
|
63689
|
+
// ../../packages/tui/src/stdin-buffer.ts
|
|
63662
63690
|
var ESC = "\x1B";
|
|
63663
63691
|
var BRACKETED_PASTE_START = "\x1B[200~";
|
|
63664
63692
|
var BRACKETED_PASTE_END = "\x1B[201~";
|
|
63665
|
-
var OSC_5522_PREFIX = "\x1B]5522;";
|
|
63666
63693
|
var OSC_5522_MAX_FRAME = 70 * 1024 * 1024;
|
|
63667
63694
|
function isCompleteSequence(data) {
|
|
63668
63695
|
if (!data.startsWith(ESC)) {
|
|
@@ -63750,16 +63777,29 @@ function isCompleteApcSequence(data) {
|
|
|
63750
63777
|
}
|
|
63751
63778
|
return "incomplete";
|
|
63752
63779
|
}
|
|
63753
|
-
function extractCompleteSequences(buffer, maxClipboardFrame = OSC_5522_MAX_FRAME) {
|
|
63780
|
+
function extractCompleteSequences(buffer, maxClipboardFrame = OSC_5522_MAX_FRAME, pending = false) {
|
|
63754
63781
|
const sequences = [];
|
|
63755
63782
|
let pos = 0;
|
|
63756
63783
|
while (pos < buffer.length) {
|
|
63757
63784
|
const remaining = buffer.slice(pos);
|
|
63785
|
+
const clipboard = classifyClipboardFragment(remaining, pending);
|
|
63786
|
+
if (clipboard) {
|
|
63787
|
+
if (clipboard.length === void 0) return { sequences, remainder: remaining };
|
|
63788
|
+
if (clipboard.valid && clipboard.length <= Math.min(maxClipboardFrame, clipboard.kind === "csi" ? 64 : Infinity)) {
|
|
63789
|
+
sequences.push(remaining.slice(0, clipboard.length));
|
|
63790
|
+
}
|
|
63791
|
+
pos += clipboard.length;
|
|
63792
|
+
continue;
|
|
63793
|
+
}
|
|
63794
|
+
if (remaining.startsWith(BRACKETED_PASTE_START)) {
|
|
63795
|
+
sequences.push(BRACKETED_PASTE_START);
|
|
63796
|
+
return { sequences, remainder: remaining.slice(BRACKETED_PASTE_START.length) };
|
|
63797
|
+
}
|
|
63758
63798
|
if (remaining.startsWith(`${ESC}]`)) {
|
|
63759
63799
|
const end = /\x07|\x1b\\/.exec(remaining);
|
|
63760
63800
|
if (!end) return { sequences, remainder: remaining };
|
|
63761
63801
|
const length = end.index + end[0].length;
|
|
63762
|
-
|
|
63802
|
+
sequences.push(remaining.slice(0, length));
|
|
63763
63803
|
pos += length;
|
|
63764
63804
|
continue;
|
|
63765
63805
|
}
|
|
@@ -63796,7 +63836,8 @@ var StdinBuffer = class extends EventEmitter {
|
|
|
63796
63836
|
timeoutMs;
|
|
63797
63837
|
pasteMode = false;
|
|
63798
63838
|
pasteBuffer = "";
|
|
63799
|
-
discardingClipboard
|
|
63839
|
+
discardingClipboard;
|
|
63840
|
+
clipboardStarted = 0;
|
|
63800
63841
|
discardEsc = false;
|
|
63801
63842
|
options;
|
|
63802
63843
|
constructor(options = {}) {
|
|
@@ -63825,19 +63866,26 @@ var StdinBuffer = class extends EventEmitter {
|
|
|
63825
63866
|
return;
|
|
63826
63867
|
}
|
|
63827
63868
|
if (this.discardingClipboard) {
|
|
63828
|
-
const
|
|
63829
|
-
const
|
|
63830
|
-
|
|
63831
|
-
|
|
63832
|
-
|
|
63833
|
-
|
|
63834
|
-
|
|
63835
|
-
|
|
63836
|
-
|
|
63869
|
+
const kind = this.discardingClipboard;
|
|
63870
|
+
const heldEscape = this.discardEsc;
|
|
63871
|
+
const discarded = (heldEscape ? ESC : "") + str2;
|
|
63872
|
+
const end = clipboardFrameEnd(discarded, kind);
|
|
63873
|
+
const escape = discarded.indexOf(ESC, heldEscape && str2.startsWith(ESC) ? 1 : 0);
|
|
63874
|
+
const resync = escape >= 0 && escape + 1 < discarded.length && (end === void 0 || escape < end - 1) && !(kind === "osc" && end !== void 0 && escape === end - 2 && discarded.startsWith(`${ESC}\\`, escape));
|
|
63875
|
+
if (resync) {
|
|
63876
|
+
this.discardingClipboard = void 0;
|
|
63877
|
+
this.discardEsc = false;
|
|
63878
|
+
str2 = discarded.slice(escape);
|
|
63879
|
+
} else {
|
|
63880
|
+
if (!end) {
|
|
63881
|
+
this.discardEsc = discarded.endsWith(ESC);
|
|
63882
|
+
this.scheduleDiscardRecovery();
|
|
63883
|
+
return;
|
|
63884
|
+
}
|
|
63885
|
+
this.discardingClipboard = void 0;
|
|
63886
|
+
this.discardEsc = false;
|
|
63887
|
+
str2 = discarded.slice(end);
|
|
63837
63888
|
}
|
|
63838
|
-
this.discardingClipboard = false;
|
|
63839
|
-
this.discardEsc = false;
|
|
63840
|
-
str2 = discarded.slice(end.index + end[0].length);
|
|
63841
63889
|
}
|
|
63842
63890
|
this.buffer += str2;
|
|
63843
63891
|
if (this.pasteMode) {
|
|
@@ -63856,16 +63904,13 @@ var StdinBuffer = class extends EventEmitter {
|
|
|
63856
63904
|
}
|
|
63857
63905
|
return;
|
|
63858
63906
|
}
|
|
63859
|
-
const
|
|
63860
|
-
if (
|
|
63861
|
-
|
|
63862
|
-
|
|
63863
|
-
|
|
63864
|
-
|
|
63865
|
-
|
|
63866
|
-
}
|
|
63867
|
-
}
|
|
63868
|
-
this.buffer = this.buffer.slice(startIndex + BRACKETED_PASTE_START.length);
|
|
63907
|
+
const result = extractCompleteSequences(this.buffer, this.options.clipboardMaxFrame, this.options.clipboardResponsePending?.());
|
|
63908
|
+
if (result.remainder.length < this.buffer.length) this.clipboardStarted = 0;
|
|
63909
|
+
this.buffer = result.remainder;
|
|
63910
|
+
for (const sequence of result.sequences) {
|
|
63911
|
+
if (sequence !== BRACKETED_PASTE_START) this.emit("data", sequence);
|
|
63912
|
+
}
|
|
63913
|
+
if (result.sequences.at(-1) === BRACKETED_PASTE_START) {
|
|
63869
63914
|
this.pasteMode = true;
|
|
63870
63915
|
this.pasteBuffer = this.buffer;
|
|
63871
63916
|
this.buffer = "";
|
|
@@ -63882,40 +63927,29 @@ var StdinBuffer = class extends EventEmitter {
|
|
|
63882
63927
|
}
|
|
63883
63928
|
return;
|
|
63884
63929
|
}
|
|
63885
|
-
const result = extractCompleteSequences(this.buffer, this.options.clipboardMaxFrame);
|
|
63886
|
-
this.buffer = result.remainder;
|
|
63887
|
-
for (const sequence of result.sequences) {
|
|
63888
|
-
this.emit("data", sequence);
|
|
63889
|
-
}
|
|
63890
63930
|
if (this.buffer.length > 0) {
|
|
63891
|
-
const
|
|
63892
|
-
if (
|
|
63931
|
+
const fragment = classifyClipboardFragment(this.buffer, this.options.clipboardResponsePending?.());
|
|
63932
|
+
if (fragment) {
|
|
63933
|
+
this.clipboardStarted ||= Date.now();
|
|
63934
|
+
const limit = Math.min(this.options.clipboardMaxFrame ?? OSC_5522_MAX_FRAME, fragment.kind === "csi" ? 64 : Infinity);
|
|
63935
|
+
if (this.buffer.length > limit) {
|
|
63936
|
+
this.discardClipboard(fragment.kind);
|
|
63937
|
+
return;
|
|
63938
|
+
}
|
|
63939
|
+
const deadline = Math.min(
|
|
63940
|
+
this.options.clipboardFrameTimeout ?? 1e3,
|
|
63941
|
+
(this.options.clipboardFrameMaxDuration ?? 1e4) - (Date.now() - this.clipboardStarted)
|
|
63942
|
+
);
|
|
63893
63943
|
this.timeout = setTimeout(() => {
|
|
63894
|
-
|
|
63895
|
-
|
|
63896
|
-
|
|
63897
|
-
if (ambiguousEscape) {
|
|
63944
|
+
if (this.buffer === ESC) {
|
|
63945
|
+
this.buffer = "";
|
|
63946
|
+
this.clipboardStarted = 0;
|
|
63898
63947
|
this.emit("data", ESC);
|
|
63899
|
-
|
|
63900
|
-
|
|
63901
|
-
this.discardingClipboard = true;
|
|
63902
|
-
this.timeout = setTimeout(() => {
|
|
63903
|
-
this.discardingClipboard = false;
|
|
63904
|
-
this.discardEsc = false;
|
|
63905
|
-
}, this.options.clipboardFrameTimeout ?? 1e3);
|
|
63906
|
-
}, this.options.clipboardFrameTimeout ?? 1e3);
|
|
63907
|
-
return;
|
|
63908
|
-
}
|
|
63909
|
-
if (heldFor5522) {
|
|
63910
|
-
this.discardEsc = this.buffer.endsWith(ESC);
|
|
63911
|
-
this.buffer = "";
|
|
63912
|
-
this.discardingClipboard = true;
|
|
63913
|
-
this.timeout = setTimeout(() => {
|
|
63914
|
-
this.discardingClipboard = false;
|
|
63915
|
-
this.discardEsc = false;
|
|
63916
|
-
}, this.options.clipboardFrameTimeout ?? 1e3);
|
|
63948
|
+
} else this.discardClipboard(fragment.kind);
|
|
63949
|
+
}, Math.max(0, deadline));
|
|
63917
63950
|
return;
|
|
63918
63951
|
}
|
|
63952
|
+
this.clipboardStarted = 0;
|
|
63919
63953
|
this.timeout = setTimeout(() => {
|
|
63920
63954
|
const flushed = this.flush();
|
|
63921
63955
|
for (const sequence of flushed) {
|
|
@@ -63924,6 +63958,19 @@ var StdinBuffer = class extends EventEmitter {
|
|
|
63924
63958
|
}, this.timeoutMs);
|
|
63925
63959
|
}
|
|
63926
63960
|
}
|
|
63961
|
+
scheduleDiscardRecovery() {
|
|
63962
|
+
this.timeout = setTimeout(() => {
|
|
63963
|
+
this.discardingClipboard = void 0;
|
|
63964
|
+
this.discardEsc = false;
|
|
63965
|
+
}, this.options.clipboardFrameTimeout ?? 1e3);
|
|
63966
|
+
}
|
|
63967
|
+
discardClipboard(kind) {
|
|
63968
|
+
this.discardEsc = this.buffer.endsWith(ESC);
|
|
63969
|
+
this.buffer = "";
|
|
63970
|
+
this.clipboardStarted = 0;
|
|
63971
|
+
this.discardingClipboard = kind;
|
|
63972
|
+
this.scheduleDiscardRecovery();
|
|
63973
|
+
}
|
|
63927
63974
|
flush() {
|
|
63928
63975
|
if (this.timeout) {
|
|
63929
63976
|
clearTimeout(this.timeout);
|
|
@@ -63932,7 +63979,13 @@ var StdinBuffer = class extends EventEmitter {
|
|
|
63932
63979
|
if (this.buffer.length === 0) {
|
|
63933
63980
|
return [];
|
|
63934
63981
|
}
|
|
63935
|
-
const
|
|
63982
|
+
const fragment = classifyClipboardFragment(this.buffer, this.options.clipboardResponsePending?.());
|
|
63983
|
+
if (fragment && this.buffer !== ESC) {
|
|
63984
|
+
this.discardClipboard(fragment.kind);
|
|
63985
|
+
return [];
|
|
63986
|
+
}
|
|
63987
|
+
const sequences = [this.buffer];
|
|
63988
|
+
this.clipboardStarted = 0;
|
|
63936
63989
|
this.buffer = "";
|
|
63937
63990
|
return sequences;
|
|
63938
63991
|
}
|
|
@@ -63944,7 +63997,8 @@ var StdinBuffer = class extends EventEmitter {
|
|
|
63944
63997
|
this.buffer = "";
|
|
63945
63998
|
this.pasteMode = false;
|
|
63946
63999
|
this.pasteBuffer = "";
|
|
63947
|
-
this.
|
|
64000
|
+
this.clipboardStarted = 0;
|
|
64001
|
+
this.discardingClipboard = void 0;
|
|
63948
64002
|
this.discardEsc = false;
|
|
63949
64003
|
}
|
|
63950
64004
|
getBuffer() {
|
|
@@ -63960,6 +64014,7 @@ import * as fs11 from "node:fs";
|
|
|
63960
64014
|
import koffi from "koffi";
|
|
63961
64015
|
|
|
63962
64016
|
// ../../packages/tui/src/osc-5522.ts
|
|
64017
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
63963
64018
|
var OSC = "\x1B]";
|
|
63964
64019
|
var ST = "\x1B\\";
|
|
63965
64020
|
var READ_TIMEOUT_MS = 8e3;
|
|
@@ -64016,13 +64071,14 @@ var Osc5522Client = class {
|
|
|
64016
64071
|
return true;
|
|
64017
64072
|
}
|
|
64018
64073
|
const packet = parseOsc5522Packet(data);
|
|
64019
|
-
if (!packet) return
|
|
64074
|
+
if (!packet) return data.startsWith(`${OSC}5522;`);
|
|
64020
64075
|
const fields = parseMetadata(packet.metadata);
|
|
64021
64076
|
const type = fields.get("type") ?? "";
|
|
64022
|
-
if (!type.startsWith("read")) return
|
|
64077
|
+
if (!type.startsWith("read")) return true;
|
|
64023
64078
|
const status = fields.get("status");
|
|
64024
64079
|
const session = this.session;
|
|
64025
64080
|
if (!session) return true;
|
|
64081
|
+
if (fields.get("id") !== session.id) return true;
|
|
64026
64082
|
if (status === void 0) {
|
|
64027
64083
|
this.finishFor(session, { ok: false, kind: "malformed", message: `OSC 5522 read packet without status: ${packet.metadata}` });
|
|
64028
64084
|
return true;
|
|
@@ -64105,6 +64161,7 @@ var Osc5522Client = class {
|
|
|
64105
64161
|
return { ok: false, kind: "busy", message: "Another OSC 5522 read is already in flight." };
|
|
64106
64162
|
}
|
|
64107
64163
|
const session = {
|
|
64164
|
+
id: `pie-${randomBytes2(8).toString("hex")}`,
|
|
64108
64165
|
resolve: void 0,
|
|
64109
64166
|
timer: void 0,
|
|
64110
64167
|
chunks: [],
|
|
@@ -64124,7 +64181,7 @@ var Osc5522Client = class {
|
|
|
64124
64181
|
}
|
|
64125
64182
|
if (this.session !== session) return promise;
|
|
64126
64183
|
const mimeList = Buffer.from("image/png image/jpeg").toString("base64");
|
|
64127
|
-
this.write(`${OSC}5522;type=read;${mimeList}${ST}`);
|
|
64184
|
+
this.write(`${OSC}5522;id=${session.id}:type=read;${mimeList}${ST}`);
|
|
64128
64185
|
return promise;
|
|
64129
64186
|
}
|
|
64130
64187
|
/** Finish only if `session` is still the live session (identity-bound). */
|
|
@@ -70296,12 +70353,21 @@ var YoloGrantTracker = class {
|
|
|
70296
70353
|
isActive(now = Date.now()) {
|
|
70297
70354
|
return this.untilMs > now;
|
|
70298
70355
|
}
|
|
70356
|
+
remainingMs(now = Date.now()) {
|
|
70357
|
+
return Math.max(0, this.untilMs - now);
|
|
70358
|
+
}
|
|
70299
70359
|
award(grantMs, now = Date.now()) {
|
|
70300
70360
|
this.untilMs = now + Math.max(0, grantMs);
|
|
70301
70361
|
}
|
|
70302
70362
|
expire() {
|
|
70303
70363
|
this.untilMs = 0;
|
|
70304
70364
|
}
|
|
70365
|
+
/** Revoke the active grant and report whether revocation changed live state. */
|
|
70366
|
+
revoke() {
|
|
70367
|
+
const wasActive = this.isActive();
|
|
70368
|
+
this.expire();
|
|
70369
|
+
return wasActive;
|
|
70370
|
+
}
|
|
70305
70371
|
/** Expiry timestamp (0 when no grant is held); useful for display. */
|
|
70306
70372
|
get until() {
|
|
70307
70373
|
return this.untilMs;
|
|
@@ -76576,7 +76642,9 @@ async function handleCalmCommand(host, args) {
|
|
|
76576
76642
|
async function handleYoloCommand(host, args) {
|
|
76577
76643
|
const mode = (args || "").trim().toLowerCase();
|
|
76578
76644
|
if (mode === "status") {
|
|
76579
|
-
|
|
76645
|
+
const persistent = `YOLO mode is ${host.yoloMode ? "on" : "off"}`;
|
|
76646
|
+
const grantRemaining = host.getYoloGrantRemainingMs();
|
|
76647
|
+
host.showStatus(grantRemaining > 0 ? `${persistent}; temporary high-risk shell grant active for ${Math.max(1, Math.ceil(grantRemaining / 6e4))} more min` : persistent);
|
|
76580
76648
|
return;
|
|
76581
76649
|
}
|
|
76582
76650
|
if (mode && !["on", "off", "enable", "enabled", "disable", "disabled", "true", "false", "1", "0"].includes(mode)) {
|
|
@@ -76584,9 +76652,10 @@ async function handleYoloCommand(host, args) {
|
|
|
76584
76652
|
return;
|
|
76585
76653
|
}
|
|
76586
76654
|
const nextYoloMode = mode ? ["on", "enable", "enabled", "true", "1"].includes(mode) : !host.yoloMode;
|
|
76655
|
+
const revokedGrant = nextYoloMode ? false : host.revokeYoloGrant();
|
|
76587
76656
|
if (host.yoloMode === nextYoloMode) {
|
|
76588
76657
|
host.footer.setState({ yoloMode: host.yoloMode });
|
|
76589
|
-
host.showStatus(`YOLO mode already ${host.yoloMode ? "on" : "off"}`);
|
|
76658
|
+
host.showStatus(`YOLO mode already ${host.yoloMode ? "on" : "off"}${revokedGrant ? "; temporary grant revoked" : ""}`);
|
|
76590
76659
|
return;
|
|
76591
76660
|
}
|
|
76592
76661
|
host.yoloMode = nextYoloMode;
|
|
@@ -76604,6 +76673,7 @@ async function handleYoloCommand(host, args) {
|
|
|
76604
76673
|
host.chatContainer.addChild(new Spacer(1));
|
|
76605
76674
|
host.chatContainer.addChild(new Text(theme.fg("accent", "\u2713 YOLO mode disabled"), 1, 0));
|
|
76606
76675
|
host.chatContainer.addChild(new Text(theme.fg("dim", " Sandbox directory restrictions restored."), 1, 0));
|
|
76676
|
+
if (revokedGrant) host.chatContainer.addChild(new Text(theme.fg("dim", " Temporary high-risk shell grant revoked."), 1, 0));
|
|
76607
76677
|
host.chatContainer.addChild(new Spacer(1));
|
|
76608
76678
|
}
|
|
76609
76679
|
host.ui.requestRender();
|
|
@@ -79596,6 +79666,9 @@ async function selectMentionOption(host, option) {
|
|
|
79596
79666
|
}
|
|
79597
79667
|
|
|
79598
79668
|
// src/input/interactive-keybindings.ts
|
|
79669
|
+
function mainEditorOwnsInput(host) {
|
|
79670
|
+
return host.editor.focused === true && host.editorContainer.children.includes(host.editor) && !host.ui.hasOverlay() && !host.mentionPickerComponent;
|
|
79671
|
+
}
|
|
79599
79672
|
function setupInteractiveKeybindings(host) {
|
|
79600
79673
|
host.ui.addInputListener((data) => {
|
|
79601
79674
|
if (isKeyRelease(data)) {
|
|
@@ -79653,7 +79726,7 @@ function setupInteractiveKeybindings(host) {
|
|
|
79653
79726
|
host.handleInterrupt();
|
|
79654
79727
|
return { consume: true };
|
|
79655
79728
|
}
|
|
79656
|
-
if (
|
|
79729
|
+
if (host.keybindings.matches(data, "pasteImage") && mainEditorOwnsInput(host)) {
|
|
79657
79730
|
host.handlePasteImage();
|
|
79658
79731
|
return { consume: true };
|
|
79659
79732
|
}
|
|
@@ -79679,8 +79752,7 @@ function setupInteractiveKeybindings(host) {
|
|
|
79679
79752
|
|
|
79680
79753
|
// src/clipboard/read-clipboard-image.ts
|
|
79681
79754
|
import { spawn as spawn2 } from "node:child_process";
|
|
79682
|
-
import {
|
|
79683
|
-
import { existsSync as existsSync18, readFileSync as readFileSync17, statSync as statSync12, unlinkSync as unlinkSync8, writeFileSync as writeFileSync12 } from "node:fs";
|
|
79755
|
+
import { chmodSync as chmodSync2, closeSync as closeSync4, existsSync as existsSync18, fchmodSync, mkdtempSync, openSync as openSync4, readFileSync as readFileSync17, rmdirSync, statSync as statSync12, unlinkSync as unlinkSync8, writeFileSync as writeFileSync12 } from "node:fs";
|
|
79684
79756
|
import { tmpdir } from "node:os";
|
|
79685
79757
|
import { join as join20 } from "node:path";
|
|
79686
79758
|
var MAX_IMAGE_BYTES = 50 * 1024 * 1024;
|
|
@@ -79746,14 +79818,67 @@ function defaultSpawnFn(file, args, spawnImpl = spawn2, maxBytes = MAX_IMAGE_BYT
|
|
|
79746
79818
|
});
|
|
79747
79819
|
});
|
|
79748
79820
|
}
|
|
79749
|
-
|
|
79750
|
-
|
|
79751
|
-
|
|
79821
|
+
var TempImageResources = class {
|
|
79822
|
+
constructor(injectedPath) {
|
|
79823
|
+
this.injectedPath = injectedPath;
|
|
79824
|
+
}
|
|
79825
|
+
injectedPath;
|
|
79826
|
+
directory;
|
|
79827
|
+
files = /* @__PURE__ */ new Set();
|
|
79828
|
+
create = (ext) => {
|
|
79829
|
+
if (!this.injectedPath && !this.directory) {
|
|
79830
|
+
this.directory = mkdtempSync(join20(tmpdir(), "pie-clipboard-"));
|
|
79831
|
+
if (process.platform !== "win32") chmodSync2(this.directory, 448);
|
|
79832
|
+
}
|
|
79833
|
+
const path34 = this.injectedPath ? this.injectedPath(ext) : join20(this.directory, `image${ext}`);
|
|
79834
|
+
const fd = openSync4(path34, "wx", 384);
|
|
79835
|
+
this.files.add(path34);
|
|
79836
|
+
try {
|
|
79837
|
+
if (process.platform !== "win32") fchmodSync(fd, 384);
|
|
79838
|
+
} finally {
|
|
79839
|
+
closeSync4(fd);
|
|
79840
|
+
}
|
|
79841
|
+
return path34;
|
|
79842
|
+
};
|
|
79843
|
+
cleanup = () => {
|
|
79844
|
+
for (const path34 of this.files) {
|
|
79845
|
+
try {
|
|
79846
|
+
unlinkSync8(path34);
|
|
79847
|
+
this.files.delete(path34);
|
|
79848
|
+
} catch (err) {
|
|
79849
|
+
if (err.code === "ENOENT") this.files.delete(path34);
|
|
79850
|
+
}
|
|
79851
|
+
}
|
|
79852
|
+
if (this.directory) {
|
|
79853
|
+
try {
|
|
79854
|
+
rmdirSync(this.directory);
|
|
79855
|
+
this.directory = void 0;
|
|
79856
|
+
} catch (err) {
|
|
79857
|
+
if (err.code === "ENOENT") this.directory = void 0;
|
|
79858
|
+
}
|
|
79859
|
+
}
|
|
79860
|
+
};
|
|
79861
|
+
};
|
|
79752
79862
|
async function readClipboardImage(deps = {}) {
|
|
79753
79863
|
const platform2 = deps.platform ?? process.platform;
|
|
79754
79864
|
const env = deps.env ?? process.env;
|
|
79755
79865
|
const spawnImpl = deps.spawnImpl ?? defaultSpawnFn;
|
|
79756
|
-
const
|
|
79866
|
+
const resources = new TempImageResources(deps.mkTempPath);
|
|
79867
|
+
let retained = false;
|
|
79868
|
+
try {
|
|
79869
|
+
const result = await readPlatformClipboard(platform2, env, spawnImpl, resources.create);
|
|
79870
|
+
if (result.ok === true) {
|
|
79871
|
+
retained = true;
|
|
79872
|
+
return { ...result, cleanup: resources.cleanup };
|
|
79873
|
+
}
|
|
79874
|
+
return result;
|
|
79875
|
+
} catch (err) {
|
|
79876
|
+
return { ok: false, kind: "failed", message: `Failed to read clipboard image: ${errorMessage4(err)}` };
|
|
79877
|
+
} finally {
|
|
79878
|
+
if (!retained) resources.cleanup();
|
|
79879
|
+
}
|
|
79880
|
+
}
|
|
79881
|
+
async function readPlatformClipboard(platform2, env, spawnImpl, mkTempPath) {
|
|
79757
79882
|
switch (platform2) {
|
|
79758
79883
|
case "darwin":
|
|
79759
79884
|
return readMacClipboard(spawnImpl, mkTempPath);
|
|
@@ -79936,15 +80061,14 @@ function writeImageBytes(bytes, declaredMime, mkTempPath) {
|
|
|
79936
80061
|
const mimeType = detectMimeFromMagic(bytes) ?? declaredMime;
|
|
79937
80062
|
const targetPath = mkTempPath(extensionForMime(mimeType));
|
|
79938
80063
|
try {
|
|
79939
|
-
writeFileSync12(targetPath, bytes);
|
|
80064
|
+
writeFileSync12(targetPath, bytes, { flag: "r+", mode: 384 });
|
|
79940
80065
|
} catch (err) {
|
|
79941
80066
|
return { ok: false, kind: "failed", message: `Failed to write temp image: ${errorMessage4(err)}` };
|
|
79942
80067
|
}
|
|
79943
80068
|
return {
|
|
79944
80069
|
ok: true,
|
|
79945
80070
|
path: targetPath,
|
|
79946
|
-
mimeType
|
|
79947
|
-
cleanup: makeCleanup(targetPath)
|
|
80071
|
+
mimeType
|
|
79948
80072
|
};
|
|
79949
80073
|
}
|
|
79950
80074
|
function finalizeTempImage(path34, mimeType) {
|
|
@@ -79955,11 +80079,9 @@ function finalizeTempImage(path34, mimeType) {
|
|
|
79955
80079
|
}
|
|
79956
80080
|
const size = statSync12(path34).size;
|
|
79957
80081
|
if (size === 0) {
|
|
79958
|
-
makeCleanup(path34)();
|
|
79959
80082
|
return { ok: false, kind: "no-image", message: "Clipboard does not contain an image." };
|
|
79960
80083
|
}
|
|
79961
80084
|
if (size > MAX_IMAGE_BYTES) {
|
|
79962
|
-
makeCleanup(path34)();
|
|
79963
80085
|
return { ok: false, kind: "too-large", message: `Clipboard image is too large (${formatBytes2(size)}).` };
|
|
79964
80086
|
}
|
|
79965
80087
|
bytes = readFileSync17(path34);
|
|
@@ -79968,10 +80090,9 @@ function finalizeTempImage(path34, mimeType) {
|
|
|
79968
80090
|
}
|
|
79969
80091
|
const detected = detectMimeFromMagic(bytes);
|
|
79970
80092
|
if (!detected) {
|
|
79971
|
-
makeCleanup(path34)();
|
|
79972
80093
|
return { ok: false, kind: "no-image", message: "Clipboard does not contain a supported image (PNG/JPEG)." };
|
|
79973
80094
|
}
|
|
79974
|
-
return { ok: true, path: path34, mimeType: detected
|
|
80095
|
+
return { ok: true, path: path34, mimeType: detected };
|
|
79975
80096
|
}
|
|
79976
80097
|
function detectMimeFromMagic(bytes) {
|
|
79977
80098
|
if (bytes.length >= 8 && bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71) {
|
|
@@ -79982,14 +80103,6 @@ function detectMimeFromMagic(bytes) {
|
|
|
79982
80103
|
}
|
|
79983
80104
|
return void 0;
|
|
79984
80105
|
}
|
|
79985
|
-
function makeCleanup(path34) {
|
|
79986
|
-
return () => {
|
|
79987
|
-
try {
|
|
79988
|
-
unlinkSync8(path34);
|
|
79989
|
-
} catch {
|
|
79990
|
-
}
|
|
79991
|
-
};
|
|
79992
|
-
}
|
|
79993
80106
|
function spawnFailure(outcome, tool) {
|
|
79994
80107
|
if (outcome.error === "too-large") {
|
|
79995
80108
|
return { ok: false, kind: "too-large", message: "Clipboard image is too large." };
|
|
@@ -80019,7 +80132,7 @@ function formatBytes2(bytes) {
|
|
|
80019
80132
|
}
|
|
80020
80133
|
|
|
80021
80134
|
// src/input/image-paste.ts
|
|
80022
|
-
import { mkdtempSync, writeFileSync as writeFileSync13, rmSync as rmSync3 } from "node:fs";
|
|
80135
|
+
import { mkdtempSync as mkdtempSync2, writeFileSync as writeFileSync13, rmSync as rmSync3 } from "node:fs";
|
|
80023
80136
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
80024
80137
|
import { join as join21 } from "node:path";
|
|
80025
80138
|
var pastingHosts = /* @__PURE__ */ new WeakSet();
|
|
@@ -80046,7 +80159,7 @@ function terminalResultToClipboardResult(result) {
|
|
|
80046
80159
|
const ext = result.mimeType === "image/jpeg" ? ".jpg" : ".png";
|
|
80047
80160
|
let dir;
|
|
80048
80161
|
try {
|
|
80049
|
-
dir =
|
|
80162
|
+
dir = mkdtempSync2(join21(tmpdir2(), "pie-osc5522-"));
|
|
80050
80163
|
const path34 = join21(dir, formatPastedImageName(/* @__PURE__ */ new Date(), ext));
|
|
80051
80164
|
writeFileSync13(path34, result.bytes);
|
|
80052
80165
|
return {
|
|
@@ -83026,6 +83139,12 @@ var InteractiveMode = class {
|
|
|
83026
83139
|
get controllerSetupHost() {
|
|
83027
83140
|
return this;
|
|
83028
83141
|
}
|
|
83142
|
+
getYoloGrantRemainingMs() {
|
|
83143
|
+
return this.yoloGrant.remainingMs();
|
|
83144
|
+
}
|
|
83145
|
+
revokeYoloGrant() {
|
|
83146
|
+
return this.yoloGrant.revoke();
|
|
83147
|
+
}
|
|
83029
83148
|
getPolicyContext = () => ({
|
|
83030
83149
|
mode: this.planModeEnabled ? "plan" : "normal",
|
|
83031
83150
|
yoloMode: this.yoloMode || this.yoloGrant.isActive(),
|
|
@@ -83183,7 +83302,7 @@ var InteractiveMode = class {
|
|
|
83183
83302
|
async init() {
|
|
83184
83303
|
const activeSession = this.sessionManager.getActiveSession();
|
|
83185
83304
|
this.thinkingLevel = resolveInitialThinkingLevel({ session: activeSession, settingsManager: this.options.settingsManager });
|
|
83186
|
-
const { Agent } = await import("./chunks/src-
|
|
83305
|
+
const { Agent } = await import("./chunks/src-5JJZZ5H7.js");
|
|
83187
83306
|
this.agent = new Agent({
|
|
83188
83307
|
initialState: {
|
|
83189
83308
|
systemPrompt: this.buildSystemPrompt(),
|
|
@@ -84075,7 +84194,7 @@ async function runPrintMode(params) {
|
|
|
84075
84194
|
`);
|
|
84076
84195
|
console.log("Assistant: ");
|
|
84077
84196
|
}
|
|
84078
|
-
const { Agent: AgentClass } = await import("./chunks/src-
|
|
84197
|
+
const { Agent: AgentClass } = await import("./chunks/src-5JJZZ5H7.js");
|
|
84079
84198
|
let agent;
|
|
84080
84199
|
const printModeExtensions = await loadPrintModeExtensions({
|
|
84081
84200
|
cwd: runtime.cwd,
|
|
@@ -84375,7 +84494,6 @@ function parseInput(line) {
|
|
|
84375
84494
|
};
|
|
84376
84495
|
}
|
|
84377
84496
|
if (parsed.type === "sidechat.request" && typeof parsed.requestId === "string" && typeof parsed.prompt === "string") {
|
|
84378
|
-
if (parsed.hostContext !== void 0 && !isHostContextBlock(parsed.hostContext)) return null;
|
|
84379
84497
|
return {
|
|
84380
84498
|
type: "sidechat.request",
|
|
84381
84499
|
sessionId: typeof parsed.sessionId === "string" ? parsed.sessionId : void 0,
|
|
@@ -84385,7 +84503,6 @@ function parseInput(line) {
|
|
|
84385
84503
|
};
|
|
84386
84504
|
}
|
|
84387
84505
|
if ((parsed.type === "turn.request" || parsed.type === "turn.input") && typeof parsed.turnId === "string" && typeof parsed.prompt === "string") {
|
|
84388
|
-
if (parsed.hostContext !== void 0 && !isHostContextBlock(parsed.hostContext)) return null;
|
|
84389
84506
|
const streamingBehavior = parsed.streamingBehavior;
|
|
84390
84507
|
if (streamingBehavior !== void 0 && streamingBehavior !== "steer" && streamingBehavior !== "followUp") {
|
|
84391
84508
|
return null;
|
|
@@ -84923,6 +85040,11 @@ async function runJsonEventsMode(params) {
|
|
|
84923
85040
|
}
|
|
84924
85041
|
const startedAt = Date.now();
|
|
84925
85042
|
if (params.mockResponse !== void 0) {
|
|
85043
|
+
const hostContextFailure = validateIntakeHostContext(message);
|
|
85044
|
+
if (hostContextFailure) {
|
|
85045
|
+
writeSidechatFailure(message, hostContextFailure.message, hostContextFailure.code);
|
|
85046
|
+
return;
|
|
85047
|
+
}
|
|
84926
85048
|
writeEvent({ type: "sidechat.started", sessionId, requestId });
|
|
84927
85049
|
const event = {
|
|
84928
85050
|
type: "sidechat.completed",
|
|
@@ -84967,7 +85089,7 @@ async function runJsonEventsMode(params) {
|
|
|
84967
85089
|
const sideTrace = trace;
|
|
84968
85090
|
const sideApiKey = runtime.apiKey;
|
|
84969
85091
|
const snapshot = structuredClone(parent.state.messages);
|
|
84970
|
-
const { Agent: AgentClass } = await import("./chunks/src-
|
|
85092
|
+
const { Agent: AgentClass } = await import("./chunks/src-5JJZZ5H7.js");
|
|
84971
85093
|
const sideAgent = new AgentClass({
|
|
84972
85094
|
initialState: {
|
|
84973
85095
|
systemPrompt: parent.state.systemPrompt,
|
|
@@ -85331,7 +85453,7 @@ async function runJsonEventsMode(params) {
|
|
|
85331
85453
|
if (runtime.initialModel.unconfigured || controller) {
|
|
85332
85454
|
return;
|
|
85333
85455
|
}
|
|
85334
|
-
const { Agent: AgentClass } = await import("./chunks/src-
|
|
85456
|
+
const { Agent: AgentClass } = await import("./chunks/src-5JJZZ5H7.js");
|
|
85335
85457
|
if (runtimeClosing) return;
|
|
85336
85458
|
const compositionRegistry = createCliHostEnvelopeRegistry();
|
|
85337
85459
|
const jsonModeExtensions = await loadJsonModeExtensions({ runtime, envelopeRegistry: compositionRegistry, getAgent: () => agent });
|
|
@@ -85523,7 +85645,7 @@ async function runJsonEventsMode(params) {
|
|
|
85523
85645
|
return message.hostContext ? [message.hostContext, { type: "text", text: message.prompt }] : [{ type: "text", text: message.prompt }];
|
|
85524
85646
|
}
|
|
85525
85647
|
function validateIntakeHostContext(message) {
|
|
85526
|
-
return message.hostContext ? intakeHostContextFailure(message.hostContext, envelopeRegistry) : void 0;
|
|
85648
|
+
return message.hostContext !== void 0 ? intakeHostContextFailure(message.hostContext, envelopeRegistry) : void 0;
|
|
85527
85649
|
}
|
|
85528
85650
|
async function runTurn(message) {
|
|
85529
85651
|
if (isSessionMismatch(message)) {
|
|
@@ -85731,7 +85853,8 @@ async function runJsonEventsMode(params) {
|
|
|
85731
85853
|
sessionId,
|
|
85732
85854
|
turnId: message.turnId,
|
|
85733
85855
|
error: failure.message,
|
|
85734
|
-
|
|
85856
|
+
code: failure.code,
|
|
85857
|
+
...failure.code === "host_context_unknown_projector" ? { hostContextKinds: cliHostEnvelopeKinds(envelopeRegistry) } : {}
|
|
85735
85858
|
});
|
|
85736
85859
|
return;
|
|
85737
85860
|
}
|
|
@@ -86018,7 +86141,7 @@ async function runWithJsonEventsConsoleIsolation(fn) {
|
|
|
86018
86141
|
}
|
|
86019
86142
|
async function createCliTestStreamFnFromEnv() {
|
|
86020
86143
|
if (!process.env.PIE_TEST_MOCK_STREAM_SEQUENCE) return void 0;
|
|
86021
|
-
return (await import("./chunks/test-stream-
|
|
86144
|
+
return (await import("./chunks/test-stream-ZBTSPU7J.js")).createTestStreamFnFromSequenceEnv();
|
|
86022
86145
|
}
|
|
86023
86146
|
function resolveJsonEventsDetailFlag() {
|
|
86024
86147
|
for (let index = 0; index < process.argv.length; index += 1) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cydm/pie",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.13",
|
|
4
4
|
"description": "Pie AI Agent CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"test:skill-regressions": "node --test --import tsx test/bash-lifecycle.test.ts test/bash-powershell-display.test.ts test/skill-creator-runner.test.ts test/tui-use-contract.test.ts test/tui-use-runtime.test.ts test/browser-runtime.test.ts test/axi-stop-semantics.test.ts test/computer-use-axi.test.ts test/computer-evidence.test.ts test/interactive-lifecycle.test.ts",
|
|
21
21
|
"test:offline:post": "node --test --import tsx test/remote-model-catalog.test.ts",
|
|
22
22
|
"test:offline": "node ../../scripts/run-cli-offline.mjs",
|
|
23
|
-
"test:offline:main": "node --test --test-concurrency=
|
|
23
|
+
"test:offline:main": "node --test --test-concurrency=2 --import tsx test/cli-attention.test.ts test/builtin-extensions.test.ts test/core-services.test.ts test/cli.test.ts test/cli-auto-compaction.test.ts test/execution-state-manager.test.ts test/queued-steer-execution-state.test.ts test/todo-steering-ownership.test.ts test/architecture-boundaries.test.ts test/attachment-resolver.test.ts test/kimi-attachment-provider.test.ts test/document-attachment-extension.test.ts test/auto-compact-overflow.test.ts test/auto-compaction-ui.test.ts test/tool-compaction-dogfood.terminal.test.ts test/hierarchical-command-system.test.ts test/mcp-adapter.test.ts test/herdr-agent-state.test.ts test/extensions-enablement.test.ts test/extension-selector-shortcuts.test.ts test/skill-tool-enablement.test.ts test/message-queue-unit.test.ts test/evals-harness.test.ts test/session-trace.test.ts test/json-events-sidechat-diagnostics.test.ts test/json-events-prewarm-shutdown.test.ts test/json-envelope-composition.test.ts test/subagent-session-store.test.ts test/runtime-mode-context.test.ts test/tool-policy.test.ts test/retry-policy.test.ts test/yolo-command.test.ts test/footer-lifecycle.test.ts test/footer-waiting-for-user.test.ts test/files-utils.test.ts test/source-size-guard.test.ts test/runtime-logger.test.ts test/release-readiness.test.ts test/package-artifacts.test.ts test/init-extension-contract.test.ts test/skills-runtime.test.ts test/skills-agents-discovery.test.ts test/skills-symlink.test.ts test/model-overrides.test.ts test/auth-storage.test.ts test/extension-register-provider.test.ts test/extension-reload.test.ts test/extension-terminal-input.test.ts test/extension-session-before-events.test.ts test/extension-widgets.test.ts test/extension-render-hint.test.ts test/extension-oauth-restore.test.ts test/cross-host-parity.test.ts test/tool-name-rendering.test.ts test/session-selector.test.ts test/tree-selector-pagination.test.ts test/context-report.test.ts test/context-signals.test.ts test/plan-cache-stability.test.ts test/cache-invalidation-trace.test.ts test/cache-retention.test.ts test/trace-report.test.ts test/boot-report.test.ts test/compaction-diff.test.ts test/entry-body-and-usage.test.ts test/session-control.test.ts test/terminal-title.test.ts test/interactive-controller-title.test.ts test/todo-title.terminal.test.ts test/host-envelope-dogfood.terminal.test.ts test/host-envelope-cross-mode.test.ts test/host-envelope-registry-lifecycle.test.ts test/host-envelope-migration-roundtrip.test.ts test/host-envelope-intake-order.test.ts test/plan-mode-extension.test.ts test/extension-interaction-signals.test.ts test/rendered-page-reader.test.ts test/tools-registry.test.ts test/system-prompt-contract.test.ts test/bash-yolo.test.ts test/bash-contract.test.ts test/bash-confirm-pending.test.ts test/interaction-status-lifecycle.test.ts test/bash-process-group.test.ts test/bash-artifact-sink.test.ts test/direct-bash.test.ts test/terminal-bell.test.ts test/ctrl-d-exit.test.ts test/session-display-title.test.ts test/calm-mode.test.ts test/stream-render-throttle.test.ts test/message-display-resync.test.ts test/project-root.test.ts test/guard-advisory-context.test.ts test/clear-command-usage.test.ts test/daily-agent-smoke.terminal.test.ts test/slash-menu-toggles.terminal.test.ts test/cli-args.test.ts test/extensions-configured-paths.test.ts test/extensions-loader-path.test.ts test/file-picker.test.ts test/interrupt-recovery.test.ts test/mention-insert-regression.test.ts test/image-paste.test.ts test/clipboard-read-image.test.ts test/clipboard-races.test.ts test/clipboard-dogfood.terminal.test.ts test/mention-picker-navigation.test.ts test/pie-unity-rpc-skill.test.ts test/skill-creator-scripts.test.ts test/interactive-compact-command.test.ts test/computer-use-broker.test.ts test/computer-use-review-regressions.test.ts test/computer-use-safety.test.ts ../../scripts/node-test-diagnostics.test.js ../../scripts/offline-test-runner.test.js ../../scripts/unity-consumer.test.mjs ../../scripts/owned-process-cleanup.test.mjs",
|
|
24
24
|
"test:all": "npm run test:offline && npm run test:terminal:vitest",
|
|
25
25
|
"test:terminal:vitest": "vitest run test/mention-file-select.terminal.test.ts test/tool-partial-display.terminal.test.ts test/footer-plan-mode.test.ts test/viewport-position-final.test.ts test/resume-header.terminal.test.ts --no-file-parallelism",
|
|
26
26
|
"test:todo-tui": "node ../../scripts/run-with-env.mjs PIE_REAL_TODO_TUI=1 -- --test --import tsx test/todo-closure.terminal.test.ts",
|