@agimon-ai/po-workflow 0.0.0-alpha.30 → 0.0.0-alpha.31

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,9 +1,9 @@
1
+ import { i as substituteShellPlaceholder, n as workflowCommandTemplateVariables, r as escapeShellArg, t as renderWorkflowCommandTemplate } from "./workflowCommandTemplate-r57z3b46.mjs";
1
2
  import { createRequire } from "node:module";
2
3
  import { BACKGROUND_CONTEXT, createSerialRunner, getOrThrow, nodeHost, pathExists, removePath, writeFileAtomic } from "@agimon-ai/po-core/platform";
3
4
  import { z } from "zod";
4
5
  import path, { basename, dirname, extname, join, relative, resolve } from "node:path";
5
6
  import { dump, load } from "js-yaml";
6
- import { Liquid } from "liquidjs";
7
7
  import { execFileSync, spawn } from "node:child_process";
8
8
  import fs, { constants, mkdirSync, rmSync } from "node:fs";
9
9
  import { chmod, link, mkdir, open, writeFile } from "node:fs/promises";
@@ -863,65 +863,6 @@ async function workflowShellOutput(runtime, command, options = {}) {
863
863
  return output;
864
864
  }
865
865
  //#endregion
866
- //#region src/services/workflowShell/index.ts
867
- /**
868
- * Shell-quoting helpers for safely interpolating values into shell command strings.
869
- *
870
- * DESIGN PATTERNS:
871
- * - Pure functions with no side effects
872
- * - Context-aware escaping driven by the surrounding quote character
873
- *
874
- * AVOID:
875
- * - String.prototype.replace with a value as the replacement string: its replacement
876
- * patterns ($&, $1, $$, ...) would corrupt any value containing `$`. Build the result
877
- * with slice/concat or a function replacer instead.
878
- */
879
- /**
880
- * Escape a string for safe use as a single-quoted shell argument.
881
- *
882
- * Wraps the value in single quotes and neutralises embedded single quotes via the
883
- * quote-break-escape-requote pattern (`'\''`).
884
- */
885
- function escapeShellArg(value) {
886
- return `'${value.replace(/'/g, "'\\''")}'`;
887
- }
888
- /**
889
- * Escape a value for safe insertion inside a double-quoted shell string (`"..."`).
890
- *
891
- * Inside double quotes only `\`, `$`, `` ` `` and `"` retain special meaning, so each is
892
- * backslash-escaped in a single pass. A function replacer is used so a `$` in the value is
893
- * never interpreted as a replacement pattern.
894
- */
895
- function escapeForDoubleQuotes(value) {
896
- return value.replace(/[\\$`"]/g, (char) => `\\${char}`);
897
- }
898
- /**
899
- * Replace every occurrence of `placeholder` in `template` with `value`, escaping the value
900
- * for the shell-quoting context of the character immediately preceding the placeholder:
901
- *
902
- * - preceded by `"` -> escape for a double-quoted slot (`\ $ ` ` " `)
903
- * - preceded by `'` -> escape embedded single quotes (the template supplies the surrounding quotes)
904
- * - otherwise (bare) -> wrap the value as a single safe single-quoted token
905
- *
906
- * The result is assembled with slice/concat so `value` is never treated as a
907
- * String.prototype.replace replacement pattern.
908
- */
909
- function substituteShellPlaceholder(template, placeholder, value) {
910
- let result = "";
911
- let searchFrom = 0;
912
- for (;;) {
913
- const index = template.indexOf(placeholder, searchFrom);
914
- if (index === -1) return result + template.slice(searchFrom);
915
- result += template.slice(searchFrom, index) + escapeForPrecedingQuote(value, template[index - 1]);
916
- searchFrom = index + placeholder.length;
917
- }
918
- }
919
- function escapeForPrecedingQuote(value, precedingChar) {
920
- if (precedingChar === "\"") return escapeForDoubleQuotes(value);
921
- if (precedingChar === "'") return value.replace(/'/g, "'\\''");
922
- return escapeShellArg(value);
923
- }
924
- //#endregion
925
866
  //#region src/services/WorkflowParserService/index.ts
926
867
  /**
927
868
  * WorkflowParserService
@@ -947,17 +888,6 @@ const CHOICE_SETTING_KEYS = new Set(Object.keys(ChoiceSettingsSchema.shape));
947
888
  /** A prompt printed raw would be split and expanded by the shell, so templates must quote it. */
948
889
  const UNQUOTED_PROMPT_PATTERN = /\{\{-?\s*(prompt|systemPrompt)\s*-?\}\}/;
949
890
  const LEGACY_INTERPOLATION_MARKER = "${{";
950
- /**
951
- * Renders command templates. Strict, so a variable a launch does not provide
952
- * fails the step instead of rendering an empty flag; lenient in `if` and
953
- * `default`, so optional values such as the system prompt can be tested.
954
- */
955
- const commandTemplates = new Liquid({
956
- strictVariables: true,
957
- strictFilters: true,
958
- lenientIf: true
959
- });
960
- commandTemplates.registerFilter("shell", (value) => escapeShellArg(Array.isArray(value) ? value.join(",") : String(value ?? "")));
961
891
  /** A declared command's template and host options, whichever form it was written in. */
962
892
  function commandTemplateOf(command) {
963
893
  return typeof command === "string" ? {
@@ -1079,6 +1009,22 @@ var WorkflowParserService = class {
1079
1009
  return parsed;
1080
1010
  }
1081
1011
  /**
1012
+ * Read and import-merge a partial workflow definition without concrete schema
1013
+ * validation or extends resolution. This is intentionally for inspection only.
1014
+ */
1015
+ async parseWorkflowTemplateFile(workflowPath) {
1016
+ const resolved = resolve(this.runtime.cwd, workflowPath);
1017
+ if (!await pathExists(this.runtime.fs, resolved, this.runtime.ioContext)) throw new Error(`Workflow file not found: ${resolved}`);
1018
+ const content = getOrThrow(await this.runtime.fs.readTextFile(resolved, this.runtime.ioContext));
1019
+ const parsed = load(content);
1020
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error(`Workflow template must be a YAML object: ${resolved}`);
1021
+ const workflow = parsed;
1022
+ workflow.jobs ??= {};
1023
+ if (workflow.imports) await this.resolveImports(workflow, resolved);
1024
+ workflow.jobs ??= {};
1025
+ return workflow;
1026
+ }
1027
+ /**
1082
1028
  * Render a command template into the shell command a step runs.
1083
1029
  *
1084
1030
  * Values enter as data and are never rendered again, so `${{ }}` text a
@@ -1086,15 +1032,15 @@ var WorkflowParserService = class {
1086
1032
  * is. Use the `shell` filter to quote a value as one shell word.
1087
1033
  */
1088
1034
  renderCommandTemplate(template, values) {
1089
- return commandTemplates.parseAndRenderSync(template, values).trim();
1035
+ return renderWorkflowCommandTemplate(template, values);
1090
1036
  }
1091
1037
  /** The top-level values a command template reads. */
1092
1038
  templateVariables(template) {
1093
- return commandTemplates.globalVariablesSync(template);
1039
+ return workflowCommandTemplateVariables(template);
1094
1040
  }
1095
1041
  /** Whether a template passes the system prompt itself; when not, it is folded into the prompt. */
1096
1042
  templateUsesSystemPrompt(template) {
1097
- return commandTemplates.globalVariablesSync(template).includes(SYSTEM_PROMPT_VARIABLE);
1043
+ return workflowCommandTemplateVariables(template).includes(SYSTEM_PROMPT_VARIABLE);
1098
1044
  }
1099
1045
  /**
1100
1046
  * Check what the schema cannot see once imports and templates are merged:
@@ -1112,9 +1058,9 @@ var WorkflowParserService = class {
1112
1058
  if (run.includes(LEGACY_INTERPOLATION_MARKER)) problems.push(`Command "${name}" uses \${{ }}; command templates are Liquid, use {{ }} instead.`);
1113
1059
  if (UNQUOTED_PROMPT_PATTERN.test(run)) problems.push(`Command "${name}" prints a prompt unquoted; write {{ prompt | shell }}.`);
1114
1060
  try {
1115
- if (!commandTemplates.globalVariablesSync(run).includes(PROMPT_VARIABLE)) problems.push(`Command "${name}" never passes {{ prompt | shell }} to the agent.`);
1061
+ if (!workflowCommandTemplateVariables(run).includes(PROMPT_VARIABLE)) problems.push(`Command "${name}" never passes {{ prompt | shell }} to the agent.`);
1116
1062
  } catch (error) {
1117
- problems.push(`Command "${name}" is not a valid Liquid template: ${error.message}`);
1063
+ problems.push(`Command "${name}" is not a valid Liquid template: ${error instanceof Error ? error.message : String(error)}`);
1118
1064
  }
1119
1065
  }
1120
1066
  for (const [name, choice] of Object.entries(choices)) for (const key of Object.keys(choice)) if (!CHOICE_SETTING_KEYS.has(key) && !(key in commands)) problems.push(`Choice "${name}" overrides "${key}", which is not a declared command.`);
@@ -9861,7 +9807,8 @@ var RunWorkflowService = class {
9861
9807
  const innerCommand = await this.createLaunchScriptCommand(input, workflowPath, workflow);
9862
9808
  const launchBaseName = input.name || workflow.name || basename(workflowPath);
9863
9809
  const launchDisplayName = input.name ? launchBaseName : `${launchBaseName}-${this.parser.generateHumanReadableId()}`;
9864
- const shell = substituteShellPlaceholder(substituteShellPlaceholder(launchCommand, LAUNCH_NAME_PLACEHOLDER, launchDisplayName), LAUNCH_COMMAND_PLACEHOLDER, innerCommand);
9810
+ const namedLaunchCommand = substituteShellPlaceholder(launchCommand, LAUNCH_NAME_PLACEHOLDER, launchDisplayName);
9811
+ const shell = substituteShellPlaceholder(namedLaunchCommand, LAUNCH_COMMAND_PLACEHOLDER, innerCommand);
9865
9812
  this.logger.info(`${DIM}Delegating via launch-command: ${shell}${RESET}`);
9866
9813
  delegated = true;
9867
9814
  const launched = await this.spawnLaunchCommand(shell, {
@@ -10873,9 +10820,10 @@ var RunWorkflowService = class {
10873
10820
  * adding --skip-launch to prevent infinite recursion.
10874
10821
  */
10875
10822
  buildLaunchCliCommand(input, workflowPath, workflow) {
10823
+ const cliPath = this.resolveCliPath();
10876
10824
  const parts = [
10877
10825
  "node",
10878
- escapeShellArg(this.resolveCliPath()),
10826
+ escapeShellArg(cliPath),
10879
10827
  "run-workflow",
10880
10828
  escapeShellArg(workflowPath),
10881
10829
  "--skip-launch"
@@ -11260,6 +11208,6 @@ var RecoverWorkflowService = class {
11260
11208
  }
11261
11209
  };
11262
11210
  //#endregion
11263
- export { workflowShellOutput as A, readWorkflowPackageVersion as C, WorkflowParserService as D, diagnoseWorkflows as E, summarizeWorkflow as M, listWorkflows as N, escapeShellArg as O, createWorkflowHost as S, diagnoseWorkflow as T, RunDirectoryService as _, WorkflowRegistryService as a, serveNativeTerminal as b, summarizeWorkflowProgress as c, WORKFLOW_DECISION_STEERING_ENV as d, WORKFLOW_DECISION_STEERING_HOST as f, recordStepDecision as g, readStepDecision as h, CodexQuotaService as i, readWorkflowCatalog as j, createWorkflowRuntime as k, workflowRunPhase as l, gateStepDecision as m, RunWorkflowService as n, readWorkflowProgress as o, formatArtifactWarning as p, createEmbeddedRunWorkflowService as r, readWorkflowProgressFrom as s, RecoverWorkflowService as t, WORKFLOW_DECISION_FILE_ENV as u, NativeTerminalService as v, resolveWorkflowCliPath as w, terminalSocketPath as x, connectNativeTerminal as y };
11211
+ export { readWorkflowCatalog as A, readWorkflowPackageVersion as C, WorkflowParserService as D, diagnoseWorkflows as E, listWorkflows as M, createWorkflowRuntime as O, createWorkflowHost as S, diagnoseWorkflow as T, RunDirectoryService as _, WorkflowRegistryService as a, serveNativeTerminal as b, summarizeWorkflowProgress as c, WORKFLOW_DECISION_STEERING_ENV as d, WORKFLOW_DECISION_STEERING_HOST as f, recordStepDecision as g, readStepDecision as h, CodexQuotaService as i, summarizeWorkflow as j, workflowShellOutput as k, workflowRunPhase as l, gateStepDecision as m, RunWorkflowService as n, readWorkflowProgress as o, formatArtifactWarning as p, createEmbeddedRunWorkflowService as r, readWorkflowProgressFrom as s, RecoverWorkflowService as t, WORKFLOW_DECISION_FILE_ENV as u, NativeTerminalService as v, resolveWorkflowCliPath as w, terminalSocketPath as x, connectNativeTerminal as y };
11264
11212
 
11265
- //# sourceMappingURL=RecoverWorkflowService-Xo-OZAJ4.mjs.map
11213
+ //# sourceMappingURL=RecoverWorkflowService-CYXGatEx.mjs.map