ptywright 0.5.0 → 0.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/agent.mjs +1 -1
- package/dist/bin/ptywright.mjs +1 -1
- package/dist/{cli-PnG6UR43.mjs → cli-IXmvK56U.mjs} +5 -5
- package/dist/cli.mjs +1 -1
- package/dist/data-sdbf3IDh.mjs +18 -0
- package/dist/index.mjs +1 -1
- package/dist/mcp.mjs +1 -1
- package/dist/pty-cassette.mjs +2 -1
- package/dist/{pty_like-BjeBibSL.mjs → pty_like-DWIlWGgA.mjs} +2 -18
- package/dist/{runner-wW_DCBX7.mjs → runner-BHXXwxYp.mjs} +3 -2
- package/dist/{runner-C1gPRyCM.mjs → runner-GIEf0C6d.mjs} +425 -40
- package/dist/script.mjs +1 -1
- package/dist/{server-DMnnXjWv.mjs → server-ceZ1-s_J.mjs} +2 -2
- package/dist/session.mjs +1 -1
- package/dist/style-BtIUv5H0.mjs +65 -0
- package/dist/{terminal_session-DJKr-O3X.mjs → terminal_session-MX_vWpRG.mjs} +2 -65
- package/package.json +1 -1
package/dist/agent.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as formatAgentLaunchPlan, i as runAgentSpecPath, n as replayAgentRecordPath, r as runAgentSpec, t as defaultSpecNameForPath } from "./runner-
|
|
1
|
+
import { a as formatAgentLaunchPlan, i as runAgentSpecPath, n as replayAgentRecordPath, r as runAgentSpec, t as defaultSpecNameForPath } from "./runner-GIEf0C6d.mjs";
|
|
2
2
|
export { defaultSpecNameForPath, formatAgentLaunchPlan, replayAgentRecordPath, runAgentSpec, runAgentSpecPath };
|
package/dist/bin/ptywright.mjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { n as loadPtywrightConfig } from "./config-bGg636EW.mjs";
|
|
2
|
-
import { C as writeAgentManifestPath, D as escapeHtml, E as escapeAttribute, O as normalizeAgentFlowSpec, S as validateAgentManifestFiles, T as readAgentCassettePath, _ as formatArgv, b as isAgentManifestLike, c as launchAgentBrowser, d as AGENT_RUN_RECORD_SCHEMA_URL, f as agentRunModeSchema, g as writeAgentRunRecordPath, h as readAgentRunRecordPath, i as runAgentSpecPath, k as sanitizeArtifactName, l as createAgentTemplateSpec, m as isAgentRunRecordLike, n as replayAgentRecordPath, o as resolveAgentLaunchTarget, p as formatAgentArgv, s as normalizeAgentFlowSpecWithConfig, u as loadAgentSpec, v as AGENT_MANIFEST_FILE_NAME, w as isAgentCassetteLike, x as readAgentManifestPath, y as agentManifestPath } from "./runner-
|
|
2
|
+
import { C as writeAgentManifestPath, D as escapeHtml, E as escapeAttribute, O as normalizeAgentFlowSpec, S as validateAgentManifestFiles, T as readAgentCassettePath, _ as formatArgv, b as isAgentManifestLike, c as launchAgentBrowser, d as AGENT_RUN_RECORD_SCHEMA_URL, f as agentRunModeSchema, g as writeAgentRunRecordPath, h as readAgentRunRecordPath, i as runAgentSpecPath, k as sanitizeArtifactName, l as createAgentTemplateSpec, m as isAgentRunRecordLike, n as replayAgentRecordPath, o as resolveAgentLaunchTarget, p as formatAgentArgv, s as normalizeAgentFlowSpecWithConfig, u as loadAgentSpec, v as AGENT_MANIFEST_FILE_NAME, w as isAgentCassetteLike, x as readAgentManifestPath, y as agentManifestPath } from "./runner-GIEf0C6d.mjs";
|
|
3
3
|
import { a as sameArgv, i as diffCommandMaps, r as formatZodIssues } from "./manifest_files-DW80c1H7.mjs";
|
|
4
4
|
import { i as portableCliPath, n as mergeProcessEnv, o as relativeHref, s as samePath } from "./env-DPYHo-zH.mjs";
|
|
5
|
-
import { d as resolvePtyBackend, u as createDefaultPtyAdapter } from "./runner-
|
|
6
|
-
import { a as resolveScriptManifestPath, c as relocateScriptManifestCommands, d as resolveScriptRunSummaryPath, f as runScriptPath, i as readScriptManifestPath, l as resolveManifestPrimaryPath$1, n as runAllScripts, o as validateScriptManifest, r as findScriptSummaryManifest, t as createPtywrightServer, u as readScriptRunSummaryPath } from "./server-
|
|
7
|
-
import { c as createPtyCassetteReplay, i as formatPtyCassetteInspectLines, l as readPtyCassettePath, o as inspectPtyCassettePath, r as createPtyCassetteRecorder, t as wrapPtyLike, v as validatePtyCassette } from "./pty_like-
|
|
5
|
+
import { d as resolvePtyBackend, u as createDefaultPtyAdapter } from "./runner-BHXXwxYp.mjs";
|
|
6
|
+
import { a as resolveScriptManifestPath, c as relocateScriptManifestCommands, d as resolveScriptRunSummaryPath, f as runScriptPath, i as readScriptManifestPath, l as resolveManifestPrimaryPath$1, n as runAllScripts, o as validateScriptManifest, r as findScriptSummaryManifest, t as createPtywrightServer, u as readScriptRunSummaryPath } from "./server-ceZ1-s_J.mjs";
|
|
7
|
+
import { c as createPtyCassetteReplay, i as formatPtyCassetteInspectLines, l as readPtyCassettePath, o as inspectPtyCassettePath, r as createPtyCassetteRecorder, t as wrapPtyLike, v as validatePtyCassette } from "./pty_like-DWIlWGgA.mjs";
|
|
8
8
|
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
9
9
|
import { basename, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
|
|
10
10
|
import { z } from "zod";
|
|
11
|
+
import { Buffer } from "node:buffer";
|
|
11
12
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
13
|
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
13
|
-
import { Buffer } from "node:buffer";
|
|
14
14
|
//#region src/agent/check_summary_schema.ts
|
|
15
15
|
const AGENT_CHECK_SCHEMA_URL = "https://ptywright.local/schemas/ptywright-agent-check.schema.json";
|
|
16
16
|
const countSummarySchema$1 = z.object({
|
package/dist/cli.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as main } from "./cli-
|
|
1
|
+
import { t as main } from "./cli-IXmvK56U.mjs";
|
|
2
2
|
export { main };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
//#region src/pty-cassette/data.ts
|
|
3
|
+
function dataToBytes(data) {
|
|
4
|
+
if (typeof data === "string") return Buffer.from(data, "utf8");
|
|
5
|
+
if (data instanceof ArrayBuffer) return new Uint8Array(data);
|
|
6
|
+
return data;
|
|
7
|
+
}
|
|
8
|
+
function dataToBase64(data) {
|
|
9
|
+
return Buffer.from(dataToBytes(data)).toString("base64");
|
|
10
|
+
}
|
|
11
|
+
function base64ToBytes(dataBase64) {
|
|
12
|
+
return Buffer.from(dataBase64, "base64");
|
|
13
|
+
}
|
|
14
|
+
function byteLength(data) {
|
|
15
|
+
return dataToBytes(data).byteLength;
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { dataToBytes as i, byteLength as n, dataToBase64 as r, base64ToBytes as t };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as createPtywrightServer } from "./server-
|
|
1
|
+
import { t as createPtywrightServer } from "./server-ceZ1-s_J.mjs";
|
|
2
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
3
|
//#region src/index.ts
|
|
4
4
|
const { server, sessions } = createPtywrightServer();
|
package/dist/mcp.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createPtywrightServer } from "./server-
|
|
1
|
+
import { t as createPtywrightServer } from "./server-ceZ1-s_J.mjs";
|
|
2
2
|
export { createPtywrightServer };
|
package/dist/pty-cassette.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as dataToBytes, n as byteLength, r as dataToBase64, t as base64ToBytes } from "./data-sdbf3IDh.mjs";
|
|
2
|
+
import { _ as ptyCassetteSchema, a as inspectPtyCassette, c as createPtyCassetteReplay, d as PTY_CASSETTE_SCHEMA_URL, f as normalizePtyCassette, g as ptyCassetteResizeEventSchema, h as ptyCassetteExitEventSchema, i as formatPtyCassetteInspectLines, l as readPtyCassettePath, m as ptyCassetteEventSchema, n as PtyCassetteRecorder, o as inspectPtyCassettePath, p as ptyCassetteDataEventSchema, r as createPtyCassetteRecorder, s as PtyCassetteReplay, t as wrapPtyLike, u as writePtyCassettePath, v as validatePtyCassette } from "./pty_like-DWIlWGgA.mjs";
|
|
2
3
|
//#region src/pty-cassette/bun_terminal.ts
|
|
3
4
|
function wrapBunTerminalOptions(options, recorder) {
|
|
4
5
|
const onData = options.data;
|
|
@@ -1,23 +1,7 @@
|
|
|
1
|
+
import { n as byteLength, r as dataToBase64, t as base64ToBytes } from "./data-sdbf3IDh.mjs";
|
|
1
2
|
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
3
|
import { dirname } from "node:path";
|
|
3
4
|
import { z } from "zod";
|
|
4
|
-
import { Buffer } from "node:buffer";
|
|
5
|
-
//#region src/pty-cassette/data.ts
|
|
6
|
-
function dataToBytes(data) {
|
|
7
|
-
if (typeof data === "string") return Buffer.from(data, "utf8");
|
|
8
|
-
if (data instanceof ArrayBuffer) return new Uint8Array(data);
|
|
9
|
-
return data;
|
|
10
|
-
}
|
|
11
|
-
function dataToBase64(data) {
|
|
12
|
-
return Buffer.from(dataToBytes(data)).toString("base64");
|
|
13
|
-
}
|
|
14
|
-
function base64ToBytes(dataBase64) {
|
|
15
|
-
return Buffer.from(dataBase64, "base64");
|
|
16
|
-
}
|
|
17
|
-
function byteLength(data) {
|
|
18
|
-
return dataToBytes(data).byteLength;
|
|
19
|
-
}
|
|
20
|
-
//#endregion
|
|
21
5
|
//#region src/pty-cassette/schema.ts
|
|
22
6
|
const PTY_CASSETTE_SCHEMA_URL = "https://ptywright.local/schemas/ptywright-pty-cassette.schema.json";
|
|
23
7
|
const base64Schema = z.string().refine((value) => value.length % 4 === 0 && /^[A-Za-z0-9+/]*={0,2}$/.test(value), { message: "expected base64-encoded data" });
|
|
@@ -401,4 +385,4 @@ function dispose(disposable) {
|
|
|
401
385
|
disposable.dispose();
|
|
402
386
|
}
|
|
403
387
|
//#endregion
|
|
404
|
-
export {
|
|
388
|
+
export { ptyCassetteSchema as _, inspectPtyCassette as a, createPtyCassetteReplay as c, PTY_CASSETTE_SCHEMA_URL as d, normalizePtyCassette as f, ptyCassetteResizeEventSchema as g, ptyCassetteExitEventSchema as h, formatPtyCassetteInspectLines as i, readPtyCassettePath as l, ptyCassetteEventSchema as m, PtyCassetteRecorder as n, inspectPtyCassettePath as o, ptyCassetteDataEventSchema as p, createPtyCassetteRecorder as r, PtyCassetteReplay as s, wrapPtyLike as t, writePtyCassettePath as u, validatePtyCassette as v };
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { n as mergeProcessEnv, o as relativeHref, t as envTruthy } from "./env-DPYHo-zH.mjs";
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as styleKey, i as isDefaultStyle, n as extractStyle, r as findMeaningfulEndCol } from "./style-BtIUv5H0.mjs";
|
|
3
|
+
import { a as fnv1a32, c as encodeSgrMouse, i as TraceRecorder, l as encodeKey, n as sleep, o as snapshotGrid, r as applyTextMaskRules, s as snapshotLines, t as TerminalSession } from "./terminal_session-MX_vWpRG.mjs";
|
|
3
4
|
import { createRequire } from "node:module";
|
|
4
5
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
6
|
import { basename, dirname, extname, isAbsolute, join, resolve } from "node:path";
|
|
6
7
|
import { pathToFileURL } from "node:url";
|
|
7
8
|
import { z } from "zod";
|
|
8
|
-
import { spawn } from "bun-pty";
|
|
9
9
|
import { Terminal } from "@xterm/headless";
|
|
10
|
+
import { spawn } from "bun-pty";
|
|
10
11
|
//#region src/pty/bun_pty_adapter.ts
|
|
11
12
|
function toForkOptions(options) {
|
|
12
13
|
return {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { a as sameArgv, n as validateManifestFiles, r as formatZodIssues, t as collectManifestFiles } from "./manifest_files-DW80c1H7.mjs";
|
|
2
2
|
import { t as envTruthy } from "./env-DPYHo-zH.mjs";
|
|
3
|
+
import { t as base64ToBytes } from "./data-sdbf3IDh.mjs";
|
|
4
|
+
import { a as styleKey, i as isDefaultStyle, n as extractStyle, r as findMeaningfulEndCol, t as DEFAULT_STYLE } from "./style-BtIUv5H0.mjs";
|
|
3
5
|
import { createRequire } from "node:module";
|
|
4
6
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
7
|
import { basename, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
|
|
@@ -7,6 +9,7 @@ import { pathToFileURL } from "node:url";
|
|
|
7
9
|
import { z } from "zod";
|
|
8
10
|
import { createServer } from "node:http";
|
|
9
11
|
import { chromium } from "playwright";
|
|
12
|
+
import { Terminal } from "@xterm/headless";
|
|
10
13
|
import { spawn } from "node:child_process";
|
|
11
14
|
//#region src/agent/normalize.ts
|
|
12
15
|
function applyAgentMasks(input, rules = [], options = {}) {
|
|
@@ -1390,23 +1393,23 @@ function renderArtifactViewerShellCss() {
|
|
|
1390
1393
|
}
|
|
1391
1394
|
.viewer-stage {
|
|
1392
1395
|
display: grid;
|
|
1393
|
-
grid-template-columns:
|
|
1394
|
-
grid-template-rows:
|
|
1396
|
+
grid-template-columns: minmax(0, 1fr);
|
|
1397
|
+
grid-template-rows: minmax(0, 1fr);
|
|
1395
1398
|
min-width: 0;
|
|
1396
1399
|
min-height: 0;
|
|
1397
|
-
justify-
|
|
1400
|
+
justify-items: center;
|
|
1398
1401
|
align-content: start;
|
|
1399
|
-
overflow:
|
|
1402
|
+
overflow: hidden;
|
|
1400
1403
|
background:
|
|
1401
1404
|
radial-gradient(circle at top left, rgba(121, 192, 255, 0.1), transparent 32%),
|
|
1402
1405
|
#060a13;
|
|
1403
1406
|
padding: 14px;
|
|
1404
1407
|
}
|
|
1405
1408
|
.viewer-viewport {
|
|
1406
|
-
width: var(--config-viewport-width);
|
|
1407
|
-
height: var(--config-viewport-height);
|
|
1408
|
-
max-width:
|
|
1409
|
-
max-height:
|
|
1409
|
+
width: min(var(--config-viewport-width), 100%);
|
|
1410
|
+
height: min(var(--config-viewport-height), 100%);
|
|
1411
|
+
max-width: 100%;
|
|
1412
|
+
max-height: 100%;
|
|
1410
1413
|
overflow: auto;
|
|
1411
1414
|
overscroll-behavior: contain;
|
|
1412
1415
|
border: 0;
|
|
@@ -1416,7 +1419,7 @@ function renderArtifactViewerShellCss() {
|
|
|
1416
1419
|
box-shadow: 0 18px 52px rgba(0, 0, 0, 0.34);
|
|
1417
1420
|
}
|
|
1418
1421
|
.viewer-viewport[data-mobile="true"] {
|
|
1419
|
-
width: var(--config-viewport-width);
|
|
1422
|
+
width: min(var(--config-viewport-width), 100%);
|
|
1420
1423
|
}
|
|
1421
1424
|
.dom-viewport {
|
|
1422
1425
|
overflow: hidden;
|
|
@@ -1455,8 +1458,8 @@ function renderArtifactViewerShellCss() {
|
|
|
1455
1458
|
padding: 0;
|
|
1456
1459
|
}
|
|
1457
1460
|
.viewer-viewport {
|
|
1458
|
-
width: var(--config-viewport-width);
|
|
1459
|
-
height: var(--config-viewport-height);
|
|
1461
|
+
width: min(var(--config-viewport-width), 100%);
|
|
1462
|
+
height: min(var(--config-viewport-height), 100%);
|
|
1460
1463
|
border-radius: 0;
|
|
1461
1464
|
}
|
|
1462
1465
|
}`;
|
|
@@ -1511,22 +1514,19 @@ function renderConfiguredViewportStyle(viewport) {
|
|
|
1511
1514
|
return `--config-viewport-width: ${viewport.width}px; --config-viewport-height: ${viewport.height}px;`;
|
|
1512
1515
|
}
|
|
1513
1516
|
//#endregion
|
|
1514
|
-
//#region src/agent/
|
|
1515
|
-
function
|
|
1516
|
-
return
|
|
1517
|
+
//#region src/agent/report_launch_args.ts
|
|
1518
|
+
function readReportLaunchArgSets(result) {
|
|
1519
|
+
return [readFlowLaunchArgs(result.flowPath), readCassetteLaunchArgs(result.replaySourceCassettePath ?? result.cassettePath)];
|
|
1517
1520
|
}
|
|
1518
|
-
function
|
|
1519
|
-
const
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
screenMode: screenModeArg && screenModeArg !== "termvision" ? "plain" : "termvision",
|
|
1528
|
-
theme: themeArg === "light" ? "light" : "dark"
|
|
1529
|
-
};
|
|
1521
|
+
function readFlagValueFromArgSets(argSets, flag) {
|
|
1522
|
+
for (const args of argSets) {
|
|
1523
|
+
const value = readFlagValue(args, flag);
|
|
1524
|
+
if (value !== void 0) return value;
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
function readFlagValue(args, flag) {
|
|
1528
|
+
const index = args.indexOf(flag);
|
|
1529
|
+
return index >= 0 ? args[index + 1] : void 0;
|
|
1530
1530
|
}
|
|
1531
1531
|
function readCassetteLaunchArgs(cassettePath) {
|
|
1532
1532
|
try {
|
|
@@ -1545,21 +1545,41 @@ function readFlowLaunchArgs(flowPath) {
|
|
|
1545
1545
|
function normalizeStringArray(value) {
|
|
1546
1546
|
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
1547
1547
|
}
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
}
|
|
1548
|
+
//#endregion
|
|
1549
|
+
//#region src/agent/report_view_options.ts
|
|
1550
|
+
function isMobileViewport(viewport) {
|
|
1551
|
+
return Boolean(viewport?.isMobile || viewport?.hasTouch || (viewport?.width ?? 9999) <= 720);
|
|
1553
1552
|
}
|
|
1554
|
-
function
|
|
1555
|
-
const
|
|
1556
|
-
|
|
1553
|
+
function resolveReportViewOptions(result, config) {
|
|
1554
|
+
const launchArgSets = readReportLaunchArgSets(result);
|
|
1555
|
+
const ptyReplayArg = readFlagValueFromArgSets(launchArgSets, "--pty-replay");
|
|
1556
|
+
const screenModeArg = readFlagValueFromArgSets(launchArgSets, "--experimental-screen-mode");
|
|
1557
|
+
const themeArg = readFlagValueFromArgSets(launchArgSets, "--theme");
|
|
1558
|
+
const fontSizeArg = readFlagValueFromArgSets(launchArgSets, "--font-size");
|
|
1559
|
+
const lineHeightArg = readFlagValueFromArgSets(launchArgSets, "--line-height");
|
|
1560
|
+
const stableFrameConfig = resolveStableFrameConfig$1(config, result.name);
|
|
1561
|
+
const themeOverride = ptyReplayArg && stableFrameConfig.enabled !== false && !stableFrameConfig.skip ? stableFrameConfig.theme : void 0;
|
|
1562
|
+
return {
|
|
1563
|
+
fontSize: parsePositiveNumber(fontSizeArg) ?? 15,
|
|
1564
|
+
lineHeight: parsePositiveNumber(lineHeightArg) ?? 1.6,
|
|
1565
|
+
screenMode: screenModeArg && screenModeArg !== "termvision" ? "plain" : "termvision",
|
|
1566
|
+
theme: themeOverride ?? (themeArg === "light" ? "light" : "dark")
|
|
1567
|
+
};
|
|
1557
1568
|
}
|
|
1558
1569
|
function parsePositiveNumber(value) {
|
|
1559
1570
|
if (value === void 0) return void 0;
|
|
1560
1571
|
const parsed = Number(value);
|
|
1561
1572
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
1562
1573
|
}
|
|
1574
|
+
function resolveStableFrameConfig$1(config, flowName) {
|
|
1575
|
+
const stableFrames = config?.agent?.report?.stableFrames;
|
|
1576
|
+
const flowConfig = stableFrames?.flows?.[flowName];
|
|
1577
|
+
return {
|
|
1578
|
+
enabled: flowConfig?.enabled ?? stableFrames?.enabled,
|
|
1579
|
+
skip: flowConfig?.skip ?? stableFrames?.skip,
|
|
1580
|
+
theme: flowConfig?.theme ?? stableFrames?.theme ?? "dark"
|
|
1581
|
+
};
|
|
1582
|
+
}
|
|
1563
1583
|
//#endregion
|
|
1564
1584
|
//#region src/agent/report_artifact_viewer.ts
|
|
1565
1585
|
function renderArtifactViewerHtml(args) {
|
|
@@ -1584,6 +1604,358 @@ function renderArtifactViewerHtml(args) {
|
|
|
1584
1604
|
});
|
|
1585
1605
|
}
|
|
1586
1606
|
//#endregion
|
|
1607
|
+
//#region src/agent/report_pty_stable_frame.ts
|
|
1608
|
+
async function extractPtyReplayStableFrameForReport(args) {
|
|
1609
|
+
const replayPathArg = readFlagValueFromArgSets(readReportLaunchArgSets(args.result), "--pty-replay");
|
|
1610
|
+
if (!replayPathArg) return null;
|
|
1611
|
+
const config = resolveStableFrameConfig(args.config, args.result.name);
|
|
1612
|
+
if (config.enabled === false || config.skip) return null;
|
|
1613
|
+
const replayPath = resolvePtyReplayPath(replayPathArg, args.config);
|
|
1614
|
+
if (!existsSync(replayPath)) return null;
|
|
1615
|
+
const recording = JSON.parse(readFileSync(replayPath, "utf8"));
|
|
1616
|
+
const events = Array.isArray(recording.events) ? recording.events : [];
|
|
1617
|
+
const firstResize = events.find((event) => event.type === "resize");
|
|
1618
|
+
const terminal = new Terminal({
|
|
1619
|
+
allowProposedApi: true,
|
|
1620
|
+
cols: config.cols ?? recording.terminal?.cols ?? recording.command?.cols ?? recording.cols ?? firstResize?.cols ?? 80,
|
|
1621
|
+
convertEol: true,
|
|
1622
|
+
rows: config.rows ?? recording.terminal?.rows ?? recording.command?.rows ?? recording.rows ?? firstResize?.rows ?? 24,
|
|
1623
|
+
scrollback: 2e4
|
|
1624
|
+
});
|
|
1625
|
+
try {
|
|
1626
|
+
return await extractStableFrame({
|
|
1627
|
+
config,
|
|
1628
|
+
events,
|
|
1629
|
+
terminal
|
|
1630
|
+
});
|
|
1631
|
+
} finally {
|
|
1632
|
+
terminal.dispose();
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
function renderPtyReplayStableFramePreviewDocument(args) {
|
|
1636
|
+
const targetCols = resolveTargetCols({
|
|
1637
|
+
config: resolveStableFrameConfig(args.config, args.flowName),
|
|
1638
|
+
fontSize: args.viewOptions.fontSize,
|
|
1639
|
+
frameCols: args.frame.cols,
|
|
1640
|
+
viewport: args.viewport
|
|
1641
|
+
});
|
|
1642
|
+
const body = renderAittyPreviewBody({
|
|
1643
|
+
snapshot: renderStableFrameDom(args.frame, targetCols),
|
|
1644
|
+
snapshotLayout: {
|
|
1645
|
+
cols: targetCols,
|
|
1646
|
+
fontSize: args.viewOptions.fontSize,
|
|
1647
|
+
lineHeight: args.viewOptions.lineHeight,
|
|
1648
|
+
paddingInline: isMobileViewport(args.viewport) ? 16 : 32,
|
|
1649
|
+
rows: args.frame.rows
|
|
1650
|
+
},
|
|
1651
|
+
viewOptions: args.viewOptions
|
|
1652
|
+
});
|
|
1653
|
+
const style = renderAittyPreviewCss(args.viewOptions);
|
|
1654
|
+
const assetTags = renderAittyPreviewAssetTags(args.aittyAssets);
|
|
1655
|
+
return `<!doctype html>
|
|
1656
|
+
<html lang="en" data-theme="${escapeAttribute(args.viewOptions.theme)}">
|
|
1657
|
+
<head>
|
|
1658
|
+
<meta charset="utf-8" />
|
|
1659
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
|
1660
|
+
<title>stable-frame preview (atMs=${args.frame.atMs})</title>
|
|
1661
|
+
${assetTags} <style>
|
|
1662
|
+
${style}
|
|
1663
|
+
</style>
|
|
1664
|
+
</head>
|
|
1665
|
+
<body>
|
|
1666
|
+
${body}
|
|
1667
|
+
</body>
|
|
1668
|
+
</html>`;
|
|
1669
|
+
}
|
|
1670
|
+
function resolveStableFrameConfig(config, flowName) {
|
|
1671
|
+
const stableFrames = config?.agent?.report?.stableFrames;
|
|
1672
|
+
const flowConfig = stableFrames?.flows?.[flowName];
|
|
1673
|
+
return {
|
|
1674
|
+
...stableFrames,
|
|
1675
|
+
...flowConfig,
|
|
1676
|
+
stableMs: flowConfig?.stableMs ?? stableFrames?.stableMs ?? 200,
|
|
1677
|
+
theme: flowConfig?.theme ?? stableFrames?.theme ?? "dark",
|
|
1678
|
+
viewportOnly: flowConfig?.viewportOnly ?? stableFrames?.viewportOnly ?? false,
|
|
1679
|
+
viewportTargets: {
|
|
1680
|
+
...stableFrames?.viewportTargets,
|
|
1681
|
+
...flowConfig?.viewportTargets
|
|
1682
|
+
}
|
|
1683
|
+
};
|
|
1684
|
+
}
|
|
1685
|
+
function resolvePtyReplayPath(replayPathArg, config) {
|
|
1686
|
+
if (isAbsolute(replayPathArg)) return replayPathArg;
|
|
1687
|
+
return resolve(config?.rootDir ?? process.cwd(), replayPathArg);
|
|
1688
|
+
}
|
|
1689
|
+
async function extractStableFrame(args) {
|
|
1690
|
+
const { config, events, terminal } = args;
|
|
1691
|
+
const targetFrameIndex = config.frameIndex;
|
|
1692
|
+
const matcher = createStableFrameMatcher(config);
|
|
1693
|
+
let matchedFrame = null;
|
|
1694
|
+
const retainedFrames = [];
|
|
1695
|
+
const retainCount = targetFrameIndex === void 0 ? 24 : targetFrameIndex < 0 ? -targetFrameIndex : 1;
|
|
1696
|
+
let totalFrames = 0;
|
|
1697
|
+
let pendingDirtySinceMs = null;
|
|
1698
|
+
let lastEventAtMs = 0;
|
|
1699
|
+
const captureFrame = (atMs, reason) => {
|
|
1700
|
+
const shouldRetain = targetFrameIndex === void 0 || targetFrameIndex >= 0 && totalFrames === targetFrameIndex || targetFrameIndex < 0;
|
|
1701
|
+
if (shouldRetain || matcher) {
|
|
1702
|
+
const frame = {
|
|
1703
|
+
...snapshotTerminalFrame(terminal, {
|
|
1704
|
+
atMs,
|
|
1705
|
+
index: totalFrames,
|
|
1706
|
+
reason,
|
|
1707
|
+
viewportOnly: config.viewportOnly
|
|
1708
|
+
}),
|
|
1709
|
+
score: scoreTerminalFrame(terminal)
|
|
1710
|
+
};
|
|
1711
|
+
if (matcher?.matches(stableFrameText(frame))) {
|
|
1712
|
+
if (matcher.mode === "last" || !matchedFrame) matchedFrame = frame;
|
|
1713
|
+
}
|
|
1714
|
+
if (shouldRetain) retainedFrames.push(frame);
|
|
1715
|
+
if (retainedFrames.length > retainCount) retainedFrames.splice(0, retainedFrames.length - retainCount);
|
|
1716
|
+
}
|
|
1717
|
+
totalFrames += 1;
|
|
1718
|
+
pendingDirtySinceMs = null;
|
|
1719
|
+
};
|
|
1720
|
+
const flushIfStable = (nowMs) => {
|
|
1721
|
+
if (pendingDirtySinceMs === null) return;
|
|
1722
|
+
if (nowMs - pendingDirtySinceMs >= config.stableMs) captureFrame(pendingDirtySinceMs, "stable");
|
|
1723
|
+
};
|
|
1724
|
+
for (const event of events) {
|
|
1725
|
+
const atMs = event.atMs ?? lastEventAtMs;
|
|
1726
|
+
flushIfStable(atMs);
|
|
1727
|
+
lastEventAtMs = atMs;
|
|
1728
|
+
if (event.type === "output" && event.dataBase64) {
|
|
1729
|
+
await writeTerminal(terminal, base64ToBytes(event.dataBase64));
|
|
1730
|
+
pendingDirtySinceMs = pendingDirtySinceMs ?? atMs;
|
|
1731
|
+
continue;
|
|
1732
|
+
}
|
|
1733
|
+
if (event.type === "resize" && event.cols && event.rows) {
|
|
1734
|
+
terminal.resize(event.cols, event.rows);
|
|
1735
|
+
pendingDirtySinceMs = pendingDirtySinceMs ?? atMs;
|
|
1736
|
+
continue;
|
|
1737
|
+
}
|
|
1738
|
+
if (event.type === "exit") flushIfStable(atMs);
|
|
1739
|
+
}
|
|
1740
|
+
flushIfStable(lastEventAtMs + config.stableMs);
|
|
1741
|
+
if (totalFrames === 0) captureFrame(lastEventAtMs, "final");
|
|
1742
|
+
if (targetFrameIndex !== void 0 && targetFrameIndex >= 0) {
|
|
1743
|
+
const exact = retainedFrames.find((frame) => frame.index === targetFrameIndex);
|
|
1744
|
+
if (exact) return exact;
|
|
1745
|
+
return null;
|
|
1746
|
+
}
|
|
1747
|
+
if (targetFrameIndex !== void 0 && targetFrameIndex < 0) {
|
|
1748
|
+
const resolved = totalFrames + targetFrameIndex;
|
|
1749
|
+
const exact = retainedFrames.find((frame) => frame.index === resolved);
|
|
1750
|
+
if (exact) return exact;
|
|
1751
|
+
}
|
|
1752
|
+
if (matchedFrame) return matchedFrame;
|
|
1753
|
+
return chooseBestStableFrame(retainedFrames);
|
|
1754
|
+
}
|
|
1755
|
+
function writeTerminal(terminal, data) {
|
|
1756
|
+
return new Promise((resolveWrite) => {
|
|
1757
|
+
terminal.write(data, resolveWrite);
|
|
1758
|
+
});
|
|
1759
|
+
}
|
|
1760
|
+
function snapshotTerminalFrame(terminal, options) {
|
|
1761
|
+
const buffer = terminal.buffer.active;
|
|
1762
|
+
const startY = options.viewportOnly ? buffer.viewportY : 0;
|
|
1763
|
+
const count = options.viewportOnly ? terminal.rows : buffer.length;
|
|
1764
|
+
const logicalLines = [];
|
|
1765
|
+
for (let offset = 0; offset < count; offset += 1) {
|
|
1766
|
+
const y = startY + offset;
|
|
1767
|
+
const line = buffer.getLine(y);
|
|
1768
|
+
const cells = readStableLineCells(terminal, y);
|
|
1769
|
+
const live = options.viewportOnly || y >= buffer.viewportY;
|
|
1770
|
+
const previous = logicalLines.at(-1);
|
|
1771
|
+
if (line?.isWrapped && previous) {
|
|
1772
|
+
previous.cells.push(...cells);
|
|
1773
|
+
previous.live = previous.live || live;
|
|
1774
|
+
previous.physicalRows += 1;
|
|
1775
|
+
continue;
|
|
1776
|
+
}
|
|
1777
|
+
logicalLines.push({
|
|
1778
|
+
cells,
|
|
1779
|
+
live,
|
|
1780
|
+
physicalRows: 1
|
|
1781
|
+
});
|
|
1782
|
+
}
|
|
1783
|
+
return {
|
|
1784
|
+
atMs: options.atMs,
|
|
1785
|
+
cols: terminal.cols,
|
|
1786
|
+
index: options.index,
|
|
1787
|
+
lines: logicalLines,
|
|
1788
|
+
reason: options.reason,
|
|
1789
|
+
rows: terminal.rows
|
|
1790
|
+
};
|
|
1791
|
+
}
|
|
1792
|
+
function readStableLineCells(terminal, y) {
|
|
1793
|
+
const buffer = terminal.buffer.active;
|
|
1794
|
+
const nullCell = buffer.getNullCell();
|
|
1795
|
+
const line = buffer.getLine(y);
|
|
1796
|
+
const endCol = findMeaningfulEndCol(line, terminal.cols, nullCell);
|
|
1797
|
+
const cells = [];
|
|
1798
|
+
for (let x = 0; x < endCol; x += 1) {
|
|
1799
|
+
const cell = line?.getCell(x, nullCell);
|
|
1800
|
+
if (!cell) {
|
|
1801
|
+
cells.push({
|
|
1802
|
+
style: DEFAULT_STYLE,
|
|
1803
|
+
text: " ",
|
|
1804
|
+
width: 1
|
|
1805
|
+
});
|
|
1806
|
+
continue;
|
|
1807
|
+
}
|
|
1808
|
+
const width = cell.getWidth();
|
|
1809
|
+
if (width === 0) continue;
|
|
1810
|
+
cells.push({
|
|
1811
|
+
style: extractStyle(cell),
|
|
1812
|
+
text: cell.getChars() || " ",
|
|
1813
|
+
width
|
|
1814
|
+
});
|
|
1815
|
+
}
|
|
1816
|
+
return cells;
|
|
1817
|
+
}
|
|
1818
|
+
function scoreTerminalFrame(terminal) {
|
|
1819
|
+
const buffer = terminal.buffer.active;
|
|
1820
|
+
const nullCell = buffer.getNullCell();
|
|
1821
|
+
let score = 0;
|
|
1822
|
+
for (let y = 0; y < buffer.length; y += 1) {
|
|
1823
|
+
const endCol = findMeaningfulEndCol(buffer.getLine(y), terminal.cols, nullCell);
|
|
1824
|
+
score += endCol;
|
|
1825
|
+
}
|
|
1826
|
+
return score;
|
|
1827
|
+
}
|
|
1828
|
+
function chooseBestStableFrame(frames) {
|
|
1829
|
+
return frames.filter((frame) => frame.score > 0).at(-1) ?? frames.at(-1) ?? null;
|
|
1830
|
+
}
|
|
1831
|
+
function createStableFrameMatcher(config) {
|
|
1832
|
+
const matchText = toStringArray(config.matchText);
|
|
1833
|
+
const matchRegex = toStringArray(config.matchRegex).map((pattern) => {
|
|
1834
|
+
try {
|
|
1835
|
+
return new RegExp(pattern);
|
|
1836
|
+
} catch (error) {
|
|
1837
|
+
throw new Error(`invalid agent.report.stableFrames.matchRegex pattern ${JSON.stringify(pattern)}: ${String(error)}`);
|
|
1838
|
+
}
|
|
1839
|
+
});
|
|
1840
|
+
if (matchText.length === 0 && matchRegex.length === 0) return null;
|
|
1841
|
+
return {
|
|
1842
|
+
mode: config.matchMode ?? "last",
|
|
1843
|
+
matches: (text) => matchText.some((needle) => text.includes(needle)) || matchRegex.some((regex) => regex.test(text))
|
|
1844
|
+
};
|
|
1845
|
+
}
|
|
1846
|
+
function stableFrameText(frame) {
|
|
1847
|
+
return frame.lines.map((line) => line.cells.map((cell) => cell.text).join("").trimEnd()).join("\n");
|
|
1848
|
+
}
|
|
1849
|
+
function toStringArray(value) {
|
|
1850
|
+
if (value === void 0) return [];
|
|
1851
|
+
return Array.isArray(value) ? value : [value];
|
|
1852
|
+
}
|
|
1853
|
+
function resolveTargetCols(args) {
|
|
1854
|
+
const explicit = args.viewport ? args.config.viewportTargets?.[args.viewport.name] : void 0;
|
|
1855
|
+
if (typeof explicit === "number" && Number.isFinite(explicit) && explicit > 0) return Math.trunc(explicit);
|
|
1856
|
+
if (explicit === null) return args.frameCols;
|
|
1857
|
+
if (isMobileViewport(args.viewport)) {
|
|
1858
|
+
const width = args.viewport?.width ?? 390;
|
|
1859
|
+
const cellWidth = Math.max(1, args.fontSize * .6);
|
|
1860
|
+
return Math.max(20, Math.floor(width / cellWidth));
|
|
1861
|
+
}
|
|
1862
|
+
return args.frameCols;
|
|
1863
|
+
}
|
|
1864
|
+
function renderStableFrameDom(frame, targetCols) {
|
|
1865
|
+
let html = "";
|
|
1866
|
+
let totalRows = 0;
|
|
1867
|
+
let wideBlockId = 0;
|
|
1868
|
+
for (const line of frame.lines) {
|
|
1869
|
+
const lineCols = Math.max(targetCols, cellsDisplayWidth(line.cells));
|
|
1870
|
+
if (lineCols > targetCols || line.physicalRows > 1) {
|
|
1871
|
+
wideBlockId += 1;
|
|
1872
|
+
html += `<div class="term-wide-row-block" data-aitty-wide-block="true" data-aitty-wide-block-id="${wideBlockId}" data-aitty-wide-block-kind="viewport-pan" style="--aitty-wide-block-cols: ${lineCols}">`;
|
|
1873
|
+
html += renderStableFrameRow(line, lineCols, totalRows);
|
|
1874
|
+
html += "</div>";
|
|
1875
|
+
} else html += renderStableFrameRow(line, targetCols, totalRows);
|
|
1876
|
+
totalRows += 1;
|
|
1877
|
+
}
|
|
1878
|
+
return `<div class="term-grid" data-cols="${targetCols}" data-rows="${totalRows}" style="--term-cols: ${targetCols}; --term-rows: ${totalRows};">${html}</div>`;
|
|
1879
|
+
}
|
|
1880
|
+
function renderStableFrameRow(line, lineCols, lineIndex) {
|
|
1881
|
+
return `<div class="${line.live ? "term-row" : "term-row term-scrollback-row"}"${line.live ? ` data-aitty-live-grid-row="${lineIndex + 1}"` : ""} data-aitty-line-cols="${lineCols}">${renderStableFrameCells(line.cells, lineCols)}</div>`;
|
|
1882
|
+
}
|
|
1883
|
+
function renderStableFrameCells(cells, lineCols) {
|
|
1884
|
+
const out = [];
|
|
1885
|
+
let usedCols = 0;
|
|
1886
|
+
let runText = "";
|
|
1887
|
+
let runWidth = 0;
|
|
1888
|
+
let runStyle = null;
|
|
1889
|
+
let runKey = null;
|
|
1890
|
+
const flush = () => {
|
|
1891
|
+
if (runText === "" && runWidth === 0) return;
|
|
1892
|
+
out.push(renderSpan(runText, runWidth, runStyle ?? DEFAULT_STYLE));
|
|
1893
|
+
runText = "";
|
|
1894
|
+
runWidth = 0;
|
|
1895
|
+
runStyle = null;
|
|
1896
|
+
runKey = null;
|
|
1897
|
+
};
|
|
1898
|
+
for (const cell of cells) {
|
|
1899
|
+
const key = styleKey(cell.style);
|
|
1900
|
+
const wide = cell.width !== 1;
|
|
1901
|
+
if (!wide && runKey === key) {
|
|
1902
|
+
runText += cell.text;
|
|
1903
|
+
runWidth += cell.width;
|
|
1904
|
+
usedCols += cell.width;
|
|
1905
|
+
continue;
|
|
1906
|
+
}
|
|
1907
|
+
flush();
|
|
1908
|
+
if (wide) {
|
|
1909
|
+
out.push(renderSpan(cell.text, cell.width, cell.style, "term-wide"));
|
|
1910
|
+
usedCols += cell.width;
|
|
1911
|
+
continue;
|
|
1912
|
+
}
|
|
1913
|
+
runText = cell.text;
|
|
1914
|
+
runWidth = cell.width;
|
|
1915
|
+
runStyle = cell.style;
|
|
1916
|
+
runKey = key;
|
|
1917
|
+
usedCols += cell.width;
|
|
1918
|
+
}
|
|
1919
|
+
flush();
|
|
1920
|
+
const remaining = lineCols - usedCols;
|
|
1921
|
+
if (remaining > 0) out.push(renderSpan("", remaining, DEFAULT_STYLE));
|
|
1922
|
+
return out.join("");
|
|
1923
|
+
}
|
|
1924
|
+
function renderSpan(text, width, style, className) {
|
|
1925
|
+
const declarations = styleDeclarations(style);
|
|
1926
|
+
declarations.push(widthDeclaration(width));
|
|
1927
|
+
if (className === "term-wide") declarations.push("overflow: hidden");
|
|
1928
|
+
return `<span${className ? ` class="${escapeAttribute(className)}"` : ""} style="${escapeAttribute(declarations.join("; "))}">${escapeHtml(text)}</span>`;
|
|
1929
|
+
}
|
|
1930
|
+
function styleDeclarations(style) {
|
|
1931
|
+
if (isDefaultStyle(style)) return [];
|
|
1932
|
+
const declarations = [];
|
|
1933
|
+
const fg = colorToCss(style.fg);
|
|
1934
|
+
const bg = colorToCss(style.bg);
|
|
1935
|
+
if (fg) declarations.push(`color: ${fg}`);
|
|
1936
|
+
if (bg) declarations.push(`background-color: ${bg}`);
|
|
1937
|
+
if (style.bold) declarations.push("font-weight: 700");
|
|
1938
|
+
if (style.dim) declarations.push("opacity: 0.72");
|
|
1939
|
+
if (style.italic) declarations.push("font-style: italic");
|
|
1940
|
+
const decorations = [style.underline ? "underline" : "", style.strikethrough ? "line-through" : ""].filter(Boolean);
|
|
1941
|
+
if (decorations.length > 0) declarations.push(`text-decoration: ${decorations.join(" ")}`);
|
|
1942
|
+
if (style.inverse) declarations.push("filter: invert(1)");
|
|
1943
|
+
return declarations;
|
|
1944
|
+
}
|
|
1945
|
+
function colorToCss(color) {
|
|
1946
|
+
if (color.mode === "default") return null;
|
|
1947
|
+
if (color.mode === "palette") return `var(--term-color-${color.value})`;
|
|
1948
|
+
const value = color.value;
|
|
1949
|
+
return `rgb(${value >> 16 & 255},${value >> 8 & 255},${value & 255})`;
|
|
1950
|
+
}
|
|
1951
|
+
function widthDeclaration(width) {
|
|
1952
|
+
if (width <= 1) return "width: var(--term-cell-width, 1ch)";
|
|
1953
|
+
return `width: calc(var(--term-cell-width, 1ch) * ${width})`;
|
|
1954
|
+
}
|
|
1955
|
+
function cellsDisplayWidth(cells) {
|
|
1956
|
+
return cells.reduce((sum, cell) => sum + cell.width, 0);
|
|
1957
|
+
}
|
|
1958
|
+
//#endregion
|
|
1587
1959
|
//#region src/agent/report_terminal_layout.ts
|
|
1588
1960
|
function resolveTerminalSnapshotLayout(snapshot, viewport, viewOptions) {
|
|
1589
1961
|
const cols = inferTerminalCols(snapshot);
|
|
@@ -1635,9 +2007,9 @@ ${body}
|
|
|
1635
2007
|
}
|
|
1636
2008
|
//#endregion
|
|
1637
2009
|
//#region src/agent/report_artifact_writer.ts
|
|
1638
|
-
function writeArtifactViewerPages(result) {
|
|
2010
|
+
async function writeArtifactViewerPages(result, options = {}) {
|
|
1639
2011
|
const viewportsByName = new Map(result.viewports.map((viewport) => [viewport.name, viewport]));
|
|
1640
|
-
const viewOptions = resolveReportViewOptions(result);
|
|
2012
|
+
const viewOptions = resolveReportViewOptions(result, options.config);
|
|
1641
2013
|
const readableArtifacts = [];
|
|
1642
2014
|
for (const artifact of result.artifacts) {
|
|
1643
2015
|
const viewerPath = artifactViewerPath(artifact);
|
|
@@ -1657,12 +2029,25 @@ function writeArtifactViewerPages(result) {
|
|
|
1657
2029
|
reportPath: result.reportPath
|
|
1658
2030
|
}) : null;
|
|
1659
2031
|
const writtenDomPreviewPaths = /* @__PURE__ */ new Set();
|
|
2032
|
+
const ptyReplayStableFrame = aittyAssets ? await extractPtyReplayStableFrameForReport({
|
|
2033
|
+
config: options.config,
|
|
2034
|
+
result
|
|
2035
|
+
}) : null;
|
|
1660
2036
|
if (aittyAssets) for (const { artifact, content } of readableArtifacts) {
|
|
1661
2037
|
if (artifact.kind !== "dom") continue;
|
|
1662
2038
|
const viewport = viewportsByName.get(artifact.viewport);
|
|
1663
2039
|
const domPreviewPath = artifactDomPreviewPath(artifact);
|
|
2040
|
+
const aittyPreviewAssets = resolveAittyPreviewAssets(domPreviewPath, aittyAssets, result.artifactsDir);
|
|
2041
|
+
const previewDocument = ptyReplayStableFrame ? renderPtyReplayStableFramePreviewDocument({
|
|
2042
|
+
aittyAssets: aittyPreviewAssets,
|
|
2043
|
+
config: options.config,
|
|
2044
|
+
flowName: result.name,
|
|
2045
|
+
frame: ptyReplayStableFrame,
|
|
2046
|
+
viewOptions,
|
|
2047
|
+
viewport
|
|
2048
|
+
}) : renderDomPreviewDocument(content, viewport, viewOptions, aittyPreviewAssets);
|
|
1664
2049
|
mkdirSync(dirname(domPreviewPath), { recursive: true });
|
|
1665
|
-
writeFileSync(domPreviewPath,
|
|
2050
|
+
writeFileSync(domPreviewPath, previewDocument, "utf8");
|
|
1666
2051
|
writtenDomPreviewPaths.add(domPreviewPath);
|
|
1667
2052
|
}
|
|
1668
2053
|
for (const { artifact, content, viewerPath } of readableArtifacts) {
|
|
@@ -2045,9 +2430,9 @@ ${renderAgentReportCss()}
|
|
|
2045
2430
|
}
|
|
2046
2431
|
//#endregion
|
|
2047
2432
|
//#region src/agent/report.ts
|
|
2048
|
-
function writeAgentReport(path, result) {
|
|
2433
|
+
async function writeAgentReport(path, result, options = {}) {
|
|
2049
2434
|
mkdirSync(dirname(path), { recursive: true });
|
|
2050
|
-
writeArtifactViewerPages(result);
|
|
2435
|
+
await writeArtifactViewerPages(result, options);
|
|
2051
2436
|
writeFileSync(path, renderAgentReportHtml(result), "utf8");
|
|
2052
2437
|
}
|
|
2053
2438
|
//#endregion
|
|
@@ -2797,7 +3182,7 @@ async function runAgentSpec(input, options = {}) {
|
|
|
2797
3182
|
else writeFileSync(cassettePath, JSON.stringify(cassette, null, 2) + "\n", "utf8");
|
|
2798
3183
|
result.cassetteFrameCount = cassette.frames.length;
|
|
2799
3184
|
writeRunRecord(result, spec);
|
|
2800
|
-
writeAgentReport(reportPath, result);
|
|
3185
|
+
await writeAgentReport(reportPath, result, { config: options.config });
|
|
2801
3186
|
writeRunManifest(result);
|
|
2802
3187
|
}
|
|
2803
3188
|
return result;
|
package/dist/script.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as runScriptFile, t as runScript } from "./runner-
|
|
1
|
+
import { n as runScriptFile, t as runScript } from "./runner-BHXXwxYp.mjs";
|
|
2
2
|
export { runScript, runScriptFile };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as sameArgv, i as diffCommandMaps, n as validateManifestFiles, r as formatZodIssues, t as collectManifestFiles } from "./manifest_files-DW80c1H7.mjs";
|
|
2
2
|
import { i as portableCliPath, o as relativeHref, r as normalizePath, s as samePath } from "./env-DPYHo-zH.mjs";
|
|
3
|
-
import { a as jsonForHtml, c as scriptSchema, i as escapeHtml, l as SessionManager, o as ensureAsciinemaPlayerAssets, r as generateTraceReportHtml, s as formatSnapshotView, t as runScript } from "./runner-
|
|
3
|
+
import { a as jsonForHtml, c as scriptSchema, i as escapeHtml, l as SessionManager, o as ensureAsciinemaPlayerAssets, r as generateTraceReportHtml, s as formatSnapshotView, t as runScript } from "./runner-BHXXwxYp.mjs";
|
|
4
4
|
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { basename, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
|
|
6
6
|
import { pathToFileURL } from "node:url";
|
|
@@ -144,7 +144,7 @@ var ScriptRecordingManager = class {
|
|
|
144
144
|
};
|
|
145
145
|
//#endregion
|
|
146
146
|
//#region package.json
|
|
147
|
-
var version = "0.
|
|
147
|
+
var version = "0.6.0";
|
|
148
148
|
//#endregion
|
|
149
149
|
//#region src/mcp/tool_result.ts
|
|
150
150
|
function toolError(message, extra = {}) {
|
package/dist/session.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as TerminalSession } from "./terminal_session-
|
|
1
|
+
import { t as TerminalSession } from "./terminal_session-MX_vWpRG.mjs";
|
|
2
2
|
export { TerminalSession };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
//#region src/terminal/style.ts
|
|
2
|
+
const DEFAULT_STYLE = {
|
|
3
|
+
fg: { mode: "default" },
|
|
4
|
+
bg: { mode: "default" },
|
|
5
|
+
bold: false,
|
|
6
|
+
dim: false,
|
|
7
|
+
italic: false,
|
|
8
|
+
underline: false,
|
|
9
|
+
inverse: false,
|
|
10
|
+
strikethrough: false
|
|
11
|
+
};
|
|
12
|
+
function extractStyle(cell) {
|
|
13
|
+
const style = {
|
|
14
|
+
fg: extractColor(cell.isFgDefault(), cell.isFgPalette(), cell.isFgRGB(), cell.getFgColor()),
|
|
15
|
+
bg: extractColor(cell.isBgDefault(), cell.isBgPalette(), cell.isBgRGB(), cell.getBgColor()),
|
|
16
|
+
bold: cell.isBold() !== 0,
|
|
17
|
+
dim: cell.isDim() !== 0,
|
|
18
|
+
italic: cell.isItalic() !== 0,
|
|
19
|
+
underline: cell.isUnderline() !== 0,
|
|
20
|
+
inverse: cell.isInverse() !== 0,
|
|
21
|
+
strikethrough: cell.isStrikethrough() !== 0
|
|
22
|
+
};
|
|
23
|
+
return isDefaultStyle(style) ? DEFAULT_STYLE : style;
|
|
24
|
+
}
|
|
25
|
+
function isDefaultStyle(style) {
|
|
26
|
+
return style.fg.mode === "default" && style.bg.mode === "default" && !style.bold && !style.dim && !style.italic && !style.underline && !style.inverse && !style.strikethrough;
|
|
27
|
+
}
|
|
28
|
+
function styleKey(style) {
|
|
29
|
+
return [
|
|
30
|
+
style.fg.mode === "default" ? "d" : `${style.fg.mode}:${style.fg.value}`,
|
|
31
|
+
style.bg.mode === "default" ? "d" : `${style.bg.mode}:${style.bg.value}`,
|
|
32
|
+
style.bold ? "b" : "",
|
|
33
|
+
style.dim ? "d" : "",
|
|
34
|
+
style.italic ? "i" : "",
|
|
35
|
+
style.underline ? "u" : "",
|
|
36
|
+
style.inverse ? "r" : "",
|
|
37
|
+
style.strikethrough ? "s" : ""
|
|
38
|
+
].join("|");
|
|
39
|
+
}
|
|
40
|
+
function findMeaningfulEndCol(line, cols, nullCell) {
|
|
41
|
+
if (!line) return 0;
|
|
42
|
+
for (let x = cols - 1; x >= 0; x -= 1) {
|
|
43
|
+
const cell = line.getCell(x, nullCell);
|
|
44
|
+
if (!cell) continue;
|
|
45
|
+
if (cell.getWidth() === 0) continue;
|
|
46
|
+
const chars = cell.getChars();
|
|
47
|
+
const style = extractStyle(cell);
|
|
48
|
+
if (chars !== "" && chars !== " " || !isDefaultStyle(style)) return x + 1;
|
|
49
|
+
}
|
|
50
|
+
return 0;
|
|
51
|
+
}
|
|
52
|
+
function extractColor(isDefault, isPalette, isRgb, value) {
|
|
53
|
+
if (isDefault) return { mode: "default" };
|
|
54
|
+
if (isRgb) return {
|
|
55
|
+
mode: "rgb",
|
|
56
|
+
value
|
|
57
|
+
};
|
|
58
|
+
if (isPalette) return {
|
|
59
|
+
mode: "palette",
|
|
60
|
+
value
|
|
61
|
+
};
|
|
62
|
+
return { mode: "default" };
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
export { styleKey as a, isDefaultStyle as i, extractStyle as n, findMeaningfulEndCol as r, DEFAULT_STYLE as t };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { a as styleKey, i as isDefaultStyle, n as extractStyle, r as findMeaningfulEndCol, t as DEFAULT_STYLE } from "./style-BtIUv5H0.mjs";
|
|
1
2
|
import { Terminal } from "@xterm/headless";
|
|
2
3
|
//#region src/terminal/keys.ts
|
|
3
4
|
const CSI = "\x1B[";
|
|
@@ -180,70 +181,6 @@ function clampInt(value, min, max) {
|
|
|
180
181
|
return int;
|
|
181
182
|
}
|
|
182
183
|
//#endregion
|
|
183
|
-
//#region src/terminal/style.ts
|
|
184
|
-
const DEFAULT_STYLE = {
|
|
185
|
-
fg: { mode: "default" },
|
|
186
|
-
bg: { mode: "default" },
|
|
187
|
-
bold: false,
|
|
188
|
-
dim: false,
|
|
189
|
-
italic: false,
|
|
190
|
-
underline: false,
|
|
191
|
-
inverse: false,
|
|
192
|
-
strikethrough: false
|
|
193
|
-
};
|
|
194
|
-
function extractStyle(cell) {
|
|
195
|
-
const style = {
|
|
196
|
-
fg: extractColor(cell.isFgDefault(), cell.isFgPalette(), cell.isFgRGB(), cell.getFgColor()),
|
|
197
|
-
bg: extractColor(cell.isBgDefault(), cell.isBgPalette(), cell.isBgRGB(), cell.getBgColor()),
|
|
198
|
-
bold: cell.isBold() !== 0,
|
|
199
|
-
dim: cell.isDim() !== 0,
|
|
200
|
-
italic: cell.isItalic() !== 0,
|
|
201
|
-
underline: cell.isUnderline() !== 0,
|
|
202
|
-
inverse: cell.isInverse() !== 0,
|
|
203
|
-
strikethrough: cell.isStrikethrough() !== 0
|
|
204
|
-
};
|
|
205
|
-
return isDefaultStyle(style) ? DEFAULT_STYLE : style;
|
|
206
|
-
}
|
|
207
|
-
function isDefaultStyle(style) {
|
|
208
|
-
return style.fg.mode === "default" && style.bg.mode === "default" && !style.bold && !style.dim && !style.italic && !style.underline && !style.inverse && !style.strikethrough;
|
|
209
|
-
}
|
|
210
|
-
function styleKey(style) {
|
|
211
|
-
return [
|
|
212
|
-
style.fg.mode === "default" ? "d" : `${style.fg.mode}:${style.fg.value}`,
|
|
213
|
-
style.bg.mode === "default" ? "d" : `${style.bg.mode}:${style.bg.value}`,
|
|
214
|
-
style.bold ? "b" : "",
|
|
215
|
-
style.dim ? "d" : "",
|
|
216
|
-
style.italic ? "i" : "",
|
|
217
|
-
style.underline ? "u" : "",
|
|
218
|
-
style.inverse ? "r" : "",
|
|
219
|
-
style.strikethrough ? "s" : ""
|
|
220
|
-
].join("|");
|
|
221
|
-
}
|
|
222
|
-
function findMeaningfulEndCol(line, cols, nullCell) {
|
|
223
|
-
if (!line) return 0;
|
|
224
|
-
for (let x = cols - 1; x >= 0; x -= 1) {
|
|
225
|
-
const cell = line.getCell(x, nullCell);
|
|
226
|
-
if (!cell) continue;
|
|
227
|
-
if (cell.getWidth() === 0) continue;
|
|
228
|
-
const chars = cell.getChars();
|
|
229
|
-
const style = extractStyle(cell);
|
|
230
|
-
if (chars !== "" && chars !== " " || !isDefaultStyle(style)) return x + 1;
|
|
231
|
-
}
|
|
232
|
-
return 0;
|
|
233
|
-
}
|
|
234
|
-
function extractColor(isDefault, isPalette, isRgb, value) {
|
|
235
|
-
if (isDefault) return { mode: "default" };
|
|
236
|
-
if (isRgb) return {
|
|
237
|
-
mode: "rgb",
|
|
238
|
-
value
|
|
239
|
-
};
|
|
240
|
-
if (isPalette) return {
|
|
241
|
-
mode: "palette",
|
|
242
|
-
value
|
|
243
|
-
};
|
|
244
|
-
return { mode: "default" };
|
|
245
|
-
}
|
|
246
|
-
//#endregion
|
|
247
184
|
//#region src/terminal/snapshot_rows.ts
|
|
248
185
|
function snapshotPlainLine(line, cols, nullCell, trimRight) {
|
|
249
186
|
let endCol = cols;
|
|
@@ -911,4 +848,4 @@ var TerminalSession = class {
|
|
|
911
848
|
}
|
|
912
849
|
};
|
|
913
850
|
//#endregion
|
|
914
|
-
export { fnv1a32 as a,
|
|
851
|
+
export { fnv1a32 as a, encodeSgrMouse as c, TraceRecorder as i, encodeKey as l, sleep as n, snapshotGrid as o, applyTextMaskRules as r, snapshotLines as s, TerminalSession as t };
|