@iamu-dev/iamu 0.8.0-beta.2 → 0.8.0-beta.4

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.
Files changed (37) hide show
  1. package/README.md +33 -5
  2. package/dist/adapters/registry.d.ts +6 -0
  3. package/dist/adapters/types.d.ts +22 -5
  4. package/dist/bin.js +7267 -4650
  5. package/dist/build-hash.txt +1 -0
  6. package/dist/commands/advise.d.ts +13 -1
  7. package/dist/commands/browse-driver.d.ts +14 -0
  8. package/dist/commands/browse.d.ts +70 -6
  9. package/dist/commands/complete.d.ts +37 -2
  10. package/dist/commands/context.d.ts +16 -0
  11. package/dist/commands/doctor.d.ts +2 -0
  12. package/dist/commands/explore-crawl.d.ts +5 -2
  13. package/dist/commands/init.d.ts +8 -2
  14. package/dist/commands/instructions.d.ts +0 -15
  15. package/dist/commands/match.d.ts +6 -0
  16. package/dist/commands/mcp-config.d.ts +84 -6
  17. package/dist/commands/new-entity.d.ts +28 -0
  18. package/dist/commands/post-walk.d.ts +21 -0
  19. package/dist/commands/pull.d.ts +1 -0
  20. package/dist/commands/set-entity.d.ts +2 -0
  21. package/dist/commands/skills.d.ts +13 -4
  22. package/dist/commands/step-numbering.d.ts +2 -1
  23. package/dist/commands/step.d.ts +2 -0
  24. package/dist/commands/triage.d.ts +4 -2
  25. package/dist/index.js +7254 -4639
  26. package/dist/templates/prompts/advise.md +8 -61
  27. package/dist/templates/prompts/design-review.md +1 -1
  28. package/dist/templates/prompts/designer.md +11 -4
  29. package/dist/templates/prompts/walk.md +6 -0
  30. package/dist/templates/skills/iamu-design.md +1 -1
  31. package/dist/templates/skills/iamu-findings.md +13 -24
  32. package/dist/templates/skills/iamu-new.md +14 -4
  33. package/dist/templates/skills/iamu-run.md +68 -33
  34. package/dist/templates/skills/iamu-setup.md +7 -1
  35. package/dist/templates/skills/iamu-stage.md +4 -4
  36. package/dist/ui/html-report.d.ts +5 -0
  37. package/package.json +3 -3
@@ -0,0 +1 @@
1
+ 980ee020a59c102f2f0d2f0ef16724675221c36b6c7f818d034b8f971b6fd4e1
@@ -1,7 +1,19 @@
1
1
  /** Stamped into `advised_by` and `advice.json`. Bump when advise.md changes meaningfully. */
2
- export declare const ADVISOR_VERSION = "1.5.0";
2
+ export declare const ADVISOR_VERSION = "1.6.0";
3
3
  /** The installed `iamu/.prompts/advise.md`, or the bundled template. */
4
4
  export declare function readAdvisePrompt(projectRoot: string): string;
5
+ /** Over this many characters, `iamu advise` warns that a host may cut the prompt. */
6
+ export declare const ADVISE_PROMPT_WARN_CHARS = 40000;
7
+ /**
8
+ * The closing "Output JSON schema (strict)" section for a bundle's mode.
9
+ * It ends the prompt so a host that cuts a long prompt in the middle
10
+ * never hides the answer's shape. A project synthesis asks only for
11
+ * directions, observations and design proposals.
12
+ *
13
+ * @example
14
+ * answerSchemaFooter("project"); // "## Output JSON schema (strict)\n\n…"
15
+ */
16
+ export declare function answerSchemaFooter(mode: "run" | "project"): string;
5
17
  export interface AdviseOptions {
6
18
  run?: string;
7
19
  project?: boolean;
@@ -46,7 +46,21 @@ export interface BrowserDriver {
46
46
  kill(pid: number, signal?: NodeJS.Signals | number): void;
47
47
  /** Is `pid` still alive in the OS process table? */
48
48
  alive?(pid: number): boolean;
49
+ /** A free port for a new browser's CDP; defaults to asking the OS. */
50
+ freePort?(): Promise<number>;
49
51
  }
52
+ /**
53
+ * `promise`, or a rejection naming `what` once `ms` pass — for page calls
54
+ * Playwright gives no timeout of their own (`evaluate`, `title`).
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * const title = await bounded(page.title(), 15_000, "The page title");
59
+ * ```
60
+ *
61
+ * @public
62
+ */
63
+ export declare function bounded<T>(promise: Promise<T>, ms: number, what: string): Promise<T>;
50
64
  /** How long a CDP liveness probe may take before the port counts as dead. */
51
65
  export declare const CDP_PROBE_TIMEOUT_MS = 1000;
52
66
  /**
@@ -37,20 +37,51 @@ interface BrowseState {
37
37
  pid?: number;
38
38
  headless?: boolean;
39
39
  activeTabIndex?: number;
40
+ /** The run this browser belongs to; absent when started without one. */
41
+ run?: string;
42
+ /** That run's project root, to tell whether it is still being walked. */
43
+ project?: string;
40
44
  }
