@cydm/pie 2.5.1 → 2.6.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/dist/builtin/extensions/ask-user/index.js +3 -3
- package/dist/builtin/extensions/computer-use/index.js +17 -2
- package/dist/builtin/extensions/computer-use/prebuilt/macos/arm64/pie-computer-use +0 -0
- package/dist/builtin/extensions/computer-use/prebuilt/macos/universal/pie-computer-use.app/Contents/MacOS/pie-computer-use +0 -0
- package/dist/builtin/extensions/computer-use/prebuilt/macos/x64/pie-computer-use +0 -0
- package/dist/builtin/extensions/computer-use/scripts/setup-helper.mjs +90 -9
- package/dist/builtin/extensions/mcp-adapter/index.js +135 -27
- package/dist/builtin/extensions/plan-mode/index.js +3 -3
- package/dist/builtin/extensions/subagent/index.js +8 -5
- package/dist/builtin/extensions/todo/index.js +3 -3
- package/dist/builtin/skills/chrome-devtools-axi/chrome-devtools-axi-bridge.js +199 -40
- package/dist/builtin/skills/chrome-devtools-axi/chrome-devtools-axi-cli.js +5 -2
- package/dist/builtin/skills/chrome-devtools-axi/chrome-devtools-axi-runtime.js +1 -1
- package/dist/builtin/skills/chrome-devtools-axi/{cli-P4VG6ZZG.js → cli-GB37NZHQ.js} +78 -29
- package/dist/builtin/skills/tui-use/SKILL.md +44 -0
- package/dist/builtin/skills/tui-use/tui-use-cli.cjs +40 -16
- package/dist/builtin/skills/tui-use/tui-use-daemon.cjs +7 -1
- package/dist/chunks/{chunk-REP6QANY.js → chunk-AZ336HKF.js} +405 -70
- package/dist/chunks/{chunk-N2MK46AE.js → chunk-G6KCJA6B.js} +7 -2
- package/dist/chunks/{chunk-YRXXRLMQ.js → chunk-O2DKMLNX.js} +152 -8
- package/dist/chunks/{chunk-ZKHMNEXL.js → chunk-Y4CYXJR7.js} +27 -2
- package/dist/chunks/src-VCWCE7YV.js +20 -0
- package/dist/chunks/{test-stream-OD3B57AS.js → test-stream-GOSEWMJ3.js} +1 -1
- package/dist/cli.js +67 -17
- package/package.json +2 -2
- package/dist/chunks/src-SXUQ7OY6.js +0 -14
|
@@ -1845,8 +1845,8 @@ function isProcessAlive(pid) {
|
|
|
1845
1845
|
try {
|
|
1846
1846
|
process.kill(pid, 0);
|
|
1847
1847
|
return true;
|
|
1848
|
-
} catch {
|
|
1849
|
-
return
|
|
1848
|
+
} catch (error) {
|
|
1849
|
+
return error?.code !== "ESRCH";
|
|
1850
1850
|
}
|
|
1851
1851
|
}
|
|
1852
1852
|
function httpGet(port, path, timeoutMs = 2e3) {
|
|
@@ -1935,6 +1935,23 @@ async function waitForProcessExit(pid, timeoutMs) {
|
|
|
1935
1935
|
return !isProcessAlive(pid);
|
|
1936
1936
|
}
|
|
1937
1937
|
function isBridgeProcess(pid) {
|
|
1938
|
+
if (process.platform === "win32") {
|
|
1939
|
+
try {
|
|
1940
|
+
const command = execFileSync(
|
|
1941
|
+
"powershell",
|
|
1942
|
+
[
|
|
1943
|
+
"-NoProfile",
|
|
1944
|
+
"-NonInteractive",
|
|
1945
|
+
"-Command",
|
|
1946
|
+
`(Get-CimInstance Win32_Process -Filter "ProcessId=${pid}").CommandLine`
|
|
1947
|
+
],
|
|
1948
|
+
{ encoding: "utf-8", timeout: 4e3 }
|
|
1949
|
+
);
|
|
1950
|
+
return command.includes("chrome-devtools-axi-bridge");
|
|
1951
|
+
} catch {
|
|
1952
|
+
return false;
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1938
1955
|
try {
|
|
1939
1956
|
const command = execFileSync("ps", ["-p", String(pid), "-o", "command="], {
|
|
1940
1957
|
encoding: "utf-8",
|
|
@@ -1949,28 +1966,43 @@ async function probeBridgeIdentity(port, sessionName) {
|
|
|
1949
1966
|
try {
|
|
1950
1967
|
const resp = await httpGet(port, "/health", HEALTH_TIMEOUT_MS);
|
|
1951
1968
|
const data = JSON.parse(resp);
|
|
1952
|
-
if (data.status !== "ok") return "unknown";
|
|
1969
|
+
if (data.status !== "ok") return { identity: "unknown" };
|
|
1953
1970
|
if (typeof data.session === "string" && data.session !== sessionName) {
|
|
1954
|
-
return "other";
|
|
1971
|
+
return { identity: "other" };
|
|
1955
1972
|
}
|
|
1956
|
-
return
|
|
1973
|
+
return {
|
|
1974
|
+
identity: "own",
|
|
1975
|
+
reportedPid: typeof data.pid === "number" && data.pid > 0 ? data.pid : void 0
|
|
1976
|
+
};
|
|
1957
1977
|
} catch {
|
|
1958
|
-
return "unknown";
|
|
1978
|
+
return { identity: "unknown" };
|
|
1959
1979
|
}
|
|
1960
1980
|
}
|
|
1961
1981
|
async function judgeRecordedBridge(pidInfo, sessionName) {
|
|
1962
|
-
const
|
|
1963
|
-
if (identity === "own") {
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1982
|
+
const probe = await probeBridgeIdentity(pidInfo.port, sessionName);
|
|
1983
|
+
if (probe.identity === "own") {
|
|
1984
|
+
if (probe.reportedPid !== void 0) {
|
|
1985
|
+
if (probe.reportedPid === pidInfo.pid) {
|
|
1986
|
+
return {
|
|
1987
|
+
terminate: true,
|
|
1988
|
+
killProcessGroup: isBridgeProcess(pidInfo.pid),
|
|
1989
|
+
targetPid: pidInfo.pid
|
|
1990
|
+
};
|
|
1991
|
+
}
|
|
1992
|
+
return {
|
|
1993
|
+
terminate: true,
|
|
1994
|
+
killProcessGroup: isBridgeProcess(probe.reportedPid),
|
|
1995
|
+
targetPid: probe.reportedPid
|
|
1996
|
+
};
|
|
1997
|
+
}
|
|
1998
|
+
const bridge2 = isBridgeProcess(pidInfo.pid);
|
|
1999
|
+
return { terminate: bridge2, killProcessGroup: bridge2, targetPid: pidInfo.pid };
|
|
1968
2000
|
}
|
|
1969
|
-
if (identity === "other") {
|
|
2001
|
+
if (probe.identity === "other") {
|
|
1970
2002
|
return { terminate: false, killProcessGroup: false };
|
|
1971
2003
|
}
|
|
1972
2004
|
const bridge = isBridgeProcess(pidInfo.pid);
|
|
1973
|
-
return { terminate: bridge, killProcessGroup: bridge };
|
|
2005
|
+
return { terminate: bridge, killProcessGroup: bridge, targetPid: pidInfo.pid };
|
|
1974
2006
|
}
|
|
1975
2007
|
function removePidFile(pidFile) {
|
|
1976
2008
|
try {
|
|
@@ -1978,13 +2010,27 @@ function removePidFile(pidFile) {
|
|
|
1978
2010
|
} catch {
|
|
1979
2011
|
}
|
|
1980
2012
|
}
|
|
2013
|
+
function taskkillTree(pid) {
|
|
2014
|
+
try {
|
|
2015
|
+
execFileSync("taskkill", ["/PID", String(pid), "/T", "/F"], {
|
|
2016
|
+
stdio: "ignore",
|
|
2017
|
+
timeout: 1e4
|
|
2018
|
+
});
|
|
2019
|
+
return true;
|
|
2020
|
+
} catch {
|
|
2021
|
+
return !isProcessAlive(pid);
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
1981
2024
|
async function terminateBridgeProcess(pid, opts = {}) {
|
|
1982
|
-
if (!isProcessAlive(pid)) return;
|
|
2025
|
+
if (!isProcessAlive(pid)) return true;
|
|
1983
2026
|
const killProcessGroup = opts.killProcessGroup === true;
|
|
2027
|
+
if (process.platform === "win32") {
|
|
2028
|
+
return taskkillTree(pid) && !await isProcessAlive(pid);
|
|
2029
|
+
}
|
|
1984
2030
|
try {
|
|
1985
2031
|
process.kill(pid, "SIGTERM");
|
|
1986
|
-
} catch {
|
|
1987
|
-
return;
|
|
2032
|
+
} catch (error) {
|
|
2033
|
+
if (error.code === "ESRCH") return true;
|
|
1988
2034
|
}
|
|
1989
2035
|
if (await waitForProcessExit(pid, 2e3)) {
|
|
1990
2036
|
if (killProcessGroup) {
|
|
@@ -1993,7 +2039,7 @@ async function terminateBridgeProcess(pid, opts = {}) {
|
|
|
1993
2039
|
} catch {
|
|
1994
2040
|
}
|
|
1995
2041
|
}
|
|
1996
|
-
return;
|
|
2042
|
+
return true;
|
|
1997
2043
|
}
|
|
1998
2044
|
if (killProcessGroup) {
|
|
1999
2045
|
try {
|
|
@@ -2010,7 +2056,7 @@ async function terminateBridgeProcess(pid, opts = {}) {
|
|
|
2010
2056
|
} catch {
|
|
2011
2057
|
}
|
|
2012
2058
|
}
|
|
2013
|
-
|
|
2059
|
+
return waitForProcessExit(pid, 1e3);
|
|
2014
2060
|
}
|
|
2015
2061
|
function spawnBridgeProcess(port, sessionName) {
|
|
2016
2062
|
const bridgeScript = resolveBridgeScript(import.meta.dirname);
|
|
@@ -2100,7 +2146,7 @@ async function ensureBridge(spawnBridge = spawnBridgeProcess, notice) {
|
|
|
2100
2146
|
}
|
|
2101
2147
|
const verdict = await judgeRecordedBridge(pidInfo, sessionName);
|
|
2102
2148
|
if (verdict.terminate) {
|
|
2103
|
-
await terminateBridgeProcess(pidInfo.pid, {
|
|
2149
|
+
await terminateBridgeProcess(verdict.targetPid ?? pidInfo.pid, {
|
|
2104
2150
|
killProcessGroup: verdict.killProcessGroup
|
|
2105
2151
|
});
|
|
2106
2152
|
} else {
|
|
@@ -2374,15 +2420,15 @@ async function getSessionSnapshotIfRunning() {
|
|
|
2374
2420
|
}
|
|
2375
2421
|
async function stopBridge() {
|
|
2376
2422
|
const pidInfo = readPidFile();
|
|
2377
|
-
if (!pidInfo) return
|
|
2378
|
-
if (!isProcessAlive(pidInfo.pid)) return
|
|
2423
|
+
if (!pidInfo) return "noop";
|
|
2424
|
+
if (!isProcessAlive(pidInfo.pid)) return "noop";
|
|
2379
2425
|
const verdict = await judgeRecordedBridge(pidInfo, resolveSessionName());
|
|
2380
|
-
if (!verdict.terminate) return
|
|
2381
|
-
await terminateBridgeProcess(pidInfo.pid, {
|
|
2426
|
+
if (!verdict.terminate) return "noop";
|
|
2427
|
+
const terminated = await terminateBridgeProcess(verdict.targetPid ?? pidInfo.pid, {
|
|
2382
2428
|
killProcessGroup: verdict.killProcessGroup
|
|
2383
2429
|
});
|
|
2384
2430
|
clearSelectedPageId();
|
|
2385
|
-
return
|
|
2431
|
+
return terminated ? "stopped" : "failed";
|
|
2386
2432
|
}
|
|
2387
2433
|
|
|
2388
2434
|
// vendor/chrome-devtools-axi/src/generation.ts
|
|
@@ -3931,12 +3977,15 @@ async function handleStart() {
|
|
|
3931
3977
|
const port = await ensureBridge();
|
|
3932
3978
|
return encode({ status: "ready", port });
|
|
3933
3979
|
}
|
|
3934
|
-
function formatStopOutput(
|
|
3935
|
-
|
|
3980
|
+
function formatStopOutput(outcome) {
|
|
3981
|
+
if (outcome === "failed") {
|
|
3982
|
+
throw new Error("bridge stop failed: the target survived SIGTERM and SIGKILL escalation");
|
|
3983
|
+
}
|
|
3984
|
+
return encode({ status: outcome === "stopped" ? "stopped" : "stopped (no-op)" });
|
|
3936
3985
|
}
|
|
3937
3986
|
async function handleStop() {
|
|
3938
|
-
const
|
|
3939
|
-
return formatStopOutput(
|
|
3987
|
+
const outcome = await stopBridge();
|
|
3988
|
+
return formatStopOutput(outcome);
|
|
3940
3989
|
}
|
|
3941
3990
|
async function handlePages() {
|
|
3942
3991
|
const result = await callTool("list_pages");
|
|
@@ -50,10 +50,54 @@ tui-use daemon stop
|
|
|
50
50
|
- Send an explicit `press enter` after typing when reliable submission matters.
|
|
51
51
|
- `wait --text` exits non-zero if the requested pattern is absent at the deadline.
|
|
52
52
|
Read the returned screen and fix the input instead of assuming the wait succeeded.
|
|
53
|
+
Do not rerun the identical failing wait; poll with `--poll` (below) or change the input.
|
|
53
54
|
- Use `wait --exit` to confirm process termination. Seeing the last output or
|
|
54
55
|
leaving fullscreen does not by itself mean the process has exited.
|
|
55
56
|
- Kill only sessions you created. Do not restart or stop a daemon that owns another task's live sessions.
|
|
56
57
|
|
|
58
|
+
## Bounded Polling For Long Tasks
|
|
59
|
+
|
|
60
|
+
For work that legitimately takes longer than one wait, opt in to poll mode:
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
tui-use --session <id> wait 20000 --text "DONE_MARKER" --poll --format json
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- `wait_state: "satisfied"` (exit 0): the marker appeared, or `--exit` saw the exit.
|
|
67
|
+
With `--exit` this means termination was observed, not that the program
|
|
68
|
+
succeeded: read `exit_code`, which can be nonzero.
|
|
69
|
+
- `wait_state: "pending"` (exit 0): the deadline passed while the process is still
|
|
70
|
+
running. This only means the PTY is alive; it is not evidence of progress.
|
|
71
|
+
- `wait_state: "failed"` (exit 1): the session exited without the `--text` marker.
|
|
72
|
+
Daemon, session and argument errors also exit 1. Never treat these as pending.
|
|
73
|
+
|
|
74
|
+
Set a total budget before polling (for example at most 6 polls or 10 minutes).
|
|
75
|
+
After each pending poll compare the `screen` with the previous poll. If the
|
|
76
|
+
screen is unchanged across two or three polls, or the budget is spent, stop and
|
|
77
|
+
report the task as not progressing, with the last screen, instead of polling on.
|
|
78
|
+
For programs that can emit structured output, prefer that over viewport text.
|
|
79
|
+
|
|
80
|
+
## Waiting On Pie Tasks
|
|
81
|
+
|
|
82
|
+
To run or supervise a Pie task, use the JSONL protocol over pipes instead of
|
|
83
|
+
driving the Pie TUI through this skill and reading its viewport:
|
|
84
|
+
|
|
85
|
+
```text
|
|
86
|
+
pie chat --json-events # stdin: one JSON request per line; stdout: one JSON event per line
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- Wait for `agent.ready`, then send
|
|
90
|
+
`{"type":"turn.request","turnId":"t1","prompt":"..."}`.
|
|
91
|
+
- The turn outcome is exactly one of `turn.completed`, `turn.failed`,
|
|
92
|
+
`turn.cancelled` or `turn.stalled`, followed by `turn.settled`. Decide from
|
|
93
|
+
these events, not from screen text or the process still running.
|
|
94
|
+
- `tool.started`/`tool.completed` and `turn.retry.*` events are progress
|
|
95
|
+
evidence. Pie emits `turn.stalled` after `PIE_JSON_EVENTS_NO_PROGRESS_MS`
|
|
96
|
+
(default 10 minutes) without activity.
|
|
97
|
+
- `turn.failed` after `turn.retry.exhausted`, or an exhausted-quota/balance
|
|
98
|
+
error, is terminal: report it instead of resubmitting the same prompt.
|
|
99
|
+
- Use `{"type":"turn.interrupt"}` to cancel and `{"type":"shutdown"}` to exit.
|
|
100
|
+
|
|
57
101
|
## Host Behavior
|
|
58
102
|
|
|
59
103
|
Windows defaults to native PowerShell with matching invocation arguments;
|
|
@@ -9950,7 +9950,13 @@ var import_node_child_process = require("node:child_process");
|
|
|
9950
9950
|
var import_node_crypto = require("node:crypto");
|
|
9951
9951
|
var import_node_os = __toESM(require("node:os"));
|
|
9952
9952
|
var import_node_path = __toESM(require("node:path"));
|
|
9953
|
-
var expandHome = (value) =>
|
|
9953
|
+
var expandHome = (value) => {
|
|
9954
|
+
if (value === "~") return import_node_os.default.homedir();
|
|
9955
|
+
if (value.startsWith("~/") || value.startsWith("~\\")) {
|
|
9956
|
+
return import_node_path.default.join(import_node_os.default.homedir(), value.slice(2).replace(/\\/g, "/"));
|
|
9957
|
+
}
|
|
9958
|
+
return value;
|
|
9959
|
+
};
|
|
9954
9960
|
var STATE_DIR = import_node_path.default.resolve(process.env.PIE_TUI_USE_STATE_DIR ? expandHome(process.env.PIE_TUI_USE_STATE_DIR) : import_node_path.default.join(expandHome(process.env.PIE_CODING_AGENT_DIR || import_node_path.default.join(import_node_os.default.homedir(), ".pie")), "tui-use"));
|
|
9955
9961
|
var LOG_PATH = import_node_path.default.join(STATE_DIR, "daemon.log");
|
|
9956
9962
|
var PID_PATH = import_node_path.default.join(STATE_DIR, "daemon.pid");
|
|
@@ -10139,17 +10145,27 @@ async function startDaemon() {
|
|
|
10139
10145
|
if (error.code !== "EEXIST") throw error;
|
|
10140
10146
|
try {
|
|
10141
10147
|
const contents = import_node_fs.default.readFileSync(LOCK_PATH, "utf8");
|
|
10142
|
-
|
|
10143
|
-
|
|
10144
|
-
|
|
10145
|
-
|
|
10148
|
+
let reclaim = false;
|
|
10149
|
+
try {
|
|
10150
|
+
const lock = JSON.parse(contents);
|
|
10151
|
+
let alive = true;
|
|
10152
|
+
if (!Number.isInteger(lock.pid) || lock.pid <= 0) alive = false;
|
|
10153
|
+
else {
|
|
10154
|
+
try {
|
|
10155
|
+
process.kill(lock.pid, 0);
|
|
10156
|
+
} catch (e) {
|
|
10157
|
+
if (e.code === "ESRCH") alive = false;
|
|
10158
|
+
}
|
|
10159
|
+
}
|
|
10160
|
+
if (!alive) reclaim = true;
|
|
10161
|
+
} catch {
|
|
10146
10162
|
try {
|
|
10147
|
-
|
|
10148
|
-
|
|
10149
|
-
|
|
10163
|
+
const mtimeMs = import_node_fs.default.statSync(LOCK_PATH).mtimeMs;
|
|
10164
|
+
if (Date.now() - mtimeMs > 5e3) reclaim = true;
|
|
10165
|
+
} catch {
|
|
10150
10166
|
}
|
|
10151
10167
|
}
|
|
10152
|
-
if (
|
|
10168
|
+
if (reclaim && import_node_fs.default.readFileSync(LOCK_PATH, "utf8") === contents) import_node_fs.default.unlinkSync(LOCK_PATH);
|
|
10153
10169
|
} catch {
|
|
10154
10170
|
}
|
|
10155
10171
|
await sleep(100);
|
|
@@ -10345,8 +10361,8 @@ program2.command("snapshot").description("Return the current rendered screen sna
|
|
|
10345
10361
|
handleResponse(res, (r) => printScreen(r, opts.format));
|
|
10346
10362
|
});
|
|
10347
10363
|
program2.command("wait [duration]").description(
|
|
10348
|
-
'Wait for screen to change or timeout.\n wait \u2192 wait for screen to change (default 3000ms)\n wait 5000 \u2192 wait for 5000ms\n wait --text "pattern" \u2192 wait until screen contains text\n wait --debounce 300 \u2192 wait until screen is stable for 300ms (default: 100ms)'
|
|
10349
|
-
).option("--text <text>", "Wait until screen contains literal text").option("--regex", "Interpret --text as a regex in a bounded worker").option("--exit", "Wait for process exit instead of just a screen change").option("--debounce <ms>", "Idle time after last change before resolving, in ms (default: 100)", "100").option("--format <fmt>", "Output format: pretty, json (default: pretty)", "pretty").option("--color", "Preserve ANSI color/style escape sequences in output lines").action(async (duration, opts) => {
|
|
10364
|
+
'Wait for screen to change or timeout.\n wait \u2192 wait for screen to change (default 3000ms)\n wait 5000 \u2192 wait for 5000ms\n wait --text "pattern" \u2192 wait until screen contains text\n wait --debounce 300 \u2192 wait until screen is stable for 300ms (default: 100ms)\n wait --text "pattern" --poll \u2192 exit 0 with wait_state "pending" if the deadline passes while the session is still running'
|
|
10365
|
+
).option("--text <text>", "Wait until screen contains literal text").option("--regex", "Interpret --text as a regex in a bounded worker").option("--exit", "Wait for process exit instead of just a screen change").option("--poll", 'Bounded polling: a deadline on a still-running session reports wait_state "pending" and exits 0; an exited session that never matched --text, and errors, exit 1. With --exit, "satisfied" means termination was observed, not success: check exit_code').option("--debounce <ms>", "Idle time after last change before resolving, in ms (default: 100)", "100").option("--format <fmt>", "Output format: pretty, json (default: pretty)", "pretty").option("--color", "Preserve ANSI color/style escape sequences in output lines").action(async (duration, opts) => {
|
|
10350
10366
|
let timeoutMs = 3e3;
|
|
10351
10367
|
if (duration) {
|
|
10352
10368
|
timeoutMs = Number(duration);
|
|
@@ -10364,8 +10380,15 @@ program2.command("wait [duration]").description(
|
|
|
10364
10380
|
});
|
|
10365
10381
|
handleResponse(res, (r) => {
|
|
10366
10382
|
const screen = r;
|
|
10367
|
-
|
|
10368
|
-
|
|
10383
|
+
const conditional = opts.text !== void 0 || opts.exit;
|
|
10384
|
+
const unmet = conditional && screen.wait_satisfied === false;
|
|
10385
|
+
const pending = !!opts.poll && screen.timed_out === true && screen.status === "running" && (unmet || !conditional);
|
|
10386
|
+
const waitState = opts.poll ? pending ? "pending" : unmet ? "failed" : "satisfied" : void 0;
|
|
10387
|
+
printScreen(screen, opts.format, waitState);
|
|
10388
|
+
if (pending) {
|
|
10389
|
+
process.stderr.write(`Wait pending: ${opts.text ?? (opts.exit ? "process exit" : "screen change")} not seen before timeout; session is still running. Liveness is not evidence of progress: compare screens across polls and stop after a bounded number of unchanged polls.
|
|
10390
|
+
`);
|
|
10391
|
+
} else if (unmet) {
|
|
10369
10392
|
process.stderr.write(`Wait condition was not met${screen.timed_out ? " before timeout" : " before the session exited"}: ${opts.text ?? "process exit"}
|
|
10370
10393
|
`);
|
|
10371
10394
|
process.exitCode = 1;
|
|
@@ -10570,7 +10593,7 @@ function inputText(parts, fromStdin) {
|
|
|
10570
10593
|
if (parts.length === 0) throw new Error("Provide text arguments or --stdin.");
|
|
10571
10594
|
return parts.join(" ");
|
|
10572
10595
|
}
|
|
10573
|
-
function printScreen(r, format = "pretty") {
|
|
10596
|
+
function printScreen(r, format = "pretty", waitState) {
|
|
10574
10597
|
if (format === "json") {
|
|
10575
10598
|
console.log(
|
|
10576
10599
|
JSON.stringify(
|
|
@@ -10586,7 +10609,8 @@ function printScreen(r, format = "pretty") {
|
|
|
10586
10609
|
cols: r.cols,
|
|
10587
10610
|
rows: r.rows,
|
|
10588
10611
|
highlights: r.highlights,
|
|
10589
|
-
...r.type === "wait" ? { wait_satisfied: r.wait_satisfied, timed_out: r.timed_out } : {}
|
|
10612
|
+
...r.type === "wait" ? { wait_satisfied: r.wait_satisfied, timed_out: r.timed_out } : {},
|
|
10613
|
+
...waitState ? { wait_state: waitState } : {}
|
|
10590
10614
|
},
|
|
10591
10615
|
null,
|
|
10592
10616
|
2
|
|
@@ -10596,7 +10620,7 @@ function printScreen(r, format = "pretty") {
|
|
|
10596
10620
|
}
|
|
10597
10621
|
const width = r.cols;
|
|
10598
10622
|
const header = `\u2500\u2500\u2500 ${r.session_id} ${"\u2500".repeat(Math.max(0, width - r.session_id.length - 5))}`;
|
|
10599
|
-
const info = `${r.status} | cursor(${r.cursor.x},${r.cursor.y}) | fullscreen:${r.is_fullscreen} | title:"${r.title || ""}"`;
|
|
10623
|
+
const info = `${r.status} | cursor(${r.cursor.x},${r.cursor.y}) | fullscreen:${r.is_fullscreen} | title:"${r.title || ""}"${waitState ? ` | wait:${waitState}` : ""}`;
|
|
10600
10624
|
const footer = `\u2500\u2500\u2500 ${info} ${"\u2500".repeat(Math.max(0, width - info.length - 5))}`;
|
|
10601
10625
|
process.stdout.write(header + "\n");
|
|
10602
10626
|
for (const line of r.lines) process.stdout.write(line + "\n");
|
|
@@ -7661,7 +7661,13 @@ function validateRequest(value) {
|
|
|
7661
7661
|
var import_node_crypto = require("node:crypto");
|
|
7662
7662
|
var import_node_os = __toESM(require("node:os"));
|
|
7663
7663
|
var import_node_path3 = __toESM(require("node:path"));
|
|
7664
|
-
var expandHome = (value) =>
|
|
7664
|
+
var expandHome = (value) => {
|
|
7665
|
+
if (value === "~") return import_node_os.default.homedir();
|
|
7666
|
+
if (value.startsWith("~/") || value.startsWith("~\\")) {
|
|
7667
|
+
return import_node_path3.default.join(import_node_os.default.homedir(), value.slice(2).replace(/\\/g, "/"));
|
|
7668
|
+
}
|
|
7669
|
+
return value;
|
|
7670
|
+
};
|
|
7665
7671
|
var STATE_DIR = import_node_path3.default.resolve(process.env.PIE_TUI_USE_STATE_DIR ? expandHome(process.env.PIE_TUI_USE_STATE_DIR) : import_node_path3.default.join(expandHome(process.env.PIE_CODING_AGENT_DIR || import_node_path3.default.join(import_node_os.default.homedir(), ".pie")), "tui-use"));
|
|
7666
7672
|
var LOG_PATH = import_node_path3.default.join(STATE_DIR, "daemon.log");
|
|
7667
7673
|
var PID_PATH = import_node_path3.default.join(STATE_DIR, "daemon.pid");
|