@agimon-ai/po-workflow 0.0.0-alpha.38 → 0.0.0-alpha.39

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.
@@ -756,6 +756,7 @@ const WorkflowLauncherMetadataSchema = zod.z.discriminatedUnion("type", [
756
756
  ]);
757
757
  const WorkflowRunRecordSchema = zod.z.object({
758
758
  activeRepairId: zod.z.string().regex(/^\d+$/).optional(),
759
+ /** Read-only legacy metadata. New runs only write runner. */
759
760
  cliAgent: zod.z.string().optional(),
760
761
  continueOnError: zod.z.boolean().optional(),
761
762
  displayName: zod.z.string(),
@@ -4752,7 +4753,6 @@ var WorkflowRegistryService = class {
4752
4753
  const runId = (0, node_crypto.randomUUID)();
4753
4754
  const runRecord = {
4754
4755
  activeRepairId: input.activeRepairId,
4755
- cliAgent: input.cliAgent,
4756
4756
  continueOnError: input.continueOnError,
4757
4757
  displayName: input.displayName,
4758
4758
  dryRun: input.dryRun,
@@ -6433,127 +6433,6 @@ const MAX_STEP_TIMEOUT_MINUTES = Math.floor(2147483647 / 6e4);
6433
6433
  const StepTimeoutMinutesSchema = zod.z.number().positive().finite().max(MAX_STEP_TIMEOUT_MINUTES);
6434
6434
  const StepTimeoutRetriesSchema = zod.z.number().int().min(0).max(STEP_TIMEOUT_RETRIES_LIMIT).default(STEP_TIMEOUT_MAX_RETRIES);
6435
6435
  //#endregion
6436
- //#region src/services/CodexQuotaService/index.ts
6437
- /**
6438
- * CodexQuotaService
6439
- *
6440
- * DESIGN PATTERNS:
6441
- * - Service pattern for business logic encapsulation
6442
- * - Single responsibility principle
6443
- *
6444
- * CODING STANDARDS:
6445
- * - Use async/await for asynchronous operations
6446
- * - Throw descriptive errors for error cases
6447
- * - Keep methods focused and well-named
6448
- * - Document complex logic with comments
6449
- *
6450
- * AVOID:
6451
- * - Mixing concerns (keep focused on single domain)
6452
- * - Direct tool implementation (services should be tool-agnostic)
6453
- */
6454
- const DEFAULT_CODEX_HOME_DIRNAME = ".codex";
6455
- const AUTH_FILENAME = "auth.json";
6456
- const CONFIG_FILENAME = "config.toml";
6457
- const DEFAULT_CHATGPT_BASE_URL = "https://chatgpt.com/backend-api/";
6458
- const CHATGPT_HOST = "https://chatgpt.com";
6459
- const CHAT_OPENAI_HOST = "https://chat.openai.com";
6460
- const BACKEND_API_SEGMENT = "/backend-api";
6461
- const QUOTA_USER_AGENT = "codex-cli";
6462
- const PRIMARY_WINDOW = "primary";
6463
- const SECONDARY_WINDOW = "secondary";
6464
- const QUOTA_REACHED_PERCENT = 100;
6465
- var CodexQuotaService = class {
6466
- codexHome;
6467
- fetchFn;
6468
- now;
6469
- readTextFile;
6470
- constructor(runtime, deps = {}) {
6471
- this.codexHome = deps.codexHome ?? runtime.baseEnvironment.CODEX_HOME ?? (0, node_path.join)(runtime.homeDirectory, DEFAULT_CODEX_HOME_DIRNAME);
6472
- this.fetchFn = deps.fetchFn ?? fetch;
6473
- this.now = deps.now ?? (() => Date.now());
6474
- this.readTextFile = deps.readTextFile ?? (async (path) => (0, _agimon_ai_po_core_platform.getOrThrow)(await runtime.fs.readTextFile(path, runtime.ioContext)));
6475
- }
6476
- isCodexCommand(command, _sourceAgentKey) {
6477
- const trimmed = command.trim();
6478
- return trimmed === "codex" || trimmed.startsWith("codex ");
6479
- }
6480
- async getQuotaStatus() {
6481
- const auth = await this.readAuthFile();
6482
- const accessToken = auth?.tokens?.access_token?.trim();
6483
- const accountId = auth?.tokens?.account_id?.trim();
6484
- if (!accessToken || !accountId) return null;
6485
- const baseUrl = await this.readChatgptBaseUrl();
6486
- const response = await this.fetchFn(this.buildUsageUrl(baseUrl), { headers: {
6487
- Authorization: `Bearer ${accessToken}`,
6488
- "ChatGPT-Account-Id": accountId,
6489
- "User-Agent": QUOTA_USER_AGENT
6490
- } });
6491
- if (!response.ok) throw new Error(`codex quota request failed with HTTP ${response.status}`);
6492
- const payload = await response.json();
6493
- return {
6494
- blockingLimit: this.findBlockingLimit(payload),
6495
- planType: payload.plan_type ?? null
6496
- };
6497
- }
6498
- async readAuthFile() {
6499
- const raw = await this.readOptionalTextFile((0, node_path.join)(this.codexHome, AUTH_FILENAME));
6500
- if (!raw) return null;
6501
- return JSON.parse(raw);
6502
- }
6503
- async readChatgptBaseUrl() {
6504
- const match = (await this.readOptionalTextFile((0, node_path.join)(this.codexHome, CONFIG_FILENAME)))?.match(/^\s*chatgpt_base_url\s*=\s*"([^"]+)"/m);
6505
- return this.normalizeBaseUrl(match?.[1] ?? DEFAULT_CHATGPT_BASE_URL);
6506
- }
6507
- buildUsageUrl(baseUrl) {
6508
- return baseUrl.includes(BACKEND_API_SEGMENT) ? `${baseUrl}/wham/usage` : `${baseUrl}/api/codex/usage`;
6509
- }
6510
- normalizeBaseUrl(baseUrl) {
6511
- let normalized = baseUrl.trim().replace(/\/+$/, "");
6512
- if ((normalized.startsWith(CHATGPT_HOST) || normalized.startsWith(CHAT_OPENAI_HOST)) && !normalized.includes(BACKEND_API_SEGMENT)) normalized = `${normalized}${BACKEND_API_SEGMENT}`;
6513
- return normalized;
6514
- }
6515
- async readOptionalTextFile(path) {
6516
- try {
6517
- return await this.readTextFile(path);
6518
- } catch (error) {
6519
- if (error.code === "ENOENT") return null;
6520
- throw error;
6521
- }
6522
- }
6523
- findBlockingLimit(payload) {
6524
- const blocks = [];
6525
- this.collectBlockingLimit(blocks, "codex", "codex", payload.rate_limit);
6526
- for (const additionalLimit of payload.additional_rate_limits ?? []) this.collectBlockingLimit(blocks, additionalLimit.metered_feature ?? additionalLimit.limit_name ?? "codex", additionalLimit.limit_name ?? additionalLimit.metered_feature ?? "codex", additionalLimit.rate_limit);
6527
- blocks.sort((left, right) => left.resetAt - right.resetAt || right.usedPercent - left.usedPercent);
6528
- return blocks[0] ?? null;
6529
- }
6530
- collectBlockingLimit(blocks, limitId, limitName, limit) {
6531
- if (!limit) return;
6532
- const windows = [{
6533
- payload: limit.primary_window,
6534
- window: PRIMARY_WINDOW
6535
- }, {
6536
- payload: limit.secondary_window,
6537
- window: SECONDARY_WINDOW
6538
- }];
6539
- for (const { payload, window } of windows) {
6540
- const resetAt = payload?.reset_at;
6541
- const usedPercent = payload?.used_percent ?? 0;
6542
- if (typeof resetAt !== "number") continue;
6543
- if (!(usedPercent >= QUOTA_REACHED_PERCENT || limit.limit_reached === true && resetAt * 1e3 > this.now() || limit.allowed === false && resetAt * 1e3 > this.now())) continue;
6544
- blocks.push({
6545
- limitId,
6546
- limitName,
6547
- resetAfterSeconds: payload?.reset_after_seconds ?? null,
6548
- resetAt,
6549
- usedPercent,
6550
- window,
6551
- windowSeconds: payload?.limit_window_seconds ?? null
6552
- });
6553
- }
6554
- }
6555
- };
6556
- //#endregion
6557
6436
  //#region src/services/StepRunnerService/index.ts
6558
6437
  /**
6559
6438
  * StepRunnerService
@@ -6716,33 +6595,15 @@ const WORKFLOW_STEP_NAME_ENV_KEY = "WORKFLOW_STEP_NAME";
6716
6595
  const WORKFLOW_STEP_DISPLAY_ENV_KEY = "WORKFLOW_STEP_DISPLAY";
6717
6596
  const WORKFLOW_STEP_ARTIFACTS_ENV_KEY = "WORKFLOW_STEP_ARTIFACTS";
6718
6597
  const WORKFLOW_TERMINAL_TITLE = "workflow-mcp";
6719
- const STATUS_FILE_PREFIX = "workflow-step-";
6720
- const STATUS_FILE_SUFFIX = ".status";
6721
- const STATUS_FILE_COMPLETION_VALUE = "YES";
6722
- const STATUS_FILE_COMPLETED_RESULT = { status: "status_completed" };
6723
- const TRANSIENT_FS_ERROR_CODES = /* @__PURE__ */ new Set([
6724
- "ENOENT",
6725
- "EBUSY",
6726
- "EAGAIN",
6727
- "EPERM",
6728
- "not_found"
6729
- ]);
6730
- const STATUS_FILE_POLL_INTERVAL_MS = 1e3;
6731
6598
  const STOP_REQUEST_POLL_INTERVAL_MS = 1e3;
6732
- const STATUS_DONE = "done";
6733
6599
  const STATUS_STOP = "stop";
6734
6600
  const EXPLICIT_RUNNER_MISSING_PREFIX = "runner";
6735
6601
  const EXPLICIT_RUNNER_MISSING_MIDDLE = "not found for step";
6736
6602
  const EXPLICIT_RUNNER_AVAILABLE_PREFIX = "available runner keys:";
6737
- const QUOTA_WAIT_POLL_INTERVAL_MS = 3e4;
6738
- const QUOTA_WAIT_RESET_BUFFER_MS = 1e3;
6739
- const QUOTA_WAIT_SOURCE = "StepRunnerService.waitForCodexQuota";
6740
- const QUOTA_RETRY_REASON = "codex quota reached after failed step, retrying after reset";
6741
6603
  const RESULT_STATUS_COMPLETED = "completed";
6742
6604
  const RESULT_STATUS_SPAWN_ERROR = "spawn_error";
6743
6605
  const RESULT_STATUS_SIGNALED = "signaled";
6744
6606
  const RESULT_STATUS_TIMED_OUT = "timed_out";
6745
- const RESULT_STATUS_STATUS_COMPLETED = "status_completed";
6746
6607
  const RESULT_STATUS_STOP_REQUESTED = "stop_requested";
6747
6608
  const RESULT_STATUS_PAUSE_REQUESTED = "pause_requested";
6748
6609
  /** The reason a step failure carries when nothing more specific was recorded. */
@@ -6775,8 +6636,7 @@ var StepRunnerService = class StepRunnerService {
6775
6636
  runtime;
6776
6637
  parser;
6777
6638
  logger;
6778
- quotaService;
6779
- watchStatusFile;
6639
+ watchControlFile;
6780
6640
  runDirectoryService;
6781
6641
  ownsTerminal;
6782
6642
  stepExecutor;
@@ -6785,7 +6645,6 @@ var StepRunnerService = class StepRunnerService {
6785
6645
  activeExternal = null;
6786
6646
  lastInteractiveReap = null;
6787
6647
  interruptedSignal = null;
6788
- activeQuotaWait = null;
6789
6648
  commandSelection = {};
6790
6649
  /** Runners of a parallel group's steps, which a stop must reach too. */
6791
6650
  forks = /* @__PURE__ */ new Set();
@@ -6800,12 +6659,11 @@ var StepRunnerService = class StepRunnerService {
6800
6659
  * must not hand a step's stdin to it, and must not `stty` or reset it
6801
6660
  * afterwards, however cooperative the intent.
6802
6661
  */
6803
- constructor(runtime, parser, logger, quotaService = new CodexQuotaService(runtime), watchStatusFile = runtime.fs.watch.bind(runtime.fs), runDirectoryService = new RunDirectoryService(runtime), ownsTerminal = true, stepExecutor, resolveSecrets) {
6662
+ constructor(runtime, parser, logger, watchControlFile = runtime.fs.watch.bind(runtime.fs), runDirectoryService = new RunDirectoryService(runtime), ownsTerminal = true, stepExecutor, resolveSecrets) {
6804
6663
  this.runtime = runtime;
6805
6664
  this.parser = parser;
6806
6665
  this.logger = logger;
6807
- this.quotaService = quotaService;
6808
- this.watchStatusFile = watchStatusFile;
6666
+ this.watchControlFile = watchControlFile;
6809
6667
  this.runDirectoryService = runDirectoryService;
6810
6668
  this.ownsTerminal = ownsTerminal;
6811
6669
  this.stepExecutor = stepExecutor;
@@ -6826,7 +6684,7 @@ var StepRunnerService = class StepRunnerService {
6826
6684
  * Release it once its step has finished.
6827
6685
  */
6828
6686
  fork(label) {
6829
- const child = new StepRunnerService(this.runtime, this.parser, labelledLogger(this.logger, label), this.quotaService, this.watchStatusFile, this.runDirectoryService, this.ownsTerminal, this.stepExecutor, this.resolveSecrets);
6687
+ const child = new StepRunnerService(this.runtime, this.parser, labelledLogger(this.logger, label), this.watchControlFile, this.runDirectoryService, this.ownsTerminal, this.stepExecutor, this.resolveSecrets);
6830
6688
  child.commandSelection = this.commandSelection;
6831
6689
  child.interruptedSignal = this.interruptedSignal;
6832
6690
  child.terminalLock = this.terminalLock;
@@ -6851,16 +6709,6 @@ var StepRunnerService = class StepRunnerService {
6851
6709
  for (const child of this.forks) child.stopActiveStep(signal);
6852
6710
  return;
6853
6711
  }
6854
- if (this.activeQuotaWait) {
6855
- if (this.activeQuotaWait.controller.signal.aborted) {
6856
- this.logger.info(` ${DIM$3}${STATUS_SKIP}${RESET$3} ${this.activeQuotaWait.stepName} ${ALREADY_STOPPING_SUFFIX}`);
6857
- return;
6858
- }
6859
- this.activeQuotaWait.signal = signal;
6860
- this.activeQuotaWait.controller.abort();
6861
- this.logger.info(` ${YELLOW$2}${STATUS_INTERRUPTED}${RESET$3} cancelling quota wait for ${this.activeQuotaWait.stepName}`);
6862
- return;
6863
- }
6864
6712
  if (this.activeExternal) {
6865
6713
  if (this.activeExternal.stopSignal) {
6866
6714
  this.logger.info(` ${DIM$3}${STATUS_SKIP}${RESET$3} ${this.activeExternal.stepName} ${ALREADY_STOPPING_SUFFIX}`);
@@ -6959,7 +6807,6 @@ var StepRunnerService = class StepRunnerService {
6959
6807
  return false;
6960
6808
  }
6961
6809
  const { command, custom, inProcessOnly, interactive, template } = resolvedStepCommand;
6962
- const isCodexCommand = this.quotaService.isCodexCommand(command, resolvedStepCommand.agentKey);
6963
6810
  const shouldContinue = step["continue-on-error"] || options.continueOnError;
6964
6811
  let timeoutMs;
6965
6812
  try {
@@ -7049,12 +6896,7 @@ var StepRunnerService = class StepRunnerService {
7049
6896
  }
7050
6897
  const stepStartedAt = Date.now();
7051
6898
  await this.logStepLifecycle("info", "workflow.step.started", stepEnv, { "workflow.step.interactive": interactive });
7052
- let statusFilePath;
7053
- if (interactive) {
7054
- statusFilePath = await this.createStatusFile();
7055
- stepEnv[STATUS_FILE_ENV_KEY] = statusFilePath;
7056
- this.logger.info(` ${DIM$3}status-file${RESET$3} ${statusFilePath}`);
7057
- } else delete stepEnv[STATUS_FILE_ENV_KEY];
6899
+ delete stepEnv[STATUS_FILE_ENV_KEY];
7058
6900
  if (options.dryRun) {
7059
6901
  this.logger.info(` ${CYAN$2}${STATUS_DRY}${RESET$3} ${stepName}`);
7060
6902
  this.logger.info(`${COMMAND_LOG_INDENT}${DIM$3}${COMMAND_LOG_PROMPT}${command.split(COMMAND_LINE_BREAK).join(COMMAND_LOG_CONTINUATION)}${RESET$3}`);
@@ -7103,9 +6945,7 @@ var StepRunnerService = class StepRunnerService {
7103
6945
  return false;
7104
6946
  }
7105
6947
  }
7106
- let quotaFailureRetried = false;
7107
6948
  for (let attempt = 0; attempt <= maxTimeoutRetries; attempt++) {
7108
- await this.waitForCodexQuotaAvailability(stepName, command, isCodexCommand);
7109
6949
  if (decisionFilePath && decisionIdentity) await resetDecisionFile(this.runtime, decisionFilePath, decisionIdentity);
7110
6950
  if (attempt > 0) this.logger.warn(` ${YELLOW$2}${STATUS_RETRY}${RESET$3} ${STEP_TIMEOUT_RETRY_PREFIX} "${stepName}" (attempt ${attempt + 1}/${maxTimeoutRetries + 1})`);
7111
6951
  else this.logger.info(` ${CYAN$2}${STATUS_RUN}${RESET$3} ${stepName}`);
@@ -7142,7 +6982,7 @@ var StepRunnerService = class StepRunnerService {
7142
6982
  timeoutMs,
7143
6983
  workDir
7144
6984
  }));
7145
- const executionResult = interactive && statusFilePath ? await this.raceInteractiveCompletion(executionPromise, statusFilePath, stepName, options.stopRequestPath, step["pause-policy"] ?? "replay") : options.stopRequestPath ? await this.raceStopRequest(executionPromise, stepName, options.stopRequestPath, step["pause-policy"] ?? "replay") : await executionPromise;
6985
+ const executionResult = interactive ? await this.raceInteractiveCompletion(executionPromise, stepName, options.stopRequestPath, step["pause-policy"] ?? "replay") : options.stopRequestPath ? await this.raceStopRequest(executionPromise, stepName, options.stopRequestPath, step["pause-policy"] ?? "replay") : await executionPromise;
7146
6986
  if (executionResult.status === RESULT_STATUS_PAUSE_REQUESTED) {
7147
6987
  await this.logStepLifecycle("info", "workflow.step.pause_requested", stepEnv, {
7148
6988
  "workflow.step.outcome": pausePolicy === "replay" ? "cancelled_for_pause" : "protected_boundary",
@@ -7199,7 +7039,6 @@ var StepRunnerService = class StepRunnerService {
7199
7039
  }
7200
7040
  const decision = decisionFilePath ? await readStepDecision(this.runtime, decisionFilePath) : void 0;
7201
7041
  if (decision) {
7202
- if (statusFilePath) await this.cleanupStatusFile(statusFilePath);
7203
7042
  if (decision.decision === "complete") {
7204
7043
  const artifactProblem = artifactSnapshots ? await this.describeArtifactWarnings(stepEnv, artifactSnapshots) : void 0;
7205
7044
  if (!artifactProblem) {
@@ -7233,15 +7072,7 @@ var StepRunnerService = class StepRunnerService {
7233
7072
  }
7234
7073
  if (executionResult.status === "timed_out") {
7235
7074
  fail(`${STEP_TIMEOUT_FAILURE_PREFIX} ${this.formatTimeoutMs(executionResult.timeoutMs)} "${stepName}" (${command.split(COMMAND_LINE_BREAK)[0]})`);
7236
- if (attempt < maxTimeoutRetries) {
7237
- if (statusFilePath) try {
7238
- (0, _agimon_ai_po_core_platform.getOrThrow)(await this.runtime.fs.writeFile(statusFilePath, "", this.runtime.ioContext));
7239
- } catch (error) {
7240
- this.logger.warn(` ${YELLOW$2}${STATUS_WARN}${RESET$3} status-file reset failed for ${stepName}: ${error instanceof Error ? error.message : String(error)}`);
7241
- }
7242
- continue;
7243
- }
7244
- if (statusFilePath) await this.cleanupStatusFile(statusFilePath);
7075
+ if (attempt < maxTimeoutRetries) continue;
7245
7076
  if (shouldContinue) {
7246
7077
  await this.logStepLifecycle("warn", "workflow.step.finished", stepEnv, {
7247
7078
  "workflow.step.duration_ms": Date.now() - stepStartedAt,
@@ -7258,7 +7089,6 @@ var StepRunnerService = class StepRunnerService {
7258
7089
  });
7259
7090
  return false;
7260
7091
  }
7261
- if (statusFilePath) await this.cleanupStatusFile(statusFilePath);
7262
7092
  if (decisionIdentity?.required && !(executionResult.status === "completed" && executionResult.failure !== void 0)) {
7263
7093
  fail(`step "${stepName}" ended without a workflow decision (workflow-mcp step complete|fix|fail)`);
7264
7094
  return this.failStep(stepName, stepEnv, stepStartedAt, shouldContinue, report);
@@ -7281,19 +7111,6 @@ var StepRunnerService = class StepRunnerService {
7281
7111
  });
7282
7112
  return true;
7283
7113
  }
7284
- if (executionResult.status === "status_completed") {
7285
- const artifactProblem = artifactSnapshots ? await this.describeArtifactWarnings(stepEnv, artifactSnapshots) : void 0;
7286
- if (artifactProblem) {
7287
- fail(`step "${stepName}" ${artifactProblem}`);
7288
- return this.failStep(stepName, stepEnv, stepStartedAt, shouldContinue, report);
7289
- }
7290
- this.logger.info(`\n ${GREEN$2}${STATUS_DONE}${RESET$3} ${stepName} (status-file signaled completion)\n`);
7291
- await this.logStepLifecycle("info", "workflow.step.finished", stepEnv, {
7292
- "workflow.step.duration_ms": Date.now() - stepStartedAt,
7293
- "workflow.step.outcome": "success"
7294
- });
7295
- return true;
7296
- }
7297
7114
  if (executionResult.status === "completed" && executionResult.exitCode === 0) {
7298
7115
  const artifactProblem = artifactSnapshots ? await this.describeArtifactWarnings(stepEnv, artifactSnapshots) : void 0;
7299
7116
  if (!artifactProblem) {
@@ -7307,12 +7124,6 @@ var StepRunnerService = class StepRunnerService {
7307
7124
  fail(`step "${stepName}" ${artifactProblem}`);
7308
7125
  }
7309
7126
  if (executionResult.status === "completed" && executionResult.exitCode !== 0) fail(executionResult.failure ? `step "${stepName}" failed: ${executionResult.failure}` : `${STEP_EXIT_FAILURE_PREFIX} "${stepName}" ${STEP_EXIT_FAILURE_MIDDLE} ${executionResult.exitCode} (${command.split(COMMAND_LINE_BREAK)[0]})`);
7310
- if (!quotaFailureRetried && await this.shouldRetryForCodexQuota(stepName, isCodexCommand)) {
7311
- quotaFailureRetried = true;
7312
- this.logger.warn(` ${YELLOW$2}${STATUS_RETRY}${RESET$3} ${QUOTA_RETRY_REASON}`);
7313
- attempt -= 1;
7314
- continue;
7315
- }
7316
7127
  if (shouldContinue) {
7317
7128
  await this.logStepLifecycle("warn", "workflow.step.finished", stepEnv, {
7318
7129
  "workflow.step.duration_ms": Date.now() - stepStartedAt,
@@ -7657,7 +7468,7 @@ var StepRunnerService = class StepRunnerService {
7657
7468
  /**
7658
7469
  * Await a host-owned execution and normalize it like a child process.
7659
7470
  *
7660
- * The engine keeps ownership of the timeout; stop, pause and status-file
7471
+ * The engine keeps ownership of the timeout; stop and pause
7661
7472
  * completion reach the execution through `killActiveStep`, which calls its
7662
7473
  * `stop`. A stopped execution reads as signalled so shutdown still interrupts
7663
7474
  * the workflow, while the completion races report their own outcome.
@@ -7980,7 +7791,7 @@ var StepRunnerService = class StepRunnerService {
7980
7791
  return [...keys];
7981
7792
  }
7982
7793
  resolveRunner(options) {
7983
- return options.runner ?? options.cliAgent;
7794
+ return options.runner;
7984
7795
  }
7985
7796
  formatStepDisplay(jobName, stepName) {
7986
7797
  return jobName ? `${jobName} > ${stepName}` : stepName;
@@ -7995,77 +7806,6 @@ var StepRunnerService = class StepRunnerService {
7995
7806
  escapeShellArg(value) {
7996
7807
  return `'${value.replace(/'/g, "'\\''")}'`;
7997
7808
  }
7998
- async shouldRetryForCodexQuota(stepName, isCodexCommand) {
7999
- if (!isCodexCommand) return false;
8000
- return (await this.readCodexQuotaStatus(stepName))?.blockingLimit != null;
8001
- }
8002
- async waitForCodexQuotaAvailability(stepName, command, isCodexCommand) {
8003
- if (!isCodexCommand) return;
8004
- while (true) {
8005
- const quotaStatus = await this.readCodexQuotaStatus(stepName);
8006
- const blockingLimit = quotaStatus?.blockingLimit;
8007
- if (!blockingLimit) return;
8008
- const waitTargetMs = blockingLimit.resetAt * 1e3 + QUOTA_WAIT_RESET_BUFFER_MS;
8009
- const remainingMs = Math.max(waitTargetMs - Date.now(), QUOTA_WAIT_RESET_BUFFER_MS);
8010
- const waitDescription = new Date(waitTargetMs).toLocaleString();
8011
- const planSuffix = quotaStatus?.planType ? ` (${quotaStatus.planType})` : "";
8012
- this.logger.warn(` ${YELLOW$2}${STATUS_WAIT}${RESET$3} codex quota ${blockingLimit.limitName}/${blockingLimit.window} is at ${blockingLimit.usedPercent}%${planSuffix}; waiting until ${waitDescription}`);
8013
- await this.waitForQuotaDelay(stepName, command, remainingMs);
8014
- }
8015
- }
8016
- async readCodexQuotaStatus(stepName) {
8017
- try {
8018
- return await this.quotaService.getQuotaStatus();
8019
- } catch (error) {
8020
- this.logger.warn(` ${YELLOW$2}${STATUS_WARN}${RESET$3} unable to read codex quota for "${stepName}" (${this.formatQuotaError(error)})`);
8021
- return null;
8022
- }
8023
- }
8024
- async waitForQuotaDelay(stepName, command, remainingMs) {
8025
- const controller = new AbortController();
8026
- this.activeQuotaWait = {
8027
- controller,
8028
- signal: null,
8029
- stepName
8030
- };
8031
- try {
8032
- let timeLeftMs = remainingMs;
8033
- while (timeLeftMs > 0) {
8034
- const sleepMs = Math.min(timeLeftMs, QUOTA_WAIT_POLL_INTERVAL_MS);
8035
- await this.waitForDelay(sleepMs, controller.signal);
8036
- timeLeftMs -= sleepMs;
8037
- }
8038
- } catch (error) {
8039
- if (controller.signal.aborted) throw new WorkflowInterruptedError(this.activeQuotaWait?.signal ?? TERMINATE_SIGNAL$1, {
8040
- cause: /* @__PURE__ */ new Error(`Interrupted while waiting for Codex quota reset`),
8041
- context: {
8042
- ...this.createInterruptContext(stepName, command),
8043
- phase: QUOTA_WAIT_SOURCE
8044
- }
8045
- });
8046
- throw error;
8047
- } finally {
8048
- this.activeQuotaWait = null;
8049
- }
8050
- }
8051
- async waitForDelay(delayMs, signal) {
8052
- await new Promise((resolveDelay, rejectDelay) => {
8053
- const timeout = setTimeout(() => {
8054
- signal.removeEventListener("abort", onAbort);
8055
- resolveDelay();
8056
- }, delayMs);
8057
- const onAbort = () => {
8058
- clearTimeout(timeout);
8059
- signal.removeEventListener("abort", onAbort);
8060
- rejectDelay(/* @__PURE__ */ new Error("aborted"));
8061
- };
8062
- signal.addEventListener("abort", onAbort, { once: true });
8063
- });
8064
- }
8065
- formatQuotaError(error) {
8066
- if (error instanceof Error && error.message.trim().length > 0) return error.message;
8067
- return "unknown quota error";
8068
- }
8069
7809
  /**
8070
7810
  * Resolve the per-step timeout from workflow YAML into milliseconds.
8071
7811
  */
@@ -8210,10 +7950,8 @@ var StepRunnerService = class StepRunnerService {
8210
7950
  return Number.isInteger(parsed) && parsed > 0 ? parsed : PROCESS_EXIT_WAIT_TIMEOUT_MS;
8211
7951
  }
8212
7952
  /**
8213
- * SIGTERM→SIGKILL grace on the completion path (status file signalled `YES`).
8214
- * Deliberately longer than the timeout-path `FORCE_KILL_GRACE_PERIOD_MS` so an
8215
- * interactive agent can flush its final telemetry batch (e.g. Claude Code's
8216
- * OTEL Stop-hook events) before SIGKILL. A fast graceful exit still settles
7953
+ * Grace for interactive stop and pause teardown, allowing telemetry to flush.
7954
+ * A fast graceful exit still settles
8217
7955
  * immediately, so this only adds latency when a child lingers. Operator-tunable
8218
7956
  * via `WORKFLOW_STEP_FORCE_KILL_GRACE_MS`; defaults to STEP_COMPLETION_KILL_GRACE_MS.
8219
7957
  */
@@ -8353,7 +8091,7 @@ var StepRunnerService = class StepRunnerService {
8353
8091
  * Interactive TUIs such as Claude Code make themselves process-group leaders
8354
8092
  * (pid === pgid) and spawn descendants into that group. Reaping by pid alone
8355
8093
  * leaves anything spawned after the one-shot tree snapshot alive, which keeps
8356
- * the interactive session running after the Stop hook signalled completion.
8094
+ * the interactive session running after a stop or pause request.
8357
8095
  */
8358
8096
  collectInteractiveProcessGroupIds(processIds) {
8359
8097
  if (processIds.length === 0) return [];
@@ -8456,38 +8194,17 @@ var StepRunnerService = class StepRunnerService {
8456
8194
  return false;
8457
8195
  }
8458
8196
  }
8459
- /**
8460
- * Create an empty temp file that the Claude Code Stop hook will write
8461
- * YES to when the agent finishes its turn. The path is injected into
8462
- * WORKFLOW_STATUS_FILE so the hook can locate it directly — no fallback
8463
- * marker file is used.
8464
- */
8465
- async createStatusFile() {
8466
- if (!this.runtime.temporaryDirectory) throw new Error("Workflow interactive status files require an admitted temporaryDirectory");
8467
- const filePath = (0, node_path.join)(this.runtime.temporaryDirectory, `${STATUS_FILE_PREFIX}${(0, node_crypto.randomUUID)()}${STATUS_FILE_SUFFIX}`);
8468
- (0, _agimon_ai_po_core_platform.getOrThrow)(await this.runtime.fs.writeFile(filePath, "", this.runtime.ioContext));
8469
- return filePath;
8470
- }
8471
- /**
8472
- * Race interactive step execution against agent completion and workflow stop files.
8473
- * When the file contains YES, SIGTERM the step process and wait for
8474
- * it to exit before returning `status_completed`. Escalates to SIGKILL
8475
- * if the process ignores SIGTERM. The next job must not start until
8476
- * the child process tree has fully exited.
8477
- */
8478
- async raceInteractiveCompletion(executionPromise, statusFilePath, stepName, stopRequestPath, pausePolicy) {
8197
+ /** Race interactive execution against workflow stop and pause requests. */
8198
+ async raceInteractiveCompletion(executionPromise, stepName, stopRequestPath, pausePolicy) {
8479
8199
  return new Promise((resolveRace) => {
8480
8200
  let settled = false;
8481
- let statusFileTriggered = false;
8482
8201
  let stopRequestTriggered = false;
8483
8202
  let pauseRequestTriggered = false;
8484
8203
  const pauseRequestPath = stopRequestPath ? (0, node_path.join)((0, node_path.dirname)(stopRequestPath), PAUSE_REQUEST_FILENAME) : void 0;
8485
8204
  let forceKillTimer = null;
8486
8205
  let completionSettleTimer = null;
8487
- let watcher = null;
8488
8206
  let stopWatcher = null;
8489
8207
  let pauseWatcher = null;
8490
- let pollTimer = null;
8491
8208
  let stopPollTimer = null;
8492
8209
  let pausePollTimer = null;
8493
8210
  let signalDelivered = false;
@@ -8495,7 +8212,6 @@ var StepRunnerService = class StepRunnerService {
8495
8212
  const resolveCompletionSource = (result) => {
8496
8213
  if (stopRequestTriggered) return "stop-request";
8497
8214
  if (pauseRequestTriggered) return "pause-request";
8498
- if (statusFileTriggered) return "status-file";
8499
8215
  switch (result.status) {
8500
8216
  case RESULT_STATUS_TIMED_OUT: return "timed-out";
8501
8217
  case RESULT_STATUS_SPAWN_ERROR: return "spawn-error";
@@ -8506,10 +8222,6 @@ var StepRunnerService = class StepRunnerService {
8506
8222
  const settle = async (result) => {
8507
8223
  if (settled) return;
8508
8224
  settled = true;
8509
- if (watcher) {
8510
- await watcher.close(this.runtime.ioContext).catch((error) => this.logger.warn(`Workflow watcher cleanup failed: ${String(error)}`));
8511
- watcher = null;
8512
- }
8513
8225
  if (stopWatcher) {
8514
8226
  await stopWatcher.close(this.runtime.ioContext).catch((error) => this.logger.warn(`Workflow watcher cleanup failed: ${String(error)}`));
8515
8227
  stopWatcher = null;
@@ -8518,10 +8230,6 @@ var StepRunnerService = class StepRunnerService {
8518
8230
  await pauseWatcher.close(this.runtime.ioContext).catch((error) => this.logger.warn(`Workflow watcher cleanup failed: ${String(error)}`));
8519
8231
  pauseWatcher = null;
8520
8232
  }
8521
- if (pollTimer) {
8522
- clearInterval(pollTimer);
8523
- pollTimer = null;
8524
- }
8525
8233
  if (stopPollTimer) {
8526
8234
  clearInterval(stopPollTimer);
8527
8235
  stopPollTimer = null;
@@ -8545,25 +8253,13 @@ var StepRunnerService = class StepRunnerService {
8545
8253
  await this.recordInteractiveCompletion({
8546
8254
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
8547
8255
  stepName,
8548
- statusFilePath,
8549
8256
  completionSource: resolveCompletionSource(settledResult),
8550
- statusFileSignaled: statusFileTriggered,
8551
8257
  sigkillEscalated: sigkillEscalated || (this.lastInteractiveReap?.sigkillEscalated ?? false),
8552
8258
  survivors: this.lastInteractiveReap?.survivors ?? []
8553
8259
  });
8554
8260
  this.lastInteractiveReap = null;
8555
8261
  resolveRace(settledResult);
8556
8262
  };
8557
- const statusFileHasCompletionValue = async () => {
8558
- try {
8559
- return await (0, _agimon_ai_po_core_platform.pathExists)(this.runtime.fs, statusFilePath, this.runtime.ioContext) && (0, _agimon_ai_po_core_platform.getOrThrow)(await this.runtime.fs.readTextFile(statusFilePath, this.runtime.ioContext)).trim() === STATUS_FILE_COMPLETION_VALUE;
8560
- } catch (error) {
8561
- const code = error.code;
8562
- if (!code || !TRANSIENT_FS_ERROR_CODES.has(code)) this.logger.warn(` ${YELLOW$2}${STATUS_WARN}${RESET$3} status-file read failed for ${stepName}: ${error instanceof Error ? error.message : String(error)}`);
8563
- else this.logger.info(` ${DIM$3}status-file${RESET$3} transient FS error (${code}) polling ${stepName}`);
8564
- return false;
8565
- }
8566
- };
8567
8263
  const scheduleAbsoluteSettle = (result, delayMs) => {
8568
8264
  if (settled || completionSettleTimer) return;
8569
8265
  completionSettleTimer = setTimeout(() => {
@@ -8582,24 +8278,6 @@ var StepRunnerService = class StepRunnerService {
8582
8278
  settle(result);
8583
8279
  }, delayMs);
8584
8280
  };
8585
- const checkFileContent = async () => {
8586
- if (!await statusFileHasCompletionValue() || settled || statusFileTriggered) return;
8587
- statusFileTriggered = true;
8588
- const graceMs = this.stepCompletionKillGraceMs();
8589
- signalDelivered = this.killActiveStep(TERMINATE_SIGNAL$1);
8590
- if (!signalDelivered) {
8591
- this.logger.warn(` ${YELLOW$2}${STATUS_WARN}${RESET$3} ${stepName} status-file: SIGTERM could not be delivered, process may have already exited`);
8592
- scheduleAbsoluteSettle(STATUS_FILE_COMPLETED_RESULT, PROCESS_EXIT_WAIT_TIMEOUT_MS);
8593
- return;
8594
- }
8595
- forceKillTimer = setTimeout(() => {
8596
- if (settled) return;
8597
- sigkillEscalated = true;
8598
- this.logger.warn(` ${YELLOW$2}${STATUS_WARN}${RESET$3} ${stepName} did not exit after status-file SIGTERM, forcing SIGKILL`);
8599
- this.killActiveStep(TERMINATE_FORCE_KILL_SIGNAL);
8600
- }, graceMs);
8601
- scheduleAbsoluteSettle(STATUS_FILE_COMPLETED_RESULT, graceMs + PROCESS_EXIT_WAIT_TIMEOUT_MS);
8602
- };
8603
8281
  const stopRequestExists = async () => Boolean(stopRequestPath && await this.hasCurrentStopRequest(stopRequestPath));
8604
8282
  const pauseRequestExists = async () => Boolean(pauseRequestPath && await (0, _agimon_ai_po_core_platform.pathExists)(this.runtime.fs, pauseRequestPath, this.runtime.ioContext) && await this.readControlAction(pauseRequestPath) === "pause");
8605
8283
  const checkStopRequest = async () => {
@@ -8639,23 +8317,9 @@ var StepRunnerService = class StepRunnerService {
8639
8317
  }, graceMs);
8640
8318
  scheduleAbsoluteSettle({ status: RESULT_STATUS_PAUSE_REQUESTED }, graceMs + PROCESS_EXIT_WAIT_TIMEOUT_MS);
8641
8319
  };
8642
- try {
8643
- this.watchStatusFile([{ path: statusFilePath }], () => {
8644
- checkFileContent().catch((error) => this.logger.warn(`Workflow control check failed: ${String(error)}`));
8645
- }, this.runtime.ioContext).then(async (result) => {
8646
- const admitted = (0, _agimon_ai_po_core_platform.getOrThrow)(result);
8647
- if (settled) await admitted.close(this.runtime.ioContext);
8648
- else watcher = admitted;
8649
- }).catch((error) => this.logger.warn(`Workflow status-file watcher unavailable, polling instead: ${String(error)}`));
8650
- } catch (error) {
8651
- this.logger.warn(` ${YELLOW$2}${STATUS_WARN}${RESET$3} status-file watcher setup failed for ${stepName}: ${error instanceof Error ? error.message : String(error)}`);
8652
- }
8653
- pollTimer = setInterval(() => {
8654
- checkFileContent().catch((error) => this.logger.warn(`Workflow control check failed: ${String(error)}`));
8655
- }, STATUS_FILE_POLL_INTERVAL_MS);
8656
8320
  if (stopRequestPath) {
8657
8321
  try {
8658
- this.watchStatusFile([{ path: stopRequestPath }], () => {
8322
+ this.watchControlFile([{ path: stopRequestPath }], () => {
8659
8323
  checkStopRequest().catch((error) => this.logger.warn(`Workflow control check failed: ${String(error)}`));
8660
8324
  }, this.runtime.ioContext).then(async (result) => {
8661
8325
  const admitted = (0, _agimon_ai_po_core_platform.getOrThrow)(result);
@@ -8671,7 +8335,7 @@ var StepRunnerService = class StepRunnerService {
8671
8335
  }
8672
8336
  if (pauseRequestPath) {
8673
8337
  try {
8674
- this.watchStatusFile([{ path: pauseRequestPath }], () => {
8338
+ this.watchControlFile([{ path: pauseRequestPath }], () => {
8675
8339
  checkPauseRequest().catch((error) => this.logger.warn(`Workflow control check failed: ${String(error)}`));
8676
8340
  }, this.runtime.ioContext).then(async (result) => {
8677
8341
  const admitted = (0, _agimon_ai_po_core_platform.getOrThrow)(result);
@@ -8685,7 +8349,6 @@ var StepRunnerService = class StepRunnerService {
8685
8349
  checkPauseRequest().catch((error) => this.logger.warn(`Workflow control check failed: ${String(error)}`));
8686
8350
  }, STOP_REQUEST_POLL_INTERVAL_MS);
8687
8351
  }
8688
- checkFileContent().catch((error) => this.logger.warn(`Workflow control check failed: ${String(error)}`));
8689
8352
  checkStopRequest().catch((error) => this.logger.warn(`Workflow control check failed: ${String(error)}`));
8690
8353
  checkPauseRequest().catch((error) => this.logger.warn(`Workflow control check failed: ${String(error)}`));
8691
8354
  executionPromise.then(async (result) => {
@@ -8694,42 +8357,9 @@ var StepRunnerService = class StepRunnerService {
8694
8357
  settle({ status: RESULT_STATUS_STOP_REQUESTED });
8695
8358
  return;
8696
8359
  }
8697
- const completedViaStatusFile = statusFileTriggered || await statusFileHasCompletionValue();
8698
- const protectedPauseEligible = result.status === RESULT_STATUS_STATUS_COMPLETED || result.status === RESULT_STATUS_COMPLETED && result.exitCode === 0;
8699
- if (pauseRequestTriggered && (pausePolicy !== "protected" || protectedPauseEligible) && (pausePolicy === "protected" || !statusFileTriggered)) {
8700
- settle({ status: RESULT_STATUS_PAUSE_REQUESTED });
8701
- return;
8702
- }
8703
- if (!completedViaStatusFile) {
8704
- settle(result);
8705
- return;
8706
- }
8707
- if (!statusFileTriggered) {
8708
- statusFileTriggered = true;
8709
- this.logger.info(` ${GREEN$2}${STATUS_DONE}${RESET$3} ${stepName} status-file observed during process exit handling`);
8710
- }
8711
- switch (result.status) {
8712
- case RESULT_STATUS_SPAWN_ERROR:
8713
- case RESULT_STATUS_TIMED_OUT:
8714
- settle(result);
8715
- return;
8716
- case RESULT_STATUS_SIGNALED:
8717
- if (sigkillEscalated) this.logger.warn(` ${YELLOW$2}${STATUS_WARN}${RESET$3} ${stepName} required SIGKILL escalation (work completed via status-file)`);
8718
- settle(STATUS_FILE_COMPLETED_RESULT);
8719
- return;
8720
- case RESULT_STATUS_COMPLETED:
8721
- if (sigkillEscalated) this.logger.warn(` ${YELLOW$2}${STATUS_WARN}${RESET$3} ${stepName} required SIGKILL escalation (work completed via status-file, exit code ${result.exitCode})`);
8722
- settle(STATUS_FILE_COMPLETED_RESULT);
8723
- return;
8724
- case RESULT_STATUS_STATUS_COMPLETED:
8725
- settle(result);
8726
- return;
8727
- case RESULT_STATUS_STOP_REQUESTED:
8728
- case RESULT_STATUS_PAUSE_REQUESTED:
8729
- settle(result);
8730
- return;
8731
- default: settle(result);
8732
- }
8360
+ const protectedPauseEligible = result.status === RESULT_STATUS_COMPLETED && result.exitCode === 0;
8361
+ if (pauseRequestTriggered && (pausePolicy !== "protected" || protectedPauseEligible)) settle({ status: RESULT_STATUS_PAUSE_REQUESTED });
8362
+ else settle(result);
8733
8363
  });
8734
8364
  });
8735
8365
  }
@@ -8778,7 +8408,7 @@ var StepRunnerService = class StepRunnerService {
8778
8408
  }, FORCE_KILL_GRACE_PERIOD_MS);
8779
8409
  };
8780
8410
  try {
8781
- this.watchStatusFile([{ path: stopRequestPath }], () => {
8411
+ this.watchControlFile([{ path: stopRequestPath }], () => {
8782
8412
  checkStopRequest().catch((error) => this.logger.warn(`Workflow control check failed: ${String(error)}`));
8783
8413
  }, this.runtime.ioContext).then(async (result) => {
8784
8414
  const admitted = (0, _agimon_ai_po_core_platform.getOrThrow)(result);
@@ -8793,7 +8423,7 @@ var StepRunnerService = class StepRunnerService {
8793
8423
  }, STOP_REQUEST_POLL_INTERVAL_MS);
8794
8424
  checkStopRequest().catch((error) => this.logger.warn(`Workflow control check failed: ${String(error)}`));
8795
8425
  executionPromise.then(async (result) => {
8796
- const protectedPauseEligible = result.status === RESULT_STATUS_STATUS_COMPLETED || result.status === RESULT_STATUS_COMPLETED && result.exitCode === 0;
8426
+ const protectedPauseEligible = result.status === RESULT_STATUS_COMPLETED && result.exitCode === 0;
8797
8427
  if (stopRequestTriggered) settle({ status: RESULT_STATUS_STOP_REQUESTED });
8798
8428
  else if (pauseRequestTriggered && (pausePolicy !== "protected" || protectedPauseEligible)) settle({ status: RESULT_STATUS_PAUSE_REQUESTED });
8799
8429
  else settle(result);
@@ -8903,16 +8533,6 @@ var StepRunnerService = class StepRunnerService {
8903
8533
  this.logger.warn(` ${YELLOW$2}${STATUS_WARN}${RESET$3} failed to restore terminal state: ${String(error)}`);
8904
8534
  }
8905
8535
  }
8906
- /**
8907
- * Remove the temp status file and the well-known marker file after step completion.
8908
- */
8909
- async cleanupStatusFile(statusFilePath) {
8910
- try {
8911
- if (await (0, _agimon_ai_po_core_platform.pathExists)(this.runtime.fs, statusFilePath, this.runtime.ioContext)) (0, _agimon_ai_po_core_platform.getOrThrow)(await this.runtime.fs.remove(statusFilePath, { force: true }, this.runtime.ioContext));
8912
- } catch (error) {
8913
- this.logger.warn(` ${YELLOW$2}${STATUS_WARN}${RESET$3} status-file cleanup failed: ${error instanceof Error ? error.message : String(error)}`);
8914
- }
8915
- }
8916
8536
  };
8917
8537
  //#endregion
8918
8538
  //#region src/services/TriggerService/index.ts
@@ -9636,7 +9256,7 @@ var RunWorkflowService = class {
9636
9256
  this.launcherMetadata = dependencies.launcherMetadata;
9637
9257
  this.parser = dependencies.parser ?? new WorkflowParserService(this.runtime);
9638
9258
  this.serviceManager = dependencies.serviceManager ?? new BackgroundServiceManager(this.runtime, this.logger);
9639
- this.stepRunner = dependencies.stepRunner ?? new StepRunnerService(this.runtime, this.parser, this.logger, void 0, void 0, void 0, dependencies.ownsTerminal, dependencies.stepExecutor, dependencies.resolveSecrets);
9259
+ this.stepRunner = dependencies.stepRunner ?? new StepRunnerService(this.runtime, this.parser, this.logger, void 0, void 0, dependencies.ownsTerminal, dependencies.stepExecutor, dependencies.resolveSecrets);
9640
9260
  this.registry = dependencies.registry ?? new WorkflowRegistryService(this.runtime);
9641
9261
  this.runDirectoryService = dependencies.runDirectoryService ?? new RunDirectoryService(this.runtime, this.registry.writeCoordinator);
9642
9262
  this.jobRunner = dependencies.jobRunner ?? new JobRunnerService(this.runtime, this.parser, this.stepRunner, this.logger, this.runDirectoryService);
@@ -9648,6 +9268,7 @@ var RunWorkflowService = class {
9648
9268
  * Run the workflow from trigger preparation through cleanup.
9649
9269
  */
9650
9270
  async run(input) {
9271
+ if ("cliAgent" in input) throw new Error("cliAgent is retired. Use runner explicitly.");
9651
9272
  this.stepRunner.resetInterruption();
9652
9273
  this.triggerService.resetInterruption();
9653
9274
  this.outputLines = [];
@@ -9835,8 +9456,7 @@ var RunWorkflowService = class {
9835
9456
  });
9836
9457
  }
9837
9458
  resolveRunner(input, workflow) {
9838
- if (input.runner && input.cliAgent && input.runner !== input.cliAgent) throw new Error(`Conflicting runner selectors: runner="${input.runner}" cliAgent="${input.cliAgent}"`);
9839
- return input.runner ?? input.cliAgent ?? (workflow ? this.resolveWorkflowRunner(workflow) : void 0);
9459
+ return input.runner ?? (workflow ? this.resolveWorkflowRunner(workflow) : void 0);
9840
9460
  }
9841
9461
  /**
9842
9462
  * Execute the workflow after signal handlers are installed.
@@ -9969,7 +9589,6 @@ var RunWorkflowService = class {
9969
9589
  if (dryRun && input.recovery) registryRun = await this.createRecoveryDryRunHandle(input, resolvedWorkspace);
9970
9590
  else registryRun = await this.registry.createRun({
9971
9591
  activeRepairId: input.recovery?.activeRepairId,
9972
- cliAgent: input.cliAgent,
9973
9592
  continueOnError: input.continueOnError,
9974
9593
  displayName: workflowName,
9975
9594
  dryRun,
@@ -10062,7 +9681,6 @@ var RunWorkflowService = class {
10062
9681
  }
10063
9682
  if (!await this.triggerService.handleAgentDecision(workflow, workflowEnv, inputs, secrets, {
10064
9683
  runner,
10065
- cliAgent: input.cliAgent,
10066
9684
  dryRun,
10067
9685
  continueOnError,
10068
9686
  stopRequestPath: registryRun.stopRequestPath,
@@ -10101,7 +9719,6 @@ var RunWorkflowService = class {
10101
9719
  this.logger.info(` ${"─".repeat(50)}`);
10102
9720
  if (!await this.worktreeService.runHook(workflow.worktree.beforeCreate, workflowDir, workflowEnv, inputs, secrets, {
10103
9721
  runner,
10104
- cliAgent: input.cliAgent,
10105
9722
  dryRun,
10106
9723
  continueOnError,
10107
9724
  stopRequestPath: registryRun.stopRequestPath,
@@ -10133,7 +9750,6 @@ var RunWorkflowService = class {
10133
9750
  this.logger.info(` ${"─".repeat(50)}`);
10134
9751
  if (!await this.worktreeService.runHook(workflow.worktree.afterCreate, worktreePath, workflowEnv, inputs, secrets, {
10135
9752
  runner,
10136
- cliAgent: input.cliAgent,
10137
9753
  dryRun,
10138
9754
  continueOnError,
10139
9755
  stopRequestPath: registryRun.stopRequestPath,
@@ -10166,7 +9782,6 @@ var RunWorkflowService = class {
10166
9782
  const preStopRequestPath = registryRun.stopRequestPath;
10167
9783
  if (!await this.recordPhase(progress, PRE_PHASE_JOB, () => this.runPreBlock(preBlock, workflowEnv, inputs, secrets, {
10168
9784
  runner,
10169
- cliAgent: input.cliAgent,
10170
9785
  dryRun,
10171
9786
  continueOnError,
10172
9787
  progress,
@@ -10244,7 +9859,6 @@ var RunWorkflowService = class {
10244
9859
  runDirectory: workflow["run-directory"]
10245
9860
  }, {
10246
9861
  runner,
10247
- cliAgent: input.cliAgent,
10248
9862
  dryRun,
10249
9863
  continueOnError,
10250
9864
  stopRequestPath,
@@ -10351,7 +9965,6 @@ var RunWorkflowService = class {
10351
9965
  } : void 0
10352
9966
  }, {
10353
9967
  runner,
10354
- cliAgent: input.cliAgent,
10355
9968
  dryRun,
10356
9969
  continueOnError,
10357
9970
  stopRequestPath: registryRun.stopRequestPath,
@@ -10562,7 +10175,6 @@ var RunWorkflowService = class {
10562
10175
  this.logger.info(` ${"─".repeat(50)}`);
10563
10176
  if (!await this.worktreeService.runHook(workflow.worktree.beforeCompleted, worktreePath, workflowEnv, inputs, secrets, {
10564
10177
  runner,
10565
- cliAgent: input.cliAgent,
10566
10178
  dryRun,
10567
10179
  continueOnError
10568
10180
  })) {
@@ -10587,7 +10199,6 @@ var RunWorkflowService = class {
10587
10199
  try {
10588
10200
  if (!await this.recordPhase(progress, POST_PHASE_JOB, () => this.runPostBlock(postBlock, workflowEnv, inputs, secrets, {
10589
10201
  runner,
10590
- cliAgent: input.cliAgent,
10591
10202
  dryRun,
10592
10203
  continueOnError,
10593
10204
  progress,
@@ -10614,7 +10225,6 @@ var RunWorkflowService = class {
10614
10225
  this.logger.info(` ${"─".repeat(50)}`);
10615
10226
  if (!await this.worktreeService.runHook(workflow.worktree.afterCompleted, originalDir, workflowEnv, inputs, secrets, {
10616
10227
  runner,
10617
- cliAgent: input.cliAgent,
10618
10228
  dryRun,
10619
10229
  continueOnError
10620
10230
  })) {
@@ -11289,13 +10899,17 @@ var RecoverWorkflowService = class {
11289
10899
  if (!recoveredJob) throw new Error(`Workflow run "${record.workspace}/${record.runKey}" does not include a recoverable failed job`);
11290
10900
  if (record.worktreePath && !await (0, _agimon_ai_po_core_platform.pathExists)(this.runtime.fs, record.worktreePath, this.runtime.ioContext)) throw new Error(`Recoverable worktree not found: ${record.worktreePath}`);
11291
10901
  const runner = input.runner ?? record.runner ?? record.cliAgent;
11292
- const cliAgent = runner === record.cliAgent ? record.cliAgent : void 0;
10902
+ if ([runner, record.command].some((value) => value !== void 0 && [
10903
+ "claude",
10904
+ "claude-code",
10905
+ "codex",
10906
+ "antigravity"
10907
+ ].includes(value))) throw new Error("Retired workflow execution cannot be replayed. Select a supported runner explicitly.");
11293
10908
  const originalJob = fixRestartFrom && !activeRepair ? void 0 : record.job;
11294
10909
  if (!this.parser.resolveJobOrder(workflow.jobs, originalJob ?? null).includes(recoveredJob)) throw new Error(`Workflow run "${record.workspace}/${record.runKey}" recovery target "${recoveredJob}" is not in the workflow job order`);
11295
10910
  const ownerSessionId = claimedOwnerSessionId?.trim();
11296
10911
  const envOverrides = ownerSessionId ? { [PI_SESSION_ENV]: ownerSessionId } : void 0;
11297
10912
  return await this.runner.run({
11298
- cliAgent,
11299
10913
  runner,
11300
10914
  command: record.command,
11301
10915
  choice: record.choice,
@@ -11352,12 +10966,6 @@ var RecoverWorkflowService = class {
11352
10966
  }
11353
10967
  };
11354
10968
  //#endregion
11355
- Object.defineProperty(exports, "CodexQuotaService", {
11356
- enumerable: true,
11357
- get: function() {
11358
- return CodexQuotaService;
11359
- }
11360
- });
11361
10969
  Object.defineProperty(exports, "NativeTerminalService", {
11362
10970
  enumerable: true,
11363
10971
  get: function() {
@@ -11448,12 +11056,6 @@ Object.defineProperty(exports, "diagnoseWorkflows", {
11448
11056
  return diagnoseWorkflows;
11449
11057
  }
11450
11058
  });
11451
- Object.defineProperty(exports, "formatArtifactWarning", {
11452
- enumerable: true,
11453
- get: function() {
11454
- return formatArtifactWarning;
11455
- }
11456
- });
11457
11059
  Object.defineProperty(exports, "gateStepDecision", {
11458
11060
  enumerable: true,
11459
11061
  get: function() {
@@ -11545,4 +11147,4 @@ Object.defineProperty(exports, "workflowShellOutput", {
11545
11147
  }
11546
11148
  });
11547
11149
 
11548
- //# sourceMappingURL=RecoverWorkflowService-CbyTPDY-.cjs.map
11150
+ //# sourceMappingURL=RecoverWorkflowService-CEYR10KF.cjs.map