41
45
  /**
42
- * The state `iamu browse start` left in `~/.iamu/browse/state.json`, or
43
- * null when no browser was started (or the file is unreadable).
46
+ * The state `iamu browse start` left for this run
47
+ * (`~/.iamu/browse/<run-id>.json`), else the one a browser started
48
+ * without a run left (`state.json`), or null when there is none.
49
+ *
50
+ * @param run - Run id; omitted, only the shared state is read.
44
51
  *
45
52
  * @example
46
53
  * ```ts
47
- * const state = readBrowseState();
54
+ * const state = readBrowseState(runId);
48
55
  * if (state) console.log(`CDP on :${state.port}`);
49
56
  * ```
50
57
  *
51
58
  * @public
52
59
  */
53
- export declare function readBrowseState(): BrowseState | null;
60
+ export declare function readBrowseState(run?: string | null): BrowseState | null;
61
+ /**
62
+ * Every browse state on this machine, one per browser `start` recorded
63
+ * (per run, plus the shared one).
64
+ *
65
+ * @example
66
+ * ```ts
67
+ * for (const s of listBrowseStates()) console.log(s.run ?? "-", s.port);
68
+ * ```
69
+ *
70
+ * @public
71
+ */
72
+ export declare function listBrowseStates(): BrowseState[];
73
+ /**
74
+ * A port nothing listens on right now: the one the OS hands out for
75
+ * port 0.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * const port = await pickFreePort();
80
+ * ```
81
+ *
82
+ * @public
83
+ */
84
+ export declare function pickFreePort(): Promise<number>;
54
85
  /**
55
86
  * Parse `"390x844"` into a size.
56
87
  *
@@ -169,8 +200,21 @@ export declare function computePageFingerprint(url: string, bodySnippet: string)
169
200
  /**
170
201
  * Track page state across consecutive steps in a run.
171
202
  * Emits a warning when 3 consecutive steps produce zero observable URL/DOM transition.
203
+ * The count lives in the run directory (`.stagnation.json`), so it goes
204
+ * with the run.
205
+ *
206
+ * @param runDirPath - The run's directory (`iamu/.runs/<id>`).
207
+ * @param fingerprint - {@link computePageFingerprint} of the page now.
208
+ * @param action - The step's action, for the warning.
209
+ *
210
+ * @example
211
+ * ```ts
212
+ * const { warning } = checkAndRecordStagnation(runDirPath, fp, "Click Pay");
213
+ * ```
214
+ *
215
+ * @public
172
216
  */
