@qaick/executor 0.1.0 → 0.2.1

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.
@@ -1,3 +1,3 @@
1
- import type { ExecutionPackage } from './types';
1
+ import type { ExecutionPackage } from './migrated-types';
2
2
  /** Stable, dependency-free content identity for the normalized execution package. */
3
3
  export declare function hashExecutionPackage(pack: ExecutionPackage): string;
@@ -1,4 +1,4 @@
1
- import type { ActionExecutor, Executor, ExecutorConfiguration, ExecutorEvent, ExecutorRequest, ExecutorResult, ExecutorRun, ControlCommand, ExecutionControlState } from './types.js';
1
+ import type { ActReplayTarget, ActReplayHandle, OperationReplayHandle, ActionExecutor, Executor, ExecutorConfiguration, ExecutorEvent, ExecutorRequest, ExecutorResult, ExecutorRun, ControlCommand, ExecutionControlState } from './types.js';
2
2
  export declare function createMigratedExecutor(configuration?: ExecutorConfiguration): Executor;
3
3
  /**
4
4
  * Compatibility facade over the extracted Runner engine. The facade owns the
@@ -18,7 +18,7 @@ export declare class MigratedExecutor implements Executor {
18
18
  controlState(requestId: string): ExecutionControlState | undefined;
19
19
  events(requestId: string): AsyncIterable<ExecutorEvent>;
20
20
  result(requestId: string): Promise<ExecutorResult>;
21
- retryAction(requestId: string, stepId: string, invocationPath?: string[]): Promise<void>;
22
- retryOperation(requestId: string, stepId: string, invocationPath?: string[]): Promise<void>;
23
- runFromHere(requestId: string, stepId: string, invocationPath?: string[]): Promise<ExecutorRun | undefined>;
21
+ retryAction(requestId: string, target: ActReplayTarget): Promise<ActReplayHandle>;
22
+ retryOperation(requestId: string, target: ActReplayTarget): Promise<OperationReplayHandle>;
23
+ runFromHere(requestId: string, target: ActReplayTarget): Promise<ExecutorRun>;
24
24
  }
@@ -48,17 +48,22 @@ export class MigratedExecutor {
48
48
  controlState(requestId) { return this.routineRuns.has(requestId) ? this.routine.controlState(requestId) : this.engine.controlState(requestId); }
49
49
  async *events(requestId) { yield* (this.routineRuns.has(requestId) ? this.routine.events(requestId) : this.engine.events(requestId)); }
50
50
  async result(requestId) { return (this.routineRuns.has(requestId) ? this.routine.result(requestId) : this.engine.result(requestId)); }
51
- async retryAction(requestId, stepId, invocationPath) { await (this.routineRuns.has(requestId) ? this.routine.retryAction(requestId, stepId, invocationPath) : this.engine.retryAction(requestId, stepId, invocationPath)); }
52
- async retryOperation(requestId, stepId, invocationPath) { await (this.routineRuns.has(requestId) ? this.routine.retryOperation(requestId, stepId, invocationPath) : this.engine.retryOperation(requestId, stepId, invocationPath)); }
53
- async runFromHere(requestId, stepId, invocationPath) {
54
- if (this.routineRuns.has(requestId)) {
55
- const targeted = await this.routine.runFromHere(requestId, stepId, invocationPath);
56
- if (targeted)
57
- this.routineRuns.add(targeted.requestId);
58
- return targeted;
59
- }
60
- const accepted = await this.engine.runFromHere(requestId, stepId, invocationPath);
61
- return accepted ? { requestId: accepted.requestId, result: this.result(accepted.requestId) } : undefined;
51
+ async retryAction(requestId, target) {
52
+ if (this.routineRuns.has(requestId))
53
+ return this.routine.retryAction(requestId, target);
54
+ throw { code: 'unsupported-execution-context', message: 'Structural Act replay requires the canonical execution path.' };
55
+ }
56
+ async retryOperation(requestId, target) {
57
+ if (this.routineRuns.has(requestId))
58
+ return this.routine.retryOperation(requestId, target);
59
+ throw { code: 'unsupported-execution-context', message: 'Structural Operation replay requires the canonical execution path.' };
60
+ }
61
+ async runFromHere(requestId, target) {
62
+ if (!this.routineRuns.has(requestId))
63
+ throw { code: 'unsupported-execution-context', message: 'Structural Run From Here requires the canonical execution path.' };
64
+ const started = await this.routine.runFromHere(requestId, target);
65
+ this.routineRuns.add(started.requestId);
66
+ return started;
62
67
  }
63
68
  }
64
69
  function toActionAdapter(executor) {
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import type { ExecutionPackage, ExecutionStep, ExecutionState, InvocationState, TerminalReason } from '@qaick/contract';
2
- export type { ExecutionPackage, ExecutionStep, ExecutionState, InvocationState, TerminalReason } from '@qaick/contract';
1
+ import type { ExecutionPackageV7 as ExecutionPackage, ExecutionStepV7 as ExecutionStep, ExecutionState, InvocationState, TerminalReason } from '@qaick/contract';
2
+ export type { ExecutionPackageV7 as ExecutionPackage, ExecutionStepV7 as ExecutionStep, ExecutionState, InvocationState, TerminalReason } from '@qaick/contract';
3
3
  export type ActionFailureCode = 'ACTION_FAILED' | 'ACTION_TIMEOUT' | 'ACTION_CANCELLED' | 'UNSUPPORTED_ACTION' | 'BINDING_RESOLUTION_ERROR' | 'CONTROL_BLOCK_ERROR' | 'PREFLIGHT_ERROR' | 'INTERNAL_EXECUTION_ERROR';
4
4
  export interface ActionFailure {
5
5
  code: string;
@@ -12,7 +12,7 @@ export interface ActionExecutionContext {
12
12
  inputs: Record<string, unknown>;
13
13
  environment: string;
14
14
  runtimeValues: Record<string, unknown>;
15
- step: ExecutionStep;
15
+ step: Pick<ExecutionStep, 'id' | 'name' | 'action' | 'output' | 'adapterConfig'>;
16
16
  signal: AbortSignal;
17
17
  }
18
18
  export interface ActionExecutionResult {
@@ -63,6 +63,8 @@ export interface ExecutorStepResult {
63
63
  inputs: Record<string, unknown>;
64
64
  outputs: Record<string, unknown>;
65
65
  durationMs: number;
66
+ structuralAddress?: import('@qaick/contract').HierarchyAddress;
67
+ iterations?: import('@qaick/contract').IterationSelection[];
66
68
  invocationId?: string;
67
69
  invocationPath?: string[];
68
70
  kind?: 'action' | 'operation' | 'control-block';
@@ -78,6 +80,7 @@ export interface ExecutorStepResult {
78
80
  error?: ActionFailure;
79
81
  }
80
82
  export interface ExecutorResult {
83
+ readonly debugProvenance?: RunFromHereProvenance;
81
84
  requestId: string;
82
85
  state: Exclude<ExecutionState, 'created' | 'preflighting' | 'running'>;
83
86
  target: ExecutionPackage['target'];
@@ -100,6 +103,9 @@ export interface ExecutorResult {
100
103
  };
101
104
  }
102
105
  export interface ExecutorEvent {
106
+ structuralAddress?: import('@qaick/contract').HierarchyAddress;
107
+ iterations?: import('@qaick/contract').IterationSelection[];
108
+ kind?: 'action' | 'operation' | 'control-block';
103
109
  requestId: string;
104
110
  sequence: number;
105
111
  type: 'run_started' | 'preflight_started' | 'step_started' | 'waiting' | 'step_finished' | 'run_finished';
@@ -138,9 +144,79 @@ export type ControlCommand = {
138
144
  };
139
145
  export type ExecutionControlState = 'idle' | 'running' | 'pause-requested' | 'paused' | 'resuming' | 'stopped' | 'failed' | 'completed';
140
146
  export interface ExecutorRun {
147
+ readonly debugProvenance?: RunFromHereProvenance;
141
148
  requestId: string;
142
149
  result: Promise<ExecutorResult>;
143
150
  }
151
+ /** Runtime diagnostic target; never serialized into an Execution v7 package. */
152
+ export interface ActReplayTarget {
153
+ structuralAddress: import('@qaick/contract').HierarchyAddress;
154
+ iterations: import('@qaick/contract').IterationSelection[];
155
+ }
156
+ /** Descriptive runtime provenance, not an execution operand or persisted package field. */
157
+ export interface RunFromHereProvenance {
158
+ readonly kind: 'run-from-here';
159
+ readonly sourceRequestId: string;
160
+ readonly selection: Readonly<ActReplayTarget>;
161
+ readonly inputSeed: {
162
+ readonly kind: 'captured-inputs';
163
+ readonly inputs: Readonly<Record<string, unknown>>;
164
+ readonly lexicalScope?: Readonly<Record<string, unknown>>;
165
+ };
166
+ readonly omittedOccurrences: readonly import('@qaick/contract').HierarchyAddress[];
167
+ }
168
+ export interface ActReplayResult {
169
+ readonly parentRequestId: string;
170
+ readonly sessionId: string;
171
+ readonly target: Readonly<ActReplayTarget>;
172
+ readonly kind: 'action';
173
+ readonly state: 'completed' | 'failed' | 'cancelled';
174
+ readonly terminalReason: 'completed' | 'failed' | 'cancelled' | 'timeout';
175
+ readonly startedAt: string;
176
+ readonly finishedAt: string;
177
+ readonly durationMs: number;
178
+ readonly inputs: Readonly<Record<string, unknown>>;
179
+ readonly outputs: Readonly<Record<string, unknown>>;
180
+ readonly evidence?: Readonly<Record<string, unknown>>;
181
+ readonly attempts: readonly ExecutionAttempt[];
182
+ readonly error?: Readonly<ActionFailure>;
183
+ }
184
+ export interface ActReplayEvent {
185
+ readonly parentRequestId: string;
186
+ readonly sessionId: string;
187
+ readonly sequence: number;
188
+ readonly timestamp: string;
189
+ readonly structuralAddress: import('@qaick/contract').HierarchyAddress;
190
+ readonly iterations: import('@qaick/contract').IterationSelection[];
191
+ readonly kind: 'action';
192
+ readonly type: 'replay_started' | 'attempt_started' | 'attempt_finished' | 'replay_finished';
193
+ readonly state: 'running' | 'finished' | 'completed' | 'failed' | 'cancelled';
194
+ readonly attempt?: number;
195
+ readonly terminalReason?: ActReplayResult['terminalReason'];
196
+ }
197
+ /** A replay is associated with a historical Run; this is not a new ExecutorRun. */
198
+ export interface ActReplayHandle {
199
+ readonly parentRequestId: string;
200
+ readonly sessionId: string;
201
+ readonly target: Readonly<ActReplayTarget>;
202
+ readonly result: Promise<ActReplayResult>;
203
+ events(): AsyncIterable<ActReplayEvent>;
204
+ cancel(): Promise<void>;
205
+ }
206
+ export interface OperationReplayResult extends Omit<ActReplayResult, 'kind' | 'attempts' | 'evidence'> {
207
+ readonly kind: 'operation';
208
+ readonly lexicalScope: Readonly<Record<string, unknown>>;
209
+ readonly children: readonly ExecutorStepResult[];
210
+ }
211
+ export interface OperationReplayEvent extends Omit<ActReplayEvent, 'kind' | 'type' | 'state'> {
212
+ readonly kind: 'action' | 'operation' | 'control-block';
213
+ readonly type: ActReplayEvent['type'] | 'step_started' | 'step_finished' | 'waiting';
214
+ readonly state: ActReplayEvent['state'] | 'waiting' | 'skipped';
215
+ }
216
+ export interface OperationReplayHandle extends Omit<ActReplayHandle, 'result' | 'events'> {
217
+ readonly result: Promise<OperationReplayResult>;
218
+ events(): AsyncIterable<OperationReplayEvent>;
219
+ }
144
220
  export interface ExecutorConfiguration {
145
221
  actionExecutors?: ActionExecutor[];
146
222
  maxTimeoutMs?: number;
@@ -152,8 +228,8 @@ export interface Executor {
152
228
  controlState(requestId: string): ExecutionControlState | undefined;
153
229
  events(requestId: string): AsyncIterable<ExecutorEvent>;
154
230
  result(requestId: string): Promise<ExecutorResult>;
155
- retryAction(requestId: string, stepId: string, invocationPath?: string[]): Promise<void>;
156
- retryOperation(requestId: string, stepId: string, invocationPath?: string[]): Promise<void>;
157
- runFromHere(requestId: string, stepId: string, invocationPath?: string[]): Promise<ExecutorRun | undefined>;
231
+ retryAction(requestId: string, target: ActReplayTarget): Promise<ActReplayHandle>;
232
+ retryOperation(requestId: string, target: ActReplayTarget): Promise<OperationReplayHandle>;
233
+ runFromHere(requestId: string, target: ActReplayTarget): Promise<ExecutorRun>;
158
234
  registerActionExecutor(executor: ActionExecutor): void;
159
235
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qaick/executor",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Host-neutral QAick action execution primitives.",
5
5
  "files": [
6
6
  "dist",
@@ -34,7 +34,7 @@
34
34
  "prepublishOnly": "npm run typecheck && npm test && npm run build"
35
35
  },
36
36
  "dependencies": {
37
- "@qaick/contract": "0.2.13"
37
+ "@qaick/contract": "0.3.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/node": "^24.13.3",