humanish 0.55.0 → 0.57.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/actor-contract.d.ts +3 -2
- package/dist/actor-contract.js.map +1 -1
- package/dist/agent-session.d.ts +11 -0
- package/dist/agent-session.js +43 -0
- package/dist/agent-session.js.map +1 -0
- package/dist/cua-actor-lab.d.ts +10 -0
- package/dist/cua-actor-lab.js +145 -21
- package/dist/cua-actor-lab.js.map +1 -1
- package/dist/e2b-terminal-lab.js +36 -1
- package/dist/e2b-terminal-lab.js.map +1 -1
- package/dist/lab-config.d.ts +29 -4
- package/dist/lab-config.js +47 -8
- package/dist/lab-config.js.map +1 -1
- package/dist/lab-engine.js +6 -0
- package/dist/lab-engine.js.map +1 -1
- package/dist/labs.d.ts +6 -0
- package/dist/labs.js +4 -1
- package/dist/labs.js.map +1 -1
- package/dist/program.d.ts +9 -0
- package/dist/program.js +79 -4
- package/dist/program.js.map +1 -1
- package/dist/reasoning-effort.js +4 -2
- package/dist/reasoning-effort.js.map +1 -1
- package/dist/run-projection.d.ts +4 -0
- package/dist/run-projection.js +1 -0
- package/dist/run-projection.js.map +1 -1
- package/dist/run.d.ts +9 -0
- package/dist/run.js +23 -15
- package/dist/run.js.map +1 -1
- package/dist/terminal-encoding.d.ts +17 -0
- package/dist/terminal-encoding.js +80 -0
- package/dist/terminal-encoding.js.map +1 -0
- package/dist/tui-app.js +118 -118
- package/dist/tui-contract.d.ts +17 -0
- package/dist/tui-contract.js +22 -0
- package/dist/tui-contract.js.map +1 -1
- package/docs/contracts/schemas.md +13 -5
- package/docs/goals/current.md +2 -2
- package/docs/principles/actor-fidelity.md +23 -1
- package/docs/ramp/README.md +1 -1
- package/package.json +1 -1
package/dist/actor-contract.d.ts
CHANGED
|
@@ -143,8 +143,9 @@ export interface ActorTrace {
|
|
|
143
143
|
* every pre-existing bundle, and its absence is tolerated by verify.
|
|
144
144
|
*
|
|
145
145
|
* It exists because effort was a silent constant: unreachable from a lab, so every run took the
|
|
146
|
-
* provider default.
|
|
147
|
-
*
|
|
146
|
+
* provider default. Effort is part of WHO the participant was, not of how the instrument was
|
|
147
|
+
* tuned (docs/principles/actor-fidelity.md), so a trace that does not carry it is a result with
|
|
148
|
+
* half its sample description missing — and two such traces cannot honestly be compared.
|
|
148
149
|
*/
|
|
149
150
|
modelSettings?: {
|
|
150
151
|
reasoningEffort: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actor-contract.js","sourceRoot":"","sources":["../src/actor-contract.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,oEAAoE;AACpE,0EAA0E;AAC1E,oFAAoF;AACpF,EAAE;AACF,iFAAiF;AACjF,8EAA8E;AAC9E,gFAAgF;AAChF,uBAAuB;AAEvB,MAAM,CAAC,MAAM,kBAAkB,GAAG,yBAAyB,CAAC;AAmB5D;;iCAEiC;AACjC,MAAM,CAAC,MAAM,4BAA4B,GAA2B,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"actor-contract.js","sourceRoot":"","sources":["../src/actor-contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface AgentSession {
|
|
2
|
+
/** Human-readable runner name, for the refusal message. */
|
|
3
|
+
runner: string;
|
|
4
|
+
/** The environment variable that identified it — named so the reader can check us. */
|
|
5
|
+
marker: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The agent runner driving this process, when one identifies itself. `undefined` means nothing
|
|
9
|
+
* claimed to be an agent — which is NOT proof a person is there, only the absence of a claim.
|
|
10
|
+
*/
|
|
11
|
+
export declare function detectAgentSession(env?: NodeJS.ProcessEnv): AgentSession | undefined;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Is the terminal on the other end of this process a PERSON's, or an agent's?
|
|
2
|
+
//
|
|
3
|
+
// WHY THIS EXISTS: `humanish tui` refused a non-TTY, on the reasoning that an agent driving an
|
|
4
|
+
// interactive surface has asked for something that cannot exist. A study of that refusal
|
|
5
|
+
// (labs/handed-a-human-surface.yaml) found it never fires: `codex exec` allocates a PTY for the
|
|
6
|
+
// commands it runs, so both streams ARE terminals. The TUI launched, the agent navigated the labs
|
|
7
|
+
// list, opened one, and — its own words — "accidentally triggered a zero-cost dry run while
|
|
8
|
+
// navigating". A stray Enter on a live row is the same two keystrokes as a deliberate one.
|
|
9
|
+
//
|
|
10
|
+
// So a TTY is a real answer to the wrong question. It says a terminal exists; it does not say
|
|
11
|
+
// anyone is reading it. Agent runners announce themselves in the environment, which is the only
|
|
12
|
+
// signal available before the first keystroke, and is what `is-in-ci` has always done for CI.
|
|
13
|
+
//
|
|
14
|
+
// EVERY MARKER BELOW WAS OBSERVED, not guessed. Two runtimes are covered because two are what we
|
|
15
|
+
// could verify: Claude Code (read off a live session) and Codex (read off the study sandbox, by a
|
|
16
|
+
// names-only `env | cut -d= -f1` probe that never touched a value). Others certainly exist — add
|
|
17
|
+
// them the same way, from a real session, rather than from a plausible-looking guess. A marker
|
|
18
|
+
// that is wrong refuses a person for no reason.
|
|
19
|
+
const MARKERS = [
|
|
20
|
+
{ marker: "CLAUDECODE", runner: "Claude Code" },
|
|
21
|
+
{ marker: "CLAUDE_CODE_SESSION_ID", runner: "Claude Code" },
|
|
22
|
+
{ marker: "CODEX_SESSION_ID", runner: "Codex" },
|
|
23
|
+
{ marker: "CODEX_THREAD_ID", runner: "Codex" },
|
|
24
|
+
// Generic, and set alongside the Claude Code markers on the machine this was written on. Kept
|
|
25
|
+
// last so a named runner wins the attribution.
|
|
26
|
+
{ marker: "AI_AGENT", runner: "an AI agent runner" }
|
|
27
|
+
];
|
|
28
|
+
/**
|
|
29
|
+
* The agent runner driving this process, when one identifies itself. `undefined` means nothing
|
|
30
|
+
* claimed to be an agent — which is NOT proof a person is there, only the absence of a claim.
|
|
31
|
+
*/
|
|
32
|
+
export function detectAgentSession(env = process.env) {
|
|
33
|
+
for (const { marker, runner } of MARKERS) {
|
|
34
|
+
const value = env[marker];
|
|
35
|
+
// Presence is the signal, but an explicitly empty or "0" value is treated as absence: a
|
|
36
|
+
// wrapper that unsets a marker by blanking it means it.
|
|
37
|
+
if (value !== undefined && value.trim().length > 0 && value.trim() !== "0") {
|
|
38
|
+
return { runner, marker };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=agent-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-session.js","sourceRoot":"","sources":["../src/agent-session.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,EAAE;AACF,+FAA+F;AAC/F,yFAAyF;AACzF,gGAAgG;AAChG,kGAAkG;AAClG,4FAA4F;AAC5F,2FAA2F;AAC3F,EAAE;AACF,8FAA8F;AAC9F,gGAAgG;AAChG,8FAA8F;AAC9F,EAAE;AACF,iGAAiG;AACjG,kGAAkG;AAClG,iGAAiG;AACjG,+FAA+F;AAC/F,gDAAgD;AAShD,MAAM,OAAO,GAAsD;IACjE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE;IAC/C,EAAE,MAAM,EAAE,wBAAwB,EAAE,MAAM,EAAE,aAAa,EAAE;IAC3D,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,OAAO,EAAE;IAC/C,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,OAAO,EAAE;IAC9C,8FAA8F;IAC9F,+CAA+C;IAC/C,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,oBAAoB,EAAE;CACrD,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACrE,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1B,wFAAwF;QACxF,wDAAwD;QACxD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/dist/cua-actor-lab.d.ts
CHANGED
|
@@ -416,6 +416,14 @@ export declare function composeLaneInstructions(args: {
|
|
|
416
416
|
* no committed file, unparseable YAML) keeps the honest fallback: the bare line and an EMPTY
|
|
417
417
|
* traitsApplied, never fabricated traits. Resolved by the caller so this stays pure. */
|
|
418
418
|
resolvedPersona?: ResolvedPersona;
|
|
419
|
+
/**
|
|
420
|
+
* desktop-cli (#495): the surface under study is a terminal window, not a page. Said plainly
|
|
421
|
+
* because a participant whose every prior world was a browser will look for one — and because a
|
|
422
|
+
* capability nobody declares is one the recording cannot later be read against. It states that a
|
|
423
|
+
* terminal is open and NOT what to type in it: naming commands would answer the question the
|
|
424
|
+
* study is asking.
|
|
425
|
+
*/
|
|
426
|
+
surface?: "desktop-cli";
|
|
419
427
|
}): {
|
|
420
428
|
instructions: string;
|
|
421
429
|
persona: ActorPersonaRef;
|
|
@@ -505,6 +513,8 @@ export interface CuaLaneDeps {
|
|
|
505
513
|
descriptor: CuaActorDescriptor;
|
|
506
514
|
appUrl: string;
|
|
507
515
|
cloneRoute: boolean;
|
|
516
|
+
/** desktop-cli (#495): a CLI studied at a desktop. Nothing is cloned and no browser is opened. */
|
|
517
|
+
desktopCliRoute?: boolean;
|
|
508
518
|
/** Optional so out-of-scope callers building CuaLaneDeps directly (other engines reusing
|
|
509
519
|
* runCuaLane) do not need to know about the local-tree route; undefined behaves as false. */
|
|
510
520
|
localTreeRoute?: boolean;
|
package/dist/cua-actor-lab.js
CHANGED
|
@@ -136,9 +136,13 @@ export function composeLaneInstructions(args) {
|
|
|
136
136
|
? renderPersonaPromptSection(args.resolvedPersona)
|
|
137
137
|
: args.persona ? `Persona: ${args.persona}.` : undefined;
|
|
138
138
|
const traitsApplied = args.resolvedPersona ? personaToDirectives(args.resolvedPersona).traitsApplied : [];
|
|
139
|
+
const surfaceLine = args.surface === "desktop-cli"
|
|
140
|
+
? "A terminal window is already open on this desktop, and there is a terminal in the dock at the bottom of the screen if you want another. Everything you need is on this machine; there is no browser task here."
|
|
141
|
+
: undefined;
|
|
139
142
|
const parts = [
|
|
140
143
|
personaLine,
|
|
141
144
|
deviceLine,
|
|
145
|
+
surfaceLine,
|
|
142
146
|
args.mission,
|
|
143
147
|
taskLines,
|
|
144
148
|
args.instruction ? `Lane focus: ${args.instruction}` : undefined
|
|
@@ -291,7 +295,8 @@ function laneSpecsAndPlan(config, opts = {}) {
|
|
|
291
295
|
...(personaId === undefined ? {} : { persona: personaId }),
|
|
292
296
|
...(resolvedPersona === undefined ? {} : { resolvedPersona }),
|
|
293
297
|
...(((roster ? lane?.instruction : actor?.laneFocus?.instruction)) === undefined ? {} : { instruction: (roster ? lane?.instruction : actor?.laneFocus?.instruction) }),
|
|
294
|
-
device: { name: device.name, preset: device.preset }
|
|
298
|
+
device: { name: device.name, preset: device.preset },
|
|
299
|
+
...(config.subject.source === "desktop-cli" ? { surface: "desktop-cli" } : {})
|
|
295
300
|
});
|
|
296
301
|
lanes.push({
|
|
297
302
|
laneId,
|
|
@@ -1069,6 +1074,91 @@ export async function captureDesktopBrowserGeometry(args) {
|
|
|
1069
1074
|
function shellSingleQuote(value) {
|
|
1070
1075
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
1071
1076
|
}
|
|
1077
|
+
/**
|
|
1078
|
+
* Put a CLI on the desktop before the participant arrives (#495).
|
|
1079
|
+
*
|
|
1080
|
+
* The install runs UNKEYED and before the session starts, for the same reason the clone route
|
|
1081
|
+
* provisions its subject first: what is being studied begins when the participant looks at the
|
|
1082
|
+
* screen, and making them fight an install first would be a study of the install.
|
|
1083
|
+
*/
|
|
1084
|
+
async function provisionDesktopCli(desktop, args) {
|
|
1085
|
+
const install = args.install;
|
|
1086
|
+
if (install === undefined)
|
|
1087
|
+
return;
|
|
1088
|
+
const now = () => Date.now();
|
|
1089
|
+
if (needsNodeRuntime([install])) {
|
|
1090
|
+
const startedAt = now();
|
|
1091
|
+
emitPhaseStarted(args.onPhase, now, "runtime", "providing the Node runtime the install needs");
|
|
1092
|
+
const bootstrap = await runDetachedStep(desktop, {
|
|
1093
|
+
name: "desktop-cli-runtime-node",
|
|
1094
|
+
command: nodeBootstrapCommand(),
|
|
1095
|
+
cwd: "/home/user",
|
|
1096
|
+
timeoutMs: INSTALL_TIMEOUT_MS,
|
|
1097
|
+
requestTimeoutMs: args.requestTimeoutMs
|
|
1098
|
+
});
|
|
1099
|
+
emitPhaseCompleted(args.onPhase, now, startedAt, "runtime", bootstrap.ok, bootstrap.ok
|
|
1100
|
+
? "Node runtime ready"
|
|
1101
|
+
: "Node runtime bootstrap failed");
|
|
1102
|
+
if (!bootstrap.ok) {
|
|
1103
|
+
throw new Error(`desktop-cli runtime bootstrap failed for "${args.product}"`);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
const startedAt = now();
|
|
1107
|
+
emitPhaseStarted(args.onPhase, now, "install", `installing ${args.product} on the desktop`);
|
|
1108
|
+
const result = await runDetachedStep(desktop, {
|
|
1109
|
+
name: "desktop-cli-install",
|
|
1110
|
+
command: install,
|
|
1111
|
+
cwd: "/home/user",
|
|
1112
|
+
timeoutMs: INSTALL_TIMEOUT_MS,
|
|
1113
|
+
requestTimeoutMs: args.requestTimeoutMs
|
|
1114
|
+
});
|
|
1115
|
+
emitPhaseCompleted(args.onPhase, now, startedAt, "install", result.ok, result.ok
|
|
1116
|
+
? `${args.product} installed`
|
|
1117
|
+
: `installing ${args.product} failed`);
|
|
1118
|
+
if (!result.ok) {
|
|
1119
|
+
// Fail closed: a participant handed a desktop where the product is not installed would produce
|
|
1120
|
+
// a transcript about a missing command, and that finding belongs to the harness, not the tool.
|
|
1121
|
+
// The tail rides along, scrubbed before truncation like every other provisioning failure — a
|
|
1122
|
+
// bare "install failed" is unactionable to whoever wrote the command.
|
|
1123
|
+
throw new Error(args.scrub(`desktop-cli install failed for "${args.product}" (${result.timedOut ? "timed out" : `exit ${result.exitCode ?? "?"}`}): ${tailOf(args.scrub(result.logTail))}`));
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
/**
|
|
1127
|
+
* Open a terminal window on the desktop.
|
|
1128
|
+
*
|
|
1129
|
+
* The stock template is XFCE and ships xfce4-terminal (also aliased x-terminal-emulator), verified
|
|
1130
|
+
* live before this route was built. `x-terminal-emulator` is tried first so a template that swaps
|
|
1131
|
+
* the emulator still works; a desktop with neither is a template problem and fails closed rather
|
|
1132
|
+
* than handing a participant an empty screen and calling it a study.
|
|
1133
|
+
*/
|
|
1134
|
+
async function openDesktopTerminal(desktop, requestTimeoutMs, workdir) {
|
|
1135
|
+
const dir = workdir ?? "/home/user";
|
|
1136
|
+
const result = await runDetachedStep(desktop, {
|
|
1137
|
+
name: "desktop-cli-terminal",
|
|
1138
|
+
command: [
|
|
1139
|
+
"for candidate in x-terminal-emulator xfce4-terminal gnome-terminal konsole xterm; do",
|
|
1140
|
+
' if command -v "$candidate" >/dev/null 2>&1; then',
|
|
1141
|
+
// LANG is set on the terminal we open, not globally: the stock image declares no locale, and
|
|
1142
|
+
// a study that measures our own mojibake against an unconfigured template would be measuring
|
|
1143
|
+
// the template. The PRODUCT-side fix (an ASCII fallback when the locale is not UTF-8) is in
|
|
1144
|
+
// src/terminal-encoding.ts, and it is the one that matters for real users.
|
|
1145
|
+
` (cd ${shellSingleQuote(dir)} 2>/dev/null || cd /home/user; DISPLAY=:0 LANG=C.UTF-8 LC_ALL=C.UTF-8 nohup "$candidate" >/dev/null 2>&1 &)`,
|
|
1146
|
+
" sleep 3",
|
|
1147
|
+
' echo "humanish: opened $candidate"',
|
|
1148
|
+
" exit 0",
|
|
1149
|
+
" fi",
|
|
1150
|
+
"done",
|
|
1151
|
+
"echo 'humanish: no terminal emulator on this desktop template' >&2",
|
|
1152
|
+
"exit 1"
|
|
1153
|
+
].join("\n"),
|
|
1154
|
+
cwd: "/home/user",
|
|
1155
|
+
timeoutMs: 60_000,
|
|
1156
|
+
requestTimeoutMs
|
|
1157
|
+
});
|
|
1158
|
+
if (!result.ok) {
|
|
1159
|
+
throw new Error("desktop-cli lane could not open a terminal on this desktop template");
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1072
1162
|
async function startDesktopStream(desktop, browserWindowId) {
|
|
1073
1163
|
if (!browserWindowId) {
|
|
1074
1164
|
await desktop.stream.start({ requireAuth: true });
|
|
@@ -1182,6 +1272,7 @@ export function resolveSelfReportedFriction(session) {
|
|
|
1182
1272
|
*/
|
|
1183
1273
|
export async function runCuaLane(spec, deps) {
|
|
1184
1274
|
const { config, appUrl, cloneRoute, localTreeRoute, serve, subjectRepo, subjectEnvNames } = deps;
|
|
1275
|
+
const desktopCliRoute = deps.desktopCliRoute === true;
|
|
1185
1276
|
const subjectEnvValues = config.subject.envValues ?? {};
|
|
1186
1277
|
const targetUrl = spec.targetUrl ?? appUrl;
|
|
1187
1278
|
const env = deps.env;
|
|
@@ -1409,6 +1500,18 @@ export async function runCuaLane(spec, deps) {
|
|
|
1409
1500
|
warnings: [...(desktopGeometry.warnings ?? []), mismatchWarning]
|
|
1410
1501
|
};
|
|
1411
1502
|
}
|
|
1503
|
+
if (desktopCliRoute) {
|
|
1504
|
+
// Put the product on the desktop before the participant sees it. UNKEYED, like every other
|
|
1505
|
+
// provisioning step: the participant's world is prepared by the harness, and what is being
|
|
1506
|
+
// studied starts at the moment they look at the screen.
|
|
1507
|
+
await provisionDesktopCli(desktop, {
|
|
1508
|
+
product: config.subject.product?.name ?? "",
|
|
1509
|
+
...(config.subject.product?.install === undefined ? {} : { install: config.subject.product.install }),
|
|
1510
|
+
requestTimeoutMs: deps.requestTimeoutMs,
|
|
1511
|
+
scrub: deps.scrubKnownValues,
|
|
1512
|
+
onPhase: onSubjectPhase
|
|
1513
|
+
});
|
|
1514
|
+
}
|
|
1412
1515
|
if (cloneRoute && serve && subjectRepo) {
|
|
1413
1516
|
subjectCommit = await provisionCloneSubject(desktop, {
|
|
1414
1517
|
repo: subjectRepo,
|
|
@@ -1442,28 +1545,44 @@ export async function runCuaLane(spec, deps) {
|
|
|
1442
1545
|
...(deps.hooks.detachedTimers ?? {})
|
|
1443
1546
|
});
|
|
1444
1547
|
}
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1548
|
+
if (!desktopCliRoute) {
|
|
1549
|
+
const browserLaunch = await openDesktopBrowserTarget(desktop, targetUrl, deps.requestTimeoutMs, config.execution?.desktop?.browser);
|
|
1550
|
+
desktopBrowser = browserLaunch.evidence;
|
|
1551
|
+
launchedBrowserFamily = browserLaunch.family;
|
|
1552
|
+
browserLaunchIdentity = browserLaunch.identity;
|
|
1553
|
+
browserLaunched = true;
|
|
1554
|
+
await desktop.wait(BROWSER_SETTLE_MS).catch(() => undefined);
|
|
1555
|
+
}
|
|
1556
|
+
else {
|
|
1557
|
+
// A terminal window, opened the way the browser is opened on every other route: the
|
|
1558
|
+
// participant arrives at a desktop with the thing they were asked to use already in front
|
|
1559
|
+
// of them. They can still open another from the dock — that is the point of a desktop.
|
|
1560
|
+
await openDesktopTerminal(desktop, deps.requestTimeoutMs, config.subject.product?.workdir);
|
|
1561
|
+
await desktop.wait(BROWSER_SETTLE_MS).catch(() => undefined);
|
|
1562
|
+
}
|
|
1451
1563
|
// World is ready: release the pipeline gate so the remaining lanes may start.
|
|
1452
1564
|
provisioned = true;
|
|
1453
1565
|
signal(true);
|
|
1454
1566
|
try {
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1567
|
+
// No browser means no browser geometry, and none is invented: the CSS-viewport facts a
|
|
1568
|
+
// browser reports have no counterpart in a terminal window, and an empty record shaped like
|
|
1569
|
+
// a measurement would read as one. The screen geometry above is still verified.
|
|
1570
|
+
if (!desktopCliRoute) {
|
|
1571
|
+
const browserGeometry = await captureDesktopBrowserGeometry({
|
|
1572
|
+
desktop,
|
|
1573
|
+
browserFamily: launchedBrowserFamily,
|
|
1574
|
+
...(browserLaunchIdentity === undefined ? {} : { launchIdentity: browserLaunchIdentity }),
|
|
1575
|
+
laneId: spec.laneId,
|
|
1576
|
+
targetUrl,
|
|
1577
|
+
requestedScreen: spec.resolution,
|
|
1578
|
+
requestTimeoutMs: deps.requestTimeoutMs
|
|
1579
|
+
});
|
|
1580
|
+
initialBrowserGeometry = browserGeometry;
|
|
1581
|
+
browserWindowId = browserGeometry.browserWindowId;
|
|
1582
|
+
browserTargetId = browserGeometry.browserTargetId;
|
|
1583
|
+
}
|
|
1584
|
+
// The WHOLE desktop, not one window: a person studying a terminal app opens other windows,
|
|
1585
|
+
// and a stream bound to the first one would quietly stop being evidence.
|
|
1467
1586
|
await startDesktopStream(desktop, browserWindowId);
|
|
1468
1587
|
const candidateStreamUrl = desktop.stream.getUrl({
|
|
1469
1588
|
authKey: desktop.stream.getAuthKey(),
|
|
@@ -2085,6 +2204,8 @@ async function runCuaActorLabInScope(options) {
|
|
|
2085
2204
|
const env = hooks.env ?? process.env;
|
|
2086
2205
|
const render = hooks.renderObserverFn ?? renderObserver;
|
|
2087
2206
|
const cloneRoute = config.subject.source === "clone";
|
|
2207
|
+
// A CLI studied at a desktop (#495): nothing cloned, no browser, a terminal instead.
|
|
2208
|
+
const desktopCliRoute = config.subject.source === "desktop-cli";
|
|
2088
2209
|
const localTreeRoute = config.subject.source === "local-tree";
|
|
2089
2210
|
// Both routes provision the subject in-sandbox (clone via git, local-tree via pack+upload)
|
|
2090
2211
|
// and then share the identical install/build/state/start/probe pipeline, so every seam that
|
|
@@ -2151,10 +2272,12 @@ async function runCuaActorLabInScope(options) {
|
|
|
2151
2272
|
return fail("HUMANISH_CUA_LAB_SUBJECT_INVALID", stateReason, descriptor.id);
|
|
2152
2273
|
}
|
|
2153
2274
|
}
|
|
2154
|
-
// Re-enforce the entry-target boundary (library API surface).
|
|
2275
|
+
// Re-enforce the entry-target boundary (library API surface). A desktop-cli study has no entry
|
|
2276
|
+
// target at all — the subject is a program on the machine, not an address — so the boundary is
|
|
2277
|
+
// vacuous there rather than violated by an empty string.
|
|
2155
2278
|
const allowPublicTargets = config.policies?.allowPublicTargets === true;
|
|
2156
2279
|
const declaredTargets = [appUrl, ...(actor?.lanes ?? []).map((lane) => lane.target).filter((target) => target !== undefined)];
|
|
2157
|
-
const entryTargetSafe = declaredTargets.every((target) => provisionedRoute || localAppSubject
|
|
2280
|
+
const entryTargetSafe = desktopCliRoute || declaredTargets.every((target) => provisionedRoute || localAppSubject
|
|
2158
2281
|
? isLoopbackUrl(target)
|
|
2159
2282
|
: allowPublicTargets
|
|
2160
2283
|
? isHttpUrl(target)
|
|
@@ -2344,6 +2467,7 @@ async function runCuaActorLabInScope(options) {
|
|
|
2344
2467
|
descriptor,
|
|
2345
2468
|
appUrl,
|
|
2346
2469
|
cloneRoute,
|
|
2470
|
+
desktopCliRoute,
|
|
2347
2471
|
localTreeRoute,
|
|
2348
2472
|
...(serve === undefined ? {} : { serve }),
|
|
2349
2473
|
...(subjectRepo === undefined ? {} : { subjectRepo }),
|