173
- export declare function checkAndRecordStagnation(projectRoot: string, runId: string, fingerprint: string, action: string): {
217
+ export declare function checkAndRecordStagnation(runDirPath: string, fingerprint: string, action: string): {
174
218
  count: number;
175
219
  warning?: string;
176
220
  };
@@ -199,6 +243,11 @@ export declare function detectAntiBotChallenge(page: Page, allowEvaluate?: boole
199
243
  * nothing on success — the caller decides the output shape. Detaching
200
244
  * never closes the page.
201
245
  *
246
+ * The whole command races a deadline (`IAMU_BROWSE_DEADLINE_MS`, default
247
+ * 45 s): a page that never answers fails the command with a clear
248
+ * message instead of hanging the walker, and the browser is still
249
+ * detached.
250
+ *
202
251
  * @public
203
252
  */
204
253
  export declare function withPage(opts: BrowseOptions, driver: BrowserDriver, fn: (page: Page) => Promise<void>,
@@ -213,6 +262,19 @@ onPostShot?: (page: Page) => Promise<void>): Promise<PageResult | null>;
213
262
  * @public
214
263
  */
215
264
  export declare function resilientAriaSnapshot(page: Page): Promise<string>;
265
+ /**
266
+ * A warning for a step that ended on another origin than the run's
267
+ * target, or undefined. It is recorded as the step's `origin_warning`,
268
+ * never in its note: a sign-in or payment page on purpose is fine, but a
269
+ * tab another app took over is not the product under test. Both URLs
270
+ * must be http(s); `about:blank` and relative URLs never warn.
271
+ *
272
+ * @example
273
+ * stepOriginWarning("http://localhost:3001/settings", "http://localhost:3000/");
274
+ * // "The step ended on http://localhost:3001, not the run's target http://localhost:3000. …"
275
+ * stepOriginWarning("http://localhost:3000/a", "http://localhost:3000/"); // undefined
276
+ */
277
+ export declare function stepOriginWarning(pageUrl: string | null | undefined, targetUrl: string | null | undefined): string | undefined;
216
278
  /** What {@link clearOriginStorage} removed. */
217
279
  export interface ClearedStorage {
218
280
  origin: string;
@@ -226,7 +288,9 @@ export interface ClearedStorage {
226
288
  */
227
289
  export declare function clearOriginStorage(origin: string, driver?: BrowserDriver,
228
290
  /** Page to open after clearing (the run's start URL); else about:blank. */
229
- returnTo?: string): Promise<ClearedStorage | {
291
+ returnTo?: string,
292
+ /** The run whose browser to clear; else the shared one. */
293
+ run?: string | null): Promise<ClearedStorage | {
230
294
  error: string;
231
295
  }>;
232
296
  /**
@@ -111,7 +111,42 @@ type AssembledRunFiles = {
111
111
  * `match-record`) does not drop them. It holds the run's record lock so
112
112
  * stages that re-derive them in parallel never interleave.
113
113
  */
114
- export declare function assembleRun(projectRoot: string, runId: string, manifest: WalkthroughManifest, completedAt: string): Promise<AssembledRunFiles>;
114
+ export declare function assembleRun(projectRoot: string, runId: string, manifest: WalkthroughManifest, completedAt: string, opts?: AssembleRunOptions): Promise<AssembledRunFiles>;
115
+ /** How an assembly may touch files outside the run directory. */
116
+ export interface AssembleRunOptions {
117
+ /**
118
+ * Write `fix_status` on earlier findings from this run's verification
119
+ * delta. Only `complete` (first completion) and `match-record` pass
120
+ * true; every other re-derivation reports without writing. Default false.
121
+ */
122
+ writeFixStatus?: boolean;
123
+ }
124
+ /**
125
+ * Re-derive a completed run's canonical.json and report.md from the
126
+ * manifest as it is on disk now. For a caller that already holds the
127
+ * run's record lock; otherwise use {@link rederiveRunLocked}.
128
+ *
129
+ * @throws Error when the run has no readable `walkthrough.json`.
130
+ */
131
+ export declare function rederiveRunUnlocked(projectRoot: string, runId: string, opts?: AssembleRunOptions): Promise<AssembledRunFiles>;
132
+ /**
133
+ * Re-derive a completed run's canonical.json and report.md under the
134
+ * run's record lock, reading the manifest inside the lock. For stages
135
+ * that changed something the report shows (triage, designer-dismiss).
136
+ * Never writes `fix_status` unless `opts.writeFixStatus` is set.
137
+ *
138
+ * @param projectRoot - Absolute path to the project root.
139
+ * @param runId - The completed run to re-derive.
140
+ * @param opts - `writeFixStatus` (default false).
141
+ * @returns The written files and the verification delta.
142
+ * @throws Error when the run has no readable `walkthrough.json`.
143
+ *
144
+ * @example
145
+ * ```ts
146
+ * await rederiveRunLocked(projectRoot, runId);
147
+ * ```
148
+ */
149
+ export declare function rederiveRunLocked(projectRoot: string, runId: string, opts?: AssembleRunOptions): Promise<AssembledRunFiles>;
115
150
  /**
116
151
  * {@link assembleRun} for a caller that already holds the run's record
117
152
  * lock (`withRunLock` is not re-entrant). The record stages take the lock
@@ -119,7 +154,7 @@ export declare function assembleRun(projectRoot: string, runId: string, manifest
119
154
  * stage never reads half-written findings or overwrites the report with
120
155
  * an older canonical.
121
156
  */
122
- export declare function assembleRunUnlocked(projectRoot: string, runId: string, manifest: WalkthroughManifest, completedAt: string): Promise<AssembledRunFiles>;
157
+ export declare function assembleRunUnlocked(projectRoot: string, runId: string, manifest: WalkthroughManifest, completedAt: string, opts?: AssembleRunOptions): Promise<AssembledRunFiles>;
123
158
  /** One requested place, whether the run reached it, and what awaits there. */
124
159
  export type RevisitReportPlace = RevisitPlaceCoverage & {
125
160
  findings: Array<{
@@ -23,6 +23,22 @@ export declare function commandError(message: string, opts?: CommandDiagnosticOp
23
23
  export declare function resolveRunDir(projectRoot: string, runId: string, opts?: {
24
24
  json?: boolean;
25
25
  }): string | null;
26
+ /**
27
+ * Resolve the directory of a run that exists — one `iamu start-run`
28
+ * created, so it holds `walkthrough.json`. Writers into a run (summary,
29
+ * step) use this so a mistyped or never-started run id fails with
30
+ * `run_not_found` instead of creating a phantom run directory. Returns
31
+ * `null` once the error has been reported.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * const dir = requireRun(projectRoot, runId, opts);
36
+ * if (!dir) return;
37
+ * ```
38
+ */
39
+ export declare function requireRun(projectRoot: string, runId: string, opts?: {
40
+ json?: boolean;
41
+ }): string | null;
26
42
  /**
27
43
  * Resolves the active scenario slug following the OpenSpec single-entity resolution pattern:
28
44
  * 1. Explicit slug argument if provided
@@ -32,6 +32,8 @@ export declare function checkProjectTestabilityContract(projectRoot: string): Pr
32
32
  }>;
33
33
  export declare function runDoctorChecks(projectRoot?: string, opts?: {
34
34
  target?: string;
35
+ /** The cloud reachability probe's fetch (tests pass a fake). */
36
+ fetch?: typeof fetch;
35
37
  }): Promise<DoctorResult>;
36
38
  export declare function doctor(opts?: {
37
39
  json?: boolean;
@@ -14,11 +14,14 @@
14
14
  * save, log out …), form submits, downloads and other origins are
15
15
  * never clicked. Nothing is typed into a field.
16
16
  * - Every request that is not GET/HEAD/OPTIONS is aborted before it
17
- * leaves the browser, and recorded on the action that caused it.
17
+ * leaves the browser, and recorded on the action that caused it. So is
18
+ * a page load or fetch whose path or query reads like a write
19
+ * (`/logout`, `?action=delete`), however a script started it.
18
20
  *
19
21
  * Dialogs are dismissed (`confirm()` answers no) and popups closed.
20
22
  * WebSocket messages are not guarded; a page controlled by a service
21
- * worker (whose requests the guard cannot see) is refused.
23
+ * worker (whose requests the guard cannot see) is refused, and a crawl
24
+ * stops (`stats.stopped: "service_worker"`) once one takes control.
22
25
  */
23
26
  import { type ExploreBudget, type ExploreStats, type ExploreSurface } from "@iamu-dev/local-store";
24
27
  import type { Page } from "playwright-core";
@@ -20,8 +20,14 @@ export declare function devServerHint(projectRoot: string, devCommandRecorded?:
20
20
  */
21
21
  export declare function detectTargetPort(projectRoot: string): number | undefined;
22
22
  export declare function detectTargetUrl(projectRoot: string): string;
23
- /** The target line of the init summary, by testability status. */
24
- export declare function describeTargetStatus(status: TestabilityStatus): string;
23
+ /**
24
+ * The target line of the init summary, by testability status. A draft
25
+ * target is "detected" only when the project named it; otherwise it is
26
+ * the default.
27
+ */
28
+ export declare function describeTargetStatus(status: TestabilityStatus, opts?: {
29
+ fallback?: boolean;
30
+ }): string;
25
31
  export declare function createDraftTestabilityContent(targetUrl?: string, status?: TestabilityStatus): string;
26
32
  export interface InitOptions {
27
33
  name?: string;
@@ -1,21 +1,6 @@
1
- export interface InstructionsOptions {
2
- phase?: string;
3
- scenario?: string;
4
- run?: string;
5
- surface?: string;
6
- json?: boolean;
7
- }
8
1
  /**
9
2
  * Generates dynamic staging instructions for an active or specified scenario.
10
3
  */
11
4
  export declare function instructionsStage(slug?: string, opts?: {
12
5
  json?: boolean;
13
6
  }): Promise<void>;
14
- /**
15
- * Phases `iamu instructions [phase]` serves (`run` is an alias of `walk`).
16
- */
17
- export declare const INSTRUCTION_PHASES: string[];
18
- /**
19
- * Top-level dispatcher for `iamu instructions [phase] [slug]`.
20
- */
21
- export declare function instructions(phase?: string, slug?: string, opts?: InstructionsOptions): Promise<void>;
@@ -1,4 +1,10 @@
1
1
  import { type WalkthroughManifest } from "@iamu-dev/local-store";
2
+ /**
3
+ * Where the matcher's raw answer goes in the run directory, parallel to
4
+ * `judge_answer.json`. `matches.json` is the validated record that only
5
+ * `match-record` writes.
6
+ */
7
+ export declare const MATCH_ANSWER_FILE = "match_answer.json";
2
8
  /** A completed run's manifest, or null after reporting why not. */
3
9
  export declare function completedManifest(runDirPath: string, runId: string, opts?: {
4
10
  json?: boolean;
@@ -1,10 +1,88 @@
1
+ import type { HostAdapter } from "../adapters/types.js";
2
+ /** What {@link writeSyncMcpEntry} changed besides the `iamu-sync` entry. */
3
+ export interface SyncMcpWriteResult {
4
+ /**
5
+ * True when the file held the old `iamu` entry (`iamu mcp-server`, a
6
+ * command that no longer exists) and it was removed.
7
+ */
8
+ removedLegacy: boolean;
9
+ }
1
10
  /**
2
- * Write or update the `iamu-sync` entry in an MCP config file.
3
- * Merges with existing content — does not clobber other servers.
4
- * Throws if existing file contains invalid JSON (avoids silent data loss).
11
+ * Remove the legacy `iamu` (`mcp-server`) entry from an existing MCP
12
+ * file, for every project, cloud-linked or not: before 0.8, `iamu init`
13
+ * wrote it everywhere. Writes only when the entry was there; a missing
14
+ * or malformed file is left alone (`false`).
15
+ *
16
+ * @returns Whether the entry was there and is now gone.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * if (await removeLegacyIamuEntry(".mcp.json")) console.log("removed");
21
+ * ```
5
22
  */
6
- export declare function writeSyncMcpEntry(mcpPath: string): Promise<void>;
23
+ export declare function removeLegacyIamuEntry(mcpPath: string): Promise<boolean>;
7
24
  /**
8
- * Check if an MCP config file has an `iamu-sync` entry.
25
+ * Write or update the `iamu-sync` entry in an MCP config file, and drop
26
+ * the legacy `iamu` (`mcp-server`) entry if it is there. Merges with
27
+ * existing content — does not clobber other servers.
28
+ *
29
+ * @param mcpPath - The host's project MCP file; `null` for a host that
30
+ * has none (see `HostAdapter.manualMcpSetup`), which throws.
31
+ * @throws When the file holds invalid JSON (avoids silent data loss), or
32
+ * when `mcpPath` is null.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * const { removedLegacy } = await writeSyncMcpEntry(".mcp.json");
37
+ * ```
9
38
  */
10
- export declare function hasSyncMcpEntry(parsed: Record<string, unknown>, mcpPath: string): boolean;
39
+ export declare function writeSyncMcpEntry(mcpPath: string | null): Promise<SyncMcpWriteResult>;
40
+ /** The outcome of registering `iamu-sync` for one host. */
41
+ export type SyncMcpRegistration = {
42
+ status: "written";
43
+ path: string;
44
+ removedLegacy: boolean;
45
+ } | {
46
+ status: "legacy_removed";
47
+ path: string;
48
+ removedLegacy: true;
49
+ } | {
50
+ status: "manual";
51
+ instruction: string;
52
+ } | {
53
+ status: "failed";
54
+ path: string;
55
+ message: string;
56
+ };
57
+ /**
58
+ * Register `iamu-sync` for `host` without ever throwing: a host with no
59
+ * project MCP file yields its by-hand instruction, a malformed file a
60
+ * failure to report. Used by `iamu init` and `iamu update`.
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * const r = await registerSyncMcpForHost(host, projectRoot);
65
+ * printSyncMcpRegistration(host, r, "registered");
66
+ * ```
67
+ */
68
+ export declare function registerSyncMcpForHost(host: HostAdapter, projectRoot: string): Promise<SyncMcpRegistration>;
69
+ /**
70
+ * For a project that registers no `iamu-sync` (not cloud-linked): drop
71
+ * the legacy `iamu` entry from `host`'s MCP file if it has one. Never
72
+ * throws; `null` when there was nothing to remove.
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * const r = await removeLegacyMcpForHost(host, projectRoot);
77
+ * if (r) printSyncMcpRegistration(host, r, "refreshed");
78
+ * ```
79
+ */
80
+ export declare function removeLegacyMcpForHost(host: HostAdapter, projectRoot: string): Promise<SyncMcpRegistration | null>;
81
+ /**
82
+ * Print one host's registration outcome: a success line (plus a note
83
+ * when the legacy entry went), the by-hand instruction, or a warning on
84
+ * stderr. Never sets an exit code — the rest of the setup stands.
85
+ *
86
+ * @param verb - "registered" (init) or "refreshed" (update).
87
+ */
88
+ export declare function printSyncMcpRegistration(host: HostAdapter, result: SyncMcpRegistration, verb: "registered" | "refreshed"): void;
@@ -3,6 +3,8 @@ export interface NewEntityOptions {
3
3
  slug?: string;
4
4
  description?: string;
5
5
  body?: string;
6
+ /** Read the body from this file (`-` for stdin). */
7
+ bodyFile?: string;
6
8
  narrative?: string;
7
9
  access?: string;
8
10
  role?: string;
@@ -31,6 +33,32 @@ export interface NewEntityOptions {
31
33
  stateApproximation?: string;
32
34
  json?: boolean;
33
35
  }
36
+ /** The body flags `iamu new` and `iamu set` share. */
37
+ export interface BodyInputOptions {
38
+ body?: string;
39
+ bodyFile?: string;
40
+ json?: boolean;
41
+ }
42
+ /**
43
+ * The body a command should write, from `--body <text>` or
44
+ * `--body-file <path>` (`-` reads stdin; a relative path is resolved
45
+ * against the working directory). A `--body` holding a literal `\n` is
46
+ * refused: the shell passed a backslash and an `n`, which would be stored
47
+ * as-is instead of a line break. Errors are reported as command errors.
48
+ *
49
+ * @param flag - The flag name the text came from (`--narrative` for the alias).
50
+ * @returns `{ body }` (undefined when neither flag was given), or `null`
51
+ * once an error has been reported.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * const input = await resolveBodyInput(opts, "iamu new persona");
56
+ * if (!input) return;
57
+ * ```
58
+ */
59
+ export declare function resolveBodyInput(opts: BodyInputOptions, command: string, flag?: string): Promise<{
60
+ body: string | undefined;
61
+ } | null>;
34
62
  /** Entity types `iamu new <type>` creates (findings: `iamu new-finding`). */
35
63
  export declare const SUPPORTED_TYPES: readonly ["persona", "outline", "capability", "source", "scenario"];
36
64
  export declare function newEntity(type: string, opts: NewEntityOptions): Promise<void>;
@@ -0,0 +1,21 @@
1
+ export interface PostWalkOptions {
2
+ run?: string;
3
+ critic?: boolean;
4
+ ux?: boolean;
5
+ byOrchestrator?: boolean;
6
+ json?: boolean;
7
+ }
8
+ /**
9
+ * Single-command post-walk orchestrator helper (`iamu post-walk [run-id]`).
10
+ *
11
+ * 1. Completes the run locally (`iamu complete --no-prompt --no-push`) if still `in-progress`.
12
+ * 2. Records any subagent answer files already present in `<run-dir>/`
13
+ * (`match_answer.json`, `judge_answer.json`, `advise_answer.json`,
14
+ * `designer_answer.json`) in canonical lock-safe order. `matches.json`
15
+ * is match-record's validated record, never an answer file.
16
+ * 3. Generates the remaining post-walk subagent prompts (`match_prompt.md`,
17
+ * `judge_prompt.md`, `designer_prompt.md`). `advise_prompt.md` waits
18
+ * for `verdicts.json`: the advisor reads the judge's verdicts, so a
19
+ * second `post-walk` after `evaluate-record` builds it.
20
+ */
21
+ export declare function postWalk(runIdArg?: string, opts?: PostWalkOptions): Promise<void>;
@@ -2,4 +2,5 @@ export declare function pull(refs?: string[], opts?: {
2
2
  force?: boolean;
3
3
  preview?: boolean;
4
4
  json?: boolean;
5
+ all?: boolean;
5
6
  }): Promise<void>;
@@ -71,6 +71,8 @@ export interface SetEntityOptions {
71
71
  glossary?: ContextFrontmatter["glossary"] | false;
72
72
  /** Markdown body narrative. */
73
73
  body?: string;
74
+ /** Read the body from this file (`-` for stdin) instead of `--body`. */
75
+ bodyFile?: string;
74
76
  /** JSON patch file (or - for stdin) containing staging fields. */
75
77
  file?: string;
76
78
  json?: boolean;
@@ -17,11 +17,18 @@ export declare function resolveTargetHosts(projectRoot: string, hostFilter?: str
17
17
  error?: string;
18
18
  };
19
19
  /**
20
- * Installed skill/command files that differ from what `iamu update` would
21
- * write for this CLI version. Local reads only — no network.
20
+ * Installed skill files that differ from what `iamu update` would write
21
+ * for this CLI version, for every host `iamu update` would touch: a
22
+ * detected host with no iamu skills yet counts (its skills are missing),
23
+ * unless the Iamu plugin supplies them. Local reads only — no network.
22
24
  *
23
- * @returns Absolute paths of the stale files; empty when up to date or
24
- * when no host has iamu skills installed.
25
+ * @returns Absolute paths of the stale (or missing) files; empty when up
26
+ * to date or when no agent host is detected.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * if ((await findStaleSkills(root)).length > 0) console.log(STALE_SKILLS_MESSAGE);
31
+ * ```
25
32
  */
26
33
  export declare function findStaleSkills(projectRoot: string): Promise<string[]>;
27
34
  /** The one-line nudge `iamu status` and `iamu sync` print. */
@@ -31,4 +38,6 @@ export declare function installSkillsForHosts(hosts: HostAdapter[], projectRoot:
31
38
  }): Promise<{
32
39
  totalSkills: number;
33
40
  totalCommands: number;
41
+ /** Project-relative paths of skills kept because they differ (see above). */
42
+ keptSkills: string[];
34
43
  }>;
@@ -1,5 +1,6 @@
1
1
  /**
2
- * A step number claimed on disk. The file at `stepPath` exists (empty)
2
+ * A step number claimed on disk. The file at `stepPath` exists (holding
3
+ * a `{ reservation: { pid, ts } }` marker that step readers skip)
3
4
  * until the caller overwrites it with the step, or calls `release()`.
4
5
  *
5
6
  * @public
@@ -30,6 +30,8 @@ export interface RecordStepInput {
30
30
  url?: string | null;
31
31
  surface?: string | null;
32
32
  grounding?: string | null;
33
+ /** The step ended on another origin than the run's target (`browse step`). */
34
+ originWarning?: string | null;
33
35
  timestamp?: string;
34
36
  maxSteps?: string | number;
35
37
  extra?: Record<string, unknown>;
@@ -2,10 +2,12 @@
2
2
  export declare const SCOPES: readonly ["project", "outline", "capability"];
3
3
  export interface TriageOptions {
4
4
  status: string;
5
- /** Why — the triager's words. Required when dismissing. */
5
+ /** Optional triage note or reason. */
6
6
  note?: string;
7
- /** Dismiss reason: not_relevant | walker_error | duplicate. */
7
+ /** Dismiss reason: not_relevant | walker_error | out_of_scope | duplicate. */
8
8
  reason?: string;
9
+ /** Finding slug or id this repeats when dismissing as duplicate. */
10
+ duplicateOf?: string;
9
11
  /** Guidance rule text; defaults to "Don't report: <title>". */
10
12
  rule?: string;
11
13
  /** Where the guidance rule applies. Default: project. */