@qaick/executor 0.3.0 → 0.4.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.
@@ -48,8 +48,14 @@ export class ExecutionPlan {
48
48
  };
49
49
  const root = document.selection.root.kind === 'occurrence' ? document.selection.root.key : document.context.root;
50
50
  const selected = this.context.get(root);
51
- const visit = (key) => { this.inScope.add(key); for (const child of this.context.get(key).children)
52
- visit(child); };
51
+ const visit = (key) => {
52
+ this.inScope.add(key);
53
+ // Branch Controls retain their shadowed direct body as context, not executable scope.
54
+ const branches = this.nodes.get(key)?.control?.branches;
55
+ const children = branches ? branches.map(branch => branch.occurrence) : this.context.get(key).children;
56
+ for (const child of children)
57
+ visit(child);
58
+ };
53
59
  visit(root);
54
60
  const entryPayload = selected.kind === 'flow' ? document.flows.find(f => f.occurrence === root) : document.nodes.find(n => n.occurrence === root);
55
61
  this.inputDeclarations = entryPayload?.inputDeclarations ?? document.selection.inputDeclarations;
package/dist/executor.js CHANGED
@@ -779,7 +779,7 @@ export class DefaultExecutor {
779
779
  const maxAttempts = Math.max(1, step.retry?.maxAttempts ?? 1);
780
780
  let lastFailure;
781
781
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
782
- const context = { action: step.action, inputs: structuredClone(originalInputs), environment: run.request.environment, runtimeValues: run.request.runtimeValues ?? {}, step, signal };
782
+ const context = { action: step.action, inputs: structuredClone(originalInputs), runtimeValues: run.request.runtimeValues ?? {}, step, signal };
783
783
  this.assertActive(run, signal);
784
784
  const startedAt = new Date().toISOString();
785
785
  const startedMs = Date.now();
@@ -877,7 +877,7 @@ export class DefaultExecutor {
877
877
  run.listeners.splice(0).forEach(resolve => resolve());
878
878
  }
879
879
  baseResult(run, startedAt, state, error, issues, children) {
880
- return { ...(run.debugProvenance ? { debugProvenance: run.debugProvenance } : {}), requestId: run.request.requestId, state, target: run.request.executionPackage.target, environment: run.request.environment, startedAt, finishedAt: new Date().toISOString(), steps: [], ...(children ? { children } : {}), ...(error ? { error } : {}), ...(issues ? { issues } : {}) };
880
+ return { ...(run.debugProvenance ? { debugProvenance: run.debugProvenance } : {}), requestId: run.request.requestId, state, target: run.request.executionPackage.target, startedAt, finishedAt: new Date().toISOString(), steps: [], ...(children ? { children } : {}), ...(error ? { error } : {}), ...(issues ? { issues } : {}) };
881
881
  }
882
882
  versionedResult(run, result) {
883
883
  return { ...result, resultVersion: 2, documentHash: run.documentHash, source: run.execution.document.source, scope: run.execution.document.selection.root, steps: result.steps, ...(result.children ? { children: result.children.map(r => this.versionedResult(run, r)) } : {}) };
@@ -78,27 +78,27 @@ export class MigratedProjectRunnerEngine {
78
78
  const invalidFlow = flows.length === 0 || flows.find(flow => !request.executionPackage.definitions.some(definition => definition.kind === 'flow' && definition.id === flow.id));
79
79
  if (invalidFlow) {
80
80
  const error = { code: 'INVALID_PROJECT', message: 'Project Flow definitions are missing or unresolved.' };
81
- this.finish(run, { requestId: request.requestId, state: 'failed', target: request.executionPackage.target, environment: request.environment, startedAt, finishedAt: new Date().toISOString(), steps: [], error });
81
+ this.finish(run, { requestId: request.requestId, state: 'failed', target: request.executionPackage.target, startedAt, finishedAt: new Date().toISOString(), steps: [], error });
82
82
  return;
83
83
  }
84
84
  const children = [];
85
85
  let inputs = { ...request.inputs };
86
86
  for (const flow of flows) {
87
87
  if (run.cancelled) {
88
- this.finish(run, { requestId: request.requestId, state: 'cancelled', target: request.executionPackage.target, environment: request.environment, startedAt, finishedAt: new Date().toISOString(), steps: [], children });
88
+ this.finish(run, { requestId: request.requestId, state: 'cancelled', target: request.executionPackage.target, startedAt, finishedAt: new Date().toISOString(), steps: [], children });
89
89
  return;
90
90
  }
91
91
  const childRequestId = `${request.requestId}:${flow.id}`;
92
92
  run.activeRequestId = childRequestId;
93
93
  const childPackage = { ...request.executionPackage, target: { kind: 'flow', id: flow.id, name: flow.name }, steps: flow.steps, flows: undefined, requiredInputs: flow.requiredInputs, inputDeclarations: flow.inputDeclarations };
94
- await this.flowEngine.submit({ requestId: childRequestId, executionPackage: childPackage, inputs, environment: request.environment, runtimeValues: request.runtimeValues, options: request.options, debugSession: request.debugSession });
94
+ await this.flowEngine.submit({ requestId: childRequestId, executionPackage: childPackage, inputs, runtimeValues: request.runtimeValues, options: request.options, debugSession: request.debugSession });
95
95
  for await (const event of this.flowEngine.events(childRequestId))
96
96
  this.emit(run, event.type, event.state, `[${flow.name}] ${event.message}`, event.stepId ? { stepId: event.stepId, stepName: event.stepName } : undefined, event.parallel, event.control);
97
97
  const childResult = await this.flowEngine.result(childRequestId);
98
98
  children.push(childResult);
99
99
  const lastStep = childResult.steps.at(-1);
100
100
  if (childResult.state !== 'completed') {
101
- const result = { requestId: request.requestId, state: childResult.state, target: request.executionPackage.target, environment: request.environment, startedAt, finishedAt: new Date().toISOString(), steps: [], children, error: childResult.error, issues: children.flatMap(child => child.issues ?? []) };
101
+ const result = { requestId: request.requestId, state: childResult.state, target: request.executionPackage.target, startedAt, finishedAt: new Date().toISOString(), steps: [], children, error: childResult.error, issues: children.flatMap(child => child.issues ?? []) };
102
102
  this.finish(run, result);
103
103
  return;
104
104
  }
@@ -109,7 +109,7 @@ export class MigratedProjectRunnerEngine {
109
109
  }));
110
110
  inputs = { ...inputs, ...(Object.keys(outputBindings).length ? mappedOutputs : lastStep?.outputs) };
111
111
  }
112
- const result = { requestId: request.requestId, state: 'completed', target: request.executionPackage.target, environment: request.environment, startedAt, finishedAt: new Date().toISOString(), steps: [], children, issues: children.flatMap(child => child.issues ?? []) };
112
+ const result = { requestId: request.requestId, state: 'completed', target: request.executionPackage.target, startedAt, finishedAt: new Date().toISOString(), steps: [], children, issues: children.flatMap(child => child.issues ?? []) };
113
113
  this.finish(run, result);
114
114
  await resultPromise;
115
115
  }
