camouflage-tui 2.4.0-beta.7 → 2.5.0-beta.4
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/package.json +1 -1
- package/scripts/install.js +2 -2
- package/src/binding.d.ts +0 -10
- package/src/binding.js +0 -37
- package/src/binding.test.js +1 -9
- package/src/index.d.ts +0 -2
- package/src/index.js +1 -1
- package/src/types.d.ts +1 -8
- package/src/types.js +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "camouflage-tui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0-beta.4",
|
|
4
4
|
"description": "High-performance terminal renderer for AI agent applications. A React Ink alternative built for streaming, persistence, and replay.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
package/scripts/install.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { createWriteStream, mkdirSync, chmodSync, existsSync, unlinkSync } from "node:fs";
|
|
12
|
-
import {
|
|
12
|
+
import { execSync } from "node:child_process";
|
|
13
13
|
import { join, dirname } from "node:path";
|
|
14
14
|
import { fileURLToPath } from "node:url";
|
|
15
15
|
import { get as httpsGet } from "node:https";
|
|
@@ -64,7 +64,7 @@ async function main() {
|
|
|
64
64
|
await download(url, tmpPath);
|
|
65
65
|
|
|
66
66
|
// Extract the binary from the tarball (Windows 10+ ships tar.exe).
|
|
67
|
-
|
|
67
|
+
execSync(`tar xzf "${tmpPath}" -C "${BIN_DIR}"`, { stdio: "pipe" });
|
|
68
68
|
unlinkSync(tmpPath);
|
|
69
69
|
|
|
70
70
|
chmodSync(BIN_PATH, 0o755);
|
package/src/binding.d.ts
CHANGED
|
@@ -69,16 +69,6 @@ export function confirm(
|
|
|
69
69
|
},
|
|
70
70
|
): Promise<ConfirmResponseEvent>;
|
|
71
71
|
|
|
72
|
-
/**
|
|
73
|
-
* Hand the terminal to a child process; resolves once the renderer has let
|
|
74
|
-
* go of it. `supported: false` means run the child without a terminal
|
|
75
|
-
* (Windows, full-screen mode, older renderers, or no answer in time).
|
|
76
|
-
*/
|
|
77
|
-
export function suspendTerminal(cam: CamouflageHandle, opts?: { timeoutMs?: number }): Promise<{ supported: boolean }>;
|
|
78
|
-
|
|
79
|
-
/** Take the terminal back after `suspendTerminal`. */
|
|
80
|
-
export function resumeTerminal(cam: CamouflageHandle): void;
|
|
81
|
-
|
|
82
72
|
/** Convenience helper: show a tabular data view. Display-only. */
|
|
83
73
|
export function table(
|
|
84
74
|
cam: CamouflageHandle,
|
package/src/binding.js
CHANGED
|
@@ -344,8 +344,6 @@ export async function mount(opts = {}) {
|
|
|
344
344
|
handle.emit("cancelRequested", {});
|
|
345
345
|
} else if (ev.event_type === "MentionQuery") {
|
|
346
346
|
handle.emit("mentionQuery", { query: ev.payload?.query ?? "" });
|
|
347
|
-
} else if (ev.event_type === "TerminalSuspended") {
|
|
348
|
-
handle.emit("terminalSuspended", { id: ev.payload?.id, supported: ev.payload?.supported === true });
|
|
349
347
|
}
|
|
350
348
|
// Always also emit the raw Event for advanced consumers.
|
|
351
349
|
handle.emit("event", ev);
|
|
@@ -423,41 +421,6 @@ export function confirm(cam, spec) {
|
|
|
423
421
|
return done;
|
|
424
422
|
}
|
|
425
423
|
|
|
426
|
-
/**
|
|
427
|
-
* Hand the terminal to a child process (a `!` shell command, an editor, a
|
|
428
|
-
* login prompt). The inline renderer clears its live area, leaves raw mode
|
|
429
|
-
* and stops reading keys before this resolves. Run the child with
|
|
430
|
-
* `stdio: "inherit"`, then call `resumeTerminal(cam)`.
|
|
431
|
-
*
|
|
432
|
-
* Resolves `{ supported: false }` when the renderer can't hand the terminal
|
|
433
|
-
* over (Windows, full-screen mode, renderers older than 2.4.0-beta.7, or no
|
|
434
|
-
* answer within `timeoutMs`); run the child without a terminal then.
|
|
435
|
-
*
|
|
436
|
-
* @param {CamouflageHandle} cam
|
|
437
|
-
* @param {{timeoutMs?: number}} [opts]
|
|
438
|
-
* @returns {Promise<{supported: boolean}>}
|
|
439
|
-
*/
|
|
440
|
-
export function suspendTerminal(cam, opts = {}) {
|
|
441
|
-
const id = `suspend-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
442
|
-
const answer = awaitResponse(cam, "terminalSuspended", (r) => r.id === id, { id, supported: false });
|
|
443
|
-
const timeout = new Promise((resolve) => {
|
|
444
|
-
const t = setTimeout(() => resolve({ id, supported: false }), opts.timeoutMs ?? 1000);
|
|
445
|
-
t.unref?.();
|
|
446
|
-
});
|
|
447
|
-
cam.send("TerminalSuspend", { id });
|
|
448
|
-
return Promise.race([answer, timeout]).then((r) => ({ supported: r.supported === true }));
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
/**
|
|
452
|
-
* Take the terminal back after `suspendTerminal`: the renderer re-enters
|
|
453
|
-
* raw mode and redraws below whatever the child printed.
|
|
454
|
-
*
|
|
455
|
-
* @param {CamouflageHandle} cam
|
|
456
|
-
*/
|
|
457
|
-
export function resumeTerminal(cam) {
|
|
458
|
-
cam.send("TerminalResume", { id: "resume" });
|
|
459
|
-
}
|
|
460
|
-
|
|
461
424
|
/**
|
|
462
425
|
* Ask the user for permission and resolve to their answer. Resolves
|
|
463
426
|
* `{ choice: "deny" }` if the renderer exits first.
|
package/src/binding.test.js
CHANGED
|
@@ -2,7 +2,7 @@ import { test } from "node:test";
|
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
5
|
-
import { mount, selectList, confirm, permission
|
|
5
|
+
import { mount, selectList, confirm, permission } from "./index.js";
|
|
6
6
|
|
|
7
7
|
const FAKE = join(dirname(fileURLToPath(import.meta.url)), "__fake-renderer.js");
|
|
8
8
|
|
|
@@ -181,11 +181,3 @@ test("a renderer that exits at startup doesn't crash the host", async () => {
|
|
|
181
181
|
await exited;
|
|
182
182
|
assert.equal(cam.send("SessionEnded", {}), false);
|
|
183
183
|
});
|
|
184
|
-
|
|
185
|
-
test("suspendTerminal() falls back to unsupported when the renderer doesn't answer", async () => {
|
|
186
|
-
const cam = await mountFake(); // echoes TerminalSuspend back; never sends TerminalSuspended
|
|
187
|
-
const r = await suspendTerminal(cam, { timeoutMs: 50 });
|
|
188
|
-
assert.deepEqual(r, { supported: false });
|
|
189
|
-
resumeTerminal(cam);
|
|
190
|
-
await cam.close();
|
|
191
|
-
});
|
package/src/index.d.ts
CHANGED
package/src/index.js
CHANGED
|
@@ -15,4 +15,4 @@ export {
|
|
|
15
15
|
encode,
|
|
16
16
|
} from "./types.js";
|
|
17
17
|
|
|
18
|
-
export { mount, selectList, confirm, permission, table, keyValueView, form, wizard, tasksSet
|
|
18
|
+
export { mount, selectList, confirm, permission, table, keyValueView, form, wizard, tasksSet } from "./binding.js";
|
package/src/types.d.ts
CHANGED
|
@@ -53,10 +53,7 @@ export type EventType =
|
|
|
53
53
|
| "Splash"
|
|
54
54
|
| "ShowToast"
|
|
55
55
|
| "MentionQuery"
|
|
56
|
-
| "AssistantReasoningDelta"
|
|
57
|
-
| "TerminalSuspend"
|
|
58
|
-
| "TerminalResume"
|
|
59
|
-
| "TerminalSuspended";
|
|
56
|
+
| "AssistantReasoningDelta";
|
|
60
57
|
|
|
61
58
|
export type Direction = "inbound" | "outbound";
|
|
62
59
|
|
|
@@ -373,10 +370,6 @@ export type Event = EnvelopeMeta &
|
|
|
373
370
|
| { event_type: "AssistantTokenDelta"; payload: AssistantTokenDelta }
|
|
374
371
|
/** v2.4+: the model's reasoning, shown when the user presses Ctrl+R (inline UI). */
|
|
375
372
|
| { event_type: "AssistantReasoningDelta"; payload: AssistantTokenDelta }
|
|
376
|
-
/** v2.4+: hand the terminal to a child process; see `suspendTerminal()`. */
|
|
377
|
-
| { event_type: "TerminalSuspend"; payload: { id: string } }
|
|
378
|
-
| { event_type: "TerminalResume"; payload: { id: string } }
|
|
379
|
-
| { event_type: "TerminalSuspended"; payload: { id: string; supported: boolean } }
|
|
380
373
|
| { event_type: "AssistantMessageCompleted"; payload: AssistantMessageCompleted }
|
|
381
374
|
| { event_type: "ToolExecutionStarted"; payload: ToolStarted }
|
|
382
375
|
| { event_type: "ToolExecutionStdout"; payload: ToolOutput }
|
package/src/types.js
CHANGED