@e2edev/e2e 0.10.0 → 0.12.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 (269) hide show
  1. package/README.md +14 -8
  2. package/dist/agent/act-validation.d.ts +2 -0
  3. package/dist/agent/act-validation.d.ts.map +1 -1
  4. package/dist/agent/act-validation.js +1 -1
  5. package/dist/agent/act-validation.js.map +1 -1
  6. package/dist/agent/act.d.ts +30 -2
  7. package/dist/agent/act.d.ts.map +1 -1
  8. package/dist/agent/act.js +18 -4
  9. package/dist/agent/act.js.map +1 -1
  10. package/dist/agent/ai-sdk.d.ts +2 -2
  11. package/dist/agent/ai-sdk.d.ts.map +1 -1
  12. package/dist/agent/ai-sdk.js +3 -4
  13. package/dist/agent/ai-sdk.js.map +1 -1
  14. package/dist/agent/default-agent.d.ts +33 -9
  15. package/dist/agent/default-agent.d.ts.map +1 -1
  16. package/dist/agent/default-agent.js +46 -31
  17. package/dist/agent/default-agent.js.map +1 -1
  18. package/dist/agent/error.d.ts.map +1 -1
  19. package/dist/agent/error.js +1 -0
  20. package/dist/agent/error.js.map +1 -1
  21. package/dist/agent/executor.d.ts +13 -0
  22. package/dist/agent/executor.d.ts.map +1 -1
  23. package/dist/agent/executor.js.map +1 -1
  24. package/dist/agent/interactive-step.d.ts +38 -0
  25. package/dist/agent/interactive-step.d.ts.map +1 -0
  26. package/dist/agent/interactive-step.js +131 -0
  27. package/dist/agent/interactive-step.js.map +1 -0
  28. package/dist/agent/model/adapter.d.ts +3 -0
  29. package/dist/agent/model/adapter.d.ts.map +1 -1
  30. package/dist/agent/model/adapter.js.map +1 -1
  31. package/dist/agent/model/overflow.d.ts +20 -0
  32. package/dist/agent/model/overflow.d.ts.map +1 -0
  33. package/dist/agent/model/overflow.js +82 -0
  34. package/dist/agent/model/overflow.js.map +1 -0
  35. package/dist/agent/model/prompt-cache.d.ts +47 -0
  36. package/dist/agent/model/prompt-cache.d.ts.map +1 -0
  37. package/dist/agent/model/prompt-cache.js +78 -0
  38. package/dist/agent/model/prompt-cache.js.map +1 -0
  39. package/dist/agent/model/sdk.d.ts +41 -24
  40. package/dist/agent/model/sdk.d.ts.map +1 -1
  41. package/dist/agent/model/sdk.js +64 -91
  42. package/dist/agent/model/sdk.js.map +1 -1
  43. package/dist/agent/model/tool-choice.d.ts +21 -0
  44. package/dist/agent/model/tool-choice.d.ts.map +1 -0
  45. package/dist/agent/model/tool-choice.js +49 -0
  46. package/dist/agent/model/tool-choice.js.map +1 -0
  47. package/dist/agent/primitives.d.ts.map +1 -1
  48. package/dist/agent/primitives.js +2 -1
  49. package/dist/agent/primitives.js.map +1 -1
  50. package/dist/agent/public.d.ts +1 -1
  51. package/dist/agent/public.d.ts.map +1 -1
  52. package/dist/agent/public.js.map +1 -1
  53. package/dist/agent/screen-update.d.ts +8 -3
  54. package/dist/agent/screen-update.d.ts.map +1 -1
  55. package/dist/agent/screen-update.js +18 -5
  56. package/dist/agent/screen-update.js.map +1 -1
  57. package/dist/agent/tool-loop.d.ts +4 -4
  58. package/dist/agent/tool-loop.d.ts.map +1 -1
  59. package/dist/agent/tool-loop.js +241 -48
  60. package/dist/agent/tool-loop.js.map +1 -1
  61. package/dist/agent/tool-output.d.ts +31 -0
  62. package/dist/agent/tool-output.d.ts.map +1 -0
  63. package/dist/agent/tool-output.js +60 -0
  64. package/dist/agent/tool-output.js.map +1 -0
  65. package/dist/agent/tool.d.ts +9 -3
  66. package/dist/agent/tool.d.ts.map +1 -1
  67. package/dist/agent/tool.js +2 -2
  68. package/dist/agent/tool.js.map +1 -1
  69. package/dist/agent/usage.d.ts +7 -0
  70. package/dist/agent/usage.d.ts.map +1 -1
  71. package/dist/agent/usage.js +11 -0
  72. package/dist/agent/usage.js.map +1 -1
  73. package/dist/cli/docs-url.d.ts +1 -1
  74. package/dist/cli/docs-url.d.ts.map +1 -1
  75. package/dist/cli/docs-url.js +1 -1
  76. package/dist/cli/docs-url.js.map +1 -1
  77. package/dist/cli/index.d.ts.map +1 -1
  78. package/dist/cli/index.js +139 -35
  79. package/dist/cli/index.js.map +1 -1
  80. package/dist/cli/init/engine-versions.json +1 -1
  81. package/dist/cli/init/engines.d.ts +17 -16
  82. package/dist/cli/init/engines.d.ts.map +1 -1
  83. package/dist/cli/init/engines.js +26 -26
  84. package/dist/cli/init/engines.js.map +1 -1
  85. package/dist/cli/init/gateways.d.ts +22 -0
  86. package/dist/cli/init/gateways.d.ts.map +1 -0
  87. package/dist/cli/init/gateways.js +50 -0
  88. package/dist/cli/init/gateways.js.map +1 -0
  89. package/dist/cli/init/mcp-config.d.ts +31 -0
  90. package/dist/cli/init/mcp-config.d.ts.map +1 -0
  91. package/dist/cli/init/mcp-config.js +72 -0
  92. package/dist/cli/init/mcp-config.js.map +1 -0
  93. package/dist/cli/init/scaffold.d.ts +8 -2
  94. package/dist/cli/init/scaffold.d.ts.map +1 -1
  95. package/dist/cli/init/scaffold.js +22 -11
  96. package/dist/cli/init/scaffold.js.map +1 -1
  97. package/dist/cli/init.d.ts.map +1 -1
  98. package/dist/cli/init.js +109 -29
  99. package/dist/cli/init.js.map +1 -1
  100. package/dist/cli/mcp.d.ts +15 -0
  101. package/dist/cli/mcp.d.ts.map +1 -0
  102. package/dist/cli/mcp.js +63 -0
  103. package/dist/cli/mcp.js.map +1 -0
  104. package/dist/collect/collect.d.ts +7 -0
  105. package/dist/collect/collect.d.ts.map +1 -1
  106. package/dist/collect/collect.js +16 -0
  107. package/dist/collect/collect.js.map +1 -1
  108. package/dist/collect/registry.d.ts.map +1 -1
  109. package/dist/collect/registry.js +33 -6
  110. package/dist/collect/registry.js.map +1 -1
  111. package/dist/collect/select.d.ts +9 -2
  112. package/dist/collect/select.d.ts.map +1 -1
  113. package/dist/collect/select.js +57 -11
  114. package/dist/collect/select.js.map +1 -1
  115. package/dist/config/agent.d.ts +13 -32
  116. package/dist/config/agent.d.ts.map +1 -1
  117. package/dist/config/agent.js +32 -123
  118. package/dist/config/agent.js.map +1 -1
  119. package/dist/config/resolve.d.ts +8 -5
  120. package/dist/config/resolve.d.ts.map +1 -1
  121. package/dist/config/resolve.js +11 -9
  122. package/dist/config/resolve.js.map +1 -1
  123. package/dist/credentials.d.ts +6 -0
  124. package/dist/credentials.d.ts.map +1 -1
  125. package/dist/credentials.js +9 -0
  126. package/dist/credentials.js.map +1 -1
  127. package/dist/explore/body.d.ts +36 -0
  128. package/dist/explore/body.d.ts.map +1 -0
  129. package/dist/explore/body.js +168 -0
  130. package/dist/explore/body.js.map +1 -0
  131. package/dist/explore/executor.d.ts +25 -0
  132. package/dist/explore/executor.d.ts.map +1 -0
  133. package/dist/explore/executor.js +86 -0
  134. package/dist/explore/executor.js.map +1 -0
  135. package/dist/explore/index.d.ts +64 -0
  136. package/dist/explore/index.d.ts.map +1 -0
  137. package/dist/explore/index.js +185 -0
  138. package/dist/explore/index.js.map +1 -0
  139. package/dist/explore/plan.d.ts +74 -0
  140. package/dist/explore/plan.d.ts.map +1 -0
  141. package/dist/explore/plan.js +149 -0
  142. package/dist/explore/plan.js.map +1 -0
  143. package/dist/explore/reporter.d.ts +11 -0
  144. package/dist/explore/reporter.d.ts.map +1 -0
  145. package/dist/explore/reporter.js +54 -0
  146. package/dist/explore/reporter.js.map +1 -0
  147. package/dist/explore/state.d.ts +58 -0
  148. package/dist/explore/state.d.ts.map +1 -0
  149. package/dist/explore/state.js +147 -0
  150. package/dist/explore/state.js.map +1 -0
  151. package/dist/internal/ai-trace.d.ts +2 -0
  152. package/dist/internal/ai-trace.d.ts.map +1 -1
  153. package/dist/internal/ai-trace.js +3 -0
  154. package/dist/internal/ai-trace.js.map +1 -1
  155. package/dist/internal/ids.d.ts +2 -2
  156. package/dist/internal/ids.d.ts.map +1 -1
  157. package/dist/internal/ids.js +3 -3
  158. package/dist/internal/ids.js.map +1 -1
  159. package/dist/internal/package-manager.d.ts +4 -0
  160. package/dist/internal/package-manager.d.ts.map +1 -1
  161. package/dist/internal/package-manager.js +26 -0
  162. package/dist/internal/package-manager.js.map +1 -1
  163. package/dist/mcp/catalog.d.ts +50 -0
  164. package/dist/mcp/catalog.d.ts.map +1 -0
  165. package/dist/mcp/catalog.js +172 -0
  166. package/dist/mcp/catalog.js.map +1 -0
  167. package/dist/mcp/config.d.ts +11 -0
  168. package/dist/mcp/config.d.ts.map +1 -0
  169. package/dist/mcp/config.js +16 -0
  170. package/dist/mcp/config.js.map +1 -0
  171. package/dist/mcp/server.d.ts +29 -0
  172. package/dist/mcp/server.d.ts.map +1 -0
  173. package/dist/mcp/server.js +86 -0
  174. package/dist/mcp/server.js.map +1 -0
  175. package/dist/mcp/session.d.ts +68 -0
  176. package/dist/mcp/session.d.ts.map +1 -0
  177. package/dist/mcp/session.js +317 -0
  178. package/dist/mcp/session.js.map +1 -0
  179. package/dist/mcp/tools.d.ts +77 -0
  180. package/dist/mcp/tools.d.ts.map +1 -0
  181. package/dist/mcp/tools.js +179 -0
  182. package/dist/mcp/tools.js.map +1 -0
  183. package/dist/report/build.d.ts +61 -0
  184. package/dist/report/build.d.ts.map +1 -1
  185. package/dist/report/build.js +13 -2
  186. package/dist/report/build.js.map +1 -1
  187. package/dist/report/debug-steps.d.ts.map +1 -1
  188. package/dist/report/debug-steps.js +15 -0
  189. package/dist/report/debug-steps.js.map +1 -1
  190. package/dist/report/format.d.ts +30 -1
  191. package/dist/report/format.d.ts.map +1 -1
  192. package/dist/report/format.js +57 -3
  193. package/dist/report/format.js.map +1 -1
  194. package/dist/report/junit.d.ts.map +1 -1
  195. package/dist/report/junit.js +4 -1
  196. package/dist/report/junit.js.map +1 -1
  197. package/dist/report/list.d.ts +10 -1
  198. package/dist/report/list.d.ts.map +1 -1
  199. package/dist/report/list.js +35 -13
  200. package/dist/report/list.js.map +1 -1
  201. package/dist/run/events.d.ts +13 -4
  202. package/dist/run/events.d.ts.map +1 -1
  203. package/dist/run/events.js.map +1 -1
  204. package/dist/run/execute.d.ts +2 -2
  205. package/dist/run/execute.d.ts.map +1 -1
  206. package/dist/run/execute.js +19 -14
  207. package/dist/run/execute.js.map +1 -1
  208. package/dist/run/fixtures.d.ts +10 -4
  209. package/dist/run/fixtures.d.ts.map +1 -1
  210. package/dist/run/fixtures.js +23 -23
  211. package/dist/run/fixtures.js.map +1 -1
  212. package/dist/run/in-process.d.ts +8 -0
  213. package/dist/run/in-process.d.ts.map +1 -1
  214. package/dist/run/in-process.js +7 -6
  215. package/dist/run/in-process.js.map +1 -1
  216. package/dist/run/provision.d.ts +51 -0
  217. package/dist/run/provision.d.ts.map +1 -0
  218. package/dist/run/provision.js +94 -0
  219. package/dist/run/provision.js.map +1 -0
  220. package/dist/run/records.d.ts +4 -0
  221. package/dist/run/records.d.ts.map +1 -1
  222. package/dist/run/runner.d.ts +25 -3
  223. package/dist/run/runner.d.ts.map +1 -1
  224. package/dist/run/runner.js +38 -81
  225. package/dist/run/runner.js.map +1 -1
  226. package/dist/run/scheduler.d.ts +5 -2
  227. package/dist/run/scheduler.d.ts.map +1 -1
  228. package/dist/run/scheduler.js +13 -10
  229. package/dist/run/scheduler.js.map +1 -1
  230. package/dist/run/serial.d.ts +1 -1
  231. package/dist/run/serial.d.ts.map +1 -1
  232. package/dist/run/serial.js +7 -2
  233. package/dist/run/serial.js.map +1 -1
  234. package/dist/run/standalone.d.ts +63 -0
  235. package/dist/run/standalone.d.ts.map +1 -0
  236. package/dist/run/standalone.js +152 -0
  237. package/dist/run/standalone.js.map +1 -0
  238. package/dist/run/steps.d.ts +7 -0
  239. package/dist/run/steps.d.ts.map +1 -1
  240. package/dist/run/steps.js.map +1 -1
  241. package/dist/run/units.d.ts +6 -3
  242. package/dist/run/units.d.ts.map +1 -1
  243. package/dist/run/units.js +0 -0
  244. package/dist/run/units.js.map +1 -1
  245. package/dist/run/worker/entry.js +2 -2
  246. package/dist/run/worker/entry.js.map +1 -1
  247. package/dist/run/worker/protocol.d.ts +5 -0
  248. package/dist/run/worker/protocol.d.ts.map +1 -1
  249. package/dist/run/worker/protocol.js.map +1 -1
  250. package/dist/run/worker/session.d.ts +3 -4
  251. package/dist/run/worker/session.d.ts.map +1 -1
  252. package/dist/run/worker/session.js +5 -4
  253. package/dist/run/worker/session.js.map +1 -1
  254. package/dist/run/worker-models.d.ts +4 -4
  255. package/dist/run/worker-models.js +6 -13
  256. package/dist/run/worker-models.js.map +1 -1
  257. package/dist/telemetry/events.d.ts.map +1 -1
  258. package/dist/telemetry/events.js +17 -2
  259. package/dist/telemetry/events.js.map +1 -1
  260. package/dist/types.d.ts +20 -20
  261. package/dist/types.d.ts.map +1 -1
  262. package/package.json +9 -6
  263. package/skills/e2e/SKILL.md +16 -6
  264. package/skills/e2e/references/agent.md +21 -16
  265. package/skills/e2e/references/debugging.md +2 -1
  266. package/skills/e2e/references/explore.md +83 -0
  267. package/skills/e2e/references/mcp.md +88 -0
  268. package/skills/e2e/references/running.md +7 -5
  269. package/skills/e2e/references/setup.md +17 -13
