hcifootprint 0.2.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.
Files changed (87) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +524 -0
  3. package/dist/atom/types.d.ts +618 -0
  4. package/dist/atom/types.d.ts.map +1 -0
  5. package/dist/atom/types.js +2 -0
  6. package/dist/atom/types.js.map +1 -0
  7. package/dist/graph/builder.d.ts +31 -0
  8. package/dist/graph/builder.d.ts.map +1 -0
  9. package/dist/graph/builder.js +165 -0
  10. package/dist/graph/builder.js.map +1 -0
  11. package/dist/graph/guards.d.ts +31 -0
  12. package/dist/graph/guards.d.ts.map +1 -0
  13. package/dist/graph/guards.js +94 -0
  14. package/dist/graph/guards.js.map +1 -0
  15. package/dist/graph/skill-deps.d.ts +20 -0
  16. package/dist/graph/skill-deps.d.ts.map +1 -0
  17. package/dist/graph/skill-deps.js +15 -0
  18. package/dist/graph/skill-deps.js.map +1 -0
  19. package/dist/index.d.ts +49 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +42 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/mcp.d.ts +16 -0
  24. package/dist/mcp.d.ts.map +1 -0
  25. package/dist/mcp.js +15 -0
  26. package/dist/mcp.js.map +1 -0
  27. package/dist/presence/presence.d.ts +50 -0
  28. package/dist/presence/presence.d.ts.map +1 -0
  29. package/dist/presence/presence.js +126 -0
  30. package/dist/presence/presence.js.map +1 -0
  31. package/dist/registry/registry.d.ts +53 -0
  32. package/dist/registry/registry.d.ts.map +1 -0
  33. package/dist/registry/registry.js +76 -0
  34. package/dist/registry/registry.js.map +1 -0
  35. package/dist/serve/mcp-server.d.ts +40 -0
  36. package/dist/serve/mcp-server.d.ts.map +1 -0
  37. package/dist/serve/mcp-server.js +72 -0
  38. package/dist/serve/mcp-server.js.map +1 -0
  39. package/dist/serve/mcp.d.ts +12 -0
  40. package/dist/serve/mcp.d.ts.map +1 -0
  41. package/dist/serve/mcp.js +62 -0
  42. package/dist/serve/mcp.js.map +1 -0
  43. package/dist/serve/modes.d.ts +66 -0
  44. package/dist/serve/modes.d.ts.map +1 -0
  45. package/dist/serve/modes.js +347 -0
  46. package/dist/serve/modes.js.map +1 -0
  47. package/dist/testing/harness.d.ts +156 -0
  48. package/dist/testing/harness.d.ts.map +1 -0
  49. package/dist/testing/harness.js +416 -0
  50. package/dist/testing/harness.js.map +1 -0
  51. package/dist/testing/index.d.ts +35 -0
  52. package/dist/testing/index.d.ts.map +1 -0
  53. package/dist/testing/index.js +32 -0
  54. package/dist/testing/index.js.map +1 -0
  55. package/dist/testing/lint.d.ts +20 -0
  56. package/dist/testing/lint.d.ts.map +1 -0
  57. package/dist/testing/lint.js +18 -0
  58. package/dist/testing/lint.js.map +1 -0
  59. package/dist/testing/model/check.d.ts +30 -0
  60. package/dist/testing/model/check.d.ts.map +1 -0
  61. package/dist/testing/model/check.js +89 -0
  62. package/dist/testing/model/check.js.map +1 -0
  63. package/dist/testing/model/lint.d.ts +54 -0
  64. package/dist/testing/model/lint.d.ts.map +1 -0
  65. package/dist/testing/model/lint.js +235 -0
  66. package/dist/testing/model/lint.js.map +1 -0
  67. package/dist/testing/model/satisfiable.d.ts +25 -0
  68. package/dist/testing/model/satisfiable.d.ts.map +1 -0
  69. package/dist/testing/model/satisfiable.js +101 -0
  70. package/dist/testing/model/satisfiable.js.map +1 -0
  71. package/dist/traverse/nav-session.d.ts +108 -0
  72. package/dist/traverse/nav-session.d.ts.map +1 -0
  73. package/dist/traverse/nav-session.js +637 -0
  74. package/dist/traverse/nav-session.js.map +1 -0
  75. package/dist/traverse/session.d.ts +239 -0
  76. package/dist/traverse/session.d.ts.map +1 -0
  77. package/dist/traverse/session.js +1305 -0
  78. package/dist/traverse/session.js.map +1 -0
  79. package/dist/tree/appmap.d.ts +8 -0
  80. package/dist/tree/appmap.d.ts.map +1 -0
  81. package/dist/tree/appmap.js +259 -0
  82. package/dist/tree/appmap.js.map +1 -0
  83. package/dist/tree/types.d.ts +151 -0
  84. package/dist/tree/types.d.ts.map +1 -0
  85. package/dist/tree/types.js +2 -0
  86. package/dist/tree/types.js.map +1 -0
  87. package/package.json +90 -0
