@lasso-ai/cli 1.4.5 → 2.0.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 (59) hide show
  1. package/dist/cli/agent.d.ts +10 -89
  2. package/dist/cli/agent.js +66 -1412
  3. package/dist/cli/backends.d.ts +53 -0
  4. package/dist/cli/backends.js +267 -0
  5. package/dist/cli/bridge-old.d.ts +259 -0
  6. package/dist/cli/bridge-old.js +1350 -0
  7. package/dist/cli/bridge.d.ts +22 -12
  8. package/dist/cli/bridge.js +824 -1174
  9. package/dist/cli/host/install.js +12 -1
  10. package/dist/cli/host/next-host-entry.js +0 -2
  11. package/dist/cli/host/vite-host-entry.js +1 -3
  12. package/dist/cli/local-runtime.d.ts +28 -0
  13. package/dist/cli/local-runtime.js +294 -0
  14. package/dist/cli/oneshot.js +177 -961
  15. package/dist/cli/runtime-client.d.ts +310 -0
  16. package/dist/cli/runtime-client.js +178 -0
  17. package/dist/cli/snapshot.d.ts +3 -1
  18. package/dist/cli/snapshot.js +8 -1
  19. package/dist/overlay.js +44 -28
  20. package/dist/runtime/__tests__/adapter-normalization.test.d.ts +1 -0
  21. package/dist/runtime/__tests__/adapter-normalization.test.js +392 -0
  22. package/dist/runtime/__tests__/state-machine.test.d.ts +1 -0
  23. package/dist/runtime/__tests__/state-machine.test.js +107 -0
  24. package/dist/runtime/__tests__/verification-engine.test.d.ts +1 -0
  25. package/dist/runtime/__tests__/verification-engine.test.js +91 -0
  26. package/dist/runtime/__tests__/workspace-guard.test.d.ts +1 -0
  27. package/dist/runtime/__tests__/workspace-guard.test.js +104 -0
  28. package/dist/runtime/adapters/claude-code-adapter.d.ts +46 -0
  29. package/dist/runtime/adapters/claude-code-adapter.js +230 -0
  30. package/dist/runtime/adapters/codex-cli-adapter.d.ts +44 -0
  31. package/dist/runtime/adapters/codex-cli-adapter.js +202 -0
  32. package/dist/runtime/adapters/cursor-adapter.d.ts +47 -0
  33. package/dist/runtime/adapters/cursor-adapter.js +214 -0
  34. package/dist/runtime/adapters/factory.d.ts +19 -0
  35. package/dist/runtime/adapters/factory.js +48 -0
  36. package/dist/runtime/adapters/local-agent-adapter.d.ts +143 -0
  37. package/dist/runtime/adapters/local-agent-adapter.js +408 -0
  38. package/dist/runtime/adapters/opencode-adapter.d.ts +43 -0
  39. package/dist/runtime/adapters/opencode-adapter.js +210 -0
  40. package/dist/runtime/agent-runtime.d.ts +286 -0
  41. package/dist/runtime/agent-runtime.js +8 -0
  42. package/dist/runtime/agent-state-machine.d.ts +67 -0
  43. package/dist/runtime/agent-state-machine.js +234 -0
  44. package/dist/runtime/backend-interface.d.ts +272 -0
  45. package/dist/runtime/backend-interface.js +38 -0
  46. package/dist/runtime/event-mapper.d.ts +11 -0
  47. package/dist/runtime/event-mapper.js +40 -0
  48. package/dist/runtime/index.d.ts +20 -0
  49. package/dist/runtime/index.js +43 -0
  50. package/dist/runtime/local-session-runner.d.ts +60 -0
  51. package/dist/runtime/local-session-runner.js +185 -0
  52. package/dist/runtime/review.d.ts +24 -0
  53. package/dist/runtime/review.js +30 -0
  54. package/dist/runtime/verification-engine.d.ts +71 -0
  55. package/dist/runtime/verification-engine.js +374 -0
  56. package/dist/runtime/workspace-guard.d.ts +70 -0
  57. package/dist/runtime/workspace-guard.js +321 -0
  58. package/docs/local-coding-agents.md +183 -0
  59. package/package.json +22 -3
