@iamu-dev/iamu 0.2.0-beta.5 → 0.2.0-beta.7
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/bin.js +251 -28
- package/dist/eval/gemini-eval-cli.js +976 -0
- package/dist/index.js +251 -28
- package/dist/templates/prompts/walk.md +16 -4
- package/dist/templates/skills/iamu-new.md +8 -4
- package/dist/templates/skills/iamu-propose.md +1 -2
- package/dist/templates/skills/iamu-run.md +26 -11
- package/dist/templates/skills/iamu-setup.md +79 -62
- package/package.json +6 -3
package/dist/bin.js
CHANGED
|
@@ -200,17 +200,24 @@ function defaultConfig(params) {
|
|
|
200
200
|
cloud_api_url: null
|
|
201
201
|
};
|
|
202
202
|
}
|
|
203
|
-
var baseProjectFields, localOnlyConfig, cloudLinkedConfig, projectConfigSchema;
|
|
203
|
+
var modelTierSchema, projectModelsConfigSchema, baseProjectFields, localOnlyConfig, cloudLinkedConfig, projectConfigSchema;
|
|
204
204
|
var init_config = __esm({
|
|
205
205
|
"../../packages/protocol/dist/schemas/frontmatter/config.js"() {
|
|
206
206
|
"use strict";
|
|
207
207
|
init_common();
|
|
208
208
|
init_version();
|
|
209
|
+
modelTierSchema = z4.string().min(1).max(128).describe("Model role tier ('fast', 'thorough', 'inherit') or a specific model identifier.");
|
|
210
|
+
projectModelsConfigSchema = z4.object({
|
|
211
|
+
walker: modelTierSchema.optional(),
|
|
212
|
+
matcher: modelTierSchema.optional(),
|
|
213
|
+
judge: modelTierSchema.optional()
|
|
214
|
+
}).strict();
|
|
209
215
|
baseProjectFields = {
|
|
210
216
|
schema_version: z4.literal(SCHEMA_VERSION),
|
|
211
217
|
id: uuidSchema,
|
|
212
218
|
project_slug: slugSchema,
|
|
213
|
-
project_name: z4.string().min(1)
|
|
219
|
+
project_name: z4.string().min(1),
|
|
220
|
+
models: projectModelsConfigSchema.optional()
|
|
214
221
|
};
|
|
215
222
|
localOnlyConfig = z4.object({
|
|
216
223
|
...baseProjectFields,
|
|
@@ -817,7 +824,14 @@ var init_scenario = __esm({
|
|
|
817
824
|
reviews: z15.array(z15.string().min(1).max(64)).max(16).default([]),
|
|
818
825
|
baseline_score: z15.number().min(0).max(100).nullish(),
|
|
819
826
|
current_score: z15.number().min(0).max(100).nullish(),
|
|
820
|
-
target_score: z15.number().min(0).max(100).default(95)
|
|
827
|
+
target_score: z15.number().min(0).max(100).default(95),
|
|
828
|
+
/** Environment state preconditions and approximation guidance. */
|
|
829
|
+
state: z15.object({
|
|
830
|
+
/** Description of data/records expected to exist in the environment. */
|
|
831
|
+
description: z15.string().max(2048).nullish(),
|
|
832
|
+
/** Guidance on how to squint or approximate if exact records are absent. */
|
|
833
|
+
approximation: z15.string().max(2048).nullish()
|
|
834
|
+
}).nullish()
|
|
821
835
|
});
|
|
822
836
|
}
|
|
823
837
|
});
|
|
@@ -1154,7 +1168,21 @@ var init_walkthrough_bundle = __esm({
|
|
|
1154
1168
|
judge_prompt: z19.string().optional(),
|
|
1155
1169
|
judge_model: z19.string().optional()
|
|
1156
1170
|
}).optional()
|
|
1157
|
-
}).optional()
|
|
1171
|
+
}).optional(),
|
|
1172
|
+
models: z19.object({
|
|
1173
|
+
walker: z19.string().optional(),
|
|
1174
|
+
matcher: z19.string().optional(),
|
|
1175
|
+
judge: z19.string().optional(),
|
|
1176
|
+
walker_reported: z19.string().optional(),
|
|
1177
|
+
matcher_reported: z19.string().optional(),
|
|
1178
|
+
judge_reported: z19.string().optional(),
|
|
1179
|
+
walker_tier: z19.string().optional(),
|
|
1180
|
+
matcher_tier: z19.string().optional(),
|
|
1181
|
+
judge_tier: z19.string().optional(),
|
|
1182
|
+
execution_mode: z19.enum(["multi_agent", "single_agent"]).optional(),
|
|
1183
|
+
velocity_sec_per_step: z19.number().optional(),
|
|
1184
|
+
total_duration_sec: z19.number().optional()
|
|
1185
|
+
}).optional().describe("AI model configuration and reported runtime provenance for this walkthrough.")
|
|
1158
1186
|
});
|
|
1159
1187
|
walkthroughBundleSchema = z19.object({
|
|
1160
1188
|
manifest: bundleManifestSchema,
|
|
@@ -1377,6 +1405,7 @@ var init_walkthrough_canonical = __esm({
|
|
|
1377
1405
|
build: buildMetadataSchema.optional(),
|
|
1378
1406
|
viewport: runViewportSchema.optional(),
|
|
1379
1407
|
environment: z20.string().optional(),
|
|
1408
|
+
models: z20.record(z20.unknown()).optional(),
|
|
1380
1409
|
findings: z20.array(canonicalFindingSchema),
|
|
1381
1410
|
steps: z20.array(canonicalStepSchema),
|
|
1382
1411
|
human_tests: z20.array(canonicalHumanTestSchema),
|
|
@@ -7248,6 +7277,7 @@ async function buildCanonical(projectRoot, manifest, completedAt, inputs) {
|
|
|
7248
7277
|
...manifest.build ? { build: manifest.build } : {},
|
|
7249
7278
|
...manifest.viewport ? { viewport: manifest.viewport } : {},
|
|
7250
7279
|
...manifest.environment ? { environment: manifest.environment } : {},
|
|
7280
|
+
...manifest.models ? { models: manifest.models } : {},
|
|
7251
7281
|
findings: canonicalFindings,
|
|
7252
7282
|
steps: canonicalSteps,
|
|
7253
7283
|
human_tests: humanTests,
|
|
@@ -7408,6 +7438,20 @@ function renderCanonicalMarkdown(canonical) {
|
|
|
7408
7438
|
lines.push(`- Viewport: ${canonical.viewport.device} (${canonical.viewport.width}\xD7${canonical.viewport.height})`);
|
|
7409
7439
|
}
|
|
7410
7440
|
lines.push(`- Started: ${canonical.provenance.started_at}`, `- Completed: ${canonical.provenance.completed_at}`, `- Walker prompt: ${canonical.provenance.walker_prompt.id}@${canonical.provenance.walker_prompt.version}`, `- Findings: ${canonical.findings.length}`, `- Steps: ${canonical.steps.length}`);
|
|
7441
|
+
const models = canonical.models;
|
|
7442
|
+
if (models) {
|
|
7443
|
+
const parts = [
|
|
7444
|
+
models.walker ? `Walker: ${models.walker}${models.walker_reported ? ` (${models.walker_reported})` : ""}` : "",
|
|
7445
|
+
models.judge ? `Judge: ${models.judge}${models.judge_reported ? ` (${models.judge_reported})` : ""}` : "",
|
|
7446
|
+
models.matcher ? `Matcher: ${models.matcher}` : ""
|
|
7447
|
+
].filter(Boolean);
|
|
7448
|
+
if (parts.length > 0) {
|
|
7449
|
+
lines.push(`- Models: ${parts.join(" \xB7 ")}`);
|
|
7450
|
+
}
|
|
7451
|
+
if (typeof models.velocity_sec_per_step === "number") {
|
|
7452
|
+
lines.push(`- Velocity: ~${models.velocity_sec_per_step}s/step (${models.total_duration_sec}s total)`);
|
|
7453
|
+
}
|
|
7454
|
+
}
|
|
7411
7455
|
const what = canonical.what_worked;
|
|
7412
7456
|
if (what && what.length > 0) {
|
|
7413
7457
|
lines.push("", "## What worked");
|
|
@@ -7777,6 +7821,7 @@ async function assembleWalkthroughBundle(projectRoot, runId) {
|
|
|
7777
7821
|
report_markdown: report3,
|
|
7778
7822
|
verdict: verdictArray,
|
|
7779
7823
|
judge_meta: judgeMeta,
|
|
7824
|
+
...manifest.models ? { models: manifest.models } : {},
|
|
7780
7825
|
...buildFields(manifest),
|
|
7781
7826
|
...await readCanonicalExtras(projectRoot, runId)
|
|
7782
7827
|
},
|
|
@@ -12287,15 +12332,6 @@ function mcpJson(cmd) {
|
|
|
12287
12332
|
2
|
|
12288
12333
|
);
|
|
12289
12334
|
}
|
|
12290
|
-
function vscodeMcpJson(cmd) {
|
|
12291
|
-
return JSON.stringify(
|
|
12292
|
-
{
|
|
12293
|
-
servers: { iamu: { type: "stdio", command: cmd[0], args: cmd.slice(1) } }
|
|
12294
|
-
},
|
|
12295
|
-
null,
|
|
12296
|
-
2
|
|
12297
|
-
);
|
|
12298
|
-
}
|
|
12299
12335
|
function detectHosts(projectRoot) {
|
|
12300
12336
|
return HOST_ADAPTERS.filter(
|
|
12301
12337
|
(host) => host.detectionPaths.some((p) => existsSync3(join3(projectRoot, p)))
|
|
@@ -12344,13 +12380,17 @@ var init_registry = __esm({
|
|
|
12344
12380
|
{
|
|
12345
12381
|
name: "GitHub Copilot",
|
|
12346
12382
|
value: "github-copilot",
|
|
12347
|
-
detectionPaths: [
|
|
12348
|
-
|
|
12349
|
-
|
|
12350
|
-
|
|
12351
|
-
|
|
12352
|
-
|
|
12353
|
-
|
|
12383
|
+
detectionPaths: [
|
|
12384
|
+
".github/copilot-instructions.md",
|
|
12385
|
+
".github/skills",
|
|
12386
|
+
".copilot"
|
|
12387
|
+
],
|
|
12388
|
+
supportsSkills: true,
|
|
12389
|
+
getSkillsDir: (root) => join3(root, ".github", "skills"),
|
|
12390
|
+
getCommandPath: (root, id) => join3(root, ".github", "skills", `iamu-${id}`, "SKILL.md"),
|
|
12391
|
+
formatCommand: richFormat,
|
|
12392
|
+
getMcpConfigPath: (root) => join3(root, ".mcp.json"),
|
|
12393
|
+
formatMcpConfig: mcpJson
|
|
12354
12394
|
},
|
|
12355
12395
|
{
|
|
12356
12396
|
name: "Cline",
|
|
@@ -12532,6 +12572,14 @@ function isCliWrittenSkill(path28) {
|
|
|
12532
12572
|
return false;
|
|
12533
12573
|
}
|
|
12534
12574
|
}
|
|
12575
|
+
function isCliWrittenPrompt(path28) {
|
|
12576
|
+
try {
|
|
12577
|
+
const content = readFileSync3(path28, "utf-8");
|
|
12578
|
+
return content.includes("iamu") || /^generatedBy:/m.test(content);
|
|
12579
|
+
} catch {
|
|
12580
|
+
return false;
|
|
12581
|
+
}
|
|
12582
|
+
}
|
|
12535
12583
|
function planSkillFiles(hosts, projectRoot, version2) {
|
|
12536
12584
|
const skillTemplates = loadSkillTemplates(version2);
|
|
12537
12585
|
const files = [];
|
|
@@ -12560,6 +12608,19 @@ function planSkillFiles(hosts, projectRoot, version2) {
|
|
|
12560
12608
|
}
|
|
12561
12609
|
}
|
|
12562
12610
|
}
|
|
12611
|
+
if (host.value === "github-copilot") {
|
|
12612
|
+
for (const cmd of commandsFromSkills(skillTemplates)) {
|
|
12613
|
+
const legacyPrompt = join4(
|
|
12614
|
+
projectRoot,
|
|
12615
|
+
".github",
|
|
12616
|
+
"prompts",
|
|
12617
|
+
`iamu-${cmd.id}.prompt.md`
|
|
12618
|
+
);
|
|
12619
|
+
if (isCliWrittenPrompt(legacyPrompt)) {
|
|
12620
|
+
files.push({ host, path: legacyPrompt, content: null });
|
|
12621
|
+
}
|
|
12622
|
+
}
|
|
12623
|
+
}
|
|
12563
12624
|
} else {
|
|
12564
12625
|
for (const cmd of commandsFromSkills(skillTemplates)) {
|
|
12565
12626
|
files.push({
|
|
@@ -12584,6 +12645,15 @@ function detectInstalledHosts(projectRoot) {
|
|
|
12584
12645
|
const skillDir = join4(host.getSkillsDir(projectRoot), "iamu-setup");
|
|
12585
12646
|
if (existsSync5(skillDir)) return true;
|
|
12586
12647
|
}
|
|
12648
|
+
if (host.value === "github-copilot") {
|
|
12649
|
+
const legacyPrompt = join4(
|
|
12650
|
+
projectRoot,
|
|
12651
|
+
".github",
|
|
12652
|
+
"prompts",
|
|
12653
|
+
"iamu-setup.prompt.md"
|
|
12654
|
+
);
|
|
12655
|
+
if (existsSync5(legacyPrompt)) return true;
|
|
12656
|
+
}
|
|
12587
12657
|
return false;
|
|
12588
12658
|
});
|
|
12589
12659
|
}
|
|
@@ -14434,6 +14504,18 @@ async function startRun(scenarioSlug, opts) {
|
|
|
14434
14504
|
}
|
|
14435
14505
|
const build = detectBuild({ cwd: projectRoot, label: opts.build });
|
|
14436
14506
|
const environment = resolveEnvironment(opts.env, start2.url);
|
|
14507
|
+
const cfg = await readConfig(projectRoot).catch(() => null);
|
|
14508
|
+
const walker = opts.walker ?? process.env.IAMU_WALKER_MODEL ?? cfg?.models?.walker ?? "fast";
|
|
14509
|
+
const judge = opts.judge ?? process.env.IAMU_JUDGE_MODEL ?? cfg?.models?.judge ?? "thorough";
|
|
14510
|
+
const matcher = opts.matcher ?? process.env.IAMU_MATCHER_MODEL ?? cfg?.models?.matcher ?? "thorough";
|
|
14511
|
+
const models = {
|
|
14512
|
+
walker,
|
|
14513
|
+
judge,
|
|
14514
|
+
matcher,
|
|
14515
|
+
walker_tier: ["fast", "thorough", "inherit"].includes(walker) ? walker : "custom",
|
|
14516
|
+
judge_tier: ["fast", "thorough", "inherit"].includes(judge) ? judge : "custom",
|
|
14517
|
+
matcher_tier: ["fast", "thorough", "inherit"].includes(matcher) ? matcher : "custom"
|
|
14518
|
+
};
|
|
14437
14519
|
let revisit = [];
|
|
14438
14520
|
try {
|
|
14439
14521
|
revisit = await computeRevisitPlaces(projectRoot, scenarioSlug, start2.url);
|
|
@@ -14451,6 +14533,7 @@ async function startRun(scenarioSlug, opts) {
|
|
|
14451
14533
|
status: "running",
|
|
14452
14534
|
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14453
14535
|
completed_at: null,
|
|
14536
|
+
models,
|
|
14454
14537
|
...build ? { build } : {},
|
|
14455
14538
|
...environment ? { environment } : {},
|
|
14456
14539
|
...revisit.length > 0 ? { revisit } : {},
|
|
@@ -14472,6 +14555,7 @@ async function startRun(scenarioSlug, opts) {
|
|
|
14472
14555
|
...targetWarning ? { target_warning: targetWarning } : {},
|
|
14473
14556
|
persona_slug: fm.persona,
|
|
14474
14557
|
outline_slug: fm.outline,
|
|
14558
|
+
models,
|
|
14475
14559
|
build: build ?? null,
|
|
14476
14560
|
environment: environment ?? null,
|
|
14477
14561
|
revisit,
|
|
@@ -14490,6 +14574,9 @@ async function startRun(scenarioSlug, opts) {
|
|
|
14490
14574
|
console.log(` ${chalk11.dim("persona:")} ${fm.persona}`);
|
|
14491
14575
|
console.log(` ${chalk11.dim("outline:")} ${fm.outline}`);
|
|
14492
14576
|
console.log(` ${chalk11.dim("target:")} ${start2.url}`);
|
|
14577
|
+
console.log(
|
|
14578
|
+
` ${chalk11.dim("models:")} walker: ${chalk11.cyan(walker)} \xB7 judge: ${chalk11.cyan(judge)} \xB7 matcher: ${chalk11.cyan(matcher)}`
|
|
14579
|
+
);
|
|
14493
14580
|
if (targetWarning) {
|
|
14494
14581
|
console.log(` ${symbols.warning} ${chalk11.yellow(targetWarning)}`);
|
|
14495
14582
|
}
|
|
@@ -16286,7 +16373,10 @@ var init_browse_actions = __esm({
|
|
|
16286
16373
|
usage: "goto <url>",
|
|
16287
16374
|
minArgs: 1,
|
|
16288
16375
|
run: async (p, args) => {
|
|
16289
|
-
await p.goto(args[0], {
|
|
16376
|
+
await p.goto(args[0], {
|
|
16377
|
+
waitUntil: "domcontentloaded",
|
|
16378
|
+
timeout: 1e4
|
|
16379
|
+
});
|
|
16290
16380
|
}
|
|
16291
16381
|
},
|
|
16292
16382
|
click: {
|
|
@@ -16447,6 +16537,12 @@ var init_browse_driver = __esm({
|
|
|
16447
16537
|
commandLine: (pid) => readProcessCommandLine(pid),
|
|
16448
16538
|
kill(pid) {
|
|
16449
16539
|
try {
|
|
16540
|
+
if (process.platform !== "win32") {
|
|
16541
|
+
try {
|
|
16542
|
+
process.kill(-pid, "SIGTERM");
|
|
16543
|
+
} catch {
|
|
16544
|
+
}
|
|
16545
|
+
}
|
|
16450
16546
|
process.kill(pid, "SIGTERM");
|
|
16451
16547
|
} catch {
|
|
16452
16548
|
}
|
|
@@ -16673,6 +16769,7 @@ __export(browse_exports, {
|
|
|
16673
16769
|
readBrowseState: () => readBrowseState,
|
|
16674
16770
|
shouldDisableSandbox: () => shouldDisableSandbox,
|
|
16675
16771
|
start: () => start,
|
|
16772
|
+
waitForVisualStability: () => waitForVisualStability,
|
|
16676
16773
|
withPage: () => withPage
|
|
16677
16774
|
});
|
|
16678
16775
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
@@ -16822,6 +16919,8 @@ function chromeArgs(opts, port, headless) {
|
|
|
16822
16919
|
`--window-size=${opts.width ?? "1280"},${opts.height ?? "900"}`,
|
|
16823
16920
|
"--no-first-run",
|
|
16824
16921
|
"--no-default-browser-check",
|
|
16922
|
+
"--password-store=basic",
|
|
16923
|
+
"--use-mock-keychain",
|
|
16825
16924
|
...headless ? ["--headless=new", "--disable-dev-shm-usage", "--disable-gpu"] : [],
|
|
16826
16925
|
...shouldDisableSandbox() ? ["--no-sandbox"] : [],
|
|
16827
16926
|
"about:blank"
|
|
@@ -16879,6 +16978,45 @@ async function stop(opts, driver) {
|
|
|
16879
16978
|
}
|
|
16880
16979
|
report2(opts, { stopped: true }, [` ${chalk20.green("\u2713")} Browser stopped`]);
|
|
16881
16980
|
}
|
|
16981
|
+
async function waitForVisualStability(page, maxWaitMs = 300) {
|
|
16982
|
+
let timer;
|
|
16983
|
+
try {
|
|
16984
|
+
const nodeTimeout = new Promise((resolve4) => {
|
|
16985
|
+
timer = setTimeout(resolve4, maxWaitMs + 100);
|
|
16986
|
+
});
|
|
16987
|
+
const browserWait = page.evaluate((maxWait) => {
|
|
16988
|
+
return new Promise((resolve4) => {
|
|
16989
|
+
const timeout = setTimeout(resolve4, maxWait);
|
|
16990
|
+
const done = () => {
|
|
16991
|
+
clearTimeout(timeout);
|
|
16992
|
+
resolve4();
|
|
16993
|
+
};
|
|
16994
|
+
const g = globalThis;
|
|
16995
|
+
if (typeof g.requestAnimationFrame !== "function") {
|
|
16996
|
+
done();
|
|
16997
|
+
return;
|
|
16998
|
+
}
|
|
16999
|
+
g.requestAnimationFrame(() => {
|
|
17000
|
+
g.requestAnimationFrame?.(() => {
|
|
17001
|
+
const animations = g.document?.getAnimations ? g.document.getAnimations().filter((a) => a.playState === "running" && a.finished) : [];
|
|
17002
|
+
if (animations.length === 0) {
|
|
17003
|
+
done();
|
|
17004
|
+
return;
|
|
17005
|
+
}
|
|
17006
|
+
Promise.allSettled(
|
|
17007
|
+
animations.map((a) => a.finished)
|
|
17008
|
+
).finally(done);
|
|
17009
|
+
});
|
|
17010
|
+
});
|
|
17011
|
+
});
|
|
17012
|
+
}, maxWaitMs).catch(() => {
|
|
17013
|
+
});
|
|
17014
|
+
await Promise.race([browserWait, nodeTimeout]);
|
|
17015
|
+
} catch {
|
|
17016
|
+
} finally {
|
|
17017
|
+
if (timer) clearTimeout(timer);
|
|
17018
|
+
}
|
|
17019
|
+
}
|
|
16882
17020
|
async function withPage(opts, driver, fn, target) {
|
|
16883
17021
|
const state = readBrowseState();
|
|
16884
17022
|
if (!state) {
|
|
@@ -16898,9 +17036,9 @@ async function withPage(opts, driver, fn, target) {
|
|
|
16898
17036
|
await fn(page);
|
|
16899
17037
|
await page.waitForLoadState("domcontentloaded").catch(() => {
|
|
16900
17038
|
});
|
|
16901
|
-
await page.waitForTimeout(400);
|
|
16902
17039
|
let screenshot = null;
|
|
16903
17040
|
if (opts.shot) {
|
|
17041
|
+
await waitForVisualStability(page);
|
|
16904
17042
|
screenshot = path22.resolve(opts.shot);
|
|
16905
17043
|
mkdirSync(path22.dirname(screenshot), { recursive: true });
|
|
16906
17044
|
await page.screenshot({ path: screenshot, fullPage: Boolean(opts.full) });
|
|
@@ -18459,13 +18597,21 @@ function defaultFrontmatter(type2, id, slug, name, opts) {
|
|
|
18459
18597
|
url: opts.url,
|
|
18460
18598
|
authority_level: opts.authority ?? "informational"
|
|
18461
18599
|
};
|
|
18462
|
-
case "scenario":
|
|
18600
|
+
case "scenario": {
|
|
18601
|
+
const stateObj = opts.stateDescription || opts.stateApproximation ? {
|
|
18602
|
+
state: {
|
|
18603
|
+
...opts.stateDescription ? { description: opts.stateDescription } : {},
|
|
18604
|
+
...opts.stateApproximation ? { approximation: opts.stateApproximation } : {}
|
|
18605
|
+
}
|
|
18606
|
+
} : {};
|
|
18463
18607
|
return {
|
|
18464
18608
|
...base,
|
|
18465
18609
|
outline: opts.outline ?? null,
|
|
18466
18610
|
persona: opts.persona ?? null,
|
|
18467
|
-
...opts.entry ? { entry_path: opts.entry } : {}
|
|
18611
|
+
...opts.entry ? { entry_path: opts.entry } : {},
|
|
18612
|
+
...stateObj
|
|
18468
18613
|
};
|
|
18614
|
+
}
|
|
18469
18615
|
default:
|
|
18470
18616
|
return base;
|
|
18471
18617
|
}
|
|
@@ -18859,6 +19005,17 @@ function composeWalkerPrompt(p) {
|
|
|
18859
19005
|
"",
|
|
18860
19006
|
"## First-person brief",
|
|
18861
19007
|
p.brief ?? "",
|
|
19008
|
+
...p.context ? ["", "## Product domain & regulatory context", p.context.trim()] : [],
|
|
19009
|
+
...p.state?.description || p.state?.approximation ? [
|
|
19010
|
+
"",
|
|
19011
|
+
"## Expected state & semantic squinting",
|
|
19012
|
+
p.state.description ? `Expected state: ${p.state.description}` : "",
|
|
19013
|
+
p.state.approximation ? `Approximation strategy: ${p.state.approximation}` : "",
|
|
19014
|
+
"Squinting Guardrails:",
|
|
19015
|
+
"\u2022 If the exact target record/option is not available, apply the approximation strategy above to pick the closest plausible entity within the domain flow.",
|
|
19016
|
+
"\u2022 Squinting does NOT permit drifting to unrelated settings, account profiles, or off-target pages. Stay strictly within the scenario journey.",
|
|
19017
|
+
"\u2022 If the system is completely empty or unseeded, and your persona role cannot create data, do NOT report false product bugs about the empty state. Note that preconditions are unseeded/blocked."
|
|
19018
|
+
].filter(Boolean) : [],
|
|
18862
19019
|
...revisitSection(p.revisit ?? []),
|
|
18863
19020
|
"",
|
|
18864
19021
|
"## Access",
|
|
@@ -18887,7 +19044,7 @@ function composeWalkerPrompt(p) {
|
|
|
18887
19044
|
`Screenshots to: ${rd}/screenshots/step-N.png \u2014 absolute paths.`,
|
|
18888
19045
|
`Record findings with: ${iamu} new-finding --scenario ${p.scenarioSlug} --run ${p.runId} --step <N> --title "..." --type <helps|hinders|missing|irrelevant|incorrect> --severity <critical|major|minor|observation> --ui-fact "..." --consequence "..." --task-impact <blocks|impairs|slows|neutral|accelerates|enables> --confidence <high|medium|low> --json \u2014 then add the body (description + "## Recommendation") below the frontmatter of the file it returns.`,
|
|
18889
19046
|
"`--step <N>` is the step whose screenshot shows the problem (or strength): it is the evidence people see next to the finding, so record that step and its screenshot first, and pick the screenshot where the thing is actually visible.",
|
|
18890
|
-
`Before you finish, write ${rd}/summary.json: {"what_worked": [...], "open_questions": [...]} \u2014 one sentence each, in the persona's language.`,
|
|
19047
|
+
`Before you finish, write ${rd}/summary.json: {"what_worked": [...], "open_questions": [...], "model": "<your model identifier if known, e.g. claude-3-5-haiku, gemini-3.8-flash, or unspecified>"} \u2014 one sentence each, in the persona's language.`,
|
|
18891
19048
|
"",
|
|
18892
19049
|
"Do not read the product's source code, other iamu/ entity files, or earlier runs: you know only what the persona knows.",
|
|
18893
19050
|
"",
|
|
@@ -19007,7 +19164,8 @@ async function instructionsWalk(opts) {
|
|
|
19007
19164
|
const result = {
|
|
19008
19165
|
scenario: {
|
|
19009
19166
|
slug: sfm.slug,
|
|
19010
|
-
brief: scenario.body.trim() || null
|
|
19167
|
+
brief: scenario.body.trim() || null,
|
|
19168
|
+
state: sfm.state ?? null
|
|
19011
19169
|
},
|
|
19012
19170
|
persona: {
|
|
19013
19171
|
slug: sfm.persona,
|
|
@@ -19061,7 +19219,9 @@ async function instructionsWalk(opts) {
|
|
|
19061
19219
|
runDirPath,
|
|
19062
19220
|
projectRoot,
|
|
19063
19221
|
surface: opts.surface ?? "browse",
|
|
19064
|
-
viewport
|
|
19222
|
+
viewport,
|
|
19223
|
+
state: sfm.state ?? null,
|
|
19224
|
+
context: contextYml
|
|
19065
19225
|
}) : null
|
|
19066
19226
|
};
|
|
19067
19227
|
if (opts.json) {
|
|
@@ -19073,6 +19233,11 @@ async function instructionsWalk(opts) {
|
|
|
19073
19233
|
console.log(` ${chalk26.dim("scenario:")} ${sfm.slug}`);
|
|
19074
19234
|
console.log(` ${chalk26.dim("persona:")} ${pfm.name} (${pfm.role})`);
|
|
19075
19235
|
console.log(` ${chalk26.dim("outline:")} ${ofm.title}`);
|
|
19236
|
+
if (sfm.state?.description || sfm.state?.approximation) {
|
|
19237
|
+
console.log(
|
|
19238
|
+
` ${chalk26.dim("state:")} ${sfm.state.description ? sfm.state.description : sfm.state.approximation ?? ""}`
|
|
19239
|
+
);
|
|
19240
|
+
}
|
|
19076
19241
|
if (targetUrl) console.log(` ${chalk26.dim("target:")} ${targetUrl}`);
|
|
19077
19242
|
console.log(
|
|
19078
19243
|
` ${chalk26.dim("access:")} ${projectAccess || personaAccess ? `${projectAccess ? "project" : ""}${projectAccess && personaAccess ? " + " : ""}${personaAccess ? "persona" : ""}` : "not recorded (walker would run as whoever is signed in)"}`
|
|
@@ -19709,6 +19874,36 @@ async function complete(runId, opts) {
|
|
|
19709
19874
|
return;
|
|
19710
19875
|
}
|
|
19711
19876
|
const completedAt = pickCompletedAt(run.manifest);
|
|
19877
|
+
const walkerSummary = await readWalkerSummary(run.runDirPath);
|
|
19878
|
+
let judgeReported;
|
|
19879
|
+
try {
|
|
19880
|
+
const verdictsRaw = await fs26.readFile(
|
|
19881
|
+
path26.join(run.runDirPath, "verdicts.json"),
|
|
19882
|
+
"utf8"
|
|
19883
|
+
);
|
|
19884
|
+
const parsed = JSON.parse(verdictsRaw);
|
|
19885
|
+
if (parsed.provenance?.model) {
|
|
19886
|
+
judgeReported = parsed.provenance.model;
|
|
19887
|
+
}
|
|
19888
|
+
} catch {
|
|
19889
|
+
}
|
|
19890
|
+
const stepCount = provenanceAudit.step_count;
|
|
19891
|
+
const durationSec = provenanceAudit.duration_seconds ?? (run.manifest.created_at && Date.parse(completedAt) > Date.parse(run.manifest.created_at) ? Math.round(
|
|
19892
|
+
(Date.parse(completedAt) - Date.parse(run.manifest.created_at)) / 1e3 * 10
|
|
19893
|
+
) / 10 : null);
|
|
19894
|
+
const velocitySec = provenanceAudit.avg_step_interval_seconds ?? (durationSec != null && stepCount > 1 ? Math.round(durationSec / (stepCount - 1) * 10) / 10 : null);
|
|
19895
|
+
const existingModels = run.manifest.models ?? {};
|
|
19896
|
+
const updatedModels = {
|
|
19897
|
+
...existingModels,
|
|
19898
|
+
...walkerSummary.model ? { walker_reported: walkerSummary.model } : {},
|
|
19899
|
+
...judgeReported ? { judge_reported: judgeReported } : {},
|
|
19900
|
+
...durationSec != null ? { total_duration_sec: durationSec } : {},
|
|
19901
|
+
...velocitySec != null ? { velocity_sec_per_step: velocitySec } : {}
|
|
19902
|
+
};
|
|
19903
|
+
run.manifest = {
|
|
19904
|
+
...run.manifest,
|
|
19905
|
+
models: updatedModels
|
|
19906
|
+
};
|
|
19712
19907
|
const assembled = await assembleRun(
|
|
19713
19908
|
run.projectRoot,
|
|
19714
19909
|
runId,
|
|
@@ -19869,6 +20064,17 @@ function printCompletionSummary(run, completedAt, assembled, extras, provenanceA
|
|
|
19869
20064
|
console.log(` steps ${count(canonical.steps.length)}`);
|
|
19870
20065
|
console.log(` started ${chalk30.dim(manifest.created_at)}`);
|
|
19871
20066
|
console.log(` completed ${chalk30.dim(completedAt)}`);
|
|
20067
|
+
const models = manifest.models;
|
|
20068
|
+
if (models?.velocity_sec_per_step != null) {
|
|
20069
|
+
console.log(
|
|
20070
|
+
` velocity ${chalk30.cyan(`~${models.velocity_sec_per_step}s/step`)} ${chalk30.dim(`(${models.total_duration_sec}s total)`)}`
|
|
20071
|
+
);
|
|
20072
|
+
}
|
|
20073
|
+
if (models && (models.walker || models.judge || models.matcher)) {
|
|
20074
|
+
const w = models.walker_reported ? `${models.walker} (${models.walker_reported})` : models.walker ?? "fast";
|
|
20075
|
+
const j = models.judge_reported ? `${models.judge} (${models.judge_reported})` : models.judge ?? "thorough";
|
|
20076
|
+
console.log(` models ${chalk30.dim(`walker: ${w} \xB7 judge: ${j}`)}`);
|
|
20077
|
+
}
|
|
19872
20078
|
console.log();
|
|
19873
20079
|
console.log(
|
|
19874
20080
|
` ${chalk30.dim("canonical:")} ${chalk30.dim(path26.relative(projectRoot, assembled.canonicalPath))}`
|
|
@@ -19962,9 +20168,11 @@ async function readWalkerSummary(runDirPath) {
|
|
|
19962
20168
|
await fs26.readFile(path26.join(runDirPath, "summary.json"), "utf8")
|
|
19963
20169
|
);
|
|
19964
20170
|
const strings = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string" && x.trim() !== "") : void 0;
|
|
20171
|
+
const model = typeof data.model === "string" && data.model.trim() !== "" ? data.model.trim() : void 0;
|
|
19965
20172
|
return {
|
|
19966
20173
|
what_worked: strings(data.what_worked),
|
|
19967
|
-
open_questions: strings(data.open_questions)
|
|
20174
|
+
open_questions: strings(data.open_questions),
|
|
20175
|
+
model
|
|
19968
20176
|
};
|
|
19969
20177
|
} catch {
|
|
19970
20178
|
return {};
|
|
@@ -20713,6 +20921,12 @@ function registerProjectCommands(program2) {
|
|
|
20713
20921
|
).option("--outline <slug>", "Outline slug (scenario only)").option("--persona <slug>", "Persona slug (scenario only)").option(
|
|
20714
20922
|
"--entry <path>",
|
|
20715
20923
|
"Where the situation starts, as a path on the product, e.g. /en/episodes/1 (scenario only)"
|
|
20924
|
+
).option(
|
|
20925
|
+
"--state-description <text>",
|
|
20926
|
+
"Assumed environment data/records state (scenario only)"
|
|
20927
|
+
).option(
|
|
20928
|
+
"--state-approximation <text>",
|
|
20929
|
+
"Guidance on how persona should approximate/squint if records are missing (scenario only)"
|
|
20716
20930
|
).option("--url <url>", "Document the source cites (source only, required)").option(
|
|
20717
20931
|
"--authority <level>",
|
|
20718
20932
|
"legislation | regulation | standard | company_policy | guideline | informational (source only, default informational)"
|
|
@@ -20754,6 +20968,15 @@ function registerWalkthroughCommands(program2) {
|
|
|
20754
20968
|
).option(
|
|
20755
20969
|
"--env <name>",
|
|
20756
20970
|
"Environment the product runs in (default: the target URL's origin)"
|
|
20971
|
+
).option(
|
|
20972
|
+
"--walker <tierOrModel>",
|
|
20973
|
+
"Model tier ('fast', 'thorough', 'inherit') or model ID for driving browser navigation (default: fast)"
|
|
20974
|
+
).option(
|
|
20975
|
+
"--judge <tierOrModel>",
|
|
20976
|
+
"Model tier ('fast', 'thorough', 'inherit') or model ID for human test evaluation (default: thorough)"
|
|
20977
|
+
).option(
|
|
20978
|
+
"--matcher <tierOrModel>",
|
|
20979
|
+
"Model tier ('fast', 'thorough', 'inherit') or model ID for finding matching (default: thorough)"
|
|
20757
20980
|
).option(
|
|
20758
20981
|
"--check",
|
|
20759
20982
|
"Enforce target URL reachability (fail fast if server is offline)"
|