@@ -44,7 +44,7 @@ export class MigratedRunnerEngine {
44
44
  this.emit(run, 'waiting', 'waiting', `Interactive retry unavailable for ${step.name}: no Action adapter.`, step, undefined, undefined, { type: 'interactive-retry-requested', stepId });
45
45
  return;
46
46
  } const previousAttempts = stepResult.attempts ?? [{ attempt: 1, kind: 'automatic', state: stepResult.state === 'failed' ? 'failed' : 'finished', startedAt: run.result.startedAt, finishedAt: run.result.finishedAt, inputs: { ...stepResult.inputs }, outputs: { ...stepResult.outputs }, durationMs: stepResult.durationMs, ...(stepResult.error ? { error: stepResult.error } : {}) }]; const attempt = previousAttempts.length + 1; const startedAt = new Date().toISOString(); const startedMs = Date.now(); this.emit(run, 'waiting', 'waiting', `Interactive retry requested for ${step.name}.`, step, undefined, undefined, { type: 'interactive-retry-requested', stepId }); this.emit(run, 'step_started', 'running', `${step.name} retry attempt ${attempt} started.`, step); let outputs; let error; try {
47
- outputs = await adapter.execute(withRuntimeValues({ action: step.action, inputs: { ...stepResult.inputs }, environment: run.request.environment, step, signal: run.abortController.signal }, run.request.runtimeValues));
47
+ outputs = await adapter.execute(withRuntimeValues({ action: step.action, inputs: { ...stepResult.inputs }, step, signal: run.abortController.signal }, run.request.runtimeValues));
48
48
  }
