@runtypelabs/cli 2.22.8 → 2.22.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +421 -25
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -15181,7 +15181,7 @@ var edgeContextPayloadSchema = external_exports.object({
15181
15181
  exp: external_exports.number().int().positive()
15182
15182
  });
15183
15183
 
15184
- // ../shared/dist/chunk-KR4LFVFE.mjs
15184
+ // ../shared/dist/chunk-3FPSMWBQ.mjs
15185
15185
  function getNestedValue(obj, path18) {
15186
15186
  let normalizedPath = path18;
15187
15187
  normalizedPath = normalizedPath.replace(/^\$\.?/, "");
@@ -15566,7 +15566,7 @@ function resolveFallback(parsed, context, tracking) {
15566
15566
  }
15567
15567
  var templateEngine = new SimpleTemplateEngine();
15568
15568
 
15569
- // ../shared/dist/chunk-6RCUU75J.mjs
15569
+ // ../shared/dist/chunk-MMDRPM6Q.mjs
15570
15570
  var tokensSchema = external_exports.object({ input: external_exports.number(), output: external_exports.number() });
15571
15571
  var wireStopReasonSchema = external_exports.enum([
15572
15572
  "end_turn",
@@ -15865,6 +15865,10 @@ var unifiedToolCompleteEventSchema = external_exports.object({
15865
15865
  iteration: external_exports.number().optional(),
15866
15866
  stepId: external_exports.string().optional()
15867
15867
  });
15868
+ var unifiedSubagentAttributionSchema = external_exports.object({
15869
+ toolName: external_exports.string(),
15870
+ agentName: external_exports.string().optional()
15871
+ });
15868
15872
  var unifiedApprovalStartEventSchema = external_exports.object({
15869
15873
  ...unifiedBase,
15870
15874
  type: external_exports.literal("approval_start"),
@@ -15878,7 +15882,10 @@ var unifiedApprovalStartEventSchema = external_exports.object({
15878
15882
  parameters: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
15879
15883
  timeout: external_exports.number().optional(),
15880
15884
  startedAt: external_exports.string().optional(),
15881
- iteration: external_exports.number().optional()
15885
+ iteration: external_exports.number().optional(),
15886
+ // Present when the approval originated inside a subagent's execution.
15887
+ // Attribution only — never a control signal.
15888
+ subagent: unifiedSubagentAttributionSchema.optional()
15882
15889
  });
15883
15890
  var unifiedApprovalCompleteEventSchema = external_exports.object({
15884
15891
  ...unifiedBase,
@@ -16015,6 +16022,10 @@ var externalAgentContextSchema = external_exports.object({
16015
16022
  contextId: external_exports.string().optional(),
16016
16023
  taskId: external_exports.string().optional()
16017
16024
  });
16025
+ var subagentAttributionSchema = external_exports.object({
16026
+ toolName: external_exports.string(),
16027
+ agentName: external_exports.string().optional()
16028
+ });
16018
16029
  var tokensSchema2 = external_exports.object({ input: external_exports.number(), output: external_exports.number() });
16019
16030
  var wireStopReasonSchema2 = external_exports.enum([
16020
16031
  "end_turn",
@@ -16166,7 +16177,11 @@ var agentApprovalStartEventSchema = external_exports.object({
16166
16177
  parameters: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
16167
16178
  timeout: external_exports.number(),
16168
16179
  startedAt: external_exports.string(),
16169
- externalAgent: externalAgentContextSchema.optional()
16180
+ externalAgent: externalAgentContextSchema.optional(),
16181
+ // Present when the approval originated inside a subagent's execution (a
16182
+ // child agent's tool required approval). Attribution only — see
16183
+ // {@link subagentAttributionSchema}.
16184
+ subagent: subagentAttributionSchema.optional()
16170
16185
  });
16171
16186
  var agentApprovalCompleteEventSchema = external_exports.object({
16172
16187
  ...baseAgentEvent,
@@ -16677,7 +16692,8 @@ var AGENT_CONTENT_CONFIG_KEYS = {
16677
16692
  artifacts: true,
16678
16693
  loggingPolicy: true,
16679
16694
  temporal: true,
16680
- memory: true
16695
+ memory: true,
16696
+ sandbox: true
16681
16697
  };
16682
16698
  var AGENT_CONTENT_CONFIG_KEY_LIST = Object.keys(AGENT_CONTENT_CONFIG_KEYS).sort();
16683
16699
  var configurationStatusSchema = external_exports.enum([
@@ -17068,7 +17084,13 @@ var setVariableConfigSchema = external_exports.object({
17068
17084
  // rejecting it. Required so nested set-variable steps validate when the
17069
17085
  // recursive conditional union lands (see
17070
17086
  // `docs/features/planning/2026-06-04-conditional-nested-step-strict-validation.md`).
17071
- value: external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean(), external_exports.null(), external_exports.record(external_exports.string(), external_exports.unknown())]),
17087
+ value: external_exports.union([
17088
+ external_exports.string(),
17089
+ external_exports.number(),
17090
+ external_exports.boolean(),
17091
+ external_exports.null(),
17092
+ external_exports.record(external_exports.string(), external_exports.unknown())
17093
+ ]),
17072
17094
  valueTemplate: external_exports.string().optional()
17073
17095
  });
17074
17096
  var sendStreamConfigSchema = external_exports.object({
@@ -17704,10 +17726,63 @@ var promptConfigSchema = external_exports.object({
17704
17726
  mode: external_exports.string().optional()
17705
17727
  // UI mode (task, agent, etc.)
17706
17728
  });
17729
+ var conditionalBranchSchema = external_exports.object({
17730
+ /** Stable identifier (unique within the conditional). */
17731
+ id: external_exports.string().min(1, "Branch id is required"),
17732
+ /** Display name ("High priority", "POST", ...). */
17733
+ name: external_exports.string().optional(),
17734
+ /** JS expression; template `{{var}}` references resolve first. */
17735
+ condition: external_exports.string().min(1, "Branch condition is required"),
17736
+ steps: external_exports.array(external_exports.lazy(() => contextStepSchema))
17737
+ });
17707
17738
  var conditionalConfigSchema = external_exports.object({
17708
- condition: external_exports.string().min(1, "Condition is required"),
17709
- trueSteps: external_exports.array(external_exports.lazy(() => contextStepSchema)),
17710
- falseSteps: external_exports.array(external_exports.lazy(() => contextStepSchema)).optional()
17739
+ /** Legacy binary shape. Required unless `branches` is provided. */
17740
+ condition: external_exports.string().min(1, "Condition is required").optional(),
17741
+ trueSteps: external_exports.array(external_exports.lazy(() => contextStepSchema)).optional(),
17742
+ falseSteps: external_exports.array(external_exports.lazy(() => contextStepSchema)).optional(),
17743
+ /**
17744
+ * N-way named branches, evaluated in order with first-match-wins. When
17745
+ * present (non-empty), this takes precedence over the legacy
17746
+ * `condition`/`trueSteps`/`falseSteps` shape.
17747
+ */
17748
+ branches: external_exports.array(conditionalBranchSchema).optional(),
17749
+ /** Steps to run when no branch condition matches (the pinned "Otherwise"). */
17750
+ otherwiseSteps: external_exports.array(external_exports.lazy(() => contextStepSchema)).optional(),
17751
+ /**
17752
+ * Optional unified branch output. After the taken branch runs, this variable
17753
+ * is bound to the value of the branch's LAST enabled, explicitly-named,
17754
+ * value-producing step (walking back past disabled / unnamed / `when`-skipped
17755
+ * steps). Left absent if the taken branch produced no named output. Lets
17756
+ * divergent branches surface a single result under one name.
17757
+ * (This is an SSA φ-node — it merges the value out of whichever branch ran.)
17758
+ */
17759
+ outputVariable: external_exports.string().optional()
17760
+ }).superRefine((config3, ctx) => {
17761
+ const hasBranches = Array.isArray(config3.branches) && config3.branches.length > 0;
17762
+ if (!hasBranches) {
17763
+ if (typeof config3.condition !== "string" || config3.condition.length === 0) {
17764
+ ctx.addIssue({ code: "custom", path: ["condition"], message: "Condition is required" });
17765
+ }
17766
+ if (!Array.isArray(config3.trueSteps)) {
17767
+ ctx.addIssue({
17768
+ code: "custom",
17769
+ path: ["trueSteps"],
17770
+ message: "trueSteps is required unless branches is provided"
17771
+ });
17772
+ }
17773
+ return;
17774
+ }
17775
+ const seen = /* @__PURE__ */ new Set();
17776
+ config3.branches.forEach((branch, index) => {
17777
+ if (seen.has(branch.id)) {
17778
+ ctx.addIssue({
17779
+ code: "custom",
17780
+ path: ["branches", index, "id"],
17781
+ message: `Duplicate branch id "${branch.id}"`
17782
+ });
17783
+ }
17784
+ seen.add(branch.id);
17785
+ });
17711
17786
  });
17712
17787
  var saveMemoryConfigSchema = external_exports.object({
17713
17788
  profileTemplate: external_exports.string().min(1, "Profile template is required"),
@@ -18362,7 +18437,8 @@ function normalizeCrawlConfig(config3) {
18362
18437
  if (maxAgeRaw !== void 0 && maxAgeRaw !== null) validateNumber(maxAgeRaw, "maxAge", "crawl");
18363
18438
  if (modifiedSince !== void 0) validateString(modifiedSince, "modifiedSince", "crawl");
18364
18439
  if (config3.options !== void 0) validateObject(config3.options, "options", "crawl");
18365
- if (config3.authenticate !== void 0) validateObject(config3.authenticate, "authenticate", "crawl");
18440
+ if (config3.authenticate !== void 0)
18441
+ validateObject(config3.authenticate, "authenticate", "crawl");
18366
18442
  if (config3.cookies !== void 0) validateArray(config3.cookies, "cookies", "crawl");
18367
18443
  if (setExtraHTTPHeaders !== void 0) {
18368
18444
  validateObject(setExtraHTTPHeaders, "setExtraHTTPHeaders", "crawl");
@@ -18385,7 +18461,8 @@ function normalizeCrawlConfig(config3) {
18385
18461
  }
18386
18462
  if (userAgent !== void 0) validateString(userAgent, "userAgent", "crawl");
18387
18463
  if (jsonOptions !== void 0) validateObject(jsonOptions, "jsonOptions", "crawl");
18388
- if (config3.streamOutput !== void 0) validateBoolean(config3.streamOutput, "streamOutput", "crawl");
18464
+ if (config3.streamOutput !== void 0)
18465
+ validateBoolean(config3.streamOutput, "streamOutput", "crawl");
18389
18466
  if (pollIntervalMsRaw !== void 0 && pollIntervalMsRaw !== null) {
18390
18467
  validateNumber(pollIntervalMsRaw, "pollIntervalMs", "crawl");
18391
18468
  }
@@ -18745,11 +18822,19 @@ function normalizeTemplateConfig(config3) {
18745
18822
  validateArray(config3.sampleData, "sampleData", "template");
18746
18823
  for (const [i, scenario] of config3.sampleData.entries()) {
18747
18824
  if (typeof scenario !== "object" || scenario === null || Array.isArray(scenario)) {
18748
- throw new NormalizationError(`sampleData[${i}] must be an object`, "template", `sampleData[${i}]`);
18825
+ throw new NormalizationError(
18826
+ `sampleData[${i}] must be an object`,
18827
+ "template",
18828
+ `sampleData[${i}]`
18829
+ );
18749
18830
  }
18750
18831
  validateString(scenario.name, `sampleData[${i}].name`, "template", true);
18751
18832
  if (typeof scenario.data !== "object" || scenario.data === null || Array.isArray(scenario.data)) {
18752
- throw new NormalizationError(`sampleData[${i}].data must be an object`, "template", `sampleData[${i}].data`);
18833
+ throw new NormalizationError(
18834
+ `sampleData[${i}].data must be an object`,
18835
+ "template",
18836
+ `sampleData[${i}].data`
18837
+ );
18753
18838
  }
18754
18839
  }
18755
18840
  }
@@ -18774,7 +18859,9 @@ function normalizeTemplateConfig(config3) {
18774
18859
  }
18775
18860
  function normalizeConditionalConfig(config3) {
18776
18861
  validateConfig(config3, "conditional");
18777
- validateString(config3.condition, "condition", "conditional", true);
18862
+ const rawBranches = config3.branches;
18863
+ const hasBranches = Array.isArray(rawBranches) && rawBranches.length > 0;
18864
+ validateString(config3.condition, "condition", "conditional", !hasBranches);
18778
18865
  const trueSteps = config3.trueSteps ?? config3.true_steps;
18779
18866
  const falseSteps = config3.falseSteps ?? config3.false_steps;
18780
18867
  if (trueSteps) {
@@ -18796,10 +18883,37 @@ function normalizeConditionalConfig(config3) {
18796
18883
  return normalizeContextStep(stepWithDefaults);
18797
18884
  });
18798
18885
  };
18886
+ let branches;
18887
+ if (hasBranches) {
18888
+ validateArray(rawBranches, "branches", "conditional");
18889
+ branches = rawBranches.map((branch, index) => {
18890
+ if (!branch || typeof branch !== "object") {
18891
+ throw new NormalizationError(
18892
+ `branches[${index}] must be an object`,
18893
+ "conditional",
18894
+ "branches"
18895
+ );
18896
+ }
18897
+ validateString(branch.condition, `branches[${index}].condition`, "conditional", true);
18898
+ const branchSteps = Array.isArray(branch.steps) ? branch.steps : [];
18899
+ return {
18900
+ id: typeof branch.id === "string" && branch.id.length > 0 ? branch.id : `branch-${index}`,
18901
+ ...typeof branch.name === "string" && branch.name.length > 0 ? { name: branch.name } : {},
18902
+ condition: branch.condition,
18903
+ steps: normalizeNestedSteps(branchSteps, `conditional-branch-${index}`)
18904
+ };
18905
+ });
18906
+ }
18907
+ const otherwiseSteps = Array.isArray(config3.otherwiseSteps) ? normalizeNestedSteps(config3.otherwiseSteps, "conditional-otherwise") : void 0;
18799
18908
  return {
18800
- condition: config3.condition,
18909
+ ...typeof config3.condition === "string" && config3.condition.length > 0 ? { condition: config3.condition } : {},
18801
18910
  trueSteps: trueSteps ? normalizeNestedSteps(trueSteps, "conditional-true") : [],
18802
- falseSteps: falseSteps ? normalizeNestedSteps(falseSteps, "conditional-false") : void 0
18911
+ falseSteps: falseSteps ? normalizeNestedSteps(falseSteps, "conditional-false") : void 0,
18912
+ ...branches ? { branches } : {},
18913
+ ...otherwiseSteps ? { otherwiseSteps } : {},
18914
+ // Preserve the optional unified branch-output binding through normalization —
18915
+ // the manual rebuild above would otherwise drop it (not condition/branches).
18916
+ ...typeof config3.outputVariable === "string" && config3.outputVariable.length > 0 ? { outputVariable: config3.outputVariable } : {}
18803
18917
  };
18804
18918
  }
18805
18919
  function normalizeSetVariableConfig(config3) {
@@ -19915,8 +20029,18 @@ function conditionalNestingDepth(config3) {
19915
20029
  if (depth > MAX_CONDITIONAL_NESTING_DEPTH) break;
19916
20030
  if (!node || typeof node !== "object") continue;
19917
20031
  const cfg = node;
19918
- for (const key of ["trueSteps", "falseSteps", "true_steps", "false_steps"]) {
19919
- const branch = cfg[key];
20032
+ const branchArrays = [];
20033
+ for (const key of ["trueSteps", "falseSteps", "true_steps", "false_steps", "otherwiseSteps"]) {
20034
+ branchArrays.push(cfg[key]);
20035
+ }
20036
+ if (Array.isArray(cfg.branches)) {
20037
+ for (const branch of cfg.branches) {
20038
+ if (branch && typeof branch === "object") {
20039
+ branchArrays.push(branch.steps);
20040
+ }
20041
+ }
20042
+ }
20043
+ for (const branch of branchArrays) {
19920
20044
  if (!Array.isArray(branch)) continue;
19921
20045
  for (const s of branch) {
19922
20046
  if (s && typeof s === "object" && s.type === "conditional") {
@@ -20040,6 +20164,15 @@ function collectCodeModeToolNameCheck(toolsConfig, stepIndex, stepRef, pendingCh
20040
20164
  }
20041
20165
  var SINGLE_BRACE_VARIABLE_PATTERN = /(?<!\{)\{([a-zA-Z_][a-zA-Z0-9_.]*)\}(?!\})/g;
20042
20166
  var DOUBLE_BRACE_VARIABLE_PATTERN = TEMPLATE_EXPRESSION_PATTERN;
20167
+ var STRING_LITERAL_OPERAND = /(?:'[^']*'|"[^"]*"|`[^`]*`)/.source;
20168
+ var EQUALITY_OPERATOR = /(?:===|!==|==|!=)/.source;
20169
+ var UNQUOTED_TEMPLATE = /(?<!['"`])\{\{[^{}]+\}\}(?!['"`])/.source;
20170
+ var UNQUOTED_TEMPLATE_BEFORE_OP = new RegExp(
20171
+ `${UNQUOTED_TEMPLATE}\\s*${EQUALITY_OPERATOR}\\s*${STRING_LITERAL_OPERAND}`
20172
+ );
20173
+ var UNQUOTED_TEMPLATE_AFTER_OP = new RegExp(
20174
+ `${STRING_LITERAL_OPERAND}\\s*${EQUALITY_OPERATOR}\\s*${UNQUOTED_TEMPLATE}`
20175
+ );
20043
20176
  var TEMPLATE_STRING_FIELDS = /* @__PURE__ */ new Set([
20044
20177
  "text",
20045
20178
  "userPrompt",
@@ -20270,6 +20403,82 @@ function validateUpsertRecordSourceShape(flowSteps, buckets) {
20270
20403
  }
20271
20404
  }
20272
20405
  }
20406
+ function checkConditionExpression(expr, path18, stepRef, buckets) {
20407
+ if (typeof expr !== "string" || !expr.includes("{{")) return;
20408
+ const match = UNQUOTED_TEMPLATE_BEFORE_OP.exec(expr) || UNQUOTED_TEMPLATE_AFTER_OP.exec(expr);
20409
+ if (!match) return;
20410
+ const snippet = match[0].trim();
20411
+ addIssue(
20412
+ "warning",
20413
+ {
20414
+ code: "CONDITION_UNQUOTED_TEMPLATE_COMPARISON",
20415
+ message: `Expression compares an unquoted {{...}} placeholder against a string literal (\`${snippet}\`). \`condition\` / \`when\` predicates are JavaScript evaluated after template substitution, so a non-numeric value substitutes in as a bare identifier (e.g. \`healthy === 'watch'\`) and throws "ReferenceError: <value> is not defined" at runtime. Quote the placeholder \u2014 e.g. '{{var}}' === '...' \u2014 or compare numerically.`,
20416
+ path: path18,
20417
+ step: stepRef,
20418
+ details: { snippet }
20419
+ },
20420
+ buckets
20421
+ );
20422
+ }
20423
+ var CONDITIONAL_BRANCH_STEP_KEYS = [
20424
+ "trueSteps",
20425
+ "falseSteps",
20426
+ "true_steps",
20427
+ "false_steps",
20428
+ "otherwiseSteps"
20429
+ ];
20430
+ function walkStepConditionExpressions(node, basePath, stepRef, buckets, depth) {
20431
+ if (!isObjectRecord(node)) return;
20432
+ if (node.enabled === false) return;
20433
+ checkConditionExpression(node.when, `${basePath}.when`, stepRef, buckets);
20434
+ if (node.type !== "conditional" || !isObjectRecord(node.config)) return;
20435
+ const config3 = node.config;
20436
+ checkConditionExpression(config3.condition, `${basePath}.config.condition`, stepRef, buckets);
20437
+ if (depth >= MAX_CONDITIONAL_NESTING_DEPTH) return;
20438
+ if (Array.isArray(config3.branches)) {
20439
+ config3.branches.forEach((branch, branchIndex) => {
20440
+ if (!isObjectRecord(branch)) return;
20441
+ checkConditionExpression(
20442
+ branch.condition,
20443
+ `${basePath}.config.branches[${branchIndex}].condition`,
20444
+ stepRef,
20445
+ buckets
20446
+ );
20447
+ if (Array.isArray(branch.steps)) {
20448
+ branch.steps.forEach(
20449
+ (nested, nestedIndex) => walkStepConditionExpressions(
20450
+ nested,
20451
+ `${basePath}.config.branches[${branchIndex}].steps[${nestedIndex}]`,
20452
+ stepRef,
20453
+ buckets,
20454
+ depth + 1
20455
+ )
20456
+ );
20457
+ }
20458
+ });
20459
+ }
20460
+ for (const key of CONDITIONAL_BRANCH_STEP_KEYS) {
20461
+ const arr = config3[key];
20462
+ if (!Array.isArray(arr)) continue;
20463
+ arr.forEach(
20464
+ (nested, nestedIndex) => walkStepConditionExpressions(
20465
+ nested,
20466
+ `${basePath}.config.${key}[${nestedIndex}]`,
20467
+ stepRef,
20468
+ buckets,
20469
+ depth + 1
20470
+ )
20471
+ );
20472
+ }
20473
+ }
20474
+ function validateConditionExpressions(flowSteps, buckets, conditionalStepsExceedingDepth) {
20475
+ for (const [stepIndex, step] of flowSteps.entries()) {
20476
+ if (step.enabled === false) continue;
20477
+ if (conditionalStepsExceedingDepth.has(stepIndex)) continue;
20478
+ const stepRef = { index: stepIndex, name: step.name, type: step.type };
20479
+ walkStepConditionExpressions(step, `flowSteps[${stepIndex}]`, stepRef, buckets, 1);
20480
+ }
20481
+ }
20273
20482
  function collectAccountScopedReferences(step, stepIndex, pendingChecks) {
20274
20483
  const stepRef = {
20275
20484
  index: stepIndex,
@@ -20851,6 +21060,7 @@ function collectFlowStructureIssues(flowData, deps, buckets) {
20851
21060
  deps.declaredFlowInputs
20852
21061
  );
20853
21062
  validateUpsertRecordSourceShape(flowData.flowSteps, buckets);
21063
+ validateConditionExpressions(flowData.flowSteps, buckets, conditionalStepsExceedingDepth);
20854
21064
  return { pendingChecks };
20855
21065
  }
20856
21066
  function validateFlowStructure(flowData, deps = {}) {
@@ -20965,7 +21175,7 @@ const helpers = (function createHelpers() {
20965
21175
 
20966
21176
  extractURLs: (text) => {
20967
21177
  if (typeof text !== 'string') return []
20968
- const urlRegex = /https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)/g
21178
+ const urlRegex = /https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&/=]*)/g
20969
21179
  const matches = text.match(urlRegex)
20970
21180
  return matches ? [...new Set(matches)] : []
20971
21181
  },
@@ -21152,6 +21362,13 @@ const helpers = (function createHelpers() {
21152
21362
  return str
21153
21363
  }
21154
21364
  },
21365
+
21366
+ coalesce: (...values) => {
21367
+ for (const value of values) {
21368
+ if (value !== null && value !== undefined) return value
21369
+ }
21370
+ return null
21371
+ },
21155
21372
  }
21156
21373
  })()
21157
21374
  `.trim();
@@ -32423,6 +32640,7 @@ var BuiltInToolGroup = {
32423
32640
  UCP_COMMERCE: "ucp_commerce",
32424
32641
  SANDBOX_USE: "sandbox_use",
32425
32642
  SANDBOX_SESSION: "sandbox_session",
32643
+ SANDBOX_AGENT: "sandbox_agent",
32426
32644
  TEMPORAL: "temporal"
32427
32645
  };
32428
32646
  var BROWSER_RUN_DOCUMENTATION_URL = "https://developers.cloudflare.com/browser-run/quick-actions/";
@@ -35521,6 +35739,150 @@ var CORE_BUILTIN_TOOLS_REGISTRY = [
35521
35739
  requiresApiKey: false,
35522
35740
  platformKeySupport: true
35523
35741
  },
35742
+ // -----------------------------------------------------------------------
35743
+ // Agent Sandbox tools — the implicit-computer surface.
35744
+ //
35745
+ // Injected (not catalog-selected) when an agent has `config.sandbox.enabled`,
35746
+ // so they are `hidden` from tool discovery. The agent believes it is already
35747
+ // inside a Linux machine: it runs `bash`, reads/edits files, and exposes
35748
+ // ports — it never provisions, names, or tears down infrastructure. The
35749
+ // machine is created lazily on the first call. See ADR 0010 and
35750
+ // `.planning/agent-sandbox-bash/PLAN.md`.
35751
+ // -----------------------------------------------------------------------
35752
+ {
35753
+ id: "bash",
35754
+ name: "Bash",
35755
+ description: "Run a shell command on your Linux computer (Node 22, Python 3.12, git, pnpm, uv preinstalled). Commands run in /workspace; files you write there stay available to later commands while you work on this task, but system-level changes outside /workspace may not. Combined stdout/stderr is returned. Long output is truncated (head + tail) with the full output spilled to a file. Pass slow_ok=true for commands that take a while (installs, builds, test suites).",
35756
+ category: BuiltInToolCategory.SANDBOX,
35757
+ toolGroup: BuiltInToolGroup.SANDBOX_AGENT,
35758
+ providers: [BuiltInToolProvider.MULTI],
35759
+ parametersSchema: {
35760
+ type: "object",
35761
+ properties: {
35762
+ command: {
35763
+ type: "string",
35764
+ description: "Shell command to execute (runs in bash, cwd is /workspace).",
35765
+ minLength: 1
35766
+ },
35767
+ slow_ok: {
35768
+ type: "boolean",
35769
+ description: "Allow a longer timeout for commands expected to take a while (installs, builds, tests). Defaults to false (short timeout)."
35770
+ }
35771
+ },
35772
+ required: ["command"]
35773
+ },
35774
+ executionHint: "platform",
35775
+ requiresApiKey: false,
35776
+ platformKeySupport: true,
35777
+ hidden: true
35778
+ },
35779
+ {
35780
+ id: "read_file",
35781
+ name: "Read File",
35782
+ description: "Read a file from your computer. Returns the file contents as a string.",
35783
+ category: BuiltInToolCategory.SANDBOX,
35784
+ toolGroup: BuiltInToolGroup.SANDBOX_AGENT,
35785
+ providers: [BuiltInToolProvider.MULTI],
35786
+ parametersSchema: {
35787
+ type: "object",
35788
+ properties: {
35789
+ path: {
35790
+ type: "string",
35791
+ description: "File path to read (relative paths resolve against /workspace).",
35792
+ minLength: 1
35793
+ }
35794
+ },
35795
+ required: ["path"]
35796
+ },
35797
+ executionHint: "platform",
35798
+ requiresApiKey: false,
35799
+ platformKeySupport: true,
35800
+ hidden: true
35801
+ },
35802
+ {
35803
+ id: "write_file",
35804
+ name: "Write File",
35805
+ description: "Write a file on your computer, creating parent directories as needed. Overwrites any existing file at the path. More reliable than shell heredocs for multi-line content.",
35806
+ category: BuiltInToolCategory.SANDBOX,
35807
+ toolGroup: BuiltInToolGroup.SANDBOX_AGENT,
35808
+ providers: [BuiltInToolProvider.MULTI],
35809
+ parametersSchema: {
35810
+ type: "object",
35811
+ properties: {
35812
+ path: {
35813
+ type: "string",
35814
+ description: "File path to write (relative paths resolve against /workspace).",
35815
+ minLength: 1
35816
+ },
35817
+ contents: {
35818
+ type: "string",
35819
+ description: "Full file contents to write."
35820
+ }
35821
+ },
35822
+ required: ["path", "contents"]
35823
+ },
35824
+ executionHint: "platform",
35825
+ requiresApiKey: false,
35826
+ platformKeySupport: true,
35827
+ hidden: true
35828
+ },
35829
+ {
35830
+ id: "edit_file",
35831
+ name: "Edit File",
35832
+ description: 'Replace an exact substring in a file with new text. The "old" text must appear exactly once in the file. Use this for surgical edits instead of rewriting the whole file.',
35833
+ category: BuiltInToolCategory.SANDBOX,
35834
+ toolGroup: BuiltInToolGroup.SANDBOX_AGENT,
35835
+ providers: [BuiltInToolProvider.MULTI],
35836
+ parametersSchema: {
35837
+ type: "object",
35838
+ properties: {
35839
+ path: {
35840
+ type: "string",
35841
+ description: "File path to edit (relative paths resolve against /workspace).",
35842
+ minLength: 1
35843
+ },
35844
+ old: {
35845
+ type: "string",
35846
+ description: "The exact text to find. Must occur exactly once in the file."
35847
+ },
35848
+ new: {
35849
+ type: "string",
35850
+ description: "The replacement text."
35851
+ }
35852
+ },
35853
+ required: ["path", "old", "new"]
35854
+ },
35855
+ executionHint: "platform",
35856
+ requiresApiKey: false,
35857
+ platformKeySupport: true,
35858
+ hidden: true
35859
+ },
35860
+ {
35861
+ id: "expose_port",
35862
+ name: "Expose Port",
35863
+ description: 'Get a public preview URL for a server you started on your computer. Start the server first (e.g. bash("node server.js &")), then expose its port.',
35864
+ category: BuiltInToolCategory.SANDBOX,
35865
+ toolGroup: BuiltInToolGroup.SANDBOX_AGENT,
35866
+ providers: [BuiltInToolProvider.MULTI],
35867
+ parametersSchema: {
35868
+ type: "object",
35869
+ properties: {
35870
+ port: {
35871
+ type: "number",
35872
+ description: "Port your server listens on (must not be 3000, which is reserved)."
35873
+ },
35874
+ name: {
35875
+ type: "string",
35876
+ description: "Optional label for the preview URL."
35877
+ }
35878
+ },
35879
+ required: ["port"]
35880
+ },
35881
+ executionHint: "platform",
35882
+ requiresApiKey: false,
35883
+ platformKeySupport: true,
35884
+ hidden: true
35885
+ },
35524
35886
  // Send email via Resend. Mirrors the send-email context step so agents can
35525
35887
  // dispatch transactional email without wrapping it in a flow.
35526
35888
  {
@@ -39849,6 +40211,25 @@ var memoryConfigSchema = external_exports.object({
39849
40211
  // Resolved via `shouldInjectMemorySummary` so the default lives in one place.
39850
40212
  injectSummary: external_exports.boolean().optional()
39851
40213
  });
40214
+ var sandboxNetworkAccessSchema = external_exports.union([
40215
+ external_exports.enum(["none", "essentials"]),
40216
+ external_exports.object({
40217
+ profile: external_exports.enum(["none", "essentials"]).optional(),
40218
+ allow: external_exports.array(external_exports.string()).optional()
40219
+ })
40220
+ ]);
40221
+ var sandboxConfigSchema = external_exports.object({
40222
+ enabled: external_exports.boolean(),
40223
+ provider: external_exports.enum(["runtype-sandbox", "daytona"]).optional(),
40224
+ persistence: external_exports.enum(["ephemeral", "conversation", "named"]).optional(),
40225
+ instanceType: external_exports.enum(["standard-1", "standard-2", "standard-3", "standard-4"]).optional(),
40226
+ networkAccess: sandboxNetworkAccessSchema.optional(),
40227
+ ttl: external_exports.enum(["5m", "1h", "24h", "unlimited"]).optional(),
40228
+ sleepAfter: external_exports.enum(["5m", "15m", "30m", "1h"]).optional(),
40229
+ // Opt-in approval gate on `bash`. Default false; wiring lands in Phase 3. The
40230
+ // approval decision is on tool name + params only — never the agent's reason.
40231
+ requireApprovalForBash: external_exports.boolean().optional()
40232
+ });
39852
40233
  var agentRuntimeConfigSchema = external_exports.object({
39853
40234
  model: external_exports.string().optional(),
39854
40235
  systemPrompt: external_exports.string().optional(),
@@ -39987,7 +40368,12 @@ var agentRuntimeConfigSchema = external_exports.object({
39987
40368
  // `memoryConfigSchema` (below) and reused by the update-agent, dispatch
39988
40369
  // inline-agent, and FPO agent schemas so the four surfaces never drift —
39989
40370
  // mirroring how `temporalConfigSchema` is shared.
39990
- memory: memoryConfigSchema.optional()
40371
+ memory: memoryConfigSchema.optional(),
40372
+ // Agent Sandbox (Linux computer). When enabled, the agent gets the sandbox
40373
+ // builtin tools + system-prompt frame at dispatch. Single-sourced as
40374
+ // `sandboxConfigSchema` (above), mirroring `memory`. The live machine is agent
40375
+ // state; this block is the operator Definition that enables it.
40376
+ sandbox: sandboxConfigSchema.optional()
39991
40377
  });
39992
40378
  function extractSecretReferences(template) {
39993
40379
  const keys = /* @__PURE__ */ new Set();
@@ -41546,10 +41932,10 @@ var FLOW_STEP_TYPE_METADATA = {
41546
41932
  configHints: "template (Liquid body), outputFormat, outputVariable, optional inputs map, optional partials, optional pdfOptions, optional asArtifact, optional streamOutput, optional sampleData"
41547
41933
  },
41548
41934
  conditional: {
41549
- description: "Branch the flow based on a JavaScript expression. Routes to trueSteps or falseSteps.",
41935
+ description: "Branch the flow on JavaScript expressions. Either the legacy binary shape (condition \u2192 trueSteps / falseSteps) or N-way named branches evaluated first-match-wins with an otherwise fallback. Set outputVariable to merge the taken branch into one named result.",
41550
41936
  category: "control-flow",
41551
41937
  isPrompt: false,
41552
- configHints: "condition (JS expression), trueSteps, falseSteps"
41938
+ configHints: "either { condition, trueSteps, falseSteps } or { branches: [{ id, name, condition, steps }], otherwiseSteps }, optional outputVariable"
41553
41939
  },
41554
41940
  "fetch-url": {
41555
41941
  description: "Make an HTTP request and capture the response.",
@@ -42256,6 +42642,11 @@ var SURFACE_TYPE_METADATA = {
42256
42642
  behaviorTypeRef: "runtype://types/surface-configs"
42257
42643
  }
42258
42644
  };
42645
+ var EMAIL_HTML_CAPABILITY_HINT = [
42646
+ "## Channel capabilities",
42647
+ '- Formatting: author the reply as an HTML email body. Write well-formed HTML and put all styling in inline `style="..."` attributes (no `<style>` blocks, no external CSS). Use semantic tags freely: `<p>`, `<h1>`-`<h3>`, `<ul>`/`<ol>`/`<li>`, `<table>`, `<a>`, `<strong>`/`<em>`, `<blockquote>`, `<img>`. Do NOT emit `<script>`, `<iframe>`, `<head>`, `<body>`, or `<html>` wrappers: Runtype wraps your body in the email document and strips any active or unsafe content before sending.',
42648
+ '- Images: embed an image with `<img src="https://..." alt="...">` and it renders inline in the email. (Some clients ask the recipient to load remote images.)'
42649
+ ].join("\n");
42259
42650
  var SURFACE_TYPE_GUIDE = (() => {
42260
42651
  const lines = Object.entries(SURFACE_TYPE_METADATA).map(([type, info]) => {
42261
42652
  return `- **${type}**: ${info.description}`;
@@ -43213,7 +43604,12 @@ var AgentInputSchema = external_exports.object({
43213
43604
  model: external_exports.string(),
43214
43605
  systemPrompt: external_exports.string().optional()
43215
43606
  }).optional().nullable(),
43216
- memory: memoryConfigSchema.optional()
43607
+ memory: memoryConfigSchema.optional(),
43608
+ // Agent Sandbox (Linux computer). When enabled (and the enable-agent-sandbox
43609
+ // flag is on), dispatch injects the sandbox builtin tools + system-prompt
43610
+ // frame — mirroring the saved-agent execute route so the two hosted-agent
43611
+ // entry points stay in lockstep.
43612
+ sandbox: sandboxConfigSchema.optional()
43217
43613
  }).superRefine((val, ctx) => {
43218
43614
  if (val.agentType !== "claude_managed") {
43219
43615
  if (!val.name) {
@@ -64489,8 +64885,8 @@ import { execFileSync } from "child_process";
64489
64885
  // src/lib/persona-init.ts
64490
64886
  init_credential_store();
64491
64887
 
64492
- // ../../node_modules/.pnpm/@runtypelabs+persona@3.37.0/node_modules/@runtypelabs/persona/dist/codegen.js
64493
- var S = "3.37.0";
64888
+ // ../../node_modules/.pnpm/@runtypelabs+persona@4.0.0/node_modules/@runtypelabs/persona/dist/codegen.js
64889
+ var S = "4.0.0";
64494
64890
  var c = S;
64495
64891
  function u(e) {
64496
64892
  if (e !== void 0) return typeof e == "string" ? e : Array.isArray(e) ? `[${e.map((r) => r.toString()).join(", ")}]` : e.toString();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runtypelabs/cli",
3
- "version": "2.22.8",
3
+ "version": "2.22.10",
4
4
  "description": "Command-line interface for Runtype AI platform",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -24,11 +24,11 @@
24
24
  "rosie-skills": "0.8.1",
25
25
  "yaml": "^2.9.0",
26
26
  "@runtypelabs/ink-components": "0.3.2",
27
- "@runtypelabs/sdk": "5.2.0",
27
+ "@runtypelabs/sdk": "5.2.2",
28
28
  "@runtypelabs/terminal-animations": "0.2.1"
29
29
  },
30
30
  "devDependencies": {
31
- "@runtypelabs/persona": "3.37.0",
31
+ "@runtypelabs/persona": "4.0.0",
32
32
  "@types/express": "^5.0.6",
33
33
  "@types/micromatch": "^4.0.9",
34
34
  "@types/node": "^25.3.3",
@@ -39,7 +39,7 @@
39
39
  "tsx": "^4.7.1",
40
40
  "typescript": "^5.3.3",
41
41
  "vitest": "^4.1.0",
42
- "@runtypelabs/shared": "1.38.0"
42
+ "@runtypelabs/shared": "1.40.0"
43
43
  },
44
44
  "engines": {
45
45
  "node": ">=22.0.0"