agent-relay 4.0.0 → 4.0.1
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/README.md +5 -5
- package/bin/agent-relay-broker-darwin-arm64 +0 -0
- package/bin/agent-relay-broker-darwin-x64 +0 -0
- package/bin/agent-relay-broker-linux-arm64 +0 -0
- package/bin/agent-relay-broker-linux-x64 +0 -0
- package/dist/index.cjs +1980 -1024
- package/dist/src/cli/commands/core.d.ts.map +1 -1
- package/dist/src/cli/commands/core.js +4 -3
- package/dist/src/cli/commands/core.js.map +1 -1
- package/dist/src/cli/commands/on/relayfile-binary.d.ts +2 -0
- package/dist/src/cli/commands/on/relayfile-binary.d.ts.map +1 -0
- package/dist/src/cli/commands/on/relayfile-binary.js +208 -0
- package/dist/src/cli/commands/on/relayfile-binary.js.map +1 -0
- package/dist/src/cli/commands/on/start.d.ts.map +1 -1
- package/dist/src/cli/commands/on/start.js +62 -26
- package/dist/src/cli/commands/on/start.js.map +1 -1
- package/dist/src/cli/commands/on/workspace.d.ts.map +1 -1
- package/dist/src/cli/commands/on/workspace.js +4 -0
- package/dist/src/cli/commands/on/workspace.js.map +1 -1
- package/dist/src/cli/commands/on.js +1 -1
- package/dist/src/cli/commands/on.js.map +1 -1
- package/dist/src/cli/lib/client-factory.d.ts +2 -2
- package/dist/src/cli/lib/client-factory.d.ts.map +1 -1
- package/dist/src/cli/lib/client-factory.js.map +1 -1
- package/dist/src/cost/pricing.d.ts +18 -0
- package/dist/src/cost/pricing.d.ts.map +1 -0
- package/dist/src/cost/pricing.js +111 -0
- package/dist/src/cost/pricing.js.map +1 -0
- package/dist/src/cost/tracker.d.ts +13 -0
- package/dist/src/cost/tracker.d.ts.map +1 -0
- package/dist/src/cost/tracker.js +152 -0
- package/dist/src/cost/tracker.js.map +1 -0
- package/dist/src/cost/types.d.ts +23 -0
- package/dist/src/cost/types.d.ts.map +1 -0
- package/dist/src/cost/types.js +2 -0
- package/dist/src/cost/types.js.map +1 -0
- package/package.json +10 -10
- package/packages/acp-bridge/package.json +2 -2
- package/packages/brand/package.json +1 -1
- package/packages/cloud/package.json +3 -3
- package/packages/config/package.json +1 -1
- package/packages/hooks/package.json +4 -4
- package/packages/memory/package.json +2 -2
- package/packages/openclaw/package.json +2 -2
- package/packages/policy/package.json +2 -2
- package/packages/sdk/dist/broker-path.d.ts +3 -2
- package/packages/sdk/dist/broker-path.d.ts.map +1 -1
- package/packages/sdk/dist/broker-path.js +119 -32
- package/packages/sdk/dist/broker-path.js.map +1 -1
- package/packages/sdk/dist/client.d.ts +12 -2
- package/packages/sdk/dist/client.d.ts.map +1 -1
- package/packages/sdk/dist/client.js +20 -1
- package/packages/sdk/dist/client.js.map +1 -1
- package/packages/sdk/dist/index.d.ts +1 -1
- package/packages/sdk/dist/index.d.ts.map +1 -1
- package/packages/sdk/dist/index.js.map +1 -1
- package/packages/sdk/dist/relay.d.ts +2 -1
- package/packages/sdk/dist/relay.d.ts.map +1 -1
- package/packages/sdk/dist/relay.js +1 -1
- package/packages/sdk/dist/relay.js.map +1 -1
- package/packages/sdk/dist/workflows/__tests__/channel-messenger.test.d.ts +2 -0
- package/packages/sdk/dist/workflows/__tests__/channel-messenger.test.d.ts.map +1 -0
- package/packages/sdk/dist/workflows/__tests__/channel-messenger.test.js +117 -0
- package/packages/sdk/dist/workflows/__tests__/channel-messenger.test.js.map +1 -0
- package/packages/sdk/dist/workflows/__tests__/run-summary-table.test.js +4 -3
- package/packages/sdk/dist/workflows/__tests__/run-summary-table.test.js.map +1 -1
- package/packages/sdk/dist/workflows/__tests__/step-executor.test.d.ts +2 -0
- package/packages/sdk/dist/workflows/__tests__/step-executor.test.d.ts.map +1 -0
- package/packages/sdk/dist/workflows/__tests__/step-executor.test.js +378 -0
- package/packages/sdk/dist/workflows/__tests__/step-executor.test.js.map +1 -0
- package/packages/sdk/dist/workflows/__tests__/template-resolver.test.d.ts +2 -0
- package/packages/sdk/dist/workflows/__tests__/template-resolver.test.d.ts.map +1 -0
- package/packages/sdk/dist/workflows/__tests__/template-resolver.test.js +145 -0
- package/packages/sdk/dist/workflows/__tests__/template-resolver.test.js.map +1 -0
- package/packages/sdk/dist/workflows/__tests__/verification.test.d.ts +2 -0
- package/packages/sdk/dist/workflows/__tests__/verification.test.d.ts.map +1 -0
- package/packages/sdk/dist/workflows/__tests__/verification.test.js +170 -0
- package/packages/sdk/dist/workflows/__tests__/verification.test.js.map +1 -0
- package/packages/sdk/dist/workflows/builder.d.ts +3 -2
- package/packages/sdk/dist/workflows/builder.d.ts.map +1 -1
- package/packages/sdk/dist/workflows/builder.js +1 -3
- package/packages/sdk/dist/workflows/builder.js.map +1 -1
- package/packages/sdk/dist/workflows/channel-messenger.d.ts +28 -0
- package/packages/sdk/dist/workflows/channel-messenger.d.ts.map +1 -0
- package/packages/sdk/dist/workflows/channel-messenger.js +255 -0
- package/packages/sdk/dist/workflows/channel-messenger.js.map +1 -0
- package/packages/sdk/dist/workflows/index.d.ts +7 -0
- package/packages/sdk/dist/workflows/index.d.ts.map +1 -1
- package/packages/sdk/dist/workflows/index.js +7 -0
- package/packages/sdk/dist/workflows/index.js.map +1 -1
- package/packages/sdk/dist/workflows/process-spawner.d.ts +35 -0
- package/packages/sdk/dist/workflows/process-spawner.d.ts.map +1 -0
- package/packages/sdk/dist/workflows/process-spawner.js +141 -0
- package/packages/sdk/dist/workflows/process-spawner.js.map +1 -0
- package/packages/sdk/dist/workflows/run.d.ts +2 -1
- package/packages/sdk/dist/workflows/run.d.ts.map +1 -1
- package/packages/sdk/dist/workflows/run.js.map +1 -1
- package/packages/sdk/dist/workflows/runner.d.ts +6 -6
- package/packages/sdk/dist/workflows/runner.d.ts.map +1 -1
- package/packages/sdk/dist/workflows/runner.js +443 -719
- package/packages/sdk/dist/workflows/runner.js.map +1 -1
- package/packages/sdk/dist/workflows/step-executor.d.ts +95 -0
- package/packages/sdk/dist/workflows/step-executor.d.ts.map +1 -0
- package/packages/sdk/dist/workflows/step-executor.js +393 -0
- package/packages/sdk/dist/workflows/step-executor.js.map +1 -0
- package/packages/sdk/dist/workflows/template-resolver.d.ts +33 -0
- package/packages/sdk/dist/workflows/template-resolver.d.ts.map +1 -0
- package/packages/sdk/dist/workflows/template-resolver.js +144 -0
- package/packages/sdk/dist/workflows/template-resolver.js.map +1 -0
- package/packages/sdk/dist/workflows/verification.d.ts +33 -0
- package/packages/sdk/dist/workflows/verification.d.ts.map +1 -0
- package/packages/sdk/dist/workflows/verification.js +122 -0
- package/packages/sdk/dist/workflows/verification.js.map +1 -0
- package/packages/sdk/package.json +2 -2
- package/packages/sdk/src/broker-path.ts +136 -30
- package/packages/sdk/src/client.ts +37 -3
- package/packages/sdk/src/index.ts +1 -0
- package/packages/sdk/src/relay.ts +6 -2
- package/packages/sdk/src/workflows/__tests__/channel-messenger.test.ts +137 -0
- package/packages/sdk/src/workflows/__tests__/run-summary-table.test.ts +4 -3
- package/packages/sdk/src/workflows/__tests__/step-executor.test.ts +444 -0
- package/packages/sdk/src/workflows/__tests__/template-resolver.test.ts +162 -0
- package/packages/sdk/src/workflows/__tests__/verification.test.ts +229 -0
- package/packages/sdk/src/workflows/builder.ts +6 -6
- package/packages/sdk/src/workflows/channel-messenger.ts +314 -0
- package/packages/sdk/src/workflows/index.ts +12 -0
- package/packages/sdk/src/workflows/process-spawner.ts +201 -0
- package/packages/sdk/src/workflows/run.ts +2 -1
- package/packages/sdk/src/workflows/runner.ts +636 -951
- package/packages/sdk/src/workflows/step-executor.ts +579 -0
- package/packages/sdk/src/workflows/template-resolver.ts +180 -0
- package/packages/sdk/src/workflows/verification.ts +184 -0
- package/packages/sdk-py/pyproject.toml +1 -1
- package/packages/telemetry/package.json +1 -1
- package/packages/trajectory/package.json +2 -2
- package/packages/user-directory/package.json +2 -2
- package/packages/utils/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -4531,15 +4531,15 @@ var require_route = __commonJS({
|
|
|
4531
4531
|
};
|
|
4532
4532
|
}
|
|
4533
4533
|
function wrapConversion(toModel, graph) {
|
|
4534
|
-
const
|
|
4534
|
+
const path19 = [graph[toModel].parent, toModel];
|
|
4535
4535
|
let fn = conversions[graph[toModel].parent][toModel];
|
|
4536
4536
|
let cur = graph[toModel].parent;
|
|
4537
4537
|
while (graph[cur].parent) {
|
|
4538
|
-
|
|
4538
|
+
path19.unshift(graph[cur].parent);
|
|
4539
4539
|
fn = link2(conversions[graph[cur].parent][cur], fn);
|
|
4540
4540
|
cur = graph[cur].parent;
|
|
4541
4541
|
}
|
|
4542
|
-
fn.conversion =
|
|
4542
|
+
fn.conversion = path19;
|
|
4543
4543
|
return fn;
|
|
4544
4544
|
}
|
|
4545
4545
|
module2.exports = function(fromModel) {
|
|
@@ -5285,17 +5285,17 @@ var require_visit = __commonJS({
|
|
|
5285
5285
|
visit.BREAK = BREAK;
|
|
5286
5286
|
visit.SKIP = SKIP;
|
|
5287
5287
|
visit.REMOVE = REMOVE;
|
|
5288
|
-
function visit_(key, node, visitor,
|
|
5289
|
-
const ctrl = callVisitor(key, node, visitor,
|
|
5288
|
+
function visit_(key, node, visitor, path19) {
|
|
5289
|
+
const ctrl = callVisitor(key, node, visitor, path19);
|
|
5290
5290
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
5291
|
-
replaceNode(key,
|
|
5292
|
-
return visit_(key, ctrl, visitor,
|
|
5291
|
+
replaceNode(key, path19, ctrl);
|
|
5292
|
+
return visit_(key, ctrl, visitor, path19);
|
|
5293
5293
|
}
|
|
5294
5294
|
if (typeof ctrl !== "symbol") {
|
|
5295
5295
|
if (identity.isCollection(node)) {
|
|
5296
|
-
|
|
5296
|
+
path19 = Object.freeze(path19.concat(node));
|
|
5297
5297
|
for (let i = 0; i < node.items.length; ++i) {
|
|
5298
|
-
const ci = visit_(i, node.items[i], visitor,
|
|
5298
|
+
const ci = visit_(i, node.items[i], visitor, path19);
|
|
5299
5299
|
if (typeof ci === "number")
|
|
5300
5300
|
i = ci - 1;
|
|
5301
5301
|
else if (ci === BREAK)
|
|
@@ -5306,13 +5306,13 @@ var require_visit = __commonJS({
|
|
|
5306
5306
|
}
|
|
5307
5307
|
}
|
|
5308
5308
|
} else if (identity.isPair(node)) {
|
|
5309
|
-
|
|
5310
|
-
const ck = visit_("key", node.key, visitor,
|
|
5309
|
+
path19 = Object.freeze(path19.concat(node));
|
|
5310
|
+
const ck = visit_("key", node.key, visitor, path19);
|
|
5311
5311
|
if (ck === BREAK)
|
|
5312
5312
|
return BREAK;
|
|
5313
5313
|
else if (ck === REMOVE)
|
|
5314
5314
|
node.key = null;
|
|
5315
|
-
const cv = visit_("value", node.value, visitor,
|
|
5315
|
+
const cv = visit_("value", node.value, visitor, path19);
|
|
5316
5316
|
if (cv === BREAK)
|
|
5317
5317
|
return BREAK;
|
|
5318
5318
|
else if (cv === REMOVE)
|
|
@@ -5333,17 +5333,17 @@ var require_visit = __commonJS({
|
|
|
5333
5333
|
visitAsync.BREAK = BREAK;
|
|
5334
5334
|
visitAsync.SKIP = SKIP;
|
|
5335
5335
|
visitAsync.REMOVE = REMOVE;
|
|
5336
|
-
async function visitAsync_(key, node, visitor,
|
|
5337
|
-
const ctrl = await callVisitor(key, node, visitor,
|
|
5336
|
+
async function visitAsync_(key, node, visitor, path19) {
|
|
5337
|
+
const ctrl = await callVisitor(key, node, visitor, path19);
|
|
5338
5338
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
5339
|
-
replaceNode(key,
|
|
5340
|
-
return visitAsync_(key, ctrl, visitor,
|
|
5339
|
+
replaceNode(key, path19, ctrl);
|
|
5340
|
+
return visitAsync_(key, ctrl, visitor, path19);
|
|
5341
5341
|
}
|
|
5342
5342
|
if (typeof ctrl !== "symbol") {
|
|
5343
5343
|
if (identity.isCollection(node)) {
|
|
5344
|
-
|
|
5344
|
+
path19 = Object.freeze(path19.concat(node));
|
|
5345
5345
|
for (let i = 0; i < node.items.length; ++i) {
|
|
5346
|
-
const ci = await visitAsync_(i, node.items[i], visitor,
|
|
5346
|
+
const ci = await visitAsync_(i, node.items[i], visitor, path19);
|
|
5347
5347
|
if (typeof ci === "number")
|
|
5348
5348
|
i = ci - 1;
|
|
5349
5349
|
else if (ci === BREAK)
|
|
@@ -5354,13 +5354,13 @@ var require_visit = __commonJS({
|
|
|
5354
5354
|
}
|
|
5355
5355
|
}
|
|
5356
5356
|
} else if (identity.isPair(node)) {
|
|
5357
|
-
|
|
5358
|
-
const ck = await visitAsync_("key", node.key, visitor,
|
|
5357
|
+
path19 = Object.freeze(path19.concat(node));
|
|
5358
|
+
const ck = await visitAsync_("key", node.key, visitor, path19);
|
|
5359
5359
|
if (ck === BREAK)
|
|
5360
5360
|
return BREAK;
|
|
5361
5361
|
else if (ck === REMOVE)
|
|
5362
5362
|
node.key = null;
|
|
5363
|
-
const cv = await visitAsync_("value", node.value, visitor,
|
|
5363
|
+
const cv = await visitAsync_("value", node.value, visitor, path19);
|
|
5364
5364
|
if (cv === BREAK)
|
|
5365
5365
|
return BREAK;
|
|
5366
5366
|
else if (cv === REMOVE)
|
|
@@ -5387,23 +5387,23 @@ var require_visit = __commonJS({
|
|
|
5387
5387
|
}
|
|
5388
5388
|
return visitor;
|
|
5389
5389
|
}
|
|
5390
|
-
function callVisitor(key, node, visitor,
|
|
5390
|
+
function callVisitor(key, node, visitor, path19) {
|
|
5391
5391
|
if (typeof visitor === "function")
|
|
5392
|
-
return visitor(key, node,
|
|
5392
|
+
return visitor(key, node, path19);
|
|
5393
5393
|
if (identity.isMap(node))
|
|
5394
|
-
return visitor.Map?.(key, node,
|
|
5394
|
+
return visitor.Map?.(key, node, path19);
|
|
5395
5395
|
if (identity.isSeq(node))
|
|
5396
|
-
return visitor.Seq?.(key, node,
|
|
5396
|
+
return visitor.Seq?.(key, node, path19);
|
|
5397
5397
|
if (identity.isPair(node))
|
|
5398
|
-
return visitor.Pair?.(key, node,
|
|
5398
|
+
return visitor.Pair?.(key, node, path19);
|
|
5399
5399
|
if (identity.isScalar(node))
|
|
5400
|
-
return visitor.Scalar?.(key, node,
|
|
5400
|
+
return visitor.Scalar?.(key, node, path19);
|
|
5401
5401
|
if (identity.isAlias(node))
|
|
5402
|
-
return visitor.Alias?.(key, node,
|
|
5402
|
+
return visitor.Alias?.(key, node, path19);
|
|
5403
5403
|
return void 0;
|
|
5404
5404
|
}
|
|
5405
|
-
function replaceNode(key,
|
|
5406
|
-
const parent =
|
|
5405
|
+
function replaceNode(key, path19, node) {
|
|
5406
|
+
const parent = path19[path19.length - 1];
|
|
5407
5407
|
if (identity.isCollection(parent)) {
|
|
5408
5408
|
parent.items[key] = node;
|
|
5409
5409
|
} else if (identity.isPair(parent)) {
|
|
@@ -6011,10 +6011,10 @@ var require_Collection = __commonJS({
|
|
|
6011
6011
|
var createNode = require_createNode();
|
|
6012
6012
|
var identity = require_identity();
|
|
6013
6013
|
var Node = require_Node();
|
|
6014
|
-
function collectionFromPath(schema,
|
|
6014
|
+
function collectionFromPath(schema, path19, value) {
|
|
6015
6015
|
let v = value;
|
|
6016
|
-
for (let i =
|
|
6017
|
-
const k =
|
|
6016
|
+
for (let i = path19.length - 1; i >= 0; --i) {
|
|
6017
|
+
const k = path19[i];
|
|
6018
6018
|
if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
|
|
6019
6019
|
const a = [];
|
|
6020
6020
|
a[k] = v;
|
|
@@ -6033,7 +6033,7 @@ var require_Collection = __commonJS({
|
|
|
6033
6033
|
sourceObjects: /* @__PURE__ */ new Map()
|
|
6034
6034
|
});
|
|
6035
6035
|
}
|
|
6036
|
-
var isEmptyPath = (
|
|
6036
|
+
var isEmptyPath = (path19) => path19 == null || typeof path19 === "object" && !!path19[Symbol.iterator]().next().done;
|
|
6037
6037
|
var Collection = class extends Node.NodeBase {
|
|
6038
6038
|
constructor(type, schema) {
|
|
6039
6039
|
super(type);
|
|
@@ -6063,11 +6063,11 @@ var require_Collection = __commonJS({
|
|
|
6063
6063
|
* be a Pair instance or a `{ key, value }` object, which may not have a key
|
|
6064
6064
|
* that already exists in the map.
|
|
6065
6065
|
*/
|
|
6066
|
-
addIn(
|
|
6067
|
-
if (isEmptyPath(
|
|
6066
|
+
addIn(path19, value) {
|
|
6067
|
+
if (isEmptyPath(path19))
|
|
6068
6068
|
this.add(value);
|
|
6069
6069
|
else {
|
|
6070
|
-
const [key, ...rest] =
|
|
6070
|
+
const [key, ...rest] = path19;
|
|
6071
6071
|
const node = this.get(key, true);
|
|
6072
6072
|
if (identity.isCollection(node))
|
|
6073
6073
|
node.addIn(rest, value);
|
|
@@ -6081,8 +6081,8 @@ var require_Collection = __commonJS({
|
|
|
6081
6081
|
* Removes a value from the collection.
|
|
6082
6082
|
* @returns `true` if the item was found and removed.
|
|
6083
6083
|
*/
|
|
6084
|
-
deleteIn(
|
|
6085
|
-
const [key, ...rest] =
|
|
6084
|
+
deleteIn(path19) {
|
|
6085
|
+
const [key, ...rest] = path19;
|
|
6086
6086
|
if (rest.length === 0)
|
|
6087
6087
|
return this.delete(key);
|
|
6088
6088
|
const node = this.get(key, true);
|
|
@@ -6096,8 +6096,8 @@ var require_Collection = __commonJS({
|
|
|
6096
6096
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
6097
6097
|
* `true` (collections are always returned intact).
|
|
6098
6098
|
*/
|
|
6099
|
-
getIn(
|
|
6100
|
-
const [key, ...rest] =
|
|
6099
|
+
getIn(path19, keepScalar) {
|
|
6100
|
+
const [key, ...rest] = path19;
|
|
6101
6101
|
const node = this.get(key, true);
|
|
6102
6102
|
if (rest.length === 0)
|
|
6103
6103
|
return !keepScalar && identity.isScalar(node) ? node.value : node;
|
|
@@ -6115,8 +6115,8 @@ var require_Collection = __commonJS({
|
|
|
6115
6115
|
/**
|
|
6116
6116
|
* Checks if the collection includes a value with the key `key`.
|
|
6117
6117
|
*/
|
|
6118
|
-
hasIn(
|
|
6119
|
-
const [key, ...rest] =
|
|
6118
|
+
hasIn(path19) {
|
|
6119
|
+
const [key, ...rest] = path19;
|
|
6120
6120
|
if (rest.length === 0)
|
|
6121
6121
|
return this.has(key);
|
|
6122
6122
|
const node = this.get(key, true);
|
|
@@ -6126,8 +6126,8 @@ var require_Collection = __commonJS({
|
|
|
6126
6126
|
* Sets a value in this collection. For `!!set`, `value` needs to be a
|
|
6127
6127
|
* boolean to add/remove the item from the set.
|
|
6128
6128
|
*/
|
|
6129
|
-
setIn(
|
|
6130
|
-
const [key, ...rest] =
|
|
6129
|
+
setIn(path19, value) {
|
|
6130
|
+
const [key, ...rest] = path19;
|
|
6131
6131
|
if (rest.length === 0) {
|
|
6132
6132
|
this.set(key, value);
|
|
6133
6133
|
} else {
|
|
@@ -8639,9 +8639,9 @@ var require_Document = __commonJS({
|
|
|
8639
8639
|
this.contents.add(value);
|
|
8640
8640
|
}
|
|
8641
8641
|
/** Adds a value to the document. */
|
|
8642
|
-
addIn(
|
|
8642
|
+
addIn(path19, value) {
|
|
8643
8643
|
if (assertCollection(this.contents))
|
|
8644
|
-
this.contents.addIn(
|
|
8644
|
+
this.contents.addIn(path19, value);
|
|
8645
8645
|
}
|
|
8646
8646
|
/**
|
|
8647
8647
|
* Create a new `Alias` node, ensuring that the target `node` has the required anchor.
|
|
@@ -8716,14 +8716,14 @@ var require_Document = __commonJS({
|
|
|
8716
8716
|
* Removes a value from the document.
|
|
8717
8717
|
* @returns `true` if the item was found and removed.
|
|
8718
8718
|
*/
|
|
8719
|
-
deleteIn(
|
|
8720
|
-
if (Collection.isEmptyPath(
|
|
8719
|
+
deleteIn(path19) {
|
|
8720
|
+
if (Collection.isEmptyPath(path19)) {
|
|
8721
8721
|
if (this.contents == null)
|
|
8722
8722
|
return false;
|
|
8723
8723
|
this.contents = null;
|
|
8724
8724
|
return true;
|
|
8725
8725
|
}
|
|
8726
|
-
return assertCollection(this.contents) ? this.contents.deleteIn(
|
|
8726
|
+
return assertCollection(this.contents) ? this.contents.deleteIn(path19) : false;
|
|
8727
8727
|
}
|
|
8728
8728
|
/**
|
|
8729
8729
|
* Returns item at `key`, or `undefined` if not found. By default unwraps
|
|
@@ -8738,10 +8738,10 @@ var require_Document = __commonJS({
|
|
|
8738
8738
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
8739
8739
|
* `true` (collections are always returned intact).
|
|
8740
8740
|
*/
|
|
8741
|
-
getIn(
|
|
8742
|
-
if (Collection.isEmptyPath(
|
|
8741
|
+
getIn(path19, keepScalar) {
|
|
8742
|
+
if (Collection.isEmptyPath(path19))
|
|
8743
8743
|
return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
|
|
8744
|
-
return identity.isCollection(this.contents) ? this.contents.getIn(
|
|
8744
|
+
return identity.isCollection(this.contents) ? this.contents.getIn(path19, keepScalar) : void 0;
|
|
8745
8745
|
}
|
|
8746
8746
|
/**
|
|
8747
8747
|
* Checks if the document includes a value with the key `key`.
|
|
@@ -8752,10 +8752,10 @@ var require_Document = __commonJS({
|
|
|
8752
8752
|
/**
|
|
8753
8753
|
* Checks if the document includes a value at `path`.
|
|
8754
8754
|
*/
|
|
8755
|
-
hasIn(
|
|
8756
|
-
if (Collection.isEmptyPath(
|
|
8755
|
+
hasIn(path19) {
|
|
8756
|
+
if (Collection.isEmptyPath(path19))
|
|
8757
8757
|
return this.contents !== void 0;
|
|
8758
|
-
return identity.isCollection(this.contents) ? this.contents.hasIn(
|
|
8758
|
+
return identity.isCollection(this.contents) ? this.contents.hasIn(path19) : false;
|
|
8759
8759
|
}
|
|
8760
8760
|
/**
|
|
8761
8761
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
@@ -8772,13 +8772,13 @@ var require_Document = __commonJS({
|
|
|
8772
8772
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
8773
8773
|
* boolean to add/remove the item from the set.
|
|
8774
8774
|
*/
|
|
8775
|
-
setIn(
|
|
8776
|
-
if (Collection.isEmptyPath(
|
|
8775
|
+
setIn(path19, value) {
|
|
8776
|
+
if (Collection.isEmptyPath(path19)) {
|
|
8777
8777
|
this.contents = value;
|
|
8778
8778
|
} else if (this.contents == null) {
|
|
8779
|
-
this.contents = Collection.collectionFromPath(this.schema, Array.from(
|
|
8779
|
+
this.contents = Collection.collectionFromPath(this.schema, Array.from(path19), value);
|
|
8780
8780
|
} else if (assertCollection(this.contents)) {
|
|
8781
|
-
this.contents.setIn(
|
|
8781
|
+
this.contents.setIn(path19, value);
|
|
8782
8782
|
}
|
|
8783
8783
|
}
|
|
8784
8784
|
/**
|
|
@@ -10735,9 +10735,9 @@ var require_cst_visit = __commonJS({
|
|
|
10735
10735
|
visit.BREAK = BREAK;
|
|
10736
10736
|
visit.SKIP = SKIP;
|
|
10737
10737
|
visit.REMOVE = REMOVE;
|
|
10738
|
-
visit.itemAtPath = (cst,
|
|
10738
|
+
visit.itemAtPath = (cst, path19) => {
|
|
10739
10739
|
let item = cst;
|
|
10740
|
-
for (const [field, index] of
|
|
10740
|
+
for (const [field, index] of path19) {
|
|
10741
10741
|
const tok = item?.[field];
|
|
10742
10742
|
if (tok && "items" in tok) {
|
|
10743
10743
|
item = tok.items[index];
|
|
@@ -10746,23 +10746,23 @@ var require_cst_visit = __commonJS({
|
|
|
10746
10746
|
}
|
|
10747
10747
|
return item;
|
|
10748
10748
|
};
|
|
10749
|
-
visit.parentCollection = (cst,
|
|
10750
|
-
const parent = visit.itemAtPath(cst,
|
|
10751
|
-
const field =
|
|
10749
|
+
visit.parentCollection = (cst, path19) => {
|
|
10750
|
+
const parent = visit.itemAtPath(cst, path19.slice(0, -1));
|
|
10751
|
+
const field = path19[path19.length - 1][0];
|
|
10752
10752
|
const coll = parent?.[field];
|
|
10753
10753
|
if (coll && "items" in coll)
|
|
10754
10754
|
return coll;
|
|
10755
10755
|
throw new Error("Parent collection not found");
|
|
10756
10756
|
};
|
|
10757
|
-
function _visit(
|
|
10758
|
-
let ctrl = visitor(item,
|
|
10757
|
+
function _visit(path19, item, visitor) {
|
|
10758
|
+
let ctrl = visitor(item, path19);
|
|
10759
10759
|
if (typeof ctrl === "symbol")
|
|
10760
10760
|
return ctrl;
|
|
10761
10761
|
for (const field of ["key", "value"]) {
|
|
10762
10762
|
const token = item[field];
|
|
10763
10763
|
if (token && "items" in token) {
|
|
10764
10764
|
for (let i = 0; i < token.items.length; ++i) {
|
|
10765
|
-
const ci = _visit(Object.freeze(
|
|
10765
|
+
const ci = _visit(Object.freeze(path19.concat([[field, i]])), token.items[i], visitor);
|
|
10766
10766
|
if (typeof ci === "number")
|
|
10767
10767
|
i = ci - 1;
|
|
10768
10768
|
else if (ci === BREAK)
|
|
@@ -10773,10 +10773,10 @@ var require_cst_visit = __commonJS({
|
|
|
10773
10773
|
}
|
|
10774
10774
|
}
|
|
10775
10775
|
if (typeof ctrl === "function" && field === "key")
|
|
10776
|
-
ctrl = ctrl(item,
|
|
10776
|
+
ctrl = ctrl(item, path19);
|
|
10777
10777
|
}
|
|
10778
10778
|
}
|
|
10779
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
10779
|
+
return typeof ctrl === "function" ? ctrl(item, path19) : ctrl;
|
|
10780
10780
|
}
|
|
10781
10781
|
exports2.visit = visit;
|
|
10782
10782
|
}
|
|
@@ -16162,7 +16162,7 @@ __export(dist_exports, {
|
|
|
16162
16162
|
cloneObject: () => cloneObject,
|
|
16163
16163
|
color: () => color,
|
|
16164
16164
|
createWritable: () => createWritable,
|
|
16165
|
-
delay: () =>
|
|
16165
|
+
delay: () => delay2,
|
|
16166
16166
|
figures: () => figures,
|
|
16167
16167
|
getRenderer: () => getRenderer,
|
|
16168
16168
|
getRendererClass: () => getRendererClass,
|
|
@@ -16246,9 +16246,9 @@ function assertFunctionOrSelf(functionOrSelf, ...args) {
|
|
|
16246
16246
|
function cloneObject(obj) {
|
|
16247
16247
|
return clone2(obj);
|
|
16248
16248
|
}
|
|
16249
|
-
function
|
|
16250
|
-
return new Promise((
|
|
16251
|
-
setTimeout(
|
|
16249
|
+
function delay2(time3) {
|
|
16250
|
+
return new Promise((resolve4) => {
|
|
16251
|
+
setTimeout(resolve4, time3);
|
|
16252
16252
|
});
|
|
16253
16253
|
}
|
|
16254
16254
|
var import_node_util3, import_util6, import_os, import_string_decoder, import_stream2, import_rfdc, import_crypto, ANSI_ESCAPE2, ANSI_ESCAPE_CODES, ListrEnvironmentVariables, ListrErrorTypes, ListrEventType, ListrRendererSelection, ListrTaskEventType, ListrTaskState, EventManager, BaseEventMap, CLEAR_LINE_REGEX, BELL_REGEX, color, FIGURES_MAIN, FIGURES_FALLBACK, figures, ListrLogLevels, LISTR_LOGGER_STYLE, LISTR_LOGGER_STDERR_LEVELS, ListrLogger, ProcessOutputBuffer, ProcessOutputStream, ProcessOutput, ListrPromptAdapter, Spinner, ListrDefaultRendererLogLevels, LISTR_DEFAULT_RENDERER_STYLE, PRESET_TIMER, PRESET_TIMESTAMP, DefaultRenderer, SilentRenderer, SimpleRenderer, TestRendererSerializer, TestRenderer, VerboseRenderer, RENDERERS, clone2, Concurrency, ListrError, ListrRendererError, PromptError, TaskWrapper, ListrTaskEventManager, Task, ListrEventManager, Listr;
|
|
@@ -17434,8 +17434,8 @@ var init_dist = __esm({
|
|
|
17434
17434
|
}
|
|
17435
17435
|
add(fn) {
|
|
17436
17436
|
if (this.count < this.concurrency) return this.run(fn);
|
|
17437
|
-
return new Promise((
|
|
17438
|
-
const callback = () =>
|
|
17437
|
+
return new Promise((resolve4) => {
|
|
17438
|
+
const callback = () => resolve4(this.run(fn));
|
|
17439
17439
|
this.queue.add(callback);
|
|
17440
17440
|
});
|
|
17441
17441
|
}
|
|
@@ -17767,7 +17767,7 @@ var init_dist = __esm({
|
|
|
17767
17767
|
const state = this.state;
|
|
17768
17768
|
this.state$ = ListrTaskState.PAUSED;
|
|
17769
17769
|
this.message$ = { paused: Date.now() + time3 };
|
|
17770
|
-
await
|
|
17770
|
+
await delay2(time3);
|
|
17771
17771
|
this.state$ = state;
|
|
17772
17772
|
this.message$ = { paused: null };
|
|
17773
17773
|
}
|
|
@@ -17785,20 +17785,20 @@ var init_dist = __esm({
|
|
|
17785
17785
|
this.emit(ListrTaskEventType.SUBTASK, this.subtasks);
|
|
17786
17786
|
result = result.run(context);
|
|
17787
17787
|
} else if (result instanceof Promise) result = result.then(handleResult2);
|
|
17788
|
-
else if (isReadable(result)) result = new Promise((
|
|
17788
|
+
else if (isReadable(result)) result = new Promise((resolve4, reject) => {
|
|
17789
17789
|
result.on("data", (data) => {
|
|
17790
17790
|
this.output$ = data.toString();
|
|
17791
17791
|
});
|
|
17792
17792
|
result.on("error", (error48) => reject(error48));
|
|
17793
|
-
result.on("end", () =>
|
|
17793
|
+
result.on("end", () => resolve4(null));
|
|
17794
17794
|
});
|
|
17795
|
-
else if (isObservable(result)) result = new Promise((
|
|
17795
|
+
else if (isObservable(result)) result = new Promise((resolve4, reject) => {
|
|
17796
17796
|
result.subscribe({
|
|
17797
17797
|
next: (data) => {
|
|
17798
17798
|
this.output$ = data;
|
|
17799
17799
|
},
|
|
17800
17800
|
error: reject,
|
|
17801
|
-
complete:
|
|
17801
|
+
complete: resolve4
|
|
17802
17802
|
});
|
|
17803
17803
|
});
|
|
17804
17804
|
return result;
|
|
@@ -18031,8 +18031,8 @@ function createWorkflowRenderer() {
|
|
|
18031
18031
|
const stepHandles = /* @__PURE__ */ new Map();
|
|
18032
18032
|
let resolveWorkflow;
|
|
18033
18033
|
let rejectWorkflow;
|
|
18034
|
-
const workflowDone = new Promise((
|
|
18035
|
-
resolveWorkflow =
|
|
18034
|
+
const workflowDone = new Promise((resolve4, reject) => {
|
|
18035
|
+
resolveWorkflow = resolve4;
|
|
18036
18036
|
rejectWorkflow = reject;
|
|
18037
18037
|
});
|
|
18038
18038
|
workflowDone.catch(() => {
|
|
@@ -18085,8 +18085,8 @@ function createWorkflowRenderer() {
|
|
|
18085
18085
|
let rejectStep;
|
|
18086
18086
|
let taskRef = null;
|
|
18087
18087
|
let skipped = false;
|
|
18088
|
-
const done = new Promise((
|
|
18089
|
-
resolveStep =
|
|
18088
|
+
const done = new Promise((resolve4, reject) => {
|
|
18089
|
+
resolveStep = resolve4;
|
|
18090
18090
|
rejectStep = reject;
|
|
18091
18091
|
});
|
|
18092
18092
|
done.catch(() => {
|
|
@@ -18803,8 +18803,8 @@ var init_supermemory = __esm({
|
|
|
18803
18803
|
/**
|
|
18804
18804
|
* Make a fetch request to the Supermemory API
|
|
18805
18805
|
*/
|
|
18806
|
-
async fetch(
|
|
18807
|
-
const url2 = `${this.endpoint}${
|
|
18806
|
+
async fetch(path19, options) {
|
|
18807
|
+
const url2 = `${this.endpoint}${path19}`;
|
|
18808
18808
|
const controller = new AbortController();
|
|
18809
18809
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
18810
18810
|
try {
|
|
@@ -19697,6 +19697,7 @@ __export(index_exports, {
|
|
|
19697
19697
|
COMMON_SEARCH_PATHS: () => COMMON_SEARCH_PATHS,
|
|
19698
19698
|
CURSOR_MODEL_OPTIONS: () => CURSOR_MODEL_OPTIONS,
|
|
19699
19699
|
CUSTOM_STEPS_FILE: () => CUSTOM_STEPS_FILE,
|
|
19700
|
+
ChannelMessenger: () => ChannelMessenger,
|
|
19700
19701
|
ClaudeModels: () => ClaudeModels,
|
|
19701
19702
|
CodexModels: () => CodexModels,
|
|
19702
19703
|
ConsensusEngine: () => ConsensusEngine,
|
|
@@ -19726,24 +19727,33 @@ __export(index_exports, {
|
|
|
19726
19727
|
ShadowManager: () => ShadowManager,
|
|
19727
19728
|
StateStore: () => StateStore,
|
|
19728
19729
|
StaticPatterns: () => StaticPatterns,
|
|
19730
|
+
StepExecutor: () => StepExecutor,
|
|
19729
19731
|
SupermemoryAdapter: () => SupermemoryAdapter,
|
|
19730
19732
|
SwarmCoordinator: () => SwarmCoordinator,
|
|
19731
19733
|
SwarmPatterns: () => SwarmPatterns,
|
|
19732
19734
|
TemplateRegistry: () => TemplateRegistry,
|
|
19735
|
+
TemplateResolver: () => TemplateResolver,
|
|
19733
19736
|
TracedError: () => TracedError,
|
|
19734
19737
|
WorkflowBuilder: () => WorkflowBuilder,
|
|
19738
|
+
WorkflowCompletionError: () => WorkflowCompletionError,
|
|
19735
19739
|
WorkflowRunner: () => WorkflowRunner,
|
|
19740
|
+
WorkflowStepLifecycleExecutor: () => StepExecutor,
|
|
19736
19741
|
WorkflowTrajectory: () => WorkflowTrajectory,
|
|
19737
19742
|
benchmarkPatterns: () => benchmarkPatterns,
|
|
19738
19743
|
brokerLog: () => brokerLog,
|
|
19739
19744
|
buildBlockReason: () => buildBlockReason,
|
|
19745
|
+
buildCommand: () => buildCommand,
|
|
19740
19746
|
buildModelSwitchCommand: () => buildModelSwitchCommand,
|
|
19747
|
+
checkExitCode: () => checkExitCode,
|
|
19748
|
+
checkFileExists: () => checkFileExists,
|
|
19741
19749
|
checkForUpdates: () => checkForUpdates,
|
|
19742
19750
|
checkForUpdatesInBackground: () => checkForUpdatesInBackground,
|
|
19751
|
+
checkOutputContains: () => checkOutputContains,
|
|
19743
19752
|
cleanLines: () => cleanLines,
|
|
19744
19753
|
clearBinaryCache: () => clearBinaryCache,
|
|
19745
19754
|
clearResolveCache: () => clearResolveCache,
|
|
19746
19755
|
collectCliSession: () => collectCliSession,
|
|
19756
|
+
collectOutput: () => collectOutput,
|
|
19747
19757
|
commandExists: () => commandExists,
|
|
19748
19758
|
connectionLog: () => connectionLog,
|
|
19749
19759
|
countMessages: () => countMessages,
|
|
@@ -19755,12 +19765,14 @@ __export(index_exports, {
|
|
|
19755
19765
|
createMemoryAdapter: () => createMemoryAdapter,
|
|
19756
19766
|
createMemoryHooks: () => createMemoryHooks,
|
|
19757
19767
|
createMemoryService: () => createMemoryService,
|
|
19768
|
+
createProcessSpawner: () => createProcessSpawner,
|
|
19758
19769
|
createRequestEnvelope: () => createRequestEnvelope,
|
|
19759
19770
|
createRequestHandler: () => createRequestHandler,
|
|
19760
19771
|
createTraceableError: () => createTraceableError,
|
|
19761
19772
|
createTrajectoryHooks: () => createTrajectoryHooks,
|
|
19762
19773
|
createWorkflowRenderer: () => createWorkflowRenderer,
|
|
19763
19774
|
customStepsFileExists: () => customStepsFileExists,
|
|
19775
|
+
detectCompletion: () => detectCompletion,
|
|
19764
19776
|
estimateContextTokens: () => estimateContextTokens,
|
|
19765
19777
|
estimateTokens: () => estimateTokens,
|
|
19766
19778
|
executeApiStep: () => executeApiStep,
|
|
@@ -19768,10 +19780,12 @@ __export(index_exports, {
|
|
|
19768
19780
|
findRelayPtyBinary: () => findRelayPtyBinary,
|
|
19769
19781
|
followLogs: () => followLogs,
|
|
19770
19782
|
formatDryRunReport: () => formatDryRunReport,
|
|
19783
|
+
formatError: () => formatError2,
|
|
19771
19784
|
formatMessagePreview: () => formatMessagePreview,
|
|
19772
19785
|
formatProposalMessage: () => formatProposalMessage,
|
|
19773
19786
|
formatResultMessage: () => formatResultMessage,
|
|
19774
19787
|
formatRunSummaryTable: () => formatRunSummaryTable,
|
|
19788
|
+
formatStepOutput: () => formatStepOutput,
|
|
19775
19789
|
generateAgentName: () => generateAgentName,
|
|
19776
19790
|
generateErrorId: () => generateErrorId,
|
|
19777
19791
|
generateRequestId: () => generateRequestId,
|
|
@@ -19801,6 +19815,7 @@ __export(index_exports, {
|
|
|
19801
19815
|
hasRelayPtyBinary: () => hasRelayPtyBinary,
|
|
19802
19816
|
hasUnreadMessages: () => hasUnreadMessages,
|
|
19803
19817
|
inboxExists: () => inboxExists,
|
|
19818
|
+
interpolateStepTask: () => interpolateStepTask,
|
|
19804
19819
|
isAgentStep: () => isAgentStep,
|
|
19805
19820
|
isConsensusCommand: () => isConsensusCommand,
|
|
19806
19821
|
isCustomStep: () => isCustomStep,
|
|
@@ -19833,15 +19848,28 @@ __export(index_exports, {
|
|
|
19833
19848
|
resolveCliSync: () => resolveCliSync,
|
|
19834
19849
|
resolveCommand: () => resolveCommand,
|
|
19835
19850
|
resolveCustomStep: () => resolveCustomStep,
|
|
19851
|
+
resolveDotPath: () => resolveDotPath,
|
|
19836
19852
|
resolveSpawnPolicy: () => resolveSpawnPolicy,
|
|
19853
|
+
resolveStepOutputRef: () => resolveStepOutputRef,
|
|
19854
|
+
resolveTemplate: () => resolveTemplate,
|
|
19855
|
+
resolveTemplateForShell: () => resolveTemplateForShell,
|
|
19856
|
+
resolveVariables: () => resolveVariables,
|
|
19837
19857
|
routerLog: () => routerLog,
|
|
19858
|
+
runVerification: () => runVerification,
|
|
19838
19859
|
runWorkflow: () => runWorkflow,
|
|
19860
|
+
scrubForChannel: () => scrubForChannel,
|
|
19861
|
+
scrubSecrets: () => scrubSecrets,
|
|
19862
|
+
sendToChannel: () => sendToChannel,
|
|
19863
|
+
shellEscape: () => shellEscape,
|
|
19839
19864
|
spawnFromEnv: () => spawnFromEnv,
|
|
19865
|
+
spawnProcess: () => spawnProcess,
|
|
19840
19866
|
stripAnsi: () => stripAnsi,
|
|
19841
19867
|
stripAnsiFast: () => stripAnsiFast,
|
|
19868
|
+
stripInjectedTaskEcho: () => stripInjectedTaskEcho,
|
|
19842
19869
|
toReleaseResult: () => toReleaseResult,
|
|
19843
19870
|
toSpawnResult: () => toSpawnResult,
|
|
19844
19871
|
trackPatternPerformance: () => trackPatternPerformance,
|
|
19872
|
+
truncateMessage: () => truncateMessage,
|
|
19845
19873
|
unescapeFenceMarkersFast: () => unescapeFenceMarkersFast,
|
|
19846
19874
|
validateCustomStepsUsage: () => validateCustomStepsUsage,
|
|
19847
19875
|
validateModelForCli: () => validateModelForCli,
|
|
@@ -19902,7 +19930,7 @@ var BrokerTransport = class {
|
|
|
19902
19930
|
return this.baseUrl.replace(/^http/, "ws") + "/ws";
|
|
19903
19931
|
}
|
|
19904
19932
|
// ── HTTP ─────────────────────────────────────────────────────────────
|
|
19905
|
-
async request(
|
|
19933
|
+
async request(path19, init) {
|
|
19906
19934
|
const headers = new Headers(init?.headers);
|
|
19907
19935
|
if (!headers.has("Content-Type")) {
|
|
19908
19936
|
headers.set("Content-Type", "application/json");
|
|
@@ -19911,7 +19939,7 @@ var BrokerTransport = class {
|
|
|
19911
19939
|
headers.set("X-API-Key", this.apiKey);
|
|
19912
19940
|
}
|
|
19913
19941
|
const signal = init?.signal ?? AbortSignal.timeout(this.requestTimeoutMs);
|
|
19914
|
-
const res = await fetch(`${this.baseUrl}${
|
|
19942
|
+
const res = await fetch(`${this.baseUrl}${path19}`, { ...init, headers, signal });
|
|
19915
19943
|
if (!res.ok) {
|
|
19916
19944
|
let body;
|
|
19917
19945
|
try {
|
|
@@ -20040,38 +20068,122 @@ var import_node_child_process = require("node:child_process");
|
|
|
20040
20068
|
var import_node_module = require("node:module");
|
|
20041
20069
|
var import_node_url = require("node:url");
|
|
20042
20070
|
var BROKER_NAME = "agent-relay-broker";
|
|
20043
|
-
function
|
|
20044
|
-
|
|
20071
|
+
function addUniquePath(paths, candidate) {
|
|
20072
|
+
if (!candidate || paths.includes(candidate)) {
|
|
20073
|
+
return;
|
|
20074
|
+
}
|
|
20075
|
+
paths.push(candidate);
|
|
20076
|
+
}
|
|
20077
|
+
function getImportMetaUrl() {
|
|
20045
20078
|
try {
|
|
20046
|
-
|
|
20047
|
-
const sdkEntry = esmRequire.resolve("@agent-relay/sdk");
|
|
20048
|
-
binDir = (0, import_node_path.join)((0, import_node_path.dirname)(sdkEntry), "..", "bin");
|
|
20079
|
+
return import_meta_url;
|
|
20049
20080
|
} catch {
|
|
20081
|
+
return null;
|
|
20082
|
+
}
|
|
20083
|
+
}
|
|
20084
|
+
function getCurrentModuleDir() {
|
|
20085
|
+
if (typeof __dirname === "string" && __dirname) {
|
|
20086
|
+
return __dirname;
|
|
20087
|
+
}
|
|
20088
|
+
if (typeof __filename === "string" && __filename) {
|
|
20089
|
+
return (0, import_node_path.dirname)(__filename);
|
|
20090
|
+
}
|
|
20091
|
+
const importMetaUrl = getImportMetaUrl();
|
|
20092
|
+
if (!importMetaUrl) {
|
|
20093
|
+
return null;
|
|
20094
|
+
}
|
|
20095
|
+
try {
|
|
20096
|
+
return (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(importMetaUrl));
|
|
20097
|
+
} catch {
|
|
20098
|
+
return null;
|
|
20099
|
+
}
|
|
20100
|
+
}
|
|
20101
|
+
function getCurrentModuleReference() {
|
|
20102
|
+
if (typeof __filename === "string" && __filename) {
|
|
20103
|
+
return __filename;
|
|
20104
|
+
}
|
|
20105
|
+
if (typeof __dirname === "string" && __dirname) {
|
|
20106
|
+
return (0, import_node_path.join)(__dirname, "broker-path.js");
|
|
20107
|
+
}
|
|
20108
|
+
return getImportMetaUrl();
|
|
20109
|
+
}
|
|
20110
|
+
function getSdkBinDirs() {
|
|
20111
|
+
const binDirs = [];
|
|
20112
|
+
const currentModuleDir = getCurrentModuleDir();
|
|
20113
|
+
if (currentModuleDir) {
|
|
20114
|
+
addUniquePath(binDirs, (0, import_node_path.resolve)(currentModuleDir, "..", "bin"));
|
|
20115
|
+
}
|
|
20116
|
+
const currentModuleReference = getCurrentModuleReference();
|
|
20117
|
+
if (currentModuleReference) {
|
|
20050
20118
|
try {
|
|
20051
|
-
|
|
20119
|
+
const sdkEntry = (0, import_node_module.createRequire)(currentModuleReference).resolve("@agent-relay/sdk");
|
|
20120
|
+
addUniquePath(binDirs, (0, import_node_path.resolve)((0, import_node_path.dirname)(sdkEntry), "..", "bin"));
|
|
20052
20121
|
} catch {
|
|
20053
20122
|
}
|
|
20054
20123
|
}
|
|
20055
|
-
|
|
20056
|
-
|
|
20057
|
-
|
|
20058
|
-
|
|
20059
|
-
|
|
20060
|
-
|
|
20124
|
+
const importMetaUrl = getImportMetaUrl();
|
|
20125
|
+
if (importMetaUrl) {
|
|
20126
|
+
try {
|
|
20127
|
+
addUniquePath(binDirs, (0, import_node_path.resolve)((0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(importMetaUrl)), "..", "bin"));
|
|
20128
|
+
} catch {
|
|
20129
|
+
}
|
|
20130
|
+
}
|
|
20131
|
+
return binDirs;
|
|
20132
|
+
}
|
|
20133
|
+
function getDevelopmentBinaryPaths(ext, binDirs) {
|
|
20134
|
+
const binaryPaths = [];
|
|
20135
|
+
const repoRoots = /* @__PURE__ */ new Set();
|
|
20136
|
+
const addRepoRoot = (candidate) => {
|
|
20137
|
+
if (!candidate) {
|
|
20138
|
+
return;
|
|
20139
|
+
}
|
|
20140
|
+
const repoRoot = (0, import_node_path.resolve)(candidate);
|
|
20141
|
+
if (repoRoots.has(repoRoot)) {
|
|
20142
|
+
return;
|
|
20143
|
+
}
|
|
20144
|
+
repoRoots.add(repoRoot);
|
|
20145
|
+
addUniquePath(binaryPaths, (0, import_node_path.join)(repoRoot, "target", "release", `${BROKER_NAME}${ext}`));
|
|
20146
|
+
addUniquePath(binaryPaths, (0, import_node_path.join)(repoRoot, "target", "debug", `${BROKER_NAME}${ext}`));
|
|
20147
|
+
};
|
|
20148
|
+
addRepoRoot(process.cwd());
|
|
20149
|
+
const currentModuleDir = getCurrentModuleDir();
|
|
20150
|
+
if (currentModuleDir) {
|
|
20151
|
+
addRepoRoot((0, import_node_path.resolve)(currentModuleDir, "..", "..", ".."));
|
|
20152
|
+
}
|
|
20153
|
+
for (const binDir of binDirs) {
|
|
20154
|
+
addRepoRoot((0, import_node_path.resolve)(binDir, "..", "..", ".."));
|
|
20061
20155
|
}
|
|
20156
|
+
return binaryPaths;
|
|
20157
|
+
}
|
|
20158
|
+
function getBrokerBinaryPath() {
|
|
20159
|
+
const ext = process.platform === "win32" ? ".exe" : "";
|
|
20160
|
+
const binDirs = getSdkBinDirs();
|
|
20062
20161
|
const platformSpecific = `${BROKER_NAME}-${process.platform}-${process.arch}${ext}`;
|
|
20063
|
-
const
|
|
20064
|
-
|
|
20065
|
-
|
|
20162
|
+
for (const binDir of binDirs) {
|
|
20163
|
+
const exactPath = (0, import_node_path.join)(binDir, `${BROKER_NAME}${ext}`);
|
|
20164
|
+
if ((0, import_node_fs.existsSync)(exactPath)) {
|
|
20165
|
+
return exactPath;
|
|
20166
|
+
}
|
|
20167
|
+
}
|
|
20168
|
+
for (const binDir of binDirs) {
|
|
20169
|
+
const platformPath = (0, import_node_path.join)(binDir, platformSpecific);
|
|
20170
|
+
if ((0, import_node_fs.existsSync)(platformPath)) {
|
|
20171
|
+
return platformPath;
|
|
20172
|
+
}
|
|
20173
|
+
}
|
|
20174
|
+
for (const developmentPath of getDevelopmentBinaryPaths(ext, binDirs)) {
|
|
20175
|
+
if ((0, import_node_fs.existsSync)(developmentPath)) {
|
|
20176
|
+
return developmentPath;
|
|
20177
|
+
}
|
|
20066
20178
|
}
|
|
20067
20179
|
try {
|
|
20068
20180
|
const cmd = process.platform === "win32" ? "where" : "which";
|
|
20069
|
-
const result = (0, import_node_child_process.
|
|
20181
|
+
const result = (0, import_node_child_process.execFileSync)(cmd, [BROKER_NAME], {
|
|
20070
20182
|
encoding: "utf-8",
|
|
20071
20183
|
stdio: ["pipe", "pipe", "pipe"]
|
|
20072
20184
|
}).trim();
|
|
20073
20185
|
if (result) {
|
|
20074
|
-
return result.split(
|
|
20186
|
+
return result.split(/\r?\n/u)[0].trim();
|
|
20075
20187
|
}
|
|
20076
20188
|
} catch {
|
|
20077
20189
|
}
|
|
@@ -20096,6 +20208,25 @@ function isProcessRunning(pid) {
|
|
|
20096
20208
|
return error48.code === "EPERM";
|
|
20097
20209
|
}
|
|
20098
20210
|
}
|
|
20211
|
+
function buildBrokerInitArgs(args) {
|
|
20212
|
+
if (!args) {
|
|
20213
|
+
return [];
|
|
20214
|
+
}
|
|
20215
|
+
const cliArgs = [];
|
|
20216
|
+
if (args.persist) {
|
|
20217
|
+
cliArgs.push("--persist");
|
|
20218
|
+
}
|
|
20219
|
+
if (args.apiPort !== void 0) {
|
|
20220
|
+
cliArgs.push("--api-port", String(args.apiPort));
|
|
20221
|
+
}
|
|
20222
|
+
if (args.apiBind !== void 0) {
|
|
20223
|
+
cliArgs.push("--api-bind", args.apiBind);
|
|
20224
|
+
}
|
|
20225
|
+
if (args.stateDir !== void 0) {
|
|
20226
|
+
cliArgs.push("--state-dir", args.stateDir);
|
|
20227
|
+
}
|
|
20228
|
+
return cliArgs;
|
|
20229
|
+
}
|
|
20099
20230
|
var AgentRelayClient = class _AgentRelayClient {
|
|
20100
20231
|
transport;
|
|
20101
20232
|
/** Set after spawn() — the managed child process. */
|
|
@@ -20157,7 +20288,7 @@ var AgentRelayClient = class _AgentRelayClient {
|
|
|
20157
20288
|
const brokerName = options?.brokerName ?? (import_node_path2.default.basename(cwd) || "project");
|
|
20158
20289
|
const channels = options?.channels ?? ["general"];
|
|
20159
20290
|
const timeoutMs = options?.startupTimeoutMs ?? 15e3;
|
|
20160
|
-
const userArgs = options?.binaryArgs
|
|
20291
|
+
const userArgs = buildBrokerInitArgs(options?.binaryArgs);
|
|
20161
20292
|
const apiKey = `br_${(0, import_node_crypto.randomBytes)(16).toString("hex")}`;
|
|
20162
20293
|
const env = {
|
|
20163
20294
|
...process.env,
|
|
@@ -20408,7 +20539,7 @@ var AgentRelayClient = class _AgentRelayClient {
|
|
|
20408
20539
|
};
|
|
20409
20540
|
async function waitForApiUrl(child, timeoutMs) {
|
|
20410
20541
|
const { createInterface: createInterface2 } = await import("node:readline");
|
|
20411
|
-
return new Promise((
|
|
20542
|
+
return new Promise((resolve4, reject) => {
|
|
20412
20543
|
if (!child.stdout) {
|
|
20413
20544
|
reject(new Error("Broker stdout not available"));
|
|
20414
20545
|
return;
|
|
@@ -20446,24 +20577,24 @@ async function waitForApiUrl(child, timeoutMs) {
|
|
|
20446
20577
|
resolved = true;
|
|
20447
20578
|
clearTimeout(timer);
|
|
20448
20579
|
rl.close();
|
|
20449
|
-
|
|
20580
|
+
resolve4(match[1]);
|
|
20450
20581
|
}
|
|
20451
20582
|
});
|
|
20452
20583
|
});
|
|
20453
20584
|
}
|
|
20454
20585
|
function waitForExit(child, timeoutMs) {
|
|
20455
|
-
return new Promise((
|
|
20586
|
+
return new Promise((resolve4) => {
|
|
20456
20587
|
if (child.exitCode !== null) {
|
|
20457
|
-
|
|
20588
|
+
resolve4();
|
|
20458
20589
|
return;
|
|
20459
20590
|
}
|
|
20460
20591
|
const timer = setTimeout(() => {
|
|
20461
20592
|
child.kill("SIGKILL");
|
|
20462
|
-
|
|
20593
|
+
resolve4();
|
|
20463
20594
|
}, timeoutMs);
|
|
20464
20595
|
child.on("exit", () => {
|
|
20465
20596
|
clearTimeout(timer);
|
|
20466
|
-
|
|
20597
|
+
resolve4();
|
|
20467
20598
|
});
|
|
20468
20599
|
});
|
|
20469
20600
|
}
|
|
@@ -20984,8 +21115,8 @@ function getErrorMap() {
|
|
|
20984
21115
|
|
|
20985
21116
|
// node_modules/zod/v3/helpers/parseUtil.js
|
|
20986
21117
|
var makeIssue = (params) => {
|
|
20987
|
-
const { data, path:
|
|
20988
|
-
const fullPath = [...
|
|
21118
|
+
const { data, path: path19, errorMaps, issueData } = params;
|
|
21119
|
+
const fullPath = [...path19, ...issueData.path || []];
|
|
20989
21120
|
const fullIssue = {
|
|
20990
21121
|
...issueData,
|
|
20991
21122
|
path: fullPath
|
|
@@ -21101,11 +21232,11 @@ var errorUtil;
|
|
|
21101
21232
|
|
|
21102
21233
|
// node_modules/zod/v3/types.js
|
|
21103
21234
|
var ParseInputLazyPath = class {
|
|
21104
|
-
constructor(parent, value,
|
|
21235
|
+
constructor(parent, value, path19, key) {
|
|
21105
21236
|
this._cachedPath = [];
|
|
21106
21237
|
this.parent = parent;
|
|
21107
21238
|
this.data = value;
|
|
21108
|
-
this._path =
|
|
21239
|
+
this._path = path19;
|
|
21109
21240
|
this._key = key;
|
|
21110
21241
|
}
|
|
21111
21242
|
get path() {
|
|
@@ -27416,10 +27547,10 @@ function mergeDefs(...defs) {
|
|
|
27416
27547
|
function cloneDef(schema) {
|
|
27417
27548
|
return mergeDefs(schema._zod.def);
|
|
27418
27549
|
}
|
|
27419
|
-
function getElementAtPath(obj,
|
|
27420
|
-
if (!
|
|
27550
|
+
function getElementAtPath(obj, path19) {
|
|
27551
|
+
if (!path19)
|
|
27421
27552
|
return obj;
|
|
27422
|
-
return
|
|
27553
|
+
return path19.reduce((acc, key) => acc?.[key], obj);
|
|
27423
27554
|
}
|
|
27424
27555
|
function promiseAllObject(promisesObj) {
|
|
27425
27556
|
const keys = Object.keys(promisesObj);
|
|
@@ -27802,11 +27933,11 @@ function aborted(x, startIndex = 0) {
|
|
|
27802
27933
|
}
|
|
27803
27934
|
return false;
|
|
27804
27935
|
}
|
|
27805
|
-
function prefixIssues(
|
|
27936
|
+
function prefixIssues(path19, issues) {
|
|
27806
27937
|
return issues.map((iss) => {
|
|
27807
27938
|
var _a2;
|
|
27808
27939
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
27809
|
-
iss.path.unshift(
|
|
27940
|
+
iss.path.unshift(path19);
|
|
27810
27941
|
return iss;
|
|
27811
27942
|
});
|
|
27812
27943
|
}
|
|
@@ -27989,7 +28120,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
|
|
|
27989
28120
|
}
|
|
27990
28121
|
function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
27991
28122
|
const result = { errors: [] };
|
|
27992
|
-
const processError = (error49,
|
|
28123
|
+
const processError = (error49, path19 = []) => {
|
|
27993
28124
|
var _a2, _b;
|
|
27994
28125
|
for (const issue2 of error49.issues) {
|
|
27995
28126
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -27999,7 +28130,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
|
27999
28130
|
} else if (issue2.code === "invalid_element") {
|
|
28000
28131
|
processError({ issues: issue2.issues }, issue2.path);
|
|
28001
28132
|
} else {
|
|
28002
|
-
const fullpath = [...
|
|
28133
|
+
const fullpath = [...path19, ...issue2.path];
|
|
28003
28134
|
if (fullpath.length === 0) {
|
|
28004
28135
|
result.errors.push(mapper(issue2));
|
|
28005
28136
|
continue;
|
|
@@ -28031,8 +28162,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
|
28031
28162
|
}
|
|
28032
28163
|
function toDotPath(_path) {
|
|
28033
28164
|
const segs = [];
|
|
28034
|
-
const
|
|
28035
|
-
for (const seg of
|
|
28165
|
+
const path19 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
28166
|
+
for (const seg of path19) {
|
|
28036
28167
|
if (typeof seg === "number")
|
|
28037
28168
|
segs.push(`[${seg}]`);
|
|
28038
28169
|
else if (typeof seg === "symbol")
|
|
@@ -40009,13 +40140,13 @@ function resolveRef(ref, ctx) {
|
|
|
40009
40140
|
if (!ref.startsWith("#")) {
|
|
40010
40141
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
40011
40142
|
}
|
|
40012
|
-
const
|
|
40013
|
-
if (
|
|
40143
|
+
const path19 = ref.slice(1).split("/").filter(Boolean);
|
|
40144
|
+
if (path19.length === 0) {
|
|
40014
40145
|
return ctx.rootSchema;
|
|
40015
40146
|
}
|
|
40016
40147
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
40017
|
-
if (
|
|
40018
|
-
const key =
|
|
40148
|
+
if (path19[0] === defsKey) {
|
|
40149
|
+
const key = path19[1];
|
|
40019
40150
|
if (!key || !ctx.defs[key]) {
|
|
40020
40151
|
throw new Error(`Reference not found: ${ref}`);
|
|
40021
40152
|
}
|
|
@@ -41660,11 +41791,11 @@ var WsClient = class {
|
|
|
41660
41791
|
this.reconnectAttempt += 1;
|
|
41661
41792
|
const reconnectingEvent = { type: "reconnecting", attempt: this.reconnectAttempt };
|
|
41662
41793
|
this.emit("reconnecting", reconnectingEvent);
|
|
41663
|
-
const
|
|
41794
|
+
const delay3 = this.computeReconnectDelayMs(this.reconnectAttempt);
|
|
41664
41795
|
this.reconnectTimer = setTimeout(() => {
|
|
41665
41796
|
this.reconnectTimer = null;
|
|
41666
41797
|
this.connect();
|
|
41667
|
-
},
|
|
41798
|
+
}, delay3);
|
|
41668
41799
|
}
|
|
41669
41800
|
};
|
|
41670
41801
|
|
|
@@ -42074,7 +42205,7 @@ function withInternalOrigin(options, origin) {
|
|
|
42074
42205
|
return copy;
|
|
42075
42206
|
}
|
|
42076
42207
|
function sleep(ms) {
|
|
42077
|
-
return new Promise((
|
|
42208
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
42078
42209
|
}
|
|
42079
42210
|
var DEFAULT_RETRY_POLICY = {
|
|
42080
42211
|
maxRetries: 3,
|
|
@@ -42165,8 +42296,8 @@ var HttpClient = class _HttpClient {
|
|
|
42165
42296
|
version: this._originVersion
|
|
42166
42297
|
}));
|
|
42167
42298
|
}
|
|
42168
|
-
async request(method,
|
|
42169
|
-
const url2 = new URL(
|
|
42299
|
+
async request(method, path19, body, query, options) {
|
|
42300
|
+
const url2 = new URL(path19, this._baseUrl);
|
|
42170
42301
|
if (query) {
|
|
42171
42302
|
for (const [k, v] of Object.entries(query)) {
|
|
42172
42303
|
if (v !== void 0)
|
|
@@ -42236,20 +42367,20 @@ var HttpClient = class _HttpClient {
|
|
|
42236
42367
|
return camelizeKeys(parsedData);
|
|
42237
42368
|
}
|
|
42238
42369
|
}
|
|
42239
|
-
get(
|
|
42240
|
-
return this.request("GET",
|
|
42370
|
+
get(path19, query, options) {
|
|
42371
|
+
return this.request("GET", path19, void 0, query, options);
|
|
42241
42372
|
}
|
|
42242
|
-
post(
|
|
42243
|
-
return this.request("POST",
|
|
42373
|
+
post(path19, body, options) {
|
|
42374
|
+
return this.request("POST", path19, body, void 0, options);
|
|
42244
42375
|
}
|
|
42245
|
-
patch(
|
|
42246
|
-
return this.request("PATCH",
|
|
42376
|
+
patch(path19, body, options) {
|
|
42377
|
+
return this.request("PATCH", path19, body, void 0, options);
|
|
42247
42378
|
}
|
|
42248
|
-
put(
|
|
42249
|
-
return this.request("PUT",
|
|
42379
|
+
put(path19, body, options) {
|
|
42380
|
+
return this.request("PUT", path19, body, void 0, options);
|
|
42250
42381
|
}
|
|
42251
|
-
async delete(
|
|
42252
|
-
await this.request("DELETE",
|
|
42382
|
+
async delete(path19, options) {
|
|
42383
|
+
await this.request("DELETE", path19, void 0, void 0, options);
|
|
42253
42384
|
}
|
|
42254
42385
|
};
|
|
42255
42386
|
|
|
@@ -43162,7 +43293,7 @@ var AgentRelay = class {
|
|
|
43162
43293
|
if (!result.targets.length) {
|
|
43163
43294
|
return { eventId: result.event_id, status: "failed", targets: [] };
|
|
43164
43295
|
}
|
|
43165
|
-
return new Promise((
|
|
43296
|
+
return new Promise((resolve4) => {
|
|
43166
43297
|
let resolved = false;
|
|
43167
43298
|
const ackedTargets = /* @__PURE__ */ new Set();
|
|
43168
43299
|
let unsubscribe;
|
|
@@ -43170,7 +43301,7 @@ var AgentRelay = class {
|
|
|
43170
43301
|
if (!resolved) {
|
|
43171
43302
|
resolved = true;
|
|
43172
43303
|
unsubscribe?.();
|
|
43173
|
-
|
|
43304
|
+
resolve4({ eventId: result.event_id, status: "timeout", targets: result.targets });
|
|
43174
43305
|
}
|
|
43175
43306
|
}, timeoutMs);
|
|
43176
43307
|
unsubscribe = client.onEvent((event) => {
|
|
@@ -43182,14 +43313,14 @@ var AgentRelay = class {
|
|
|
43182
43313
|
resolved = true;
|
|
43183
43314
|
clearTimeout(timer);
|
|
43184
43315
|
unsubscribe?.();
|
|
43185
|
-
|
|
43316
|
+
resolve4({ eventId: result.event_id, status: "ack", targets: result.targets });
|
|
43186
43317
|
}
|
|
43187
43318
|
}
|
|
43188
43319
|
if (event.kind === "delivery_failed" && event.event_id === result.event_id && result.targets.includes(event.name)) {
|
|
43189
43320
|
resolved = true;
|
|
43190
43321
|
clearTimeout(timer);
|
|
43191
43322
|
unsubscribe?.();
|
|
43192
|
-
|
|
43323
|
+
resolve4({ eventId: result.event_id, status: "failed", targets: result.targets });
|
|
43193
43324
|
}
|
|
43194
43325
|
});
|
|
43195
43326
|
});
|
|
@@ -43308,7 +43439,7 @@ var AgentRelay = class {
|
|
|
43308
43439
|
if (existing && this.readyAgents.has(name)) {
|
|
43309
43440
|
return existing;
|
|
43310
43441
|
}
|
|
43311
|
-
return new Promise((
|
|
43442
|
+
return new Promise((resolve4, reject) => {
|
|
43312
43443
|
let settled = false;
|
|
43313
43444
|
let timeout;
|
|
43314
43445
|
const cleanup = () => {
|
|
@@ -43323,7 +43454,7 @@ var AgentRelay = class {
|
|
|
43323
43454
|
return;
|
|
43324
43455
|
settled = true;
|
|
43325
43456
|
cleanup();
|
|
43326
|
-
|
|
43457
|
+
resolve4(agent);
|
|
43327
43458
|
};
|
|
43328
43459
|
const rejectWith = (error48) => {
|
|
43329
43460
|
if (settled)
|
|
@@ -43356,7 +43487,7 @@ var AgentRelay = class {
|
|
|
43356
43487
|
if (existing && this.messageReadyAgents.has(name)) {
|
|
43357
43488
|
return existing;
|
|
43358
43489
|
}
|
|
43359
|
-
return new Promise((
|
|
43490
|
+
return new Promise((resolve4, reject) => {
|
|
43360
43491
|
let settled = false;
|
|
43361
43492
|
let timeout;
|
|
43362
43493
|
const cleanup = () => {
|
|
@@ -43371,7 +43502,7 @@ var AgentRelay = class {
|
|
|
43371
43502
|
return;
|
|
43372
43503
|
settled = true;
|
|
43373
43504
|
cleanup();
|
|
43374
|
-
|
|
43505
|
+
resolve4(agent);
|
|
43375
43506
|
};
|
|
43376
43507
|
const rejectWith = (error48) => {
|
|
43377
43508
|
if (settled)
|
|
@@ -43786,13 +43917,13 @@ var AgentRelay = class {
|
|
|
43786
43917
|
await relay.waitForAgentReady(name, timeoutMs);
|
|
43787
43918
|
},
|
|
43788
43919
|
waitForExit(timeoutMs) {
|
|
43789
|
-
return new Promise((
|
|
43920
|
+
return new Promise((resolve4) => {
|
|
43790
43921
|
if (!relay.knownAgents.has(name)) {
|
|
43791
|
-
|
|
43922
|
+
resolve4("exited");
|
|
43792
43923
|
return;
|
|
43793
43924
|
}
|
|
43794
43925
|
if (timeoutMs === 0) {
|
|
43795
|
-
|
|
43926
|
+
resolve4("timeout");
|
|
43796
43927
|
return;
|
|
43797
43928
|
}
|
|
43798
43929
|
let timer;
|
|
@@ -43801,7 +43932,7 @@ var AgentRelay = class {
|
|
|
43801
43932
|
resolve(reason) {
|
|
43802
43933
|
if (timer)
|
|
43803
43934
|
clearTimeout(timer);
|
|
43804
|
-
|
|
43935
|
+
resolve4(reason);
|
|
43805
43936
|
},
|
|
43806
43937
|
token
|
|
43807
43938
|
});
|
|
@@ -43811,19 +43942,19 @@ var AgentRelay = class {
|
|
|
43811
43942
|
if (current?.token === token) {
|
|
43812
43943
|
relay.exitResolvers.delete(name);
|
|
43813
43944
|
}
|
|
43814
|
-
|
|
43945
|
+
resolve4("timeout");
|
|
43815
43946
|
}, timeoutMs);
|
|
43816
43947
|
}
|
|
43817
43948
|
});
|
|
43818
43949
|
},
|
|
43819
43950
|
waitForIdle(timeoutMs) {
|
|
43820
|
-
return new Promise((
|
|
43951
|
+
return new Promise((resolve4) => {
|
|
43821
43952
|
if (!relay.knownAgents.has(name)) {
|
|
43822
|
-
|
|
43953
|
+
resolve4("exited");
|
|
43823
43954
|
return;
|
|
43824
43955
|
}
|
|
43825
43956
|
if (timeoutMs === 0) {
|
|
43826
|
-
|
|
43957
|
+
resolve4("timeout");
|
|
43827
43958
|
return;
|
|
43828
43959
|
}
|
|
43829
43960
|
let timer;
|
|
@@ -43832,7 +43963,7 @@ var AgentRelay = class {
|
|
|
43832
43963
|
resolve(reason) {
|
|
43833
43964
|
if (timer)
|
|
43834
43965
|
clearTimeout(timer);
|
|
43835
|
-
|
|
43966
|
+
resolve4(reason);
|
|
43836
43967
|
},
|
|
43837
43968
|
token
|
|
43838
43969
|
});
|
|
@@ -43842,7 +43973,7 @@ var AgentRelay = class {
|
|
|
43842
43973
|
if (current?.token === token) {
|
|
43843
43974
|
relay.idleResolvers.delete(name);
|
|
43844
43975
|
}
|
|
43845
|
-
|
|
43976
|
+
resolve4("timeout");
|
|
43846
43977
|
}, timeoutMs);
|
|
43847
43978
|
}
|
|
43848
43979
|
});
|
|
@@ -44826,12 +44957,12 @@ function isAgentStep(step) {
|
|
|
44826
44957
|
}
|
|
44827
44958
|
|
|
44828
44959
|
// packages/sdk/dist/workflows/runner.js
|
|
44829
|
-
var
|
|
44960
|
+
var import_node_child_process6 = require("node:child_process");
|
|
44830
44961
|
var import_node_crypto5 = require("node:crypto");
|
|
44831
|
-
var
|
|
44962
|
+
var import_node_fs11 = require("node:fs");
|
|
44832
44963
|
var import_promises5 = require("node:fs/promises");
|
|
44833
44964
|
var import_node_os7 = require("node:os");
|
|
44834
|
-
var
|
|
44965
|
+
var import_node_path14 = __toESM(require("node:path"), 1);
|
|
44835
44966
|
var import_chalk = __toESM(require_source(), 1);
|
|
44836
44967
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
44837
44968
|
|
|
@@ -45089,9 +45220,9 @@ async function resolveCli(cli) {
|
|
|
45089
45220
|
for (const binary of def.binaries) {
|
|
45090
45221
|
try {
|
|
45091
45222
|
const { stdout } = await execFileAsync("which", [binary]);
|
|
45092
|
-
const
|
|
45093
|
-
if (
|
|
45094
|
-
const result = { binary, path:
|
|
45223
|
+
const path19 = stdout.trim();
|
|
45224
|
+
if (path19) {
|
|
45225
|
+
const result = { binary, path: path19 };
|
|
45095
45226
|
resolveCache.set(cli, result);
|
|
45096
45227
|
return result;
|
|
45097
45228
|
}
|
|
@@ -45124,13 +45255,13 @@ function resolveCliSync(cli) {
|
|
|
45124
45255
|
const def = getCliDefinition(cli);
|
|
45125
45256
|
if (!def)
|
|
45126
45257
|
return void 0;
|
|
45127
|
-
const { execFileSync } = require("node:child_process");
|
|
45258
|
+
const { execFileSync: execFileSync2 } = require("node:child_process");
|
|
45128
45259
|
for (const binary of def.binaries) {
|
|
45129
45260
|
try {
|
|
45130
|
-
const stdout =
|
|
45131
|
-
const
|
|
45132
|
-
if (
|
|
45133
|
-
const result = { binary, path:
|
|
45261
|
+
const stdout = execFileSync2("which", [binary], { stdio: ["pipe", "pipe", "ignore"] });
|
|
45262
|
+
const path19 = stdout.toString().trim();
|
|
45263
|
+
if (path19) {
|
|
45264
|
+
const result = { binary, path: path19 };
|
|
45134
45265
|
resolveCache.set(cli, result);
|
|
45135
45266
|
return result;
|
|
45136
45267
|
}
|
|
@@ -46282,6 +46413,224 @@ async function executeApiStep(model, task, options = {}) {
|
|
|
46282
46413
|
return response.content;
|
|
46283
46414
|
}
|
|
46284
46415
|
|
|
46416
|
+
// packages/sdk/dist/workflows/channel-messenger.js
|
|
46417
|
+
async function sendToChannel(relay, channel, message) {
|
|
46418
|
+
await relay.send(channel, message);
|
|
46419
|
+
}
|
|
46420
|
+
function truncateMessage(message, maxLength) {
|
|
46421
|
+
if (maxLength <= 0)
|
|
46422
|
+
return "";
|
|
46423
|
+
return message.length > maxLength ? message.slice(-maxLength) : message;
|
|
46424
|
+
}
|
|
46425
|
+
function formatStepOutput(stepName, output, maxLength = 2e3) {
|
|
46426
|
+
const scrubbed = scrubForChannel(output);
|
|
46427
|
+
if (scrubbed.length === 0) {
|
|
46428
|
+
return `**[${stepName}]** Step completed \u2014 output written to disk`;
|
|
46429
|
+
}
|
|
46430
|
+
const preview = truncateMessage(scrubbed, maxLength);
|
|
46431
|
+
return `**[${stepName}] Output:**
|
|
46432
|
+
\`\`\`
|
|
46433
|
+
${preview}
|
|
46434
|
+
\`\`\``;
|
|
46435
|
+
}
|
|
46436
|
+
function formatError2(stepName, error48) {
|
|
46437
|
+
const raw = error48 instanceof Error ? error48.message : String(error48);
|
|
46438
|
+
const message = raw.replace(/(?:\/[\w.-]+){3,}/g, "[path]");
|
|
46439
|
+
return `**[${stepName}]** Failed: ${message}`;
|
|
46440
|
+
}
|
|
46441
|
+
var SECRET_PATTERNS = [
|
|
46442
|
+
/(?:api[_-]?key|apikey|secret[_-]?key|access[_-]?token|auth[_-]?token|bearer)\s*[:=]\s*\S+/gi,
|
|
46443
|
+
/(?:sk|pk|rk|ak)[-_][a-zA-Z0-9]{20,}/g,
|
|
46444
|
+
/ghp_[a-zA-Z0-9]{36,}/g,
|
|
46445
|
+
/gho_[a-zA-Z0-9]{36,}/g,
|
|
46446
|
+
/github_pat_[a-zA-Z0-9_]{22,}/g,
|
|
46447
|
+
/xox[bpors]-[a-zA-Z0-9-]+/g,
|
|
46448
|
+
/-----BEGIN\s+(?:RSA\s+)?PRIVATE\s+KEY-----[\s\S]*?-----END/g
|
|
46449
|
+
];
|
|
46450
|
+
var SPINNER = "\\u2756\\u2738\\u2739\\u273a\\u273b\\u273c\\u273d\\u2731\\u2732\\u2733\\u2734\\u2735\\u2736\\u2737\\u2743\\u2745\\u2746\\u25d6\\u25d7\\u25d8\\u25d9\\u2022\\u25cf\\u25cb\\u25a0\\u25a1\\u25b6\\u25c0\\u23f5\\u23f6\\u23f7\\u23f8\\u23f9\\u25e2\\u25e3\\u25e4\\u25e5\\u2597\\u2596\\u2598\\u259d\\u2bc8\\u2bc7\\u2bc5\\u2bc6\\u00b7\\u2590\\u258c\\u2588\\u2584\\u2580\\u259a\\u259e\\u2b21\\u2b22";
|
|
46451
|
+
var SPINNER_RE = new RegExp(`[${SPINNER}]`, "gu");
|
|
46452
|
+
var SPINNER_CLASS_RE = new RegExp(`^[\\s${SPINNER}]*$`, "u");
|
|
46453
|
+
var BOX_DRAWING_ONLY_RE = /^[\s\u2500-\u257f\u2580-\u259f\u25a0-\u25ff\-_=~]{3,}$/u;
|
|
46454
|
+
var BROKER_LOG_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z\s+(?:INFO|WARN|ERROR|DEBUG)\s/u;
|
|
46455
|
+
var CLAUDE_HEADER_RE = /^(?:[\s\u2580-\u259f✢*·▗▖▘▝]+\s*)?(?:Claude\s+Code(?:\s+v?[\d.]+)?|(?:Sonnet|Haiku|Opus)\s*[\d.]+|claude-(?:sonnet|haiku|opus)-[\w.-]+|Running\s+on\s+claude)/iu;
|
|
46456
|
+
var DIR_BREADCRUMB_RE = /^\s*~[\\/]/u;
|
|
46457
|
+
var UI_HINT_RE = /\b(?:Press\s+up\s+to\s+edit|tab\s+to\s+queue|bypass\s+permissions|esc\s+to\s+interrupt)\b/iu;
|
|
46458
|
+
var THINKING_LINE_RE = new RegExp(`^[\\s${SPINNER}]*\\s*\\w[\\w\\s]*\\u2026\\s*$`, "u");
|
|
46459
|
+
var CURSOR_ONLY_RE = /^[\s❯⎿›»◀▶←→↑↓⟨⟩⟪⟫·]+$/u;
|
|
46460
|
+
var CURSOR_AGENT_RE = /^(?:Cursor Agent|[\s⬡⬢]*Generating[.\s]|\[Pasted text|Auto-run all|Add a follow-up|ctrl\+c to stop|shift\+tab|Auto$|\/\s*commands|@\s*files|!\s*shell|follow-ups?\s|The user ha)/iu;
|
|
46461
|
+
var SLASH_COMMAND_RE = /^\/\w+\s*$/u;
|
|
46462
|
+
var MCP_JSON_KV_RE = /^\s*"(?:type|method|params|result|id|jsonrpc|tool|name|arguments|content|role|metadata)"\s*:/u;
|
|
46463
|
+
var MEANINGFUL_CONTENT_RE = /[a-zA-Z0-9]/u;
|
|
46464
|
+
function scrubSecrets(text) {
|
|
46465
|
+
let result = text;
|
|
46466
|
+
for (const pattern of SECRET_PATTERNS) {
|
|
46467
|
+
result = result.replace(pattern, "[REDACTED]");
|
|
46468
|
+
}
|
|
46469
|
+
return result;
|
|
46470
|
+
}
|
|
46471
|
+
function scrubForChannel(text) {
|
|
46472
|
+
let withoutSystemReminders = text;
|
|
46473
|
+
const openTag = "<system-reminder>";
|
|
46474
|
+
const closeTag = "</system-reminder>";
|
|
46475
|
+
let idx;
|
|
46476
|
+
while ((idx = withoutSystemReminders.toLowerCase().indexOf(openTag)) !== -1) {
|
|
46477
|
+
const closeIdx = withoutSystemReminders.toLowerCase().indexOf(closeTag, idx + openTag.length);
|
|
46478
|
+
if (closeIdx !== -1) {
|
|
46479
|
+
withoutSystemReminders = withoutSystemReminders.slice(0, idx) + withoutSystemReminders.slice(closeIdx + closeTag.length);
|
|
46480
|
+
} else {
|
|
46481
|
+
withoutSystemReminders = withoutSystemReminders.slice(0, idx);
|
|
46482
|
+
break;
|
|
46483
|
+
}
|
|
46484
|
+
}
|
|
46485
|
+
const normalized = withoutSystemReminders.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
46486
|
+
const ansiStripped = stripAnsi(normalized);
|
|
46487
|
+
const secretsRedacted = scrubSecrets(ansiStripped);
|
|
46488
|
+
const countJsonDepth = (line) => {
|
|
46489
|
+
let depth = 0;
|
|
46490
|
+
for (const ch of line) {
|
|
46491
|
+
if (ch === "{" || ch === "[")
|
|
46492
|
+
depth += 1;
|
|
46493
|
+
if (ch === "}" || ch === "]")
|
|
46494
|
+
depth -= 1;
|
|
46495
|
+
}
|
|
46496
|
+
return depth;
|
|
46497
|
+
};
|
|
46498
|
+
const lines = secretsRedacted.split("\n");
|
|
46499
|
+
const meaningful = [];
|
|
46500
|
+
let jsonDepth = 0;
|
|
46501
|
+
for (const line of lines) {
|
|
46502
|
+
const trimmed = line.trim();
|
|
46503
|
+
if (jsonDepth > 0) {
|
|
46504
|
+
jsonDepth += countJsonDepth(line);
|
|
46505
|
+
if (jsonDepth <= 0)
|
|
46506
|
+
jsonDepth = 0;
|
|
46507
|
+
continue;
|
|
46508
|
+
}
|
|
46509
|
+
if (trimmed.length === 0)
|
|
46510
|
+
continue;
|
|
46511
|
+
if (trimmed.startsWith("{") || /^\[\s*\{/.test(trimmed)) {
|
|
46512
|
+
jsonDepth = Math.max(countJsonDepth(line), 0);
|
|
46513
|
+
continue;
|
|
46514
|
+
}
|
|
46515
|
+
if (MCP_JSON_KV_RE.test(line))
|
|
46516
|
+
continue;
|
|
46517
|
+
if (SPINNER_CLASS_RE.test(trimmed))
|
|
46518
|
+
continue;
|
|
46519
|
+
if (BOX_DRAWING_ONLY_RE.test(trimmed))
|
|
46520
|
+
continue;
|
|
46521
|
+
if (BROKER_LOG_RE.test(trimmed))
|
|
46522
|
+
continue;
|
|
46523
|
+
if (CLAUDE_HEADER_RE.test(trimmed))
|
|
46524
|
+
continue;
|
|
46525
|
+
if (DIR_BREADCRUMB_RE.test(trimmed))
|
|
46526
|
+
continue;
|
|
46527
|
+
if (UI_HINT_RE.test(trimmed))
|
|
46528
|
+
continue;
|
|
46529
|
+
if (THINKING_LINE_RE.test(trimmed))
|
|
46530
|
+
continue;
|
|
46531
|
+
if (CURSOR_ONLY_RE.test(trimmed))
|
|
46532
|
+
continue;
|
|
46533
|
+
if (CURSOR_AGENT_RE.test(trimmed))
|
|
46534
|
+
continue;
|
|
46535
|
+
if (SLASH_COMMAND_RE.test(trimmed))
|
|
46536
|
+
continue;
|
|
46537
|
+
if (!MEANINGFUL_CONTENT_RE.test(trimmed))
|
|
46538
|
+
continue;
|
|
46539
|
+
const alphanum = trimmed.replace(SPINNER_RE, "").replace(/\s+/g, "");
|
|
46540
|
+
if (alphanum.replace(/[^a-zA-Z0-9]/g, "").length <= 3)
|
|
46541
|
+
continue;
|
|
46542
|
+
meaningful.push(line);
|
|
46543
|
+
}
|
|
46544
|
+
return meaningful.join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
46545
|
+
}
|
|
46546
|
+
var ChannelMessenger = class {
|
|
46547
|
+
postFn;
|
|
46548
|
+
constructor(options = {}) {
|
|
46549
|
+
this.postFn = options.postFn;
|
|
46550
|
+
}
|
|
46551
|
+
buildNonInteractiveAwareness(agentMap, stepStates) {
|
|
46552
|
+
const nonInteractive = [...agentMap.values()].filter((agent) => agent.interactive === false);
|
|
46553
|
+
if (nonInteractive.length === 0)
|
|
46554
|
+
return void 0;
|
|
46555
|
+
const agentToSteps = /* @__PURE__ */ new Map();
|
|
46556
|
+
for (const [stepName, state] of stepStates) {
|
|
46557
|
+
const agentName = state.row.agentName;
|
|
46558
|
+
if (!agentName)
|
|
46559
|
+
continue;
|
|
46560
|
+
if (!agentToSteps.has(agentName))
|
|
46561
|
+
agentToSteps.set(agentName, []);
|
|
46562
|
+
agentToSteps.get(agentName).push(stepName);
|
|
46563
|
+
}
|
|
46564
|
+
const lines = nonInteractive.map((agent) => {
|
|
46565
|
+
const stepRefs = (agentToSteps.get(agent.name) ?? []).map((stepName) => `{{steps.${stepName}.output}}`);
|
|
46566
|
+
return `- ${agent.name} (${agent.cli}) \u2014 will return output when complete` + (stepRefs.length > 0 ? `. Access via: ${stepRefs.join(", ")}` : "");
|
|
46567
|
+
});
|
|
46568
|
+
return "\n\n---\nNote: The following agents are non-interactive workers and cannot receive messages:\n" + lines.join("\n") + "\nDo NOT attempt to message these agents. Use the {{steps.<name>.output}} references above to access their results.";
|
|
46569
|
+
}
|
|
46570
|
+
buildRelayRegistrationNote(cli, agentName) {
|
|
46571
|
+
if (cli === "claude")
|
|
46572
|
+
return "";
|
|
46573
|
+
return `---
|
|
46574
|
+
RELAY SETUP \u2014 do this FIRST before any other relay tool:
|
|
46575
|
+
1. Call: register(name="${agentName}")
|
|
46576
|
+
This authenticates you in the Relaycast workspace.
|
|
46577
|
+
ALL relay tools (mcp__relaycast__message_dm_send, mcp__relaycast__message_inbox_check, mcp__relaycast__message_post, etc.) require
|
|
46578
|
+
registration first \u2014 they will fail with "Not registered" otherwise.
|
|
46579
|
+
2. Your agent name is "${agentName}" \u2014 use this exact name when registering.`;
|
|
46580
|
+
}
|
|
46581
|
+
buildDelegationGuidance(cli, timeoutMs) {
|
|
46582
|
+
const timeoutNote = timeoutMs ? `You have approximately ${Math.round(timeoutMs / 6e4)} minutes before this step times out. Plan accordingly \u2014 delegate early if the work is substantial.
|
|
46583
|
+
|
|
46584
|
+
` : "";
|
|
46585
|
+
const subAgentOption = cli === "claude" ? "Option 2 \u2014 Use built-in sub-agents (Task tool) for research or scoped work:\n - Good for exploring code, reading files, or making targeted changes\n - Can run multiple sub-agents in parallel\n\n" : "";
|
|
46586
|
+
return "---\nAUTONOMOUS DELEGATION \u2014 READ THIS BEFORE STARTING:\n" + timeoutNote + 'Before diving in, assess whether this task is too large or complex for a single agent. If it involves multiple independent subtasks, touches many files, or could take a long time, you should break it down and delegate to helper agents to avoid timeouts.\n\nOption 1 \u2014 Spawn relay agents (for real parallel coding work):\n - mcp__relaycast__agent_add(name="helper-1", cli="claude", task="Specific subtask description")\n - Coordinate via mcp__relaycast__message_dm_send(to="helper-1", text="...")\n - Check on them with mcp__relaycast__message_inbox_check()\n - Clean up when done: mcp__relaycast__agent_remove(name="helper-1")\n\n' + subAgentOption + `Guidelines:
|
|
46587
|
+
- You are the lead \u2014 delegate but stay in control, track progress, integrate results
|
|
46588
|
+
- Give each helper a clear, self-contained task with enough context to work independently
|
|
46589
|
+
- For simple or quick work, just do it yourself \u2014 don't over-delegate
|
|
46590
|
+
- Always release spawned relay agents when their work is complete
|
|
46591
|
+
- When spawning non-claude agents (codex, gemini, etc.), prepend to their task:
|
|
46592
|
+
"RELAY SETUP: First call register(name='<exact-agent-name>') before any other relay tool."`;
|
|
46593
|
+
}
|
|
46594
|
+
postCompletionReport(workflowName, outcomes, summary, confidence) {
|
|
46595
|
+
const completed = outcomes.filter((outcome) => outcome.status === "completed");
|
|
46596
|
+
const skipped = outcomes.filter((outcome) => outcome.status === "skipped");
|
|
46597
|
+
const retried = outcomes.filter((outcome) => outcome.attempts > 1);
|
|
46598
|
+
const lines = [
|
|
46599
|
+
`## Workflow **${workflowName}** \u2014 Complete`,
|
|
46600
|
+
"",
|
|
46601
|
+
summary,
|
|
46602
|
+
`Confidence: ${Math.round(confidence * 100)}%`,
|
|
46603
|
+
"",
|
|
46604
|
+
"### Steps",
|
|
46605
|
+
...completed.map((outcome) => `- **${outcome.name}** (${outcome.agent}) \u2014 passed${outcome.verificationPassed ? " (verified)" : ""}${outcome.attempts > 1 ? ` after ${outcome.attempts} attempts` : ""}`),
|
|
46606
|
+
...skipped.map((outcome) => `- **${outcome.name}** \u2014 skipped`)
|
|
46607
|
+
];
|
|
46608
|
+
if (retried.length > 0) {
|
|
46609
|
+
lines.push("", "### Retries");
|
|
46610
|
+
for (const outcome of retried) {
|
|
46611
|
+
lines.push(`- ${outcome.name}: ${outcome.attempts} attempts`);
|
|
46612
|
+
}
|
|
46613
|
+
}
|
|
46614
|
+
this.postFn?.(lines.join("\n"));
|
|
46615
|
+
}
|
|
46616
|
+
postFailureReport(workflowName, outcomes, errorMsg) {
|
|
46617
|
+
const completed = outcomes.filter((outcome) => outcome.status === "completed");
|
|
46618
|
+
const failed = outcomes.filter((outcome) => outcome.status === "failed");
|
|
46619
|
+
const skipped = outcomes.filter((outcome) => outcome.status === "skipped");
|
|
46620
|
+
const lines = [
|
|
46621
|
+
`## Workflow **${workflowName}** \u2014 Failed`,
|
|
46622
|
+
"",
|
|
46623
|
+
`${completed.length}/${outcomes.length} steps passed. Error: ${errorMsg}`,
|
|
46624
|
+
"",
|
|
46625
|
+
"### Steps",
|
|
46626
|
+
...completed.map((outcome) => `- **${outcome.name}** (${outcome.agent}) \u2014 passed`),
|
|
46627
|
+
...failed.map((outcome) => `- **${outcome.name}** (${outcome.agent}) \u2014 FAILED: ${outcome.error ?? "unknown"}`),
|
|
46628
|
+
...skipped.map((outcome) => `- **${outcome.name}** \u2014 skipped`)
|
|
46629
|
+
];
|
|
46630
|
+
this.postFn?.(lines.join("\n"));
|
|
46631
|
+
}
|
|
46632
|
+
};
|
|
46633
|
+
|
|
46285
46634
|
// packages/sdk/dist/workflows/memory-db.js
|
|
46286
46635
|
var InMemoryWorkflowDb = class {
|
|
46287
46636
|
runs = /* @__PURE__ */ new Map();
|
|
@@ -46312,6 +46661,265 @@ var InMemoryWorkflowDb = class {
|
|
|
46312
46661
|
}
|
|
46313
46662
|
};
|
|
46314
46663
|
|
|
46664
|
+
// packages/sdk/dist/workflows/process-spawner.js
|
|
46665
|
+
var import_node_child_process5 = require("node:child_process");
|
|
46666
|
+
|
|
46667
|
+
// packages/sdk/dist/workflows/verification.js
|
|
46668
|
+
var import_node_fs9 = require("node:fs");
|
|
46669
|
+
var import_node_path12 = __toESM(require("node:path"), 1);
|
|
46670
|
+
var WorkflowCompletionError = class extends Error {
|
|
46671
|
+
completionReason;
|
|
46672
|
+
constructor(message, completionReason) {
|
|
46673
|
+
super(message);
|
|
46674
|
+
this.name = "WorkflowCompletionError";
|
|
46675
|
+
this.completionReason = completionReason;
|
|
46676
|
+
}
|
|
46677
|
+
};
|
|
46678
|
+
function runVerification(check2, output, stepName, injectedTaskText, options = {}, sideEffects = {}) {
|
|
46679
|
+
const cwd = options.cwd ?? process.cwd();
|
|
46680
|
+
const fail = (message) => {
|
|
46681
|
+
const observedAt2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
46682
|
+
sideEffects.recordStepToolSideEffect?.(stepName, {
|
|
46683
|
+
type: "verification_observed",
|
|
46684
|
+
detail: message,
|
|
46685
|
+
observedAt: observedAt2,
|
|
46686
|
+
raw: { passed: false, type: check2.type, value: check2.value }
|
|
46687
|
+
});
|
|
46688
|
+
sideEffects.getOrCreateStepEvidenceRecord?.(stepName).evidence.coordinationSignals.push({
|
|
46689
|
+
kind: "verification_failed",
|
|
46690
|
+
source: "verification",
|
|
46691
|
+
text: message,
|
|
46692
|
+
observedAt: observedAt2,
|
|
46693
|
+
value: check2.value
|
|
46694
|
+
});
|
|
46695
|
+
if (options.allowFailure) {
|
|
46696
|
+
return {
|
|
46697
|
+
passed: false,
|
|
46698
|
+
completionReason: "failed_verification",
|
|
46699
|
+
error: message
|
|
46700
|
+
};
|
|
46701
|
+
}
|
|
46702
|
+
throw new WorkflowCompletionError(message, "failed_verification");
|
|
46703
|
+
};
|
|
46704
|
+
switch (check2.type) {
|
|
46705
|
+
case "output_contains": {
|
|
46706
|
+
const token = check2.value;
|
|
46707
|
+
if (!checkOutputContains(output, token, injectedTaskText)) {
|
|
46708
|
+
return fail(`Verification failed for "${stepName}": output does not contain "${token}"`);
|
|
46709
|
+
}
|
|
46710
|
+
break;
|
|
46711
|
+
}
|
|
46712
|
+
case "exit_code":
|
|
46713
|
+
if (!checkExitCode(check2.value)) {
|
|
46714
|
+
return fail(`Verification failed for "${stepName}": exit code did not match "${check2.value}"`);
|
|
46715
|
+
}
|
|
46716
|
+
break;
|
|
46717
|
+
case "file_exists":
|
|
46718
|
+
if (!checkFileExists(check2.value, cwd)) {
|
|
46719
|
+
return fail(`Verification failed for "${stepName}": file "${check2.value}" does not exist`);
|
|
46720
|
+
}
|
|
46721
|
+
break;
|
|
46722
|
+
case "custom":
|
|
46723
|
+
return { passed: false };
|
|
46724
|
+
default:
|
|
46725
|
+
break;
|
|
46726
|
+
}
|
|
46727
|
+
if (options.completionMarkerFound === false) {
|
|
46728
|
+
sideEffects.log?.(`[${stepName}] Verification passed without legacy STEP_COMPLETE marker; allowing completion`);
|
|
46729
|
+
}
|
|
46730
|
+
const observedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
46731
|
+
const successMessage = options.completionMarkerFound === false ? "Verification passed without legacy STEP_COMPLETE marker" : "Verification passed";
|
|
46732
|
+
sideEffects.recordStepToolSideEffect?.(stepName, {
|
|
46733
|
+
type: "verification_observed",
|
|
46734
|
+
detail: successMessage,
|
|
46735
|
+
observedAt,
|
|
46736
|
+
raw: { passed: true, type: check2.type, value: check2.value }
|
|
46737
|
+
});
|
|
46738
|
+
sideEffects.getOrCreateStepEvidenceRecord?.(stepName).evidence.coordinationSignals.push({
|
|
46739
|
+
kind: "verification_passed",
|
|
46740
|
+
source: "verification",
|
|
46741
|
+
text: successMessage,
|
|
46742
|
+
observedAt,
|
|
46743
|
+
value: check2.value
|
|
46744
|
+
});
|
|
46745
|
+
return {
|
|
46746
|
+
passed: true,
|
|
46747
|
+
completionReason: "completed_verified"
|
|
46748
|
+
};
|
|
46749
|
+
}
|
|
46750
|
+
function stripInjectedTaskEcho(output, injectedTaskText) {
|
|
46751
|
+
if (!injectedTaskText) {
|
|
46752
|
+
return output;
|
|
46753
|
+
}
|
|
46754
|
+
const candidates = [
|
|
46755
|
+
injectedTaskText,
|
|
46756
|
+
injectedTaskText.replace(/\r\n/g, "\n"),
|
|
46757
|
+
injectedTaskText.replace(/\n/g, "\r\n")
|
|
46758
|
+
].filter((candidate, index, all) => candidate.length > 0 && all.indexOf(candidate) === index);
|
|
46759
|
+
for (const candidate of candidates) {
|
|
46760
|
+
const start = output.indexOf(candidate);
|
|
46761
|
+
if (start !== -1) {
|
|
46762
|
+
return output.slice(0, start) + output.slice(start + candidate.length);
|
|
46763
|
+
}
|
|
46764
|
+
}
|
|
46765
|
+
return output;
|
|
46766
|
+
}
|
|
46767
|
+
function checkExitCode(_expectedExitCode) {
|
|
46768
|
+
return true;
|
|
46769
|
+
}
|
|
46770
|
+
function checkOutputContains(output, token, injectedTaskText) {
|
|
46771
|
+
if (!token) {
|
|
46772
|
+
return false;
|
|
46773
|
+
}
|
|
46774
|
+
return stripInjectedTaskEcho(output, injectedTaskText).includes(token);
|
|
46775
|
+
}
|
|
46776
|
+
function checkFileExists(filePath, cwd = process.cwd()) {
|
|
46777
|
+
const normalizedCwd = import_node_path12.default.resolve(cwd);
|
|
46778
|
+
const resolved = import_node_path12.default.resolve(normalizedCwd, filePath);
|
|
46779
|
+
if (!resolved.startsWith(normalizedCwd + import_node_path12.default.sep) && resolved !== normalizedCwd) {
|
|
46780
|
+
return false;
|
|
46781
|
+
}
|
|
46782
|
+
return (0, import_node_fs9.existsSync)(resolved);
|
|
46783
|
+
}
|
|
46784
|
+
|
|
46785
|
+
// packages/sdk/dist/workflows/process-spawner.js
|
|
46786
|
+
function resolveNonInteractiveCli(cli) {
|
|
46787
|
+
if (cli !== "cursor") {
|
|
46788
|
+
return cli;
|
|
46789
|
+
}
|
|
46790
|
+
const resolved = resolveCliSync("cursor");
|
|
46791
|
+
return resolved?.binary ?? "agent";
|
|
46792
|
+
}
|
|
46793
|
+
function buildCommand(cli, extraArgs = [], task) {
|
|
46794
|
+
if (cli === "api") {
|
|
46795
|
+
throw new Error('cli "api" uses direct API calls, not a subprocess command');
|
|
46796
|
+
}
|
|
46797
|
+
const resolvedCli = resolveNonInteractiveCli(cli);
|
|
46798
|
+
const definition = getCliDefinition(resolvedCli);
|
|
46799
|
+
if (!definition || definition.binaries.length === 0) {
|
|
46800
|
+
throw new Error(`Unknown or non-executable CLI: ${resolvedCli}`);
|
|
46801
|
+
}
|
|
46802
|
+
return [definition.binaries[0], ...definition.nonInteractiveArgs(task, extraArgs)];
|
|
46803
|
+
}
|
|
46804
|
+
function spawnProcess(command, options) {
|
|
46805
|
+
const [bin, ...args] = command;
|
|
46806
|
+
return (0, import_node_child_process5.spawn)(bin, args, options);
|
|
46807
|
+
}
|
|
46808
|
+
function collectOutput(process8) {
|
|
46809
|
+
return new Promise((resolve4, reject) => {
|
|
46810
|
+
let settled = false;
|
|
46811
|
+
const stdout = [];
|
|
46812
|
+
const stderr = [];
|
|
46813
|
+
process8.stdout?.on("data", (chunk) => {
|
|
46814
|
+
stdout.push(chunk.toString());
|
|
46815
|
+
});
|
|
46816
|
+
process8.stderr?.on("data", (chunk) => {
|
|
46817
|
+
stderr.push(chunk.toString());
|
|
46818
|
+
});
|
|
46819
|
+
process8.once("error", (err) => {
|
|
46820
|
+
if (!settled) {
|
|
46821
|
+
settled = true;
|
|
46822
|
+
reject(err);
|
|
46823
|
+
}
|
|
46824
|
+
});
|
|
46825
|
+
process8.once("close", () => {
|
|
46826
|
+
if (!settled) {
|
|
46827
|
+
settled = true;
|
|
46828
|
+
resolve4(`${stdout.join("")}${stderr.join("")}`);
|
|
46829
|
+
}
|
|
46830
|
+
});
|
|
46831
|
+
});
|
|
46832
|
+
}
|
|
46833
|
+
function detectCompletion(output, verification) {
|
|
46834
|
+
if (/OWNER_DECISION:\s*(?:INCOMPLETE_RETRY|INCOMPLETE_FAIL|NEEDS_CLARIFICATION)\b/i.test(output)) {
|
|
46835
|
+
return false;
|
|
46836
|
+
}
|
|
46837
|
+
if (/OWNER_DECISION:\s*COMPLETE\b/i.test(output)) {
|
|
46838
|
+
return true;
|
|
46839
|
+
}
|
|
46840
|
+
if (/\bSTEP_COMPLETE:([A-Za-z0-9_.:-]+)/.test(output)) {
|
|
46841
|
+
return true;
|
|
46842
|
+
}
|
|
46843
|
+
if (!verification) {
|
|
46844
|
+
return false;
|
|
46845
|
+
}
|
|
46846
|
+
return runVerification(verification, output, "process", void 0, { allowFailure: true }).passed;
|
|
46847
|
+
}
|
|
46848
|
+
async function runCommand(command, opts) {
|
|
46849
|
+
const child = spawnProcess([command.bin, ...command.args], {
|
|
46850
|
+
cwd: opts.cwd,
|
|
46851
|
+
env: { ...process.env, ...command.env },
|
|
46852
|
+
stdio: "pipe"
|
|
46853
|
+
});
|
|
46854
|
+
const outputPromise = collectOutput(child);
|
|
46855
|
+
const exitPromise = new Promise((resolve4, reject) => {
|
|
46856
|
+
let timedOut = false;
|
|
46857
|
+
let timer;
|
|
46858
|
+
let killTimer;
|
|
46859
|
+
if (opts.timeoutMs) {
|
|
46860
|
+
timer = setTimeout(() => {
|
|
46861
|
+
timedOut = true;
|
|
46862
|
+
child.kill("SIGTERM");
|
|
46863
|
+
killTimer = setTimeout(() => child.kill("SIGKILL"), 5e3);
|
|
46864
|
+
}, opts.timeoutMs);
|
|
46865
|
+
}
|
|
46866
|
+
const clearTimer = () => {
|
|
46867
|
+
if (timer)
|
|
46868
|
+
clearTimeout(timer);
|
|
46869
|
+
if (killTimer)
|
|
46870
|
+
clearTimeout(killTimer);
|
|
46871
|
+
};
|
|
46872
|
+
child.once("error", (error48) => {
|
|
46873
|
+
clearTimer();
|
|
46874
|
+
reject(error48);
|
|
46875
|
+
});
|
|
46876
|
+
child.once("close", (exitCode, exitSignal) => {
|
|
46877
|
+
clearTimer();
|
|
46878
|
+
if (timedOut) {
|
|
46879
|
+
reject(new Error(`Process timed out after ${opts.timeoutMs ?? "unknown"}ms`));
|
|
46880
|
+
return;
|
|
46881
|
+
}
|
|
46882
|
+
resolve4({
|
|
46883
|
+
exitCode: exitCode ?? void 0,
|
|
46884
|
+
exitSignal: exitSignal ?? void 0
|
|
46885
|
+
});
|
|
46886
|
+
});
|
|
46887
|
+
});
|
|
46888
|
+
const [outputResult, exitResult] = await Promise.allSettled([outputPromise, exitPromise]);
|
|
46889
|
+
const output = outputResult.status === "fulfilled" ? outputResult.value : "";
|
|
46890
|
+
if (exitResult.status === "rejected") {
|
|
46891
|
+
const err = exitResult.reason instanceof Error ? exitResult.reason : new Error(String(exitResult.reason));
|
|
46892
|
+
err.partialOutput = output;
|
|
46893
|
+
throw err;
|
|
46894
|
+
}
|
|
46895
|
+
return {
|
|
46896
|
+
output,
|
|
46897
|
+
exitCode: exitResult.value.exitCode,
|
|
46898
|
+
exitSignal: exitResult.value.exitSignal
|
|
46899
|
+
};
|
|
46900
|
+
}
|
|
46901
|
+
function createProcessSpawner(deps) {
|
|
46902
|
+
const buildAgentCommand = (agent, task) => {
|
|
46903
|
+
const extraArgs = agent.constraints?.model ? ["--model", agent.constraints.model] : [];
|
|
46904
|
+
const [bin, ...args] = buildCommand(agent.cli, extraArgs, task);
|
|
46905
|
+
return { bin, args };
|
|
46906
|
+
};
|
|
46907
|
+
return {
|
|
46908
|
+
async spawnShell(command, opts) {
|
|
46909
|
+
return runCommand({ bin: "sh", args: ["-c", command] }, { ...opts, cwd: opts.cwd ?? deps.cwd });
|
|
46910
|
+
},
|
|
46911
|
+
async spawnAgent(agent, task, opts) {
|
|
46912
|
+
return runCommand(buildAgentCommand(agent, task), { ...opts, cwd: opts.cwd ?? deps.cwd });
|
|
46913
|
+
},
|
|
46914
|
+
async spawnInteractive(agent, task, opts) {
|
|
46915
|
+
return runCommand(buildAgentCommand(agent, task), { ...opts, cwd: opts.cwd ?? deps.cwd });
|
|
46916
|
+
},
|
|
46917
|
+
buildCommand(agent, task) {
|
|
46918
|
+
return buildAgentCommand(agent, task);
|
|
46919
|
+
}
|
|
46920
|
+
};
|
|
46921
|
+
}
|
|
46922
|
+
|
|
46315
46923
|
// packages/sdk/dist/workflows/run-summary-table.js
|
|
46316
46924
|
function formatCurrency(value) {
|
|
46317
46925
|
return typeof value === "number" ? `$${value.toFixed(2)}` : "--";
|
|
@@ -46403,11 +47011,528 @@ function formatRunSummaryTable(outcomes, reports) {
|
|
|
46403
47011
|
return lines.map((line) => ` ${line}`).join("\n");
|
|
46404
47012
|
}
|
|
46405
47013
|
|
|
47014
|
+
// packages/sdk/dist/workflows/template-resolver.js
|
|
47015
|
+
function shellEscape(value) {
|
|
47016
|
+
return "'" + value.replace(/'/g, "'\\''") + "'";
|
|
47017
|
+
}
|
|
47018
|
+
var TEMPLATE_VARIABLE_PATTERN = /\{\{([\w][\w.\-]*)\}\}/g;
|
|
47019
|
+
var STEP_OUTPUT_TEMPLATE_PATTERN = /\{\{(steps\.[\w\-]+\.output)\}\}/g;
|
|
47020
|
+
var STEP_OUTPUT_REF_PATTERN = /^steps\.([\w\-]+)\.output$/;
|
|
47021
|
+
function resolveVariables(config2, vars) {
|
|
47022
|
+
const resolved = structuredClone(config2);
|
|
47023
|
+
for (const agent of resolved.agents) {
|
|
47024
|
+
if (agent.task) {
|
|
47025
|
+
agent.task = resolveTemplate(agent.task, vars);
|
|
47026
|
+
}
|
|
47027
|
+
}
|
|
47028
|
+
if (resolved.workflows) {
|
|
47029
|
+
for (const workflow2 of resolved.workflows) {
|
|
47030
|
+
for (const step of workflow2.steps) {
|
|
47031
|
+
if (step.task) {
|
|
47032
|
+
step.task = resolveTemplate(step.task, vars);
|
|
47033
|
+
}
|
|
47034
|
+
if (step.command) {
|
|
47035
|
+
step.command = resolveTemplateForShell(step.command, vars);
|
|
47036
|
+
}
|
|
47037
|
+
if (step.params && typeof step.params === "object") {
|
|
47038
|
+
for (const key of Object.keys(step.params)) {
|
|
47039
|
+
const value = step.params[key];
|
|
47040
|
+
if (typeof value === "string") {
|
|
47041
|
+
step.params[key] = resolveTemplate(value, vars);
|
|
47042
|
+
}
|
|
47043
|
+
}
|
|
47044
|
+
}
|
|
47045
|
+
}
|
|
47046
|
+
}
|
|
47047
|
+
}
|
|
47048
|
+
return resolved;
|
|
47049
|
+
}
|
|
47050
|
+
function resolveTemplate(template, context) {
|
|
47051
|
+
return template.replace(TEMPLATE_VARIABLE_PATTERN, (match, key) => {
|
|
47052
|
+
if (key.startsWith("steps.")) {
|
|
47053
|
+
return match;
|
|
47054
|
+
}
|
|
47055
|
+
const value = resolveDotPath(key, context);
|
|
47056
|
+
if (value === void 0) {
|
|
47057
|
+
throw new Error(`Unresolved variable: {{${key}}}`);
|
|
47058
|
+
}
|
|
47059
|
+
return String(value);
|
|
47060
|
+
});
|
|
47061
|
+
}
|
|
47062
|
+
function resolveTemplateForShell(template, context) {
|
|
47063
|
+
return template.replace(TEMPLATE_VARIABLE_PATTERN, (match, key) => {
|
|
47064
|
+
if (key.startsWith("steps.")) {
|
|
47065
|
+
return match;
|
|
47066
|
+
}
|
|
47067
|
+
const value = resolveDotPath(key, context);
|
|
47068
|
+
if (value === void 0) {
|
|
47069
|
+
throw new Error(`Unresolved variable: {{${key}}}`);
|
|
47070
|
+
}
|
|
47071
|
+
return shellEscape(String(value));
|
|
47072
|
+
});
|
|
47073
|
+
}
|
|
47074
|
+
function resolveDotPath(key, context) {
|
|
47075
|
+
if (!key.includes(".")) {
|
|
47076
|
+
return toTemplateScalar(context[key]);
|
|
47077
|
+
}
|
|
47078
|
+
const parts = key.split(".");
|
|
47079
|
+
let current = context;
|
|
47080
|
+
for (const part of parts) {
|
|
47081
|
+
if (current === null || current === void 0 || typeof current !== "object") {
|
|
47082
|
+
return void 0;
|
|
47083
|
+
}
|
|
47084
|
+
current = current[part];
|
|
47085
|
+
}
|
|
47086
|
+
return toTemplateScalar(current);
|
|
47087
|
+
}
|
|
47088
|
+
function resolveStepOutputRef(ref, stepOutputs) {
|
|
47089
|
+
const normalizedRef = ref.startsWith("{{") && ref.endsWith("}}") ? ref.slice(2, -2).trim() : ref;
|
|
47090
|
+
const match = STEP_OUTPUT_REF_PATTERN.exec(normalizedRef);
|
|
47091
|
+
if (!match) {
|
|
47092
|
+
throw new Error(`Invalid step output reference: ${ref}`);
|
|
47093
|
+
}
|
|
47094
|
+
const stepOutput = stepOutputs.get(match[1]);
|
|
47095
|
+
if (stepOutput === void 0) {
|
|
47096
|
+
throw new Error(`Unresolved step output reference: ${ref}`);
|
|
47097
|
+
}
|
|
47098
|
+
return stepOutput;
|
|
47099
|
+
}
|
|
47100
|
+
function interpolateStepTask(template, context) {
|
|
47101
|
+
const stepOutputs = buildStepOutputMap(context);
|
|
47102
|
+
return template.replace(STEP_OUTPUT_TEMPLATE_PATTERN, (match, ref) => {
|
|
47103
|
+
try {
|
|
47104
|
+
return resolveStepOutputRef(ref, stepOutputs);
|
|
47105
|
+
} catch {
|
|
47106
|
+
return match;
|
|
47107
|
+
}
|
|
47108
|
+
});
|
|
47109
|
+
}
|
|
47110
|
+
function buildStepOutputMap(context) {
|
|
47111
|
+
const stepOutputs = /* @__PURE__ */ new Map();
|
|
47112
|
+
const steps = context.steps;
|
|
47113
|
+
if (!steps || typeof steps !== "object") {
|
|
47114
|
+
return stepOutputs;
|
|
47115
|
+
}
|
|
47116
|
+
for (const [stepName, stepState] of Object.entries(steps)) {
|
|
47117
|
+
if (!stepState || typeof stepState !== "object") {
|
|
47118
|
+
continue;
|
|
47119
|
+
}
|
|
47120
|
+
const output = toTemplateScalar(stepState.output);
|
|
47121
|
+
if (output !== void 0) {
|
|
47122
|
+
stepOutputs.set(stepName, String(output));
|
|
47123
|
+
}
|
|
47124
|
+
}
|
|
47125
|
+
return stepOutputs;
|
|
47126
|
+
}
|
|
47127
|
+
function toTemplateScalar(value) {
|
|
47128
|
+
if (value === void 0 || value === null)
|
|
47129
|
+
return void 0;
|
|
47130
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
47131
|
+
return value;
|
|
47132
|
+
}
|
|
47133
|
+
return String(value);
|
|
47134
|
+
}
|
|
47135
|
+
var TemplateResolver = class {
|
|
47136
|
+
resolveVariables(config2, vars) {
|
|
47137
|
+
return resolveVariables(config2, vars);
|
|
47138
|
+
}
|
|
47139
|
+
interpolate(template, vars) {
|
|
47140
|
+
return resolveTemplate(template, vars);
|
|
47141
|
+
}
|
|
47142
|
+
resolveDotPath(key, vars) {
|
|
47143
|
+
return resolveDotPath(key, vars);
|
|
47144
|
+
}
|
|
47145
|
+
interpolateStepTask(template, context) {
|
|
47146
|
+
return interpolateStepTask(template, context);
|
|
47147
|
+
}
|
|
47148
|
+
};
|
|
47149
|
+
|
|
47150
|
+
// packages/sdk/dist/workflows/step-executor.js
|
|
47151
|
+
var StepExecutor = class {
|
|
47152
|
+
deps;
|
|
47153
|
+
templateResolver;
|
|
47154
|
+
channelMessenger;
|
|
47155
|
+
verificationRunner;
|
|
47156
|
+
constructor(deps) {
|
|
47157
|
+
this.deps = deps;
|
|
47158
|
+
this.templateResolver = deps.templateResolver ?? new TemplateResolver();
|
|
47159
|
+
this.channelMessenger = deps.channelMessenger ?? new ChannelMessenger({ postFn: deps.postToChannel });
|
|
47160
|
+
this.verificationRunner = deps.verificationRunner ?? runVerification;
|
|
47161
|
+
}
|
|
47162
|
+
findReady(steps, statuses) {
|
|
47163
|
+
return steps.filter((step) => {
|
|
47164
|
+
const state = statuses.get(step.name);
|
|
47165
|
+
const status = this.getStatus(state);
|
|
47166
|
+
if (status !== "pending")
|
|
47167
|
+
return false;
|
|
47168
|
+
return (step.dependsOn ?? []).every((dependency) => {
|
|
47169
|
+
const depState = statuses.get(dependency);
|
|
47170
|
+
const depStatus = this.getStatus(depState);
|
|
47171
|
+
return depStatus === "completed" || depStatus === "skipped";
|
|
47172
|
+
});
|
|
47173
|
+
});
|
|
47174
|
+
}
|
|
47175
|
+
/** @deprecated Use {@link findReady} instead. This is an alias kept for backward compatibility. */
|
|
47176
|
+
findReadySteps(steps, statuses) {
|
|
47177
|
+
return this.findReady(steps, statuses);
|
|
47178
|
+
}
|
|
47179
|
+
scheduleStep(step, options = {}) {
|
|
47180
|
+
return {
|
|
47181
|
+
step,
|
|
47182
|
+
readyAt: options.readyAt ?? Date.now(),
|
|
47183
|
+
staggerDelay: options.staggerDelay ?? 0
|
|
47184
|
+
};
|
|
47185
|
+
}
|
|
47186
|
+
async startStep(step, state, startMessage) {
|
|
47187
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
47188
|
+
state.row.status = "running";
|
|
47189
|
+
state.row.error = void 0;
|
|
47190
|
+
state.row.completionReason = void 0;
|
|
47191
|
+
state.row.startedAt = startedAt;
|
|
47192
|
+
await this.deps.persistStepRow?.(state.row.id, {
|
|
47193
|
+
status: "running",
|
|
47194
|
+
error: void 0,
|
|
47195
|
+
completionReason: void 0,
|
|
47196
|
+
startedAt,
|
|
47197
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
47198
|
+
});
|
|
47199
|
+
if (startMessage) {
|
|
47200
|
+
this.deps.postToChannel?.(startMessage);
|
|
47201
|
+
}
|
|
47202
|
+
await this.deps.onStepStarted?.(step, state);
|
|
47203
|
+
}
|
|
47204
|
+
async retryStep(step, state, attempt, maxRetries) {
|
|
47205
|
+
state.row.retryCount = attempt;
|
|
47206
|
+
await this.deps.persistStepRow?.(state.row.id, {
|
|
47207
|
+
retryCount: attempt,
|
|
47208
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
47209
|
+
});
|
|
47210
|
+
await this.deps.onStepRetried?.(step, state, attempt, maxRetries);
|
|
47211
|
+
}
|
|
47212
|
+
async completeStep(step, state, result) {
|
|
47213
|
+
const completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
47214
|
+
const finalResult = {
|
|
47215
|
+
status: result.status ?? "completed",
|
|
47216
|
+
output: result.output ?? "",
|
|
47217
|
+
exitCode: result.exitCode,
|
|
47218
|
+
exitSignal: result.exitSignal,
|
|
47219
|
+
duration: result.duration ?? 0,
|
|
47220
|
+
retries: result.retries ?? state.row.retryCount,
|
|
47221
|
+
completionReason: result.completionReason,
|
|
47222
|
+
error: result.error
|
|
47223
|
+
};
|
|
47224
|
+
state.row.status = finalResult.status;
|
|
47225
|
+
state.row.output = finalResult.output;
|
|
47226
|
+
state.row.error = finalResult.error;
|
|
47227
|
+
state.row.completionReason = finalResult.completionReason;
|
|
47228
|
+
state.row.completedAt = completedAt;
|
|
47229
|
+
await this.deps.persistStepRow?.(state.row.id, {
|
|
47230
|
+
status: finalResult.status,
|
|
47231
|
+
output: finalResult.output,
|
|
47232
|
+
error: finalResult.error,
|
|
47233
|
+
completionReason: finalResult.completionReason,
|
|
47234
|
+
completedAt,
|
|
47235
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
47236
|
+
});
|
|
47237
|
+
if (finalResult.status === "completed" && this.deps.runId && finalResult.output) {
|
|
47238
|
+
await this.deps.persistStepOutput?.(this.deps.runId, step.name, finalResult.output);
|
|
47239
|
+
}
|
|
47240
|
+
if (finalResult.status === "failed") {
|
|
47241
|
+
await this.deps.onStepFailed?.(step, state, finalResult);
|
|
47242
|
+
} else {
|
|
47243
|
+
await this.deps.onStepCompleted?.(step, state, finalResult);
|
|
47244
|
+
}
|
|
47245
|
+
return finalResult;
|
|
47246
|
+
}
|
|
47247
|
+
async monitorStep(step, state, options) {
|
|
47248
|
+
const maxRetries = options.maxRetries ?? 0;
|
|
47249
|
+
const retryDelayMs = options.retryDelayMs ?? 1e3;
|
|
47250
|
+
let lastError;
|
|
47251
|
+
for (let attempt = 0; attempt <= maxRetries; attempt += 1) {
|
|
47252
|
+
this.deps.checkAborted?.();
|
|
47253
|
+
await this.deps.waitIfPaused?.();
|
|
47254
|
+
if (attempt > 0) {
|
|
47255
|
+
await this.retryStep(step, state, attempt, maxRetries);
|
|
47256
|
+
await options.onRetry?.(attempt, maxRetries, state);
|
|
47257
|
+
if (retryDelayMs > 0) {
|
|
47258
|
+
await delay(retryDelayMs);
|
|
47259
|
+
}
|
|
47260
|
+
}
|
|
47261
|
+
const attemptStartedAt = Date.now();
|
|
47262
|
+
await this.startStep(step, state, options.startMessage);
|
|
47263
|
+
await options.onStart?.(attempt, state);
|
|
47264
|
+
try {
|
|
47265
|
+
const rawResult = await options.execute(attempt, state);
|
|
47266
|
+
const completion = options.toCompletionResult(rawResult, attempt, state);
|
|
47267
|
+
return await this.completeStep(step, state, {
|
|
47268
|
+
...completion,
|
|
47269
|
+
duration: completion.duration ?? Date.now() - attemptStartedAt,
|
|
47270
|
+
retries: completion.retries ?? attempt
|
|
47271
|
+
});
|
|
47272
|
+
} catch (error48) {
|
|
47273
|
+
lastError = error48;
|
|
47274
|
+
await options.onAttemptFailed?.(error48, attempt, state);
|
|
47275
|
+
}
|
|
47276
|
+
}
|
|
47277
|
+
const failure = options.getFailureResult?.(lastError, maxRetries, state) ?? {
|
|
47278
|
+
status: "failed",
|
|
47279
|
+
output: "",
|
|
47280
|
+
error: lastError instanceof Error ? lastError.message : String(lastError ?? "Unknown error"),
|
|
47281
|
+
retries: maxRetries
|
|
47282
|
+
};
|
|
47283
|
+
return this.completeStep(step, state, {
|
|
47284
|
+
...failure,
|
|
47285
|
+
status: "failed"
|
|
47286
|
+
});
|
|
47287
|
+
}
|
|
47288
|
+
async executeAll(steps, agentMap, errorHandling, providedStates) {
|
|
47289
|
+
const states = providedStates ?? this.createEphemeralStates(steps);
|
|
47290
|
+
const strategy = normalizeStrategy(errorHandling?.strategy ?? "fail-fast");
|
|
47291
|
+
const results = /* @__PURE__ */ new Map();
|
|
47292
|
+
while (true) {
|
|
47293
|
+
this.deps.checkAborted?.();
|
|
47294
|
+
await this.deps.waitIfPaused?.();
|
|
47295
|
+
const readySteps = this.findReady(steps, states);
|
|
47296
|
+
if (readySteps.length === 0)
|
|
47297
|
+
break;
|
|
47298
|
+
const schedules = readySteps.map((step, index) => this.scheduleStep(step, {
|
|
47299
|
+
readyAt: Date.now(),
|
|
47300
|
+
staggerDelay: readySteps.length > 3 ? index * 2e3 : 0
|
|
47301
|
+
}));
|
|
47302
|
+
if (schedules.length > 1) {
|
|
47303
|
+
await this.deps.onBeginTrack?.(readySteps);
|
|
47304
|
+
}
|
|
47305
|
+
const settled = await Promise.allSettled(schedules.map(async (schedule) => {
|
|
47306
|
+
if (schedule.staggerDelay > 0) {
|
|
47307
|
+
await delay(schedule.staggerDelay);
|
|
47308
|
+
}
|
|
47309
|
+
return this.executeScheduledStep(schedule.step, states, agentMap, errorHandling);
|
|
47310
|
+
}));
|
|
47311
|
+
const batchOutcomes = [];
|
|
47312
|
+
for (let index = 0; index < settled.length; index += 1) {
|
|
47313
|
+
const settledResult = settled[index];
|
|
47314
|
+
const step = readySteps[index];
|
|
47315
|
+
const state = states.get(step.name);
|
|
47316
|
+
if (settledResult.status === "fulfilled") {
|
|
47317
|
+
const result = settledResult.value;
|
|
47318
|
+
const outcomeStatus = result.status === "completed" || result.status === "skipped" ? result.status : "failed";
|
|
47319
|
+
results.set(step.name, result);
|
|
47320
|
+
batchOutcomes.push({
|
|
47321
|
+
name: step.name,
|
|
47322
|
+
agent: step.agent ?? "deterministic",
|
|
47323
|
+
status: outcomeStatus,
|
|
47324
|
+
attempts: result.retries + 1,
|
|
47325
|
+
output: result.output,
|
|
47326
|
+
error: result.error,
|
|
47327
|
+
verificationPassed: outcomeStatus === "completed" && step.verification !== void 0,
|
|
47328
|
+
completionMode: result.completionReason !== void 0 ? this.deps.buildCompletionMode?.(step.name, result.completionReason) : void 0
|
|
47329
|
+
});
|
|
47330
|
+
if (result.status === "failed") {
|
|
47331
|
+
await this.deps.markDownstreamSkipped?.(step.name);
|
|
47332
|
+
if (strategy === "fail-fast") {
|
|
47333
|
+
throw new Error(`Step "${step.name}" failed: ${result.error ?? "unknown error"}`);
|
|
47334
|
+
}
|
|
47335
|
+
}
|
|
47336
|
+
continue;
|
|
47337
|
+
}
|
|
47338
|
+
const error48 = settledResult.reason instanceof Error ? settledResult.reason.message : String(settledResult.reason);
|
|
47339
|
+
if (state) {
|
|
47340
|
+
const failed = state.row.status === "failed" ? {
|
|
47341
|
+
status: "failed",
|
|
47342
|
+
output: state.row.output ?? "",
|
|
47343
|
+
duration: 0,
|
|
47344
|
+
retries: state.row.retryCount,
|
|
47345
|
+
completionReason: state.row.completionReason,
|
|
47346
|
+
error: state.row.error ?? error48
|
|
47347
|
+
} : await this.completeStep(step, state, {
|
|
47348
|
+
status: "failed",
|
|
47349
|
+
output: "",
|
|
47350
|
+
error: error48,
|
|
47351
|
+
retries: state.row.retryCount
|
|
47352
|
+
});
|
|
47353
|
+
results.set(step.name, failed);
|
|
47354
|
+
}
|
|
47355
|
+
batchOutcomes.push({
|
|
47356
|
+
name: step.name,
|
|
47357
|
+
agent: step.agent ?? "deterministic",
|
|
47358
|
+
status: "failed",
|
|
47359
|
+
attempts: (state?.row.retryCount ?? 0) + 1,
|
|
47360
|
+
error: error48
|
|
47361
|
+
});
|
|
47362
|
+
await this.deps.markDownstreamSkipped?.(step.name);
|
|
47363
|
+
if (strategy === "fail-fast") {
|
|
47364
|
+
throw new Error(`Step "${step.name}" failed: ${error48}`);
|
|
47365
|
+
}
|
|
47366
|
+
}
|
|
47367
|
+
if (readySteps.length > 1 && batchOutcomes.length > 0) {
|
|
47368
|
+
await this.deps.onConverge?.(readySteps, batchOutcomes);
|
|
47369
|
+
}
|
|
47370
|
+
}
|
|
47371
|
+
return results;
|
|
47372
|
+
}
|
|
47373
|
+
async executeOne(step, agentMap, errorHandling, providedState) {
|
|
47374
|
+
const state = providedState ?? this.createEphemeralState(step);
|
|
47375
|
+
if (this.deps.executeStep) {
|
|
47376
|
+
const result = await this.deps.executeStep(step, state, agentMap, errorHandling);
|
|
47377
|
+
if (state.row.status !== "pending" && state.row.status !== "running") {
|
|
47378
|
+
return {
|
|
47379
|
+
status: state.row.status,
|
|
47380
|
+
output: state.row.output ?? "",
|
|
47381
|
+
duration: result?.duration ?? 0,
|
|
47382
|
+
retries: result?.retries ?? state.row.retryCount,
|
|
47383
|
+
exitCode: result?.exitCode,
|
|
47384
|
+
exitSignal: result?.exitSignal,
|
|
47385
|
+
completionReason: state.row.completionReason ?? result?.completionReason,
|
|
47386
|
+
error: state.row.error ?? result?.error
|
|
47387
|
+
};
|
|
47388
|
+
}
|
|
47389
|
+
return this.completeStep(step, state, {
|
|
47390
|
+
status: result?.status ?? "completed",
|
|
47391
|
+
output: result?.output ?? "",
|
|
47392
|
+
exitCode: result?.exitCode,
|
|
47393
|
+
exitSignal: result?.exitSignal,
|
|
47394
|
+
completionReason: result?.completionReason,
|
|
47395
|
+
retries: result?.retries ?? state.row.retryCount,
|
|
47396
|
+
duration: result?.duration ?? 0,
|
|
47397
|
+
error: result?.error
|
|
47398
|
+
});
|
|
47399
|
+
}
|
|
47400
|
+
return this.executeWithProcessSpawner(step, state, agentMap, errorHandling);
|
|
47401
|
+
}
|
|
47402
|
+
async markFailed(stepName, error48) {
|
|
47403
|
+
this.deps.postToChannel?.(`**[${stepName}]** Failed: ${error48}`);
|
|
47404
|
+
}
|
|
47405
|
+
buildStepOutputContext(stepStates) {
|
|
47406
|
+
const steps = {};
|
|
47407
|
+
for (const [name, state] of stepStates) {
|
|
47408
|
+
if (state.row.status === "completed" && state.row.output !== void 0) {
|
|
47409
|
+
steps[name] = { output: state.row.output };
|
|
47410
|
+
continue;
|
|
47411
|
+
}
|
|
47412
|
+
if (state.row.status === "completed" && this.deps.runId) {
|
|
47413
|
+
const persisted = this.deps.loadStepOutput?.(this.deps.runId, name);
|
|
47414
|
+
if (persisted !== void 0) {
|
|
47415
|
+
state.row.output = persisted;
|
|
47416
|
+
steps[name] = { output: persisted };
|
|
47417
|
+
}
|
|
47418
|
+
}
|
|
47419
|
+
}
|
|
47420
|
+
return steps;
|
|
47421
|
+
}
|
|
47422
|
+
resolveStepTemplate(template, context) {
|
|
47423
|
+
if (this.deps.resolveTemplate) {
|
|
47424
|
+
return this.deps.resolveTemplate(template, context);
|
|
47425
|
+
}
|
|
47426
|
+
return this.templateResolver.interpolateStepTask(template, context);
|
|
47427
|
+
}
|
|
47428
|
+
getChannelMessenger() {
|
|
47429
|
+
return this.channelMessenger;
|
|
47430
|
+
}
|
|
47431
|
+
runVerification(check2, output, stepName, injectedTaskText, options) {
|
|
47432
|
+
return this.verificationRunner(check2, output, stepName, injectedTaskText, {
|
|
47433
|
+
...options,
|
|
47434
|
+
cwd: options?.cwd ?? this.deps.cwd
|
|
47435
|
+
});
|
|
47436
|
+
}
|
|
47437
|
+
async executeScheduledStep(step, states, agentMap, errorHandling) {
|
|
47438
|
+
const state = states.get(step.name) ?? this.createEphemeralState(step);
|
|
47439
|
+
if (!states.has(step.name)) {
|
|
47440
|
+
states.set(step.name, state);
|
|
47441
|
+
}
|
|
47442
|
+
return this.executeOne(step, agentMap, errorHandling, state);
|
|
47443
|
+
}
|
|
47444
|
+
async executeWithProcessSpawner(step, state, agentMap, errorHandling) {
|
|
47445
|
+
const spawner = this.deps.processSpawner;
|
|
47446
|
+
if (!spawner) {
|
|
47447
|
+
throw new Error(`No step execution callback or process spawner configured for step "${step.name}"`);
|
|
47448
|
+
}
|
|
47449
|
+
const maxRetries = step.retries ?? errorHandling?.maxRetries ?? 0;
|
|
47450
|
+
return this.monitorStep(step, state, {
|
|
47451
|
+
maxRetries,
|
|
47452
|
+
retryDelayMs: errorHandling?.retryDelayMs ?? 1e3,
|
|
47453
|
+
startMessage: `**[${step.name}]** Started`,
|
|
47454
|
+
onRetry: (attempt, total) => {
|
|
47455
|
+
this.deps.postToChannel?.(`**[${step.name}]** Retrying (attempt ${attempt + 1}/${total + 1})`);
|
|
47456
|
+
},
|
|
47457
|
+
execute: async () => {
|
|
47458
|
+
if (step.type === "deterministic") {
|
|
47459
|
+
const command = step.command ?? "";
|
|
47460
|
+
return spawner.spawnShell(command, { cwd: this.deps.cwd, timeoutMs: step.timeoutMs });
|
|
47461
|
+
}
|
|
47462
|
+
const agent = step.agent ? agentMap.get(step.agent) : void 0;
|
|
47463
|
+
if (!agent) {
|
|
47464
|
+
throw new Error(`Agent "${step.agent ?? "(missing)"}" not found in config`);
|
|
47465
|
+
}
|
|
47466
|
+
const task = step.task ?? "";
|
|
47467
|
+
if (agent.interactive === false) {
|
|
47468
|
+
return spawner.spawnAgent(agent, task, { cwd: this.deps.cwd, timeoutMs: step.timeoutMs });
|
|
47469
|
+
}
|
|
47470
|
+
return spawner.spawnInteractive(agent, task, { cwd: this.deps.cwd, timeoutMs: step.timeoutMs });
|
|
47471
|
+
},
|
|
47472
|
+
toCompletionResult: (spawnResult, attempt) => {
|
|
47473
|
+
const failOnError = step.failOnError !== false;
|
|
47474
|
+
const failed = failOnError && ((spawnResult.exitCode ?? 0) !== 0 || spawnResult.exitCode === void 0 && spawnResult.exitSignal !== void 0);
|
|
47475
|
+
const output = step.captureOutput === false ? `Command completed (exit code ${spawnResult.exitCode ?? 0})` : spawnResult.output;
|
|
47476
|
+
if (failed) {
|
|
47477
|
+
return {
|
|
47478
|
+
status: "failed",
|
|
47479
|
+
output,
|
|
47480
|
+
exitCode: spawnResult.exitCode,
|
|
47481
|
+
exitSignal: spawnResult.exitSignal,
|
|
47482
|
+
retries: attempt,
|
|
47483
|
+
error: spawnResult.output || `Command failed with exit code ${spawnResult.exitCode ?? "unknown"}`
|
|
47484
|
+
};
|
|
47485
|
+
}
|
|
47486
|
+
return {
|
|
47487
|
+
status: "completed",
|
|
47488
|
+
output,
|
|
47489
|
+
exitCode: spawnResult.exitCode,
|
|
47490
|
+
exitSignal: spawnResult.exitSignal,
|
|
47491
|
+
retries: attempt
|
|
47492
|
+
};
|
|
47493
|
+
}
|
|
47494
|
+
});
|
|
47495
|
+
}
|
|
47496
|
+
createEphemeralStates(steps) {
|
|
47497
|
+
return new Map(steps.map((step) => [step.name, this.createEphemeralState(step)]));
|
|
47498
|
+
}
|
|
47499
|
+
createEphemeralState(step) {
|
|
47500
|
+
return {
|
|
47501
|
+
row: {
|
|
47502
|
+
id: `step-${step.name}`,
|
|
47503
|
+
runId: this.deps.runId ?? "run",
|
|
47504
|
+
stepName: step.name,
|
|
47505
|
+
agentName: step.agent ?? null,
|
|
47506
|
+
stepType: step.type ?? "agent",
|
|
47507
|
+
status: "pending",
|
|
47508
|
+
task: step.task ?? step.command ?? step.branch ?? "",
|
|
47509
|
+
dependsOn: step.dependsOn ?? [],
|
|
47510
|
+
retryCount: 0,
|
|
47511
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
47512
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
47513
|
+
}
|
|
47514
|
+
};
|
|
47515
|
+
}
|
|
47516
|
+
getStatus(state) {
|
|
47517
|
+
if (typeof state === "string")
|
|
47518
|
+
return state;
|
|
47519
|
+
return state?.row.status;
|
|
47520
|
+
}
|
|
47521
|
+
};
|
|
47522
|
+
function normalizeStrategy(strategy) {
|
|
47523
|
+
if (strategy === "continue")
|
|
47524
|
+
return "continue";
|
|
47525
|
+
return "fail-fast";
|
|
47526
|
+
}
|
|
47527
|
+
function delay(ms) {
|
|
47528
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
47529
|
+
}
|
|
47530
|
+
|
|
46406
47531
|
// packages/sdk/dist/workflows/trajectory.js
|
|
46407
47532
|
var import_node_crypto4 = require("node:crypto");
|
|
46408
|
-
var
|
|
47533
|
+
var import_node_fs10 = require("node:fs");
|
|
46409
47534
|
var import_promises4 = require("node:fs/promises");
|
|
46410
|
-
var
|
|
47535
|
+
var import_node_path13 = __toESM(require("node:path"), 1);
|
|
46411
47536
|
function classifyFailure(error48) {
|
|
46412
47537
|
const e = error48.toLowerCase();
|
|
46413
47538
|
if (e.includes("timed out") || e.includes("timeout"))
|
|
@@ -46459,7 +47584,7 @@ var WorkflowTrajectory = class {
|
|
|
46459
47584
|
this.reflectOnConverge = cfg.reflectOnConverge !== false;
|
|
46460
47585
|
this.autoDecisions = cfg.autoDecisions !== false;
|
|
46461
47586
|
this.runId = runId;
|
|
46462
|
-
this.dataDir = process.env.TRAJECTORIES_DATA_DIR ??
|
|
47587
|
+
this.dataDir = process.env.TRAJECTORIES_DATA_DIR ?? import_node_path13.default.join(cwd, ".trajectories");
|
|
46463
47588
|
}
|
|
46464
47589
|
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
|
46465
47590
|
/** Start the trajectory (called at run:started). */
|
|
@@ -46868,9 +47993,9 @@ var WorkflowTrajectory = class {
|
|
|
46868
47993
|
if (!this.trajectory)
|
|
46869
47994
|
return;
|
|
46870
47995
|
try {
|
|
46871
|
-
const activeDir =
|
|
47996
|
+
const activeDir = import_node_path13.default.join(this.dataDir, "active");
|
|
46872
47997
|
await (0, import_promises4.mkdir)(activeDir, { recursive: true });
|
|
46873
|
-
const filePath =
|
|
47998
|
+
const filePath = import_node_path13.default.join(activeDir, `${this.trajectory.id}.json`);
|
|
46874
47999
|
await (0, import_promises4.writeFile)(filePath, JSON.stringify(this.trajectory, null, 2), "utf-8");
|
|
46875
48000
|
} catch {
|
|
46876
48001
|
}
|
|
@@ -46879,12 +48004,12 @@ var WorkflowTrajectory = class {
|
|
|
46879
48004
|
if (!this.trajectory)
|
|
46880
48005
|
return;
|
|
46881
48006
|
try {
|
|
46882
|
-
const activeDir =
|
|
46883
|
-
const completedDir =
|
|
48007
|
+
const activeDir = import_node_path13.default.join(this.dataDir, "active");
|
|
48008
|
+
const completedDir = import_node_path13.default.join(this.dataDir, "completed");
|
|
46884
48009
|
await (0, import_promises4.mkdir)(completedDir, { recursive: true });
|
|
46885
|
-
const activePath =
|
|
46886
|
-
const completedPath =
|
|
46887
|
-
if ((0,
|
|
48010
|
+
const activePath = import_node_path13.default.join(activeDir, `${this.trajectory.id}.json`);
|
|
48011
|
+
const completedPath = import_node_path13.default.join(completedDir, `${this.trajectory.id}.json`);
|
|
48012
|
+
if ((0, import_node_fs10.existsSync)(activePath)) {
|
|
46888
48013
|
await (0, import_promises4.rename)(activePath, completedPath);
|
|
46889
48014
|
}
|
|
46890
48015
|
} catch {
|
|
@@ -46893,6 +48018,53 @@ var WorkflowTrajectory = class {
|
|
|
46893
48018
|
};
|
|
46894
48019
|
|
|
46895
48020
|
// packages/sdk/dist/workflows/runner.js
|
|
48021
|
+
var ENV_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
48022
|
+
"PATH",
|
|
48023
|
+
"HOME",
|
|
48024
|
+
"USER",
|
|
48025
|
+
"SHELL",
|
|
48026
|
+
"LANG",
|
|
48027
|
+
"TERM",
|
|
48028
|
+
"TMPDIR",
|
|
48029
|
+
"TZ",
|
|
48030
|
+
"NODE_ENV",
|
|
48031
|
+
"NODE_PATH",
|
|
48032
|
+
"NODE_OPTIONS",
|
|
48033
|
+
"NODE_EXTRA_CA_CERTS",
|
|
48034
|
+
"RUST_LOG",
|
|
48035
|
+
"RUST_BACKTRACE",
|
|
48036
|
+
"RELAY_API_KEY",
|
|
48037
|
+
"RELAYCAST_BASE_URL",
|
|
48038
|
+
"AGENT_RELAY_DASHBOARD_PORT",
|
|
48039
|
+
"AGENT_RELAY_RUN_ID_FILE",
|
|
48040
|
+
"EDITOR",
|
|
48041
|
+
"VISUAL",
|
|
48042
|
+
"GIT_AUTHOR_NAME",
|
|
48043
|
+
"GIT_AUTHOR_EMAIL",
|
|
48044
|
+
"GIT_COMMITTER_NAME",
|
|
48045
|
+
"GIT_COMMITTER_EMAIL",
|
|
48046
|
+
"HTTPS_PROXY",
|
|
48047
|
+
"HTTP_PROXY",
|
|
48048
|
+
"NO_PROXY",
|
|
48049
|
+
"https_proxy",
|
|
48050
|
+
"http_proxy",
|
|
48051
|
+
"no_proxy",
|
|
48052
|
+
"XDG_CONFIG_HOME",
|
|
48053
|
+
"XDG_DATA_HOME",
|
|
48054
|
+
"XDG_CACHE_HOME"
|
|
48055
|
+
]);
|
|
48056
|
+
function filteredEnv(extra) {
|
|
48057
|
+
const env = {};
|
|
48058
|
+
for (const key of ENV_ALLOWLIST) {
|
|
48059
|
+
if (process.env[key] !== void 0) {
|
|
48060
|
+
env[key] = process.env[key];
|
|
48061
|
+
}
|
|
48062
|
+
}
|
|
48063
|
+
if (extra) {
|
|
48064
|
+
Object.assign(env, extra);
|
|
48065
|
+
}
|
|
48066
|
+
return env;
|
|
48067
|
+
}
|
|
46896
48068
|
var SpawnExitError = class extends Error {
|
|
46897
48069
|
exitCode;
|
|
46898
48070
|
exitSignal;
|
|
@@ -46903,14 +48075,6 @@ var SpawnExitError = class extends Error {
|
|
|
46903
48075
|
this.exitSignal = exitSignal ?? void 0;
|
|
46904
48076
|
}
|
|
46905
48077
|
};
|
|
46906
|
-
var WorkflowCompletionError = class extends Error {
|
|
46907
|
-
completionReason;
|
|
46908
|
-
constructor(message, completionReason) {
|
|
46909
|
-
super(message);
|
|
46910
|
-
this.name = "WorkflowCompletionError";
|
|
46911
|
-
this.completionReason = completionReason;
|
|
46912
|
-
}
|
|
46913
|
-
};
|
|
46914
48078
|
function resolveCursorCli() {
|
|
46915
48079
|
const resolved = resolveCliSync("cursor");
|
|
46916
48080
|
return resolved?.binary ?? "agent";
|
|
@@ -46923,6 +48087,8 @@ var WorkflowRunner = class _WorkflowRunner {
|
|
|
46923
48087
|
summaryDir;
|
|
46924
48088
|
executor;
|
|
46925
48089
|
envSecrets;
|
|
48090
|
+
templateResolver;
|
|
48091
|
+
channelMessenger;
|
|
46926
48092
|
/** @internal exposed for CLI signal-handler shutdown only */
|
|
46927
48093
|
relay;
|
|
46928
48094
|
relaycast;
|
|
@@ -46982,10 +48148,12 @@ var WorkflowRunner = class _WorkflowRunner {
|
|
|
46982
48148
|
this.workspaceId = options.workspaceId ?? "local";
|
|
46983
48149
|
this.relayOptions = options.relay ?? {};
|
|
46984
48150
|
this.cwd = options.cwd ?? process.cwd();
|
|
46985
|
-
this.summaryDir = options.summaryDir ??
|
|
46986
|
-
this.workersPath =
|
|
48151
|
+
this.summaryDir = options.summaryDir ?? import_node_path14.default.join(this.cwd, ".relay", "summaries");
|
|
48152
|
+
this.workersPath = import_node_path14.default.join(this.cwd, ".agent-relay", "team", "workers.json");
|
|
46987
48153
|
this.executor = options.executor;
|
|
46988
48154
|
this.envSecrets = options.envSecrets;
|
|
48155
|
+
this.templateResolver = new TemplateResolver();
|
|
48156
|
+
this.channelMessenger = new ChannelMessenger({ postFn: (text) => this.postToChannel(text) });
|
|
46989
48157
|
}
|
|
46990
48158
|
// ── Path resolution ─────────────────────────────────────────────────────
|
|
46991
48159
|
/** Expand environment variables like $HOME or $VAR in a path string. */
|
|
@@ -47013,10 +48181,10 @@ var WorkflowRunner = class _WorkflowRunner {
|
|
|
47013
48181
|
}
|
|
47014
48182
|
seenNames.add(pd.name);
|
|
47015
48183
|
const expanded = _WorkflowRunner.resolveEnvVars(pd.path);
|
|
47016
|
-
const abs =
|
|
48184
|
+
const abs = import_node_path14.default.resolve(baseCwd, expanded);
|
|
47017
48185
|
resolved.set(pd.name, abs);
|
|
47018
48186
|
const isRequired = pd.required !== false;
|
|
47019
|
-
if (!(0,
|
|
48187
|
+
if (!(0, import_node_fs11.existsSync)(abs)) {
|
|
47020
48188
|
if (isRequired) {
|
|
47021
48189
|
errors.push(`Path "${pd.name}" resolves to "${abs}" which does not exist (required)`);
|
|
47022
48190
|
} else {
|
|
@@ -47039,7 +48207,7 @@ var WorkflowRunner = class _WorkflowRunner {
|
|
|
47039
48207
|
return resolved;
|
|
47040
48208
|
}
|
|
47041
48209
|
if (agent.cwd) {
|
|
47042
|
-
return
|
|
48210
|
+
return import_node_path14.default.resolve(this.cwd, agent.cwd);
|
|
47043
48211
|
}
|
|
47044
48212
|
return this.cwd;
|
|
47045
48213
|
}
|
|
@@ -47058,7 +48226,7 @@ var WorkflowRunner = class _WorkflowRunner {
|
|
|
47058
48226
|
}
|
|
47059
48227
|
resolveEffectiveCwd(step, agentDef) {
|
|
47060
48228
|
if (step.cwd) {
|
|
47061
|
-
return
|
|
48229
|
+
return import_node_path14.default.resolve(this.cwd, step.cwd);
|
|
47062
48230
|
}
|
|
47063
48231
|
return this.resolveStepWorkdir(step) ?? (agentDef ? this.resolveAgentCwd(agentDef) : this.cwd);
|
|
47064
48232
|
}
|
|
@@ -47352,16 +48520,18 @@ ${next}` : next;
|
|
|
47352
48520
|
return void 0;
|
|
47353
48521
|
}
|
|
47354
48522
|
uniqueEvidenceRoots(roots) {
|
|
47355
|
-
return [
|
|
48523
|
+
return [
|
|
48524
|
+
...new Set(roots.filter((root) => Boolean(root)).map((root) => import_node_path14.default.resolve(root)))
|
|
48525
|
+
];
|
|
47356
48526
|
}
|
|
47357
48527
|
captureFileSnapshot(root) {
|
|
47358
48528
|
const snapshot = /* @__PURE__ */ new Map();
|
|
47359
|
-
if (!(0,
|
|
48529
|
+
if (!(0, import_node_fs11.existsSync)(root))
|
|
47360
48530
|
return snapshot;
|
|
47361
48531
|
const visit = (currentPath) => {
|
|
47362
48532
|
let entries;
|
|
47363
48533
|
try {
|
|
47364
|
-
entries = (0,
|
|
48534
|
+
entries = (0, import_node_fs11.readdirSync)(currentPath, { withFileTypes: true });
|
|
47365
48535
|
} catch {
|
|
47366
48536
|
return;
|
|
47367
48537
|
}
|
|
@@ -47369,13 +48539,13 @@ ${next}` : next;
|
|
|
47369
48539
|
if (entry.isDirectory() && _WorkflowRunner.EVIDENCE_IGNORED_DIRS.has(entry.name)) {
|
|
47370
48540
|
continue;
|
|
47371
48541
|
}
|
|
47372
|
-
const fullPath =
|
|
48542
|
+
const fullPath = import_node_path14.default.join(currentPath, entry.name);
|
|
47373
48543
|
if (entry.isDirectory()) {
|
|
47374
48544
|
visit(fullPath);
|
|
47375
48545
|
continue;
|
|
47376
48546
|
}
|
|
47377
48547
|
try {
|
|
47378
|
-
const stats = (0,
|
|
48548
|
+
const stats = (0, import_node_fs11.statSync)(fullPath);
|
|
47379
48549
|
if (!stats.isFile())
|
|
47380
48550
|
continue;
|
|
47381
48551
|
snapshot.set(fullPath, { mtimeMs: stats.mtimeMs, size: stats.size });
|
|
@@ -47384,7 +48554,7 @@ ${next}` : next;
|
|
|
47384
48554
|
}
|
|
47385
48555
|
};
|
|
47386
48556
|
try {
|
|
47387
|
-
const stats = (0,
|
|
48557
|
+
const stats = (0, import_node_fs11.statSync)(root);
|
|
47388
48558
|
if (stats.isFile()) {
|
|
47389
48559
|
snapshot.set(root, { mtimeMs: stats.mtimeMs, size: stats.size });
|
|
47390
48560
|
return snapshot;
|
|
@@ -47421,9 +48591,9 @@ ${next}` : next;
|
|
|
47421
48591
|
return changes.sort((a, b) => a.path.localeCompare(b.path));
|
|
47422
48592
|
}
|
|
47423
48593
|
normalizeEvidencePath(filePath) {
|
|
47424
|
-
const relative =
|
|
48594
|
+
const relative = import_node_path14.default.relative(this.cwd, filePath);
|
|
47425
48595
|
if (!relative || relative === "")
|
|
47426
|
-
return
|
|
48596
|
+
return import_node_path14.default.basename(filePath);
|
|
47427
48597
|
return relative.startsWith("..") ? filePath : relative;
|
|
47428
48598
|
}
|
|
47429
48599
|
buildStepCompletionDecision(stepName, completionReason) {
|
|
@@ -47540,7 +48710,7 @@ ${next}` : next;
|
|
|
47540
48710
|
return this.relayOptions.env;
|
|
47541
48711
|
}
|
|
47542
48712
|
return {
|
|
47543
|
-
...this.relayOptions.env ??
|
|
48713
|
+
...this.relayOptions.env ?? filteredEnv(),
|
|
47544
48714
|
RELAY_API_KEY: this.relayApiKey
|
|
47545
48715
|
};
|
|
47546
48716
|
}
|
|
@@ -47631,7 +48801,7 @@ ${next}` : next;
|
|
|
47631
48801
|
// ── Parsing & validation ────────────────────────────────────────────────
|
|
47632
48802
|
/** Parse a relay.yaml file from disk. */
|
|
47633
48803
|
async parseYamlFile(filePath) {
|
|
47634
|
-
const absPath =
|
|
48804
|
+
const absPath = import_node_path14.default.resolve(this.cwd, filePath);
|
|
47635
48805
|
const raw = await (0, import_promises5.readFile)(absPath, "utf-8");
|
|
47636
48806
|
return this.parseYamlString(raw, absPath);
|
|
47637
48807
|
}
|
|
@@ -47785,15 +48955,15 @@ ${err.suggestion}`);
|
|
|
47785
48955
|
}
|
|
47786
48956
|
for (const agent of resolved.agents) {
|
|
47787
48957
|
if (agent.cwd) {
|
|
47788
|
-
const resolvedCwd =
|
|
47789
|
-
if (!(0,
|
|
48958
|
+
const resolvedCwd = import_node_path14.default.resolve(this.cwd, agent.cwd);
|
|
48959
|
+
if (!(0, import_node_fs11.existsSync)(resolvedCwd)) {
|
|
47790
48960
|
warnings.push(`Agent "${agent.name}" cwd "${agent.cwd}" resolves to "${resolvedCwd}" which does not exist`);
|
|
47791
48961
|
}
|
|
47792
48962
|
}
|
|
47793
48963
|
if (agent.additionalPaths) {
|
|
47794
48964
|
for (const ap of agent.additionalPaths) {
|
|
47795
|
-
const resolvedPath =
|
|
47796
|
-
if (!(0,
|
|
48965
|
+
const resolvedPath = import_node_path14.default.resolve(this.cwd, ap);
|
|
48966
|
+
if (!(0, import_node_fs11.existsSync)(resolvedPath)) {
|
|
47797
48967
|
warnings.push(`Agent "${agent.name}" additionalPath "${ap}" resolves to "${resolvedPath}" which does not exist`);
|
|
47798
48968
|
}
|
|
47799
48969
|
}
|
|
@@ -48034,65 +49204,13 @@ ${err.suggestion}`);
|
|
|
48034
49204
|
// ── Template variable resolution ────────────────────────────────────────
|
|
48035
49205
|
/** Resolve {{variable}} placeholders in all task strings. */
|
|
48036
49206
|
resolveVariables(config2, vars) {
|
|
48037
|
-
|
|
48038
|
-
for (const agent of resolved.agents) {
|
|
48039
|
-
if (agent.task) {
|
|
48040
|
-
agent.task = this.interpolate(agent.task, vars);
|
|
48041
|
-
}
|
|
48042
|
-
}
|
|
48043
|
-
if (resolved.workflows) {
|
|
48044
|
-
for (const wf of resolved.workflows) {
|
|
48045
|
-
for (const step of wf.steps) {
|
|
48046
|
-
if (step.task) {
|
|
48047
|
-
step.task = this.interpolate(step.task, vars);
|
|
48048
|
-
}
|
|
48049
|
-
if (step.command) {
|
|
48050
|
-
step.command = this.interpolate(step.command, vars);
|
|
48051
|
-
}
|
|
48052
|
-
if (step.params && typeof step.params === "object") {
|
|
48053
|
-
for (const key of Object.keys(step.params)) {
|
|
48054
|
-
const val = step.params[key];
|
|
48055
|
-
if (typeof val === "string") {
|
|
48056
|
-
step.params[key] = this.interpolate(val, vars);
|
|
48057
|
-
}
|
|
48058
|
-
}
|
|
48059
|
-
}
|
|
48060
|
-
}
|
|
48061
|
-
}
|
|
48062
|
-
}
|
|
48063
|
-
return resolved;
|
|
49207
|
+
return this.templateResolver.resolveVariables(config2, vars);
|
|
48064
49208
|
}
|
|
48065
49209
|
interpolate(template, vars) {
|
|
48066
|
-
return template
|
|
48067
|
-
if (key.startsWith("steps.")) {
|
|
48068
|
-
return _match;
|
|
48069
|
-
}
|
|
48070
|
-
const value = this.resolveDotPath(key, vars);
|
|
48071
|
-
if (value === void 0) {
|
|
48072
|
-
throw new Error(`Unresolved variable: {{${key}}}`);
|
|
48073
|
-
}
|
|
48074
|
-
return String(value);
|
|
48075
|
-
});
|
|
49210
|
+
return resolveTemplate(template, vars);
|
|
48076
49211
|
}
|
|
48077
49212
|
resolveDotPath(key, vars) {
|
|
48078
|
-
|
|
48079
|
-
return vars[key];
|
|
48080
|
-
}
|
|
48081
|
-
const parts = key.split(".");
|
|
48082
|
-
let current = vars;
|
|
48083
|
-
for (const part of parts) {
|
|
48084
|
-
if (current === null || current === void 0 || typeof current !== "object") {
|
|
48085
|
-
return void 0;
|
|
48086
|
-
}
|
|
48087
|
-
current = current[part];
|
|
48088
|
-
}
|
|
48089
|
-
if (current === void 0 || current === null) {
|
|
48090
|
-
return void 0;
|
|
48091
|
-
}
|
|
48092
|
-
if (typeof current === "string" || typeof current === "number" || typeof current === "boolean") {
|
|
48093
|
-
return current;
|
|
48094
|
-
}
|
|
48095
|
-
return String(current);
|
|
49213
|
+
return resolveDotPath(key, vars);
|
|
48096
49214
|
}
|
|
48097
49215
|
/** Build a nested context from completed step outputs for {{steps.X.output}} resolution. */
|
|
48098
49216
|
buildStepOutputContext(stepStates, runId) {
|
|
@@ -48112,13 +49230,80 @@ ${err.suggestion}`);
|
|
|
48112
49230
|
}
|
|
48113
49231
|
/** Interpolate step-output variables, silently skipping unresolved ones (they may be user vars). */
|
|
48114
49232
|
interpolateStepTask(template, context) {
|
|
48115
|
-
return template
|
|
48116
|
-
|
|
48117
|
-
|
|
48118
|
-
|
|
48119
|
-
|
|
48120
|
-
|
|
48121
|
-
|
|
49233
|
+
return interpolateStepTask(template, context);
|
|
49234
|
+
}
|
|
49235
|
+
createStepLifecycleExecutor(workflow2, stepStates, agentMap, errorHandling, runId) {
|
|
49236
|
+
let lifecycle;
|
|
49237
|
+
const deps = {
|
|
49238
|
+
cwd: this.cwd,
|
|
49239
|
+
runId,
|
|
49240
|
+
templateResolver: this.templateResolver,
|
|
49241
|
+
channelMessenger: this.channelMessenger,
|
|
49242
|
+
verificationRunner: (check2, output, stepName, injectedTaskText, options) => this.runVerification(check2, output, stepName, injectedTaskText, options),
|
|
49243
|
+
postToChannel: (text) => this.postToChannel(text),
|
|
49244
|
+
persistStepRow: async (stepId, patch) => this.db.updateStep(stepId, patch),
|
|
49245
|
+
persistStepOutput: async (lifecycleRunId, stepName, output) => this.persistStepOutput(lifecycleRunId, stepName, output),
|
|
49246
|
+
loadStepOutput: (lifecycleRunId, stepName) => this.loadStepOutput(lifecycleRunId, stepName),
|
|
49247
|
+
checkAborted: () => this.checkAborted(),
|
|
49248
|
+
waitIfPaused: () => this.waitIfPaused(),
|
|
49249
|
+
log: (message) => this.log(message),
|
|
49250
|
+
onStepStarted: async (step) => {
|
|
49251
|
+
this.emit({ type: "step:started", runId, stepName: step.name });
|
|
49252
|
+
},
|
|
49253
|
+
onStepCompleted: async (step, state, result) => {
|
|
49254
|
+
this.emit({
|
|
49255
|
+
type: "step:completed",
|
|
49256
|
+
runId,
|
|
49257
|
+
stepName: step.name,
|
|
49258
|
+
output: result.output,
|
|
49259
|
+
exitCode: result.exitCode,
|
|
49260
|
+
exitSignal: result.exitSignal
|
|
49261
|
+
});
|
|
49262
|
+
this.finalizeStepEvidence(step.name, result.status, state.row.completedAt, result.completionReason);
|
|
49263
|
+
},
|
|
49264
|
+
onStepFailed: async (step, state, result) => {
|
|
49265
|
+
this.captureStepTerminalEvidence(step.name, {}, {
|
|
49266
|
+
exitCode: result.exitCode,
|
|
49267
|
+
exitSignal: result.exitSignal
|
|
49268
|
+
});
|
|
49269
|
+
this.emit({
|
|
49270
|
+
type: "step:failed",
|
|
49271
|
+
runId,
|
|
49272
|
+
stepName: step.name,
|
|
49273
|
+
error: result.error ?? "Unknown error",
|
|
49274
|
+
exitCode: result.exitCode,
|
|
49275
|
+
exitSignal: result.exitSignal
|
|
49276
|
+
});
|
|
49277
|
+
this.finalizeStepEvidence(step.name, "failed", state.row.completedAt, result.completionReason);
|
|
49278
|
+
},
|
|
49279
|
+
executeStep: async (step, state) => {
|
|
49280
|
+
await this.executeStep(step, state, stepStates, agentMap, errorHandling, runId, lifecycle);
|
|
49281
|
+
return {
|
|
49282
|
+
status: state.row.status,
|
|
49283
|
+
output: state.row.output ?? "",
|
|
49284
|
+
completionReason: state.row.completionReason,
|
|
49285
|
+
retries: state.row.retryCount,
|
|
49286
|
+
error: state.row.error
|
|
49287
|
+
};
|
|
49288
|
+
},
|
|
49289
|
+
onBeginTrack: async (steps) => {
|
|
49290
|
+
if (steps.length > 1 && this.trajectory) {
|
|
49291
|
+
await this.trajectory.beginTrack(steps.map((step) => step.name).join(", "));
|
|
49292
|
+
}
|
|
49293
|
+
},
|
|
49294
|
+
onConverge: async (readySteps, batchOutcomes) => {
|
|
49295
|
+
if (readySteps.length <= 1 || !this.trajectory?.shouldReflectOnConverge()) {
|
|
49296
|
+
return;
|
|
49297
|
+
}
|
|
49298
|
+
const completedNames = new Set(batchOutcomes.filter((outcome) => outcome.status === "completed").map((outcome) => outcome.name));
|
|
49299
|
+
const unblocked = workflow2.steps.filter((step) => step.dependsOn?.some((dependency) => completedNames.has(dependency))).filter((step) => stepStates.get(step.name)?.row.status === "pending").map((step) => step.name);
|
|
49300
|
+
await this.trajectory.synthesizeAndReflect(readySteps.map((step) => step.name).join(" + "), batchOutcomes, unblocked.length > 0 ? unblocked : void 0);
|
|
49301
|
+
},
|
|
49302
|
+
markDownstreamSkipped: async (failedStepName) => this.markDownstreamSkipped(failedStepName, workflow2.steps, stepStates, runId),
|
|
49303
|
+
buildCompletionMode: (stepName, completionReason) => completionReason ? this.buildStepCompletionDecision(stepName, completionReason)?.mode : void 0
|
|
49304
|
+
};
|
|
49305
|
+
lifecycle = new StepExecutor(deps);
|
|
49306
|
+
return lifecycle;
|
|
48122
49307
|
}
|
|
48123
49308
|
// ── Execution ───────────────────────────────────────────────────────────
|
|
48124
49309
|
/** Execute a named workflow from a validated config. */
|
|
@@ -48324,7 +49509,7 @@ ${err.suggestion}`);
|
|
|
48324
49509
|
}
|
|
48325
49510
|
}
|
|
48326
49511
|
this.log("Starting broker...");
|
|
48327
|
-
const brokerBaseName =
|
|
49512
|
+
const brokerBaseName = import_node_path14.default.basename(this.cwd) || "workflow";
|
|
48328
49513
|
const brokerName = `${brokerBaseName}-${runId.slice(0, 8)}`;
|
|
48329
49514
|
this.relay = new AgentRelay({
|
|
48330
49515
|
...this.relayOptions,
|
|
@@ -48346,7 +49531,7 @@ ${err.suggestion}`);
|
|
|
48346
49531
|
if (/Read\(/.test(stripped)) {
|
|
48347
49532
|
const m = stripped.match(/Read\(\s*~?([^\s)"']{8,})/);
|
|
48348
49533
|
if (m) {
|
|
48349
|
-
const base =
|
|
49534
|
+
const base = import_node_path14.default.basename(m[1]);
|
|
48350
49535
|
activity = base.length >= 3 ? `Reading ${base}` : "Reading file...";
|
|
48351
49536
|
} else {
|
|
48352
49537
|
activity = "Reading file...";
|
|
@@ -48354,7 +49539,7 @@ ${err.suggestion}`);
|
|
|
48354
49539
|
} else if (/Edit\(/.test(stripped)) {
|
|
48355
49540
|
const m = stripped.match(/Edit\(\s*~?([^\s)"']{8,})/);
|
|
48356
49541
|
if (m) {
|
|
48357
|
-
const base =
|
|
49542
|
+
const base = import_node_path14.default.basename(m[1]);
|
|
48358
49543
|
activity = base.length >= 3 ? `Editing ${base}` : "Editing file...";
|
|
48359
49544
|
} else {
|
|
48360
49545
|
activity = "Editing file...";
|
|
@@ -48635,72 +49820,11 @@ ${err.suggestion}`);
|
|
|
48635
49820
|
async executeSteps(workflow2, stepStates, agentMap, errorHandling, runId) {
|
|
48636
49821
|
const rawStrategy = errorHandling?.strategy ?? workflow2.onError ?? "fail-fast";
|
|
48637
49822
|
const strategy = rawStrategy === "fail" ? "fail-fast" : rawStrategy === "skip" ? "continue" : rawStrategy === "retry" ? "fail-fast" : rawStrategy;
|
|
48638
|
-
|
|
48639
|
-
|
|
48640
|
-
|
|
48641
|
-
|
|
48642
|
-
|
|
48643
|
-
break;
|
|
48644
|
-
}
|
|
48645
|
-
if (readySteps.length > 1 && this.trajectory) {
|
|
48646
|
-
const trackNames = readySteps.map((s) => s.name).join(", ");
|
|
48647
|
-
await this.trajectory.beginTrack(trackNames);
|
|
48648
|
-
}
|
|
48649
|
-
const STAGGER_THRESHOLD = 3;
|
|
48650
|
-
const STAGGER_DELAY_MS = 2e3;
|
|
48651
|
-
const results = await Promise.allSettled(readySteps.map((step, i) => {
|
|
48652
|
-
const delay2 = readySteps.length > STAGGER_THRESHOLD ? i * STAGGER_DELAY_MS : 0;
|
|
48653
|
-
if (delay2 === 0) {
|
|
48654
|
-
return this.executeStep(step, stepStates, agentMap, errorHandling, runId);
|
|
48655
|
-
}
|
|
48656
|
-
return new Promise((resolve3) => setTimeout(resolve3, delay2)).then(() => this.executeStep(step, stepStates, agentMap, errorHandling, runId));
|
|
48657
|
-
}));
|
|
48658
|
-
const batchOutcomes = [];
|
|
48659
|
-
for (let i = 0; i < results.length; i++) {
|
|
48660
|
-
const result = results[i];
|
|
48661
|
-
const step = readySteps[i];
|
|
48662
|
-
const state = stepStates.get(step.name);
|
|
48663
|
-
if (result.status === "rejected") {
|
|
48664
|
-
const error48 = result.reason instanceof Error ? result.reason.message : String(result.reason);
|
|
48665
|
-
if (state && state.row.status !== "failed") {
|
|
48666
|
-
await this.markStepFailed(state, error48, runId);
|
|
48667
|
-
}
|
|
48668
|
-
batchOutcomes.push({
|
|
48669
|
-
name: step.name,
|
|
48670
|
-
agent: step.agent ?? "deterministic",
|
|
48671
|
-
status: "failed",
|
|
48672
|
-
attempts: (state?.row.retryCount ?? 0) + 1,
|
|
48673
|
-
error: error48
|
|
48674
|
-
});
|
|
48675
|
-
if (strategy === "fail-fast") {
|
|
48676
|
-
await this.markDownstreamSkipped(step.name, workflow2.steps, stepStates, runId);
|
|
48677
|
-
throw new Error(`Step "${step.name}" failed: ${error48}`);
|
|
48678
|
-
}
|
|
48679
|
-
if (strategy === "continue") {
|
|
48680
|
-
await this.markDownstreamSkipped(step.name, workflow2.steps, stepStates, runId);
|
|
48681
|
-
}
|
|
48682
|
-
} else {
|
|
48683
|
-
batchOutcomes.push({
|
|
48684
|
-
name: step.name,
|
|
48685
|
-
agent: step.agent ?? "deterministic",
|
|
48686
|
-
status: state?.row.status === "completed" ? "completed" : "failed",
|
|
48687
|
-
attempts: (state?.row.retryCount ?? 0) + 1,
|
|
48688
|
-
output: state?.row.output,
|
|
48689
|
-
verificationPassed: state?.row.status === "completed" && step.verification !== void 0,
|
|
48690
|
-
completionMode: state?.row.completionReason ? this.buildStepCompletionDecision(step.name, state.row.completionReason)?.mode : void 0
|
|
48691
|
-
});
|
|
48692
|
-
}
|
|
48693
|
-
}
|
|
48694
|
-
if (readySteps.length > 1 && this.trajectory?.shouldReflectOnConverge()) {
|
|
48695
|
-
const label = readySteps.map((s) => s.name).join(" + ");
|
|
48696
|
-
const completedNames = new Set(batchOutcomes.filter((o) => o.status === "completed").map((o) => o.name));
|
|
48697
|
-
const unblocked = workflow2.steps.filter((s) => s.dependsOn?.some((dep) => completedNames.has(dep))).filter((s) => {
|
|
48698
|
-
const st = stepStates.get(s.name);
|
|
48699
|
-
return st && st.row.status === "pending";
|
|
48700
|
-
}).map((s) => s.name);
|
|
48701
|
-
await this.trajectory.synthesizeAndReflect(label, batchOutcomes, unblocked.length > 0 ? unblocked : void 0);
|
|
48702
|
-
}
|
|
48703
|
-
}
|
|
49823
|
+
const lifecycle = this.createStepLifecycleExecutor(workflow2, stepStates, agentMap, errorHandling, runId);
|
|
49824
|
+
await lifecycle.executeAll(workflow2.steps, agentMap, {
|
|
49825
|
+
...errorHandling ?? { strategy: "fail-fast" },
|
|
49826
|
+
strategy
|
|
49827
|
+
}, stepStates);
|
|
48704
49828
|
}
|
|
48705
49829
|
findReadySteps(steps, stepStates) {
|
|
48706
49830
|
return steps.filter((step) => {
|
|
@@ -48725,11 +49849,11 @@ ${err.suggestion}`);
|
|
|
48725
49849
|
const description = check2.description ?? check2.command.slice(0, 50);
|
|
48726
49850
|
this.postToChannel(`**[preflight]** ${description}`);
|
|
48727
49851
|
try {
|
|
48728
|
-
const output = await new Promise((
|
|
48729
|
-
const child = (0,
|
|
49852
|
+
const output = await new Promise((resolve4, reject) => {
|
|
49853
|
+
const child = (0, import_node_child_process6.spawn)("sh", ["-c", check2.command], {
|
|
48730
49854
|
stdio: "pipe",
|
|
48731
49855
|
cwd: this.cwd,
|
|
48732
|
-
env:
|
|
49856
|
+
env: filteredEnv()
|
|
48733
49857
|
});
|
|
48734
49858
|
const stdoutChunks = [];
|
|
48735
49859
|
const stderrChunks = [];
|
|
@@ -48765,7 +49889,7 @@ ${err.suggestion}`);
|
|
|
48765
49889
|
reject(new Error(`Preflight check failed (exit ${code})${stderr ? `: ${stderr.slice(0, 200)}` : ""}`));
|
|
48766
49890
|
return;
|
|
48767
49891
|
}
|
|
48768
|
-
|
|
49892
|
+
resolve4(stdoutChunks.join(""));
|
|
48769
49893
|
});
|
|
48770
49894
|
child.on("error", (err) => {
|
|
48771
49895
|
clearTimeout(timer);
|
|
@@ -48818,15 +49942,15 @@ ${trimmedOutput.slice(0, 200)}`);
|
|
|
48818
49942
|
isIntegrationStep(step) {
|
|
48819
49943
|
return step.type === "integration";
|
|
48820
49944
|
}
|
|
48821
|
-
async executeStep(step, stepStates, agentMap, errorHandling, runId) {
|
|
49945
|
+
async executeStep(step, state, stepStates, agentMap, errorHandling, runId, lifecycle) {
|
|
48822
49946
|
if (this.isDeterministicStep(step)) {
|
|
48823
|
-
return this.executeDeterministicStep(step, stepStates, runId, errorHandling);
|
|
49947
|
+
return this.executeDeterministicStep(step, state, stepStates, runId, errorHandling, lifecycle);
|
|
48824
49948
|
}
|
|
48825
49949
|
if (this.isWorktreeStep(step)) {
|
|
48826
|
-
return this.executeWorktreeStep(step, stepStates, runId);
|
|
49950
|
+
return this.executeWorktreeStep(step, state, stepStates, runId, lifecycle);
|
|
48827
49951
|
}
|
|
48828
49952
|
if (this.isIntegrationStep(step)) {
|
|
48829
|
-
return this.executeIntegrationStep(step, stepStates, runId);
|
|
49953
|
+
return this.executeIntegrationStep(step, state, stepStates, runId, lifecycle);
|
|
48830
49954
|
}
|
|
48831
49955
|
return this.executeAgentStep(step, stepStates, agentMap, errorHandling, runId);
|
|
48832
49956
|
}
|
|
@@ -48834,92 +49958,213 @@ ${trimmedOutput.slice(0, 200)}`);
|
|
|
48834
49958
|
* Execute a deterministic step (shell command).
|
|
48835
49959
|
* Fast, reliable, $0 LLM cost.
|
|
48836
49960
|
*/
|
|
48837
|
-
async executeDeterministicStep(step, stepStates, runId, errorHandling) {
|
|
48838
|
-
const state = stepStates.get(step.name);
|
|
48839
|
-
if (!state)
|
|
48840
|
-
throw new Error(`Step state not found: ${step.name}`);
|
|
49961
|
+
async executeDeterministicStep(step, state, stepStates, runId, errorHandling, lifecycle) {
|
|
48841
49962
|
const maxRetries = step.retries ?? errorHandling?.maxRetries ?? 0;
|
|
48842
49963
|
const retryDelay = errorHandling?.retryDelayMs ?? 1e3;
|
|
48843
|
-
let lastError;
|
|
49964
|
+
let lastError = "Unknown error";
|
|
48844
49965
|
let lastCompletionReason;
|
|
48845
49966
|
let lastExitCode;
|
|
48846
49967
|
let lastExitSignal;
|
|
48847
|
-
|
|
48848
|
-
|
|
48849
|
-
|
|
48850
|
-
|
|
48851
|
-
|
|
49968
|
+
const result = await lifecycle.monitorStep(step, state, {
|
|
49969
|
+
maxRetries,
|
|
49970
|
+
retryDelayMs: retryDelay,
|
|
49971
|
+
startMessage: `**[${step.name}]** Started (deterministic)`,
|
|
49972
|
+
onRetry: async (attempt, total) => {
|
|
48852
49973
|
this.emit({ type: "step:retrying", runId, stepName: step.name, attempt });
|
|
48853
|
-
this.postToChannel(`**[${step.name}]** Retrying (attempt ${attempt + 1}/${
|
|
49974
|
+
this.postToChannel(`**[${step.name}]** Retrying (attempt ${attempt + 1}/${total + 1})`);
|
|
48854
49975
|
this.recordStepToolSideEffect(step.name, {
|
|
48855
49976
|
type: "retry",
|
|
48856
|
-
detail: `Retrying attempt ${attempt + 1}/${
|
|
48857
|
-
raw: { attempt, maxRetries }
|
|
49977
|
+
detail: `Retrying attempt ${attempt + 1}/${total + 1}`,
|
|
49978
|
+
raw: { attempt, maxRetries: total }
|
|
48858
49979
|
});
|
|
48859
|
-
|
|
48860
|
-
|
|
48861
|
-
|
|
48862
|
-
|
|
49980
|
+
},
|
|
49981
|
+
execute: async () => {
|
|
49982
|
+
const stepOutputContext = this.buildStepOutputContext(stepStates, runId);
|
|
49983
|
+
let resolvedCommand = this.interpolateStepTask(step.command ?? "", stepOutputContext);
|
|
49984
|
+
resolvedCommand = resolvedCommand.replace(/\{\{([\w][\w.\-]*)\}\}/g, (_match, key) => {
|
|
49985
|
+
if (key.startsWith("steps."))
|
|
49986
|
+
return _match;
|
|
49987
|
+
const value = this.resolveDotPath(key, stepOutputContext);
|
|
49988
|
+
return value !== void 0 ? String(value) : _match;
|
|
48863
49989
|
});
|
|
48864
|
-
|
|
48865
|
-
|
|
48866
|
-
state.row.status = "running";
|
|
48867
|
-
state.row.error = void 0;
|
|
48868
|
-
state.row.completionReason = void 0;
|
|
48869
|
-
state.row.startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
48870
|
-
await this.db.updateStep(state.row.id, {
|
|
48871
|
-
status: "running",
|
|
48872
|
-
error: void 0,
|
|
48873
|
-
completionReason: void 0,
|
|
48874
|
-
startedAt: state.row.startedAt,
|
|
48875
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
48876
|
-
});
|
|
48877
|
-
this.emit({ type: "step:started", runId, stepName: step.name });
|
|
48878
|
-
this.postToChannel(`**[${step.name}]** Started (deterministic)`);
|
|
48879
|
-
const stepOutputContext = this.buildStepOutputContext(stepStates, runId);
|
|
48880
|
-
let resolvedCommand = this.interpolateStepTask(step.command ?? "", stepOutputContext);
|
|
48881
|
-
resolvedCommand = resolvedCommand.replace(/\{\{([\w][\w.\-]*)\}\}/g, (_match, key) => {
|
|
48882
|
-
if (key.startsWith("steps."))
|
|
48883
|
-
return _match;
|
|
48884
|
-
const value = this.resolveDotPath(key, stepOutputContext);
|
|
48885
|
-
return value !== void 0 ? String(value) : _match;
|
|
48886
|
-
});
|
|
48887
|
-
const stepCwd = this.resolveEffectiveCwd(step);
|
|
48888
|
-
this.beginStepEvidence(step.name, [stepCwd], state.row.startedAt);
|
|
48889
|
-
try {
|
|
49990
|
+
const stepCwd = this.resolveEffectiveCwd(step);
|
|
49991
|
+
this.beginStepEvidence(step.name, [stepCwd], state.row.startedAt);
|
|
48890
49992
|
if (this.executor?.executeDeterministicStep) {
|
|
48891
|
-
const
|
|
48892
|
-
lastExitCode =
|
|
49993
|
+
const executorResult = await this.executor.executeDeterministicStep(step, resolvedCommand, stepCwd);
|
|
49994
|
+
lastExitCode = executorResult.exitCode;
|
|
49995
|
+
lastExitSignal = void 0;
|
|
48893
49996
|
const failOnError = step.failOnError !== false;
|
|
48894
|
-
if (failOnError &&
|
|
48895
|
-
throw new Error(`Command failed with exit code ${
|
|
49997
|
+
if (failOnError && executorResult.exitCode !== 0) {
|
|
49998
|
+
throw new Error(`Command failed with exit code ${executorResult.exitCode}: ${executorResult.output.slice(0, 500)}`);
|
|
48896
49999
|
}
|
|
48897
|
-
const output2 = step.captureOutput !== false ?
|
|
48898
|
-
this.captureStepTerminalEvidence(step.name, { stdout:
|
|
50000
|
+
const output2 = step.captureOutput !== false ? executorResult.output : `Command completed (exit code ${executorResult.exitCode})`;
|
|
50001
|
+
this.captureStepTerminalEvidence(step.name, { stdout: executorResult.output, combined: executorResult.output }, { exitCode: executorResult.exitCode });
|
|
48899
50002
|
const verificationResult2 = step.verification ? this.runVerification(step.verification, output2, step.name) : void 0;
|
|
48900
|
-
|
|
48901
|
-
state.row.output = output2;
|
|
48902
|
-
state.row.completionReason = verificationResult2?.completionReason;
|
|
48903
|
-
state.row.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
48904
|
-
await this.db.updateStep(state.row.id, {
|
|
48905
|
-
status: "completed",
|
|
50003
|
+
return {
|
|
48906
50004
|
output: output2,
|
|
48907
|
-
completionReason: verificationResult2?.completionReason
|
|
48908
|
-
|
|
48909
|
-
|
|
50005
|
+
completionReason: verificationResult2?.completionReason
|
|
50006
|
+
};
|
|
50007
|
+
}
|
|
50008
|
+
let commandStdout = "";
|
|
50009
|
+
let commandStderr = "";
|
|
50010
|
+
const output = await new Promise((resolve4, reject) => {
|
|
50011
|
+
const child = (0, import_node_child_process6.spawn)("sh", ["-c", resolvedCommand], {
|
|
50012
|
+
stdio: "pipe",
|
|
50013
|
+
cwd: stepCwd,
|
|
50014
|
+
env: filteredEnv()
|
|
48910
50015
|
});
|
|
48911
|
-
|
|
48912
|
-
|
|
48913
|
-
|
|
48914
|
-
|
|
50016
|
+
const stdoutChunks = [];
|
|
50017
|
+
const stderrChunks = [];
|
|
50018
|
+
const abortSignal = this.abortController?.signal;
|
|
50019
|
+
let abortHandler;
|
|
50020
|
+
if (abortSignal && !abortSignal.aborted) {
|
|
50021
|
+
abortHandler = () => {
|
|
50022
|
+
child.kill("SIGTERM");
|
|
50023
|
+
setTimeout(() => child.kill("SIGKILL"), 5e3);
|
|
50024
|
+
};
|
|
50025
|
+
abortSignal.addEventListener("abort", abortHandler, { once: true });
|
|
50026
|
+
}
|
|
50027
|
+
let timedOut = false;
|
|
50028
|
+
let timer;
|
|
50029
|
+
if (step.timeoutMs) {
|
|
50030
|
+
timer = setTimeout(() => {
|
|
50031
|
+
timedOut = true;
|
|
50032
|
+
child.kill("SIGTERM");
|
|
50033
|
+
setTimeout(() => child.kill("SIGKILL"), 5e3);
|
|
50034
|
+
}, step.timeoutMs);
|
|
50035
|
+
}
|
|
50036
|
+
child.stdout?.on("data", (chunk) => {
|
|
50037
|
+
stdoutChunks.push(chunk.toString());
|
|
50038
|
+
});
|
|
50039
|
+
child.stderr?.on("data", (chunk) => {
|
|
50040
|
+
stderrChunks.push(chunk.toString());
|
|
50041
|
+
});
|
|
50042
|
+
child.on("close", (code, signal) => {
|
|
50043
|
+
if (timer)
|
|
50044
|
+
clearTimeout(timer);
|
|
50045
|
+
if (abortHandler && abortSignal) {
|
|
50046
|
+
abortSignal.removeEventListener("abort", abortHandler);
|
|
50047
|
+
}
|
|
50048
|
+
if (abortSignal?.aborted) {
|
|
50049
|
+
reject(new Error(`Step "${step.name}" aborted`));
|
|
50050
|
+
return;
|
|
50051
|
+
}
|
|
50052
|
+
if (timedOut) {
|
|
50053
|
+
reject(new Error(`Step "${step.name}" timed out (no step timeout set, check global swarm.timeoutMs)`));
|
|
50054
|
+
return;
|
|
50055
|
+
}
|
|
50056
|
+
const stdout = stdoutChunks.join("");
|
|
50057
|
+
const stderr = stderrChunks.join("");
|
|
50058
|
+
commandStdout = stdout;
|
|
50059
|
+
commandStderr = stderr;
|
|
50060
|
+
lastExitCode = code ?? void 0;
|
|
50061
|
+
lastExitSignal = signal ?? void 0;
|
|
50062
|
+
const failOnError = step.failOnError !== false;
|
|
50063
|
+
if (failOnError && code !== 0 && code !== null) {
|
|
50064
|
+
reject(new Error(`Command failed with exit code ${code}${stderr ? `: ${stderr.slice(0, 500)}` : ""}`));
|
|
50065
|
+
return;
|
|
50066
|
+
}
|
|
50067
|
+
resolve4(step.captureOutput !== false ? stdout : `Command completed (exit code ${code ?? 0})`);
|
|
50068
|
+
});
|
|
50069
|
+
child.on("error", (err) => {
|
|
50070
|
+
if (timer)
|
|
50071
|
+
clearTimeout(timer);
|
|
50072
|
+
if (abortHandler && abortSignal) {
|
|
50073
|
+
abortSignal.removeEventListener("abort", abortHandler);
|
|
50074
|
+
}
|
|
50075
|
+
reject(new Error(`Failed to execute command: ${err.message}`));
|
|
50076
|
+
});
|
|
50077
|
+
});
|
|
50078
|
+
this.captureStepTerminalEvidence(step.name, {
|
|
50079
|
+
stdout: commandStdout || output,
|
|
50080
|
+
stderr: commandStderr,
|
|
50081
|
+
combined: [commandStdout || output, commandStderr].filter(Boolean).join("\n")
|
|
50082
|
+
}, { exitCode: lastExitCode, exitSignal: lastExitSignal });
|
|
50083
|
+
const verificationResult = step.verification ? this.runVerification(step.verification, output, step.name) : void 0;
|
|
50084
|
+
return {
|
|
50085
|
+
output,
|
|
50086
|
+
completionReason: verificationResult?.completionReason
|
|
50087
|
+
};
|
|
50088
|
+
},
|
|
50089
|
+
toCompletionResult: ({ output, completionReason }, attempt) => ({
|
|
50090
|
+
status: "completed",
|
|
50091
|
+
output,
|
|
50092
|
+
completionReason,
|
|
50093
|
+
retries: attempt,
|
|
50094
|
+
exitCode: lastExitCode,
|
|
50095
|
+
exitSignal: lastExitSignal
|
|
50096
|
+
}),
|
|
50097
|
+
onAttemptFailed: async (error48) => {
|
|
50098
|
+
lastError = error48 instanceof Error ? error48.message : String(error48);
|
|
50099
|
+
lastCompletionReason = error48 instanceof WorkflowCompletionError ? error48.completionReason : void 0;
|
|
50100
|
+
},
|
|
50101
|
+
getFailureResult: () => ({
|
|
50102
|
+
status: "failed",
|
|
50103
|
+
output: "",
|
|
50104
|
+
error: lastError,
|
|
50105
|
+
retries: state.row.retryCount,
|
|
50106
|
+
exitCode: lastExitCode,
|
|
50107
|
+
exitSignal: lastExitSignal,
|
|
50108
|
+
completionReason: lastCompletionReason
|
|
50109
|
+
})
|
|
50110
|
+
});
|
|
50111
|
+
if (result.status === "failed") {
|
|
50112
|
+
this.postToChannel(`**[${step.name}]** Failed: ${result.error ?? "Unknown error"}`);
|
|
50113
|
+
throw new Error(`Step "${step.name}" failed: ${result.error ?? "Unknown error"}`);
|
|
50114
|
+
}
|
|
50115
|
+
}
|
|
50116
|
+
/**
|
|
50117
|
+
* Execute a worktree step (git worktree setup).
|
|
50118
|
+
* Fast, reliable, $0 LLM cost.
|
|
50119
|
+
* Outputs the worktree path for downstream steps to use.
|
|
50120
|
+
*/
|
|
50121
|
+
async executeWorktreeStep(step, state, stepStates, runId, lifecycle) {
|
|
50122
|
+
let lastExitCode;
|
|
50123
|
+
let lastExitSignal;
|
|
50124
|
+
let worktreeBranch = "";
|
|
50125
|
+
let createdBranch = false;
|
|
50126
|
+
const result = await lifecycle.monitorStep(step, state, {
|
|
50127
|
+
startMessage: `**[${step.name}]** Started (worktree setup)`,
|
|
50128
|
+
execute: async () => {
|
|
50129
|
+
const stepOutputContext = this.buildStepOutputContext(stepStates, runId);
|
|
50130
|
+
const branch = this.interpolateStepTask(step.branch ?? "", stepOutputContext);
|
|
50131
|
+
const baseBranch = step.baseBranch ? this.interpolateStepTask(step.baseBranch, stepOutputContext) : "HEAD";
|
|
50132
|
+
const worktreePath = step.path ? this.interpolateStepTask(step.path, stepOutputContext) : import_node_path14.default.join(".worktrees", step.name);
|
|
50133
|
+
const createBranch = step.createBranch !== false;
|
|
50134
|
+
const stepCwd = this.resolveStepWorkdir(step) ?? this.cwd;
|
|
50135
|
+
this.beginStepEvidence(step.name, [stepCwd], state.row.startedAt);
|
|
50136
|
+
if (!branch) {
|
|
50137
|
+
throw new Error('Worktree step missing required "branch" field');
|
|
50138
|
+
}
|
|
50139
|
+
const absoluteWorktreePath = import_node_path14.default.resolve(stepCwd, worktreePath);
|
|
50140
|
+
let branchExists = false;
|
|
50141
|
+
await new Promise((resolve4) => {
|
|
50142
|
+
const checkChild = (0, import_node_child_process6.spawn)("git", ["rev-parse", "--verify", "--quiet", branch], {
|
|
50143
|
+
stdio: "pipe",
|
|
50144
|
+
cwd: stepCwd,
|
|
50145
|
+
env: filteredEnv()
|
|
50146
|
+
});
|
|
50147
|
+
checkChild.on("close", (code) => {
|
|
50148
|
+
branchExists = code === 0;
|
|
50149
|
+
resolve4();
|
|
50150
|
+
});
|
|
50151
|
+
checkChild.on("error", () => resolve4());
|
|
50152
|
+
});
|
|
50153
|
+
let worktreeArgs;
|
|
50154
|
+
if (branchExists) {
|
|
50155
|
+
worktreeArgs = ["worktree", "add", absoluteWorktreePath, branch];
|
|
50156
|
+
} else if (createBranch) {
|
|
50157
|
+
worktreeArgs = ["worktree", "add", "-b", branch, absoluteWorktreePath, baseBranch];
|
|
50158
|
+
} else {
|
|
50159
|
+
throw new Error(`Branch "${branch}" does not exist and createBranch is false`);
|
|
48915
50160
|
}
|
|
48916
50161
|
let commandStdout = "";
|
|
48917
50162
|
let commandStderr = "";
|
|
48918
|
-
const output = await new Promise((
|
|
48919
|
-
const child = (0,
|
|
50163
|
+
const output = await new Promise((resolve4, reject) => {
|
|
50164
|
+
const child = (0, import_node_child_process6.spawn)("git", worktreeArgs, {
|
|
48920
50165
|
stdio: "pipe",
|
|
48921
50166
|
cwd: stepCwd,
|
|
48922
|
-
env:
|
|
50167
|
+
env: filteredEnv()
|
|
48923
50168
|
});
|
|
48924
50169
|
const stdoutChunks = [];
|
|
48925
50170
|
const stderrChunks = [];
|
|
@@ -48961,18 +50206,15 @@ ${trimmedOutput.slice(0, 200)}`);
|
|
|
48961
50206
|
reject(new Error(`Step "${step.name}" timed out (no step timeout set, check global swarm.timeoutMs)`));
|
|
48962
50207
|
return;
|
|
48963
50208
|
}
|
|
48964
|
-
|
|
48965
|
-
|
|
48966
|
-
commandStdout = stdout;
|
|
48967
|
-
commandStderr = stderr;
|
|
50209
|
+
commandStdout = stdoutChunks.join("");
|
|
50210
|
+
commandStderr = stderrChunks.join("");
|
|
48968
50211
|
lastExitCode = code ?? void 0;
|
|
48969
50212
|
lastExitSignal = signal ?? void 0;
|
|
48970
|
-
|
|
48971
|
-
|
|
48972
|
-
reject(new Error(`Command failed with exit code ${code}${stderr ? `: ${stderr.slice(0, 500)}` : ""}`));
|
|
50213
|
+
if (code !== 0 && code !== null) {
|
|
50214
|
+
reject(new Error(`git worktree add failed with exit code ${code}${commandStderr ? `: ${commandStderr.slice(0, 500)}` : ""}`));
|
|
48973
50215
|
return;
|
|
48974
50216
|
}
|
|
48975
|
-
|
|
50217
|
+
resolve4(absoluteWorktreePath);
|
|
48976
50218
|
});
|
|
48977
50219
|
child.on("error", (err) => {
|
|
48978
50220
|
if (timer)
|
|
@@ -48980,7 +50222,7 @@ ${trimmedOutput.slice(0, 200)}`);
|
|
|
48980
50222
|
if (abortHandler && abortSignal) {
|
|
48981
50223
|
abortSignal.removeEventListener("abort", abortHandler);
|
|
48982
50224
|
}
|
|
48983
|
-
reject(new Error(`Failed to execute command: ${err.message}`));
|
|
50225
|
+
reject(new Error(`Failed to execute git worktree command: ${err.message}`));
|
|
48984
50226
|
});
|
|
48985
50227
|
});
|
|
48986
50228
|
this.captureStepTerminalEvidence(step.name, {
|
|
@@ -48988,253 +50230,78 @@ ${trimmedOutput.slice(0, 200)}`);
|
|
|
48988
50230
|
stderr: commandStderr,
|
|
48989
50231
|
combined: [commandStdout || output, commandStderr].filter(Boolean).join("\n")
|
|
48990
50232
|
}, { exitCode: lastExitCode, exitSignal: lastExitSignal });
|
|
48991
|
-
|
|
48992
|
-
|
|
48993
|
-
|
|
48994
|
-
|
|
48995
|
-
|
|
48996
|
-
await this.db.updateStep(state.row.id, {
|
|
48997
|
-
status: "completed",
|
|
48998
|
-
output,
|
|
48999
|
-
completionReason: verificationResult?.completionReason,
|
|
49000
|
-
completedAt: state.row.completedAt,
|
|
49001
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
49002
|
-
});
|
|
49003
|
-
await this.persistStepOutput(runId, step.name, output);
|
|
49004
|
-
this.emit({ type: "step:completed", runId, stepName: step.name, output });
|
|
49005
|
-
this.finalizeStepEvidence(step.name, "completed", state.row.completedAt, verificationResult?.completionReason);
|
|
49006
|
-
return;
|
|
49007
|
-
} catch (err) {
|
|
49008
|
-
lastError = err instanceof Error ? err.message : String(err);
|
|
49009
|
-
lastCompletionReason = err instanceof WorkflowCompletionError ? err.completionReason : void 0;
|
|
49010
|
-
}
|
|
49011
|
-
}
|
|
49012
|
-
const errorMsg = lastError ?? "Unknown error";
|
|
49013
|
-
this.postToChannel(`**[${step.name}]** Failed: ${errorMsg}`);
|
|
49014
|
-
await this.markStepFailed(state, errorMsg, runId, { exitCode: lastExitCode, exitSignal: lastExitSignal }, lastCompletionReason);
|
|
49015
|
-
throw new Error(`Step "${step.name}" failed: ${errorMsg}`);
|
|
49016
|
-
}
|
|
49017
|
-
/**
|
|
49018
|
-
* Execute a worktree step (git worktree setup).
|
|
49019
|
-
* Fast, reliable, $0 LLM cost.
|
|
49020
|
-
* Outputs the worktree path for downstream steps to use.
|
|
49021
|
-
*/
|
|
49022
|
-
async executeWorktreeStep(step, stepStates, runId) {
|
|
49023
|
-
const state = stepStates.get(step.name);
|
|
49024
|
-
if (!state)
|
|
49025
|
-
throw new Error(`Step state not found: ${step.name}`);
|
|
49026
|
-
let lastExitCode;
|
|
49027
|
-
let lastExitSignal;
|
|
49028
|
-
this.checkAborted();
|
|
49029
|
-
state.row.status = "running";
|
|
49030
|
-
state.row.error = void 0;
|
|
49031
|
-
state.row.completionReason = void 0;
|
|
49032
|
-
state.row.startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
49033
|
-
await this.db.updateStep(state.row.id, {
|
|
49034
|
-
status: "running",
|
|
49035
|
-
error: void 0,
|
|
49036
|
-
completionReason: void 0,
|
|
49037
|
-
startedAt: state.row.startedAt,
|
|
49038
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
49039
|
-
});
|
|
49040
|
-
this.emit({ type: "step:started", runId, stepName: step.name });
|
|
49041
|
-
this.postToChannel(`**[${step.name}]** Started (worktree setup)`);
|
|
49042
|
-
const stepOutputContext = this.buildStepOutputContext(stepStates, runId);
|
|
49043
|
-
const branch = this.interpolateStepTask(step.branch ?? "", stepOutputContext);
|
|
49044
|
-
const baseBranch = step.baseBranch ? this.interpolateStepTask(step.baseBranch, stepOutputContext) : "HEAD";
|
|
49045
|
-
const worktreePath = step.path ? this.interpolateStepTask(step.path, stepOutputContext) : import_node_path13.default.join(".worktrees", step.name);
|
|
49046
|
-
const createBranch = step.createBranch !== false;
|
|
49047
|
-
const stepCwd = this.resolveStepWorkdir(step) ?? this.cwd;
|
|
49048
|
-
this.beginStepEvidence(step.name, [stepCwd], state.row.startedAt);
|
|
49049
|
-
if (!branch) {
|
|
49050
|
-
const errorMsg = 'Worktree step missing required "branch" field';
|
|
49051
|
-
await this.markStepFailed(state, errorMsg, runId);
|
|
49052
|
-
throw new Error(`Step "${step.name}" failed: ${errorMsg}`);
|
|
49053
|
-
}
|
|
49054
|
-
try {
|
|
49055
|
-
const absoluteWorktreePath = import_node_path13.default.resolve(stepCwd, worktreePath);
|
|
49056
|
-
const checkBranchCmd = `git rev-parse --verify --quiet ${branch} 2>/dev/null`;
|
|
49057
|
-
let branchExists = false;
|
|
49058
|
-
await new Promise((resolve3) => {
|
|
49059
|
-
const checkChild = (0, import_node_child_process5.spawn)("sh", ["-c", checkBranchCmd], {
|
|
49060
|
-
stdio: "pipe",
|
|
49061
|
-
cwd: stepCwd,
|
|
49062
|
-
env: { ...process.env }
|
|
49063
|
-
});
|
|
49064
|
-
checkChild.on("close", (code) => {
|
|
49065
|
-
branchExists = code === 0;
|
|
49066
|
-
resolve3();
|
|
49067
|
-
});
|
|
49068
|
-
checkChild.on("error", () => resolve3());
|
|
49069
|
-
});
|
|
49070
|
-
let worktreeCmd;
|
|
49071
|
-
if (branchExists) {
|
|
49072
|
-
worktreeCmd = `git worktree add "${absoluteWorktreePath}" ${branch}`;
|
|
49073
|
-
} else if (createBranch) {
|
|
49074
|
-
worktreeCmd = `git worktree add -b ${branch} "${absoluteWorktreePath}" ${baseBranch}`;
|
|
49075
|
-
} else {
|
|
49076
|
-
const errorMsg = `Branch "${branch}" does not exist and createBranch is false`;
|
|
49077
|
-
await this.markStepFailed(state, errorMsg, runId);
|
|
49078
|
-
throw new Error(`Step "${step.name}" failed: ${errorMsg}`);
|
|
49079
|
-
}
|
|
49080
|
-
let commandStdout = "";
|
|
49081
|
-
let commandStderr = "";
|
|
49082
|
-
let commandExitCode;
|
|
49083
|
-
let commandExitSignal;
|
|
49084
|
-
const output = await new Promise((resolve3, reject) => {
|
|
49085
|
-
const child = (0, import_node_child_process5.spawn)("sh", ["-c", worktreeCmd], {
|
|
49086
|
-
stdio: "pipe",
|
|
49087
|
-
cwd: stepCwd,
|
|
49088
|
-
env: { ...process.env }
|
|
49089
|
-
});
|
|
49090
|
-
const stdoutChunks = [];
|
|
49091
|
-
const stderrChunks = [];
|
|
49092
|
-
const abortSignal = this.abortController?.signal;
|
|
49093
|
-
let abortHandler;
|
|
49094
|
-
if (abortSignal && !abortSignal.aborted) {
|
|
49095
|
-
abortHandler = () => {
|
|
49096
|
-
child.kill("SIGTERM");
|
|
49097
|
-
setTimeout(() => child.kill("SIGKILL"), 5e3);
|
|
49098
|
-
};
|
|
49099
|
-
abortSignal.addEventListener("abort", abortHandler, { once: true });
|
|
49100
|
-
}
|
|
49101
|
-
let timedOut = false;
|
|
49102
|
-
let timer;
|
|
49103
|
-
if (step.timeoutMs) {
|
|
49104
|
-
timer = setTimeout(() => {
|
|
49105
|
-
timedOut = true;
|
|
49106
|
-
child.kill("SIGTERM");
|
|
49107
|
-
setTimeout(() => child.kill("SIGKILL"), 5e3);
|
|
49108
|
-
}, step.timeoutMs);
|
|
49109
|
-
}
|
|
49110
|
-
child.stdout?.on("data", (chunk) => {
|
|
49111
|
-
stdoutChunks.push(chunk.toString());
|
|
49112
|
-
});
|
|
49113
|
-
child.stderr?.on("data", (chunk) => {
|
|
49114
|
-
stderrChunks.push(chunk.toString());
|
|
49115
|
-
});
|
|
49116
|
-
child.on("close", (code, signal) => {
|
|
49117
|
-
if (timer)
|
|
49118
|
-
clearTimeout(timer);
|
|
49119
|
-
if (abortHandler && abortSignal) {
|
|
49120
|
-
abortSignal.removeEventListener("abort", abortHandler);
|
|
49121
|
-
}
|
|
49122
|
-
if (abortSignal?.aborted) {
|
|
49123
|
-
reject(new Error(`Step "${step.name}" aborted`));
|
|
49124
|
-
return;
|
|
49125
|
-
}
|
|
49126
|
-
if (timedOut) {
|
|
49127
|
-
reject(new Error(`Step "${step.name}" timed out (no step timeout set, check global swarm.timeoutMs)`));
|
|
49128
|
-
return;
|
|
49129
|
-
}
|
|
49130
|
-
commandStdout = stdoutChunks.join("");
|
|
49131
|
-
const stderr = stderrChunks.join("");
|
|
49132
|
-
commandStderr = stderr;
|
|
49133
|
-
commandExitCode = code ?? void 0;
|
|
49134
|
-
commandExitSignal = signal ?? void 0;
|
|
49135
|
-
lastExitCode = commandExitCode;
|
|
49136
|
-
lastExitSignal = commandExitSignal;
|
|
49137
|
-
if (code !== 0 && code !== null) {
|
|
49138
|
-
reject(new Error(`git worktree add failed with exit code ${code}${stderr ? `: ${stderr.slice(0, 500)}` : ""}`));
|
|
49139
|
-
return;
|
|
49140
|
-
}
|
|
49141
|
-
resolve3(absoluteWorktreePath);
|
|
49142
|
-
});
|
|
49143
|
-
child.on("error", (err) => {
|
|
49144
|
-
if (timer)
|
|
49145
|
-
clearTimeout(timer);
|
|
49146
|
-
if (abortHandler && abortSignal) {
|
|
49147
|
-
abortSignal.removeEventListener("abort", abortHandler);
|
|
49148
|
-
}
|
|
49149
|
-
reject(new Error(`Failed to execute git worktree command: ${err.message}`));
|
|
49150
|
-
});
|
|
49151
|
-
});
|
|
49152
|
-
this.captureStepTerminalEvidence(step.name, {
|
|
49153
|
-
stdout: commandStdout || output,
|
|
49154
|
-
stderr: commandStderr,
|
|
49155
|
-
combined: [commandStdout || output, commandStderr].filter(Boolean).join("\n")
|
|
49156
|
-
}, { exitCode: commandExitCode, exitSignal: commandExitSignal });
|
|
49157
|
-
state.row.status = "completed";
|
|
49158
|
-
state.row.output = output;
|
|
49159
|
-
state.row.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
49160
|
-
await this.db.updateStep(state.row.id, {
|
|
50233
|
+
worktreeBranch = branch;
|
|
50234
|
+
createdBranch = !branchExists && createBranch;
|
|
50235
|
+
return { output };
|
|
50236
|
+
},
|
|
50237
|
+
toCompletionResult: ({ output }, attempt) => ({
|
|
49161
50238
|
status: "completed",
|
|
49162
50239
|
output,
|
|
49163
|
-
|
|
49164
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
49165
|
-
});
|
|
49166
|
-
await this.persistStepOutput(runId, step.name, output);
|
|
49167
|
-
this.emit({ type: "step:completed", runId, stepName: step.name, output });
|
|
49168
|
-
this.postToChannel(`**[${step.name}]** Worktree created at: ${output}
|
|
49169
|
-
Branch: ${branch}${!branchExists && createBranch ? " (created)" : ""}`);
|
|
49170
|
-
this.recordStepToolSideEffect(step.name, {
|
|
49171
|
-
type: "worktree_created",
|
|
49172
|
-
detail: `Worktree created at ${output}`,
|
|
49173
|
-
raw: { branch, createdBranch: !branchExists && createBranch }
|
|
49174
|
-
});
|
|
49175
|
-
this.finalizeStepEvidence(step.name, "completed", state.row.completedAt);
|
|
49176
|
-
} catch (err) {
|
|
49177
|
-
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
49178
|
-
this.postToChannel(`**[${step.name}]** Failed: ${errorMsg}`);
|
|
49179
|
-
await this.markStepFailed(state, errorMsg, runId, {
|
|
50240
|
+
retries: attempt,
|
|
49180
50241
|
exitCode: lastExitCode,
|
|
49181
50242
|
exitSignal: lastExitSignal
|
|
49182
|
-
})
|
|
49183
|
-
|
|
50243
|
+
}),
|
|
50244
|
+
getFailureResult: (error48) => ({
|
|
50245
|
+
status: "failed",
|
|
50246
|
+
output: "",
|
|
50247
|
+
error: error48 instanceof Error ? error48.message : String(error48),
|
|
50248
|
+
retries: state.row.retryCount,
|
|
50249
|
+
exitCode: lastExitCode,
|
|
50250
|
+
exitSignal: lastExitSignal
|
|
50251
|
+
})
|
|
50252
|
+
});
|
|
50253
|
+
if (result.status === "failed") {
|
|
50254
|
+
this.postToChannel(`**[${step.name}]** Failed: ${result.error ?? "Unknown error"}`);
|
|
50255
|
+
throw new Error(`Step "${step.name}" failed: ${result.error ?? "Unknown error"}`);
|
|
49184
50256
|
}
|
|
50257
|
+
this.postToChannel(`**[${step.name}]** Worktree created at: ${result.output}
|
|
50258
|
+
Branch: ${worktreeBranch}${createdBranch ? " (created)" : ""}`);
|
|
50259
|
+
this.recordStepToolSideEffect(step.name, {
|
|
50260
|
+
type: "worktree_created",
|
|
50261
|
+
detail: `Worktree created at ${result.output}`,
|
|
50262
|
+
raw: { branch: worktreeBranch, createdBranch }
|
|
50263
|
+
});
|
|
49185
50264
|
}
|
|
49186
50265
|
/**
|
|
49187
50266
|
* Execute an integration step (external service interaction via executor).
|
|
49188
50267
|
*/
|
|
49189
|
-
async executeIntegrationStep(step, stepStates, runId) {
|
|
49190
|
-
const
|
|
49191
|
-
|
|
49192
|
-
|
|
49193
|
-
|
|
49194
|
-
|
|
49195
|
-
|
|
49196
|
-
|
|
49197
|
-
|
|
49198
|
-
|
|
49199
|
-
|
|
49200
|
-
|
|
49201
|
-
|
|
49202
|
-
|
|
49203
|
-
|
|
49204
|
-
|
|
49205
|
-
|
|
49206
|
-
|
|
49207
|
-
|
|
49208
|
-
|
|
49209
|
-
|
|
49210
|
-
resolvedParams[key] = this.interpolateStepTask(value, stepOutputContext);
|
|
49211
|
-
}
|
|
49212
|
-
try {
|
|
49213
|
-
if (!this.executor?.executeIntegrationStep) {
|
|
49214
|
-
throw new Error(`Integration steps require a cloud executor. Step "${step.name}" cannot run locally. Use "cloud run" to execute workflows with integration steps.`);
|
|
49215
|
-
}
|
|
49216
|
-
const result = await this.executor.executeIntegrationStep(step, resolvedParams, { workspaceId: this.workspaceId });
|
|
49217
|
-
if (!result.success) {
|
|
49218
|
-
throw new Error(`Integration step "${step.name}" failed: ${result.output}`);
|
|
49219
|
-
}
|
|
49220
|
-
state.row.status = "completed";
|
|
49221
|
-
state.row.output = result.output;
|
|
49222
|
-
state.row.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
49223
|
-
await this.db.updateStep(state.row.id, {
|
|
50268
|
+
async executeIntegrationStep(step, state, stepStates, runId, lifecycle) {
|
|
50269
|
+
const result = await lifecycle.monitorStep(step, state, {
|
|
50270
|
+
startMessage: `**[${step.name}]** Started (integration: ${step.integration}.${step.action})`,
|
|
50271
|
+
execute: async () => {
|
|
50272
|
+
const stepOutputContext = this.buildStepOutputContext(stepStates, runId);
|
|
50273
|
+
const resolvedParams = {};
|
|
50274
|
+
for (const [key, value] of Object.entries(step.params ?? {})) {
|
|
50275
|
+
resolvedParams[key] = this.interpolateStepTask(value, stepOutputContext);
|
|
50276
|
+
}
|
|
50277
|
+
if (!this.executor?.executeIntegrationStep) {
|
|
50278
|
+
throw new Error(`Integration steps require a cloud executor. Step "${step.name}" cannot run locally. Use "cloud run" to execute workflows with integration steps.`);
|
|
50279
|
+
}
|
|
50280
|
+
const integrationResult = await this.executor.executeIntegrationStep(step, resolvedParams, {
|
|
50281
|
+
workspaceId: this.workspaceId
|
|
50282
|
+
});
|
|
50283
|
+
if (!integrationResult.success) {
|
|
50284
|
+
throw new Error(`Integration step "${step.name}" failed: ${integrationResult.output}`);
|
|
50285
|
+
}
|
|
50286
|
+
return { output: integrationResult.output };
|
|
50287
|
+
},
|
|
50288
|
+
toCompletionResult: ({ output }, attempt) => ({
|
|
49224
50289
|
status: "completed",
|
|
49225
|
-
output
|
|
49226
|
-
|
|
49227
|
-
|
|
49228
|
-
|
|
49229
|
-
|
|
49230
|
-
|
|
49231
|
-
|
|
49232
|
-
|
|
49233
|
-
|
|
49234
|
-
|
|
49235
|
-
|
|
49236
|
-
|
|
50290
|
+
output,
|
|
50291
|
+
retries: attempt
|
|
50292
|
+
}),
|
|
50293
|
+
getFailureResult: (error48) => ({
|
|
50294
|
+
status: "failed",
|
|
50295
|
+
output: "",
|
|
50296
|
+
error: error48 instanceof Error ? error48.message : String(error48),
|
|
50297
|
+
retries: state.row.retryCount
|
|
50298
|
+
})
|
|
50299
|
+
});
|
|
50300
|
+
if (result.status === "failed") {
|
|
50301
|
+
this.postToChannel(`**[${step.name}]** Failed: ${result.error ?? "Unknown error"}`);
|
|
50302
|
+
throw new Error(`Step "${step.name}" failed: ${result.error ?? "Unknown error"}`);
|
|
49237
50303
|
}
|
|
50304
|
+
this.postToChannel(`**[${step.name}]** Completed (integration: ${step.integration}.${step.action})`);
|
|
49238
50305
|
}
|
|
49239
50306
|
/**
|
|
49240
50307
|
* Execute an agent step (LLM-powered).
|
|
@@ -49265,7 +50332,11 @@ ${trimmedOutput.slice(0, 200)}`);
|
|
|
49265
50332
|
this.emit({ type: "step:started", runId, stepName: step.name });
|
|
49266
50333
|
this.postToChannel(`**[${step.name}]** Started (api)`);
|
|
49267
50334
|
try {
|
|
49268
|
-
const output = await executeApiStep(specialistDef.constraints?.model ?? "claude-sonnet-4-20250514", resolvedTask, {
|
|
50335
|
+
const output = await executeApiStep(specialistDef.constraints?.model ?? "claude-sonnet-4-20250514", resolvedTask, {
|
|
50336
|
+
envSecrets: this.envSecrets,
|
|
50337
|
+
skills: specialistDef.skills,
|
|
50338
|
+
defaultMaxTokens: specialistDef.constraints?.maxTokens
|
|
50339
|
+
});
|
|
49269
50340
|
state.row.status = "completed";
|
|
49270
50341
|
state.row.output = output;
|
|
49271
50342
|
state.row.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -49514,7 +50585,14 @@ ${resolvedTask}`;
|
|
|
49514
50585
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
49515
50586
|
});
|
|
49516
50587
|
await this.persistStepOutput(runId, step.name, combinedOutput);
|
|
49517
|
-
this.emit({
|
|
50588
|
+
this.emit({
|
|
50589
|
+
type: "step:completed",
|
|
50590
|
+
runId,
|
|
50591
|
+
stepName: step.name,
|
|
50592
|
+
output: combinedOutput,
|
|
50593
|
+
exitCode: lastExitCode,
|
|
50594
|
+
exitSignal: lastExitSignal
|
|
50595
|
+
});
|
|
49518
50596
|
this.finalizeStepEvidence(step.name, "completed", state.row.completedAt, completionReason);
|
|
49519
50597
|
await this.trajectory?.stepCompleted(step, combinedOutput, attempt + 1);
|
|
49520
50598
|
return;
|
|
@@ -49668,8 +50746,8 @@ WORKER COMPLETION CONTRACT:
|
|
|
49668
50746
|
let workerReleased = false;
|
|
49669
50747
|
let resolveWorkerSpawn;
|
|
49670
50748
|
let rejectWorkerSpawn;
|
|
49671
|
-
const workerReady = new Promise((
|
|
49672
|
-
resolveWorkerSpawn =
|
|
50749
|
+
const workerReady = new Promise((resolve4, reject) => {
|
|
50750
|
+
resolveWorkerSpawn = resolve4;
|
|
49673
50751
|
rejectWorkerSpawn = reject;
|
|
49674
50752
|
});
|
|
49675
50753
|
const specialistTask = this.buildWorkerHandoffTask(step, resolvedTask, supervised);
|
|
@@ -49944,7 +51022,7 @@ WORKER COMPLETION CONTRACT:
|
|
|
49944
51022
|
}
|
|
49945
51023
|
hasOwnerCompletionMarker(step, output, injectedTaskText) {
|
|
49946
51024
|
const marker = `STEP_COMPLETE:${step.name}`;
|
|
49947
|
-
const strippedOutput =
|
|
51025
|
+
const strippedOutput = stripInjectedTaskEcho(output, injectedTaskText);
|
|
49948
51026
|
if (strippedOutput.includes(marker)) {
|
|
49949
51027
|
return true;
|
|
49950
51028
|
}
|
|
@@ -49994,28 +51072,11 @@ WORKER COMPLETION CONTRACT:
|
|
|
49994
51072
|
stripEchoedPromptLines(output, patterns) {
|
|
49995
51073
|
return output.split("\n").map((line) => line.trim()).filter(Boolean).filter((line) => patterns.every((pattern) => !pattern.test(line))).join("\n");
|
|
49996
51074
|
}
|
|
49997
|
-
stripInjectedTaskEcho(output, injectedTaskText) {
|
|
49998
|
-
if (!injectedTaskText) {
|
|
49999
|
-
return output;
|
|
50000
|
-
}
|
|
50001
|
-
const candidates = [
|
|
50002
|
-
injectedTaskText,
|
|
50003
|
-
injectedTaskText.replace(/\r\n/g, "\n"),
|
|
50004
|
-
injectedTaskText.replace(/\n/g, "\r\n")
|
|
50005
|
-
].filter((candidate, index, all) => candidate.length > 0 && all.indexOf(candidate) === index);
|
|
50006
|
-
for (const candidate of candidates) {
|
|
50007
|
-
const start = output.indexOf(candidate);
|
|
50008
|
-
if (start !== -1) {
|
|
50009
|
-
return output.slice(0, start) + output.slice(start + candidate.length);
|
|
50010
|
-
}
|
|
50011
|
-
}
|
|
50012
|
-
return output;
|
|
50013
|
-
}
|
|
50014
51075
|
outputContainsVerificationToken(output, token, injectedTaskText) {
|
|
50015
51076
|
if (!token) {
|
|
50016
51077
|
return false;
|
|
50017
51078
|
}
|
|
50018
|
-
return
|
|
51079
|
+
return stripInjectedTaskEcho(output, injectedTaskText).includes(token);
|
|
50019
51080
|
}
|
|
50020
51081
|
prepareInteractiveSpawnTask(agentName, taskText) {
|
|
50021
51082
|
if (Buffer.byteLength(taskText, "utf8") <= _WorkflowRunner.PTY_TASK_ARG_SIZE_LIMIT) {
|
|
@@ -50024,9 +51085,9 @@ WORKER COMPLETION CONTRACT:
|
|
|
50024
51085
|
promptTaskText: taskText
|
|
50025
51086
|
};
|
|
50026
51087
|
}
|
|
50027
|
-
const taskTmpDir = (0,
|
|
50028
|
-
const taskTmpFile =
|
|
50029
|
-
(0,
|
|
51088
|
+
const taskTmpDir = (0, import_node_fs11.mkdtempSync)(import_node_path14.default.join((0, import_node_os7.tmpdir)(), "relay-pty-task-"));
|
|
51089
|
+
const taskTmpFile = import_node_path14.default.join(taskTmpDir, `${agentName}-${Date.now()}.txt`);
|
|
51090
|
+
(0, import_node_fs11.writeFileSync)(taskTmpFile, taskText, { encoding: "utf8", mode: 384, flag: "wx" });
|
|
50030
51091
|
const promptTaskText = `TASK_FILE:${taskTmpFile}
|
|
50031
51092
|
Read that file completely before taking any action.
|
|
50032
51093
|
Treat the file contents as the full workflow task and follow them exactly.
|
|
@@ -50362,17 +51423,10 @@ ${review}
|
|
|
50362
51423
|
* Delegates to the consolidated CLI registry for per-CLI arg formats.
|
|
50363
51424
|
*/
|
|
50364
51425
|
static buildNonInteractiveCommand(cli, task, extraArgs = []) {
|
|
50365
|
-
|
|
50366
|
-
throw new Error('cli "api" uses direct API calls, not a subprocess command');
|
|
50367
|
-
}
|
|
50368
|
-
const resolvedCli = cli === "cursor" ? resolveCursorCli() : cli;
|
|
50369
|
-
const def = getCliDefinition(resolvedCli);
|
|
50370
|
-
if (!def || def.binaries.length === 0) {
|
|
50371
|
-
throw new Error(`Unknown or non-executable CLI: ${resolvedCli}`);
|
|
50372
|
-
}
|
|
51426
|
+
const [cmd, ...args] = buildCommand(cli, extraArgs, task);
|
|
50373
51427
|
return {
|
|
50374
|
-
cmd
|
|
50375
|
-
args
|
|
51428
|
+
cmd,
|
|
51429
|
+
args
|
|
50376
51430
|
};
|
|
50377
51431
|
}
|
|
50378
51432
|
/**
|
|
@@ -50438,8 +51492,8 @@ DO NOT:
|
|
|
50438
51492
|
- Output only status messages without the actual deliverable content`;
|
|
50439
51493
|
const { cmd, args } = _WorkflowRunner.buildNonInteractiveCommand(agentDef.cli, taskWithDeliverable, modelArgs);
|
|
50440
51494
|
const logsDir = this.getWorkerLogsDir();
|
|
50441
|
-
const logPath =
|
|
50442
|
-
const logStream = (0,
|
|
51495
|
+
const logPath = import_node_path14.default.join(logsDir, `${agentName}.log`);
|
|
51496
|
+
const logStream = (0, import_node_fs11.createWriteStream)(logPath, { flags: "a" });
|
|
50443
51497
|
this.registerWorker(agentName, agentDef.cli, step.task ?? "", void 0, false);
|
|
50444
51498
|
let stopHeartbeat;
|
|
50445
51499
|
if (this.relayApiKey) {
|
|
@@ -50455,11 +51509,11 @@ DO NOT:
|
|
|
50455
51509
|
const stdoutChunks = [];
|
|
50456
51510
|
const stderrChunks = [];
|
|
50457
51511
|
try {
|
|
50458
|
-
const { stdout: output, exitCode, exitSignal } = await new Promise((
|
|
50459
|
-
const child = (
|
|
51512
|
+
const { stdout: output, exitCode, exitSignal } = await new Promise((resolve4, reject) => {
|
|
51513
|
+
const child = spawnProcess([cmd, ...args], {
|
|
50460
51514
|
stdio: ["ignore", "pipe", "pipe"],
|
|
50461
51515
|
cwd: this.resolveEffectiveCwd(step, agentDef),
|
|
50462
|
-
env: this.getRelayEnv() ??
|
|
51516
|
+
env: this.getRelayEnv() ?? filteredEnv()
|
|
50463
51517
|
});
|
|
50464
51518
|
this.registerWorker(agentName, agentDef.cli, step.task ?? "", child.pid, false);
|
|
50465
51519
|
const abortSignal = this.abortController?.signal;
|
|
@@ -50523,7 +51577,7 @@ DO NOT:
|
|
|
50523
51577
|
reject(new SpawnExitError(`Step "${step.name}" exited with code ${code}${stderr ? `: ${stderr.slice(0, 500)}` : ""}`, code, signal));
|
|
50524
51578
|
return;
|
|
50525
51579
|
}
|
|
50526
|
-
|
|
51580
|
+
resolve4({
|
|
50527
51581
|
stdout,
|
|
50528
51582
|
exitCode: code ?? void 0,
|
|
50529
51583
|
exitSignal: signal ?? void 0
|
|
@@ -50577,7 +51631,7 @@ DO NOT:
|
|
|
50577
51631
|
const preparedTask = this.prepareInteractiveSpawnTask(agentName, taskWithExit);
|
|
50578
51632
|
this.ptyOutputBuffers.set(agentName, []);
|
|
50579
51633
|
const logsDir = this.getWorkerLogsDir();
|
|
50580
|
-
const logStream = (0,
|
|
51634
|
+
const logStream = (0, import_node_fs11.createWriteStream)(import_node_path14.default.join(logsDir, `${agentName}.log`), { flags: "a" });
|
|
50581
51635
|
this.ptyLogStreams.set(agentName, logStream);
|
|
50582
51636
|
this.ptyListeners.set(agentName, (chunk) => {
|
|
50583
51637
|
const stripped = _WorkflowRunner.stripAnsi(chunk);
|
|
@@ -50612,18 +51666,18 @@ DO NOT:
|
|
|
50612
51666
|
const oldName = agentName;
|
|
50613
51667
|
this.ptyOutputBuffers.set(agent.name, this.ptyOutputBuffers.get(oldName) ?? []);
|
|
50614
51668
|
this.ptyOutputBuffers.delete(oldName);
|
|
50615
|
-
const oldLogPath =
|
|
50616
|
-
const newLogPath =
|
|
51669
|
+
const oldLogPath = import_node_path14.default.join(logsDir, `${oldName}.log`);
|
|
51670
|
+
const newLogPath = import_node_path14.default.join(logsDir, `${agent.name}.log`);
|
|
50617
51671
|
const oldLogStream = this.ptyLogStreams.get(oldName);
|
|
50618
51672
|
if (oldLogStream) {
|
|
50619
51673
|
oldLogStream.end();
|
|
50620
51674
|
this.ptyLogStreams.delete(oldName);
|
|
50621
51675
|
try {
|
|
50622
|
-
(0,
|
|
51676
|
+
(0, import_node_fs11.renameSync)(oldLogPath, newLogPath);
|
|
50623
51677
|
} catch {
|
|
50624
51678
|
}
|
|
50625
51679
|
}
|
|
50626
|
-
const newLogStream = (0,
|
|
51680
|
+
const newLogStream = (0, import_node_fs11.createWriteStream)(newLogPath, { flags: "a" });
|
|
50627
51681
|
this.ptyLogStreams.set(agent.name, newLogStream);
|
|
50628
51682
|
const oldListener = this.ptyListeners.get(oldName);
|
|
50629
51683
|
if (oldListener) {
|
|
@@ -50682,12 +51736,12 @@ DO NOT:
|
|
|
50682
51736
|
if (verificationResult.passed) {
|
|
50683
51737
|
this.log(`[${step.name}] Agent timed out but verification passed \u2014 treating as complete`);
|
|
50684
51738
|
this.postToChannel(`**[${step.name}]** Agent idle after completing work \u2014 verification passed, releasing`);
|
|
50685
|
-
await agent.release();
|
|
51739
|
+
await agent.release().catch(() => void 0);
|
|
50686
51740
|
timeoutRecovered = true;
|
|
50687
51741
|
}
|
|
50688
51742
|
}
|
|
50689
51743
|
if (!timeoutRecovered) {
|
|
50690
|
-
await agent.release();
|
|
51744
|
+
await agent.release().catch(() => void 0);
|
|
50691
51745
|
throw new Error(`Step "${step.name}" timed out after ${timeoutMs ?? "unknown"}ms`);
|
|
50692
51746
|
}
|
|
50693
51747
|
}
|
|
@@ -50730,8 +51784,8 @@ DO NOT:
|
|
|
50730
51784
|
if (ptyChunks.length > 0) {
|
|
50731
51785
|
output = ptyChunks.join("");
|
|
50732
51786
|
} else {
|
|
50733
|
-
const summaryPath =
|
|
50734
|
-
output = (0,
|
|
51787
|
+
const summaryPath = import_node_path14.default.join(this.summaryDir, `${step.name}.md`);
|
|
51788
|
+
output = (0, import_node_fs11.existsSync)(summaryPath) ? await (0, import_promises5.readFile)(summaryPath, "utf-8") : exitResult === "timeout" ? "Agent completed (released after idle timeout)" : exitResult === "released" ? "Agent completed (idle \u2014 treated as done)" : `Agent exited (${exitResult})`;
|
|
50735
51789
|
}
|
|
50736
51790
|
if (ptyChunks.length === 0) {
|
|
50737
51791
|
this.captureStepTerminalEvidence(evidenceStepName, { stdout: output, combined: output }, { exitCode: agent?.exitCode, exitSignal: agent?.exitSignal }, {
|
|
@@ -50827,13 +51881,13 @@ DO NOT:
|
|
|
50827
51881
|
}
|
|
50828
51882
|
this.log(`[${step.name}] Agent "${agent.name}" still idle after ${idleGraceSecs}s grace \u2014 releasing`);
|
|
50829
51883
|
this.postToChannel(`**[${step.name}]** Agent \`${agent.name}\` idle \u2014 releasing (verification pending)`);
|
|
50830
|
-
await agent.release();
|
|
51884
|
+
await agent.release().catch(() => void 0);
|
|
50831
51885
|
return "released";
|
|
50832
51886
|
}
|
|
50833
51887
|
}
|
|
50834
51888
|
this.log(`[${step.name}] Agent "${agent.name}" went idle \u2014 treating as complete`);
|
|
50835
51889
|
this.postToChannel(`**[${step.name}]** Agent \`${agent.name}\` idle \u2014 treating as complete`);
|
|
50836
|
-
await agent.release();
|
|
51890
|
+
await agent.release().catch(() => void 0);
|
|
50837
51891
|
return "released";
|
|
50838
51892
|
}
|
|
50839
51893
|
return result.result;
|
|
@@ -50877,7 +51931,7 @@ DO NOT:
|
|
|
50877
51931
|
}
|
|
50878
51932
|
this.postToChannel(`**[${step.name}]** Agent \`${agent.name}\` still idle after ${nudgeCount} nudge(s) \u2014 force-releasing`);
|
|
50879
51933
|
this.emit({ type: "step:force-released", runId: this.currentRunId ?? "", stepName: step.name });
|
|
50880
|
-
await agent.release();
|
|
51934
|
+
await agent.release().catch(() => void 0);
|
|
50881
51935
|
return "force-released";
|
|
50882
51936
|
}
|
|
50883
51937
|
}
|
|
@@ -50933,70 +51987,11 @@ DO NOT:
|
|
|
50933
51987
|
}
|
|
50934
51988
|
// ── Verification ────────────────────────────────────────────────────────
|
|
50935
51989
|
runVerification(check2, output, stepName, injectedTaskText, options) {
|
|
50936
|
-
|
|
50937
|
-
|
|
50938
|
-
this.
|
|
50939
|
-
|
|
50940
|
-
detail: message,
|
|
50941
|
-
observedAt: observedAt2,
|
|
50942
|
-
raw: { passed: false, type: check2.type, value: check2.value }
|
|
50943
|
-
});
|
|
50944
|
-
this.getOrCreateStepEvidenceRecord(stepName).evidence.coordinationSignals.push({
|
|
50945
|
-
kind: "verification_failed",
|
|
50946
|
-
source: "verification",
|
|
50947
|
-
text: message,
|
|
50948
|
-
observedAt: observedAt2,
|
|
50949
|
-
value: check2.value
|
|
50950
|
-
});
|
|
50951
|
-
if (options?.allowFailure) {
|
|
50952
|
-
return {
|
|
50953
|
-
passed: false,
|
|
50954
|
-
completionReason: "failed_verification",
|
|
50955
|
-
error: message
|
|
50956
|
-
};
|
|
50957
|
-
}
|
|
50958
|
-
throw new WorkflowCompletionError(message, "failed_verification");
|
|
50959
|
-
};
|
|
50960
|
-
switch (check2.type) {
|
|
50961
|
-
case "output_contains": {
|
|
50962
|
-
const token = check2.value;
|
|
50963
|
-
if (!this.outputContainsVerificationToken(output, token, injectedTaskText)) {
|
|
50964
|
-
return fail(`Verification failed for "${stepName}": output does not contain "${token}"`);
|
|
50965
|
-
}
|
|
50966
|
-
break;
|
|
50967
|
-
}
|
|
50968
|
-
case "exit_code":
|
|
50969
|
-
break;
|
|
50970
|
-
case "file_exists":
|
|
50971
|
-
if (!(0, import_node_fs10.existsSync)(import_node_path13.default.resolve(this.cwd, check2.value))) {
|
|
50972
|
-
return fail(`Verification failed for "${stepName}": file "${check2.value}" does not exist`);
|
|
50973
|
-
}
|
|
50974
|
-
break;
|
|
50975
|
-
case "custom":
|
|
50976
|
-
return { passed: false };
|
|
50977
|
-
}
|
|
50978
|
-
if (options?.completionMarkerFound === false) {
|
|
50979
|
-
this.log(`[${stepName}] Verification passed without legacy STEP_COMPLETE marker; allowing completion`);
|
|
50980
|
-
}
|
|
50981
|
-
const successMessage = options?.completionMarkerFound === false ? `Verification passed without legacy STEP_COMPLETE marker` : `Verification passed`;
|
|
50982
|
-
const observedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
50983
|
-
this.recordStepToolSideEffect(stepName, {
|
|
50984
|
-
type: "verification_observed",
|
|
50985
|
-
detail: successMessage,
|
|
50986
|
-
observedAt,
|
|
50987
|
-
raw: { passed: true, type: check2.type, value: check2.value }
|
|
51990
|
+
return runVerification(check2, output, stepName, injectedTaskText, { ...options, cwd: this.cwd }, {
|
|
51991
|
+
recordStepToolSideEffect: (name, effect) => this.recordStepToolSideEffect(name, effect),
|
|
51992
|
+
getOrCreateStepEvidenceRecord: (name) => this.getOrCreateStepEvidenceRecord(name),
|
|
51993
|
+
log: (message) => this.log(message)
|
|
50988
51994
|
});
|
|
50989
|
-
this.getOrCreateStepEvidenceRecord(stepName).evidence.coordinationSignals.push({
|
|
50990
|
-
kind: "verification_passed",
|
|
50991
|
-
source: "verification",
|
|
50992
|
-
text: successMessage,
|
|
50993
|
-
observedAt,
|
|
50994
|
-
value: check2.value
|
|
50995
|
-
});
|
|
50996
|
-
return {
|
|
50997
|
-
passed: true,
|
|
50998
|
-
completionReason: "completed_verified"
|
|
50999
|
-
};
|
|
51000
51995
|
}
|
|
51001
51996
|
// ── State helpers ─────────────────────────────────────────────────────
|
|
51002
51997
|
async updateRunStatus(runId, status, error48) {
|
|
@@ -51117,12 +52112,12 @@ DO NOT:
|
|
|
51117
52112
|
async waitIfPaused() {
|
|
51118
52113
|
if (!this.paused)
|
|
51119
52114
|
return;
|
|
51120
|
-
await new Promise((
|
|
51121
|
-
this.pauseResolver =
|
|
52115
|
+
await new Promise((resolve4) => {
|
|
52116
|
+
this.pauseResolver = resolve4;
|
|
51122
52117
|
});
|
|
51123
52118
|
}
|
|
51124
52119
|
delay(ms) {
|
|
51125
|
-
return new Promise((
|
|
52120
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
51126
52121
|
}
|
|
51127
52122
|
// ── Channel messaging ──────────────────────────────────────────────────
|
|
51128
52123
|
/**
|
|
@@ -51130,24 +52125,7 @@ DO NOT:
|
|
|
51130
52125
|
* Returns undefined if there are no non-interactive agents.
|
|
51131
52126
|
*/
|
|
51132
52127
|
buildNonInteractiveAwareness(agentMap, stepStates) {
|
|
51133
|
-
|
|
51134
|
-
if (nonInteractive.length === 0)
|
|
51135
|
-
return void 0;
|
|
51136
|
-
const agentToSteps = /* @__PURE__ */ new Map();
|
|
51137
|
-
for (const [stepName, state] of stepStates) {
|
|
51138
|
-
const agentName = state.row.agentName;
|
|
51139
|
-
if (!agentName)
|
|
51140
|
-
continue;
|
|
51141
|
-
if (!agentToSteps.has(agentName))
|
|
51142
|
-
agentToSteps.set(agentName, []);
|
|
51143
|
-
agentToSteps.get(agentName).push(stepName);
|
|
51144
|
-
}
|
|
51145
|
-
const lines = nonInteractive.map((a) => {
|
|
51146
|
-
const steps = agentToSteps.get(a.name) ?? [];
|
|
51147
|
-
const stepRefs = steps.map((s) => `{{steps.${s}.output}}`).join(", ");
|
|
51148
|
-
return `- ${a.name} (${a.cli}) \u2014 will return output when complete${stepRefs ? `. Access via: ${stepRefs}` : ""}`;
|
|
51149
|
-
});
|
|
51150
|
-
return "\n\n---\nNote: The following agents are non-interactive workers and cannot receive messages:\n" + lines.join("\n") + "\nDo NOT attempt to message these agents. Use the {{steps.<name>.output}} references above to access their results.";
|
|
52128
|
+
return this.channelMessenger.buildNonInteractiveAwareness(agentMap, stepStates);
|
|
51151
52129
|
}
|
|
51152
52130
|
/**
|
|
51153
52131
|
* Build guidance that encourages agents to autonomously delegate subtasks
|
|
@@ -51162,28 +52140,10 @@ DO NOT:
|
|
|
51162
52140
|
* key, but they won't call `register` unless explicitly told to.
|
|
51163
52141
|
*/
|
|
51164
52142
|
buildRelayRegistrationNote(cli, agentName) {
|
|
51165
|
-
|
|
51166
|
-
return "";
|
|
51167
|
-
return `---
|
|
51168
|
-
RELAY SETUP \u2014 do this FIRST before any other relay tool:
|
|
51169
|
-
1. Call: register(name="${agentName}")
|
|
51170
|
-
This authenticates you in the Relaycast workspace.
|
|
51171
|
-
ALL relay tools (mcp__relaycast__message_dm_send, mcp__relaycast__message_inbox_check, mcp__relaycast__message_post, etc.) require
|
|
51172
|
-
registration first \u2014 they will fail with "Not registered" otherwise.
|
|
51173
|
-
2. Your agent name is "${agentName}" \u2014 use this exact name when registering.`;
|
|
52143
|
+
return this.channelMessenger.buildRelayRegistrationNote(cli, agentName);
|
|
51174
52144
|
}
|
|
51175
52145
|
buildDelegationGuidance(cli, timeoutMs) {
|
|
51176
|
-
|
|
51177
|
-
|
|
51178
|
-
` : "";
|
|
51179
|
-
const subAgentOption = cli === "claude" ? "Option 2 \u2014 Use built-in sub-agents (Task tool) for research or scoped work:\n - Good for exploring code, reading files, or making targeted changes\n - Can run multiple sub-agents in parallel\n\n" : "";
|
|
51180
|
-
return "---\nAUTONOMOUS DELEGATION \u2014 READ THIS BEFORE STARTING:\n" + timeoutNote + 'Before diving in, assess whether this task is too large or complex for a single agent. If it involves multiple independent subtasks, touches many files, or could take a long time, you should break it down and delegate to helper agents to avoid timeouts.\n\nOption 1 \u2014 Spawn relay agents (for real parallel coding work):\n - mcp__relaycast__agent_add(name="helper-1", cli="claude", task="Specific subtask description")\n - Coordinate via mcp__relaycast__message_dm_send(to="helper-1", text="...")\n - Check on them with mcp__relaycast__message_inbox_check()\n - Clean up when done: mcp__relaycast__agent_remove(name="helper-1")\n\n' + subAgentOption + `Guidelines:
|
|
51181
|
-
- You are the lead \u2014 delegate but stay in control, track progress, integrate results
|
|
51182
|
-
- Give each helper a clear, self-contained task with enough context to work independently
|
|
51183
|
-
- For simple or quick work, just do it yourself \u2014 don't over-delegate
|
|
51184
|
-
- Always release spawned relay agents when their work is complete
|
|
51185
|
-
- When spawning non-claude agents (codex, gemini, etc.), prepend to their task:
|
|
51186
|
-
"RELAY SETUP: First call register(name='<exact-agent-name>') before any other relay tool."`;
|
|
52146
|
+
return this.channelMessenger.buildDelegationGuidance(cli, timeoutMs);
|
|
51187
52147
|
}
|
|
51188
52148
|
/** Post a message to the workflow channel. Fire-and-forget — never throws or blocks. */
|
|
51189
52149
|
postToChannel(text, options = {}) {
|
|
@@ -51208,43 +52168,11 @@ RELAY SETUP \u2014 do this FIRST before any other relay tool:
|
|
|
51208
52168
|
}
|
|
51209
52169
|
/** Post a rich completion report to the channel. */
|
|
51210
52170
|
postCompletionReport(workflowName, outcomes, summary, confidence) {
|
|
51211
|
-
|
|
51212
|
-
const skipped = outcomes.filter((o) => o.status === "skipped");
|
|
51213
|
-
const retried = outcomes.filter((o) => o.attempts > 1);
|
|
51214
|
-
const lines = [
|
|
51215
|
-
`## Workflow **${workflowName}** \u2014 Complete`,
|
|
51216
|
-
"",
|
|
51217
|
-
summary,
|
|
51218
|
-
`Confidence: ${Math.round(confidence * 100)}%`,
|
|
51219
|
-
"",
|
|
51220
|
-
"### Steps",
|
|
51221
|
-
...completed.map((o) => `- **${o.name}** (${o.agent}) \u2014 passed${o.verificationPassed ? " (verified)" : ""}${o.attempts > 1 ? ` after ${o.attempts} attempts` : ""}`),
|
|
51222
|
-
...skipped.map((o) => `- **${o.name}** \u2014 skipped`)
|
|
51223
|
-
];
|
|
51224
|
-
if (retried.length > 0) {
|
|
51225
|
-
lines.push("", "### Retries");
|
|
51226
|
-
for (const o of retried) {
|
|
51227
|
-
lines.push(`- ${o.name}: ${o.attempts} attempts`);
|
|
51228
|
-
}
|
|
51229
|
-
}
|
|
51230
|
-
this.postToChannel(lines.join("\n"));
|
|
52171
|
+
this.channelMessenger.postCompletionReport(workflowName, outcomes, summary, confidence);
|
|
51231
52172
|
}
|
|
51232
52173
|
/** Post a failure report to the channel. */
|
|
51233
52174
|
postFailureReport(workflowName, outcomes, errorMsg) {
|
|
51234
|
-
|
|
51235
|
-
const failed = outcomes.filter((o) => o.status === "failed");
|
|
51236
|
-
const skipped = outcomes.filter((o) => o.status === "skipped");
|
|
51237
|
-
const lines = [
|
|
51238
|
-
`## Workflow **${workflowName}** \u2014 Failed`,
|
|
51239
|
-
"",
|
|
51240
|
-
`${completed.length}/${outcomes.length} steps passed. Error: ${errorMsg}`,
|
|
51241
|
-
"",
|
|
51242
|
-
"### Steps",
|
|
51243
|
-
...completed.map((o) => `- **${o.name}** (${o.agent}) \u2014 passed`),
|
|
51244
|
-
...failed.map((o) => `- **${o.name}** (${o.agent}) \u2014 FAILED: ${o.error ?? "unknown"}`),
|
|
51245
|
-
...skipped.map((o) => `- **${o.name}** \u2014 skipped`)
|
|
51246
|
-
];
|
|
51247
|
-
this.postToChannel(lines.join("\n"));
|
|
52175
|
+
this.channelMessenger.postFailureReport(workflowName, outcomes, errorMsg);
|
|
51248
52176
|
}
|
|
51249
52177
|
/**
|
|
51250
52178
|
* Log a human-readable run summary to the console after completion or failure.
|
|
@@ -51276,7 +52204,7 @@ RELAY SETUP \u2014 do this FIRST before any other relay tool:
|
|
|
51276
52204
|
}
|
|
51277
52205
|
}
|
|
51278
52206
|
const outputDir = this.getStepOutputDir(runId);
|
|
51279
|
-
const logsDir =
|
|
52207
|
+
const logsDir = import_node_path14.default.join(this.cwd, ".agent-relay", "team", "worker-logs");
|
|
51280
52208
|
console.log("");
|
|
51281
52209
|
console.log(` Run ID: ${runId}`);
|
|
51282
52210
|
console.log(` Step output: ${outputDir}`);
|
|
@@ -51362,8 +52290,8 @@ ${excerpt}` : "";
|
|
|
51362
52290
|
if (!target)
|
|
51363
52291
|
return;
|
|
51364
52292
|
try {
|
|
51365
|
-
(0,
|
|
51366
|
-
(0,
|
|
52293
|
+
(0, import_node_fs11.mkdirSync)(import_node_path14.default.dirname(target), { recursive: true });
|
|
52294
|
+
(0, import_node_fs11.writeFileSync)(target, runId + "\n", "utf8");
|
|
51367
52295
|
} catch {
|
|
51368
52296
|
}
|
|
51369
52297
|
}
|
|
@@ -51387,15 +52315,15 @@ ${excerpt}` : "";
|
|
|
51387
52315
|
const withoutSystemReminders = text.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/giu, "").replace(/<system-reminder>[\s\S]*/giu, "");
|
|
51388
52316
|
const normalized = withoutSystemReminders.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
51389
52317
|
const ansiStripped = stripAnsi(normalized);
|
|
51390
|
-
const
|
|
51391
|
-
const spinnerRe = new RegExp(`[${
|
|
51392
|
-
const spinnerClassRe = new RegExp(`^[\\s${
|
|
52318
|
+
const SPINNER2 = "\\u2756\\u2738\\u2739\\u273a\\u273b\\u273c\\u273d\\u2731\\u2732\\u2733\\u2734\\u2735\\u2736\\u2737\\u2743\\u2745\\u2746\\u25d6\\u25d7\\u25d8\\u25d9\\u2022\\u25cf\\u25cb\\u25a0\\u25a1\\u25b6\\u25c0\\u23f5\\u23f6\\u23f7\\u23f8\\u23f9\\u25e2\\u25e3\\u25e4\\u25e5\\u2597\\u2596\\u2598\\u259d\\u2bc8\\u2bc7\\u2bc5\\u2bc6\\u00b7\\u2590\\u258c\\u2588\\u2584\\u2580\\u259a\\u259e\\u2b21\\u2b22";
|
|
52319
|
+
const spinnerRe = new RegExp(`[${SPINNER2}]`, "gu");
|
|
52320
|
+
const spinnerClassRe = new RegExp(`^[\\s${SPINNER2}]*$`, "u");
|
|
51393
52321
|
const boxDrawingOnlyRe = /^[\s\u2500-\u257f\u2580-\u259f\u25a0-\u25ff\-_=~]{3,}$/u;
|
|
51394
52322
|
const brokerLogRe = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z\s+(?:INFO|WARN|ERROR|DEBUG)\s/u;
|
|
51395
52323
|
const claudeHeaderRe = /^(?:[\s\u2580-\u259f✢*·▗▖▘▝]+\s*)?(?:Claude\s+Code(?:\s+v?[\d.]+)?|(?:Sonnet|Haiku|Opus)\s*[\d.]+|claude-(?:sonnet|haiku|opus)-[\w.-]+|Running\s+on\s+claude)/iu;
|
|
51396
52324
|
const dirBreadcrumbRe = /^\s*~[\\/]/u;
|
|
51397
52325
|
const uiHintRe = /\b(?:Press\s+up\s+to\s+edit|tab\s+to\s+queue|bypass\s+permissions|esc\s+to\s+interrupt)\b/iu;
|
|
51398
|
-
const thinkingLineRe = new RegExp(`^[\\s${
|
|
52326
|
+
const thinkingLineRe = new RegExp(`^[\\s${SPINNER2}]*\\s*\\w[\\w\\s]*\\u2026\\s*$`, "u");
|
|
51399
52327
|
const cursorOnlyRe = /^[\s❯⎿›»◀▶←→↑↓⟨⟩⟪⟫·]+$/u;
|
|
51400
52328
|
const cursorAgentRe = /^(?:Cursor Agent|[\s⬡⬢]*Generating[.\s]|\[Pasted text|Auto-run all|Add a follow-up|ctrl\+c to stop|shift\+tab|Auto$|\/\s*commands|@\s*files|!\s*shell|follow-ups?\s|The user ha)/iu;
|
|
51401
52329
|
const slashCommandRe = /^\/\w+\s*$/u;
|
|
@@ -51472,14 +52400,14 @@ ${excerpt}` : "";
|
|
|
51472
52400
|
/** Directory for persisted step outputs: .agent-relay/step-outputs/{runId}/ */
|
|
51473
52401
|
getStepOutputDir(runId) {
|
|
51474
52402
|
this.validateRunId(runId);
|
|
51475
|
-
return
|
|
52403
|
+
return import_node_path14.default.join(this.cwd, ".agent-relay", "step-outputs", runId);
|
|
51476
52404
|
}
|
|
51477
52405
|
/** Persist step output to disk and post full output as a channel message. */
|
|
51478
52406
|
async persistStepOutput(runId, stepName, output) {
|
|
51479
|
-
const outputPath =
|
|
52407
|
+
const outputPath = import_node_path14.default.join(this.getStepOutputDir(runId), `${stepName}.md`);
|
|
51480
52408
|
try {
|
|
51481
52409
|
const dir = this.getStepOutputDir(runId);
|
|
51482
|
-
(0,
|
|
52410
|
+
(0, import_node_fs11.mkdirSync)(dir, { recursive: true });
|
|
51483
52411
|
const cleaned = _WorkflowRunner.stripAnsi(output);
|
|
51484
52412
|
await (0, import_promises5.writeFile)(outputPath, cleaned);
|
|
51485
52413
|
} catch {
|
|
@@ -51502,9 +52430,9 @@ ${preview}
|
|
|
51502
52430
|
\`\`\``, { stepName });
|
|
51503
52431
|
}
|
|
51504
52432
|
async persistAgentReport(runId, stepName, report) {
|
|
51505
|
-
const reportPath =
|
|
52433
|
+
const reportPath = import_node_path14.default.join(this.getStepOutputDir(runId), `${stepName}.report.json`);
|
|
51506
52434
|
try {
|
|
51507
|
-
(0,
|
|
52435
|
+
(0, import_node_fs11.mkdirSync)(this.getStepOutputDir(runId), { recursive: true });
|
|
51508
52436
|
await (0, import_promises5.writeFile)(reportPath, JSON.stringify(report, null, 2), "utf8");
|
|
51509
52437
|
} catch {
|
|
51510
52438
|
}
|
|
@@ -51512,18 +52440,18 @@ ${preview}
|
|
|
51512
52440
|
/** Scan .agent-relay/step-outputs/ for the most recent run directory containing the needed steps. */
|
|
51513
52441
|
findMostRecentRunWithSteps(stepNames) {
|
|
51514
52442
|
try {
|
|
51515
|
-
const baseDir =
|
|
51516
|
-
if (!(0,
|
|
52443
|
+
const baseDir = import_node_path14.default.join(this.cwd, ".agent-relay", "step-outputs");
|
|
52444
|
+
if (!(0, import_node_fs11.existsSync)(baseDir))
|
|
51517
52445
|
return void 0;
|
|
51518
|
-
const entries = (0,
|
|
52446
|
+
const entries = (0, import_node_fs11.readdirSync)(baseDir);
|
|
51519
52447
|
let best;
|
|
51520
52448
|
for (const entry of entries) {
|
|
51521
|
-
const dirPath =
|
|
52449
|
+
const dirPath = import_node_path14.default.join(baseDir, entry);
|
|
51522
52450
|
try {
|
|
51523
|
-
const stat2 = (0,
|
|
52451
|
+
const stat2 = (0, import_node_fs11.statSync)(dirPath);
|
|
51524
52452
|
if (!stat2.isDirectory())
|
|
51525
52453
|
continue;
|
|
51526
|
-
const hasAny = [...stepNames].some((name) => (0,
|
|
52454
|
+
const hasAny = [...stepNames].some((name) => (0, import_node_fs11.existsSync)(import_node_path14.default.join(dirPath, `${name}.md`)));
|
|
51527
52455
|
if (!hasAny)
|
|
51528
52456
|
continue;
|
|
51529
52457
|
if (!best || stat2.mtimeMs > best.mtime) {
|
|
@@ -51541,10 +52469,10 @@ ${preview}
|
|
|
51541
52469
|
/** Load persisted step output from disk. */
|
|
51542
52470
|
loadStepOutput(runId, stepName) {
|
|
51543
52471
|
try {
|
|
51544
|
-
const filePath =
|
|
51545
|
-
if (!(0,
|
|
52472
|
+
const filePath = import_node_path14.default.join(this.getStepOutputDir(runId), `${stepName}.md`);
|
|
52473
|
+
if (!(0, import_node_fs11.existsSync)(filePath))
|
|
51546
52474
|
return void 0;
|
|
51547
|
-
return (0,
|
|
52475
|
+
return (0, import_node_fs11.readFileSync)(filePath, "utf-8");
|
|
51548
52476
|
} catch {
|
|
51549
52477
|
return void 0;
|
|
51550
52478
|
}
|
|
@@ -51566,14 +52494,14 @@ ${preview}
|
|
|
51566
52494
|
}
|
|
51567
52495
|
reconstructRunFromCache(runId, config2) {
|
|
51568
52496
|
const stepOutputDir = this.getStepOutputDir(runId);
|
|
51569
|
-
if (!(0,
|
|
52497
|
+
if (!(0, import_node_fs11.existsSync)(stepOutputDir))
|
|
51570
52498
|
return null;
|
|
51571
52499
|
let resumeConfig = config2 ?? this.currentConfig;
|
|
51572
52500
|
if (!resumeConfig) {
|
|
51573
|
-
const yamlPath =
|
|
51574
|
-
if ((0,
|
|
52501
|
+
const yamlPath = import_node_path14.default.join(this.cwd, "relay.yaml");
|
|
52502
|
+
if ((0, import_node_fs11.existsSync)(yamlPath)) {
|
|
51575
52503
|
try {
|
|
51576
|
-
const raw = (0,
|
|
52504
|
+
const raw = (0, import_node_fs11.readFileSync)(yamlPath, "utf-8");
|
|
51577
52505
|
resumeConfig = this.parseYamlString(raw, yamlPath);
|
|
51578
52506
|
} catch {
|
|
51579
52507
|
return null;
|
|
@@ -51584,7 +52512,7 @@ ${preview}
|
|
|
51584
52512
|
}
|
|
51585
52513
|
let entries;
|
|
51586
52514
|
try {
|
|
51587
|
-
entries = (0,
|
|
52515
|
+
entries = (0, import_node_fs11.readdirSync)(stepOutputDir, { withFileTypes: true });
|
|
51588
52516
|
} catch {
|
|
51589
52517
|
return null;
|
|
51590
52518
|
}
|
|
@@ -51599,10 +52527,10 @@ ${preview}
|
|
|
51599
52527
|
let earliestMtime = Date.now();
|
|
51600
52528
|
for (const stepName of cachedStepNames) {
|
|
51601
52529
|
try {
|
|
51602
|
-
const mdPath =
|
|
51603
|
-
const reportPath =
|
|
51604
|
-
const mdStat = (0,
|
|
51605
|
-
const reportStat = (0,
|
|
52530
|
+
const mdPath = import_node_path14.default.join(stepOutputDir, `${stepName}.md`);
|
|
52531
|
+
const reportPath = import_node_path14.default.join(stepOutputDir, `${stepName}.report.json`);
|
|
52532
|
+
const mdStat = (0, import_node_fs11.existsSync)(mdPath) ? (0, import_node_fs11.statSync)(mdPath) : null;
|
|
52533
|
+
const reportStat = (0, import_node_fs11.existsSync)(reportPath) ? (0, import_node_fs11.statSync)(reportPath) : null;
|
|
51606
52534
|
const mtime = Math.max(mdStat?.mtimeMs ?? 0, reportStat?.mtimeMs ?? 0);
|
|
51607
52535
|
if (mtime > 0) {
|
|
51608
52536
|
stepMtimes.set(stepName, new Date(mtime).toISOString());
|
|
@@ -51654,8 +52582,8 @@ ${preview}
|
|
|
51654
52582
|
}
|
|
51655
52583
|
/** Get or create the worker logs directory (.agent-relay/team/worker-logs) */
|
|
51656
52584
|
getWorkerLogsDir() {
|
|
51657
|
-
const logsDir =
|
|
51658
|
-
(0,
|
|
52585
|
+
const logsDir = import_node_path14.default.join(this.cwd, ".agent-relay", "team", "worker-logs");
|
|
52586
|
+
(0, import_node_fs11.mkdirSync)(logsDir, { recursive: true });
|
|
51659
52587
|
return logsDir;
|
|
51660
52588
|
}
|
|
51661
52589
|
/** Register a spawned agent in workers.json so `agents:kill` can find it. */
|
|
@@ -51666,12 +52594,12 @@ ${preview}
|
|
|
51666
52594
|
spawnedAt: Date.now(),
|
|
51667
52595
|
pid,
|
|
51668
52596
|
interactive,
|
|
51669
|
-
logFile:
|
|
52597
|
+
logFile: import_node_path14.default.join(this.getWorkerLogsDir(), `${agentName}.log`)
|
|
51670
52598
|
};
|
|
51671
52599
|
this.activeWorkers.set(agentName, workerEntry);
|
|
51672
52600
|
this.workersFileLock = this.workersFileLock.then(() => {
|
|
51673
52601
|
try {
|
|
51674
|
-
(0,
|
|
52602
|
+
(0, import_node_fs11.mkdirSync)(import_node_path14.default.dirname(this.workersPath), { recursive: true });
|
|
51675
52603
|
const existing = this.readWorkers().filter((w) => w.name !== agentName);
|
|
51676
52604
|
existing.push({ name: agentName, ...workerEntry });
|
|
51677
52605
|
this.writeWorkers(existing);
|
|
@@ -51693,22 +52621,22 @@ ${preview}
|
|
|
51693
52621
|
}
|
|
51694
52622
|
readWorkers() {
|
|
51695
52623
|
try {
|
|
51696
|
-
if (!(0,
|
|
52624
|
+
if (!(0, import_node_fs11.existsSync)(this.workersPath))
|
|
51697
52625
|
return [];
|
|
51698
|
-
const raw = JSON.parse((0,
|
|
52626
|
+
const raw = JSON.parse((0, import_node_fs11.readFileSync)(this.workersPath, "utf-8"));
|
|
51699
52627
|
return Array.isArray(raw?.workers) ? raw.workers : [];
|
|
51700
52628
|
} catch {
|
|
51701
52629
|
return [];
|
|
51702
52630
|
}
|
|
51703
52631
|
}
|
|
51704
52632
|
writeWorkers(workers) {
|
|
51705
|
-
(0,
|
|
52633
|
+
(0, import_node_fs11.writeFileSync)(this.workersPath, JSON.stringify({ workers }, null, 2));
|
|
51706
52634
|
}
|
|
51707
52635
|
};
|
|
51708
52636
|
|
|
51709
52637
|
// packages/sdk/dist/workflows/file-db.js
|
|
51710
|
-
var
|
|
51711
|
-
var
|
|
52638
|
+
var import_node_fs12 = require("node:fs");
|
|
52639
|
+
var import_node_path15 = __toESM(require("node:path"), 1);
|
|
51712
52640
|
var JsonFileWorkflowDb = class {
|
|
51713
52641
|
filePath;
|
|
51714
52642
|
/** Whether the storage directory is writable. False = silent no-op mode. */
|
|
@@ -51718,7 +52646,7 @@ var JsonFileWorkflowDb = class {
|
|
|
51718
52646
|
this.filePath = filePath;
|
|
51719
52647
|
let writable = false;
|
|
51720
52648
|
try {
|
|
51721
|
-
(0,
|
|
52649
|
+
(0, import_node_fs12.mkdirSync)(import_node_path15.default.dirname(filePath), { recursive: true });
|
|
51722
52650
|
writable = true;
|
|
51723
52651
|
} catch {
|
|
51724
52652
|
}
|
|
@@ -51730,8 +52658,8 @@ var JsonFileWorkflowDb = class {
|
|
|
51730
52658
|
}
|
|
51731
52659
|
hasStepOutputs(runId) {
|
|
51732
52660
|
try {
|
|
51733
|
-
const dir =
|
|
51734
|
-
return (0,
|
|
52661
|
+
const dir = import_node_path15.default.join(import_node_path15.default.dirname(this.filePath), "step-outputs", runId);
|
|
52662
|
+
return (0, import_node_fs12.existsSync)(dir) && (0, import_node_fs12.readdirSync)(dir).length > 0;
|
|
51735
52663
|
} catch {
|
|
51736
52664
|
return false;
|
|
51737
52665
|
}
|
|
@@ -51741,7 +52669,7 @@ var JsonFileWorkflowDb = class {
|
|
|
51741
52669
|
if (!this.writable)
|
|
51742
52670
|
return;
|
|
51743
52671
|
try {
|
|
51744
|
-
(0,
|
|
52672
|
+
(0, import_node_fs12.appendFileSync)(this.filePath, JSON.stringify(entry) + "\n", "utf8");
|
|
51745
52673
|
} catch (err) {
|
|
51746
52674
|
if (!this.appendFailedOnce) {
|
|
51747
52675
|
this.appendFailedOnce = true;
|
|
@@ -51755,7 +52683,7 @@ var JsonFileWorkflowDb = class {
|
|
|
51755
52683
|
const steps = /* @__PURE__ */ new Map();
|
|
51756
52684
|
let raw = "";
|
|
51757
52685
|
try {
|
|
51758
|
-
raw = (0,
|
|
52686
|
+
raw = (0, import_node_fs12.readFileSync)(this.filePath, "utf8");
|
|
51759
52687
|
} catch {
|
|
51760
52688
|
return { runs, steps };
|
|
51761
52689
|
}
|
|
@@ -53197,8 +54125,8 @@ var StateStore = class extends import_node_events4.EventEmitter {
|
|
|
53197
54125
|
};
|
|
53198
54126
|
|
|
53199
54127
|
// packages/sdk/dist/workflows/templates.js
|
|
53200
|
-
var
|
|
53201
|
-
var
|
|
54128
|
+
var import_node_fs13 = require("node:fs");
|
|
54129
|
+
var import_node_path16 = __toESM(require("node:path"), 1);
|
|
53202
54130
|
var import_node_url2 = require("node:url");
|
|
53203
54131
|
var import_yaml4 = __toESM(require_dist(), 1);
|
|
53204
54132
|
var YAML_EXTENSIONS = [".yaml", ".yml"];
|
|
@@ -53223,7 +54151,7 @@ var TemplateRegistry = class {
|
|
|
53223
54151
|
fetcher;
|
|
53224
54152
|
constructor(options = {}) {
|
|
53225
54153
|
this.builtInTemplatesDir = this.resolveBuiltInTemplatesDir(options.builtInTemplatesDir);
|
|
53226
|
-
this.customTemplatesDir = options.customTemplatesDir ?
|
|
54154
|
+
this.customTemplatesDir = options.customTemplatesDir ? import_node_path16.default.resolve(options.customTemplatesDir) : import_node_path16.default.resolve(options.workspaceDir ?? process.cwd(), ".relay/workflows");
|
|
53227
54155
|
this.fetcher = options.fetcher ?? fetch;
|
|
53228
54156
|
}
|
|
53229
54157
|
listBuiltInTemplates() {
|
|
@@ -53297,13 +54225,13 @@ var TemplateRegistry = class {
|
|
|
53297
54225
|
if (!templateName) {
|
|
53298
54226
|
throw new Error('Template name is required. Provide name explicitly or include a string "name" field.');
|
|
53299
54227
|
}
|
|
53300
|
-
if (templateName.includes("/") || templateName.includes("\\") || templateName.includes("..") ||
|
|
54228
|
+
if (templateName.includes("/") || templateName.includes("\\") || templateName.includes("..") || import_node_path16.default.isAbsolute(templateName)) {
|
|
53301
54229
|
throw new Error(`Invalid template name: "${templateName}" contains path separators or traversal sequences`);
|
|
53302
54230
|
}
|
|
53303
54231
|
this.validateRelayConfig(parsed, url2);
|
|
53304
|
-
await
|
|
53305
|
-
const targetPath =
|
|
53306
|
-
await
|
|
54232
|
+
await import_node_fs13.promises.mkdir(this.customTemplatesDir, { recursive: true });
|
|
54233
|
+
const targetPath = import_node_path16.default.join(this.customTemplatesDir, `${templateName}.yaml`);
|
|
54234
|
+
await import_node_fs13.promises.writeFile(targetPath, (0, import_yaml4.stringify)(parsed), "utf-8");
|
|
53307
54235
|
return targetPath;
|
|
53308
54236
|
}
|
|
53309
54237
|
isTemplateShorthand(input) {
|
|
@@ -53324,15 +54252,15 @@ var TemplateRegistry = class {
|
|
|
53324
54252
|
}
|
|
53325
54253
|
resolveBuiltInTemplatesDir(explicitDir) {
|
|
53326
54254
|
if (explicitDir) {
|
|
53327
|
-
return
|
|
54255
|
+
return import_node_path16.default.resolve(explicitDir);
|
|
53328
54256
|
}
|
|
53329
|
-
const currentDir =
|
|
54257
|
+
const currentDir = import_node_path16.default.dirname((0, import_node_url2.fileURLToPath)(import_meta_url));
|
|
53330
54258
|
const candidates = [
|
|
53331
|
-
|
|
53332
|
-
|
|
54259
|
+
import_node_path16.default.resolve(currentDir, "builtin-templates"),
|
|
54260
|
+
import_node_path16.default.resolve(currentDir, "../workflows/builtin-templates")
|
|
53333
54261
|
];
|
|
53334
54262
|
for (const candidate of candidates) {
|
|
53335
|
-
if ((0,
|
|
54263
|
+
if ((0, import_node_fs13.existsSync)(candidate)) {
|
|
53336
54264
|
return candidate;
|
|
53337
54265
|
}
|
|
53338
54266
|
}
|
|
@@ -53352,9 +54280,9 @@ var TemplateRegistry = class {
|
|
|
53352
54280
|
}
|
|
53353
54281
|
async findTemplatePath(directory, templateName) {
|
|
53354
54282
|
for (const ext of YAML_EXTENSIONS) {
|
|
53355
|
-
const candidate =
|
|
54283
|
+
const candidate = import_node_path16.default.join(directory, `${templateName}${ext}`);
|
|
53356
54284
|
try {
|
|
53357
|
-
const stat2 = await
|
|
54285
|
+
const stat2 = await import_node_fs13.promises.stat(candidate);
|
|
53358
54286
|
if (stat2.isFile()) {
|
|
53359
54287
|
return candidate;
|
|
53360
54288
|
}
|
|
@@ -53364,7 +54292,7 @@ var TemplateRegistry = class {
|
|
|
53364
54292
|
return void 0;
|
|
53365
54293
|
}
|
|
53366
54294
|
async readTemplateFile(templatePath) {
|
|
53367
|
-
const raw = await
|
|
54295
|
+
const raw = await import_node_fs13.promises.readFile(templatePath, "utf-8");
|
|
53368
54296
|
const parsed = (0, import_yaml4.parse)(raw);
|
|
53369
54297
|
if (!isRecord(parsed)) {
|
|
53370
54298
|
throw new Error(`Template at ${templatePath} is not a YAML object`);
|
|
@@ -53557,7 +54485,7 @@ var TemplateRegistry = class {
|
|
|
53557
54485
|
}
|
|
53558
54486
|
async safeReadDir(directory) {
|
|
53559
54487
|
try {
|
|
53560
|
-
return await
|
|
54488
|
+
return await import_node_fs13.promises.readdir(directory);
|
|
53561
54489
|
} catch {
|
|
53562
54490
|
return [];
|
|
53563
54491
|
}
|
|
@@ -53724,8 +54652,8 @@ function isValidAgentName(name) {
|
|
|
53724
54652
|
}
|
|
53725
54653
|
|
|
53726
54654
|
// packages/utils/dist/logger.js
|
|
53727
|
-
var
|
|
53728
|
-
var
|
|
54655
|
+
var import_node_fs14 = __toESM(require("node:fs"), 1);
|
|
54656
|
+
var import_node_path17 = __toESM(require("node:path"), 1);
|
|
53729
54657
|
function getLogFile() {
|
|
53730
54658
|
return process.env.AGENT_RELAY_LOG_FILE;
|
|
53731
54659
|
}
|
|
@@ -53743,9 +54671,9 @@ var LEVEL_PRIORITY = {
|
|
|
53743
54671
|
};
|
|
53744
54672
|
var createdLogDirs = /* @__PURE__ */ new Set();
|
|
53745
54673
|
function ensureLogDir(logFile) {
|
|
53746
|
-
const logDir =
|
|
53747
|
-
if (!createdLogDirs.has(logDir) && !
|
|
53748
|
-
|
|
54674
|
+
const logDir = import_node_path17.default.dirname(logFile);
|
|
54675
|
+
if (!createdLogDirs.has(logDir) && !import_node_fs14.default.existsSync(logDir)) {
|
|
54676
|
+
import_node_fs14.default.mkdirSync(logDir, { recursive: true });
|
|
53749
54677
|
createdLogDirs.add(logDir);
|
|
53750
54678
|
}
|
|
53751
54679
|
}
|
|
@@ -53774,7 +54702,7 @@ function log(level, component, msg, extra) {
|
|
|
53774
54702
|
const logFile = getLogFile();
|
|
53775
54703
|
if (logFile) {
|
|
53776
54704
|
ensureLogDir(logFile);
|
|
53777
|
-
|
|
54705
|
+
import_node_fs14.default.appendFileSync(logFile, formatted + "\n");
|
|
53778
54706
|
return;
|
|
53779
54707
|
}
|
|
53780
54708
|
if (level === "ERROR" || level === "WARN") {
|
|
@@ -54044,14 +54972,14 @@ function benchmarkPatterns(iterations = 1e4) {
|
|
|
54044
54972
|
}
|
|
54045
54973
|
|
|
54046
54974
|
// packages/utils/dist/command-resolver.js
|
|
54047
|
-
var
|
|
54048
|
-
var
|
|
54975
|
+
var import_node_child_process7 = require("node:child_process");
|
|
54976
|
+
var import_node_fs15 = __toESM(require("node:fs"), 1);
|
|
54049
54977
|
function resolveCommand(command) {
|
|
54050
54978
|
if (command.startsWith("/")) {
|
|
54051
54979
|
return resolveSymlinks(command);
|
|
54052
54980
|
}
|
|
54053
54981
|
try {
|
|
54054
|
-
const output = (0,
|
|
54982
|
+
const output = (0, import_node_child_process7.execSync)(`which ${command}`, {
|
|
54055
54983
|
encoding: "utf-8",
|
|
54056
54984
|
stdio: ["pipe", "pipe", "pipe"],
|
|
54057
54985
|
// Ensure we have a reasonable PATH
|
|
@@ -54071,7 +54999,7 @@ function resolveCommand(command) {
|
|
|
54071
54999
|
}
|
|
54072
55000
|
function resolveSymlinks(filePath) {
|
|
54073
55001
|
try {
|
|
54074
|
-
const resolved =
|
|
55002
|
+
const resolved = import_node_fs15.default.realpathSync(filePath);
|
|
54075
55003
|
if (resolved !== filePath && process.env.DEBUG_SPAWN === "1") {
|
|
54076
55004
|
console.log(`[command-resolver] Resolved symlink: ${filePath} -> ${resolved}`);
|
|
54077
55005
|
}
|
|
@@ -54085,7 +55013,7 @@ function resolveSymlinks(filePath) {
|
|
|
54085
55013
|
}
|
|
54086
55014
|
function commandExists(command) {
|
|
54087
55015
|
try {
|
|
54088
|
-
(0,
|
|
55016
|
+
(0, import_node_child_process7.execSync)(`which ${command}`, {
|
|
54089
55017
|
encoding: "utf-8",
|
|
54090
55018
|
stdio: ["pipe", "pipe", "pipe"]
|
|
54091
55019
|
});
|
|
@@ -54097,8 +55025,8 @@ function commandExists(command) {
|
|
|
54097
55025
|
|
|
54098
55026
|
// packages/utils/dist/git-remote.js
|
|
54099
55027
|
var fs6 = __toESM(require("node:fs"), 1);
|
|
54100
|
-
var
|
|
54101
|
-
var
|
|
55028
|
+
var path15 = __toESM(require("node:path"), 1);
|
|
55029
|
+
var import_node_child_process8 = require("node:child_process");
|
|
54102
55030
|
function parseGitRemoteUrl(url2) {
|
|
54103
55031
|
if (!url2)
|
|
54104
55032
|
return null;
|
|
@@ -54114,11 +55042,11 @@ function parseGitRemoteUrl(url2) {
|
|
|
54114
55042
|
}
|
|
54115
55043
|
function getGitRemoteUrl(workingDirectory, remoteName = "origin") {
|
|
54116
55044
|
try {
|
|
54117
|
-
const gitDir =
|
|
55045
|
+
const gitDir = path15.join(workingDirectory, ".git");
|
|
54118
55046
|
if (!fs6.existsSync(gitDir)) {
|
|
54119
55047
|
return null;
|
|
54120
55048
|
}
|
|
54121
|
-
const result = (0,
|
|
55049
|
+
const result = (0, import_node_child_process8.execSync)(`git remote get-url ${remoteName}`, {
|
|
54122
55050
|
cwd: workingDirectory,
|
|
54123
55051
|
encoding: "utf-8",
|
|
54124
55052
|
timeout: 5e3,
|
|
@@ -54127,7 +55055,7 @@ function getGitRemoteUrl(workingDirectory, remoteName = "origin") {
|
|
|
54127
55055
|
return result.trim() || null;
|
|
54128
55056
|
} catch {
|
|
54129
55057
|
try {
|
|
54130
|
-
const configPath =
|
|
55058
|
+
const configPath = path15.join(workingDirectory, ".git", "config");
|
|
54131
55059
|
if (!fs6.existsSync(configPath)) {
|
|
54132
55060
|
return null;
|
|
54133
55061
|
}
|
|
@@ -54148,13 +55076,13 @@ function getRepoFullName(workingDirectory) {
|
|
|
54148
55076
|
return parseGitRemoteUrl(remoteUrl);
|
|
54149
55077
|
}
|
|
54150
55078
|
function findGitRoot(startPath) {
|
|
54151
|
-
let currentPath =
|
|
54152
|
-
const root =
|
|
55079
|
+
let currentPath = path15.resolve(startPath);
|
|
55080
|
+
const root = path15.parse(currentPath).root;
|
|
54153
55081
|
while (currentPath !== root) {
|
|
54154
|
-
if (fs6.existsSync(
|
|
55082
|
+
if (fs6.existsSync(path15.join(currentPath, ".git"))) {
|
|
54155
55083
|
return currentPath;
|
|
54156
55084
|
}
|
|
54157
|
-
currentPath =
|
|
55085
|
+
currentPath = path15.dirname(currentPath);
|
|
54158
55086
|
}
|
|
54159
55087
|
return null;
|
|
54160
55088
|
}
|
|
@@ -54171,8 +55099,8 @@ function getRepoFullNameFromPath(workingDirectory) {
|
|
|
54171
55099
|
}
|
|
54172
55100
|
|
|
54173
55101
|
// packages/utils/dist/update-checker.js
|
|
54174
|
-
var
|
|
54175
|
-
var
|
|
55102
|
+
var import_node_fs16 = __toESM(require("node:fs"), 1);
|
|
55103
|
+
var import_node_path18 = __toESM(require("node:path"), 1);
|
|
54176
55104
|
var import_node_https = __toESM(require("node:https"), 1);
|
|
54177
55105
|
var import_node_os9 = __toESM(require("node:os"), 1);
|
|
54178
55106
|
var import_compare_versions = __toESM(require_umd(), 1);
|
|
@@ -54180,15 +55108,15 @@ var PACKAGE_NAME = "agent-relay";
|
|
|
54180
55108
|
var CHECK_INTERVAL_MS = 60 * 60 * 1e3;
|
|
54181
55109
|
var NPM_REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
|
|
54182
55110
|
function getCachePath() {
|
|
54183
|
-
const cacheDir =
|
|
54184
|
-
return
|
|
55111
|
+
const cacheDir = import_node_path18.default.join(import_node_os9.default.homedir(), ".agent-relay");
|
|
55112
|
+
return import_node_path18.default.join(cacheDir, "update-cache.json");
|
|
54185
55113
|
}
|
|
54186
55114
|
function readCache() {
|
|
54187
55115
|
try {
|
|
54188
55116
|
const cachePath = getCachePath();
|
|
54189
|
-
if (!
|
|
55117
|
+
if (!import_node_fs16.default.existsSync(cachePath))
|
|
54190
55118
|
return null;
|
|
54191
|
-
const data =
|
|
55119
|
+
const data = import_node_fs16.default.readFileSync(cachePath, "utf-8");
|
|
54192
55120
|
return JSON.parse(data);
|
|
54193
55121
|
} catch {
|
|
54194
55122
|
return null;
|
|
@@ -54197,27 +55125,27 @@ function readCache() {
|
|
|
54197
55125
|
function writeCache(cache) {
|
|
54198
55126
|
try {
|
|
54199
55127
|
const cachePath = getCachePath();
|
|
54200
|
-
const cacheDir =
|
|
54201
|
-
if (!
|
|
54202
|
-
|
|
55128
|
+
const cacheDir = import_node_path18.default.dirname(cachePath);
|
|
55129
|
+
if (!import_node_fs16.default.existsSync(cacheDir)) {
|
|
55130
|
+
import_node_fs16.default.mkdirSync(cacheDir, { recursive: true });
|
|
54203
55131
|
}
|
|
54204
|
-
|
|
55132
|
+
import_node_fs16.default.writeFileSync(cachePath, JSON.stringify(cache, null, 2));
|
|
54205
55133
|
} catch {
|
|
54206
55134
|
}
|
|
54207
55135
|
}
|
|
54208
55136
|
function fetchLatestVersion() {
|
|
54209
|
-
return new Promise((
|
|
55137
|
+
return new Promise((resolve4, reject) => {
|
|
54210
55138
|
const req = import_node_https.default.get(NPM_REGISTRY_URL, { timeout: 5e3 }, (res) => {
|
|
54211
55139
|
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
54212
55140
|
const location = res.headers.location;
|
|
54213
55141
|
if (location) {
|
|
54214
55142
|
import_node_https.default.get(location, { timeout: 5e3 }, (redirectRes) => {
|
|
54215
|
-
handleResponse(redirectRes,
|
|
55143
|
+
handleResponse(redirectRes, resolve4, reject);
|
|
54216
55144
|
}).on("error", reject);
|
|
54217
55145
|
return;
|
|
54218
55146
|
}
|
|
54219
55147
|
}
|
|
54220
|
-
handleResponse(res,
|
|
55148
|
+
handleResponse(res, resolve4, reject);
|
|
54221
55149
|
});
|
|
54222
55150
|
req.on("error", reject);
|
|
54223
55151
|
req.on("timeout", () => {
|
|
@@ -54226,7 +55154,7 @@ function fetchLatestVersion() {
|
|
|
54226
55154
|
});
|
|
54227
55155
|
});
|
|
54228
55156
|
}
|
|
54229
|
-
function handleResponse(res,
|
|
55157
|
+
function handleResponse(res, resolve4, reject) {
|
|
54230
55158
|
if (res.statusCode !== 200) {
|
|
54231
55159
|
reject(new Error(`HTTP ${res.statusCode}`));
|
|
54232
55160
|
return;
|
|
@@ -54239,7 +55167,7 @@ function handleResponse(res, resolve3, reject) {
|
|
|
54239
55167
|
try {
|
|
54240
55168
|
const json2 = JSON.parse(data);
|
|
54241
55169
|
if (json2.version) {
|
|
54242
|
-
|
|
55170
|
+
resolve4(json2.version);
|
|
54243
55171
|
} else {
|
|
54244
55172
|
reject(new Error("No version in response"));
|
|
54245
55173
|
}
|
|
@@ -54480,9 +55408,9 @@ function validateModelForCli(cli, model) {
|
|
|
54480
55408
|
}
|
|
54481
55409
|
|
|
54482
55410
|
// packages/utils/dist/relay-pty-path.js
|
|
54483
|
-
var
|
|
55411
|
+
var import_node_fs17 = __toESM(require("node:fs"), 1);
|
|
54484
55412
|
var import_node_os10 = __toESM(require("node:os"), 1);
|
|
54485
|
-
var
|
|
55413
|
+
var import_node_path19 = __toESM(require("node:path"), 1);
|
|
54486
55414
|
var SUPPORTED_PLATFORMS = {
|
|
54487
55415
|
darwin: {
|
|
54488
55416
|
arm64: "relay-pty-darwin-arm64",
|
|
@@ -54530,23 +55458,23 @@ function findRelayPtyBinary(callerDirname) {
|
|
|
54530
55458
|
const scopedMatch = normalizedCaller.match(/^(.+?\/node_modules)\/@agent-relay\//);
|
|
54531
55459
|
const directMatch = normalizedCaller.match(/^(.+?\/node_modules\/agent-relay)/);
|
|
54532
55460
|
if (scopedMatch) {
|
|
54533
|
-
packageRoots.push(
|
|
55461
|
+
packageRoots.push(import_node_path19.default.join(scopedMatch[1], "agent-relay"));
|
|
54534
55462
|
}
|
|
54535
55463
|
if (directMatch) {
|
|
54536
55464
|
packageRoots.push(directMatch[1]);
|
|
54537
55465
|
}
|
|
54538
55466
|
if (!normalizedCaller.includes("node_modules")) {
|
|
54539
|
-
packageRoots.push(
|
|
55467
|
+
packageRoots.push(import_node_path19.default.join(callerDirname, "..", "..", ".."));
|
|
54540
55468
|
}
|
|
54541
55469
|
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
54542
55470
|
if (home) {
|
|
54543
|
-
const npxCacheBase =
|
|
54544
|
-
if (
|
|
55471
|
+
const npxCacheBase = import_node_path19.default.join(home, ".npm", "_npx");
|
|
55472
|
+
if (import_node_fs17.default.existsSync(npxCacheBase)) {
|
|
54545
55473
|
try {
|
|
54546
|
-
const entries =
|
|
55474
|
+
const entries = import_node_fs17.default.readdirSync(npxCacheBase);
|
|
54547
55475
|
for (const entry of entries) {
|
|
54548
|
-
const npxPackage =
|
|
54549
|
-
if (
|
|
55476
|
+
const npxPackage = import_node_path19.default.join(npxCacheBase, entry, "node_modules", "agent-relay");
|
|
55477
|
+
if (import_node_fs17.default.existsSync(npxPackage)) {
|
|
54550
55478
|
packageRoots.push(npxPackage);
|
|
54551
55479
|
}
|
|
54552
55480
|
}
|
|
@@ -54554,42 +55482,42 @@ function findRelayPtyBinary(callerDirname) {
|
|
|
54554
55482
|
}
|
|
54555
55483
|
}
|
|
54556
55484
|
}
|
|
54557
|
-
packageRoots.push(
|
|
55485
|
+
packageRoots.push(import_node_path19.default.join(process.cwd(), "node_modules", "agent-relay"));
|
|
54558
55486
|
if (home) {
|
|
54559
|
-
packageRoots.push(
|
|
54560
|
-
packageRoots.push(
|
|
54561
|
-
packageRoots.push(
|
|
54562
|
-
packageRoots.push(
|
|
54563
|
-
packageRoots.push(
|
|
54564
|
-
packageRoots.push(
|
|
54565
|
-
packageRoots.push(
|
|
54566
|
-
packageRoots.push(
|
|
54567
|
-
}
|
|
54568
|
-
const bashInstallerDir = process.env.AGENT_RELAY_INSTALL_DIR ?
|
|
54569
|
-
const bashInstallerBinDir = process.env.AGENT_RELAY_BIN_DIR || (home ?
|
|
54570
|
-
const nodePrefix =
|
|
54571
|
-
packageRoots.push(
|
|
55487
|
+
packageRoots.push(import_node_path19.default.join(home, ".nvm", "versions", "node", process.version, "lib", "node_modules", "agent-relay"));
|
|
55488
|
+
packageRoots.push(import_node_path19.default.join(home, ".volta", "tools", "image", "packages", "agent-relay", "lib", "node_modules", "agent-relay"));
|
|
55489
|
+
packageRoots.push(import_node_path19.default.join(home, ".fnm", "node-versions", process.version, "installation", "lib", "node_modules", "agent-relay"));
|
|
55490
|
+
packageRoots.push(import_node_path19.default.join(home, "n", "lib", "node_modules", "agent-relay"));
|
|
55491
|
+
packageRoots.push(import_node_path19.default.join(home, ".asdf", "installs", "nodejs", process.version.replace("v", ""), "lib", "node_modules", "agent-relay"));
|
|
55492
|
+
packageRoots.push(import_node_path19.default.join(home, ".local", "share", "pnpm", "global", "node_modules", "agent-relay"));
|
|
55493
|
+
packageRoots.push(import_node_path19.default.join(home, ".config", "yarn", "global", "node_modules", "agent-relay"));
|
|
55494
|
+
packageRoots.push(import_node_path19.default.join(home, ".yarn", "global", "node_modules", "agent-relay"));
|
|
55495
|
+
}
|
|
55496
|
+
const bashInstallerDir = process.env.AGENT_RELAY_INSTALL_DIR ? import_node_path19.default.join(process.env.AGENT_RELAY_INSTALL_DIR, "bin") : home ? import_node_path19.default.join(home, ".agent-relay", "bin") : null;
|
|
55497
|
+
const bashInstallerBinDir = process.env.AGENT_RELAY_BIN_DIR || (home ? import_node_path19.default.join(home, ".local", "bin") : null);
|
|
55498
|
+
const nodePrefix = import_node_path19.default.resolve(import_node_path19.default.dirname(process.execPath), "..");
|
|
55499
|
+
packageRoots.push(import_node_path19.default.join(nodePrefix, "lib", "node_modules", "agent-relay"));
|
|
54572
55500
|
packageRoots.push("/usr/local/lib/node_modules/agent-relay");
|
|
54573
55501
|
packageRoots.push("/opt/homebrew/lib/node_modules/agent-relay");
|
|
54574
55502
|
packageRoots.push("/usr/lib/node_modules/agent-relay");
|
|
54575
55503
|
const candidates = [];
|
|
54576
55504
|
for (const root of packageRoots) {
|
|
54577
55505
|
if (platformBinary) {
|
|
54578
|
-
candidates.push(
|
|
55506
|
+
candidates.push(import_node_path19.default.join(root, "bin", platformBinary));
|
|
54579
55507
|
}
|
|
54580
|
-
candidates.push(
|
|
55508
|
+
candidates.push(import_node_path19.default.join(root, "bin", "relay-pty"));
|
|
54581
55509
|
}
|
|
54582
55510
|
if (bashInstallerDir) {
|
|
54583
55511
|
if (platformBinary) {
|
|
54584
|
-
candidates.push(
|
|
55512
|
+
candidates.push(import_node_path19.default.join(bashInstallerDir, platformBinary));
|
|
54585
55513
|
}
|
|
54586
|
-
candidates.push(
|
|
55514
|
+
candidates.push(import_node_path19.default.join(bashInstallerDir, "relay-pty"));
|
|
54587
55515
|
}
|
|
54588
55516
|
if (bashInstallerBinDir) {
|
|
54589
55517
|
if (platformBinary) {
|
|
54590
|
-
candidates.push(
|
|
55518
|
+
candidates.push(import_node_path19.default.join(bashInstallerBinDir, platformBinary));
|
|
54591
55519
|
}
|
|
54592
|
-
candidates.push(
|
|
55520
|
+
candidates.push(import_node_path19.default.join(bashInstallerBinDir, "relay-pty"));
|
|
54593
55521
|
}
|
|
54594
55522
|
candidates.push("/app/bin/relay-pty");
|
|
54595
55523
|
candidates.push("/usr/local/bin/relay-pty");
|
|
@@ -54604,7 +55532,7 @@ function findRelayPtyBinary(callerDirname) {
|
|
|
54604
55532
|
}
|
|
54605
55533
|
function isExecutable(filePath) {
|
|
54606
55534
|
try {
|
|
54607
|
-
|
|
55535
|
+
import_node_fs17.default.accessSync(filePath, import_node_fs17.default.constants.X_OK);
|
|
54608
55536
|
return true;
|
|
54609
55537
|
} catch {
|
|
54610
55538
|
return false;
|
|
@@ -54613,9 +55541,9 @@ function isExecutable(filePath) {
|
|
|
54613
55541
|
function isPlatformCompatibleBinary(filePath) {
|
|
54614
55542
|
let fd;
|
|
54615
55543
|
try {
|
|
54616
|
-
fd =
|
|
55544
|
+
fd = import_node_fs17.default.openSync(filePath, "r");
|
|
54617
55545
|
const header = Buffer.alloc(4);
|
|
54618
|
-
const bytesRead =
|
|
55546
|
+
const bytesRead = import_node_fs17.default.readSync(fd, header, 0, 4, 0);
|
|
54619
55547
|
if (bytesRead < 4) {
|
|
54620
55548
|
return false;
|
|
54621
55549
|
}
|
|
@@ -54633,7 +55561,7 @@ function isPlatformCompatibleBinary(filePath) {
|
|
|
54633
55561
|
} finally {
|
|
54634
55562
|
if (fd !== void 0) {
|
|
54635
55563
|
try {
|
|
54636
|
-
|
|
55564
|
+
import_node_fs17.default.closeSync(fd);
|
|
54637
55565
|
} catch {
|
|
54638
55566
|
}
|
|
54639
55567
|
}
|
|
@@ -54714,16 +55642,16 @@ function isMatchingResponse(response, requestId, correlationId) {
|
|
|
54714
55642
|
const ackPayload = response.type === "ACK" ? response.payload : null;
|
|
54715
55643
|
return response.id === requestId || responsePayload?.replyTo === requestId || !!correlationId && (responsePayload?.correlationId === correlationId || ackPayload?.correlationId === correlationId);
|
|
54716
55644
|
}
|
|
54717
|
-
function handleResponse2(response,
|
|
55645
|
+
function handleResponse2(response, resolve4, reject) {
|
|
54718
55646
|
const responsePayload = response.payload;
|
|
54719
55647
|
if (response.type === "ERROR") {
|
|
54720
55648
|
reject(new Error(responsePayload?.message || responsePayload?.code || "Unknown error"));
|
|
54721
55649
|
} else if (response.type === "ACK" || response.type === "SPAWN_RESULT" || response.type === "RELEASE_RESULT") {
|
|
54722
|
-
|
|
55650
|
+
resolve4(response.payload);
|
|
54723
55651
|
} else if (responsePayload?.error && !responsePayload?.success) {
|
|
54724
55652
|
reject(new Error(responsePayload.error));
|
|
54725
55653
|
} else {
|
|
54726
|
-
|
|
55654
|
+
resolve4(response.payload);
|
|
54727
55655
|
}
|
|
54728
55656
|
}
|
|
54729
55657
|
function createRequestEnvelope(type, payload, requestId, options) {
|
|
@@ -54757,7 +55685,7 @@ function toReleaseResult(payload) {
|
|
|
54757
55685
|
};
|
|
54758
55686
|
}
|
|
54759
55687
|
function createRequestHandler(socketPath, envelope, options) {
|
|
54760
|
-
return new Promise((
|
|
55688
|
+
return new Promise((resolve4, reject) => {
|
|
54761
55689
|
const correlationId = options.payloadMeta?.sync?.correlationId;
|
|
54762
55690
|
let timedOut = false;
|
|
54763
55691
|
const parser = new FrameParser();
|
|
@@ -54779,7 +55707,7 @@ function createRequestHandler(socketPath, envelope, options) {
|
|
|
54779
55707
|
if (isMatchingResponse(response, envelope.id, correlationId)) {
|
|
54780
55708
|
clearTimeout(timeoutId);
|
|
54781
55709
|
socket.end();
|
|
54782
|
-
handleResponse2(response,
|
|
55710
|
+
handleResponse2(response, resolve4, reject);
|
|
54783
55711
|
return;
|
|
54784
55712
|
}
|
|
54785
55713
|
}
|
|
@@ -55249,12 +56177,12 @@ var HookRegistry = class {
|
|
|
55249
56177
|
};
|
|
55250
56178
|
|
|
55251
56179
|
// packages/trajectory/dist/integration.js
|
|
55252
|
-
var
|
|
56180
|
+
var import_node_child_process9 = require("node:child_process");
|
|
55253
56181
|
|
|
55254
56182
|
// packages/config/dist/project-namespace.js
|
|
55255
56183
|
var import_node_crypto13 = __toESM(require("node:crypto"), 1);
|
|
55256
|
-
var
|
|
55257
|
-
var
|
|
56184
|
+
var import_node_path20 = __toESM(require("node:path"), 1);
|
|
56185
|
+
var import_node_fs18 = __toESM(require("node:fs"), 1);
|
|
55258
56186
|
var import_node_os11 = __toESM(require("node:os"), 1);
|
|
55259
56187
|
function getGlobalBaseDir2() {
|
|
55260
56188
|
if (process.env.AGENT_RELAY_DATA_DIR) {
|
|
@@ -55262,65 +56190,65 @@ function getGlobalBaseDir2() {
|
|
|
55262
56190
|
}
|
|
55263
56191
|
const xdgDataHome = process.env.XDG_DATA_HOME;
|
|
55264
56192
|
if (xdgDataHome) {
|
|
55265
|
-
return
|
|
56193
|
+
return import_node_path20.default.join(xdgDataHome, "agent-relay");
|
|
55266
56194
|
}
|
|
55267
|
-
return
|
|
56195
|
+
return import_node_path20.default.join(import_node_os11.default.homedir(), ".agent-relay");
|
|
55268
56196
|
}
|
|
55269
56197
|
var GLOBAL_BASE_DIR2 = getGlobalBaseDir2();
|
|
55270
56198
|
var PROJECT_DATA_DIR = ".agent-relay";
|
|
55271
56199
|
function hashPath(projectPath) {
|
|
55272
|
-
const normalized =
|
|
56200
|
+
const normalized = import_node_path20.default.resolve(projectPath);
|
|
55273
56201
|
const hash2 = import_node_crypto13.default.createHash("sha256").update(normalized).digest("hex");
|
|
55274
56202
|
return hash2.substring(0, 12);
|
|
55275
56203
|
}
|
|
55276
56204
|
function findProjectRoot(startDir = process.cwd()) {
|
|
55277
56205
|
if (process.env.AGENT_RELAY_PROJECT) {
|
|
55278
|
-
return
|
|
56206
|
+
return import_node_path20.default.resolve(process.env.AGENT_RELAY_PROJECT);
|
|
55279
56207
|
}
|
|
55280
|
-
let current =
|
|
55281
|
-
const root =
|
|
56208
|
+
let current = import_node_path20.default.resolve(startDir);
|
|
56209
|
+
const root = import_node_path20.default.parse(current).root;
|
|
55282
56210
|
const markers = [".git", "package.json", "Cargo.toml", "go.mod", "pyproject.toml", ".agent-relay"];
|
|
55283
56211
|
while (current !== root) {
|
|
55284
56212
|
for (const marker of markers) {
|
|
55285
|
-
if (
|
|
56213
|
+
if (import_node_fs18.default.existsSync(import_node_path20.default.join(current, marker))) {
|
|
55286
56214
|
return current;
|
|
55287
56215
|
}
|
|
55288
56216
|
}
|
|
55289
|
-
current =
|
|
56217
|
+
current = import_node_path20.default.dirname(current);
|
|
55290
56218
|
}
|
|
55291
|
-
return
|
|
56219
|
+
return import_node_path20.default.resolve(startDir);
|
|
55292
56220
|
}
|
|
55293
56221
|
function getProjectPaths2(projectRoot) {
|
|
55294
56222
|
const root = projectRoot ?? findProjectRoot();
|
|
55295
56223
|
const projectId = hashPath(root);
|
|
55296
|
-
const dataDir =
|
|
56224
|
+
const dataDir = import_node_path20.default.join(root, PROJECT_DATA_DIR);
|
|
55297
56225
|
return {
|
|
55298
56226
|
dataDir,
|
|
55299
|
-
teamDir:
|
|
55300
|
-
dbPath:
|
|
55301
|
-
socketPath:
|
|
56227
|
+
teamDir: import_node_path20.default.join(dataDir, "team"),
|
|
56228
|
+
dbPath: import_node_path20.default.join(dataDir, "messages.sqlite"),
|
|
56229
|
+
socketPath: import_node_path20.default.join(dataDir, "relay.sock"),
|
|
55302
56230
|
projectRoot: root,
|
|
55303
56231
|
projectId
|
|
55304
56232
|
};
|
|
55305
56233
|
}
|
|
55306
56234
|
|
|
55307
56235
|
// packages/config/dist/trajectory-config.js
|
|
55308
|
-
var
|
|
55309
|
-
var
|
|
56236
|
+
var import_node_fs19 = require("node:fs");
|
|
56237
|
+
var import_node_path21 = require("node:path");
|
|
55310
56238
|
var import_node_os12 = require("node:os");
|
|
55311
56239
|
var import_node_crypto14 = require("node:crypto");
|
|
55312
56240
|
function getAgentRelayConfigDir() {
|
|
55313
|
-
return process.env.AGENT_RELAY_CONFIG_DIR ?? (0,
|
|
56241
|
+
return process.env.AGENT_RELAY_CONFIG_DIR ?? (0, import_node_path21.join)((0, import_node_os12.homedir)(), ".config", "agent-relay");
|
|
55314
56242
|
}
|
|
55315
56243
|
var configCache = null;
|
|
55316
56244
|
function getRelayConfigPath(_projectRoot) {
|
|
55317
|
-
return (0,
|
|
56245
|
+
return (0, import_node_path21.join)(getAgentRelayConfigDir(), "relay.json");
|
|
55318
56246
|
}
|
|
55319
56247
|
function readRelayConfig(projectRoot) {
|
|
55320
56248
|
const configPath = getRelayConfigPath(projectRoot);
|
|
55321
56249
|
if (configCache && configCache.path === configPath) {
|
|
55322
56250
|
try {
|
|
55323
|
-
const stat2 = (0,
|
|
56251
|
+
const stat2 = (0, import_node_fs19.statSync)(configPath);
|
|
55324
56252
|
if (stat2.mtimeMs === configCache.mtime) {
|
|
55325
56253
|
return configCache.config;
|
|
55326
56254
|
}
|
|
@@ -55328,13 +56256,13 @@ function readRelayConfig(projectRoot) {
|
|
|
55328
56256
|
}
|
|
55329
56257
|
}
|
|
55330
56258
|
try {
|
|
55331
|
-
if (!(0,
|
|
56259
|
+
if (!(0, import_node_fs19.existsSync)(configPath)) {
|
|
55332
56260
|
return {};
|
|
55333
56261
|
}
|
|
55334
|
-
const content = (0,
|
|
56262
|
+
const content = (0, import_node_fs19.readFileSync)(configPath, "utf-8");
|
|
55335
56263
|
const config2 = JSON.parse(content);
|
|
55336
56264
|
try {
|
|
55337
|
-
const stat2 = (0,
|
|
56265
|
+
const stat2 = (0, import_node_fs19.statSync)(configPath);
|
|
55338
56266
|
configCache = { path: configPath, config: config2, mtime: stat2.mtimeMs };
|
|
55339
56267
|
} catch {
|
|
55340
56268
|
}
|
|
@@ -55354,12 +56282,12 @@ function getProjectHash(projectRoot) {
|
|
|
55354
56282
|
}
|
|
55355
56283
|
function getUserTrajectoriesDir(projectRoot) {
|
|
55356
56284
|
const projectHash = getProjectHash(projectRoot);
|
|
55357
|
-
const configDir = process.env.XDG_CONFIG_HOME || (0,
|
|
55358
|
-
return (0,
|
|
56285
|
+
const configDir = process.env.XDG_CONFIG_HOME || (0, import_node_path21.join)((0, import_node_os12.homedir)(), ".config");
|
|
56286
|
+
return (0, import_node_path21.join)(configDir, "agent-relay", "trajectories", projectHash);
|
|
55359
56287
|
}
|
|
55360
56288
|
function getRepoTrajectoriesDir(projectRoot) {
|
|
55361
56289
|
const root = projectRoot ?? getProjectPaths2().projectRoot;
|
|
55362
|
-
return (0,
|
|
56290
|
+
return (0, import_node_path21.join)(root, ".trajectories");
|
|
55363
56291
|
}
|
|
55364
56292
|
function getPrimaryTrajectoriesDir(projectRoot) {
|
|
55365
56293
|
if (shouldStoreInRepo(projectRoot)) {
|
|
@@ -55376,9 +56304,9 @@ function getTrajectoryEnvVars(projectRoot) {
|
|
|
55376
56304
|
|
|
55377
56305
|
// packages/trajectory/dist/integration.js
|
|
55378
56306
|
async function runTrail(args) {
|
|
55379
|
-
return new Promise((
|
|
56307
|
+
return new Promise((resolve4) => {
|
|
55380
56308
|
const trajectoryEnv = getTrajectoryEnvVars();
|
|
55381
|
-
const proc = (0,
|
|
56309
|
+
const proc = (0, import_node_child_process9.spawn)("trail", args, {
|
|
55382
56310
|
cwd: getProjectPaths2().projectRoot,
|
|
55383
56311
|
env: { ...process.env, ...trajectoryEnv },
|
|
55384
56312
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -55392,13 +56320,13 @@ async function runTrail(args) {
|
|
|
55392
56320
|
stderr += data.toString();
|
|
55393
56321
|
});
|
|
55394
56322
|
proc.on("error", (err) => {
|
|
55395
|
-
|
|
56323
|
+
resolve4({ success: false, output: "", error: `Failed to run trail: ${err.message}` });
|
|
55396
56324
|
});
|
|
55397
56325
|
proc.on("close", (code) => {
|
|
55398
56326
|
if (code === 0) {
|
|
55399
|
-
|
|
56327
|
+
resolve4({ success: true, output: stdout.trim() });
|
|
55400
56328
|
} else {
|
|
55401
|
-
|
|
56329
|
+
resolve4({ success: false, output: stdout.trim(), error: stderr.trim() || `Exit code: ${code}` });
|
|
55402
56330
|
}
|
|
55403
56331
|
});
|
|
55404
56332
|
});
|
|
@@ -55649,7 +56577,7 @@ var TrajectoryIntegration = class {
|
|
|
55649
56577
|
*/
|
|
55650
56578
|
isTrailInstalledSync() {
|
|
55651
56579
|
try {
|
|
55652
|
-
(0,
|
|
56580
|
+
(0, import_node_child_process9.execSync)("which trail", { stdio: "pipe" });
|
|
55653
56581
|
return true;
|
|
55654
56582
|
} catch {
|
|
55655
56583
|
return false;
|
|
@@ -55999,8 +56927,8 @@ var HookEmitter = class {
|
|
|
55999
56927
|
};
|
|
56000
56928
|
|
|
56001
56929
|
// packages/hooks/dist/inbox-check/utils.js
|
|
56002
|
-
var
|
|
56003
|
-
var
|
|
56930
|
+
var import_node_fs20 = require("node:fs");
|
|
56931
|
+
var import_node_path22 = require("node:path");
|
|
56004
56932
|
var DEFAULT_INBOX_DIR = "/tmp/agent-relay";
|
|
56005
56933
|
function getAgentName() {
|
|
56006
56934
|
return process.env.AGENT_RELAY_NAME;
|
|
@@ -56010,16 +56938,16 @@ function getInboxPath(config2) {
|
|
|
56010
56938
|
if (!agentName) {
|
|
56011
56939
|
throw new Error("Agent name not configured. Set AGENT_RELAY_NAME env var.");
|
|
56012
56940
|
}
|
|
56013
|
-
return (0,
|
|
56941
|
+
return (0, import_node_path22.join)(config2.inboxDir, agentName, "inbox.md");
|
|
56014
56942
|
}
|
|
56015
56943
|
function inboxExists(inboxPath) {
|
|
56016
|
-
return (0,
|
|
56944
|
+
return (0, import_node_fs20.existsSync)(inboxPath);
|
|
56017
56945
|
}
|
|
56018
56946
|
function readInbox(inboxPath) {
|
|
56019
56947
|
if (!inboxExists(inboxPath)) {
|
|
56020
56948
|
return "";
|
|
56021
56949
|
}
|
|
56022
|
-
return (0,
|
|
56950
|
+
return (0, import_node_fs20.readFileSync)(inboxPath, "utf-8");
|
|
56023
56951
|
}
|
|
56024
56952
|
function hasUnreadMessages(inboxPath) {
|
|
56025
56953
|
const content = readInbox(inboxPath);
|
|
@@ -56092,6 +57020,7 @@ init_dist2();
|
|
|
56092
57020
|
COMMON_SEARCH_PATHS,
|
|
56093
57021
|
CURSOR_MODEL_OPTIONS,
|
|
56094
57022
|
CUSTOM_STEPS_FILE,
|
|
57023
|
+
ChannelMessenger,
|
|
56095
57024
|
ClaudeModels,
|
|
56096
57025
|
CodexModels,
|
|
56097
57026
|
ConsensusEngine,
|
|
@@ -56121,24 +57050,33 @@ init_dist2();
|
|
|
56121
57050
|
ShadowManager,
|
|
56122
57051
|
StateStore,
|
|
56123
57052
|
StaticPatterns,
|
|
57053
|
+
StepExecutor,
|
|
56124
57054
|
SupermemoryAdapter,
|
|
56125
57055
|
SwarmCoordinator,
|
|
56126
57056
|
SwarmPatterns,
|
|
56127
57057
|
TemplateRegistry,
|
|
57058
|
+
TemplateResolver,
|
|
56128
57059
|
TracedError,
|
|
56129
57060
|
WorkflowBuilder,
|
|
57061
|
+
WorkflowCompletionError,
|
|
56130
57062
|
WorkflowRunner,
|
|
57063
|
+
WorkflowStepLifecycleExecutor,
|
|
56131
57064
|
WorkflowTrajectory,
|
|
56132
57065
|
benchmarkPatterns,
|
|
56133
57066
|
brokerLog,
|
|
56134
57067
|
buildBlockReason,
|
|
57068
|
+
buildCommand,
|
|
56135
57069
|
buildModelSwitchCommand,
|
|
57070
|
+
checkExitCode,
|
|
57071
|
+
checkFileExists,
|
|
56136
57072
|
checkForUpdates,
|
|
56137
57073
|
checkForUpdatesInBackground,
|
|
57074
|
+
checkOutputContains,
|
|
56138
57075
|
cleanLines,
|
|
56139
57076
|
clearBinaryCache,
|
|
56140
57077
|
clearResolveCache,
|
|
56141
57078
|
collectCliSession,
|
|
57079
|
+
collectOutput,
|
|
56142
57080
|
commandExists,
|
|
56143
57081
|
connectionLog,
|
|
56144
57082
|
countMessages,
|
|
@@ -56150,12 +57088,14 @@ init_dist2();
|
|
|
56150
57088
|
createMemoryAdapter,
|
|
56151
57089
|
createMemoryHooks,
|
|
56152
57090
|
createMemoryService,
|
|
57091
|
+
createProcessSpawner,
|
|
56153
57092
|
createRequestEnvelope,
|
|
56154
57093
|
createRequestHandler,
|
|
56155
57094
|
createTraceableError,
|
|
56156
57095
|
createTrajectoryHooks,
|
|
56157
57096
|
createWorkflowRenderer,
|
|
56158
57097
|
customStepsFileExists,
|
|
57098
|
+
detectCompletion,
|
|
56159
57099
|
estimateContextTokens,
|
|
56160
57100
|
estimateTokens,
|
|
56161
57101
|
executeApiStep,
|
|
@@ -56163,10 +57103,12 @@ init_dist2();
|
|
|
56163
57103
|
findRelayPtyBinary,
|
|
56164
57104
|
followLogs,
|
|
56165
57105
|
formatDryRunReport,
|
|
57106
|
+
formatError,
|
|
56166
57107
|
formatMessagePreview,
|
|
56167
57108
|
formatProposalMessage,
|
|
56168
57109
|
formatResultMessage,
|
|
56169
57110
|
formatRunSummaryTable,
|
|
57111
|
+
formatStepOutput,
|
|
56170
57112
|
generateAgentName,
|
|
56171
57113
|
generateErrorId,
|
|
56172
57114
|
generateRequestId,
|
|
@@ -56196,6 +57138,7 @@ init_dist2();
|
|
|
56196
57138
|
hasRelayPtyBinary,
|
|
56197
57139
|
hasUnreadMessages,
|
|
56198
57140
|
inboxExists,
|
|
57141
|
+
interpolateStepTask,
|
|
56199
57142
|
isAgentStep,
|
|
56200
57143
|
isConsensusCommand,
|
|
56201
57144
|
isCustomStep,
|
|
@@ -56228,15 +57171,28 @@ init_dist2();
|
|
|
56228
57171
|
resolveCliSync,
|
|
56229
57172
|
resolveCommand,
|
|
56230
57173
|
resolveCustomStep,
|
|
57174
|
+
resolveDotPath,
|
|
56231
57175
|
resolveSpawnPolicy,
|
|
57176
|
+
resolveStepOutputRef,
|
|
57177
|
+
resolveTemplate,
|
|
57178
|
+
resolveTemplateForShell,
|
|
57179
|
+
resolveVariables,
|
|
56232
57180
|
routerLog,
|
|
57181
|
+
runVerification,
|
|
56233
57182
|
runWorkflow,
|
|
57183
|
+
scrubForChannel,
|
|
57184
|
+
scrubSecrets,
|
|
57185
|
+
sendToChannel,
|
|
57186
|
+
shellEscape,
|
|
56234
57187
|
spawnFromEnv,
|
|
57188
|
+
spawnProcess,
|
|
56235
57189
|
stripAnsi,
|
|
56236
57190
|
stripAnsiFast,
|
|
57191
|
+
stripInjectedTaskEcho,
|
|
56237
57192
|
toReleaseResult,
|
|
56238
57193
|
toSpawnResult,
|
|
56239
57194
|
trackPatternPerformance,
|
|
57195
|
+
truncateMessage,
|
|
56240
57196
|
unescapeFenceMarkersFast,
|
|
56241
57197
|
validateCustomStepsUsage,
|
|
56242
57198
|
validateModelForCli,
|