49
49
  catch (cause) {
50
50
  error = { code: isAdapterError(cause) ? cause.code : 'ACTION_FAILED', message: cause instanceof Error ? cause.message : `Action ${step.action} failed.` };
@@ -68,7 +68,7 @@ export class MigratedRunnerEngine {
68
68
  return; const stepResult = findStepResult(run.result.steps, stepId, invocationPath); const step = findExecutionStep(run.request.executionPackage.steps, stepId, invocationPath); if (!stepResult || !step || step.kind !== 'operation' || !step.children?.length || stepResult.state === 'skipped') {
69
69
  this.emit(run, 'waiting', 'waiting', `Interactive Operation retry unavailable for ${stepId}.`, step, undefined, undefined, { type: 'interactive-retry-requested', stepId });
70
70
  return;
71
- } const childPackage = { ...run.request.executionPackage, target: { kind: 'flow', id: `${run.request.executionPackage.target.id}:${step.id}`, name: step.name }, steps: step.children, flows: undefined, requiredInputs: [] }; const childEngine = new MigratedRunnerEngine(this.adapters); const retryRequestId = `${requestId}:operation-retry:${step.id}:${(stepResult.attempts?.length ?? 0) + 1}`; const startedAt = new Date().toISOString(); const startedMs = Date.now(); this.emit(run, 'waiting', 'waiting', `Interactive Operation retry requested for ${step.name}.`, step, undefined, undefined, { type: 'interactive-retry-requested', stepId }); this.emit(run, 'step_started', 'running', `${step.name} retry attempt ${(stepResult.attempts?.length ?? 0) + 1} started.`, step); await childEngine.submit({ requestId: retryRequestId, executionPackage: childPackage, inputs: run.request.inputs, environment: run.request.environment, runtimeValues: run.request.runtimeValues, options: run.request.options }); const retryResult = await childEngine.result(retryRequestId); const finishedAt = new Date().toISOString(); const durationMs = Date.now() - startedMs; const previousAttempts = stepResult.attempts ?? [{ attempt: 1, kind: 'automatic', state: stepResult.state === 'failed' ? 'failed' : 'finished', startedAt: run.result.startedAt, finishedAt: run.result.finishedAt, inputs: {}, outputs: { ...stepResult.outputs }, durationMs: stepResult.durationMs, children: stepResult.children?.map(child => ({ ...child, attempts: child.attempts })) }]; const attempt = previousAttempts.length + 1; const interactiveAttempt = { attempt, kind: 'interactive', state: retryResult.state === 'completed' ? 'finished' : 'failed', startedAt, finishedAt, inputs: {}, outputs: { ...stepResult.outputs }, durationMs, children: retryResult.steps, ...(retryResult.error ? { error: retryResult.error } : {}) }; stepResult.attempts = [...previousAttempts, interactiveAttempt]; stepResult.children = retryResult.steps; stepResult.state = retryResult.state === 'completed' ? 'finished' : 'failed'; stepResult.durationMs = durationMs; if (retryResult.state === 'completed') {
71
+ } const childPackage = { ...run.request.executionPackage, target: { kind: 'flow', id: `${run.request.executionPackage.target.id}:${step.id}`, name: step.name }, steps: step.children, flows: undefined, requiredInputs: [] }; const childEngine = new MigratedRunnerEngine(this.adapters); const retryRequestId = `${requestId}:operation-retry:${step.id}:${(stepResult.attempts?.length ?? 0) + 1}`; const startedAt = new Date().toISOString(); const startedMs = Date.now(); this.emit(run, 'waiting', 'waiting', `Interactive Operation retry requested for ${step.name}.`, step, undefined, undefined, { type: 'interactive-retry-requested', stepId }); this.emit(run, 'step_started', 'running', `${step.name} retry attempt ${(stepResult.attempts?.length ?? 0) + 1} started.`, step); await childEngine.submit({ requestId: retryRequestId, executionPackage: childPackage, inputs: run.request.inputs, runtimeValues: run.request.runtimeValues, options: run.request.options }); const retryResult = await childEngine.result(retryRequestId); const finishedAt = new Date().toISOString(); const durationMs = Date.now() - startedMs; const previousAttempts = stepResult.attempts ?? [{ attempt: 1, kind: 'automatic', state: stepResult.state === 'failed' ? 'failed' : 'finished', startedAt: run.result.startedAt, finishedAt: run.result.finishedAt, inputs: {}, outputs: { ...stepResult.outputs }, durationMs: stepResult.durationMs, children: stepResult.children?.map(child => ({ ...child, attempts: child.attempts })) }]; const attempt = previousAttempts.length + 1; const interactiveAttempt = { attempt, kind: 'interactive', state: retryResult.state === 'completed' ? 'finished' : 'failed', startedAt, finishedAt, inputs: {}, outputs: { ...stepResult.outputs }, durationMs, children: retryResult.steps, ...(retryResult.error ? { error: retryResult.error } : {}) }; stepResult.attempts = [...previousAttempts, interactiveAttempt]; stepResult.children = retryResult.steps; stepResult.state = retryResult.state === 'completed' ? 'finished' : 'failed'; stepResult.durationMs = durationMs; if (retryResult.state === 'completed') {
72
72
  stepResult.outputs = retryResult.steps.at(-1)?.outputs ?? {};
73
73
  delete stepResult.error;
74
74
  stepResult.terminalReason = 'completed';
@@ -94,7 +94,7 @@ export class MigratedRunnerEngine {
94
94
  return undefined;
95
95
  staticInputs[name] = value;
96
96
  }
97
- } const targetedStep = { ...step, bindings: undefined, staticInputs }; const targetedPackage = { ...run.request.executionPackage, target: { kind: 'flow', id: `${run.request.executionPackage.target.id}:from:${step.id}`, name: `${run.request.executionPackage.target.name} · ${step.name}` }, steps: step.kind === 'operation' ? step.children ?? [targetedStep] : [targetedStep], flows: undefined, requiredInputs: [] }; const targetedRequestId = `${requestId}:from:${step.id}:${Date.now()}`; await this.submit({ requestId: targetedRequestId, executionPackage: targetedPackage, inputs: run.request.inputs, environment: run.request.environment, runtimeValues: run.request.runtimeValues, options: run.request.options }); const targetRun = this.runs.get(targetedRequestId); if (targetRun)
97
+ } const targetedStep = { ...step, bindings: undefined, staticInputs }; const targetedPackage = { ...run.request.executionPackage, target: { kind: 'flow', id: `${run.request.executionPackage.target.id}:from:${step.id}`, name: `${run.request.executionPackage.target.name} · ${step.name}` }, steps: step.kind === 'operation' ? step.children ?? [targetedStep] : [targetedStep], flows: undefined, requiredInputs: [] }; const targetedRequestId = `${requestId}:from:${step.id}:${Date.now()}`; await this.submit({ requestId: targetedRequestId, executionPackage: targetedPackage, inputs: run.request.inputs, runtimeValues: run.request.runtimeValues, options: run.request.options }); const targetRun = this.runs.get(targetedRequestId); if (targetRun)
98
98
  void this.result(targetedRequestId).then(result => { result.provenance = { kind: 'run-from-here', sourceRequestId: requestId, sourceArtifactHash: run.result?.artifactHash, selectedStepId: step.id, ...(selected.invocationPath ? { selectedInvocationPath: selected.invocationPath } : {}), omittedStepIds: run.request.executionPackage.steps.flatMap(item => item.id === step.id ? [] : [item.id]) }; }); return { requestId: targetedRequestId }; }
