humanish 0.49.0 → 0.51.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/README.md +52 -3
- package/dist/concurrent-shared-world-lab.d.ts +5 -0
- package/dist/concurrent-shared-world-lab.js +28 -0
- package/dist/concurrent-shared-world-lab.js.map +1 -1
- package/dist/cua-actor-lab.d.ts +7 -0
- package/dist/cua-actor-lab.js +64 -3
- package/dist/cua-actor-lab.js.map +1 -1
- package/dist/e2b-terminal-lab.d.ts +7 -0
- package/dist/e2b-terminal-lab.js +54 -0
- package/dist/e2b-terminal-lab.js.map +1 -1
- package/dist/init-templates.js +7 -2
- package/dist/init-templates.js.map +1 -1
- package/dist/lab-engine.d.ts +11 -0
- package/dist/lab-engine.js +18 -0
- package/dist/lab-engine.js.map +1 -1
- package/dist/lab-summary.d.ts +36 -0
- package/dist/lab-summary.js +86 -0
- package/dist/lab-summary.js.map +1 -0
- package/dist/oss-lab.d.ts +3 -0
- package/dist/oss-lab.js.map +1 -1
- package/dist/oss-meta-lab.d.ts +3 -0
- package/dist/oss-meta-lab.js +13 -0
- package/dist/oss-meta-lab.js.map +1 -1
- package/dist/program.d.ts +14 -0
- package/dist/program.js +131 -9
- package/dist/program.js.map +1 -1
- package/dist/run-detail.d.ts +59 -0
- package/dist/run-detail.js +108 -0
- package/dist/run-detail.js.map +1 -0
- package/dist/run-index.d.ts +71 -0
- package/dist/run-index.js +206 -0
- package/dist/run-index.js.map +1 -0
- package/dist/run-paths.js +16 -1
- package/dist/run-paths.js.map +1 -1
- package/dist/run-projection.d.ts +182 -0
- package/dist/run-projection.js +349 -0
- package/dist/run-projection.js.map +1 -0
- package/dist/run-status.d.ts +139 -0
- package/dist/run-status.js +218 -0
- package/dist/run-status.js.map +1 -0
- package/dist/run.d.ts +15 -0
- package/dist/run.js +91 -6
- package/dist/run.js.map +1 -1
- package/dist/scripted-browser-lab.d.ts +5 -0
- package/dist/scripted-browser-lab.js +27 -0
- package/dist/scripted-browser-lab.js.map +1 -1
- package/dist/shared-world-lab.d.ts +5 -0
- package/dist/shared-world-lab.js +27 -0
- package/dist/shared-world-lab.js.map +1 -1
- package/dist/tui-app.js +402 -0
- package/dist/tui-contract.d.ts +84 -0
- package/dist/tui-contract.js +32 -0
- package/dist/tui-contract.js.map +1 -0
- package/dist/tui-launch.d.ts +48 -0
- package/dist/tui-launch.js +159 -0
- package/dist/tui-launch.js.map +1 -0
- package/dist/tui-project.d.ts +9 -0
- package/dist/tui-project.js +18 -0
- package/dist/tui-project.js.map +1 -0
- package/docs/contracts/run-bundle.md +8 -0
- package/docs/contracts/schemas.md +70 -1
- package/docs/goals/current.md +3 -2
- package/docs/ramp/README.md +1 -1
- package/package.json +8 -5
- package/skills/humanish/SKILL.md +19 -0
package/dist/cua-actor-lab.js
CHANGED
|
@@ -26,6 +26,7 @@ import { readFile, realpath, rm } from "node:fs/promises";
|
|
|
26
26
|
import path from "node:path";
|
|
27
27
|
import { runDesktopCommandOrThrow, toErrorMessage } from "./command-failure.js";
|
|
28
28
|
import { pathToFileURL } from "node:url";
|
|
29
|
+
import { beginRunStatus } from "./run-status.js";
|
|
29
30
|
import { adapterScoreFailureMessage, applyBrowserAdapterHooks } from "./adapter-extension.js";
|
|
30
31
|
import { actorRegistry, isCuaActorDescriptor } from "./actor-registry.js";
|
|
31
32
|
import { CHROMIUM_EVIDENCE_HYGIENE_FLAGS, chromiumEvidenceProfilePreferencesJson } from "./browser-evidence-hygiene.js";
|
|
@@ -2261,6 +2262,17 @@ export async function runCuaActorLab(options) {
|
|
|
2261
2262
|
}
|
|
2262
2263
|
const runId = options.runId ?? makeCuaRunId();
|
|
2263
2264
|
const runPaths = await prepareRunArtifactPaths(cwd, runId);
|
|
2265
|
+
// Identity + liveness on disk from the first moment (#455): anything watching the runs
|
|
2266
|
+
// directory — the TUI, another terminal, an agent — can now tell which lab this is and that
|
|
2267
|
+
// it is alive, without waiting for the interactive observer flush that used to be the only
|
|
2268
|
+
// mid-run write. The success path finalizes it with the real outcome; the fail-closed returns
|
|
2269
|
+
// below do not, so `runLab`'s status scope finalizes those with no outcome. A crash reaches
|
|
2270
|
+
// neither and leaves the record stale, which reads as interrupted rather than as a lie.
|
|
2271
|
+
const runStatus = beginRunStatus(runPaths, {
|
|
2272
|
+
runId,
|
|
2273
|
+
mode: dryRun ? "dry-run" : "live",
|
|
2274
|
+
...(options.lab === undefined ? {} : { lab: options.lab })
|
|
2275
|
+
});
|
|
2264
2276
|
const artifactRoot = runPaths.absoluteRunRoot;
|
|
2265
2277
|
const physicalArtifactRoot = runPaths.physicalRunRoot;
|
|
2266
2278
|
const createdAt = new Date().toISOString();
|
|
@@ -2353,9 +2365,16 @@ export async function runCuaActorLab(options) {
|
|
|
2353
2365
|
}));
|
|
2354
2366
|
const inProgressAggregateSubject = inProgressLaneSubjects[0];
|
|
2355
2367
|
const inProgressProvenance = subjectProvenanceArg(inProgressAggregateSubject, publicRepo, subjectEnvNames);
|
|
2356
|
-
|
|
2368
|
+
// A live run writes what it is doing AS IT DOES IT, whether or not anyone is currently watching.
|
|
2369
|
+
// This used to be gated on `options.onObserverReady` — the interactive Observer callback — so a
|
|
2370
|
+
// run launched by an agent (`lab run --json`), detached, or from the terminal surface recorded
|
|
2371
|
+
// nothing at all until it completed, and anything asking "what is this participant doing right
|
|
2372
|
+
// now" got silence for the whole run. Who reads the evidence is not the run's business; the
|
|
2373
|
+
// callback below stays conditional, the writing does not.
|
|
2374
|
+
if (!dryRun) {
|
|
2357
2375
|
const inProgressBundle = laneCount === 1 && rerunLineage === undefined
|
|
2358
2376
|
? buildSingleLaneBundle({
|
|
2377
|
+
...(options.lab === undefined ? {} : { lab: options.lab }),
|
|
2359
2378
|
spec: laneSpecs[0],
|
|
2360
2379
|
outcome: undefined,
|
|
2361
2380
|
descriptor,
|
|
@@ -2372,6 +2391,7 @@ export async function runCuaActorLab(options) {
|
|
|
2372
2391
|
localAppSubject
|
|
2373
2392
|
})
|
|
2374
2393
|
: buildCuaFanoutBundle({
|
|
2394
|
+
...(options.lab === undefined ? {} : { lab: options.lab }),
|
|
2375
2395
|
specs: laneSpecs,
|
|
2376
2396
|
laneSubjects: inProgressLaneSubjects,
|
|
2377
2397
|
aggregateSubject: inProgressAggregateSubject,
|
|
@@ -2394,7 +2414,8 @@ export async function runCuaActorLab(options) {
|
|
|
2394
2414
|
liveObserver = observerResultForCuaArtifacts(cwd, runId, artifactRoot, [
|
|
2395
2415
|
"Live CUA Observer is attached before final verification; stream auth URLs are runtime-only and are not persisted."
|
|
2396
2416
|
]);
|
|
2397
|
-
|
|
2417
|
+
if (options.onObserverReady)
|
|
2418
|
+
await options.onObserverReady(liveObserver);
|
|
2398
2419
|
// Incremental live flush (#441): as each lane's loop reports its recorded-so-far items,
|
|
2399
2420
|
// rewrite the in-progress bundle with per-stream `liveActor` partials so the attached
|
|
2400
2421
|
// Observer's 5s poll sees the timeline grow. Throttled (one write per interval, trailing
|
|
@@ -2402,6 +2423,10 @@ export async function runCuaActorLab(options) {
|
|
|
2402
2423
|
// write so a stale flush can never resurrect the in-progress bundle. A flush failure is
|
|
2403
2424
|
// swallowed: mid-run observability must never break the run itself.
|
|
2404
2425
|
const streamIdByLane = new Map(laneSpecs.map((spec) => [spec.laneId, spec.streamId]));
|
|
2426
|
+
// The persona each lane is running, so the live flush can say who is in it.
|
|
2427
|
+
const personaByStream = new Map(laneSpecs
|
|
2428
|
+
.map((spec) => [spec.streamId, spec.persona?.id])
|
|
2429
|
+
.filter((entry) => typeof entry[1] === "string"));
|
|
2405
2430
|
const liveItemsByStream = new Map();
|
|
2406
2431
|
let flushWriting;
|
|
2407
2432
|
let flushDirty = false;
|
|
@@ -2420,7 +2445,20 @@ export async function runCuaActorLab(options) {
|
|
|
2420
2445
|
const liveItems = liveItemsByStream.get(stream.id);
|
|
2421
2446
|
return liveItems === undefined
|
|
2422
2447
|
? stream
|
|
2423
|
-
: {
|
|
2448
|
+
: {
|
|
2449
|
+
...stream,
|
|
2450
|
+
liveActor: {
|
|
2451
|
+
schema: "humanish.live-actor.v1",
|
|
2452
|
+
updatedAt,
|
|
2453
|
+
// WHO is in this lane, carried while the run is live. Without it a surface
|
|
2454
|
+
// watching a live run can only name the lane, and "CUA browser — observer-live-
|
|
2455
|
+
// check" is the harness talking about itself where the participant should be.
|
|
2456
|
+
...(personaByStream.get(stream.id) === undefined
|
|
2457
|
+
? {}
|
|
2458
|
+
: { persona: { id: personaByStream.get(stream.id) } }),
|
|
2459
|
+
items: [...liveItems]
|
|
2460
|
+
}
|
|
2461
|
+
};
|
|
2424
2462
|
})
|
|
2425
2463
|
};
|
|
2426
2464
|
try {
|
|
@@ -2585,6 +2623,7 @@ export async function runCuaActorLab(options) {
|
|
|
2585
2623
|
const finalProvenance = subjectProvenanceArg(aggregateSubject, publicRepo, subjectEnvNames);
|
|
2586
2624
|
const bundle = laneCount === 1 && rerunLineage === undefined
|
|
2587
2625
|
? buildSingleLaneBundle({
|
|
2626
|
+
...(options.lab === undefined ? {} : { lab: options.lab }),
|
|
2588
2627
|
spec: laneSpecs[0],
|
|
2589
2628
|
outcome: outcomes?.[0],
|
|
2590
2629
|
descriptor,
|
|
@@ -2600,6 +2639,7 @@ export async function runCuaActorLab(options) {
|
|
|
2600
2639
|
localAppSubject
|
|
2601
2640
|
})
|
|
2602
2641
|
: buildCuaFanoutBundle({
|
|
2642
|
+
...(options.lab === undefined ? {} : { lab: options.lab }),
|
|
2603
2643
|
specs: laneSpecs,
|
|
2604
2644
|
...(outcomes === undefined ? {} : { outcomes }),
|
|
2605
2645
|
laneSubjects,
|
|
@@ -2639,6 +2679,24 @@ export async function runCuaActorLab(options) {
|
|
|
2639
2679
|
...(options.scorerProvenance === undefined ? {} : { scorerProvenance: options.scorerProvenance })
|
|
2640
2680
|
});
|
|
2641
2681
|
await writeCuaRunArtifacts(bundle, createdAt, runPaths);
|
|
2682
|
+
// Finalize the status record from the bundle that was just written, so the index can never
|
|
2683
|
+
// claim an outcome the evidence does not carry. A run that throws before reaching here leaves
|
|
2684
|
+
// its record `running` and goes stale — read as interrupted, which is the truth.
|
|
2685
|
+
await runStatus.finish({
|
|
2686
|
+
...(bundle.review?.verdict === undefined ? {} : { verdict: bundle.review.verdict }),
|
|
2687
|
+
...(bundle.review?.participants === undefined
|
|
2688
|
+
? {}
|
|
2689
|
+
: {
|
|
2690
|
+
participants: {
|
|
2691
|
+
total: bundle.review.participants.total,
|
|
2692
|
+
reachedGoal: bundle.review.participants.reachedGoal,
|
|
2693
|
+
...(bundle.review.participants.reportedFriction === undefined
|
|
2694
|
+
? {}
|
|
2695
|
+
: { reportedFriction: bundle.review.participants.reportedFriction })
|
|
2696
|
+
}
|
|
2697
|
+
}),
|
|
2698
|
+
...(bundle.cost?.estimatedTotalUsd === undefined ? {} : { estimatedCostUsd: bundle.cost.estimatedTotalUsd })
|
|
2699
|
+
});
|
|
2642
2700
|
const observer = await render(cwd, runId, { open: options.open === true });
|
|
2643
2701
|
if (observer.ok && runtimeStreamUrls.length > 0) {
|
|
2644
2702
|
attachObserverRuntimeStreamUrls(observer, runtimeStreamUrls);
|
|
@@ -2801,6 +2859,7 @@ function observerResultForCuaArtifacts(cwd, runId, artifactRoot, warnings = [])
|
|
|
2801
2859
|
function buildSingleLaneBundle(args) {
|
|
2802
2860
|
const { spec, outcome, config } = args;
|
|
2803
2861
|
return buildCuaBundle({
|
|
2862
|
+
...(args.lab === undefined ? {} : { lab: args.lab }),
|
|
2804
2863
|
actorId: args.descriptor.id,
|
|
2805
2864
|
appUrl: args.appUrl,
|
|
2806
2865
|
laneId: spec.laneId,
|
|
@@ -3606,6 +3665,7 @@ export function buildCuaBundle(args) {
|
|
|
3606
3665
|
createdAt: args.createdAt,
|
|
3607
3666
|
cwd: PUBLIC_TARGET_CWD,
|
|
3608
3667
|
artifactRoot: path.join(".humanish", "runs", args.runId),
|
|
3668
|
+
...(args.lab === undefined ? {} : { lab: args.lab }),
|
|
3609
3669
|
source: args.source,
|
|
3610
3670
|
persona: {
|
|
3611
3671
|
id: args.persona.id,
|
|
@@ -4078,6 +4138,7 @@ export function buildCuaFanoutBundle(args) {
|
|
|
4078
4138
|
createdAt: args.createdAt,
|
|
4079
4139
|
cwd: PUBLIC_TARGET_CWD,
|
|
4080
4140
|
artifactRoot: path.join(".humanish", "runs", args.runId),
|
|
4141
|
+
...(args.lab === undefined ? {} : { lab: args.lab }),
|
|
4081
4142
|
source: args.source,
|
|
4082
4143
|
persona: {
|
|
4083
4144
|
id: specs[0].persona.id,
|