humanish 0.32.0 → 0.34.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/adapter-extension.d.ts +24 -2
- package/dist/adapter-extension.js +64 -7
- package/dist/adapter-extension.js.map +1 -1
- package/dist/adapter-scorer-loader.d.ts +42 -0
- package/dist/adapter-scorer-loader.js +129 -0
- package/dist/adapter-scorer-loader.js.map +1 -0
- package/dist/concurrent-shared-world-lab.d.ts +4 -1
- package/dist/concurrent-shared-world-lab.js +4 -3
- package/dist/concurrent-shared-world-lab.js.map +1 -1
- package/dist/cua-actor-lab.d.ts +4 -1
- package/dist/cua-actor-lab.js +4 -3
- package/dist/cua-actor-lab.js.map +1 -1
- package/dist/e2b-terminal-lab.d.ts +17 -1
- package/dist/e2b-terminal-lab.js +57 -12
- package/dist/e2b-terminal-lab.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js.map +1 -1
- package/dist/lab-config.d.ts +9 -0
- package/dist/lab-config.js +47 -8
- package/dist/lab-config.js.map +1 -1
- package/dist/lab-engine.d.ts +8 -1
- package/dist/lab-engine.js +8 -4
- package/dist/lab-engine.js.map +1 -1
- package/dist/pricing.js +17 -12
- package/dist/pricing.js.map +1 -1
- package/dist/program.js +76 -7
- package/dist/program.js.map +1 -1
- package/dist/run.d.ts +29 -1
- package/dist/run.js +20 -0
- package/dist/run.js.map +1 -1
- package/dist/shared-world-lab.d.ts +4 -1
- package/dist/shared-world-lab.js +4 -3
- package/dist/shared-world-lab.js.map +1 -1
- package/docs/contracts/schemas.md +7 -2
- package/docs/goals/current.md +23 -7
- package/docs/ramp/README.md +13 -1
- package/package.json +1 -1
package/dist/program.js
CHANGED
|
@@ -11,6 +11,7 @@ import { runInit } from "./init.js";
|
|
|
11
11
|
import { inspectLabManifest, listLabManifests, resolveLabManifest } from "./labs.js";
|
|
12
12
|
import { runLabPreflight } from "./lab-preflight.js";
|
|
13
13
|
import { runLab, resolveLabDryRun, selectLabBackend } from "./lab-engine.js";
|
|
14
|
+
import { loadAdapterScorer } from "./adapter-scorer-loader.js";
|
|
14
15
|
import { CUA_ACTOR_LAB_SCHEMA } from "./cua-actor-lab.js";
|
|
15
16
|
import { openTarget, renderObserver, serveObserver } from "./observer.js";
|
|
16
17
|
import { serveObserverStatic } from "./observer-static.js";
|
|
@@ -481,6 +482,7 @@ function registerWatchCommand(parent, io) {
|
|
|
481
482
|
.option("--redact-repos", "Lab only: redact repo labels in durable artifacts.")
|
|
482
483
|
.option("--no-redact-repos", "Lab only: persist repo labels. Use only for public-safe runs.")
|
|
483
484
|
.option("--keep", "Lab only: keep disposable clone sandbox for debugging.")
|
|
485
|
+
.option("--scorer <path>", "Terminal/computer-use/shared-world labs only: repo-relative adopter scorer module (.mjs). Overrides review.scorer.ref. Executable code — review it as code.")
|
|
484
486
|
.option("--run-id <id>", "Explicit run id for deterministic fixture tests.")
|
|
485
487
|
.option("--cwd <path>", "Target project directory.", ".")
|
|
486
488
|
.option("--env-file <path>", "Load a local env file for this watch without persisting values.")
|
|
@@ -574,6 +576,7 @@ function registerWatchCommand(parent, io) {
|
|
|
574
576
|
repo: options.repo,
|
|
575
577
|
...(options.repos === undefined ? {} : { repos: options.repos }),
|
|
576
578
|
...(options.runId === undefined ? {} : { runId: options.runId }),
|
|
579
|
+
...(options.scorer === undefined ? {} : { scorer: options.scorer }),
|
|
577
580
|
...(options.sims === undefined ? {} : { sims: options.sims }),
|
|
578
581
|
...(options.expose === undefined ? {} : { expose: options.expose }),
|
|
579
582
|
...(options.tunnel === undefined ? {} : { tunnel: options.tunnel }),
|
|
@@ -1238,6 +1241,7 @@ function registerLabCommands(parent, io) {
|
|
|
1238
1241
|
.option("--redact-repos", "Meta only: redact repo labels in durable lab artifacts.")
|
|
1239
1242
|
.option("--no-redact-repos", "Meta only: persist repo labels in durable lab artifacts. Use only for public-safe runs.")
|
|
1240
1243
|
.option("--keep", "Smoke labs only: keep disposable clone sandbox for debugging.")
|
|
1244
|
+
.option("--scorer <path>", "Terminal/computer-use/shared-world labs only: repo-relative adopter scorer module (.mjs). Overrides review.scorer.ref. Executable code — review it as code.")
|
|
1241
1245
|
.option("--json", JSON_OPTION_DESCRIPTION)
|
|
1242
1246
|
.addHelpText("after", [
|
|
1243
1247
|
"",
|
|
@@ -1245,6 +1249,7 @@ function registerLabCommands(parent, io) {
|
|
|
1245
1249
|
" humanish lab run first-run",
|
|
1246
1250
|
" humanish lab run fanout-demo --rerun-failed-from latest --lanes lane-02,lane-04",
|
|
1247
1251
|
" humanish lab run oss --dry-run --json --no-open",
|
|
1252
|
+
" humanish lab run my-terminal-lab --scorer scorers/product.mjs",
|
|
1248
1253
|
" humanish lab run .humanish/labs/private-dogfood.yaml --env-file .humanish/local/provider.env",
|
|
1249
1254
|
"",
|
|
1250
1255
|
"Human watch path:",
|
|
@@ -1473,6 +1478,39 @@ async function runOssSmokeAction(args) {
|
|
|
1473
1478
|
writeResult(args.command, args.io, result, formatOssLabHuman);
|
|
1474
1479
|
args.io.setExitCode(result.ok ? 0 : 2);
|
|
1475
1480
|
}
|
|
1481
|
+
/**
|
|
1482
|
+
* Resolve `review.scorer.ref` (or the `--scorer` override) to a loaded adopter scorer, fail-closed
|
|
1483
|
+
* (typed error) PRE-SPEND. Precedence: CLI `--scorer` overrides the manifest; `source` records which
|
|
1484
|
+
* won. No scorer declared → `{ ok: true }` with no scorer. A declared scorer on an unsupported
|
|
1485
|
+
* backend, or a bad/unreadable/broken ref, → `{ ok: false }` so the caller aborts with exit 2.
|
|
1486
|
+
*/
|
|
1487
|
+
async function maybeLoadAdapterScorer(args) {
|
|
1488
|
+
const ref = args.flag ?? args.config.review?.scorer?.ref;
|
|
1489
|
+
if (ref === undefined)
|
|
1490
|
+
return { ok: true };
|
|
1491
|
+
const source = args.flag !== undefined ? "cli-flag" : "manifest";
|
|
1492
|
+
const loaded = await loadAdapterScorer({ cwd: args.cwd, ref, backend: args.backend, source });
|
|
1493
|
+
if (!loaded.ok)
|
|
1494
|
+
return { ok: false, error: loaded.error };
|
|
1495
|
+
return { ok: true, scorer: { hooks: loaded.hooks, provenance: loaded.provenance } };
|
|
1496
|
+
}
|
|
1497
|
+
/** Terminal route hooks bag from a loaded scorer (deriveArtifacts is browser-only, dropped here). */
|
|
1498
|
+
function terminalScorerHooks(scorer) {
|
|
1499
|
+
const { hooks } = scorer;
|
|
1500
|
+
return {
|
|
1501
|
+
...(hooks.score ? { score: hooks.score } : {}),
|
|
1502
|
+
...(hooks.deriveFeedback ? { deriveFeedback: hooks.deriveFeedback } : {})
|
|
1503
|
+
};
|
|
1504
|
+
}
|
|
1505
|
+
/** Browser route hooks bag from a loaded scorer (score + deriveFeedback + deriveArtifacts). */
|
|
1506
|
+
function browserScorerHooks(scorer) {
|
|
1507
|
+
const { hooks } = scorer;
|
|
1508
|
+
return {
|
|
1509
|
+
...(hooks.score ? { score: hooks.score } : {}),
|
|
1510
|
+
...(hooks.deriveFeedback ? { deriveFeedback: hooks.deriveFeedback } : {}),
|
|
1511
|
+
...(hooks.deriveArtifacts ? { deriveArtifacts: hooks.deriveArtifacts } : {})
|
|
1512
|
+
};
|
|
1513
|
+
}
|
|
1476
1514
|
async function runLabCommand(args) {
|
|
1477
1515
|
const resolved = await resolveLabManifest(args.options.cwd, args.lab);
|
|
1478
1516
|
if (!resolved.ok) {
|
|
@@ -1508,6 +1546,33 @@ async function runLabCommand(args) {
|
|
|
1508
1546
|
args.io.setExitCode(2);
|
|
1509
1547
|
return;
|
|
1510
1548
|
}
|
|
1549
|
+
// #316: resolve + load a config-declared/CLI-flagged adopter scorer FAIL-CLOSED, before any spend.
|
|
1550
|
+
// A declared gate that cannot load (bad ref, not found, load failure, no hooks, unsupported backend)
|
|
1551
|
+
// aborts with exit 2 rather than green-passing.
|
|
1552
|
+
const scorerLoad = await maybeLoadAdapterScorer({
|
|
1553
|
+
cwd: args.options.cwd,
|
|
1554
|
+
config,
|
|
1555
|
+
backend,
|
|
1556
|
+
flag: args.options.scorer
|
|
1557
|
+
});
|
|
1558
|
+
if (!scorerLoad.ok) {
|
|
1559
|
+
const result = {
|
|
1560
|
+
schema: "humanish.run-result.v1",
|
|
1561
|
+
ok: false,
|
|
1562
|
+
cwd: resolve(args.options.cwd),
|
|
1563
|
+
warnings: [],
|
|
1564
|
+
error: scorerLoad.error
|
|
1565
|
+
};
|
|
1566
|
+
writeResult(args.command, args.io, result, formatRunHuman);
|
|
1567
|
+
args.io.setExitCode(2);
|
|
1568
|
+
return;
|
|
1569
|
+
}
|
|
1570
|
+
const scorer = scorerLoad.scorer;
|
|
1571
|
+
if (scorer) {
|
|
1572
|
+
// Cross-repo guardrail: `humanish lab run` now import()s host JS named in the manifest. Surface it
|
|
1573
|
+
// visibly so the invoker (who may not be the manifest author) knows executable code just ran.
|
|
1574
|
+
args.io.writeErr(`warning: review scorer ${scorer.provenance.ref} (${scorer.provenance.source}) is executable host code loaded and run in-process — review it as code, not config.\n`);
|
|
1575
|
+
}
|
|
1511
1576
|
switch (backend) {
|
|
1512
1577
|
case "synthetic":
|
|
1513
1578
|
await runSyntheticBackend({ ...args, config });
|
|
@@ -1519,19 +1584,19 @@ async function runLabCommand(args) {
|
|
|
1519
1584
|
await runSmokeBackend({ ...args, config });
|
|
1520
1585
|
return;
|
|
1521
1586
|
case "cua":
|
|
1522
|
-
await runCuaBackend({ ...args, config });
|
|
1587
|
+
await runCuaBackend({ ...args, config, ...(scorer ? { scorer } : {}) });
|
|
1523
1588
|
return;
|
|
1524
1589
|
case "scripted":
|
|
1525
1590
|
await runScriptedBackend({ ...args, config });
|
|
1526
1591
|
return;
|
|
1527
1592
|
case "terminal":
|
|
1528
|
-
await runTerminalBackend({ ...args, config });
|
|
1593
|
+
await runTerminalBackend({ ...args, config, ...(scorer ? { scorer } : {}) });
|
|
1529
1594
|
return;
|
|
1530
1595
|
case "shared-world":
|
|
1531
|
-
await runSharedWorldBackend({ ...args, config });
|
|
1596
|
+
await runSharedWorldBackend({ ...args, config, ...(scorer ? { scorer } : {}) });
|
|
1532
1597
|
return;
|
|
1533
1598
|
case "concurrent-shared-world":
|
|
1534
|
-
await runConcurrentSharedWorldBackend({ ...args, config });
|
|
1599
|
+
await runConcurrentSharedWorldBackend({ ...args, config, ...(scorer ? { scorer } : {}) });
|
|
1535
1600
|
return;
|
|
1536
1601
|
default:
|
|
1537
1602
|
// Compile-time exhaustiveness: a future backend must be handled here, not silently no-op.
|
|
@@ -1718,6 +1783,7 @@ async function runCuaBackend(args) {
|
|
|
1718
1783
|
}
|
|
1719
1784
|
: {}),
|
|
1720
1785
|
...(args.options.runId === undefined ? {} : { runId: args.options.runId }),
|
|
1786
|
+
...(args.scorer ? { cuaHooks: browserScorerHooks(args.scorer), scorerProvenance: args.scorer.provenance } : {}),
|
|
1721
1787
|
...(args.options.rerunFailedFrom === undefined
|
|
1722
1788
|
? {}
|
|
1723
1789
|
: {
|
|
@@ -1853,7 +1919,8 @@ async function runTerminalBackend(args) {
|
|
|
1853
1919
|
cwd: args.options.cwd,
|
|
1854
1920
|
open: args.mode === "watch" ? false : shouldOpen,
|
|
1855
1921
|
...(args.options.dryRun === undefined ? {} : { dryRun: args.options.dryRun }),
|
|
1856
|
-
...(args.options.runId === undefined ? {} : { runId: args.options.runId })
|
|
1922
|
+
...(args.options.runId === undefined ? {} : { runId: args.options.runId }),
|
|
1923
|
+
...(args.scorer ? { terminalHooks: terminalScorerHooks(args.scorer), scorerProvenance: args.scorer.provenance } : {})
|
|
1857
1924
|
});
|
|
1858
1925
|
if (outcome.backend !== "terminal") {
|
|
1859
1926
|
throw new Error(`Expected terminal backend, got ${outcome.backend}.`);
|
|
@@ -1885,7 +1952,8 @@ async function runSharedWorldBackend(args) {
|
|
|
1885
1952
|
cwd: args.options.cwd,
|
|
1886
1953
|
open: args.mode === "watch" ? false : shouldOpen,
|
|
1887
1954
|
...(args.options.dryRun === undefined ? {} : { dryRun: args.options.dryRun }),
|
|
1888
|
-
...(args.options.runId === undefined ? {} : { runId: args.options.runId })
|
|
1955
|
+
...(args.options.runId === undefined ? {} : { runId: args.options.runId }),
|
|
1956
|
+
...(args.scorer ? { sharedWorldHooks: browserScorerHooks(args.scorer), scorerProvenance: args.scorer.provenance } : {})
|
|
1889
1957
|
});
|
|
1890
1958
|
if (outcome.backend !== "shared-world") {
|
|
1891
1959
|
throw new Error(`Expected shared-world backend, got ${outcome.backend}.`);
|
|
@@ -1975,7 +2043,8 @@ async function runConcurrentSharedWorldBackend(args) {
|
|
|
1975
2043
|
}
|
|
1976
2044
|
}
|
|
1977
2045
|
: {}),
|
|
1978
|
-
...(args.options.runId === undefined ? {} : { runId: args.options.runId })
|
|
2046
|
+
...(args.options.runId === undefined ? {} : { runId: args.options.runId }),
|
|
2047
|
+
...(args.scorer ? { sharedWorldHooks: browserScorerHooks(args.scorer), scorerProvenance: args.scorer.provenance } : {})
|
|
1979
2048
|
});
|
|
1980
2049
|
}
|
|
1981
2050
|
catch (error) {
|