99
99
  controlState(requestId) { return this.runs.get(requestId)?.controlState; }
100
100
  debugSession(requestId) { const session = this.runs.get(requestId)?.debugSession; return session ? { ...session, breakpoints: [...session.breakpoints] } : undefined; }
@@ -130,7 +130,7 @@ export class MigratedRunnerEngine {
130
130
  return;
131
131
  }
132
132
  if (request.options?.timeoutMs !== undefined && (request.options.timeoutMs <= 0 || request.options.timeoutMs > MAX_EXECUTION_TIMEOUT_MS)) {
133
- this.finish(run, { requestId: request.requestId, state: 'failed', target: request.executionPackage.target, environment: request.environment, startedAt, finishedAt: new Date().toISOString(), steps: [], error: { code: 'EXECUTION_BUDGET_EXCEEDED', message: `Execution timeout must be between 1ms and ${MAX_EXECUTION_TIMEOUT_MS}ms.` } });
133
+ this.finish(run, { requestId: request.requestId, state: 'failed', target: request.executionPackage.target, startedAt, finishedAt: new Date().toISOString(), steps: [], error: { code: 'EXECUTION_BUDGET_EXCEEDED', message: `Execution timeout must be between 1ms and ${MAX_EXECUTION_TIMEOUT_MS}ms.` } });
134
134
  await resultPromise;
135
135
  return;
136
136
  }