@@ -0,0 +1,347 @@
1
+ import { detectSchema } from 'footprintjs';
2
+ import { normalizeSchema } from 'footprintjs/advanced';
3
+ const SKILL_USAGE = ' Call with no arguments to open this skill and see its ready steps; call again with' +
4
+ " {step: '<name from readySteps>', input: {...}} to perform a step. High-effect steps additionally" +
5
+ ' need confirm: true. Steps arrive as DATA in results — they are never separate tools.';
6
+ const WHATS_HERE_DESCRIPTION = 'Describe the current position: the page, the open skill (if any), what happened recently, ' +
7
+ 'and the actions and skills available right now. Pass sinceVersion (the version from any ' +
8
+ 'earlier result) to get only what changed since your last look — including what the user ' +
9
+ 'did themselves in the meantime.';
10
+ const DO_ACTION_DESCRIPTION = 'Perform one available action outside any skill flow. Call whats_here first to see action names. ' +
11
+ 'High-effect actions additionally need confirm: true.';
12
+ const WHY_DESCRIPTION = 'Explain why a state key currently holds its value: the causal chain of session actions — and ' +
13
+ 'who fired each one — that produced it. Pass a state key name seen in results or guards.';
14
+ const STEP_INPUT_SCHEMA = {
15
+ type: 'object',
16
+ properties: {
17
+ step: { type: 'string', description: 'A step name taken from readySteps in a previous result.' },
18
+ input: { type: 'object', description: 'The step input. Each result states what the next step expects.' },
19
+ confirm: { type: 'boolean', description: 'Required true for high-effect steps.' },
20
+ instance: {
21
+ type: 'string',
22
+ description: 'Which instance to act on, when the step lists instances (e.g. an order id).',
23
+ },
24
+ },
25
+ additionalProperties: false,
26
+ };
27
+ export function skillsAsTools(session, opts) {
28
+ const confirmHighEffect = opts?.confirmHighEffect ?? true;
29
+ const source = opts?.source ?? 'agent';
30
+ const graphId = session.graphId;
31
+ // Skills are declared-only data: the tool array derived from them is static
32
+ // BY CONSTRUCTION — freeze it once, serve identical bytes every turn.
33
+ const declaredSkills = session.availableSkills().skills;
34
+ const skillToolNames = new Map(); // tool name → skill id
35
+ for (const skill of declaredSkills) {
36
+ skillToolNames.set(sanitizeName(`${graphId}.skill.${skill.id}`), skill.id);
37
+ }
38
+ const skillSteps = new Map(declaredSkills.map((skill) => [skill.id, [...skill.steps]]));
39
+ const whatsHereName = sanitizeName(`${graphId}.whats_here`);
40
+ const doActionName = sanitizeName(`${graphId}.do_action`);
41
+ const whyName = sanitizeName(`${graphId}.why`);
42
+ const staticTools = [
43
+ ...declaredSkills.map((skill) => ({
44
+ name: sanitizeName(`${graphId}.skill.${skill.id}`),
45
+ description: skill.description + SKILL_USAGE,
46
+ inputSchema: structuredClone(STEP_INPUT_SCHEMA),
47
+ })),
48
+ {
49
+ name: whatsHereName,
50
+ description: WHATS_HERE_DESCRIPTION,
51
+ inputSchema: {
52
+ type: 'object',
53
+ properties: {
54
+ sinceVersion: {
55
+ type: 'number',
56
+ description: 'A version from a previous result: the reply narrates only the delta since it.',
57
+ },
58
+ },
59
+ additionalProperties: false,
60
+ },
61
+ },
62
+ {
63
+ name: whyName,
64
+ description: WHY_DESCRIPTION,
65
+ inputSchema: {
66
+ type: 'object',
67
+ properties: {
68
+ key: { type: 'string', description: 'A state key name, as seen in results, guards, or evidence.' },
69
+ },
70
+ required: ['key'],
71
+ additionalProperties: false,
72
+ },
73
+ },
74
+ {
75
+ name: doActionName,
76
+ description: DO_ACTION_DESCRIPTION,
77
+ inputSchema: {
78
+ type: 'object',
79
+ properties: {
80
+ action: { type: 'string', description: 'An action name from whats_here.' },
81
+ input: structuredClone(STEP_INPUT_SCHEMA.properties.input),
82
+ confirm: structuredClone(STEP_INPUT_SCHEMA.properties.confirm),
83
+ instance: structuredClone(STEP_INPUT_SCHEMA.properties.instance),
84
+ },
85
+ required: ['action'],
86
+ additionalProperties: false,
87
+ },
88
+ },
89
+ ];
90
+ /** Currently-fireable edges by id — the serve layer's only view of tool detail. */
91
+ function edgeById() {
92
+ return new Map(session.available().edges.map((edge) => [edge.affordanceId, edge]));
93
+ }
94
+ function callSkill(skillId, args) {
95
+ // Cross-skill switch is implicit — but NEVER destructive-first: the open
96
+ // frame is left only after the target skill is known to be openable, so a
97
+ // blocked target cannot cost the model its current flow.
98
+ const openFrame = session.skillFrame();
99
+ if (openFrame && openFrame.skillId !== skillId) {
100
+ const target = session.availableSkills().skills.find((skill) => skill.id === skillId);
101
+ if (target && !target.preconditionPassed) {
102
+ return {
103
+ ok: false,
104
+ judgment: 'blocked',
105
+ skill: skillId,
106
+ why: 'This skill’s precondition does not hold right now. Your current skill is still open.',
107
+ evidence: structuredClone(target.evidence),
108
+ keptFrame: openFrame.skillId,
109
+ ...positionData(),
110
+ };
111
+ }
112
+ session.leaveSkill();
113
+ }
114
+ if (!session.skillFrame()) {
115
+ const committed = session.commitSkill(skillId, { source });
116
+ if (!committed.ok) {
117
+ if (committed.reason === 'PRECONDITION_FAILED') {
118
+ return {
119
+ ok: false,
120
+ judgment: 'blocked',
121
+ skill: skillId,
122
+ why: 'This skill’s precondition does not hold right now.',
123
+ evidence: structuredClone(committed.evidence),
124
+ ...positionData(),
125
+ };
126
+ }
127
+ return { ok: false, judgment: 'error', skill: skillId, reason: committed.reason, ...positionData() };
128
+ }
129
+ }
130
+ if (args.step === undefined) {
131
+ return { ok: true, skill: skillId, ...frameData(skillId), ...positionData() };
132
+ }
133
+ const stepId = resolveStep(skillId, args.step);
134
+ if (!stepId) {
135
+ return {
136
+ ok: false,
137
+ judgment: 'error',
138
+ skill: skillId,
139
+ reason: 'UNKNOWN_STEP',
140
+ steps: [...(skillSteps.get(skillId) ?? [])],
141
+ ...positionData(),
142
+ };
143
+ }
144
+ const edge = edgeById().get(stepId);
145
+ if (confirmHighEffect && edge?.highEffect && args.confirm !== true) {
146
+ return {
147
+ ok: false,
148
+ judgment: 'needs-confirm',
149
+ skill: skillId,
150
+ step: stepId,
151
+ does: edge.description,
152
+ howToAct: 'Ask the human, then call again with confirm: true.',
153
+ ...positionData(),
154
+ };
155
+ }
156
+ const fired = session.fire(stepId, { source, payload: args.input, instance: args.instance });
157
+ // frameData FIRST: on a rejected fire, fireData's judgment ('rejected')
158
+ // must win over the frame's ('needs-choice'); on success fireData carries
159
+ // no judgment and the frame's stands.
160
+ return { skill: skillId, ...frameData(skillId), ...fireData(fired, stepId, edge), ...positionData() };
161
+ }
162
+ function resolveStep(skillId, step) {
163
+ const steps = skillSteps.get(skillId) ?? [];
164
+ if (steps.includes(step))
165
+ return step;
166
+ const matches = steps.filter((candidate) => candidate.endsWith(`.${step}`));
167
+ return matches.length === 1 ? matches[0] : null;
168
+ }
169
+ function callWhatsHere(sinceVersion) {
170
+ const brief = session.contextBrief(sinceVersion === undefined ? undefined : { sinceVersion });
171
+ return {
172
+ ok: true,
173
+ brief: brief.text,
174
+ actions: session.available().edges.map(edgeData),
175
+ skills: session.availableSkills().skills.map((skill) => ({
176
+ skill: skill.id,
177
+ does: skill.description,
178
+ feasible: skill.preconditionPassed,
179
+ ...(skill.preconditionUnevaluable ? { feasibilityUnknownFor: skill.preconditionUnevaluable } : {}),
180
+ })),
181
+ ...positionData(),
182
+ };
183
+ }
184
+ function callDoAction(args) {
185
+ const edges = session.available().edges;
186
+ const exact = edges.find((edge) => edge.affordanceId === args.action);
187
+ const matches = exact ? [exact] : edges.filter((edge) => edge.affordanceId.endsWith(`.${args.action}`));
188
+ if (matches.length !== 1) {
189
+ return {
190
+ ok: false,
191
+ judgment: 'error',
192
+ reason: matches.length === 0 ? 'UNKNOWN_ACTION' : 'AMBIGUOUS_ACTION',
193
+ actions: edges.map((edge) => edge.affordanceId),
194
+ ...positionData(),
195
+ };
196
+ }
197
+ const edge = matches[0];
198
+ if (confirmHighEffect && edge.highEffect && args.confirm !== true) {
199
+ return {
200
+ ok: false,
201
+ judgment: 'needs-confirm',
202
+ action: edge.affordanceId,
203
+ does: edge.description,
204
+ howToAct: 'Ask the human, then call again with confirm: true.',
205
+ ...positionData(),
206
+ };
207
+ }
208
+ const fired = session.fire(edge.affordanceId, { source, payload: args.input, instance: args.instance });
209
+ return { ...fireData(fired, edge.affordanceId, edge), ...positionData() };
210
+ }
211
+ // -- result builders (data channel; text = authored strings only) -----------
212
+ function positionData() {
213
+ return { youAreOn: session.node, version: session.version };
214
+ }
215
+ function frameData(skillId) {
216
+ const frame = session.skillFrame();
217
+ if (!frame || frame.skillId !== skillId) {
218
+ const closed = session
219
+ .frames()
220
+ .filter((candidate) => candidate.skillId === skillId)
221
+ .pop();
222
+ return closed ? { frame: closed.status } : {};
223
+ }
224
+ const plan = session.skillPlan(skillId);
225
+ if (plan.steps.every((step) => step.status === 'done' || step.status === 'inferred-done')) {
226
+ session.leaveSkill({ reason: 'completed' });
227
+ return { frame: 'completed', judgment: 'done' };
228
+ }
229
+ const edges = edgeById();
230
+ // A step whose fire is still awaiting the app's state report is NOT ready
231
+ // to fire again — advertising it would instruct the model to double-fire.
232
+ const awaiting = new Set(session.pending().map((pendingInfo) => pendingInfo.affordanceId));
233
+ const ready = plan.steps.filter((step) => step.status === 'ready' && !awaiting.has(step.affordanceId));
234
+ return {
235
+ frame: 'open',
236
+ judgment: ready.length === 0 ? 'navigate-or-wait' : ready.length === 1 ? 'one-ready-step' : 'needs-choice',
237
+ ...(awaiting.size > 0 ? { awaitingState: [...awaiting] } : {}),
238
+ readySteps: ready.map((step) => {
239
+ const edge = edges.get(step.affordanceId);
240
+ return {
241
+ step: step.affordanceId,
242
+ does: step.description,
243
+ ...(edge?.highEffect ? { highEffect: true } : {}),
244
+ ...(step.guardUnevaluated ? { guardUnevaluated: step.guardUnevaluated } : {}),
245
+ ...expectsData(edge?.schema),
246
+ };
247
+ }),
248
+ laterSteps: plan.steps
249
+ .filter((step) => step.status !== 'ready')
250
+ .map((step) => ({ step: step.affordanceId, status: step.status })),
251
+ howToAct: 'Call this tool again with step set to one of readySteps.',
252
+ };
253
+ }
254
+ function fireData(fired, id, edge) {
255
+ if (fired.ok) {
256
+ return {
257
+ ok: true,
258
+ did: id,
259
+ settlement: fired.settlement,
260
+ // The transition id lets a caller fetch producedFor() AFTER awaiting the
261
+ // handler — the "act → data back" channel (the tool result is built
262
+ // synchronously here, before an async handler has produced anything).
263
+ transitionId: fired.transition.id,
264
+ // Copy: fired.transition is the LIVE record — a consumer mutating its
265
+ // result must never rewrite the trace.
266
+ ...(fired.transition.guardUnevaluated ? { guardUnevaluated: [...fired.transition.guardUnevaluated] } : {}),
267
+ };
268
+ }
269
+ return {
270
+ ok: false,
271
+ judgment: 'rejected',
272
+ did: id,
273
+ reason: fired.reason,
274
+ ...('evidence' in fired ? { evidence: structuredClone(fired.evidence) } : {}),
275
+ ...('issues' in fired ? { issues: fired.issues } : {}),
276
+ ...('instances' in fired ? { instances: [...fired.instances] } : {}),
277
+ ...('node' in fired ? { node: fired.node } : {}),
278
+ ...(fired.reason === 'PAYLOAD_INVALID' ? expectsData(edge?.schema) : {}),
279
+ ...(fired.reason === 'STILL_MOUNTING' ? { retriable: true } : {}),
280
+ };
281
+ }
282
+ function edgeData(edge) {
283
+ return {
284
+ action: edge.affordanceId,
285
+ does: edge.description,
286
+ ...(edge.highEffect ? { highEffect: true } : {}),
287
+ ...(edge.guardUnevaluated ? { guardUnevaluated: edge.guardUnevaluated } : {}),
288
+ ...(edge.instances ? { instances: edge.instances, enumeration: edge.enumeration } : {}),
289
+ ...(edge.activation && edge.activation !== 'registered' && edge.activation !== 'synced'
290
+ ? { activation: edge.activation }
291
+ : {}),
292
+ };
293
+ }
294
+ /** The step's expected input, rendered as DATA in the result (never as tool schema). */
295
+ function expectsData(schema) {
296
+ if (schema === undefined)
297
+ return {};
298
+ const kind = detectSchema(schema);
299
+ if (kind === 'zod')
300
+ return { expects: normalizeSchema(schema) };
301
+ if (kind === 'json-schema')
302
+ return { expects: structuredClone(schema) };
303
+ return { expects: 'validated at fire time (non-serializable validator)' };
304
+ }
305
+ return {
306
+ tools: () => structuredClone(staticTools),
307
+ call(name, args) {
308
+ const parsed = (args ?? {});
309
+ const skillId = skillToolNames.get(name);
310
+ if (skillId !== undefined) {
311
+ return callSkill(skillId, {
312
+ step: typeof parsed['step'] === 'string' ? parsed['step'] : undefined,
313
+ input: parsed['input'],
314
+ confirm: parsed['confirm'] === true,
315
+ instance: typeof parsed['instance'] === 'string' ? parsed['instance'] : undefined,
316
+ });
317
+ }
318
+ if (name === whatsHereName) {
319
+ return callWhatsHere(typeof parsed['sinceVersion'] === 'number' ? parsed['sinceVersion'] : undefined);
320
+ }
321
+ if (name === whyName) {
322
+ if (typeof parsed['key'] !== 'string' || !parsed['key']) {
323
+ return { ok: false, judgment: 'error', reason: 'KEY_REQUIRED' };
324
+ }
325
+ // The slice text is DATA (it can carry committed state values) — it
326
+ // rides the result channel like producedFor(), never a description.
327
+ return { ok: true, key: parsed['key'], why: session.why(parsed['key']), ...positionData() };
328
+ }
329
+ if (name === doActionName) {
330
+ if (typeof parsed['action'] !== 'string' || !parsed['action']) {
331
+ return { ok: false, judgment: 'error', reason: 'ACTION_REQUIRED' };
332
+ }
333
+ return callDoAction({
334
+ action: parsed['action'],
335
+ input: parsed['input'],
336
+ confirm: parsed['confirm'] === true,
337
+ instance: typeof parsed['instance'] === 'string' ? parsed['instance'] : undefined,
338
+ });
339
+ }
340
+ return { ok: false, judgment: 'error', reason: 'UNKNOWN_TOOL', tools: staticTools.map((tool) => tool.name) };
341
+ },
342
+ };
343
+ }
344
+ function sanitizeName(name) {
345
+ return name.replace(/[^A-Za-z0-9_.-]/g, '_');
346
+ }
347
+ //# sourceMappingURL=modes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modes.js","sourceRoot":"","sources":["../../src/serve/modes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,156 @@
1
+ import type { DoActionArgs, ServeResult, SkillCallArgs } from '../serve/modes.js';
2
+ import type { NavigationGraph } from '../tree/types.js';
3
+ import type { InteractionSession, ToolGroupHandle } from '../traverse/nav-session.js';
4
+ import type { FireResult, GapRecord, StimulusKind, TransitionRecord } from '../atom/types.js';
5
+ import type { MCPToolDescription } from 'footprintjs';
6
+ export interface ResolverContext<State> {
7
+ /** The current projected state, as the real handler would read it. */
8
+ state: State;
9
+ }
10
+ export interface ResolverOutcome<State> {
11
+ /**
12
+ * The state change this action makes — reported through the REAL updateState,
13
+ * so the session verifies it against the action's declared writes. Keep it
14
+ * EXPLICIT (do not mirror effect.writes) or the drift check rubber-stamps
15
+ * itself: the whole value is that the graph's claim and the mock's real delta
16
+ * are independent.
17
+ */
18
+ patch?: Partial<State> & Record<string, unknown>;
19
+ /** Navigate to this page after the delta (like the app's router confirming). */
20
+ goTo?: string;
21
+ /** The "act → data back" return value (search results, a looked-up record). */
22
+ produced?: unknown;
23
+ }
24
+ /** One mock handler for an action. Synchronous — runs inside the precise-attribution window. */
25
+ export type Resolver<State> = (payload: unknown, ctx: ResolverContext<State>) => ResolverOutcome<State> | void;
26
+ /** A controllable clock for deterministic time-dependent staleness tests. */
27
+ export interface TestClock {
28
+ now(): number;
29
+ set(ms: number): void;
30
+ advance(ms: number): void;
31
+ }
32
+ export interface DriftReport {
33
+ /** True when no declared-effect drift was observed (the release-readiness signal). */
34
+ ok: boolean;
35
+ /** Actions whose settled delta did not cover their declared writes — the graph drifted from the handler. */
36
+ effectDrift: Array<{
37
+ transitionId: string;
38
+ affordanceId: string;
39
+ declaredWrites: string[];
40
+ }>;
41
+ /** Guard keys taken on faith because the state view never held them (honesty, not failure). */
42
+ unevaluatedGuards: Array<{
43
+ transitionId: string;
44
+ affordanceId: string;
45
+ keys: string[];
46
+ }>;
47
+ /** The unmet-demand ledger: refused fires + reported gaps. */
48
+ gaps: GapRecord[];
49
+ }
50
+ export interface TestAppOptions<State> {
51
+ /** The initial projected state (guards read it; enables the state tap). */
52
+ initialState?: State;
53
+ /** One mock handler per action, keyed by affordance id (qualified or bare/leaf). */
54
+ resolvers?: Record<string, Resolver<State>>;
55
+ /** Starting page (default: the graph's first page). */
56
+ node?: string;
57
+ /** Fail the test the instant declared-effect drift appears. Default false (report-by-default). */
58
+ strict?: boolean;
59
+ /** Keys stored redacted in the commit log. */
60
+ redactedKeys?: string[];
61
+ /** Dormancy grace window for the drift/overlay timers (default 3000ms). */
62
+ dormantGraceMs?: number;
63
+ /** Sink for the session's dev warnings (default: collected, readable via warnings()). */
64
+ onWarn?: (message: string) => void;
65
+ /**
66
+ * Bring your own already-wired session (real registerToolGroup / taps) for
67
+ * full integration fidelity. In this mode the harness does NOT auto-mount or
68
+ * inject a clock — it wraps what you built. `graph`/`resolvers` are ignored.
69
+ */
70
+ session?: InteractionSession;
71
+ }
72
+ export interface TestApp<State> {
73
+ /** The real session under the hood — drop to it for anything the facade omits. */
74
+ readonly session: InteractionSession;
75
+ /** The current page id. */
76
+ readonly node: string;
77
+ /** The session cursor version. */
78
+ readonly version: number;
79
+ /** A detached snapshot of the projected state. */
80
+ state(): State;
81
+ /** Dev warnings the session emitted (StrictMode notes, handler errors, drift warnings). */
82
+ warnings(): string[];
83
+ /** The controllable clock (deterministic dormancy/mount-grace tests). */
84
+ readonly clock: TestClock;
85
+ /** Advance the injected clock (sugar for clock.advance). */
86
+ advanceTime(ms: number): void;
87
+ /** Drive like a human click. Throws on rejection (fail-fast). */
88
+ readonly user: {
89
+ /** Fire, auto-settle, return the settled record. Throws if the fire is refused. */
90
+ fire(affordanceId: string, opts?: {
91
+ payload?: unknown;
92
+ instance?: string;
93
+ }): Promise<TransitionRecord>;
94
+ /** Fire + auto-settle but NEVER throw — return the raw FireResult (inspect a rejection). */
95
+ tryFire(affordanceId: string, opts?: {
96
+ payload?: unknown;
97
+ instance?: string;
98
+ }): Promise<FireResult>;
99
+ /** Fire WITHOUT auto-settling — observe the pending/optimistic-UI window yourself. */
100
+ fireRaw(affordanceId: string, opts?: {
101
+ payload?: unknown;
102
+ instance?: string;
103
+ }): FireResult;
104
+ };
105
+ /** Drive like the planning LLM, through the real Mode B port. Returns ServeResult (needs-confirm is data, never a throw). */
106
+ readonly agent: {
107
+ /** The FIXED tool array the model sees (one per skill + whats_here/do_action). */
108
+ tools(): MCPToolDescription[];
109
+ /** Call whats_here. */
110
+ whatsHere(): Promise<ServeResult>;
111
+ /** Open/step a skill by its id (maps to the skill's fixed tool). */
112
+ skill(skillId: string, args?: SkillCallArgs): Promise<ServeResult>;
113
+ /** Perform one action outside a skill flow (do_action). */
114
+ do(action: string, args?: Omit<DoActionArgs, 'action'>): Promise<ServeResult>;
115
+ };
116
+ /** A world-initiated state change (server push, background update) — never blamed on a pending fire. */
117
+ stimulus(patch: Partial<State> & Record<string, unknown>, opts?: {
118
+ stimulus?: StimulusKind;
119
+ }): void;
120
+ /** The browser back button (or any external navigation) — recorded as a stimulus sync. */
121
+ back(page: string): void;
122
+ /** Mount + show a modal/tab node's tools (not auto-mounted). Returns its handle. */
123
+ open(path: string, opts?: {
124
+ instance?: string;
125
+ }): ToolGroupHandle;
126
+ /** Unmount a node opened with open(). */
127
+ close(path: string): void;
128
+ /** Drain to quiescence (auto-called by user.fire/agent.*; call it after fireRaw/stimulus). */
129
+ settled(): Promise<void>;
130
+ /** The honesty-marker drift report — the release-readiness signal. */
131
+ report(): DriftReport;
132
+ /** Assert the cursor is on `page`. */
133
+ expectOn(page: string): void;
134
+ /** Assert the projected state contains these key/value pairs (deep). */
135
+ expectState(partial: Partial<State> & Record<string, unknown>): void;
136
+ /** Assert an action (by id or bare/leaf suffix) is available right now. */
137
+ expectAvailable(affordanceId: string): void;
138
+ /** Assert a FireResult was refused (optionally with a specific reason, e.g. 'GUARD_FAILED'). */
139
+ expectRejected(result: FireResult, reason?: string): void;
140
+ /** Assert a skill has a completed frame in the history. */
141
+ expectSkillCompleted(skillId: string): void;
142
+ /** Assert no declared-effect drift (optionally also fail on any gaps). The opt-in release gate. */
143
+ expectClean(opts?: {
144
+ includeGaps?: boolean;
145
+ }): void;
146
+ }
147
+ /**
148
+ * Build a headless test harness over a navigation graph. Wires each resolver as
149
+ * a real handler, auto-mounts the current page's tools, and drives the real
150
+ * session — so tests exercise production code, not a copy.
151
+ */
152
+ export declare function testApp<State extends Record<string, unknown> = Record<string, unknown>>(graph: NavigationGraph, options?: TestAppOptions<State>): TestApp<State>;
153
+ export declare function testApp<State extends Record<string, unknown> = Record<string, unknown>>(options: TestAppOptions<State> & {
154
+ session: InteractionSession;
155
+ }): TestApp<State>;
156
+ //# sourceMappingURL=harness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../../src/testing/harness.ts"],"names":[],"mappings":"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"}