executant 1.4.3 → 1.4.4

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.
package/dist/index.js CHANGED
@@ -1295,17 +1295,69 @@ async function runPass3Judge(description, workflow2) {
1295
1295
  function isNumericSequence(arr) {
1296
1296
  return arr.every((item, i) => item === String(i + 1));
1297
1297
  }
1298
+ function parseSeqCommand(cmd) {
1299
+ const t = cmd.trim();
1300
+ const shorthand = t.match(/^seq\s+(\d+)$/);
1301
+ if (shorthand) return parseInt(shorthand[1], 10);
1302
+ const explicit = t.match(/^seq\s+1\s+(\d+)$/);
1303
+ if (explicit) return parseInt(explicit[1], 10);
1304
+ return null;
1305
+ }
1306
+ function extractCountFromName(name) {
1307
+ const m = name.match(/_of_(\d+)/);
1308
+ return m ? parseInt(m[1], 10) : null;
1309
+ }
1298
1310
  function normalizeWorkflow(workflow2) {
1299
- return {
1300
- ...workflow2,
1301
- steps: workflow2.steps.map((step) => {
1302
- if (Array.isArray(step.forEach) && isNumericSequence(step.forEach)) {
1311
+ const steps = workflow2.steps.map((step) => {
1312
+ if (Array.isArray(step.forEach) && isNumericSequence(step.forEach)) {
1313
+ const { forEach, ...rest } = step;
1314
+ return { ...rest, repeat: forEach.length };
1315
+ }
1316
+ if (typeof step.forEach === "string") {
1317
+ const n = parseSeqCommand(step.forEach);
1318
+ if (n !== null) {
1303
1319
  const { forEach, ...rest } = step;
1304
- return { ...rest, repeat: forEach.length };
1320
+ return { ...rest, repeat: n };
1305
1321
  }
1306
- return step;
1307
- })
1308
- };
1322
+ }
1323
+ const prompt = typeof step.prompt === "string" ? step.prompt : "";
1324
+ if (prompt.includes("{{item}}") && step.forEach === void 0 && step.repeat === void 0) {
1325
+ const n = extractCountFromName(step.name);
1326
+ if (n !== null) return { ...step, repeat: n };
1327
+ }
1328
+ return step;
1329
+ });
1330
+ return { ...workflow2, steps: collapseSequentialSteps(steps) };
1331
+ }
1332
+ function collapseSequentialSteps(steps) {
1333
+ const result = [];
1334
+ let i = 0;
1335
+ while (i < steps.length) {
1336
+ const step = steps[i];
1337
+ if (step.forEach !== void 0 || step.repeat !== void 0) {
1338
+ result.push(step);
1339
+ i++;
1340
+ continue;
1341
+ }
1342
+ const m = step.name.match(/^(.+?)_1$/);
1343
+ if (!m) {
1344
+ result.push(step);
1345
+ i++;
1346
+ continue;
1347
+ }
1348
+ const prefix = m[1];
1349
+ let n = 1;
1350
+ while (i + n < steps.length && steps[i + n].name === `${prefix}_${n + 1}`) n++;
1351
+ if (n < 2) {
1352
+ result.push(step);
1353
+ i++;
1354
+ continue;
1355
+ }
1356
+ const { name, ...rest } = step;
1357
+ result.push({ ...rest, name: `${prefix}_{{item}}`, repeat: n });
1358
+ i += n;
1359
+ }
1360
+ return result;
1309
1361
  }
1310
1362
  async function* streamPlan(args) {
1311
1363
  const { description, taskFile } = args;
@@ -1371,7 +1423,7 @@ async function* streamPlan(args) {
1371
1423
  ${basePrompt}` : basePrompt,
1372
1424
  allowedTools: [],
1373
1425
  permissionMode: "bypassPermissions",
1374
- model: "opus",
1426
+ model: skipResearch ? "sonnet" : "opus",
1375
1427
  appendSystemPrompt: PLAN_SYSTEM_RULES,
1376
1428
  jsonSchema: WORKFLOW_JSON_SCHEMA
1377
1429
  };
@@ -65,6 +65,8 @@ If the user's goal mentions "N times", "repeat N", "N iterations", or "N passes"
65
65
  - Does any step use `forEach` with a sequential numeric array like `["1","2","3","4","5"]`?
66
66
  - This is always wrong — `repeat: N` must be used instead of a numeric forEach array
67
67
  - Reject and require the offending step be converted to `repeat: N`
68
+ - Does any single step's `prompt` describe doing something "N times" or "across N passes" inline, instead of using `repeat: N`? A step that says "do this 10 times" or "perform N passes" inside its prompt text rather than setting `repeat: N` is wrong — reject it and require it to be restructured as a single-pass prompt with `repeat: N` on the step
69
+ - Are there N consecutive steps with names like `step_1`, `step_2`, `step_3`? Sequential named steps are always wrong when they do the same thing — reject and require a single step with `repeat: N`
68
70
 
69
71
  ## Output Format
70
72
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "executant",
3
- "version": "1.4.3",
3
+ "version": "1.4.4",
4
4
  "description": "Harness for YAML-defined workflows that enables stepping through Claude sessions and bash commands",
5
5
  "repository": {
6
6
  "type": "git",