@@ -0,0 +1,185 @@
1
+ /**
2
+ * `e2e explore`: a run whose one test is a goal. The project config is loaded
3
+ * as `run` loads it, the explorer replaces the executor of the agent the run
4
+ * uses, and the exploration body is registered in memory as the run's only
5
+ * test, so the reporters, `report.json`, artifacts, video, the AI trace, and
6
+ * the exit codes are the runner's own. The record of the exploration rides
7
+ * along as `run.explore`.
8
+ */
9
+ import { MAX_PARAMS_BYTES } from '../agent/act-validation.js';
10
+ import { isStepExecutor } from '../agent/executor.js';
11
+ import { selectTargets } from '../collect/select.js';
12
+ import { discoverConfig, loadConfigModule, missingConfigError } from '../config/load.js';
13
+ import { resolveConfig } from '../config/resolve.js';
14
+ import { ConfigurationError } from '../internal/errors.js';
15
+ import { run } from '../run/runner.js';
16
+ import { createExploreBody } from './body.js';
17
+ import { createExplorer } from './executor.js';
18
+ import { exploreReporter } from './reporter.js';
19
+ import { ExploreState } from './state.js';
20
+ const DEFAULT_GOAL = 'Explore the app and find bugs';
21
+ /** Exploration steps per run: breadth first, and diminishing returns come fast. */
22
+ export const STEP_BOUNDS = { min: 1, max: 12, default: 8 };
23
+ /** The run's wall clock in milliseconds: three to fifteen minutes. */
24
+ export const TIMEOUT_BOUNDS = { min: 180_000, max: 900_000, default: 600_000 };
25
+ const MAX_GOAL_CHARS = 2_000;
26
+ /** Each step's action and model-call budget when the config sets none: a charter is longer than a scripted step. */
27
+ const DEFAULT_STEP_BUDGET = 40;
28
+ /** One charter's own deadline; the run's remaining time caps it. */
29
+ const STEP_TIMEOUT_MS = 240_000;
30
+ /** Added to the test timeout so the body's own clock ends the exploration before the attempt's does. */
31
+ const TIMEOUT_GRACE_MS = 60_000;
32
+ /** The virtual file the report and the reporters show for the exploration. */
33
+ const EXPLORE_FILE = 'explore';
34
+ /**
35
+ * Every charter carries every configured account as a step parameter, and
36
+ * step parameters have a size limit. The inventory takes at most a quarter of
37
+ * it, leaving room for the findings that ride along, so an oversized one is a
38
+ * configuration error before anything starts and not a failed first step.
39
+ */
40
+ const MAX_CREDENTIAL_BYTES = MAX_PARAMS_BYTES / 4;
41
+ /**
42
+ * Runs one exploration and returns the run's outcome with the exploration
43
+ * record. The config is resolved once here, with the agent `--agent` named,
44
+ * so the target, the agent the explorer is built from, and the credential
45
+ * inventory are what the run resolves too; a config that does not resolve,
46
+ * an unknown agent, or an unknown target is an error before anything starts,
47
+ * as a bad flag is.
48
+ */
49
+ export async function explore(options = {}) {
50
+ const cwd = options.cwd ?? process.cwd();
51
+ const env = options.env ?? process.env;
52
+ const notice = options.notice ?? (() => undefined);
53
+ const goal = resolveGoal(options.goal);
54
+ const budgets = {
55
+ maxSteps: resolveBounded(options.maxSteps, STEP_BOUNDS, 'maxSteps'),
56
+ timeoutMs: resolveBounded(options.timeoutMs, TIMEOUT_BOUNDS, 'timeout'),
57
+ };
58
+ const { raw, projectRoot } = await loadRawConfig(options, cwd);
59
+ // Nothing replays an exploration, and a retry would explore twice.
60
+ const rawConfig = { ...raw, cache: 'off', retries: 0 };
61
+ const resolved = resolveConfig(rawConfig, { projectRoot, env, cli: options.agent === undefined ? {} : { agents: [options.agent] } });
62
+ const target = pickTarget(resolved.targets, options.target, notice);
63
+ const accounts = credentialAccounts(resolved.credentials);
64
+ // An exploration runs as exactly one agent: the one named, else `default`.
65
+ const agentName = resolved.agentNames[0];
66
+ if (agentName !== 'default')
67
+ notice(`exploring with agent "${agentName}"`);
68
+ const state = new ExploreState(goal, budgets);
69
+ const explorer = createExplorer({ state, from: resolved.agent.executor, notice });
70
+ const outcome = await run({
71
+ cwd: projectRoot,
72
+ rawConfig: {
73
+ ...rawConfig,
74
+ agents: { ...rawConfig.agents, [agentName]: exploreAgentConfig(rawConfig.agents?.[agentName], explorer) },
75
+ reporters: [...(rawConfig.reporters ?? ['list']), exploreReporter(state)],
76
+ },
77
+ agent: options.agent,
78
+ env,
79
+ tests: {
80
+ file: EXPLORE_FILE,
81
+ registration: exploreRegistration(state, target.app.base !== undefined, accounts),
82
+ explore: () => state.snapshot(),
83
+ },
84
+ targetIds: [target.name],
85
+ headed: options.headed,
86
+ reporters: options.reporters,
87
+ artifactsDir: options.artifactsDir,
88
+ debug: options.debug,
89
+ aiTrace: options.aiTrace,
90
+ video: options.video,
91
+ interruptSignal: options.interruptSignal,
92
+ forceSignal: options.forceSignal,
93
+ });
94
+ return { ...outcome, explore: state.snapshot() };
95
+ }
96
+ async function loadRawConfig(options, cwd) {
97
+ if (options.rawConfig !== undefined)
98
+ return { raw: options.rawConfig, projectRoot: cwd };
99
+ const discovered = discoverConfig(cwd, options.configPath);
100
+ if (discovered.configPath === undefined)
101
+ throw missingConfigError(cwd);
102
+ return { raw: await loadConfigModule(discovered.configPath), projectRoot: discovered.projectRoot };
103
+ }
104
+ function resolveGoal(goal) {
105
+ const trimmed = goal?.trim() ?? '';
106
+ if (trimmed === '')
107
+ return DEFAULT_GOAL;
108
+ if (trimmed.length > MAX_GOAL_CHARS) {
109
+ throw new ConfigurationError('INVALID_CONFIG', `the goal must be at most ${MAX_GOAL_CHARS} characters, got ${trimmed.length}`);
110
+ }
111
+ return trimmed;
112
+ }
113
+ function resolveBounded(value, bounds, label) {
114
+ if (value === undefined)
115
+ return bounds.default;
116
+ if (!Number.isSafeInteger(value) || value < bounds.min || value > bounds.max) {
117
+ throw new ConfigurationError('INVALID_CONFIG', `${label} must be an integer from ${bounds.min} through ${bounds.max}, got ${String(value)}`);
118
+ }
119
+ return value;
120
+ }
121
+ /**
122
+ * The target to explore: the one `--target` names (an unknown one is
123
+ * `UNKNOWN_TARGET`, as for `run`), else the first configured, with a notice
124
+ * when there are several.
125
+ */
126
+ function pickTarget(targets, requested, notice) {
127
+ const chosen = selectTargets(targets, requested === undefined ? undefined : [requested])[0];
128
+ if (chosen === undefined)
129
+ throw new Error('unreachable: a resolved config declares at least one target');
130
+ if (requested === undefined && targets.length > 1) {
131
+ notice(`exploring target "${chosen.name}"; pass --target to explore another`);
132
+ }
133
+ return chosen;
134
+ }
135
+ /**
136
+ * The agent block the exploration runs as: the project's own options with the
137
+ * explorer as the executor, and per-step budgets that default higher than a
138
+ * scripted step's, a charter being longer. A bare executor has no options to
139
+ * keep; the explorer already lent from it what it could.
140
+ */
141
+ function exploreAgentConfig(entry, explorer) {
142
+ const block = entry === undefined || isStepExecutor(entry) ? {} : entry;
143
+ return {
144
+ ...block,
145
+ executor: explorer,
146
+ maxSteps: block.maxSteps ?? DEFAULT_STEP_BUDGET,
147
+ maxModelCalls: block.maxModelCalls ?? DEFAULT_STEP_BUDGET,
148
+ };
149
+ }
150
+ /**
151
+ * The accounts every charter carries, bounded to what a step parameter holds.
152
+ * Measured as the step sees them: the usernames and the secret placeholders
153
+ * the passwords become there.
154
+ */
155
+ function credentialAccounts(credentials) {
156
+ const accounts = [...credentials.values()].map((credential) => ({ name: credential.name, username: credential.username }));
157
+ const carried = Object.fromEntries(accounts.map((account) => [account.name, { username: account.username, password: { kind: 'secret', name: account.name, purpose: 'password' } }]));
158
+ const bytes = Buffer.byteLength(JSON.stringify({ credentials: carried }));
159
+ if (bytes > MAX_CREDENTIAL_BYTES) {
160
+ throw new ConfigurationError('INVALID_CONFIG', `explore carries every configured credential into each step: ${String(accounts.length)} account(s) serialize to ${String(bytes)} bytes, the maximum is ${String(MAX_CREDENTIAL_BYTES)}; explore with a config that declares fewer`);
161
+ }
162
+ return accounts;
163
+ }
164
+ /** The one-test registration: the goal is the title, the body is the exploration loop. */
165
+ function exploreRegistration(state, openApp, accounts) {
166
+ const title = state.goal;
167
+ const test = {
168
+ kind: 'test',
169
+ title,
170
+ titlePath: [title],
171
+ declarationIndex: 0,
172
+ options: {
173
+ timeout: state.budgets.timeoutMs + TIMEOUT_GRACE_MS,
174
+ retries: 0,
175
+ agentContext: `Exploration goal: ${state.goal}`,
176
+ },
177
+ sessions: [],
178
+ fn: createExploreBody({ state, stepTimeoutMs: STEP_TIMEOUT_MS, openApp, accounts }),
179
+ group: undefined,
180
+ mode: 'normal',
181
+ source: undefined,
182
+ };
183
+ return { tests: [test], hooks: [] };
184
+ }
185
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/explore/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * The planner: between exploration steps, one structured model call decides
3
+ * the next charter or finishes the run. It runs as an `agent.extract` step,
4
+ * so it reads the current screen and the ledger of prior steps the same way
5
+ * every judgment does, under the same budgets and repair loop.
6
+ */
7
+ import { z } from 'zod';
8
+ import type { Agent } from '../types.ts';
9
+ import { type ExploreState } from './state.ts';
10
+ /**
11
+ * A flat object with every field required rather than a union: OpenAI's
12
+ * strict structured output rejects a schema whose `required` omits a
13
+ * property, and every provider renders a flat object. Fields the decision
14
+ * does not use are empty strings. The shape is lenient on purpose: a model
15
+ * that puts the whole charter into `title` and leaves `instruction` empty
16
+ * (seen live) has still planned a step, and `repairPlan` derives the missing
17
+ * field rather than spending the repair round on it.
18
+ */
19
+ export declare const PLAN_SCHEMA: z.ZodObject<{
20
+ decision: z.ZodEnum<{
21
+ finish: "finish";
22
+ step: "step";
23
+ }>;
24
+ title: z.ZodString;
25
+ instruction: z.ZodString;
26
+ summary: z.ZodString;
27
+ }, z.core.$strip>;
28
+ type PlanAnswer = z.output<typeof PLAN_SCHEMA>;
29
+ export type PlanDecision = {
30
+ readonly kind: 'step';
31
+ readonly title: string;
32
+ readonly instruction: string;
33
+ } | {
34
+ readonly kind: 'finish';
35
+ readonly summary: string;
36
+ };
37
+ /** One configured credential the explorer can sign in with, by name; the password stays out of every prompt. */
38
+ export interface PlanAccount {
39
+ readonly name: string;
40
+ readonly username: string;
41
+ }
42
+ export interface PlanRequest {
43
+ /** The run must end now; the planner is asked for the closing assessment only. */
44
+ readonly mustFinish: boolean;
45
+ /** The accounts the explorer can sign in with. */
46
+ readonly accounts?: readonly PlanAccount[] | undefined;
47
+ /** Why it must end, in the planner's prompt. */
48
+ readonly reason?: string | undefined;
49
+ readonly remainingMs: number;
50
+ readonly timeoutMs: number;
51
+ }
52
+ /** Asks the model for the next charter or the closing assessment. */
53
+ export declare function planNext(agent: Agent, state: ExploreState, request: PlanRequest): Promise<PlanDecision>;
54
+ /**
55
+ * The decision, after the repairs live providers' answers have needed. Every
56
+ * repair the planner makes is here:
57
+ *
58
+ * - Digit runs a provider pads a field with (seen live: a title followed by
59
+ * hundreds of `1234567890`) are removed; they carry no meaning and would
60
+ * otherwise become the charter's tail. The threshold sits past any number a
61
+ * charter can mean: phone numbers, order ids, card numbers, and amounts all
62
+ * stop short of twenty digits.
63
+ * - A step with only one of `title` and `instruction` filled has the other
64
+ * derived: a charter with no title takes its first clause, a title with no
65
+ * charter is the charter.
66
+ *
67
+ * Length is not repaired here: the grammar accepts long fields, and the state
68
+ * clips them to the report's ceilings when the step opens.
69
+ */
70
+ export declare function repairPlan(answer: PlanAnswer): PlanDecision;
71
+ /** The planner's instruction: the goal, the record so far, the budget, and how to decide. */
72
+ export declare function planInstruction(state: ExploreState, request: PlanRequest): string;
73
+ export {};
74
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/explore/plan.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAahE;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW;;;;;;;;iBAepB,CAAC;AAEL,KAAK,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AAE/C,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC/E;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1D,gHAAgH;AAChH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,kFAAkF;IAClF,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,kDAAkD;IAClD,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,WAAW,EAAE,GAAG,SAAS,CAAC;IACvD,gDAAgD;IAChD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,qEAAqE;AACrE,wBAAsB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAE7G;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CAS3D;AAmBD,6FAA6F;AAC7F,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CA2DjF"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * The planner: between exploration steps, one structured model call decides
3
+ * the next charter or finishes the run. It runs as an `agent.extract` step,
4
+ * so it reads the current screen and the ledger of prior steps the same way
5
+ * every judgment does, under the same budgets and repair loop.
6
+ */
7
+ import { z } from 'zod';
8
+ import { MAX_TITLE_CHARS } from './state.js';
9
+ const MIN_SUMMARY_CHARS = 10;
10
+ /** A title derived from an instruction stops at the first clause or here. */
11
+ const DERIVED_TITLE_CHARS = 80;
12
+ /**
13
+ * The most the grammar accepts in one field. Well above the report's ceilings,
14
+ * which the state clips to when the step opens: a model that pours a whole
15
+ * charter into one field (seen live, past 2000 characters) has still planned
16
+ * a step, and a rejection would cost a repair round for nothing.
17
+ */
18
+ const MAX_FIELD_CHARS = 8_000;
19
+ /**
20
+ * A flat object with every field required rather than a union: OpenAI's
21
+ * strict structured output rejects a schema whose `required` omits a
22
+ * property, and every provider renders a flat object. Fields the decision
23
+ * does not use are empty strings. The shape is lenient on purpose: a model
24
+ * that puts the whole charter into `title` and leaves `instruction` empty
25
+ * (seen live) has still planned a step, and `repairPlan` derives the missing
26
+ * field rather than spending the repair round on it.
27
+ */
28
+ export const PLAN_SCHEMA = z
29
+ .object({
30
+ decision: z.enum(['step', 'finish']),
31
+ title: z.string().max(MAX_FIELD_CHARS).describe('For a step: the area or flow in a few words. Empty for finish.'),
32
+ instruction: z.string().max(MAX_FIELD_CHARS).describe('For a step: the concrete charter. Empty for finish.'),
33
+ summary: z.string().max(MAX_FIELD_CHARS).describe('For finish: the overall assessment. Empty for a step.'),
34
+ })
35
+ .superRefine((value, context) => {
36
+ if (value.decision === 'step') {
37
+ if (`${value.title}${value.instruction}`.trim() === '') {
38
+ context.addIssue({ code: 'custom', path: ['instruction'], message: 'a step needs a concrete instruction' });
39
+ }
40
+ }
41
+ else if (value.summary.trim().length < MIN_SUMMARY_CHARS) {
42
+ context.addIssue({ code: 'custom', path: ['summary'], message: 'finishing needs an overall assessment' });
43
+ }
44
+ });
45
+ /** Asks the model for the next charter or the closing assessment. */
46
+ export async function planNext(agent, state, request) {
47
+ return repairPlan(await agent.extract(planInstruction(state, request), { schema: PLAN_SCHEMA, timeout: request.timeoutMs }));
48
+ }
49
+ /**
50
+ * The decision, after the repairs live providers' answers have needed. Every
51
+ * repair the planner makes is here:
52
+ *
53
+ * - Digit runs a provider pads a field with (seen live: a title followed by
54
+ * hundreds of `1234567890`) are removed; they carry no meaning and would
55
+ * otherwise become the charter's tail. The threshold sits past any number a
56
+ * charter can mean: phone numbers, order ids, card numbers, and amounts all
57
+ * stop short of twenty digits.
58
+ * - A step with only one of `title` and `instruction` filled has the other
59
+ * derived: a charter with no title takes its first clause, a title with no
60
+ * charter is the charter.
61
+ *
62
+ * Length is not repaired here: the grammar accepts long fields, and the state
63
+ * clips them to the report's ceilings when the step opens.
64
+ */
65
+ export function repairPlan(answer) {
66
+ if (answer.decision === 'finish')
67
+ return { kind: 'finish', summary: unpad(answer.summary) };
68
+ const title = unpad(answer.title);
69
+ const instruction = unpad(answer.instruction);
70
+ const charter = instruction === '' ? title : instruction;
71
+ // A title that stood in for the charter is a heading only while it is short.
72
+ const longest = instruction === '' ? DERIVED_TITLE_CHARS : MAX_TITLE_CHARS;
73
+ const heading = title !== '' && title.length <= longest ? title : deriveTitle(charter);
74
+ return { kind: 'step', title: heading, instruction: charter };
75
+ }
76
+ function unpad(text) {
77
+ return text.replace(/\s*\d{20,}\s*/g, ' ').trim();
78
+ }
79
+ function deriveTitle(charter) {
80
+ const clause = charter.split(/[.:;\n]/, 1)[0].trim();
81
+ const short = clause === '' ? charter : clause;
82
+ return short.length <= DERIVED_TITLE_CHARS ? short : `${short.slice(0, DERIVED_TITLE_CHARS - 1)}…`;
83
+ }
84
+ const STATUS_MARKS = {
85
+ passed: 'passed',
86
+ failed: 'FAILED',
87
+ blocked: 'blocked',
88
+ exhausted: 'ended at its limit',
89
+ };
90
+ /** The planner's instruction: the goal, the record so far, the budget, and how to decide. */
91
+ export function planInstruction(state, request) {
92
+ const used = state.steps.length;
93
+ const minutesLeft = Math.max(0, Math.round(request.remainingMs / 60_000));
94
+ const steps = used === 0
95
+ ? '(none yet: this is the first step)'
96
+ : state.steps
97
+ .map((step) => `${step.index}. [${STATUS_MARKS[step.status]}] ${step.title}${step.summary === undefined ? '' : ` — ${step.summary}`}`)
98
+ .join('\n');
99
+ const findings = state.findings.length === 0
100
+ ? '(none yet)'
101
+ : state.findings.map((finding) => `- [${finding.kind}, severity ${finding.severity}] ${finding.title}`).join('\n');
102
+ const header = [
103
+ request.mustFinish
104
+ ? 'Finish an exploratory test run with your overall assessment.'
105
+ : 'Plan the next step of an exploratory test run, or finish it.',
106
+ '',
107
+ `Goal: ${state.goal}`,
108
+ `Budget: ${used} of ${state.budgets.maxSteps} steps used, about ${minutesLeft} minute(s) left.`,
109
+ '',
110
+ 'Steps so far:',
111
+ steps,
112
+ '',
113
+ 'Findings so far:',
114
+ findings,
115
+ ...(request.accounts === undefined || request.accounts.length === 0
116
+ ? []
117
+ : [
118
+ '',
119
+ 'Accounts the agent can sign in with (it fills the password itself, by name):',
120
+ ...request.accounts.map((account) => `- ${account.name} (username: ${account.username})`),
121
+ ]),
122
+ '',
123
+ ];
124
+ if (request.mustFinish) {
125
+ return [
126
+ ...header,
127
+ `The run must end now: ${request.reason ?? 'its budget is spent'}.`,
128
+ 'Respond with {"decision": "finish", "title": "", "instruction": "", "summary": "..."}: the overall assessment in two to five sentences,',
129
+ 'what was explored, the key findings, and your verdict on the goal. Ground it in the steps and findings above.',
130
+ ].join('\n');
131
+ }
132
+ return [
133
+ ...header,
134
+ 'Decide from the goal, the steps so far, and the current screen:',
135
+ '- "step": the next exploration charter. "title" names the area or flow in a few words. "instruction" is a concrete,',
136
+ ' self-contained charter for an agent that sees only the screen and that text: which flow to exercise, what inputs',
137
+ ' to try, what to check. One flow or screen per step, sized for five to fifteen actions; split anything bigger.',
138
+ ' Ask the agent to interact, not only to look: submit forms with made-up test data, save and revisit, sign in with',
139
+ ' the accounts listed above (or made-up credentials when none are configured), act on a non-first item of a list. Prefer breadth: touch the main',
140
+ ' flows the goal names before drilling deeper into one. Do not re-test an area a passed step already covered, and',
141
+ ' never plan a step to re-confirm a finding already recorded above. When a step ended at its limit, continue where',
142
+ ' it stopped or move on. When a step summary mentions something odd that is not among the findings, spend the next',
143
+ ' step confirming it.',
144
+ '- "finish": the goal is covered, or nothing new is reachable. "summary" is the overall assessment in two to',
145
+ ' five sentences: what was explored, the key findings, and your verdict on the goal.',
146
+ 'Respond with every field present: {"decision": "step", "title": "...", "instruction": "...", "summary": ""} or {"decision": "finish", "title": "", "instruction": "", "summary": "..."}.',
147
+ ].join('\n');
148
+ }
149
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/explore/plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The exploration summary under the run summary: a `Reporter` whose
3
+ * `onRunFinished` rows the list reporter prints, so the findings appear where
4
+ * a reporter's own rows do, and the JSON reporter is left to the report.
5
+ */
6
+ import type { Reporter, ReporterSummary } from '../types.ts';
7
+ import type { ExploreState } from './state.ts';
8
+ export declare function exploreReporter(state: ExploreState): Reporter;
9
+ /** The rows: what was explored, what was found, one row per finding, and the assessment. */
10
+ export declare function summaryRows(state: ExploreState): ReporterSummary;
11
+ //# sourceMappingURL=reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../../src/explore/reporter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,QAAQ,CAK7D;AAED,4FAA4F;AAC5F,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,eAAe,CAgChE"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * The exploration summary under the run summary: a `Reporter` whose
3
+ * `onRunFinished` rows the list reporter prints, so the findings appear where
4
+ * a reporter's own rows do, and the JSON reporter is left to the report.
5
+ */
6
+ export function exploreReporter(state) {
7
+ return {
8
+ name: 'explore',
9
+ onRunFinished: async () => summaryRows(state),
10
+ };
11
+ }
12
+ /** The rows: what was explored, what was found, one row per finding, and the assessment. */
13
+ export function summaryRows(state) {
14
+ const counts = { passed: 0, failed: 0, blocked: 0, exhausted: 0 };
15
+ for (const step of state.steps)
16
+ counts[step.status] += 1;
17
+ const parts = [
18
+ `${counts.passed} passed`,
19
+ ...(counts.failed > 0 ? [`${counts.failed} failed`] : []),
20
+ ...(counts.exhausted > 0 ? [`${counts.exhausted} ended at their limit`] : []),
21
+ ...(counts.blocked > 0 ? [`${counts.blocked} blocked`] : []),
22
+ ];
23
+ const issues = state.issues.length;
24
+ const warnings = state.findings.length - issues;
25
+ const rows = [
26
+ {
27
+ label: 'Explored',
28
+ text: `${state.steps.length} step${state.steps.length === 1 ? '' : 's'} (${parts.join(', ')}); ended: ${ENDED_TEXT[state.ended]}`,
29
+ },
30
+ {
31
+ label: 'Findings',
32
+ text: state.findings.length === 0
33
+ ? 'none'
34
+ : `${issues} issue${issues === 1 ? '' : 's'}, ${warnings} warning${warnings === 1 ? '' : 's'}`,
35
+ },
36
+ ];
37
+ for (const finding of [...state.findings].toSorted((a, b) => b.severity - a.severity || a.index - b.index)) {
38
+ rows.push({
39
+ label: ` S${finding.severity} ${finding.kind}`,
40
+ text: `${finding.title}${finding.path === undefined ? '' : ` (${finding.path})`}`,
41
+ });
42
+ }
43
+ if (state.summary !== undefined)
44
+ rows.push({ label: 'Assessment', text: state.summary });
45
+ return rows;
46
+ }
47
+ const ENDED_TEXT = {
48
+ finished: 'the agent covered the goal',
49
+ 'step-limit': 'the step limit was reached',
50
+ time: 'the time budget ran out',
51
+ stuck: 'steps kept failing',
52
+ aborted: 'the run was cut short',
53
+ };
54
+ //# sourceMappingURL=reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../src/explore/reporter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,MAAM,UAAU,eAAe,CAAC,KAAmB;IACjD,OAAO;QACL,IAAI,EAAE,SAAS;QACf,aAAa,EAAE,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,WAAW,CAAC,KAAmB;IAC7C,MAAM,MAAM,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IAClE,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK;QAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG;QACZ,GAAG,MAAM,CAAC,MAAM,SAAS;QACzB,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,SAAS,uBAAuB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,GAAG,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7D,CAAC;IACF,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;IACnC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;IAChD,MAAM,IAAI,GAAsC;QAC9C;YACE,KAAK,EAAE,UAAU;YACjB,IAAI,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,QAAQ,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;SAClI;QACD;YACE,KAAK,EAAE,UAAU;YACjB,IAAI,EACF,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;gBACzB,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,GAAG,MAAM,SAAS,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,QAAQ,WAAW,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE;SACnG;KACF,CAAC;IACF,KAAK,MAAM,OAAO,IAAI,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3G,IAAI,CAAC,IAAI,CAAC;YACR,KAAK,EAAE,MAAM,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE;YAC/C,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,GAAG,EAAE;SAClF,CAAC,CAAC;IACL,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;QAAE,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACzF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,GAA0C;IACxD,QAAQ,EAAE,4BAA4B;IACtC,YAAY,EAAE,4BAA4B;IAC1C,IAAI,EAAE,yBAAyB;IAC/B,KAAK,EAAE,oBAAoB;IAC3B,OAAO,EAAE,uBAAuB;CACjC,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * The record of one exploration: the goal, its budgets, the steps the agent
3
+ * planned and ran, and the findings it reported. One instance is shared by
4
+ * the planner, the explorer's finding tool, the exploration body, and the
5
+ * summary reporter, and its snapshot becomes `run.explore` in the report.
6
+ * The state is the report boundary: every free text is bounded to the
7
+ * schema's ceilings here, and nowhere else.
8
+ */
9
+ import type { ReportExplore, ReportExploreFinding, ReportExploreStep } from '../report/build.ts';
10
+ export interface ExploreBudgets {
11
+ readonly maxSteps: number;
12
+ readonly timeoutMs: number;
13
+ }
14
+ /** A finding as the tool reports it; the state assigns identity, position, and time. */
15
+ export type FindingInput = Omit<ReportExploreFinding, 'id' | 'index' | 'step' | 'reportedAt' | 'artifactId'>;
16
+ /** A step as opened: title and charter bounded to the report's ceilings, which is what the step runs with. */
17
+ export type OpenedStep = Pick<ReportExploreStep, 'index' | 'title' | 'instruction'>;
18
+ /** Ceilings mirroring `schema/report-v1.schema.json` `explore`. */
19
+ export declare const MAX_TITLE_CHARS = 200;
20
+ export declare class ExploreState {
21
+ #private;
22
+ readonly goal: string;
23
+ readonly budgets: ExploreBudgets;
24
+ private readonly now;
25
+ readonly steps: ReportExploreStep[];
26
+ readonly findings: ReportExploreFinding[];
27
+ constructor(goal: string, budgets: ExploreBudgets, now?: () => number);
28
+ /** Why exploration stopped; `aborted` until `end` says otherwise. */
29
+ get ended(): ReportExplore['ended'];
30
+ /** The agent's closing assessment, once it gave one. */
31
+ get summary(): string | undefined;
32
+ /** Opens the next step; the index is one-based. */
33
+ beginStep(title: string, instruction: string): OpenedStep;
34
+ /** Closes the open step with its outcome. */
35
+ endStep(status: ReportExploreStep['status'], summary?: string, errorCode?: string): ReportExploreStep;
36
+ /** Records one finding against the step in progress. */
37
+ addFinding(input: FindingInput): ReportExploreFinding;
38
+ /** Attaches the evidence screenshot kept for a finding, by its artifact id. */
39
+ attachEvidence(id: string, artifactId: string): void;
40
+ /** Closes the record: why exploration stopped and, when the agent gave one, its closing assessment. */
41
+ end(ended: ReportExplore['ended'], summary?: string): void;
42
+ get issues(): readonly ReportExploreFinding[];
43
+ /**
44
+ * How many steps in a row made no progress, newest first: failed or blocked
45
+ * without recording a finding. A failed step that reported a defect did its
46
+ * job, and a step that ended at its budget is a time-boxed charter, not a
47
+ * failure; neither breaks the streak nor adds to it.
48
+ */
49
+ consecutiveFailures(): number;
50
+ snapshot(): ReportExplore;
51
+ }
52
+ /**
53
+ * Trims and bounds free text so the report stays inside the schema's
54
+ * ceilings. Counted in code points, as the schema counts, so a cut never
55
+ * splits a surrogate pair.
56
+ */
57
+ export declare function clip(text: string, max: number): string;
58
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/explore/state.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEjG,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,wFAAwF;AACxF,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,oBAAoB,EAAE,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,YAAY,GAAG,YAAY,CAAC,CAAC;AAE7G,8GAA8G;AAC9G,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,EAAE,OAAO,GAAG,OAAO,GAAG,aAAa,CAAC,CAAC;AAEpF,mEAAmE;AACnE,eAAO,MAAM,eAAe,MAAM,CAAC;AAanC,qBAAa,YAAY;;IAQrB,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,OAAO,EAAE,cAAc;IAChC,OAAO,CAAC,QAAQ,CAAC,GAAG;IATtB,QAAQ,CAAC,KAAK,EAAE,iBAAiB,EAAE,CAAM;IACzC,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,EAAE,CAAM;IAK/C,YACW,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,EACf,GAAG,GAAE,MAAM,MAAiB,EAC3C;IAEJ,qEAAqE;IACrE,IAAI,KAAK,IAAI,aAAa,CAAC,OAAO,CAAC,CAElC;IAED,wDAAwD;IACxD,IAAI,OAAO,IAAI,MAAM,GAAG,SAAS,CAEhC;IAED,mDAAmD;IACnD,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,UAAU,CAWxD;IAED,6CAA6C;IAC7C,OAAO,CAAC,MAAM,EAAE,iBAAiB,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAgBpG;IAED,wDAAwD;IACxD,UAAU,CAAC,KAAK,EAAE,YAAY,GAAG,oBAAoB,CAiBpD;IAED,+EAA+E;IAC/E,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAInD;IAED,uGAAuG;IACvG,GAAG,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAGzD;IAED,IAAI,MAAM,IAAI,SAAS,oBAAoB,EAAE,CAE5C;IAED;;;;;OAKG;IACH,mBAAmB,IAAI,MAAM,CAU5B;IAED,QAAQ,IAAI,aAAa,CASxB;CACF;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAItD"}