@@ -140,14 +140,14 @@ export class MigratedRunnerEngine {
140
140
  const validationIssues = [...arguments_.issues, ...this.validateAll(request.executionPackage, arguments_.inputs, request.runtimeValues ?? {})];
141
141
  const validationWarnings = this.validateBrowserWarnings(request.executionPackage);
142
142
  if (request.options?.dryRun) {
143
- const dryRunResult = { requestId: request.requestId, state: validationIssues.length ? 'failed' : 'completed', target: request.executionPackage.target, environment: request.environment, startedAt, finishedAt: new Date().toISOString(), steps: [], terminalReason: validationIssues.length ? 'failed' : 'completed', issues: validationIssues, warnings: validationWarnings, ...(validationIssues.length ? { error: { code: 'DRY_RUN_ISSUES', message: `${validationIssues.length} issue${validationIssues.length === 1 ? '' : 's'} found during dry run.` } } : {}) };
143
+ const dryRunResult = { requestId: request.requestId, state: validationIssues.length ? 'failed' : 'completed', target: request.executionPackage.target, startedAt, finishedAt: new Date().toISOString(), steps: [], terminalReason: validationIssues.length ? 'failed' : 'completed', issues: validationIssues, warnings: validationWarnings, ...(validationIssues.length ? { error: { code: 'DRY_RUN_ISSUES', message: `${validationIssues.length} issue${validationIssues.length === 1 ? '' : 's'} found during dry run.` } } : {}) };
144
144
  this.finish(run, dryRunResult);
145
145
  await resultPromise;
146
146
  return;
147
147
  }
148
148
  const validationError = validationIssues.find(issue => !['INVALID_BINDING', 'MISSING_INPUT_BINDING', 'MISSING_STEP_BINDING'].includes(issue.code));
149
149
  if (validationError) {
150
- this.finish(run, { requestId: request.requestId, state: 'failed', target: request.executionPackage.target, environment: request.environment, startedAt, finishedAt: new Date().toISOString(), steps: [], warnings: validationWarnings, error: validationError });
150
+ this.finish(run, { requestId: request.requestId, state: 'failed', target: request.executionPackage.target, startedAt, finishedAt: new Date().toISOString(), steps: [], warnings: validationWarnings, error: validationError });
151
151
  return;
152
152
  }
153
153
  const steps = [];
@@ -160,7 +160,7 @@ export class MigratedRunnerEngine {
160
160
  }
161
161
  catch (cause) {
162
162
  const error = { code: cause instanceof Error && cause.message.startsWith('Graph') ? 'INVALID_GRAPH' : 'RECURSION_LIMIT', message: cause instanceof Error ? cause.message : 'The execution graph is invalid.' };
163
- this.finish(run, { requestId: request.requestId, state: 'failed', target: request.executionPackage.target, environment: request.environment, startedAt, finishedAt: new Date().toISOString(), steps: [], error });
163
+ this.finish(run, { requestId: request.requestId, state: 'failed', target: request.executionPackage.target, startedAt, finishedAt: new Date().toISOString(), steps: [], error });
164
164
  return;
165
165
  }
166
166
  for (let plannedIndex = 0; plannedIndex < plannedSteps.length; plannedIndex += 1) {
@@ -205,7 +205,7 @@ export class MigratedRunnerEngine {
205
205
  }
206
206
  const terminalFailure = parallel.errors.find(item => !item.continueOnError);
207
207
  if (terminalFailure) {
208
- this.finish(run, { requestId: request.requestId, state: 'failed', target: request.executionPackage.target, environment: request.environment, startedAt, finishedAt: new Date().toISOString(), steps, error: terminalFailure.error });
208
+ this.finish(run, { requestId: request.requestId, state: 'failed', target: request.executionPackage.target, startedAt, finishedAt: new Date().toISOString(), steps, error: terminalFailure.error });
209
209
  return;
210
210
  }
211
211
  continue;
@@ -213,7 +213,7 @@ export class MigratedRunnerEngine {
213
213
  const { step } = planned;
214
214
  const invocationId = `${request.requestId}:${planned.path.join('.')}`;
215
215
  if (run.cancelled) {
216
- this.finish(run, { requestId: request.requestId, state: 'cancelled', target: request.executionPackage.target, environment: request.environment, startedAt, finishedAt: new Date().toISOString(), steps });
216
+ this.finish(run, { requestId: request.requestId, state: 'cancelled', target: request.executionPackage.target, startedAt, finishedAt: new Date().toISOString(), steps });
217
217
  return;
218
218
  }
219
219
  if (planned.guards?.some(condition => !conditionMatches(condition, request.inputs, stepOutputs))) {
@@ -240,7 +240,7 @@ export class MigratedRunnerEngine {
240
240
  steps.push({ id: step.id, name: step.name, state: 'failed', inputs: {}, outputs: {}, durationMs: 0, invocationId, invocationPath: planned.path, kind: step.kind ?? 'action', iteration: planned.iteration, error });
241
241
  failedStepIds.add(step.id);
242
242
  if (!planned.continueOnError) {
243
- this.finish(run, { requestId: request.requestId, state: 'failed', target: request.executionPackage.target, environment: request.environment, startedAt, finishedAt: new Date().toISOString(), steps, error });
243
+ this.finish(run, { requestId: request.requestId, state: 'failed', target: request.executionPackage.target, startedAt, finishedAt: new Date().toISOString(), steps, error });
244
244
  return;
245
245
  }
246
246
  continue;
@@ -262,7 +262,7 @@ export class MigratedRunnerEngine {
262
262
  steps.push({ id: step.id, name: step.name, state: 'failed', inputs: stepInputs, outputs: {}, durationMs: Date.now() - stepStarted, invocationId, invocationPath: planned.path, kind: step.kind ?? 'action', iteration: planned.iteration, error });
263
263
  failedStepIds.add(step.id);
264
264
  if (!planned.continueOnError) {
265
- this.finish(run, { requestId: request.requestId, state: 'failed', target: request.executionPackage.target, environment: request.environment, startedAt, finishedAt: new Date().toISOString(), steps, error });
265
+ this.finish(run, { requestId: request.requestId, state: 'failed', target: request.executionPackage.target, startedAt, finishedAt: new Date().toISOString(), steps, error });
266
266
  return;
267
267
  }
268
268
  continue;
@@ -274,7 +274,7 @@ export class MigratedRunnerEngine {
274
274
  let lastError;
275
275
  for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
276
276
  try {
277
- outputs = await adapter.execute(withRuntimeValues({ action: step.action, inputs: stepInputs, environment: request.environment, step, signal: run.abortController.signal }, request.runtimeValues));
277
+ outputs = await adapter.execute(withRuntimeValues({ action: step.action, inputs: stepInputs, step, signal: run.abortController.signal }, request.runtimeValues));
278
278
  break;
279
279
  }
280
280
  catch (cause) {
@@ -297,7 +297,7 @@ export class MigratedRunnerEngine {
297
297
  steps.push({ id: step.id, name: step.name, state: 'failed', inputs: stepInputs, outputs: {}, durationMs: Date.now() - stepStarted, transportTiming: { requestStartedAt: transportStartedAt, responseReceivedAt: new Date().toISOString(), durationMs: Date.now() - transportStartedMs }, invocationId, invocationPath: planned.path, kind: step.kind ?? 'action', iteration: planned.iteration, error });
298
298
  failedStepIds.add(step.id);
299
299
  if (!planned.continueOnError) {
300
- this.finish(run, { requestId: request.requestId, state: 'failed', target: request.executionPackage.target, environment: request.environment, startedAt, finishedAt: new Date().toISOString(), steps, error });
300
+ this.finish(run, { requestId: request.requestId, state: 'failed', target: request.executionPackage.target, startedAt, finishedAt: new Date().toISOString(), steps, error });
301
301
  return;
302
302
  }
303
303
  continue;
@@ -314,7 +314,7 @@ export class MigratedRunnerEngine {
314
314
  return;
315
315
  }
316
316
  }
317
- this.finish(run, { requestId: request.requestId, state: 'completed', target: request.executionPackage.target, environment: request.environment, startedAt, finishedAt: new Date().toISOString(), steps: this.normalizeResults(steps, request.executionPackage.steps), warnings: validationWarnings });
317
+ this.finish(run, { requestId: request.requestId, state: 'completed', target: request.executionPackage.target, startedAt, finishedAt: new Date().toISOString(), steps: this.normalizeResults(steps, request.executionPackage.steps), warnings: validationWarnings });
318
318
  await resultPromise;
319
319
  }
320
320
  validateAll(pack, inputs, runtimeValues) {
@@ -448,7 +448,7 @@ export class MigratedRunnerEngine {
448
448
  const maxAttempts = Math.max(1, step.retry?.maxAttempts ?? 1);
449
449
  for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
450
450
  try {
451
- outputs = await adapter.execute(withRuntimeValues({ action: step.action, inputs: stepInputs, environment: request.environment, step, signal: controller.signal }, request.runtimeValues));
451
+ outputs = await adapter.execute(withRuntimeValues({ action: step.action, inputs: stepInputs, step, signal: controller.signal }, request.runtimeValues));
452
452
  break;
453
453
  }
454
454
  catch (cause) {
@@ -587,10 +587,10 @@ export class MigratedRunnerEngine {
587
587
  return false; run.controlState = 'running'; return true; }
588
588
  finishCancelled(run, startedAt, steps) { if (run.timedOut) {
589
589
  const error = { code: 'TIMEOUT', message: `Run exceeded its ${run.request.options?.timeoutMs}ms timeout.` };
590
- this.finish(run, { requestId: run.request.requestId, state: 'failed', target: run.request.executionPackage.target, environment: run.request.environment, startedAt, finishedAt: new Date().toISOString(), steps, error });
590
+ this.finish(run, { requestId: run.request.requestId, state: 'failed', target: run.request.executionPackage.target, startedAt, finishedAt: new Date().toISOString(), steps, error });
591
591
  }
592
592
  else
593
- this.finish(run, { requestId: run.request.requestId, state: 'cancelled', target: run.request.executionPackage.target, environment: run.request.environment, startedAt, finishedAt: new Date().toISOString(), steps }); }
593
+ this.finish(run, { requestId: run.request.requestId, state: 'cancelled', target: run.request.executionPackage.target, startedAt, finishedAt: new Date().toISOString(), steps }); }
594
594
  pause(run, ms) { return new Promise(resolve => { const started = Date.now(); const timer = globalThis.setInterval(() => { if (run.cancelled) {
595
595
  globalThis.clearInterval(timer);
596
596
  resolve(false);
package/dist/types.d.ts CHANGED
@@ -10,7 +10,6 @@ export interface ActionFailure {
10
10
  export interface ActionExecutionContext {
11
11
  action: string;
12
12
  inputs: Record<string, unknown>;
13
- environment: string;
14
13
  runtimeValues: Record<string, unknown>;
15
14
  step: Pick<ExecutionStep, 'id' | 'name' | 'action' | 'output' | 'adapterConfig'>;
16
15
  signal: AbortSignal;
@@ -32,7 +31,6 @@ export interface ExecutorRequest {
32
31
  requestId: string;
33
32
  executionPackage: ExecutionPackage;
34
33
  inputs: Record<string, unknown>;
35
- environment: string;
36
34
  runtimeValues?: Record<string, unknown>;
37
35
  options?: {
38
36
  timeoutMs?: number;
@@ -84,7 +82,6 @@ export interface ExecutorResult {
84
82
  requestId: string;
85
83
  state: Exclude<ExecutionState, 'created' | 'preflighting' | 'running'>;
86
84
  target: ExecutionPackage['target'];
87
- environment: string;
88
85
  startedAt: string;
89
86
  finishedAt: string;
90
87
  steps: ExecutorStepResult[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qaick/executor",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
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.6.1"
37
+ "@qaick/contract": "0.7.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/node": "^24.13.3",