@@ -0,0 +1,286 @@
1
+ /**
2
+ * Lasso Agentic Runtime - Core Type Definitions
3
+ *
4
+ * This file defines all the core contracts for the Lasso-owned agentic runtime.
5
+ * The model is an interchangeable intelligence provider; Lasso owns the loop.
6
+ */
7
+ export type AgentPhase = "understand" | "inspect" | "plan" | "execute" | "verify" | "recover" | "complete";
8
+ export type AgentStatus = "running" | "waiting" | "completed" | "failed" | "cancelled";
9
+ export interface LassoAgentSession {
10
+ id: string;
11
+ phase: AgentPhase;
12
+ status: AgentStatus;
13
+ iteration: number;
14
+ userPrompt: string;
15
+ conversation: AgentMessage[];
16
+ observations: Observation[];
17
+ actions: AgentAction[];
18
+ completedActions: AgentAction[];
19
+ errors: AgentError[];
20
+ plan?: AgentPlan;
21
+ selection?: SelectionContext;
22
+ project: ProjectContext;
23
+ model: ModelMetadata;
24
+ createdAt: Date;
25
+ updatedAt: Date;
26
+ conversationUid?: string;
27
+ metadata?: Record<string, unknown>;
28
+ }
29
+ export interface AgentMessage {
30
+ id: string;
31
+ role: "user" | "assistant" | "system" | "tool";
32
+ content: string;
33
+ timestamp: number;
34
+ metadata?: Record<string, unknown>;
35
+ }
36
+ export interface SelectionContext {
37
+ element?: {
38
+ tag: string;
39
+ text?: string;
40
+ source?: string;
41
+ attributes?: Record<string, string>;
42
+ };
43
+ viewport?: {
44
+ width: number;
45
+ height: number;
46
+ scrollY?: number;
47
+ scrollHeight?: number;
48
+ };
49
+ route?: string;
50
+ screenshot?: string;
51
+ }
52
+ export interface ProjectContext {
53
+ projectId: string;
54
+ framework?: string;
55
+ hasTypeScript: boolean;
56
+ hasTailwind: boolean;
57
+ hasReact: boolean;
58
+ hasNext: boolean;
59
+ hasVite: boolean;
60
+ files: string[];
61
+ dependencies?: string[];
62
+ devDependencies?: string[];
63
+ currentRoute?: string;
64
+ sourceHints?: Record<string, string>;
65
+ pageContext?: {
66
+ route?: string;
67
+ title?: string;
68
+ viewport?: {
69
+ width: number;
70
+ height: number;
71
+ scrollY?: number;
72
+ scrollHeight?: number;
73
+ };
74
+ domSummary?: {
75
+ headings?: Array<{
76
+ level: number;
77
+ text: string;
78
+ }>;
79
+ sections?: Array<{
80
+ name: string;
81
+ textPreview: string;
82
+ }>;
83
+ buttons?: string[];
84
+ links?: string[];
85
+ visibleTextSnippet?: string;
86
+ };
87
+ runtimeErrors?: string[];
88
+ selectedElement?: SelectionContext["element"];
89
+ screenshot?: string;
90
+ };
91
+ }
92
+ export interface AgentPlan {
93
+ id: string;
94
+ goal: string;
95
+ steps: PlanStep[];
96
+ estimatedActions?: number;
97
+ createdAt: Date;
98
+ }
99
+ export interface PlanStep {
100
+ id: string;
101
+ description: string;
102
+ status: "pending" | "in_progress" | "completed" | "failed";
103
+ actionCount?: number;
104
+ }
105
+ export type ObservationType = "file" | "search" | "command" | "browser" | "build" | "runtime" | "error" | "verification" | "tool";
106
+ export interface Observation {
107
+ id: string;
108
+ type: ObservationType;
109
+ summary: string;
110
+ data?: unknown;
111
+ timestamp: number;
112
+ phase?: AgentPhase;
113
+ actionId?: string;
114
+ }
115
+ export type AgentAction = ReadFileAction | SearchCodeAction | InspectProjectAction | EditFileAction | CreateFileAction | DeleteFileAction | RunCommandAction | BrowserCheckAction;
116
+ export interface BaseAction {
117
+ id: string;
118
+ data: Record<string, unknown>;
119
+ }
120
+ export interface ReadFileAction extends BaseAction {
121
+ type: "read_file";
122
+ }
123
+ export interface SearchCodeAction extends BaseAction {
124
+ type: "search_code";
125
+ }
126
+ export interface InspectProjectAction extends BaseAction {
127
+ type: "inspect_project";
128
+ }
129
+ export interface EditFileAction extends BaseAction {
130
+ type: "edit_file";
131
+ }
132
+ export interface CreateFileAction extends BaseAction {
133
+ type: "create_file";
134
+ }
135
+ export interface DeleteFileAction extends BaseAction {
136
+ type: "delete_file";
137
+ }
138
+ export interface RunCommandAction extends BaseAction {
139
+ type: "run_command";
140
+ }
141
+ export interface BrowserCheckAction extends BaseAction {
142
+ type: "browser_check";
143
+ }
144
+ export interface AgentError {
145
+ id: string;
146
+ type: "validation" | "execution" | "verification" | "timeout" | "permission" | "unknown";
147
+ message: string;
148
+ phase: AgentPhase;
149
+ actionId?: string;
150
+ timestamp: number;
151
+ details?: Record<string, unknown>;
152
+ recoverable: boolean;
153
+ }
154
+ export interface ModelMetadata {
155
+ provider: "anthropic" | "openai" | "google" | "nvidia" | "ollama" | "claude_code" | "opencode" | "codex_cli" | "cursor";
156
+ id: string;
157
+ name?: string;
158
+ }
159
+ export interface LassoAgentContext {
160
+ session: {
161
+ id: string;
162
+ phase: AgentPhase;
163
+ iteration: number;
164
+ };
165
+ userPrompt: string;
166
+ conversation: AgentMessage[];
167
+ selection?: SelectionContext;
168
+ project: ProjectContext;
169
+ observations: Observation[];
170
+ previousActions: AgentAction[];
171
+ errors: AgentError[];
172
+ currentPlan?: AgentPlan;
173
+ availableTools: ToolDefinition[];
174
+ constraints: AgentConstraints;
175
+ }
176
+ export interface ToolDefinition {
177
+ name: string;
178
+ description: string;
179
+ allowedPhases: AgentPhase[];
180
+ parameters?: Record<string, unknown>;
181
+ }
182
+ export interface AgentConstraints {
183
+ maxActionsPerTurn: number;
184
+ allowedPhases: AgentPhase[];
185
+ maxFileSize?: number;
186
+ allowedCommands?: string[];
187
+ forbiddenPaths?: string[];
188
+ safetyLevel?: "strict" | "standard" | "permissive";
189
+ }
190
+ export interface LassoModelResponse {
191
+ status: "continue" | "waiting" | "complete" | "failed";
192
+ reasoning: {
193
+ summary: string;
194
+ };
195
+ decision: {
196
+ type: "inspect" | "plan" | "execute" | "verify" | "recover" | "ask_user";
197
+ goal: string;
198
+ };
199
+ actions: AgentAction[];
200
+ expectedOutcome?: string;
201
+ }
202
+ export type AgentEventType = "agent_started" | "agent_reasoning" | "agent_completed" | "agent_failed" | "agent_cancelled" | "phase_changed" | "tool_started" | "tool_completed" | "observation" | "plan_created" | "file_changed" | "verification_started" | "verification_completed" | "error" | "model_changed" | "waiting_for_user";
203
+ export interface AgentEvent {
204
+ type: AgentEventType;
205
+ sessionId: string;
206
+ timestamp: number;
207
+ data?: Record<string, unknown>;
208
+ }
209
+ export interface AgentReasoningEvent extends AgentEvent {
210
+ type: "agent_reasoning";
211
+ data: {
212
+ summary: string;
213
+ decision?: string;
214
+ };
215
+ }
216
+ export interface PhaseChangedEvent extends AgentEvent {
217
+ type: "phase_changed";
218
+ data: {
219
+ from: AgentPhase;
220
+ to: AgentPhase;
221
+ reason?: string;
222
+ };
223
+ }
224
+ export interface ToolStartedEvent extends AgentEvent {
225
+ type: "tool_started";
226
+ data: {
227
+ actionType: string;
228
+ target?: string;
229
+ };
230
+ }
231
+ export interface ToolCompletedEvent extends AgentEvent {
232
+ type: "tool_completed";
233
+ data: {
234
+ actionType: string;
235
+ target?: string;
236
+ success: boolean;
237
+ duration?: number;
238
+ };
239
+ }
240
+ export interface ObservationEvent extends AgentEvent {
241
+ type: "observation";
242
+ data: {
243
+ observationType: ObservationType;
244
+ summary: string;
245
+ details?: unknown;
246
+ };
247
+ }
248
+ export interface VerificationStartedEvent extends AgentEvent {
249
+ type: "verification_started";
250
+ data: {
251
+ verificationType: "typecheck" | "build" | "runtime" | "browser";
252
+ };
253
+ }
254
+ export interface VerificationCompletedEvent extends AgentEvent {
255
+ type: "verification_completed";
256
+ data: {
257
+ verificationType: "typecheck" | "build" | "runtime" | "browser";
258
+ success: boolean;
259
+ duration?: number;
260
+ errors?: string[];
261
+ };
262
+ }
263
+ export interface ErrorEvent extends AgentEvent {
264
+ type: "error";
265
+ data: {
266
+ errorType: string;
267
+ message: string;
268
+ phase: AgentPhase;
269
+ recoverable: boolean;
270
+ };
271
+ }
272
+ export interface ModelChangedEvent extends AgentEvent {
273
+ type: "model_changed";
274
+ data: {
275
+ from: ModelMetadata;
276
+ to: ModelMetadata;
277
+ };
278
+ }
279
+ export interface WaitingForUserEvent extends AgentEvent {
280
+ type: "waiting_for_user";
281
+ data: {
282
+ question?: string;
283
+ options?: string[];
284
+ kind?: "input" | "single_select" | "multiselect";
285
+ };
286
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ /**
3
+ * Lasso Agentic Runtime - Core Type Definitions
4
+ *
5
+ * This file defines all the core contracts for the Lasso-owned agentic runtime.
6
+ * The model is an interchangeable intelligence provider; Lasso owns the loop.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,67 @@
1
+ import { AgentPhase, LassoAgentSession, AgentAction } from "./agent-runtime";
2
+ /**
3
+ * Lasso Agent State Machine
4
+ *
5
+ * Controls phase transitions and validates state changes.
6
+ * Lasso owns the transitions; the model can only suggest decisions.
7
+ */
8
+ export declare class AgentStateMachine {
9
+ /**
10
+ * Valid phase transitions based on the current state
11
+ */
12
+ private static readonly TRANSITIONS;
13
+ /**
14
+ * Actions allowed in each phase
15
+ */
16
+ private static readonly ALLOWED_ACTIONS;
17
+ /**
18
+ * Check if a phase transition is valid
19
+ */
20
+ static canTransition(session: LassoAgentSession, toPhase: AgentPhase): boolean;
21
+ /**
22
+ * Attempt to transition to a new phase
23
+ * Returns success status and error message if invalid
24
+ */
25
+ static transition(session: LassoAgentSession, toPhase: AgentPhase, reason?: string): {
26
+ success: boolean;
27
+ error?: string;
28
+ };
29
+ /**
30
+ * Validate that an action is allowed in the current phase
31
+ */
32
+ static validateAction(session: LassoAgentSession, action: AgentAction): {
33
+ valid: boolean;
34
+ error?: string;
35
+ };
36
+ /**
37
+ * Determine the next phase based on current state and model decision
38
+ */
39
+ static determineNextPhase(session: LassoAgentSession, modelDecision: {
40
+ type: string;
41
+ goal: string;
42
+ }): AgentPhase;
43
+ /**
44
+ * Check if the session is in a terminal state
45
+ */
46
+ static isTerminal(session: LassoAgentSession): boolean;
47
+ /**
48
+ * Check if the session can accept new actions
49
+ */
50
+ static canAcceptActions(session: LassoAgentSession): boolean;
51
+ /**
52
+ * Check if the session should trigger verification
53
+ */
54
+ static shouldVerify(session: LassoAgentSession): boolean;
55
+ /**
56
+ * Check if the session should trigger recovery
57
+ */
58
+ static shouldRecover(session: LassoAgentSession): boolean;
59
+ /**
60
+ * Check if the session can switch models
61
+ */
62
+ static canSwitchModel(session: LassoAgentSession): boolean;
63
+ /**
64
+ * Calculate the estimated number of remaining turns
65
+ */
66
+ static estimateRemainingTurns(session: LassoAgentSession): number;
67
+ }
@@ -0,0 +1,234 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AgentStateMachine = void 0;
4
+ /**
5
+ * Lasso Agent State Machine
6
+ *
7
+ * Controls phase transitions and validates state changes.
8
+ * Lasso owns the transitions; the model can only suggest decisions.
9
+ */
10
+ class AgentStateMachine {
11
+ /**
12
+ * Valid phase transitions based on the current state
13
+ */
14
+ static TRANSITIONS = {
15
+ understand: ["inspect", "complete"],
16
+ inspect: ["plan", "understand", "complete"],
17
+ plan: ["execute", "inspect", "understand", "complete"],
18
+ execute: ["verify", "plan", "inspect", "understand"],
19
+ verify: ["complete", "recover", "execute", "plan"],
20
+ recover: ["inspect", "plan", "execute", "verify", "understand"],
21
+ complete: [], // Terminal state
22
+ };
23
+ /**
24
+ * Actions allowed in each phase
25
+ */
26
+ static ALLOWED_ACTIONS = {
27
+ understand: [],
28
+ inspect: ["read_file", "search_code", "inspect_project"],
29
+ plan: [],
30
+ execute: ["edit_file", "create_file", "delete_file", "run_command"],
31
+ verify: ["browser_check", "run_command"],
32
+ recover: ["edit_file", "read_file", "run_command"],
33
+ complete: [],
34
+ };
35
+ /**
36
+ * Check if a phase transition is valid
37
+ */
38
+ static canTransition(session, toPhase) {
39
+ const currentPhase = session.phase;
40
+ const allowed = this.TRANSITIONS[currentPhase] || [];
41
+ return allowed.includes(toPhase);
42
+ }
43
+ /**
44
+ * Attempt to transition to a new phase
45
+ * Returns success status and error message if invalid
46
+ */
47
+ static transition(session, toPhase, reason) {
48
+ if (!this.canTransition(session, toPhase)) {
49
+ return {
50
+ success: false,
51
+ error: `Invalid phase transition from ${session.phase} to ${toPhase}`,
52
+ };
53
+ }
54
+ // Special checks for specific transitions
55
+ if (toPhase === "complete") {
56
+ if (session.actions.length === 0 && session.completedActions.length === 0) {
57
+ return {
58
+ success: false,
59
+ error: "Cannot complete without executing any actions",
60
+ };
61
+ }
62
+ if (session.status === "failed") {
63
+ return {
64
+ success: false,
65
+ error: "Cannot complete a failed session",
66
+ };
67
+ }
68
+ }
69
+ if (toPhase === "recover") {
70
+ if (session.errors.length === 0) {
71
+ return {
72
+ success: false,
73
+ error: "Cannot enter recovery phase without errors",
74
+ };
75
+ }
76
+ }
77
+ return { success: true };
78
+ }
79
+ /**
80
+ * Validate that an action is allowed in the current phase
81
+ */
82
+ static validateAction(session, action) {
83
+ const allowedActions = this.ALLOWED_ACTIONS[session.phase] || [];
84
+ const actionType = action.type;
85
+ if (!allowedActions.includes(actionType)) {
86
+ return {
87
+ valid: false,
88
+ error: `Action type "${actionType}" is not allowed in phase "${session.phase}"`,
89
+ };
90
+ }
91
+ // Additional validation for specific actions
92
+ if (action.type === "edit_file") {
93
+ const data = action.data;
94
+ if (!data.oldString && !data.newString) {
95
+ return {
96
+ valid: false,
97
+ error: "Edit action must have oldString or newString",
98
+ };
99
+ }
100
+ }
101
+ if (action.type === "run_command") {
102
+ const data = action.data;
103
+ if (!data.command || !data.command.trim()) {
104
+ return {
105
+ valid: false,
106
+ error: "Run command action must have a command",
107
+ };
108
+ }
109
+ }
110
+ return { valid: true };
111
+ }
112
+ /**
113
+ * Determine the next phase based on current state and model decision
114
+ */
115
+ static determineNextPhase(session, modelDecision) {
116
+ const currentPhase = session.phase;
117
+ const decisionType = modelDecision.type;
118
+ // If model explicitly asks for a phase, validate it
119
+ if (decisionType === "inspect" && this.canTransition(session, "inspect")) {
120
+ return "inspect";
121
+ }
122
+ if (decisionType === "plan" && this.canTransition(session, "plan")) {
123
+ return "plan";
124
+ }
125
+ if (decisionType === "execute" && this.canTransition(session, "execute")) {
126
+ return "execute";
127
+ }
128
+ if (decisionType === "verify" && this.canTransition(session, "verify")) {
129
+ return "verify";
130
+ }
131
+ if (decisionType === "recover" && this.canTransition(session, "recover")) {
132
+ return "recover";
133
+ }
134
+ // Default progression based on current phase
135
+ switch (currentPhase) {
136
+ case "understand":
137
+ return "inspect";
138
+ case "inspect":
139
+ // If we have observations, move to plan
140
+ if (session.observations.length > 0) {
141
+ return "plan";
142
+ }
143
+ return "inspect";
144
+ case "plan":
145
+ // If we have a plan, move to execute
146
+ if (session.plan) {
147
+ return "execute";
148
+ }
149
+ return "plan";
150
+ case "execute":
151
+ // If we have completed actions, move to verify
152
+ if (session.completedActions.length > 0) {
153
+ return "verify";
154
+ }
155
+ return "execute";
156
+ case "verify":
157
+ // If verification succeeded, complete; if failed, recover
158
+ const hasErrors = session.errors.some((e) => e.phase === "verify");
159
+ if (hasErrors) {
160
+ return "recover";
161
+ }
162
+ return "complete";
163
+ case "recover":
164
+ // After recovery attempt, go back to verify
165
+ return "verify";
166
+ case "complete":
167
+ return "complete";
168
+ default:
169
+ return "understand";
170
+ }
171
+ }
172
+ /**
173
+ * Check if the session is in a terminal state
174
+ */
175
+ static isTerminal(session) {
176
+ return session.phase === "complete" || session.status === "failed" || session.status === "cancelled";
177
+ }
178
+ /**
179
+ * Check if the session can accept new actions
180
+ */
181
+ static canAcceptActions(session) {
182
+ return (session.status === "running" &&
183
+ session.phase !== "complete" &&
184
+ session.phase !== "understand");
185
+ }
186
+ /**
187
+ * Check if the session should trigger verification
188
+ */
189
+ static shouldVerify(session) {
190
+ return (session.phase === "execute" &&
191
+ session.completedActions.length > 0 &&
192
+ session.errors.filter((e) => e.phase === "execute").length === 0);
193
+ }
194
+ /**
195
+ * Check if the session should trigger recovery
196
+ */
197
+ static shouldRecover(session) {
198
+ return (session.phase === "verify" &&
199
+ session.errors.filter((e) => e.phase === "verify").length > 0);
200
+ }
201
+ /**
202
+ * Check if the session can switch models
203
+ */
204
+ static canSwitchModel(session) {
205
+ return session.status === "running" && session.phase !== "complete";
206
+ }
207
+ /**
208
+ * Calculate the estimated number of remaining turns
209
+ */
210
+ static estimateRemainingTurns(session) {
211
+ const { phase, plan, completedActions, errors } = session;
212
+ if (phase === "complete")
213
+ return 0;
214
+ if (phase === "understand")
215
+ return 5; // understand → inspect → plan → execute → verify
216
+ if (phase === "inspect")
217
+ return 4; // inspect → plan → execute → verify
218
+ if (phase === "plan")
219
+ return 3; // plan → execute → verify
220
+ if (phase === "execute") {
221
+ const remaining = (plan?.estimatedActions || 5) - completedActions.length;
222
+ return Math.max(remaining + 1, 2); // execute → verify
223
+ }
224
+ if (phase === "verify") {
225
+ if (errors.length > 0)
226
+ return 3; // verify → recover → verify
227
+ return 1; // verify → complete
228
+ }
229
+ if (phase === "recover")
230
+ return 2; // recover → verify
231
+ return 5;
232
+ }
233
+ }
234
+ exports.AgentStateMachine = AgentStateMachine;