@gobing-ai/spur 0.3.23 → 0.3.25
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/config/config.example.yaml +74 -31
- package/config/templates/AGENTS.md +1 -0
- package/config/workflows/docs-pipeline.yaml +9 -0
- package/config/workflows/idea-pipeline.yaml +78 -18
- package/package.json +9 -9
- package/schemas/spur-config.schema.json +4 -4
- package/schemas/task-batch.schema.json +12 -0
- package/spur.js +1893 -477
- package/web/_astro/{BoardApp.b8HvN_Uy.js → BoardApp.DH9wI8y7.js} +72 -72
- package/web/_astro/BoardApp.DZiwQCP7.js +1 -0
- package/web/_astro/{TaskDetail.BRr8ebLd.js → TaskDetail.Dsk9DnGY.js} +1 -1
- package/web/_astro/{arc.D9I3ghf3.js → arc.Biv8k-OR.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.B60VjZ82.js → architectureDiagram-3BPJPVTR.BrtW5Sn7.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.B8xiXsGb.js → blockDiagram-GPEHLZMM.CTpFZJhW.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.D8Q9jRJZ.js → c4Diagram-AAUBKEIU._ZJj9H0G.js} +1 -1
- package/web/_astro/channel.Ih1_8SAH.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.BVcogAuP.js → chunk-2J33WTMH.DD9mDiEM.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.pDodeppW.js → chunk-4BX2VUAB.ENDQu3TH.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.5dYLJxJn.js → chunk-55IACEB6.DLpJf8Xp.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.C6GTI_n6.js → chunk-727SXJPM.BR6vsvIV.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.kgDX41bQ.js → chunk-AQP2D5EJ.DGOBzXM6.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.CSnAi74r.js → chunk-FMBD7UC4.DrghnRtZ.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.qQ8ldUUT.js → chunk-ND2GUHAM.BqIqI3oO.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.PzPFlVri.js → chunk-QZHKN3VN.CJ2RJt0K.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.C7RulRYW.js → classDiagram-4FO5ZUOK.Qu1p6crX.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.C7RulRYW.js → classDiagram-v2-Q7XG4LA2.Qu1p6crX.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.Dw4HZHnT.js → cose-bilkent-S5V4N54A.7VrRetJ0.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.MmGbZWM_.js → dagre-BM42HDAG.r4lTyJXQ.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.DugWYvZC.js → diagram-2AECGRRQ.DahExuaR.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.BL7D0BMi.js → diagram-5GNKFQAL.B-dSm3op.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.B9GQMjwM.js → diagram-KO2AKTUF.CQGlKa6a.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.CbHPvhbu.js → diagram-LMA3HP47.CJ6nomD-.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.Bx6GcKpw.js → diagram-OG6HWLK6.ijGl68sM.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35._sHJgXD7.js → erDiagram-TEJ5UH35.DBAe2Iin.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.D305L8m4.js → flowDiagram-I6XJVG4X.z3iXF6Ku.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.qjJ4kX00.js → ganttDiagram-6RSMTGT7.DP2ouiRt.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.D-t4MzVO.js → gitGraphDiagram-PVQCEYII.DizVfgVG.js} +1 -1
- package/web/_astro/index.D3Y4Q0mx.css +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.WwSNIljZ.js → infoDiagram-5YYISTIA.BPTTgL0f.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.EWsUYdpd.js → ishikawaDiagram-YF4QCWOH.CXdMa4-b.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.CqKE9hNP.js → journeyDiagram-JHISSGLW.ChSKZ-1j.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.BDCCufoa.js → kanban-definition-UN3LZRKU.DUUlW-km.js} +1 -1
- package/web/_astro/{linear.CyHEakPy.js → linear.AzHrSiEQ.js} +1 -1
- package/web/_astro/{mermaid.core.B-9P_KDH.js → mermaid.core.BajX78G7.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.bCxpjW2r.js → mindmap-definition-RKZ34NQL.BmdUHcac.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.x_CRiGMu.js → pieDiagram-4H26LBE5.Dh59Ur2v.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.CnbQkwo7.js → quadrantDiagram-W4KKPZXB.D2qYQmFj.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.CfeJKVEP.js → requirementDiagram-4Y6WPE33.DW5nnrHl.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.COYpTQlG.js → sankeyDiagram-5OEKKPKP.CMl1PJrk.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.DVzoeimO.js → sequenceDiagram-3UESZ5HK.U5dq1PA0.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.BVL5te9q.js → stateDiagram-AJRCARHV.zrt55DVx.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.C_x1GbV0.js → stateDiagram-v2-BHNVJYJU.CKBGQ0dG.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.DtZPbOJL.js → timeline-definition-PNZ67QCA.CKAlx9rU.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.pexoUOut.js → vennDiagram-CIIHVFJN.Bgt1eF06.js} +1 -1
- package/web/_astro/{wardley-L42UT6IY.DLG5pKRN.js → wardley-L42UT6IY.BF02aioC.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.CnYrM4tH.js → wardleyDiagram-YWT4CUSO.C94wxcnJ.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.kBrlce_Y.js → xychartDiagram-2RQKCTM6.BwK7SRoW.js} +1 -1
- package/web/index.html +2 -2
- package/web/_astro/BoardApp.LygxZgOy.js +0 -1
- package/web/_astro/channel.BToTp7Lu.js +0 -1
- package/web/_astro/index.CmVh0AUD.css +0 -1
package/spur.js
CHANGED
|
@@ -47,7 +47,7 @@ var __export = (target, all) => {
|
|
|
47
47
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
48
48
|
var __require = import.meta.require;
|
|
49
49
|
|
|
50
|
-
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.
|
|
50
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.14/node_modules/@gobing-ai/ts-utils/dist/errors.js
|
|
51
51
|
var ErrorCode;
|
|
52
52
|
var init_errors = __esm(() => {
|
|
53
53
|
ErrorCode = {
|
|
@@ -58,7 +58,7 @@ var init_errors = __esm(() => {
|
|
|
58
58
|
};
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
-
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.
|
|
61
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.14/node_modules/@gobing-ai/ts-utils/dist/api-response.js
|
|
62
62
|
var API_ERROR_CODES, ERROR_CODE_TO_HTTP, CLIENT_SAFE_CODES;
|
|
63
63
|
var init_api_response = __esm(() => {
|
|
64
64
|
init_errors();
|
|
@@ -81,10 +81,10 @@ var init_api_response = __esm(() => {
|
|
|
81
81
|
CLIENT_SAFE_CODES = new Set([ErrorCode.NotFound, ErrorCode.Validation, ErrorCode.Conflict]);
|
|
82
82
|
});
|
|
83
83
|
|
|
84
|
-
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.
|
|
84
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.14/node_modules/@gobing-ai/ts-utils/dist/cursor.js
|
|
85
85
|
var init_cursor = () => {};
|
|
86
86
|
|
|
87
|
-
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.
|
|
87
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.14/node_modules/@gobing-ai/ts-utils/dist/object.js
|
|
88
88
|
function isPlainObject(value) {
|
|
89
89
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
90
90
|
}
|
|
@@ -100,7 +100,7 @@ function deepMerge(target, source) {
|
|
|
100
100
|
return result;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.
|
|
103
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.14/node_modules/@gobing-ai/ts-utils/dist/output.js
|
|
104
104
|
function processStream(name) {
|
|
105
105
|
const proc = globalThis.process;
|
|
106
106
|
const stream = proc?.[name];
|
|
@@ -121,7 +121,7 @@ function echoError(message, target = defaultStderrTarget ?? processStream("stder
|
|
|
121
121
|
}
|
|
122
122
|
var defaultStdoutTarget, defaultStderrTarget;
|
|
123
123
|
|
|
124
|
-
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.
|
|
124
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.14/node_modules/@gobing-ai/ts-utils/dist/index.js
|
|
125
125
|
var init_dist = __esm(() => {
|
|
126
126
|
init_api_response();
|
|
127
127
|
init_cursor();
|
|
@@ -21743,7 +21743,7 @@ var init_zod = __esm(() => {
|
|
|
21743
21743
|
init_external();
|
|
21744
21744
|
});
|
|
21745
21745
|
|
|
21746
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
21746
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+c51d44ed7d8b072c/node_modules/@gobing-ai/ts-runtime/dist/config.js
|
|
21747
21747
|
function getProcessEnv() {
|
|
21748
21748
|
return process.env;
|
|
21749
21749
|
}
|
|
@@ -21821,7 +21821,7 @@ var init_config = __esm(() => {
|
|
|
21821
21821
|
};
|
|
21822
21822
|
});
|
|
21823
21823
|
|
|
21824
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
21824
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+c51d44ed7d8b072c/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
|
|
21825
21825
|
import { appendFileSync, cpSync, createReadStream, createWriteStream, existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "fs";
|
|
21826
21826
|
import { dirname, resolve as resolvePath } from "path";
|
|
21827
21827
|
function createNodeFileSystem(root) {
|
|
@@ -21908,7 +21908,7 @@ function findProjectRoot(startDir) {
|
|
|
21908
21908
|
}
|
|
21909
21909
|
var init_file_system_node = () => {};
|
|
21910
21910
|
|
|
21911
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
21911
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+c51d44ed7d8b072c/node_modules/@gobing-ai/ts-runtime/dist/db-errors.js
|
|
21912
21912
|
var DbModuleNotInstalledError;
|
|
21913
21913
|
var init_db_errors = __esm(() => {
|
|
21914
21914
|
DbModuleNotInstalledError = class DbModuleNotInstalledError extends Error {
|
|
@@ -29099,7 +29099,7 @@ var init_execa = __esm(() => {
|
|
|
29099
29099
|
} = getIpcExport());
|
|
29100
29100
|
});
|
|
29101
29101
|
|
|
29102
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29102
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+c51d44ed7d8b072c/node_modules/@gobing-ai/ts-runtime/dist/process-executor.js
|
|
29103
29103
|
import { isatty } from "tty";
|
|
29104
29104
|
|
|
29105
29105
|
class NodeProcessExecutor {
|
|
@@ -29141,7 +29141,11 @@ class NodeProcessExecutor {
|
|
|
29141
29141
|
...options.label !== undefined ? { label: options.label } : {}
|
|
29142
29142
|
});
|
|
29143
29143
|
try {
|
|
29144
|
-
const
|
|
29144
|
+
const subprocess = execa(options.command, args, execaOptions);
|
|
29145
|
+
const stopGroupCancellation = observeProcessGroupCancellation(subprocess, options.signal);
|
|
29146
|
+
observeOutput(subprocess.stdout, "stdout", options.onOutput);
|
|
29147
|
+
observeOutput(subprocess.stderr, "stderr", options.onOutput);
|
|
29148
|
+
const result = await subprocess.finally(stopGroupCancellation);
|
|
29145
29149
|
const processResult = {
|
|
29146
29150
|
command: options.command,
|
|
29147
29151
|
args,
|
|
@@ -29367,9 +29371,42 @@ function buildExecaOptions(opts) {
|
|
|
29367
29371
|
...opts.env !== undefined ? { env: opts.env } : {},
|
|
29368
29372
|
...opts.timeout !== undefined ? { timeout: opts.timeout } : {},
|
|
29369
29373
|
...opts.maxOutput !== undefined ? { maxBuffer: opts.maxOutput } : {},
|
|
29370
|
-
...opts.signal !== undefined ? {
|
|
29374
|
+
...opts.signal !== undefined ? {
|
|
29375
|
+
cancelSignal: opts.signal,
|
|
29376
|
+
...process.platform !== "win32" ? { detached: true } : {}
|
|
29377
|
+
} : {}
|
|
29371
29378
|
};
|
|
29372
29379
|
}
|
|
29380
|
+
function observeProcessGroupCancellation(subprocess, signal) {
|
|
29381
|
+
const pid = subprocess.pid;
|
|
29382
|
+
if (signal === undefined || process.platform === "win32" || pid === undefined)
|
|
29383
|
+
return () => {};
|
|
29384
|
+
const abort = () => {
|
|
29385
|
+
try {
|
|
29386
|
+
process.kill(-pid, "SIGTERM");
|
|
29387
|
+
} catch {
|
|
29388
|
+
subprocess.kill("SIGTERM");
|
|
29389
|
+
}
|
|
29390
|
+
};
|
|
29391
|
+
if (signal.aborted)
|
|
29392
|
+
abort();
|
|
29393
|
+
else
|
|
29394
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
29395
|
+
return () => signal.removeEventListener("abort", abort);
|
|
29396
|
+
}
|
|
29397
|
+
function observeOutput(stream, name, observer) {
|
|
29398
|
+
if (!stream || !observer)
|
|
29399
|
+
return;
|
|
29400
|
+
stream.on("data", (chunk) => {
|
|
29401
|
+
try {
|
|
29402
|
+
observer({
|
|
29403
|
+
stream: name,
|
|
29404
|
+
chunk: asString(chunk),
|
|
29405
|
+
timestamp: new Date().toISOString()
|
|
29406
|
+
});
|
|
29407
|
+
} catch {}
|
|
29408
|
+
});
|
|
29409
|
+
}
|
|
29373
29410
|
function asString(value) {
|
|
29374
29411
|
if (typeof value === "string")
|
|
29375
29412
|
return value;
|
|
@@ -29392,7 +29429,7 @@ var init_process_executor = __esm(() => {
|
|
|
29392
29429
|
init_execa();
|
|
29393
29430
|
});
|
|
29394
29431
|
|
|
29395
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29432
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+c51d44ed7d8b072c/node_modules/@gobing-ai/ts-runtime/dist/runtime-node-bun.js
|
|
29396
29433
|
function getNodeFileSystem() {
|
|
29397
29434
|
if (!_nodeFileSystem)
|
|
29398
29435
|
_nodeFileSystem = createNodeFileSystem();
|
|
@@ -29452,7 +29489,7 @@ var init_runtime_node_bun = __esm(() => {
|
|
|
29452
29489
|
};
|
|
29453
29490
|
});
|
|
29454
29491
|
|
|
29455
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29492
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+c51d44ed7d8b072c/node_modules/@gobing-ai/ts-runtime/dist/context.js
|
|
29456
29493
|
class RuntimeContext {
|
|
29457
29494
|
scope;
|
|
29458
29495
|
runtimeName;
|
|
@@ -29522,7 +29559,7 @@ var init_context = __esm(() => {
|
|
|
29522
29559
|
init_runtime_node_bun();
|
|
29523
29560
|
});
|
|
29524
29561
|
|
|
29525
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29562
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+c51d44ed7d8b072c/node_modules/@gobing-ai/ts-runtime/dist/path.js
|
|
29526
29563
|
function normalizeSeparators(path6) {
|
|
29527
29564
|
return path6.replaceAll("\\", "/");
|
|
29528
29565
|
}
|
|
@@ -29583,17 +29620,17 @@ var init_path = __esm(() => {
|
|
|
29583
29620
|
SEP = globalThis.process?.platform === "win32" ? "\\" : "/";
|
|
29584
29621
|
});
|
|
29585
29622
|
|
|
29586
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29623
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+c51d44ed7d8b072c/node_modules/@gobing-ai/ts-runtime/dist/schema-validation.js
|
|
29587
29624
|
var REMOTE_SCHEMA_MAX_BYTES;
|
|
29588
29625
|
var init_schema_validation = __esm(() => {
|
|
29589
29626
|
init_dist2();
|
|
29590
29627
|
REMOTE_SCHEMA_MAX_BYTES = 5 * 1024 * 1024;
|
|
29591
29628
|
});
|
|
29592
29629
|
|
|
29593
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29630
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+c51d44ed7d8b072c/node_modules/@gobing-ai/ts-runtime/dist/types.js
|
|
29594
29631
|
var init_types = () => {};
|
|
29595
29632
|
|
|
29596
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29633
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+c51d44ed7d8b072c/node_modules/@gobing-ai/ts-runtime/dist/index.js
|
|
29597
29634
|
var init_dist3 = __esm(() => {
|
|
29598
29635
|
init_config();
|
|
29599
29636
|
init_context();
|
|
@@ -29602,7 +29639,7 @@ var init_dist3 = __esm(() => {
|
|
|
29602
29639
|
init_types();
|
|
29603
29640
|
});
|
|
29604
29641
|
|
|
29605
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29642
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+c51d44ed7d8b072c/node_modules/@gobing-ai/ts-runtime/dist/bun-sqlite.js
|
|
29606
29643
|
import { Database } from "bun:sqlite";
|
|
29607
29644
|
var init_bun_sqlite = () => {};
|
|
29608
29645
|
|
|
@@ -33794,7 +33831,7 @@ var init_bun_sqlite2 = __esm(() => {
|
|
|
33794
33831
|
init_session2();
|
|
33795
33832
|
});
|
|
33796
33833
|
|
|
33797
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
33834
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/schema/inbox-messages.js
|
|
33798
33835
|
var inboxMessages;
|
|
33799
33836
|
var init_inbox_messages = __esm(() => {
|
|
33800
33837
|
init_sqlite_core();
|
|
@@ -33813,7 +33850,7 @@ var init_inbox_messages = __esm(() => {
|
|
|
33813
33850
|
}, (table2) => [index("idx_inbox_messages_to_status").on(table2.toId, table2.status)]);
|
|
33814
33851
|
});
|
|
33815
33852
|
|
|
33816
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
33853
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/schema/common.js
|
|
33817
33854
|
function nowTimestamp() {
|
|
33818
33855
|
return Date.now();
|
|
33819
33856
|
}
|
|
@@ -33842,7 +33879,7 @@ var init_common3 = __esm(() => {
|
|
|
33842
33879
|
appendOnlyColumns = buildAppendOnlyColumns();
|
|
33843
33880
|
});
|
|
33844
33881
|
|
|
33845
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
33882
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/schema/queue-jobs.js
|
|
33846
33883
|
var queueJobs;
|
|
33847
33884
|
var init_queue_jobs = __esm(() => {
|
|
33848
33885
|
init_sqlite_core();
|
|
@@ -33862,7 +33899,7 @@ var init_queue_jobs = __esm(() => {
|
|
|
33862
33899
|
}, (table2) => [index("queue_jobs_ready_idx").on(table2.status, table2.nextRetryAt, table2.createdAt)]);
|
|
33863
33900
|
});
|
|
33864
33901
|
|
|
33865
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
33902
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/schema/runtime.js
|
|
33866
33903
|
var exports_runtime = {};
|
|
33867
33904
|
__export(exports_runtime, {
|
|
33868
33905
|
queueJobs: () => queueJobs,
|
|
@@ -33873,7 +33910,7 @@ var init_runtime = __esm(() => {
|
|
|
33873
33910
|
init_queue_jobs();
|
|
33874
33911
|
});
|
|
33875
33912
|
|
|
33876
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
33913
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/adapters/bun-sqlite.js
|
|
33877
33914
|
var exports_bun_sqlite = {};
|
|
33878
33915
|
__export(exports_bun_sqlite, {
|
|
33879
33916
|
BunSqliteAdapter: () => BunSqliteAdapter
|
|
@@ -34162,7 +34199,7 @@ var init_d1 = __esm(() => {
|
|
|
34162
34199
|
init_session3();
|
|
34163
34200
|
});
|
|
34164
34201
|
|
|
34165
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34202
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/adapters/d1.js
|
|
34166
34203
|
var exports_d1 = {};
|
|
34167
34204
|
__export(exports_d1, {
|
|
34168
34205
|
D1Adapter: () => D1Adapter
|
|
@@ -34226,7 +34263,7 @@ var init_d12 = __esm(() => {
|
|
|
34226
34263
|
init_runtime();
|
|
34227
34264
|
});
|
|
34228
34265
|
|
|
34229
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34266
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/adapter.js
|
|
34230
34267
|
async function createDbAdapter(config3) {
|
|
34231
34268
|
switch (config3.driver) {
|
|
34232
34269
|
case "bun-sqlite": {
|
|
@@ -34266,7 +34303,7 @@ var init_drizzle_orm = __esm(() => {
|
|
|
34266
34303
|
init_view_common();
|
|
34267
34304
|
});
|
|
34268
34305
|
|
|
34269
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34306
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/query-spec.js
|
|
34270
34307
|
function compilePredicate(predicate) {
|
|
34271
34308
|
if ("and" in predicate) {
|
|
34272
34309
|
const parts = predicate.and.map(compilePredicate).filter((p) => p !== undefined);
|
|
@@ -34304,7 +34341,7 @@ var init_query_spec = __esm(() => {
|
|
|
34304
34341
|
};
|
|
34305
34342
|
});
|
|
34306
34343
|
|
|
34307
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34344
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/base-dao.js
|
|
34308
34345
|
function asSelectQuery(query) {
|
|
34309
34346
|
return query;
|
|
34310
34347
|
}
|
|
@@ -34346,7 +34383,7 @@ var init_base_dao = __esm(() => {
|
|
|
34346
34383
|
init_query_spec();
|
|
34347
34384
|
});
|
|
34348
34385
|
|
|
34349
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34386
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/embedded-migrations.js
|
|
34350
34387
|
var embeddedMigrations;
|
|
34351
34388
|
var init_embedded_migrations = __esm(() => {
|
|
34352
34389
|
embeddedMigrations = [
|
|
@@ -34378,7 +34415,7 @@ var init_embedded_migrations = __esm(() => {
|
|
|
34378
34415
|
];
|
|
34379
34416
|
});
|
|
34380
34417
|
|
|
34381
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34418
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/entity-dao.js
|
|
34382
34419
|
var EntityDao;
|
|
34383
34420
|
var init_entity_dao = __esm(() => {
|
|
34384
34421
|
init_drizzle_orm();
|
|
@@ -34540,7 +34577,7 @@ var init_entity_dao = __esm(() => {
|
|
|
34540
34577
|
};
|
|
34541
34578
|
});
|
|
34542
34579
|
|
|
34543
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34580
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/inbox-message-dao.js
|
|
34544
34581
|
function isPromiseLike(value) {
|
|
34545
34582
|
return value !== null && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
|
|
34546
34583
|
}
|
|
@@ -34713,7 +34750,7 @@ var init_migrator2 = __esm(() => {
|
|
|
34713
34750
|
init_migrator();
|
|
34714
34751
|
});
|
|
34715
34752
|
|
|
34716
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34753
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/migrate.js
|
|
34717
34754
|
async function ensureJournalTable(adapter, table3) {
|
|
34718
34755
|
await adapter.exec(`CREATE TABLE IF NOT EXISTS "${table3}" (` + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "hash text NOT NULL, " + "created_at numeric" + ")");
|
|
34719
34756
|
}
|
|
@@ -34788,7 +34825,7 @@ var init_migrate = __esm(() => {
|
|
|
34788
34825
|
init_embedded_migrations();
|
|
34789
34826
|
});
|
|
34790
34827
|
|
|
34791
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34828
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/queue-job-dao.js
|
|
34792
34829
|
var QueueJobDao;
|
|
34793
34830
|
var init_queue_job_dao = __esm(() => {
|
|
34794
34831
|
init_drizzle_orm();
|
|
@@ -34929,7 +34966,7 @@ var init_queue_job_dao = __esm(() => {
|
|
|
34929
34966
|
};
|
|
34930
34967
|
});
|
|
34931
34968
|
|
|
34932
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34969
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/index.js
|
|
34933
34970
|
var exports_dist = {};
|
|
34934
34971
|
__export(exports_dist, {
|
|
34935
34972
|
embeddedMigrations: () => embeddedMigrations,
|
|
@@ -37077,6 +37114,8 @@ var init_finding_codes = __esm(() => {
|
|
|
37077
37114
|
"L2.forbidden-section",
|
|
37078
37115
|
"L2.disallowed-section",
|
|
37079
37116
|
"L3.requirements-format",
|
|
37117
|
+
"L3.requirements-empty",
|
|
37118
|
+
"L3.ac-empty",
|
|
37080
37119
|
"L3.solution-file-line",
|
|
37081
37120
|
"L3.review-priority-table",
|
|
37082
37121
|
"L3.testing-coverage",
|
|
@@ -37108,7 +37147,9 @@ var init_finding_codes = __esm(() => {
|
|
|
37108
37147
|
"L4.uncovered-task-scenario",
|
|
37109
37148
|
"L4.uncovered-feature-scenario",
|
|
37110
37149
|
"L4.verifying-incomplete-tasks",
|
|
37111
|
-
"L4.dogfood-missing"
|
|
37150
|
+
"L4.dogfood-missing",
|
|
37151
|
+
"L4.scenario-unverified",
|
|
37152
|
+
"L4.stale-line-anchor"
|
|
37112
37153
|
];
|
|
37113
37154
|
FINDING_CODES = {
|
|
37114
37155
|
L1_MARKDOWN_PARSE: "L1.markdown-parse",
|
|
@@ -37117,6 +37158,8 @@ var init_finding_codes = __esm(() => {
|
|
|
37117
37158
|
L2_FORBIDDEN_SECTION: "L2.forbidden-section",
|
|
37118
37159
|
L2_DISALLOWED_SECTION: "L2.disallowed-section",
|
|
37119
37160
|
L3_REQUIREMENTS_FORMAT: "L3.requirements-format",
|
|
37161
|
+
L3_REQUIREMENTS_EMPTY: "L3.requirements-empty",
|
|
37162
|
+
L3_AC_EMPTY: "L3.ac-empty",
|
|
37120
37163
|
L3_SOLUTION_FILE_LINE: "L3.solution-file-line",
|
|
37121
37164
|
L3_REVIEW_PRIORITY_TABLE: "L3.review-priority-table",
|
|
37122
37165
|
L3_TESTING_COVERAGE: "L3.testing-coverage",
|
|
@@ -37148,7 +37191,9 @@ var init_finding_codes = __esm(() => {
|
|
|
37148
37191
|
L4_UNCOVERED_TASK_SCENARIO: "L4.uncovered-task-scenario",
|
|
37149
37192
|
L4_UNCOVERED_FEATURE_SCENARIO: "L4.uncovered-feature-scenario",
|
|
37150
37193
|
L4_VERIFYING_INCOMPLETE_TASKS: "L4.verifying-incomplete-tasks",
|
|
37151
|
-
L4_DOGFOOD_MISSING: "L4.dogfood-missing"
|
|
37194
|
+
L4_DOGFOOD_MISSING: "L4.dogfood-missing",
|
|
37195
|
+
L4_SCENARIO_UNVERIFIED: "L4.scenario-unverified",
|
|
37196
|
+
L4_STALE_LINE_ANCHOR: "L4.stale-line-anchor"
|
|
37152
37197
|
};
|
|
37153
37198
|
});
|
|
37154
37199
|
|
|
@@ -37156,6 +37201,9 @@ var init_finding_codes = __esm(() => {
|
|
|
37156
37201
|
function folderPathWithDefault(defaultPath) {
|
|
37157
37202
|
return exports_external.preprocess((v) => v == null ? undefined : v, exports_external.string().default(defaultPath));
|
|
37158
37203
|
}
|
|
37204
|
+
function normalizeExecutorTier(value) {
|
|
37205
|
+
return value === "capable" ? "capable-1" : value;
|
|
37206
|
+
}
|
|
37159
37207
|
function normalizeMember(member) {
|
|
37160
37208
|
return typeof member === "string" ? { executor: member } : { ...member };
|
|
37161
37209
|
}
|
|
@@ -37196,7 +37244,7 @@ function buildConfigFromEnv(env = process.env) {
|
|
|
37196
37244
|
}
|
|
37197
37245
|
});
|
|
37198
37246
|
}
|
|
37199
|
-
var SPUR_ENV_VARS, SPUR_LOG_LEVELS, DEFAULT_TASKS_DIR = "docs/tasks", DEFAULT_FEATURES_DIR = "docs/features", DEFAULT_DATABASE_URL = ".spur/spur.db", IN_MEMORY_DATABASE_URL = ":memory:", folderConfigSchema, tasksConfigSchema, featuresConfigSchema, AgentExecutorConfigSchema, AGENT_ID_REGEX, TeamMemberConfigSchema, TeamConfigSchema, AgentConfigSchema, RulesConfigSchema, WorkflowsConfigSchema, RedactionConfigSchema, spurConfigSchema, configSchema2;
|
|
37247
|
+
var SPUR_ENV_VARS, SPUR_LOG_LEVELS, DEFAULT_TASKS_DIR = "docs/tasks", DEFAULT_FEATURES_DIR = "docs/features", DEFAULT_DATABASE_URL = ".spur/spur.db", IN_MEMORY_DATABASE_URL = ":memory:", folderConfigSchema, tasksConfigSchema, featuresConfigSchema, EXECUTOR_CAPABILITY_TIERS, executorCapabilityTierSchema, AgentExecutorConfigSchema, AGENT_ID_REGEX, TeamMemberConfigSchema, TeamConfigSchema, AgentConfigSchema, RulesConfigSchema, WorkflowsConfigSchema, RedactionConfigSchema, spurConfigSchema, configSchema2;
|
|
37200
37248
|
var init_src = __esm(() => {
|
|
37201
37249
|
init_zod();
|
|
37202
37250
|
init_finding_codes();
|
|
@@ -37232,11 +37280,17 @@ var init_src = __esm(() => {
|
|
|
37232
37280
|
featuresConfigSchema = exports_external.object({
|
|
37233
37281
|
dir: folderPathWithDefault(DEFAULT_FEATURES_DIR)
|
|
37234
37282
|
});
|
|
37283
|
+
EXECUTOR_CAPABILITY_TIERS = ["cheap", "standard", "capable-1", "capable-2", "capable-3"];
|
|
37284
|
+
executorCapabilityTierSchema = exports_external.preprocess((value) => {
|
|
37285
|
+
if (value === undefined || value === null)
|
|
37286
|
+
return;
|
|
37287
|
+
return normalizeExecutorTier(value);
|
|
37288
|
+
}, exports_external.enum(EXECUTOR_CAPABILITY_TIERS).optional());
|
|
37235
37289
|
AgentExecutorConfigSchema = exports_external.object({
|
|
37236
37290
|
name: exports_external.string().min(1),
|
|
37237
37291
|
agent: exports_external.string().min(1),
|
|
37238
37292
|
model: exports_external.string().min(1).optional(),
|
|
37239
|
-
tier:
|
|
37293
|
+
tier: executorCapabilityTierSchema.optional()
|
|
37240
37294
|
});
|
|
37241
37295
|
AGENT_ID_REGEX = /^[a-z][a-z0-9_-]{1,63}$/;
|
|
37242
37296
|
TeamMemberConfigSchema = exports_external.union([
|
|
@@ -37354,7 +37408,7 @@ var init_src = __esm(() => {
|
|
|
37354
37408
|
});
|
|
37355
37409
|
});
|
|
37356
37410
|
|
|
37357
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37411
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/config.js
|
|
37358
37412
|
function parseYamlObject(text3) {
|
|
37359
37413
|
let parsed;
|
|
37360
37414
|
try {
|
|
@@ -37481,7 +37535,7 @@ var init_config2 = __esm(() => {
|
|
|
37481
37535
|
};
|
|
37482
37536
|
});
|
|
37483
37537
|
|
|
37484
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37538
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
|
|
37485
37539
|
import { appendFileSync as appendFileSync3, cpSync as cpSync2, createReadStream as createReadStream3, createWriteStream as createWriteStream3, existsSync as existsSync2, mkdirSync as mkdirSync2, readdirSync as readdirSync2, readFileSync as readFileSync4, realpathSync as realpathSync2, renameSync as renameSync2, rmSync as rmSync2, statSync as statSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
37486
37540
|
import { dirname as dirname2, resolve as resolvePath3 } from "path";
|
|
37487
37541
|
function createNodeFileSystem3(root) {
|
|
@@ -37568,7 +37622,7 @@ function findProjectRoot3(startDir) {
|
|
|
37568
37622
|
}
|
|
37569
37623
|
var init_file_system_node2 = () => {};
|
|
37570
37624
|
|
|
37571
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37625
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/db-errors.js
|
|
37572
37626
|
var D1NotConfiguredError2, DbModuleNotInstalledError3;
|
|
37573
37627
|
var init_db_errors2 = __esm(() => {
|
|
37574
37628
|
D1NotConfiguredError2 = class D1NotConfiguredError2 extends Error {
|
|
@@ -37585,7 +37639,7 @@ var init_db_errors2 = __esm(() => {
|
|
|
37585
37639
|
};
|
|
37586
37640
|
});
|
|
37587
37641
|
|
|
37588
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37642
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/file-system-cf.js
|
|
37589
37643
|
function createCfFileSystem2() {
|
|
37590
37644
|
return {
|
|
37591
37645
|
getProjectRoot: () => "/bundle",
|
|
@@ -37624,7 +37678,7 @@ function createCfFileSystem2() {
|
|
|
37624
37678
|
}
|
|
37625
37679
|
var UNSUPPORTED = "FileSystem is not available on Cloudflare Workers. Use D1, KV, or R2 for persistent storage.";
|
|
37626
37680
|
|
|
37627
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37681
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/runtime-cf.js
|
|
37628
37682
|
var exports_runtime_cf = {};
|
|
37629
37683
|
__export(exports_runtime_cf, {
|
|
37630
37684
|
cloudflareWorkersFactory: () => cloudflareWorkersFactory2
|
|
@@ -37662,7 +37716,7 @@ var init_runtime_cf = __esm(() => {
|
|
|
37662
37716
|
};
|
|
37663
37717
|
});
|
|
37664
37718
|
|
|
37665
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37719
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/process-executor.js
|
|
37666
37720
|
import { isatty as isatty2 } from "tty";
|
|
37667
37721
|
|
|
37668
37722
|
class NodeProcessExecutor3 {
|
|
@@ -37704,7 +37758,11 @@ class NodeProcessExecutor3 {
|
|
|
37704
37758
|
...options.label !== undefined ? { label: options.label } : {}
|
|
37705
37759
|
});
|
|
37706
37760
|
try {
|
|
37707
|
-
const
|
|
37761
|
+
const subprocess = execa(options.command, args, execaOptions);
|
|
37762
|
+
const stopGroupCancellation = observeProcessGroupCancellation2(subprocess, options.signal);
|
|
37763
|
+
observeOutput2(subprocess.stdout, "stdout", options.onOutput);
|
|
37764
|
+
observeOutput2(subprocess.stderr, "stderr", options.onOutput);
|
|
37765
|
+
const result = await subprocess.finally(stopGroupCancellation);
|
|
37708
37766
|
const processResult = {
|
|
37709
37767
|
command: options.command,
|
|
37710
37768
|
args,
|
|
@@ -37970,9 +38028,42 @@ function buildExecaOptions2(opts) {
|
|
|
37970
38028
|
...opts.env !== undefined ? { env: opts.env } : {},
|
|
37971
38029
|
...opts.timeout !== undefined ? { timeout: opts.timeout } : {},
|
|
37972
38030
|
...opts.maxOutput !== undefined ? { maxBuffer: opts.maxOutput } : {},
|
|
37973
|
-
...opts.signal !== undefined ? {
|
|
38031
|
+
...opts.signal !== undefined ? {
|
|
38032
|
+
cancelSignal: opts.signal,
|
|
38033
|
+
...process.platform !== "win32" ? { detached: true } : {}
|
|
38034
|
+
} : {}
|
|
37974
38035
|
};
|
|
37975
38036
|
}
|
|
38037
|
+
function observeProcessGroupCancellation2(subprocess, signal) {
|
|
38038
|
+
const pid = subprocess.pid;
|
|
38039
|
+
if (signal === undefined || process.platform === "win32" || pid === undefined)
|
|
38040
|
+
return () => {};
|
|
38041
|
+
const abort = () => {
|
|
38042
|
+
try {
|
|
38043
|
+
process.kill(-pid, "SIGTERM");
|
|
38044
|
+
} catch {
|
|
38045
|
+
subprocess.kill("SIGTERM");
|
|
38046
|
+
}
|
|
38047
|
+
};
|
|
38048
|
+
if (signal.aborted)
|
|
38049
|
+
abort();
|
|
38050
|
+
else
|
|
38051
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
38052
|
+
return () => signal.removeEventListener("abort", abort);
|
|
38053
|
+
}
|
|
38054
|
+
function observeOutput2(stream, name, observer) {
|
|
38055
|
+
if (!stream || !observer)
|
|
38056
|
+
return;
|
|
38057
|
+
stream.on("data", (chunk) => {
|
|
38058
|
+
try {
|
|
38059
|
+
observer({
|
|
38060
|
+
stream: name,
|
|
38061
|
+
chunk: asString2(chunk),
|
|
38062
|
+
timestamp: new Date().toISOString()
|
|
38063
|
+
});
|
|
38064
|
+
} catch {}
|
|
38065
|
+
});
|
|
38066
|
+
}
|
|
37976
38067
|
function asString2(value) {
|
|
37977
38068
|
if (typeof value === "string")
|
|
37978
38069
|
return value;
|
|
@@ -38002,7 +38093,7 @@ var init_process_executor2 = __esm(() => {
|
|
|
38002
38093
|
ProcessExecutor2 = NodeProcessExecutor3;
|
|
38003
38094
|
});
|
|
38004
38095
|
|
|
38005
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38096
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/runtime-node-bun.js
|
|
38006
38097
|
var exports_runtime_node_bun = {};
|
|
38007
38098
|
__export(exports_runtime_node_bun, {
|
|
38008
38099
|
nodeBunFactory: () => nodeBunFactory3,
|
|
@@ -38070,7 +38161,7 @@ var init_runtime_node_bun2 = __esm(() => {
|
|
|
38070
38161
|
};
|
|
38071
38162
|
});
|
|
38072
38163
|
|
|
38073
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38164
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/platform.js
|
|
38074
38165
|
function isCloudflareWorkerRuntime2() {
|
|
38075
38166
|
return globalThis.navigator?.userAgent?.startsWith("Cloudflare-Workers") ?? false;
|
|
38076
38167
|
}
|
|
@@ -38100,7 +38191,7 @@ function _resetRuntimeFactory2() {
|
|
|
38100
38191
|
}
|
|
38101
38192
|
var _factory, _runtimeName;
|
|
38102
38193
|
|
|
38103
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38194
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/context.js
|
|
38104
38195
|
class RuntimeContext2 {
|
|
38105
38196
|
scope;
|
|
38106
38197
|
runtimeName;
|
|
@@ -38190,7 +38281,7 @@ var init_context2 = __esm(() => {
|
|
|
38190
38281
|
init_runtime_node_bun2();
|
|
38191
38282
|
});
|
|
38192
38283
|
|
|
38193
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38284
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/path.js
|
|
38194
38285
|
function normalizeSeparators2(path7) {
|
|
38195
38286
|
return path7.replaceAll("\\", "/");
|
|
38196
38287
|
}
|
|
@@ -38313,7 +38404,7 @@ var init_path2 = __esm(() => {
|
|
|
38313
38404
|
SEP2 = globalThis.process?.platform === "win32" ? "\\" : "/";
|
|
38314
38405
|
});
|
|
38315
38406
|
|
|
38316
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38407
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/fs.js
|
|
38317
38408
|
async function ensureDirForFile2(path7, fs2 = createNodeFileSystem3()) {
|
|
38318
38409
|
await fs2.ensureDir(dirnamePath(path7));
|
|
38319
38410
|
}
|
|
@@ -38364,7 +38455,7 @@ var init_fs = __esm(() => {
|
|
|
38364
38455
|
init_path2();
|
|
38365
38456
|
});
|
|
38366
38457
|
|
|
38367
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38458
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/process-registry.js
|
|
38368
38459
|
function allocateId() {
|
|
38369
38460
|
nextIdSeq += 1;
|
|
38370
38461
|
return `pe_${Date.now().toString(36)}_${nextIdSeq.toString(36)}`;
|
|
@@ -38488,7 +38579,7 @@ function createInMemoryProcessRegistry2(options) {
|
|
|
38488
38579
|
}
|
|
38489
38580
|
var nextIdSeq = 0;
|
|
38490
38581
|
|
|
38491
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38582
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/schema-validation.js
|
|
38492
38583
|
async function loadStructuredConfig(path7, options = {}) {
|
|
38493
38584
|
const content = await (options.fileSystem ?? createNodeFileSystem3()).readFile(path7);
|
|
38494
38585
|
return await parseStructuredConfig(content, path7, options);
|
|
@@ -38765,10 +38856,10 @@ var init_schema_validation2 = __esm(() => {
|
|
|
38765
38856
|
defaultResolve = typeof Bun !== "undefined" ? (specifier, from) => Bun.resolveSync(specifier, from) : undefined;
|
|
38766
38857
|
});
|
|
38767
38858
|
|
|
38768
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38859
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/types.js
|
|
38769
38860
|
var init_types2 = () => {};
|
|
38770
38861
|
|
|
38771
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38862
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/index.js
|
|
38772
38863
|
var exports_dist2 = {};
|
|
38773
38864
|
__export(exports_dist2, {
|
|
38774
38865
|
writeJsonFile: () => writeJsonFile2,
|
|
@@ -40917,7 +41008,7 @@ var init_mod = __esm(() => {
|
|
|
40917
41008
|
init_config3();
|
|
40918
41009
|
});
|
|
40919
41010
|
|
|
40920
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
41011
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/logger.js
|
|
40921
41012
|
function toLogTapeLevel(level) {
|
|
40922
41013
|
return level === "warn" ? "warning" : level;
|
|
40923
41014
|
}
|
|
@@ -42470,7 +42561,7 @@ var require_src = __commonJS((exports) => {
|
|
|
42470
42561
|
};
|
|
42471
42562
|
});
|
|
42472
42563
|
|
|
42473
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
42564
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/telemetry/sdk.js
|
|
42474
42565
|
function getTelemetryConfig(configPartial = {}) {
|
|
42475
42566
|
return {
|
|
42476
42567
|
enabled: configPartial.enabled ?? CONFIG_DEFAULTS.enabled,
|
|
@@ -42506,7 +42597,7 @@ var init_sdk = __esm(() => {
|
|
|
42506
42597
|
resolvedConfig = getTelemetryConfig();
|
|
42507
42598
|
});
|
|
42508
42599
|
|
|
42509
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
42600
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/telemetry/tracing.js
|
|
42510
42601
|
function isSuppressed(tracer2) {
|
|
42511
42602
|
return tracer2 === undefined && !getResolvedConfig().enabled;
|
|
42512
42603
|
}
|
|
@@ -42546,7 +42637,7 @@ var init_tracing2 = __esm(() => {
|
|
|
42546
42637
|
import_api2 = __toESM(require_src(), 1);
|
|
42547
42638
|
});
|
|
42548
42639
|
|
|
42549
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
42640
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/telemetry/metrics.js
|
|
42550
42641
|
function getMeter() {
|
|
42551
42642
|
return import_api3.metrics.getMeter(METER_NAME, METER_VERSION);
|
|
42552
42643
|
}
|
|
@@ -42643,7 +42734,7 @@ var init_metrics = __esm(() => {
|
|
|
42643
42734
|
instruments = {};
|
|
42644
42735
|
});
|
|
42645
42736
|
|
|
42646
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
42737
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/event-bus/event-bus.js
|
|
42647
42738
|
function busLogger() {
|
|
42648
42739
|
if (!_busLogger)
|
|
42649
42740
|
_busLogger = getLogger2("event-bus");
|
|
@@ -42888,7 +42979,7 @@ var init_event_bus = __esm(() => {
|
|
|
42888
42979
|
init_metrics();
|
|
42889
42980
|
});
|
|
42890
42981
|
|
|
42891
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
42982
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/event-bus/default-observers.js
|
|
42892
42983
|
function obsLogger() {
|
|
42893
42984
|
if (!_obsLogger)
|
|
42894
42985
|
_obsLogger = getLogger2("event-bus.observers");
|
|
@@ -42952,7 +43043,7 @@ var init_default_observers = __esm(() => {
|
|
|
42952
43043
|
init_event_bus();
|
|
42953
43044
|
});
|
|
42954
43045
|
|
|
42955
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
43046
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/event-bus/file-observer.js
|
|
42956
43047
|
function parentDir(filePath) {
|
|
42957
43048
|
const idx = filePath.lastIndexOf("/");
|
|
42958
43049
|
return idx <= 0 ? "." : filePath.slice(0, idx);
|
|
@@ -43050,7 +43141,7 @@ var init_file_observer = __esm(() => {
|
|
|
43050
43141
|
init_logger3();
|
|
43051
43142
|
});
|
|
43052
43143
|
|
|
43053
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
43144
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/scheduler/node.js
|
|
43054
43145
|
function parseInterval(cron) {
|
|
43055
43146
|
const trimmed = cron.trim();
|
|
43056
43147
|
const num = Number(trimmed);
|
|
@@ -43124,7 +43215,7 @@ var init_node3 = __esm(() => {
|
|
|
43124
43215
|
init_metrics();
|
|
43125
43216
|
});
|
|
43126
43217
|
|
|
43127
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
43218
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/scheduler-node.js
|
|
43128
43219
|
var exports_scheduler_node = {};
|
|
43129
43220
|
__export(exports_scheduler_node, {
|
|
43130
43221
|
NodeSchedulerAdapter: () => NodeSchedulerAdapter
|
|
@@ -49380,6 +49471,168 @@ var init_errors5 = __esm(() => {
|
|
|
49380
49471
|
};
|
|
49381
49472
|
});
|
|
49382
49473
|
|
|
49474
|
+
// ../../packages/app/src/observability/agent-execution.ts
|
|
49475
|
+
class AgentExecutionLifecycle {
|
|
49476
|
+
observer;
|
|
49477
|
+
secrets;
|
|
49478
|
+
heartbeatMs;
|
|
49479
|
+
sequence = 0;
|
|
49480
|
+
correlation;
|
|
49481
|
+
queue = [];
|
|
49482
|
+
draining = false;
|
|
49483
|
+
dropped = 0;
|
|
49484
|
+
heartbeat;
|
|
49485
|
+
startedAt = 0;
|
|
49486
|
+
timeoutMs;
|
|
49487
|
+
outputCarry = { stdout: "", stderr: "" };
|
|
49488
|
+
constructor(observer, correlation, secrets, heartbeatMs = 30000) {
|
|
49489
|
+
this.observer = observer;
|
|
49490
|
+
this.secrets = secrets;
|
|
49491
|
+
this.heartbeatMs = heartbeatMs;
|
|
49492
|
+
this.correlation = correlation ?? {
|
|
49493
|
+
runId: crypto.randomUUID(),
|
|
49494
|
+
executionId: crypto.randomUUID()
|
|
49495
|
+
};
|
|
49496
|
+
}
|
|
49497
|
+
get identity() {
|
|
49498
|
+
return this.correlation;
|
|
49499
|
+
}
|
|
49500
|
+
start(detail) {
|
|
49501
|
+
this.startedAt = Date.now();
|
|
49502
|
+
this.timeoutMs = detail.timeoutMs;
|
|
49503
|
+
this.emit({
|
|
49504
|
+
kind: "started",
|
|
49505
|
+
agent: redactAndBound(detail.agent, this.secrets, 256),
|
|
49506
|
+
...detail.model !== undefined ? { model: redactAndBound(detail.model, this.secrets, 256) } : {},
|
|
49507
|
+
invocation: redactAndBound(detail.invocation, this.secrets, 512),
|
|
49508
|
+
...detail.timeoutMs !== undefined ? { timeoutMs: detail.timeoutMs } : {}
|
|
49509
|
+
});
|
|
49510
|
+
if (!this.observer || this.heartbeatMs <= 0)
|
|
49511
|
+
return;
|
|
49512
|
+
this.heartbeat = setInterval(() => {
|
|
49513
|
+
this.drain();
|
|
49514
|
+
this.emit({
|
|
49515
|
+
kind: "heartbeat",
|
|
49516
|
+
elapsedMs: Math.max(0, Date.now() - this.startedAt),
|
|
49517
|
+
...this.timeoutMs !== undefined ? { timeoutMs: this.timeoutMs } : {}
|
|
49518
|
+
});
|
|
49519
|
+
}, this.heartbeatMs);
|
|
49520
|
+
this.heartbeat.unref?.();
|
|
49521
|
+
}
|
|
49522
|
+
observe(output2) {
|
|
49523
|
+
if (!this.observer)
|
|
49524
|
+
return;
|
|
49525
|
+
const combined = this.outputCarry[output2.stream] + output2.chunk;
|
|
49526
|
+
const { ready, carry } = redactStreamingValue(combined, this.secrets);
|
|
49527
|
+
this.outputCarry[output2.stream] = carry;
|
|
49528
|
+
if (ready === "")
|
|
49529
|
+
return;
|
|
49530
|
+
this.enqueueOutput(output2.stream, ready);
|
|
49531
|
+
}
|
|
49532
|
+
finish(detail) {
|
|
49533
|
+
if (this.heartbeat !== undefined)
|
|
49534
|
+
clearInterval(this.heartbeat);
|
|
49535
|
+
this.heartbeat = undefined;
|
|
49536
|
+
for (const stream of ["stdout", "stderr"]) {
|
|
49537
|
+
const carry = this.outputCarry[stream];
|
|
49538
|
+
this.outputCarry[stream] = "";
|
|
49539
|
+
if (carry !== "")
|
|
49540
|
+
this.enqueueOutput(stream, redactAndBound(carry, this.secrets, MAX_CHUNK_CHARS));
|
|
49541
|
+
}
|
|
49542
|
+
this.drain();
|
|
49543
|
+
if (this.dropped > 0) {
|
|
49544
|
+
this.emit({ kind: "dropped", chunks: this.dropped });
|
|
49545
|
+
this.dropped = 0;
|
|
49546
|
+
}
|
|
49547
|
+
const cancelled = detail.signal !== undefined || detail.reason === "cancelled";
|
|
49548
|
+
this.emit({
|
|
49549
|
+
kind: "finished",
|
|
49550
|
+
outcome: cancelled ? "cancelled" : detail.exitCode === 0 ? "done" : "failed",
|
|
49551
|
+
exitCode: detail.exitCode,
|
|
49552
|
+
durationMs: detail.durationMs,
|
|
49553
|
+
...detail.signal !== undefined ? { signal: detail.signal } : {},
|
|
49554
|
+
usage: "unavailable",
|
|
49555
|
+
...detail.reason !== undefined ? { reason: redactAndBound(detail.reason, this.secrets, 512) } : {}
|
|
49556
|
+
});
|
|
49557
|
+
}
|
|
49558
|
+
enqueueOutput(stream, chunk) {
|
|
49559
|
+
if (this.queue.length >= MAX_PENDING_CHUNKS) {
|
|
49560
|
+
this.dropped += 1;
|
|
49561
|
+
return;
|
|
49562
|
+
}
|
|
49563
|
+
this.queue.push(this.makeEvent({
|
|
49564
|
+
kind: "output",
|
|
49565
|
+
stream,
|
|
49566
|
+
chunk: redactAndBound(chunk, this.secrets, MAX_CHUNK_CHARS)
|
|
49567
|
+
}));
|
|
49568
|
+
this.scheduleDrain();
|
|
49569
|
+
}
|
|
49570
|
+
scheduleDrain() {
|
|
49571
|
+
if (this.draining)
|
|
49572
|
+
return;
|
|
49573
|
+
this.draining = true;
|
|
49574
|
+
queueMicrotask(() => this.drain());
|
|
49575
|
+
}
|
|
49576
|
+
drain() {
|
|
49577
|
+
this.draining = false;
|
|
49578
|
+
while (this.queue.length > 0) {
|
|
49579
|
+
const event = this.queue.shift();
|
|
49580
|
+
if (event !== undefined)
|
|
49581
|
+
this.deliver(event);
|
|
49582
|
+
}
|
|
49583
|
+
}
|
|
49584
|
+
emit(detail) {
|
|
49585
|
+
this.deliver(this.makeEvent(detail));
|
|
49586
|
+
}
|
|
49587
|
+
makeEvent(detail) {
|
|
49588
|
+
this.sequence += 1;
|
|
49589
|
+
return {
|
|
49590
|
+
...detail,
|
|
49591
|
+
schemaVersion: 1,
|
|
49592
|
+
eventId: crypto.randomUUID(),
|
|
49593
|
+
sequence: this.sequence,
|
|
49594
|
+
runId: this.correlation.runId,
|
|
49595
|
+
executionId: this.correlation.executionId,
|
|
49596
|
+
...this.correlation.actionId !== undefined ? { actionId: this.correlation.actionId } : {},
|
|
49597
|
+
at: new Date().toISOString()
|
|
49598
|
+
};
|
|
49599
|
+
}
|
|
49600
|
+
deliver(event) {
|
|
49601
|
+
try {
|
|
49602
|
+
this.observer?.(event);
|
|
49603
|
+
} catch {}
|
|
49604
|
+
}
|
|
49605
|
+
}
|
|
49606
|
+
function configuredSecretValues(env) {
|
|
49607
|
+
return Object.entries(env).filter(([key, value]) => /(?:secret|token|password|api[_-]?key|credential)/i.test(key) && (value?.length ?? 0) >= 4).map(([, value]) => value);
|
|
49608
|
+
}
|
|
49609
|
+
function redactAndBound(value, secrets, maxChars) {
|
|
49610
|
+
let redacted = value.replace(SECRET_PATTERN, "[REDACTED]");
|
|
49611
|
+
for (const secret of secrets) {
|
|
49612
|
+
if (secret !== "")
|
|
49613
|
+
redacted = redacted.split(secret).join("[REDACTED]");
|
|
49614
|
+
}
|
|
49615
|
+
return redacted.length <= maxChars ? redacted : `${redacted.slice(0, maxChars)}\u2026`;
|
|
49616
|
+
}
|
|
49617
|
+
function redactStreamingValue(value, secrets) {
|
|
49618
|
+
const redacted = redactAndBound(value, secrets, Number.MAX_SAFE_INTEGER);
|
|
49619
|
+
let carryLength = 0;
|
|
49620
|
+
for (const secret of secrets) {
|
|
49621
|
+
for (let length = 1;length < secret.length && length <= redacted.length; length += 1) {
|
|
49622
|
+
if (redacted.endsWith(secret.slice(0, length)))
|
|
49623
|
+
carryLength = Math.max(carryLength, length);
|
|
49624
|
+
}
|
|
49625
|
+
}
|
|
49626
|
+
return {
|
|
49627
|
+
ready: carryLength === 0 ? redacted : redacted.slice(0, -carryLength),
|
|
49628
|
+
carry: carryLength === 0 ? "" : redacted.slice(-carryLength)
|
|
49629
|
+
};
|
|
49630
|
+
}
|
|
49631
|
+
var MAX_CHUNK_CHARS = 4096, MAX_PENDING_CHUNKS = 64, SECRET_PATTERN;
|
|
49632
|
+
var init_agent_execution = __esm(() => {
|
|
49633
|
+
SECRET_PATTERN = /(?:sk-[a-z0-9_-]{8,}|(?:api[_-]?key|token|secret|password)\s*[:=]\s*\S+|bearer\s+\S+)/gi;
|
|
49634
|
+
});
|
|
49635
|
+
|
|
49383
49636
|
// ../../packages/domain/src/analytics/models.ts
|
|
49384
49637
|
function resolvePricing(model) {
|
|
49385
49638
|
if (model === undefined || model.length === 0)
|
|
@@ -50657,7 +50910,7 @@ var init_drizzle_zod = __esm(() => {
|
|
|
50657
50910
|
};
|
|
50658
50911
|
});
|
|
50659
50912
|
|
|
50660
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
50913
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/schema/drizzle-internals.js
|
|
50661
50914
|
function sqlExpressionToText(value) {
|
|
50662
50915
|
if (typeof value !== "object" || value === null || !("queryChunks" in value)) {
|
|
50663
50916
|
return;
|
|
@@ -50680,7 +50933,7 @@ function getDrizzleTableName(table3) {
|
|
|
50680
50933
|
return String(table3[nameSym]);
|
|
50681
50934
|
}
|
|
50682
50935
|
|
|
50683
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
50936
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/schema/ddl.js
|
|
50684
50937
|
function quoteIdent(name) {
|
|
50685
50938
|
return `"${name.replace(/"/g, '""')}"`;
|
|
50686
50939
|
}
|
|
@@ -50774,7 +51027,7 @@ var init_ddl = __esm(() => {
|
|
|
50774
51027
|
init_sqlite_core();
|
|
50775
51028
|
});
|
|
50776
51029
|
|
|
50777
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
51030
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/schema/define-table.js
|
|
50778
51031
|
function defineTable(name, columns2) {
|
|
50779
51032
|
const table3 = sqliteTable(name, columns2);
|
|
50780
51033
|
let insert2;
|
|
@@ -50808,7 +51061,7 @@ var init_define_table = __esm(() => {
|
|
|
50808
51061
|
init_ddl();
|
|
50809
51062
|
});
|
|
50810
51063
|
|
|
50811
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
51064
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.14+eb0d628435e6547b/node_modules/@gobing-ai/ts-db/dist/schema/index.js
|
|
50812
51065
|
var init_schema = __esm(() => {
|
|
50813
51066
|
init_sqlite_core();
|
|
50814
51067
|
init_define_table();
|
|
@@ -51137,6 +51390,15 @@ var init_run_dao = __esm(() => {
|
|
|
51137
51390
|
stampMetadata(runId, metadata) {
|
|
51138
51391
|
return this.adapter.run("UPDATE runs SET metadata_json = ? WHERE id = ?", JSON.stringify(metadata), runId);
|
|
51139
51392
|
}
|
|
51393
|
+
stampFailureReason(runId, reason) {
|
|
51394
|
+
return this.adapter.run(`UPDATE runs
|
|
51395
|
+
SET metadata_json = json_set(
|
|
51396
|
+
COALESCE(NULLIF(metadata_json, ''), '{}'),
|
|
51397
|
+
'$.failureReason',
|
|
51398
|
+
?1
|
|
51399
|
+
)
|
|
51400
|
+
WHERE id = ?2`, reason, runId);
|
|
51401
|
+
}
|
|
51140
51402
|
listStaleRuns(cutoffIso) {
|
|
51141
51403
|
return this.adapter.queryAll(`SELECT id, status, started_at
|
|
51142
51404
|
FROM runs
|
|
@@ -51384,7 +51646,7 @@ var init_dao = __esm(() => {
|
|
|
51384
51646
|
init_workspace_dao();
|
|
51385
51647
|
});
|
|
51386
51648
|
|
|
51387
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
51649
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/errors.js
|
|
51388
51650
|
var WorkflowValidationError, FSMError, RunCollisionError, WorkflowResumeError;
|
|
51389
51651
|
var init_errors6 = __esm(() => {
|
|
51390
51652
|
WorkflowValidationError = class WorkflowValidationError extends Error {
|
|
@@ -51419,12 +51681,12 @@ var init_errors6 = __esm(() => {
|
|
|
51419
51681
|
};
|
|
51420
51682
|
});
|
|
51421
51683
|
|
|
51422
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
51684
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/event-bus/index.js
|
|
51423
51685
|
var init_event_bus2 = __esm(() => {
|
|
51424
51686
|
init_event_bus();
|
|
51425
51687
|
});
|
|
51426
51688
|
|
|
51427
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
51689
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/api-client.js
|
|
51428
51690
|
function sanitizeUrlForObservability(url2) {
|
|
51429
51691
|
try {
|
|
51430
51692
|
const parsed = new URL(url2);
|
|
@@ -51654,12 +51916,12 @@ var init_api_client = __esm(() => {
|
|
|
51654
51916
|
};
|
|
51655
51917
|
});
|
|
51656
51918
|
|
|
51657
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
51919
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/telemetry/index.js
|
|
51658
51920
|
var init_telemetry = __esm(() => {
|
|
51659
51921
|
init_tracing2();
|
|
51660
51922
|
});
|
|
51661
51923
|
|
|
51662
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
51924
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/index.js
|
|
51663
51925
|
var init_dist6 = __esm(() => {
|
|
51664
51926
|
init_api_client();
|
|
51665
51927
|
init_event_bus2();
|
|
@@ -51667,7 +51929,7 @@ var init_dist6 = __esm(() => {
|
|
|
51667
51929
|
init_telemetry();
|
|
51668
51930
|
});
|
|
51669
51931
|
|
|
51670
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
51932
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/run-lifecycle.js
|
|
51671
51933
|
function runtimeBuiltins(workflowName, stateOrNodeId, runId, transitionsTaken, mode) {
|
|
51672
51934
|
return {
|
|
51673
51935
|
workflow: workflowName,
|
|
@@ -51740,9 +52002,12 @@ class RunLifecycle {
|
|
|
51740
52002
|
return await loop(lifecycle);
|
|
51741
52003
|
}, { attributes: { "workflow.name": workflowName, "workflow.mode": mode } });
|
|
51742
52004
|
}
|
|
51743
|
-
async enter(stateOrNodeId, transitionsTaken, persist = true) {
|
|
52005
|
+
async enter(stateOrNodeId, transitionsTaken, persist = true, vars) {
|
|
51744
52006
|
if (persist) {
|
|
51745
|
-
|
|
52007
|
+
const data = { transitionsTaken };
|
|
52008
|
+
if (vars !== undefined)
|
|
52009
|
+
data.effectiveVars = vars;
|
|
52010
|
+
await this.persistence.saveWorkflowState(this.runId, stateOrNodeId, data);
|
|
51746
52011
|
await this.persistence.savePhase(this.runId, stateOrNodeId, "running");
|
|
51747
52012
|
}
|
|
51748
52013
|
addSpanEvent("workflow.node.enter", {
|
|
@@ -51756,8 +52021,11 @@ class RunLifecycle {
|
|
|
51756
52021
|
transitionsTaken
|
|
51757
52022
|
});
|
|
51758
52023
|
}
|
|
51759
|
-
async commitHop(from, to, trigger, transitionsTaken, phase) {
|
|
51760
|
-
|
|
52024
|
+
async commitHop(from, to, trigger, transitionsTaken, phase, vars) {
|
|
52025
|
+
const data = { transitionsTaken };
|
|
52026
|
+
if (vars !== undefined)
|
|
52027
|
+
data.effectiveVars = vars;
|
|
52028
|
+
await this.persistence.commitTransition(this.runId, from, to, trigger, to, data, phase);
|
|
51761
52029
|
addSpanEvent("workflow.node.transition", {
|
|
51762
52030
|
runId: this.runId,
|
|
51763
52031
|
from,
|
|
@@ -51814,7 +52082,11 @@ class RunLifecycle {
|
|
|
51814
52082
|
this.logger.warn("workflow run failed", { finalState, transitionsTaken, reason });
|
|
51815
52083
|
return this.result("failed", finalState, transitionsTaken, reason);
|
|
51816
52084
|
}
|
|
51817
|
-
async pause(stateOrNodeId, transitionsTaken) {
|
|
52085
|
+
async pause(stateOrNodeId, transitionsTaken, vars) {
|
|
52086
|
+
const data = { transitionsTaken };
|
|
52087
|
+
if (vars !== undefined)
|
|
52088
|
+
data.effectiveVars = vars;
|
|
52089
|
+
await this.persistence.saveWorkflowState(this.runId, stateOrNodeId, data);
|
|
51818
52090
|
await this.persistence.savePhase(this.runId, stateOrNodeId, "paused");
|
|
51819
52091
|
await this.persistence.finalizeRun(this.runId, "paused", new Date().toISOString());
|
|
51820
52092
|
this.logger.info("workflow run paused", { stateOrNodeId, transitionsTaken });
|
|
@@ -51916,7 +52188,7 @@ var init_run_lifecycle = __esm(() => {
|
|
|
51916
52188
|
];
|
|
51917
52189
|
});
|
|
51918
52190
|
|
|
51919
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
52191
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/schema.js
|
|
51920
52192
|
var RESERVED_VAR_NAMES, IDENTIFIER, VarsSchema, EnvSchema, ActionDefSchema, GuardDefSchema, StateMachineWorkflowDefSchema, TransitionFlowWorkflowDefSchema, WorkflowDefSchema;
|
|
51921
52193
|
var init_schema2 = __esm(() => {
|
|
51922
52194
|
init_zod();
|
|
@@ -52000,7 +52272,7 @@ var init_schema2 = __esm(() => {
|
|
|
52000
52272
|
WorkflowDefSchema = exports_external.union([StateMachineWorkflowDefSchema, TransitionFlowWorkflowDefSchema]);
|
|
52001
52273
|
});
|
|
52002
52274
|
|
|
52003
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
52275
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/config.js
|
|
52004
52276
|
async function loadWorkflowDef(path9, options = {}) {
|
|
52005
52277
|
return parseWorkflowDef(await loadStructuredConfig(path9, options), path9);
|
|
52006
52278
|
}
|
|
@@ -52159,7 +52431,7 @@ var init_config4 = __esm(() => {
|
|
|
52159
52431
|
RUNTIME_TEMPLATE_NAMESPACES = new Set(RUNTIME_BUILTIN_KEYS);
|
|
52160
52432
|
});
|
|
52161
52433
|
|
|
52162
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
52434
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/extension/capability-registry.js
|
|
52163
52435
|
class CapabilityRegistry {
|
|
52164
52436
|
kind;
|
|
52165
52437
|
capabilities = new Map;
|
|
@@ -52190,7 +52462,7 @@ class CapabilityRegistry {
|
|
|
52190
52462
|
}
|
|
52191
52463
|
}
|
|
52192
52464
|
|
|
52193
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
52465
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-path.js
|
|
52194
52466
|
function assertRelativeExtensionPath(path9, options = {}) {
|
|
52195
52467
|
const where = options.sourceName !== undefined ? ` declared by "${options.sourceName}"` : "";
|
|
52196
52468
|
if (/^([/\\]|[A-Za-z]:[/\\])/.test(path9)) {
|
|
@@ -52201,20 +52473,20 @@ function assertRelativeExtensionPath(path9, options = {}) {
|
|
|
52201
52473
|
}
|
|
52202
52474
|
}
|
|
52203
52475
|
|
|
52204
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
52476
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-loader.js
|
|
52205
52477
|
var init_extension_loader = () => {};
|
|
52206
52478
|
|
|
52207
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
52479
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/extension/index.js
|
|
52208
52480
|
var init_extension = __esm(() => {
|
|
52209
52481
|
init_extension_loader();
|
|
52210
52482
|
});
|
|
52211
52483
|
|
|
52212
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
52484
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.14+1afbae169bbe5102/node_modules/@gobing-ai/ts-runtime/dist/extension.js
|
|
52213
52485
|
var init_extension2 = __esm(() => {
|
|
52214
52486
|
init_extension();
|
|
52215
52487
|
});
|
|
52216
52488
|
|
|
52217
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
52489
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/host.js
|
|
52218
52490
|
class WorkflowEngineHost {
|
|
52219
52491
|
lifecycleBus;
|
|
52220
52492
|
actions = new CapabilityRegistry("workflow action");
|
|
@@ -52383,7 +52655,7 @@ var init_host = __esm(() => {
|
|
|
52383
52655
|
init_errors6();
|
|
52384
52656
|
});
|
|
52385
52657
|
|
|
52386
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
52658
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/schema-sql.js
|
|
52387
52659
|
var WORKFLOW_ENGINE_SCHEMA_SQL;
|
|
52388
52660
|
var init_schema_sql = __esm(() => {
|
|
52389
52661
|
WORKFLOW_ENGINE_SCHEMA_SQL = `
|
|
@@ -52456,7 +52728,7 @@ CREATE TABLE IF NOT EXISTS action_runs (
|
|
|
52456
52728
|
`.trim();
|
|
52457
52729
|
});
|
|
52458
52730
|
|
|
52459
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
52731
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/persistence.js
|
|
52460
52732
|
async function applyWorkflowEngineSchema(db2) {
|
|
52461
52733
|
for (const statement of WORKFLOW_ENGINE_SCHEMA_SQL.split(";")) {
|
|
52462
52734
|
const sql4 = statement.trim();
|
|
@@ -52608,6 +52880,21 @@ class DbWorkflowPersistenceAdapter {
|
|
|
52608
52880
|
const row = await this.db.queryFirst("SELECT state FROM workflow_states WHERE run_id = ? ORDER BY created_at DESC, rowid DESC LIMIT 1", runId);
|
|
52609
52881
|
return row?.state;
|
|
52610
52882
|
}
|
|
52883
|
+
async loadLatestStateSnapshot(runId) {
|
|
52884
|
+
await this.ensureSchema();
|
|
52885
|
+
const row = await this.db.queryFirst("SELECT state, data_json FROM workflow_states WHERE run_id = ? ORDER BY created_at DESC, rowid DESC LIMIT 1", runId);
|
|
52886
|
+
if (row == null)
|
|
52887
|
+
return;
|
|
52888
|
+
let data = {};
|
|
52889
|
+
if (row.data_json !== null && row.data_json.length > 0) {
|
|
52890
|
+
try {
|
|
52891
|
+
data = JSON.parse(row.data_json);
|
|
52892
|
+
} catch {
|
|
52893
|
+
data = {};
|
|
52894
|
+
}
|
|
52895
|
+
}
|
|
52896
|
+
return { state: row.state, data };
|
|
52897
|
+
}
|
|
52611
52898
|
async listPausedRuns(options) {
|
|
52612
52899
|
await this.ensureSchema();
|
|
52613
52900
|
const where = ["status = 'paused'"];
|
|
@@ -52710,6 +52997,12 @@ class MemoryWorkflowPersistenceAdapter {
|
|
|
52710
52997
|
const last = this.states.findLast((s) => s.runId === runId);
|
|
52711
52998
|
return last?.state;
|
|
52712
52999
|
}
|
|
53000
|
+
async loadLatestStateSnapshot(runId) {
|
|
53001
|
+
const last = this.states.findLast((s) => s.runId === runId);
|
|
53002
|
+
if (last === undefined)
|
|
53003
|
+
return;
|
|
53004
|
+
return { state: last.state, data: last.data };
|
|
53005
|
+
}
|
|
52713
53006
|
async listPausedRuns(options) {
|
|
52714
53007
|
let runs2 = [...this.runs.values()].filter((r) => r.status === "paused");
|
|
52715
53008
|
if (options?.workflowName !== undefined) {
|
|
@@ -52724,7 +53017,7 @@ var init_persistence = __esm(() => {
|
|
|
52724
53017
|
init_schema_sql();
|
|
52725
53018
|
});
|
|
52726
53019
|
|
|
52727
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53020
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/variables.js
|
|
52728
53021
|
function mergeVars(workflowVars = {}, overrideVars = {}) {
|
|
52729
53022
|
return { ...workflowVars, ...overrideVars };
|
|
52730
53023
|
}
|
|
@@ -52784,7 +53077,7 @@ var init_variables = __esm(() => {
|
|
|
52784
53077
|
TEMPLATE_REF = /\$\{([^}]+)\}/g;
|
|
52785
53078
|
});
|
|
52786
53079
|
|
|
52787
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53080
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/action-step.js
|
|
52788
53081
|
async function runActionStep(action, vars, deps) {
|
|
52789
53082
|
const { host, persistence, lifecycle, stateOrNodeId, runId } = deps;
|
|
52790
53083
|
const resolved = resolveTemplates(action.options ?? {}, {
|
|
@@ -52799,6 +53092,7 @@ async function runActionStep(action, vars, deps) {
|
|
|
52799
53092
|
try {
|
|
52800
53093
|
result = await host.runAction(action.kind, resolved, {
|
|
52801
53094
|
runId,
|
|
53095
|
+
actionId,
|
|
52802
53096
|
workdir: deps.options.workdir,
|
|
52803
53097
|
stateOrNodeId,
|
|
52804
53098
|
vars,
|
|
@@ -52841,7 +53135,7 @@ var init_action_step = __esm(() => {
|
|
|
52841
53135
|
init_variables();
|
|
52842
53136
|
});
|
|
52843
53137
|
|
|
52844
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53138
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/state-machine.js
|
|
52845
53139
|
class StateMachineDriver {
|
|
52846
53140
|
options;
|
|
52847
53141
|
constructor(options) {
|
|
@@ -52875,7 +53169,7 @@ class StateMachineDriver {
|
|
|
52875
53169
|
isResume = false;
|
|
52876
53170
|
persistedViaHop = true;
|
|
52877
53171
|
} else {
|
|
52878
|
-
await lifecycle.enter(current.id, transitionsTaken, !persistedViaHop);
|
|
53172
|
+
await lifecycle.enter(current.id, transitionsTaken, !persistedViaHop, vars);
|
|
52879
53173
|
const enter = options.dryRun ? EMPTY_OUTCOME : await runActionSequence(current.onEnter ?? [], vars, {
|
|
52880
53174
|
host: this.options.host,
|
|
52881
53175
|
persistence: this.options.persistence,
|
|
@@ -52900,7 +53194,7 @@ class StateMachineDriver {
|
|
|
52900
53194
|
return await lifecycle.fail(current.id, transitionsTaken, lastActionResult?.error);
|
|
52901
53195
|
}
|
|
52902
53196
|
if (current.pause === true) {
|
|
52903
|
-
return await lifecycle.pause(current.id, transitionsTaken);
|
|
53197
|
+
return await lifecycle.pause(current.id, transitionsTaken, vars);
|
|
52904
53198
|
}
|
|
52905
53199
|
}
|
|
52906
53200
|
const outbound = workflow.transitions.filter((transition) => transition.from === current?.id);
|
|
@@ -52939,7 +53233,7 @@ class StateMachineDriver {
|
|
|
52939
53233
|
await lifecycle.commitHop(current.id, nextTransition.to, nextTransition.trigger ?? null, transitionsTaken, {
|
|
52940
53234
|
phase: nextTransition.to,
|
|
52941
53235
|
status: "running"
|
|
52942
|
-
});
|
|
53236
|
+
}, vars);
|
|
52943
53237
|
if (transitionsTaken > iterationBound) {
|
|
52944
53238
|
return await lifecycle.fail(current.id, transitionsTaken, "iteration-bound-exceeded");
|
|
52945
53239
|
}
|
|
@@ -52975,7 +53269,7 @@ var init_state_machine = __esm(() => {
|
|
|
52975
53269
|
EMPTY_OUTCOME = { outcome: "completed", result: undefined };
|
|
52976
53270
|
});
|
|
52977
53271
|
|
|
52978
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53272
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/transition-flow.js
|
|
52979
53273
|
class TransitionFlowDriver {
|
|
52980
53274
|
options;
|
|
52981
53275
|
constructor(options) {
|
|
@@ -53009,7 +53303,7 @@ class TransitionFlowDriver {
|
|
|
53009
53303
|
isResume = false;
|
|
53010
53304
|
persistedViaHop = true;
|
|
53011
53305
|
} else {
|
|
53012
|
-
await lifecycle.enter(current.id, transitionsTaken, !persistedViaHop);
|
|
53306
|
+
await lifecycle.enter(current.id, transitionsTaken, !persistedViaHop, vars);
|
|
53013
53307
|
if (options.dryRun) {
|
|
53014
53308
|
if (current.action !== undefined) {
|
|
53015
53309
|
lastActionResult = undefined;
|
|
@@ -53039,7 +53333,7 @@ class TransitionFlowDriver {
|
|
|
53039
53333
|
}
|
|
53040
53334
|
}
|
|
53041
53335
|
if (current.pause === true) {
|
|
53042
|
-
return await lifecycle.pause(current.id, transitionsTaken);
|
|
53336
|
+
return await lifecycle.pause(current.id, transitionsTaken, vars);
|
|
53043
53337
|
}
|
|
53044
53338
|
}
|
|
53045
53339
|
const outbound = workflow.edges.filter((edge2) => edge2.from === current?.id);
|
|
@@ -53059,7 +53353,7 @@ class TransitionFlowDriver {
|
|
|
53059
53353
|
await lifecycle.commitHop(current.id, edge.to, edge.condition?.kind ?? null, transitionsTaken, {
|
|
53060
53354
|
phase: edge.to,
|
|
53061
53355
|
status: "running"
|
|
53062
|
-
});
|
|
53356
|
+
}, vars);
|
|
53063
53357
|
if (transitionsTaken > iterationBound) {
|
|
53064
53358
|
return await lifecycle.fail(current.id, transitionsTaken, "iteration-bound-exceeded");
|
|
53065
53359
|
}
|
|
@@ -53093,7 +53387,7 @@ var init_transition_flow = __esm(() => {
|
|
|
53093
53387
|
init_variables();
|
|
53094
53388
|
});
|
|
53095
53389
|
|
|
53096
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53390
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/service.js
|
|
53097
53391
|
class WorkflowService {
|
|
53098
53392
|
host;
|
|
53099
53393
|
persistence;
|
|
@@ -53183,20 +53477,24 @@ class WorkflowService {
|
|
|
53183
53477
|
if (currentState === undefined) {
|
|
53184
53478
|
throw new WorkflowResumeError(`Run "${runId}" has no persisted state to resume from`);
|
|
53185
53479
|
}
|
|
53480
|
+
const snapshot = await this.persistence.loadLatestStateSnapshot(runId);
|
|
53481
|
+
const persistedVars = extractEffectiveVars(snapshot?.data);
|
|
53482
|
+
const restoredVars = mergeVars(persistedVars, options?.vars);
|
|
53483
|
+
const mergedOptions = { ...options, vars: restoredVars };
|
|
53186
53484
|
const extKey = run.external_key ?? undefined;
|
|
53187
53485
|
await this.persistence.finalizeRun(runId, "running", "");
|
|
53188
|
-
const events = this.resolveEvents(
|
|
53486
|
+
const events = this.resolveEvents(mergedOptions.events);
|
|
53189
53487
|
events?.emit("workflow.run.resumed", { runId, node: currentState, externalKey: extKey });
|
|
53190
53488
|
if (workflow.kind === "transition-flow") {
|
|
53191
53489
|
return await new TransitionFlowDriver({
|
|
53192
53490
|
host: this.host,
|
|
53193
53491
|
persistence: this.persistence
|
|
53194
|
-
}).resume(workflow, runId, currentState, extKey,
|
|
53492
|
+
}).resume(workflow, runId, currentState, extKey, mergedOptions);
|
|
53195
53493
|
}
|
|
53196
53494
|
return await new StateMachineDriver({
|
|
53197
53495
|
host: this.host,
|
|
53198
53496
|
persistence: this.persistence
|
|
53199
|
-
}).resume(workflow, runId, currentState, extKey,
|
|
53497
|
+
}).resume(workflow, runId, currentState, extKey, mergedOptions);
|
|
53200
53498
|
}
|
|
53201
53499
|
async listPausedRuns(options) {
|
|
53202
53500
|
return await this.persistence.listPausedRuns(options);
|
|
@@ -53281,6 +53579,21 @@ class WorkflowService {
|
|
|
53281
53579
|
return { allowed: false, ...denial };
|
|
53282
53580
|
}
|
|
53283
53581
|
}
|
|
53582
|
+
function extractEffectiveVars(data) {
|
|
53583
|
+
if (data === undefined)
|
|
53584
|
+
return {};
|
|
53585
|
+
const raw = data.effectiveVars;
|
|
53586
|
+
if (raw === undefined || raw === null)
|
|
53587
|
+
return {};
|
|
53588
|
+
if (typeof raw !== "object")
|
|
53589
|
+
return {};
|
|
53590
|
+
const filtered = {};
|
|
53591
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
53592
|
+
if (typeof value === "string")
|
|
53593
|
+
filtered[key] = value;
|
|
53594
|
+
}
|
|
53595
|
+
return filtered;
|
|
53596
|
+
}
|
|
53284
53597
|
var init_service = __esm(() => {
|
|
53285
53598
|
init_dist6();
|
|
53286
53599
|
init_config4();
|
|
@@ -53291,7 +53604,7 @@ var init_service = __esm(() => {
|
|
|
53291
53604
|
init_variables();
|
|
53292
53605
|
});
|
|
53293
53606
|
|
|
53294
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53607
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/index.js
|
|
53295
53608
|
var init_dist7 = __esm(() => {
|
|
53296
53609
|
init_config4();
|
|
53297
53610
|
init_host();
|
|
@@ -53300,7 +53613,7 @@ var init_dist7 = __esm(() => {
|
|
|
53300
53613
|
init_service();
|
|
53301
53614
|
});
|
|
53302
53615
|
|
|
53303
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
53616
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.14+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/errors.js
|
|
53304
53617
|
var HistoryImportError;
|
|
53305
53618
|
var init_errors7 = __esm(() => {
|
|
53306
53619
|
HistoryImportError = class HistoryImportError extends Error {
|
|
@@ -53313,7 +53626,7 @@ var init_errors7 = __esm(() => {
|
|
|
53313
53626
|
};
|
|
53314
53627
|
});
|
|
53315
53628
|
|
|
53316
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
53629
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.14+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/hash.js
|
|
53317
53630
|
import { createHash } from "crypto";
|
|
53318
53631
|
function stableJson(value) {
|
|
53319
53632
|
if (Array.isArray(value)) {
|
|
@@ -53330,7 +53643,7 @@ function sha256(value) {
|
|
|
53330
53643
|
}
|
|
53331
53644
|
var init_hash = () => {};
|
|
53332
53645
|
|
|
53333
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
53646
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.14+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/redaction.js
|
|
53334
53647
|
function redactValue(value, rules = DEFAULT_REDACTION_RULES) {
|
|
53335
53648
|
if (typeof value === "string") {
|
|
53336
53649
|
return rules.reduce((current, rule) => current.replace(rule.pattern, rule.replacement), value);
|
|
@@ -53367,7 +53680,7 @@ var init_redaction = __esm(() => {
|
|
|
53367
53680
|
];
|
|
53368
53681
|
});
|
|
53369
53682
|
|
|
53370
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
53683
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.14+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/schema-sql.js
|
|
53371
53684
|
var HISTORY_IMPORT_SCHEMA_SQL;
|
|
53372
53685
|
var init_schema_sql2 = __esm(() => {
|
|
53373
53686
|
HISTORY_IMPORT_SCHEMA_SQL = `
|
|
@@ -53454,7 +53767,7 @@ CREATE TABLE IF NOT EXISTS history_etl_openclaw (
|
|
|
53454
53767
|
`.trim();
|
|
53455
53768
|
});
|
|
53456
53769
|
|
|
53457
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
53770
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.14+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/sources.js
|
|
53458
53771
|
function firstString(...values) {
|
|
53459
53772
|
for (const value of values) {
|
|
53460
53773
|
if (typeof value === "string" && value.length > 0)
|
|
@@ -53542,7 +53855,7 @@ var init_sources = __esm(() => {
|
|
|
53542
53855
|
};
|
|
53543
53856
|
});
|
|
53544
53857
|
|
|
53545
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
53858
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.14+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/importer.js
|
|
53546
53859
|
async function applyHistoryImportSchema(db2) {
|
|
53547
53860
|
for (const statement of HISTORY_IMPORT_SCHEMA_SQL.split(";")) {
|
|
53548
53861
|
const sql4 = statement.trim();
|
|
@@ -53779,13 +54092,13 @@ var init_importer = __esm(() => {
|
|
|
53779
54092
|
VALID_TABLE_NAME = /^history_etl_[a-z_]+$/;
|
|
53780
54093
|
});
|
|
53781
54094
|
|
|
53782
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
54095
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.14+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/index.js
|
|
53783
54096
|
var init_dist8 = __esm(() => {
|
|
53784
54097
|
init_importer();
|
|
53785
54098
|
init_schema_sql2();
|
|
53786
54099
|
});
|
|
53787
54100
|
|
|
53788
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
54101
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/config/extensions.js
|
|
53789
54102
|
function collectExtensions(sourceName, sourceDir, extensions) {
|
|
53790
54103
|
if (extensions === undefined)
|
|
53791
54104
|
return [];
|
|
@@ -53801,7 +54114,7 @@ var init_extensions = __esm(() => {
|
|
|
53801
54114
|
init_dist5();
|
|
53802
54115
|
});
|
|
53803
54116
|
|
|
53804
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
54117
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/types.js
|
|
53805
54118
|
function createFinding(rule, message, filePath, extras = {}) {
|
|
53806
54119
|
return {
|
|
53807
54120
|
ruleId: rule.id,
|
|
@@ -53872,7 +54185,7 @@ var init_types3 = __esm(() => {
|
|
|
53872
54185
|
});
|
|
53873
54186
|
});
|
|
53874
54187
|
|
|
53875
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
54188
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/config/loader.js
|
|
53876
54189
|
async function loadPreset(name, options) {
|
|
53877
54190
|
const merged = await buildMergedRoots(options.roots.map((root) => resolvePath4(root)), options.fileSystem);
|
|
53878
54191
|
const presetPath = findMergedPreset(merged, name);
|
|
@@ -54087,7 +54400,7 @@ var init_loader2 = __esm(() => {
|
|
|
54087
54400
|
FIX_MODE_AUTHORITY = { none: 0, suggest: 1, auto: 2 };
|
|
54088
54401
|
});
|
|
54089
54402
|
|
|
54090
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
54403
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/fixers/test-stub-fixer.js
|
|
54091
54404
|
function normalizeFindingPath(filePath) {
|
|
54092
54405
|
if (!filePath || isAbsolutePath2(filePath))
|
|
54093
54406
|
return null;
|
|
@@ -54152,7 +54465,7 @@ var init_test_stub_fixer = __esm(() => {
|
|
|
54152
54465
|
realFileSystem = createNodeFileSystem3();
|
|
54153
54466
|
});
|
|
54154
54467
|
|
|
54155
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
54468
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/fixers/fixers.js
|
|
54156
54469
|
function registerBuiltinFixers(host, exec) {
|
|
54157
54470
|
const regexFixer = new RegexFixerProvider;
|
|
54158
54471
|
const pathFixer = new PathFixerProvider;
|
|
@@ -54355,7 +54668,7 @@ var init_fixers = __esm(() => {
|
|
|
54355
54668
|
};
|
|
54356
54669
|
});
|
|
54357
54670
|
|
|
54358
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
54671
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.14+127e896e9a498407/node_modules/@gobing-ai/ts-ai-runner/dist/agents/shims.js
|
|
54359
54672
|
function resolveAgentName(input) {
|
|
54360
54673
|
if (isCanonicalName(input))
|
|
54361
54674
|
return input;
|
|
@@ -54606,7 +54919,7 @@ var init_shims = __esm(() => {
|
|
|
54606
54919
|
ALIAS_TO_CANONICAL = Object.fromEntries(Object.values(AGENT_SHIMS).flatMap((shim) => (shim.aliases ?? []).map((alias3) => [alias3, shim.name])));
|
|
54607
54920
|
});
|
|
54608
54921
|
|
|
54609
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
54922
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.14+127e896e9a498407/node_modules/@gobing-ai/ts-ai-runner/dist/identity.js
|
|
54610
54923
|
function buildIdentityPreamble(ctx) {
|
|
54611
54924
|
const sections = [
|
|
54612
54925
|
`You are agent \`${ctx.agentId}\` (${ctx.agentType}) in workspace \`${ctx.workspace}\`.`
|
|
@@ -54666,7 +54979,7 @@ var init_identity = __esm(() => {
|
|
|
54666
54979
|
init_dist5();
|
|
54667
54980
|
});
|
|
54668
54981
|
|
|
54669
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
54982
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.14+127e896e9a498407/node_modules/@gobing-ai/ts-ai-runner/dist/slash-command.js
|
|
54670
54983
|
function isClaudeStyleSlashCommand(input) {
|
|
54671
54984
|
return SLASH_COMMAND_RE.test(input);
|
|
54672
54985
|
}
|
|
@@ -54694,7 +55007,7 @@ var init_slash_command = __esm(() => {
|
|
|
54694
55007
|
SLASH_COMMAND_RE = /^\/([a-zA-Z0-9._-]+):([a-zA-Z0-9._-]+)(\s.*)?$/;
|
|
54695
55008
|
});
|
|
54696
55009
|
|
|
54697
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
55010
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.14+127e896e9a498407/node_modules/@gobing-ai/ts-ai-runner/dist/ai-runner.js
|
|
54698
55011
|
class AiRunner {
|
|
54699
55012
|
processExecutor;
|
|
54700
55013
|
defaultCwd;
|
|
@@ -54747,7 +55060,12 @@ class AiRunner {
|
|
|
54747
55060
|
async invoke(agent, operation, command, options, forceBuffered) {
|
|
54748
55061
|
const label = `ai-runner.${agent}.${operation}`;
|
|
54749
55062
|
this.logger.debug("invoke", { label, command: command.command, args: command.args.join(" ") });
|
|
54750
|
-
this.events?.emit("agent.invoke.start", {
|
|
55063
|
+
this.events?.emit("agent.invoke.start", {
|
|
55064
|
+
agent,
|
|
55065
|
+
operation,
|
|
55066
|
+
label,
|
|
55067
|
+
...options.correlation !== undefined ? { correlation: options.correlation } : {}
|
|
55068
|
+
});
|
|
54751
55069
|
const result = await this.processExecutor.run({
|
|
54752
55070
|
command: command.command,
|
|
54753
55071
|
args: command.args,
|
|
@@ -54756,7 +55074,8 @@ class AiRunner {
|
|
|
54756
55074
|
forceBuffered,
|
|
54757
55075
|
cwd: options.cwd ?? this.defaultCwd,
|
|
54758
55076
|
timeout: options.timeout ?? this.defaultTimeout,
|
|
54759
|
-
...options.signal !== undefined ? { signal: options.signal } : {}
|
|
55077
|
+
...options.signal !== undefined ? { signal: options.signal } : {},
|
|
55078
|
+
...options.onOutput !== undefined ? { onOutput: options.onOutput } : {}
|
|
54760
55079
|
});
|
|
54761
55080
|
if (result.exitCode !== 0) {
|
|
54762
55081
|
this.logger.error("invoke exited non-zero", {
|
|
@@ -54771,7 +55090,8 @@ class AiRunner {
|
|
|
54771
55090
|
label,
|
|
54772
55091
|
exitCode: result.exitCode,
|
|
54773
55092
|
...result.signal !== undefined ? { signal: result.signal } : {},
|
|
54774
|
-
durationMs: result.durationMs
|
|
55093
|
+
durationMs: result.durationMs,
|
|
55094
|
+
...options.correlation !== undefined ? { correlation: options.correlation } : {}
|
|
54775
55095
|
});
|
|
54776
55096
|
return {
|
|
54777
55097
|
exitCode: result.exitCode,
|
|
@@ -54812,7 +55132,7 @@ var init_ai_runner = __esm(() => {
|
|
|
54812
55132
|
init_slash_command();
|
|
54813
55133
|
});
|
|
54814
55134
|
|
|
54815
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
55135
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.14+127e896e9a498407/node_modules/@gobing-ai/ts-ai-runner/dist/agent-detector.js
|
|
54816
55136
|
class AgentDetector {
|
|
54817
55137
|
runner;
|
|
54818
55138
|
timeout;
|
|
@@ -54888,7 +55208,7 @@ var init_agent_detector = __esm(() => {
|
|
|
54888
55208
|
VERSION_PATTERN = /(?<version>\d+\.\d+(?:\.\d+)?)/;
|
|
54889
55209
|
});
|
|
54890
55210
|
|
|
54891
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
55211
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.14+127e896e9a498407/node_modules/@gobing-ai/ts-ai-runner/dist/agent-spec.js
|
|
54892
55212
|
function validateAgentId(id) {
|
|
54893
55213
|
if (!/^[a-z][a-z0-9_-]{1,63}$/.test(id)) {
|
|
54894
55214
|
throw new ValueError(`Invalid agent id "${id}": expected 2-64 chars, lowercase alphanumeric, "_" or "-"`);
|
|
@@ -54985,7 +55305,7 @@ var init_agent_spec = __esm(() => {
|
|
|
54985
55305
|
};
|
|
54986
55306
|
});
|
|
54987
55307
|
|
|
54988
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
55308
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.14+127e896e9a498407/node_modules/@gobing-ai/ts-ai-runner/dist/agents/auth-shims.js
|
|
54989
55309
|
function isNonEmpty(value) {
|
|
54990
55310
|
return value !== undefined && value.trim().length > 0;
|
|
54991
55311
|
}
|
|
@@ -55090,7 +55410,7 @@ var init_auth_shims = __esm(() => {
|
|
|
55090
55410
|
};
|
|
55091
55411
|
});
|
|
55092
55412
|
|
|
55093
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
55413
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.14+127e896e9a498407/node_modules/@gobing-ai/ts-ai-runner/dist/model-health-probe.js
|
|
55094
55414
|
class ModelHealthProbeRegistry {
|
|
55095
55415
|
probes = new Map;
|
|
55096
55416
|
register(providerPrefix, probe) {
|
|
@@ -55198,7 +55518,7 @@ var init_model_health_probe = __esm(() => {
|
|
|
55198
55518
|
};
|
|
55199
55519
|
});
|
|
55200
55520
|
|
|
55201
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
55521
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.14+127e896e9a498407/node_modules/@gobing-ai/ts-ai-runner/dist/doctor-runner.js
|
|
55202
55522
|
class DoctorRunner {
|
|
55203
55523
|
detector;
|
|
55204
55524
|
runner;
|
|
@@ -55335,15 +55655,15 @@ var init_doctor_runner = __esm(() => {
|
|
|
55335
55655
|
init_model_health_probe();
|
|
55336
55656
|
});
|
|
55337
55657
|
|
|
55338
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
55658
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.14+127e896e9a498407/node_modules/@gobing-ai/ts-ai-runner/dist/events.js
|
|
55339
55659
|
var init_events = () => {};
|
|
55340
55660
|
|
|
55341
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
55661
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.14+127e896e9a498407/node_modules/@gobing-ai/ts-ai-runner/dist/messages.js
|
|
55342
55662
|
function formatMessage(msg) {
|
|
55343
55663
|
return `[task from=${msg.fromId ?? "operator"} id=${msg.id}] ${msg.body}`;
|
|
55344
55664
|
}
|
|
55345
55665
|
|
|
55346
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
55666
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.14+127e896e9a498407/node_modules/@gobing-ai/ts-ai-runner/dist/team-agent-process.js
|
|
55347
55667
|
import { Buffer as Buffer5 } from "buffer";
|
|
55348
55668
|
|
|
55349
55669
|
class TeamAgentProcess {
|
|
@@ -55477,7 +55797,7 @@ var init_team_agent_process = __esm(() => {
|
|
|
55477
55797
|
init_dist5();
|
|
55478
55798
|
});
|
|
55479
55799
|
|
|
55480
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
55800
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.14+127e896e9a498407/node_modules/@gobing-ai/ts-ai-runner/dist/team-orchestrator.js
|
|
55481
55801
|
class TeamOrchestrator {
|
|
55482
55802
|
configDir;
|
|
55483
55803
|
inbox;
|
|
@@ -55606,7 +55926,7 @@ var init_team_orchestrator = __esm(() => {
|
|
|
55606
55926
|
init_team_agent_process();
|
|
55607
55927
|
});
|
|
55608
55928
|
|
|
55609
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
55929
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.14+127e896e9a498407/node_modules/@gobing-ai/ts-ai-runner/dist/index.js
|
|
55610
55930
|
var exports_dist3 = {};
|
|
55611
55931
|
__export(exports_dist3, {
|
|
55612
55932
|
validateAgentId: () => validateAgentId,
|
|
@@ -55654,7 +55974,7 @@ var init_dist9 = __esm(() => {
|
|
|
55654
55974
|
init_team_orchestrator();
|
|
55655
55975
|
});
|
|
55656
55976
|
|
|
55657
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
55977
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/config-access.js
|
|
55658
55978
|
function stringArray(value) {
|
|
55659
55979
|
return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : undefined;
|
|
55660
55980
|
}
|
|
@@ -55692,7 +56012,7 @@ function parseInlineFlags(source) {
|
|
|
55692
56012
|
return { flags, rest: source.slice(match[0].length) };
|
|
55693
56013
|
}
|
|
55694
56014
|
|
|
55695
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56015
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/glob-match.js
|
|
55696
56016
|
function matchesAny(path9, patterns) {
|
|
55697
56017
|
if (patterns === undefined || patterns.length === 0)
|
|
55698
56018
|
return true;
|
|
@@ -55740,7 +56060,7 @@ function escapeRegExp(value) {
|
|
|
55740
56060
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
55741
56061
|
}
|
|
55742
56062
|
|
|
55743
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56063
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/file-discovery.js
|
|
55744
56064
|
async function discoverFiles2(options) {
|
|
55745
56065
|
const fs3 = options.fs ?? createNodeFileSystem3();
|
|
55746
56066
|
const allFiles = await walkDir2(options.workdir, fs3, DEFAULT_EXCLUDES);
|
|
@@ -55768,12 +56088,12 @@ var init_file_discovery = __esm(() => {
|
|
|
55768
56088
|
DEFAULT_EXCLUDES = new Set([".git", "node_modules", "dist", ".coverage", ".astro", ".wrangler"]);
|
|
55769
56089
|
});
|
|
55770
56090
|
|
|
55771
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56091
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/file-utils.js
|
|
55772
56092
|
var init_file_utils = __esm(() => {
|
|
55773
56093
|
init_file_discovery();
|
|
55774
56094
|
});
|
|
55775
56095
|
|
|
55776
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56096
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/agent-detection-evaluator.js
|
|
55777
56097
|
class AgentDetectionEvaluator {
|
|
55778
56098
|
detector;
|
|
55779
56099
|
constructor(detector = new AgentDetector) {
|
|
@@ -55801,7 +56121,7 @@ var init_agent_detection_evaluator = __esm(() => {
|
|
|
55801
56121
|
init_file_utils();
|
|
55802
56122
|
});
|
|
55803
56123
|
|
|
55804
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56124
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/coverage-gate-evaluator.js
|
|
55805
56125
|
class CoverageGateEvaluator {
|
|
55806
56126
|
constructor() {}
|
|
55807
56127
|
async evaluate(rule, context4) {
|
|
@@ -55885,7 +56205,7 @@ var init_coverage_gate_evaluator = __esm(() => {
|
|
|
55885
56205
|
init_file_utils();
|
|
55886
56206
|
});
|
|
55887
56207
|
|
|
55888
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56208
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/exit-code-evaluator.js
|
|
55889
56209
|
class ExitCodeEvaluator {
|
|
55890
56210
|
executor;
|
|
55891
56211
|
constructor(executor = nodeBunFactory3.createProcessExecutor()) {
|
|
@@ -55921,7 +56241,7 @@ var init_exit_code_evaluator = __esm(() => {
|
|
|
55921
56241
|
init_file_utils();
|
|
55922
56242
|
});
|
|
55923
56243
|
|
|
55924
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56244
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/forbidden-import-evaluator.js
|
|
55925
56245
|
class ForbiddenImportEvaluator {
|
|
55926
56246
|
constructor() {}
|
|
55927
56247
|
async evaluate(rule, context4) {
|
|
@@ -56002,7 +56322,7 @@ var init_forbidden_import_evaluator = __esm(() => {
|
|
|
56002
56322
|
init_file_utils();
|
|
56003
56323
|
});
|
|
56004
56324
|
|
|
56005
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56325
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/import-boundary-evaluator.js
|
|
56006
56326
|
class ImportBoundaryEvaluator {
|
|
56007
56327
|
async evaluate(rule, context4) {
|
|
56008
56328
|
const config4 = rule.evaluator.config ?? {};
|
|
@@ -56095,7 +56415,7 @@ var init_import_boundary_evaluator = __esm(() => {
|
|
|
56095
56415
|
init_file_utils();
|
|
56096
56416
|
});
|
|
56097
56417
|
|
|
56098
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56418
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/path-evaluator.js
|
|
56099
56419
|
class PathEvaluator {
|
|
56100
56420
|
constructor() {}
|
|
56101
56421
|
async evaluate(rule, context4) {
|
|
@@ -56156,7 +56476,7 @@ var init_path_evaluator = __esm(() => {
|
|
|
56156
56476
|
init_file_utils();
|
|
56157
56477
|
});
|
|
56158
56478
|
|
|
56159
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56479
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/regex-evaluator.js
|
|
56160
56480
|
class RegexEvaluator {
|
|
56161
56481
|
constructor() {}
|
|
56162
56482
|
async evaluate(rule, context4) {
|
|
@@ -56234,7 +56554,7 @@ var init_regex_evaluator = __esm(() => {
|
|
|
56234
56554
|
init_file_utils();
|
|
56235
56555
|
});
|
|
56236
56556
|
|
|
56237
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56557
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/ripgrep-evaluator.js
|
|
56238
56558
|
class RipgrepEvaluator {
|
|
56239
56559
|
executor;
|
|
56240
56560
|
constructor(executor = nodeBunFactory3.createProcessExecutor()) {
|
|
@@ -56327,7 +56647,7 @@ var init_ripgrep_evaluator = __esm(() => {
|
|
|
56327
56647
|
init_file_utils();
|
|
56328
56648
|
});
|
|
56329
56649
|
|
|
56330
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56650
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/schema-artifact-evaluator.js
|
|
56331
56651
|
class SchemaArtifactEvaluator {
|
|
56332
56652
|
constructor() {}
|
|
56333
56653
|
async evaluate(rule, context4) {
|
|
@@ -56405,7 +56725,7 @@ var init_schema_artifact_evaluator = __esm(() => {
|
|
|
56405
56725
|
init_file_utils();
|
|
56406
56726
|
});
|
|
56407
56727
|
|
|
56408
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56728
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/secrets-scanner-evaluator.js
|
|
56409
56729
|
class SecretsScannerEvaluator {
|
|
56410
56730
|
constructor() {}
|
|
56411
56731
|
async evaluate(rule, context4) {
|
|
@@ -56473,7 +56793,7 @@ var init_secrets_scanner_evaluator = __esm(() => {
|
|
|
56473
56793
|
ALL_CATEGORIES = Object.keys(BUILTIN_PATTERNS);
|
|
56474
56794
|
});
|
|
56475
56795
|
|
|
56476
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56796
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/sg-evaluator.js
|
|
56477
56797
|
class SgEvaluator {
|
|
56478
56798
|
executor;
|
|
56479
56799
|
constructor(executor = nodeBunFactory3.createProcessExecutor()) {
|
|
@@ -56570,7 +56890,7 @@ var init_sg_evaluator = __esm(() => {
|
|
|
56570
56890
|
init_file_utils();
|
|
56571
56891
|
});
|
|
56572
56892
|
|
|
56573
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56893
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/resolvers/test-path-resolver.js
|
|
56574
56894
|
class TypeScriptTestPathResolver {
|
|
56575
56895
|
name = "typescript";
|
|
56576
56896
|
constructor() {}
|
|
@@ -56653,7 +56973,7 @@ function testify(rel) {
|
|
|
56653
56973
|
return `${dir}test_${base2}`;
|
|
56654
56974
|
}
|
|
56655
56975
|
|
|
56656
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56976
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/test-location-evaluator.js
|
|
56657
56977
|
class TestLocationEvaluator {
|
|
56658
56978
|
resolvers;
|
|
56659
56979
|
constructor(resolvers) {
|
|
@@ -56728,7 +57048,7 @@ var init_test_location_evaluator = __esm(() => {
|
|
|
56728
57048
|
TYPESCRIPT_FALLBACK = new TypeScriptTestPathResolver;
|
|
56729
57049
|
});
|
|
56730
57050
|
|
|
56731
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
57051
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/tsdoc-export-evaluator.js
|
|
56732
57052
|
class TsdocExportEvaluator {
|
|
56733
57053
|
constructor() {}
|
|
56734
57054
|
async evaluate(rule, context4) {
|
|
@@ -56813,7 +57133,7 @@ var init_tsdoc_export_evaluator = __esm(() => {
|
|
|
56813
57133
|
};
|
|
56814
57134
|
});
|
|
56815
57135
|
|
|
56816
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
57136
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/json.js
|
|
56817
57137
|
class JsonFormatter {
|
|
56818
57138
|
constructor() {}
|
|
56819
57139
|
format(result) {
|
|
@@ -56821,7 +57141,7 @@ class JsonFormatter {
|
|
|
56821
57141
|
}
|
|
56822
57142
|
}
|
|
56823
57143
|
|
|
56824
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
57144
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/text.js
|
|
56825
57145
|
class TextFormatter {
|
|
56826
57146
|
constructor() {}
|
|
56827
57147
|
format(result) {
|
|
@@ -56835,7 +57155,7 @@ class TextFormatter {
|
|
|
56835
57155
|
}
|
|
56836
57156
|
}
|
|
56837
57157
|
|
|
56838
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
57158
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/host/builtins.js
|
|
56839
57159
|
function registerBuiltins(host, executor) {
|
|
56840
57160
|
const path9 = new PathEvaluator;
|
|
56841
57161
|
host.evaluators.register("regex", new RegexEvaluator, "builtin");
|
|
@@ -56875,7 +57195,7 @@ var init_builtins = __esm(() => {
|
|
|
56875
57195
|
init_tsdoc_export_evaluator();
|
|
56876
57196
|
});
|
|
56877
57197
|
|
|
56878
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
57198
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/host/rule-engine-host.js
|
|
56879
57199
|
class RuleEngineHost {
|
|
56880
57200
|
evaluators;
|
|
56881
57201
|
formatters;
|
|
@@ -56892,7 +57212,7 @@ var init_rule_engine_host = __esm(() => {
|
|
|
56892
57212
|
init_extension2();
|
|
56893
57213
|
});
|
|
56894
57214
|
|
|
56895
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
57215
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/engine.js
|
|
56896
57216
|
class RuleEngine {
|
|
56897
57217
|
host;
|
|
56898
57218
|
events;
|
|
@@ -57063,7 +57383,7 @@ var init_engine = __esm(() => {
|
|
|
57063
57383
|
init_types3();
|
|
57064
57384
|
});
|
|
57065
57385
|
|
|
57066
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
57386
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/host/bundled-rules.js
|
|
57067
57387
|
async function bundledRulesRoot() {
|
|
57068
57388
|
if (cachedRoot2 !== undefined)
|
|
57069
57389
|
return cachedRoot2;
|
|
@@ -57114,7 +57434,7 @@ var init_bundled_rules = __esm(() => {
|
|
|
57114
57434
|
init_dist5();
|
|
57115
57435
|
});
|
|
57116
57436
|
|
|
57117
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
57437
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/db-adapter.js
|
|
57118
57438
|
class DbRulePersistenceAdapter {
|
|
57119
57439
|
db;
|
|
57120
57440
|
constructor(db2) {
|
|
@@ -57148,7 +57468,7 @@ class DbRulePersistenceAdapter {
|
|
|
57148
57468
|
}
|
|
57149
57469
|
}
|
|
57150
57470
|
|
|
57151
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
57471
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/schema.js
|
|
57152
57472
|
var RULE_ENGINE_SCHEMA_SQL = `
|
|
57153
57473
|
CREATE TABLE IF NOT EXISTS rule_runs (
|
|
57154
57474
|
id TEXT PRIMARY KEY,
|
|
@@ -57194,10 +57514,10 @@ CREATE TABLE IF NOT EXISTS rule_eval_runs (
|
|
|
57194
57514
|
CREATE INDEX IF NOT EXISTS idx_rule_eval_runs_run_id ON rule_eval_runs (run_id);
|
|
57195
57515
|
`;
|
|
57196
57516
|
|
|
57197
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
57517
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/index.js
|
|
57198
57518
|
var init_persistence2 = () => {};
|
|
57199
57519
|
|
|
57200
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
57520
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.14+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/index.js
|
|
57201
57521
|
var init_dist10 = __esm(() => {
|
|
57202
57522
|
init_extensions();
|
|
57203
57523
|
init_loader2();
|
|
@@ -57396,7 +57716,7 @@ ${SYSTEM_EVENTS_SCHEMA_SQL}
|
|
|
57396
57716
|
];
|
|
57397
57717
|
});
|
|
57398
57718
|
|
|
57399
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
57719
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/job-queue/db-job-queue.js
|
|
57400
57720
|
function queueLogger() {
|
|
57401
57721
|
if (!_queueLogger)
|
|
57402
57722
|
_queueLogger = getLogger2("job-queue");
|
|
@@ -57624,7 +57944,7 @@ var init_db_job_queue = __esm(() => {
|
|
|
57624
57944
|
init_tracing2();
|
|
57625
57945
|
});
|
|
57626
57946
|
|
|
57627
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
57947
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/job-queue-db.js
|
|
57628
57948
|
var exports_job_queue_db = {};
|
|
57629
57949
|
__export(exports_job_queue_db, {
|
|
57630
57950
|
DBQueueConsumer: () => DBQueueConsumer,
|
|
@@ -57688,6 +58008,9 @@ function bumpStageSchemaMajor(version3) {
|
|
|
57688
58008
|
function bumpStageSchemaMinor(version3) {
|
|
57689
58009
|
return { major: version3.major, minor: version3.minor + 1 };
|
|
57690
58010
|
}
|
|
58011
|
+
function normalizeCapabilityTier(value) {
|
|
58012
|
+
return value === LEGACY_CAPABLE_ALIAS ? "capable-1" : value;
|
|
58013
|
+
}
|
|
57691
58014
|
function isTierEligible(candidateTier, minTier) {
|
|
57692
58015
|
return TIER_RANK[candidateTier] >= TIER_RANK[minTier];
|
|
57693
58016
|
}
|
|
@@ -57759,7 +58082,7 @@ function parseStageRecord(raw, consumerVersion = STAGE_REGISTRY_SCHEMA_VERSION)
|
|
|
57759
58082
|
function getCanonicalStage(idOrAlias) {
|
|
57760
58083
|
return CANONICAL_STAGE_BY_KEY.get(idOrAlias);
|
|
57761
58084
|
}
|
|
57762
|
-
var STAGE_REGISTRY_SCHEMA_VERSION, stageSchemaVersionSchema, AUTHORITY_LANES, MUTATION_CLASSES, EXECUTION_KINDS, inlineExecutionSchema, subprocessExecutionSchema, deterministicExecutionSchema, hitlExecutionSchema, irreversibleExecutionSchema, executionKindSchema, ARTIFACT_DIRECTIONS, stageArtifactSchema, stageGateSchema, stageRetryPolicySchema, stageModelPolicySchema, TIER_RANK, CONTEXT_LAYER_NAMES, stageContextLayerSchema, stageEventSchema, STAGE_ID_PATTERN, stageRecordSchema, StageRegistryError, REGISTERED_CANONICAL_STAGES, CANONICAL_STAGE_BY_KEY;
|
|
58085
|
+
var STAGE_REGISTRY_SCHEMA_VERSION, stageSchemaVersionSchema, AUTHORITY_LANES, MUTATION_CLASSES, EXECUTION_KINDS, inlineExecutionSchema, subprocessExecutionSchema, deterministicExecutionSchema, hitlExecutionSchema, irreversibleExecutionSchema, executionKindSchema, ARTIFACT_DIRECTIONS, stageArtifactSchema, stageGateSchema, stageRetryPolicySchema, CAPABILITY_TIERS, LEGACY_CAPABLE_ALIAS = "capable", capabilityTierSchema, stageModelPolicySchema, TIER_RANK, CONTEXT_LAYER_NAMES, stageContextLayerSchema, stageEventSchema, STAGE_ID_PATTERN, stageRecordSchema, StageRegistryError, REGISTERED_CANONICAL_STAGES, CANONICAL_STAGE_BY_KEY;
|
|
57763
58086
|
var init_schema4 = __esm(() => {
|
|
57764
58087
|
init_zod();
|
|
57765
58088
|
STAGE_REGISTRY_SCHEMA_VERSION = {
|
|
@@ -57833,10 +58156,12 @@ var init_schema4 = __esm(() => {
|
|
|
57833
58156
|
terminal_stop: exports_external.enum(["block", "escalate", "fail"]),
|
|
57834
58157
|
timeout_seconds: exports_external.number().int().positive().optional()
|
|
57835
58158
|
}).strict();
|
|
58159
|
+
CAPABILITY_TIERS = ["cheap", "standard", "capable-1", "capable-2", "capable-3"];
|
|
58160
|
+
capabilityTierSchema = exports_external.preprocess(normalizeCapabilityTier, exports_external.enum(CAPABILITY_TIERS));
|
|
57836
58161
|
stageModelPolicySchema = exports_external.object({
|
|
57837
|
-
min_tier:
|
|
58162
|
+
min_tier: capabilityTierSchema,
|
|
57838
58163
|
fallback: exports_external.array(exports_external.object({
|
|
57839
|
-
tier:
|
|
58164
|
+
tier: capabilityTierSchema,
|
|
57840
58165
|
trigger: exports_external.enum(["gate-fail", "timeout", "insufficient-evidence", "retry-exhausted"])
|
|
57841
58166
|
}).strict()),
|
|
57842
58167
|
override_key: exports_external.string().optional()
|
|
@@ -57844,7 +58169,9 @@ var init_schema4 = __esm(() => {
|
|
|
57844
58169
|
TIER_RANK = {
|
|
57845
58170
|
cheap: 1,
|
|
57846
58171
|
standard: 2,
|
|
57847
|
-
capable: 3
|
|
58172
|
+
"capable-1": 3,
|
|
58173
|
+
"capable-2": 4,
|
|
58174
|
+
"capable-3": 5
|
|
57848
58175
|
};
|
|
57849
58176
|
CONTEXT_LAYER_NAMES = [
|
|
57850
58177
|
"harness-policy",
|
|
@@ -57906,7 +58233,7 @@ var init_schema4 = __esm(() => {
|
|
|
57906
58233
|
retry: { max_attempts: 3, terminal_stop: "block" },
|
|
57907
58234
|
model_policy: {
|
|
57908
58235
|
min_tier: "standard",
|
|
57909
|
-
fallback: [{ tier: "capable", trigger: "gate-fail" }]
|
|
58236
|
+
fallback: [{ tier: "capable-2", trigger: "gate-fail" }]
|
|
57910
58237
|
},
|
|
57911
58238
|
context_layers: [],
|
|
57912
58239
|
observability: [],
|
|
@@ -57924,8 +58251,8 @@ var init_schema4 = __esm(() => {
|
|
|
57924
58251
|
mutation_class: "corpus",
|
|
57925
58252
|
retry: { max_attempts: 3, terminal_stop: "block" },
|
|
57926
58253
|
model_policy: {
|
|
57927
|
-
min_tier: "capable",
|
|
57928
|
-
fallback: []
|
|
58254
|
+
min_tier: "capable-2",
|
|
58255
|
+
fallback: [{ tier: "capable-3", trigger: "gate-fail" }]
|
|
57929
58256
|
},
|
|
57930
58257
|
context_layers: [],
|
|
57931
58258
|
observability: [],
|
|
@@ -57945,8 +58272,8 @@ var init_schema4 = __esm(() => {
|
|
|
57945
58272
|
model_policy: {
|
|
57946
58273
|
min_tier: "standard",
|
|
57947
58274
|
fallback: [
|
|
57948
|
-
{ tier: "capable", trigger: "gate-fail" },
|
|
57949
|
-
{ tier: "capable", trigger: "timeout" }
|
|
58275
|
+
{ tier: "capable-1", trigger: "gate-fail" },
|
|
58276
|
+
{ tier: "capable-1", trigger: "timeout" }
|
|
57950
58277
|
]
|
|
57951
58278
|
},
|
|
57952
58279
|
context_layers: [],
|
|
@@ -57966,7 +58293,7 @@ var init_schema4 = __esm(() => {
|
|
|
57966
58293
|
retry: { max_attempts: 3, terminal_stop: "block" },
|
|
57967
58294
|
model_policy: {
|
|
57968
58295
|
min_tier: "standard",
|
|
57969
|
-
fallback: [{ tier: "capable", trigger: "gate-fail" }]
|
|
58296
|
+
fallback: [{ tier: "capable-1", trigger: "gate-fail" }]
|
|
57970
58297
|
},
|
|
57971
58298
|
context_layers: [],
|
|
57972
58299
|
observability: [],
|
|
@@ -57984,7 +58311,7 @@ var init_schema4 = __esm(() => {
|
|
|
57984
58311
|
mutation_class: "verdict",
|
|
57985
58312
|
retry: { max_attempts: 2, terminal_stop: "escalate" },
|
|
57986
58313
|
model_policy: {
|
|
57987
|
-
min_tier: "capable",
|
|
58314
|
+
min_tier: "capable-1",
|
|
57988
58315
|
fallback: []
|
|
57989
58316
|
},
|
|
57990
58317
|
context_layers: [],
|
|
@@ -58004,7 +58331,7 @@ var init_schema4 = __esm(() => {
|
|
|
58004
58331
|
retry: { max_attempts: 2, terminal_stop: "block" },
|
|
58005
58332
|
model_policy: {
|
|
58006
58333
|
min_tier: "standard",
|
|
58007
|
-
fallback: [{ tier: "capable", trigger: "gate-fail" }]
|
|
58334
|
+
fallback: [{ tier: "capable-1", trigger: "gate-fail" }]
|
|
58008
58335
|
},
|
|
58009
58336
|
context_layers: [],
|
|
58010
58337
|
observability: [],
|
|
@@ -58023,7 +58350,7 @@ var init_schema4 = __esm(() => {
|
|
|
58023
58350
|
retry: { max_attempts: 2, terminal_stop: "block" },
|
|
58024
58351
|
model_policy: {
|
|
58025
58352
|
min_tier: "standard",
|
|
58026
|
-
fallback: [{ tier: "capable", trigger: "gate-fail" }]
|
|
58353
|
+
fallback: [{ tier: "capable-1", trigger: "gate-fail" }]
|
|
58027
58354
|
},
|
|
58028
58355
|
context_layers: [],
|
|
58029
58356
|
observability: [],
|
|
@@ -58041,7 +58368,7 @@ var init_schema4 = __esm(() => {
|
|
|
58041
58368
|
mutation_class: "driver",
|
|
58042
58369
|
retry: { max_attempts: 3, terminal_stop: "block" },
|
|
58043
58370
|
model_policy: {
|
|
58044
|
-
min_tier: "capable",
|
|
58371
|
+
min_tier: "capable-1",
|
|
58045
58372
|
fallback: []
|
|
58046
58373
|
},
|
|
58047
58374
|
context_layers: [],
|
|
@@ -59297,6 +59624,9 @@ var init_schema6 = __esm(() => {
|
|
|
59297
59624
|
name: exports_external.string().min(1, "name is required"),
|
|
59298
59625
|
background: exports_external.string().optional(),
|
|
59299
59626
|
requirements: exports_external.string().optional(),
|
|
59627
|
+
design: exports_external.string().optional(),
|
|
59628
|
+
plan: exports_external.string().optional(),
|
|
59629
|
+
acceptance_criteria: exports_external.string().optional(),
|
|
59300
59630
|
feature_id: featureId,
|
|
59301
59631
|
parent_wbs: wbsString,
|
|
59302
59632
|
priority: exports_external.enum(PRIORITIES).optional(),
|
|
@@ -59674,6 +60004,7 @@ __export(exports_src, {
|
|
|
59674
60004
|
normalizeTaskStatusSafe: () => normalizeTaskStatusSafe,
|
|
59675
60005
|
normalizeTaskStatus: () => normalizeTaskStatus,
|
|
59676
60006
|
normalizeFeatureStatus: () => normalizeFeatureStatus,
|
|
60007
|
+
normalizeCapabilityTier: () => normalizeCapabilityTier,
|
|
59677
60008
|
mergeStubs: () => mergeStubs,
|
|
59678
60009
|
matrixEntrySchema: () => matrixEntrySchema,
|
|
59679
60010
|
matchEtlPayloads: () => matchEtlPayloads,
|
|
@@ -59726,6 +60057,7 @@ __export(exports_src, {
|
|
|
59726
60057
|
cleanupTempFiles: () => cleanupTempFiles,
|
|
59727
60058
|
checkLayerStale: () => checkLayerStale,
|
|
59728
60059
|
checkAcCoverage: () => checkAcCoverage,
|
|
60060
|
+
capabilityTierSchema: () => capabilityTierSchema,
|
|
59729
60061
|
canonicalJson: () => canonicalJson,
|
|
59730
60062
|
cacheHitRatio: () => cacheHitRatio,
|
|
59731
60063
|
bumpStageSchemaMinor: () => bumpStageSchemaMinor,
|
|
@@ -59779,6 +60111,7 @@ __export(exports_src, {
|
|
|
59779
60111
|
MarkdownDocument: () => MarkdownDocument,
|
|
59780
60112
|
MUTATION_CLASSES: () => MUTATION_CLASSES,
|
|
59781
60113
|
MODEL_PRICING: () => MODEL_PRICING,
|
|
60114
|
+
LEGACY_CAPABLE_ALIAS: () => LEGACY_CAPABLE_ALIAS,
|
|
59782
60115
|
InlineContext: () => InlineContext,
|
|
59783
60116
|
InboxRecentDao: () => InboxRecentDao,
|
|
59784
60117
|
InboxMessageDao: () => InboxMessageDao,
|
|
@@ -59796,6 +60129,7 @@ __export(exports_src, {
|
|
|
59796
60129
|
CLI_SCHEMA_SQL: () => CLI_SCHEMA_SQL,
|
|
59797
60130
|
CLI_MIGRATION_FILE_MARKER: () => CLI_MIGRATION_FILE_MARKER,
|
|
59798
60131
|
CLI_MIGRATIONS: () => CLI_MIGRATIONS,
|
|
60132
|
+
CAPABILITY_TIERS: () => CAPABILITY_TIERS,
|
|
59799
60133
|
CACHEABILITY_CLASSES: () => CACHEABILITY_CLASSES,
|
|
59800
60134
|
ArtifactDao: () => ArtifactDao,
|
|
59801
60135
|
ActionRunDao: () => ActionRunDao,
|
|
@@ -59881,7 +60215,10 @@ class AgentService {
|
|
|
59881
60215
|
return results.some((result) => !result.usable && result.tier === 1) ? 1 : 0;
|
|
59882
60216
|
}
|
|
59883
60217
|
async run(prompt, flags, deps) {
|
|
59884
|
-
const outcome = await this.executeRun(prompt, flags, deps, {
|
|
60218
|
+
const outcome = await this.executeRun(prompt, flags, deps, {
|
|
60219
|
+
silent: false,
|
|
60220
|
+
execution: this.defaultExecutionOptions(flags)
|
|
60221
|
+
});
|
|
59885
60222
|
if (!outcome.ok) {
|
|
59886
60223
|
this.ctx.output.error(outcome.message);
|
|
59887
60224
|
return outcome.exitCode;
|
|
@@ -59913,8 +60250,12 @@ class AgentService {
|
|
|
59913
60250
|
stderr: result.stderr
|
|
59914
60251
|
};
|
|
59915
60252
|
}
|
|
59916
|
-
async runTraced(prompt, flags, deps) {
|
|
59917
|
-
const outcome = await this.executeRun(prompt, flags, deps, {
|
|
60253
|
+
async runTraced(prompt, flags, deps, execution) {
|
|
60254
|
+
const outcome = await this.executeRun(prompt, flags, deps, {
|
|
60255
|
+
silent: true,
|
|
60256
|
+
nonInteractive: true,
|
|
60257
|
+
execution: execution ?? this.defaultExecutionOptions(flags)
|
|
60258
|
+
});
|
|
59918
60259
|
if (!outcome.ok) {
|
|
59919
60260
|
return { exitCode: outcome.exitCode, stdout: "", message: outcome.message };
|
|
59920
60261
|
}
|
|
@@ -60023,22 +60364,59 @@ class AgentService {
|
|
|
60023
60364
|
let result;
|
|
60024
60365
|
const controller = new AbortController;
|
|
60025
60366
|
const onTerminate = () => controller.abort();
|
|
60367
|
+
const onExternalAbort = () => controller.abort();
|
|
60368
|
+
const lifecycle = new AgentExecutionLifecycle(options.execution?.observer, options.execution?.correlation, configuredSecretValues(this.ctx.env), options.execution?.heartbeatMs);
|
|
60369
|
+
lifecycle.start({
|
|
60370
|
+
agent,
|
|
60371
|
+
...model !== undefined ? { model } : {},
|
|
60372
|
+
invocation: `${invocation.command} ${invocation.argv.join(" ")}`,
|
|
60373
|
+
...timeoutMs !== undefined ? { timeoutMs } : {}
|
|
60374
|
+
});
|
|
60375
|
+
const dispatchStartedAt = Date.now();
|
|
60026
60376
|
try {
|
|
60027
60377
|
process.on("SIGTERM", onTerminate);
|
|
60028
60378
|
process.on("SIGINT", onTerminate);
|
|
60379
|
+
options.execution?.signal?.addEventListener("abort", onExternalAbort, { once: true });
|
|
60380
|
+
if (options.execution?.signal?.aborted === true)
|
|
60381
|
+
controller.abort();
|
|
60029
60382
|
result = await runner.runPromptCommand(agent, promptOptions, {
|
|
60030
60383
|
cwd: cwd || undefined,
|
|
60031
60384
|
...timeoutMs !== undefined ? { timeout: timeoutMs } : {},
|
|
60032
|
-
signal: controller.signal
|
|
60385
|
+
signal: controller.signal,
|
|
60386
|
+
correlation: lifecycle.identity,
|
|
60387
|
+
onOutput: (output2) => lifecycle.observe(output2)
|
|
60033
60388
|
});
|
|
60034
60389
|
} catch (error51) {
|
|
60390
|
+
lifecycle.finish({
|
|
60391
|
+
exitCode: null,
|
|
60392
|
+
durationMs: Date.now() - dispatchStartedAt,
|
|
60393
|
+
...controller.signal.aborted ? { reason: "cancelled" } : {},
|
|
60394
|
+
...!controller.signal.aborted ? { reason: error51 instanceof Error ? error51.message : String(error51) } : {}
|
|
60395
|
+
});
|
|
60035
60396
|
return { ok: false, exitCode: 2, message: error51 instanceof Error ? error51.message : String(error51) };
|
|
60036
60397
|
} finally {
|
|
60037
60398
|
process.off("SIGTERM", onTerminate);
|
|
60038
60399
|
process.off("SIGINT", onTerminate);
|
|
60400
|
+
options.execution?.signal?.removeEventListener("abort", onExternalAbort);
|
|
60039
60401
|
}
|
|
60402
|
+
lifecycle.finish({
|
|
60403
|
+
exitCode: result.exitCode,
|
|
60404
|
+
durationMs: result.durationMs,
|
|
60405
|
+
...result.signal !== undefined ? { signal: result.signal } : {},
|
|
60406
|
+
...controller.signal.aborted && result.signal === undefined ? { reason: "cancelled" } : {}
|
|
60407
|
+
});
|
|
60040
60408
|
return { ok: true, result, invocation };
|
|
60041
60409
|
}
|
|
60410
|
+
defaultExecutionOptions(flags) {
|
|
60411
|
+
const runId = stringFlag(flags, "run-id", "") || crypto.randomUUID();
|
|
60412
|
+
const observer = this.ctx.events === undefined ? undefined : (event) => {
|
|
60413
|
+
this.ctx.events?.emit("agent.execution", event);
|
|
60414
|
+
};
|
|
60415
|
+
return {
|
|
60416
|
+
correlation: { runId, executionId: crypto.randomUUID() },
|
|
60417
|
+
...observer !== undefined ? { observer } : {}
|
|
60418
|
+
};
|
|
60419
|
+
}
|
|
60042
60420
|
hasWarnedDeprecation = false;
|
|
60043
60421
|
warnDeprecationOnce(message) {
|
|
60044
60422
|
if (!this.hasWarnedDeprecation) {
|
|
@@ -60050,7 +60428,7 @@ class AgentService {
|
|
|
60050
60428
|
const raw = stringFlag(flags, "agent", "auto");
|
|
60051
60429
|
if (raw === "auto")
|
|
60052
60430
|
return this.resolveAgentAuto(prompt, flags, doctorRunner);
|
|
60053
|
-
return this.
|
|
60431
|
+
return this.resolveExecutorSelector(raw, doctorRunner, "explicit");
|
|
60054
60432
|
}
|
|
60055
60433
|
async resolveAgentAuto(prompt, flags, doctorRunner) {
|
|
60056
60434
|
const config4 = this.ctx.agentConfig;
|
|
@@ -60175,16 +60553,6 @@ class AgentService {
|
|
|
60175
60553
|
return usable.result;
|
|
60176
60554
|
return { ok: true, agent: canonical, source };
|
|
60177
60555
|
}
|
|
60178
|
-
async resolveAgentExplicit(name, doctorRunner, source) {
|
|
60179
|
-
const canonical = resolveAgentName(name);
|
|
60180
|
-
if (canonical === undefined) {
|
|
60181
|
-
return { ok: false, exitCode: 2, message: `Unknown agent: ${name}` };
|
|
60182
|
-
}
|
|
60183
|
-
const usable = await this.checkUsable(canonical, doctorRunner);
|
|
60184
|
-
if (!usable.ok)
|
|
60185
|
-
return usable.result;
|
|
60186
|
-
return { ok: true, agent: canonical, source };
|
|
60187
|
-
}
|
|
60188
60556
|
async checkUsable(canonical, doctorRunner) {
|
|
60189
60557
|
const result = await doctorRunner.runOne(canonical);
|
|
60190
60558
|
if (!result.installed) {
|
|
@@ -60354,13 +60722,15 @@ function parseTagsFlag(flags) {
|
|
|
60354
60722
|
return tags.length > 0 ? tags : undefined;
|
|
60355
60723
|
}
|
|
60356
60724
|
function getExecutorTier(executor) {
|
|
60357
|
-
if (executor.tier)
|
|
60358
|
-
|
|
60725
|
+
if (executor.tier) {
|
|
60726
|
+
const declared = executor.tier;
|
|
60727
|
+
return declared === "capable" ? "capable-1" : declared;
|
|
60728
|
+
}
|
|
60359
60729
|
const combined = `${executor.name} ${executor.model ?? ""} ${executor.agent}`.toLowerCase();
|
|
60360
60730
|
if (/\b(cheap|haiku|flash|lite|mini|fast)\b/.test(combined))
|
|
60361
60731
|
return "cheap";
|
|
60362
60732
|
if (/\b(capable|opus|pro|sonnet|r1|o1|o3|expert)\b/.test(combined))
|
|
60363
|
-
return "capable";
|
|
60733
|
+
return "capable-1";
|
|
60364
60734
|
return "standard";
|
|
60365
60735
|
}
|
|
60366
60736
|
var TRACE_SAFE_SLASH_COMMAND, TRACE_SAFE_SLASH_TOKEN, SENSITIVE_FLAG, SENSITIVE_INLINE_FLAG;
|
|
@@ -60368,6 +60738,7 @@ var init_agent_service = __esm(() => {
|
|
|
60368
60738
|
init_src2();
|
|
60369
60739
|
init_dist9();
|
|
60370
60740
|
init_dist5();
|
|
60741
|
+
init_agent_execution();
|
|
60371
60742
|
TRACE_SAFE_SLASH_COMMAND = /^(?:\/skill:(?:sp|rd3)-|\/(?:sp|rd3)[:-]|\$(?:sp|rd3)-)[A-Za-z0-9._-]+(?:\s|$)/;
|
|
60372
60743
|
TRACE_SAFE_SLASH_TOKEN = /^(?:\d{4}|--(?:auto|next|force|bdd)|--(?:mode|fix|focus)|implement|test|review|verify|all|none|blockers-first|quick|requirements|background|constraints|acceptance)$/;
|
|
60373
60744
|
SENSITIVE_FLAG = /^--?(?:api[-_]?key|authorization|credential|password|secret|token)$/i;
|
|
@@ -60902,12 +61273,23 @@ function evaluateDoneTransition(input) {
|
|
|
60902
61273
|
if (targetStatus === currentStatus) {
|
|
60903
61274
|
return { kind: "noop", fromStatus: currentStatus, message: formatNoopMessage(wbs, currentStatus) };
|
|
60904
61275
|
}
|
|
60905
|
-
if (artifact === undefined) {
|
|
60906
|
-
return { kind: "allow", reason: "no-artifact" };
|
|
60907
|
-
}
|
|
60908
61276
|
if (forced) {
|
|
60909
61277
|
return { kind: "allow", reason: "forced" };
|
|
60910
61278
|
}
|
|
61279
|
+
if (artifact === undefined) {
|
|
61280
|
+
const verdictPath2 = `.spur/run/${wbs}-verdict.json`;
|
|
61281
|
+
return {
|
|
61282
|
+
kind: "deny",
|
|
61283
|
+
verdict: "UNKNOWN",
|
|
61284
|
+
message: [
|
|
61285
|
+
`Cannot transition task ${wbs} to done: missing verify verdict artifact.`,
|
|
61286
|
+
` task: ${taskFilePath}`,
|
|
61287
|
+
` verdict: ${verdictPath2} (not found)`,
|
|
61288
|
+
` remediation: re-run \`/sp:dev-verify ${wbs}\` until PASS (writes the artifact), ` + `or override with \`spur task update ${wbs} done --force-done --reason "<why>"\`.`
|
|
61289
|
+
].join(`
|
|
61290
|
+
`)
|
|
61291
|
+
};
|
|
61292
|
+
}
|
|
60911
61293
|
const computed = computeAggregate(artifact);
|
|
60912
61294
|
const effective = harshnessMax(artifact.verdict, computed);
|
|
60913
61295
|
if (effective === "PASS") {
|
|
@@ -61176,10 +61558,22 @@ var init_planning_check_base = __esm(() => {
|
|
|
61176
61558
|
// ../../packages/app/src/services/feature-check.ts
|
|
61177
61559
|
var exports_feature_check = {};
|
|
61178
61560
|
__export(exports_feature_check, {
|
|
61561
|
+
defaultVerdictRunDir: () => defaultVerdictRunDir,
|
|
61179
61562
|
FeatureCheckService: () => FeatureCheckService,
|
|
61180
61563
|
DEFAULT_FEATURE_MATRIX: () => DEFAULT_FEATURE_MATRIX
|
|
61181
61564
|
});
|
|
61182
61565
|
import { dirname as dirname8, join as join7 } from "path";
|
|
61566
|
+
function defaultVerdictRunDir(tasksDir) {
|
|
61567
|
+
const norm = tasksDir.replace(/\\/g, "/");
|
|
61568
|
+
if (/\/docs\/tasks\d*$/.test(norm) || /\/docs\/tasks$/.test(norm)) {
|
|
61569
|
+
return join7(dirname8(dirname8(tasksDir)), ".spur", "run");
|
|
61570
|
+
}
|
|
61571
|
+
return join7(dirname8(tasksDir), ".spur", "run");
|
|
61572
|
+
}
|
|
61573
|
+
function rowMatchesScenario(id, sc) {
|
|
61574
|
+
const stripped = id.replace(/^Scenario:\s*/i, "").trim();
|
|
61575
|
+
return normalizeTitle(id) === sc.normalized || normalizeTitle(stripped) === sc.normalized || id === sc.alias || stripped === sc.alias;
|
|
61576
|
+
}
|
|
61183
61577
|
var DEFAULT_FEATURE_MATRIX, FeatureCheckService;
|
|
61184
61578
|
var init_feature_check = __esm(() => {
|
|
61185
61579
|
init_src2();
|
|
@@ -61245,7 +61639,8 @@ var init_feature_check = __esm(() => {
|
|
|
61245
61639
|
await this.checkChildrenLimit(featureId2, options.featuresDir, findings);
|
|
61246
61640
|
}
|
|
61247
61641
|
const dogfoodDir = options?.dogfoodDir ?? (options?.featuresDir ? join7(dirname8(options.featuresDir), "dogfood") : undefined);
|
|
61248
|
-
|
|
61642
|
+
const runDir = options?.runDir ?? (options?.tasksDir ? defaultVerdictRunDir(options.tasksDir) : undefined);
|
|
61643
|
+
await this.runL4(doc2, featureId2, status, options?.tasksDir, dogfoodDir, runDir, findings);
|
|
61249
61644
|
return { id: featureId2, ...this.summarizeWithStatus(status, findings, strict, options?.severityOverrides) };
|
|
61250
61645
|
}
|
|
61251
61646
|
runL3(doc2, findings) {
|
|
@@ -61377,13 +61772,14 @@ var init_feature_check = __esm(() => {
|
|
|
61377
61772
|
});
|
|
61378
61773
|
}
|
|
61379
61774
|
}
|
|
61380
|
-
async runL4(doc2, featureId2, status, tasksDir, dogfoodDir, findings) {
|
|
61775
|
+
async runL4(doc2, featureId2, status, tasksDir, dogfoodDir, runDir, findings) {
|
|
61381
61776
|
if (tasksDir === undefined)
|
|
61382
61777
|
return;
|
|
61383
61778
|
let linkedTasks = 0;
|
|
61384
61779
|
const incompleteTasks = [];
|
|
61385
61780
|
const linkedTaskAc = [];
|
|
61386
61781
|
const linkedTaskSolutions = [];
|
|
61782
|
+
const linkedTaskRecords = [];
|
|
61387
61783
|
try {
|
|
61388
61784
|
const entries = await this.fs.readDir(tasksDir);
|
|
61389
61785
|
for (const entry of entries) {
|
|
@@ -61398,13 +61794,15 @@ var init_feature_check = __esm(() => {
|
|
|
61398
61794
|
continue;
|
|
61399
61795
|
linkedTasks += 1;
|
|
61400
61796
|
const tStatus = tfm.status ?? "backlog";
|
|
61797
|
+
const wbs = entry.match(/^(\d{4})_/)?.[1] ?? entry;
|
|
61401
61798
|
if (tStatus !== "done" && tStatus !== "cancelled") {
|
|
61402
|
-
incompleteTasks.push(
|
|
61799
|
+
incompleteTasks.push(wbs);
|
|
61403
61800
|
}
|
|
61404
61801
|
const tac = stripAcFence(taskDoc.getSection("Acceptance Criteria") ?? "");
|
|
61405
61802
|
if (tac.trim().length > 0)
|
|
61406
61803
|
linkedTaskAc.push(tac);
|
|
61407
61804
|
linkedTaskSolutions.push(taskDoc.getSection("Solution") ?? "");
|
|
61805
|
+
linkedTaskRecords.push({ wbs, status: tStatus, ac: tac });
|
|
61408
61806
|
} catch {
|
|
61409
61807
|
findings.push({
|
|
61410
61808
|
layer: "L4",
|
|
@@ -61446,6 +61844,7 @@ var init_feature_check = __esm(() => {
|
|
|
61446
61844
|
});
|
|
61447
61845
|
}
|
|
61448
61846
|
}
|
|
61847
|
+
await this.checkScenarioSatisfaction(acBody, linkedTaskRecords, runDir, findings);
|
|
61449
61848
|
if (status === "verifying" && incompleteTasks.length > 0) {
|
|
61450
61849
|
findings.push({
|
|
61451
61850
|
layer: "L4",
|
|
@@ -61481,9 +61880,152 @@ var init_feature_check = __esm(() => {
|
|
|
61481
61880
|
}
|
|
61482
61881
|
}
|
|
61483
61882
|
}
|
|
61883
|
+
async checkScenarioSatisfaction(featureAc, linkedTasks, runDir, findings) {
|
|
61884
|
+
if (linkedTasks.length === 0 || runDir === undefined)
|
|
61885
|
+
return;
|
|
61886
|
+
const parsed = parseFeature(featureAc);
|
|
61887
|
+
if (parsed === null)
|
|
61888
|
+
return;
|
|
61889
|
+
if (parsed.scenarios.length === 0)
|
|
61890
|
+
return;
|
|
61891
|
+
const scenarioAliases = parsed.scenarios.map((s, i2) => ({
|
|
61892
|
+
title: s.name,
|
|
61893
|
+
normalized: normalizeTitle(s.name),
|
|
61894
|
+
alias: `AC-${i2 + 1}`
|
|
61895
|
+
}));
|
|
61896
|
+
const covers = {};
|
|
61897
|
+
for (const sc of scenarioAliases) {
|
|
61898
|
+
const linked = [];
|
|
61899
|
+
for (const task of linkedTasks) {
|
|
61900
|
+
const taskCov = checkAcCoverage(`Feature: x
|
|
61901
|
+
Scenario: ${sc.title}
|
|
61902
|
+
Given x`, task.ac);
|
|
61903
|
+
if (!taskCov.orphans.includes(sc.title)) {
|
|
61904
|
+
linked.push({ wbs: task.wbs, status: task.status });
|
|
61905
|
+
}
|
|
61906
|
+
}
|
|
61907
|
+
covers[sc.title] = linked;
|
|
61908
|
+
}
|
|
61909
|
+
for (const sc of scenarioAliases) {
|
|
61910
|
+
const linked = covers[sc.title] ?? [];
|
|
61911
|
+
if (linked.length === 0)
|
|
61912
|
+
continue;
|
|
61913
|
+
const verified = await this.isScenarioVerified(sc, linked, runDir);
|
|
61914
|
+
if (!verified) {
|
|
61915
|
+
findings.push({
|
|
61916
|
+
layer: "L4",
|
|
61917
|
+
code: FINDING_CODES.L4_SCENARIO_UNVERIFIED,
|
|
61918
|
+
severity: "warning",
|
|
61919
|
+
section: "Acceptance Criteria",
|
|
61920
|
+
message: `Feature scenario "${sc.title}" is linked but unverified: covering task(s) ` + `${linked.map((l) => l.wbs).join(", ")} have no PASS verdict with MET requirement`
|
|
61921
|
+
});
|
|
61922
|
+
}
|
|
61923
|
+
}
|
|
61924
|
+
}
|
|
61925
|
+
async isScenarioVerified(sc, linked, runDir) {
|
|
61926
|
+
for (const task of linked) {
|
|
61927
|
+
if (task.status !== "done")
|
|
61928
|
+
continue;
|
|
61929
|
+
const artifact = await this.readVerdictArtifact(runDir, task.wbs);
|
|
61930
|
+
if (artifact === null)
|
|
61931
|
+
continue;
|
|
61932
|
+
if (artifact.verdict !== "PASS")
|
|
61933
|
+
continue;
|
|
61934
|
+
const rows = [...artifact.requirements, ...artifact.acceptanceCriteria];
|
|
61935
|
+
const matched = rows.find((r) => rowMatchesScenario(r.id, sc));
|
|
61936
|
+
if (matched !== undefined && matched.status === "MET")
|
|
61937
|
+
return true;
|
|
61938
|
+
}
|
|
61939
|
+
return false;
|
|
61940
|
+
}
|
|
61941
|
+
async readVerdictArtifact(runDir, wbs) {
|
|
61942
|
+
try {
|
|
61943
|
+
const raw = await this.fs.readFile(join7(runDir, `${wbs}-verdict.json`));
|
|
61944
|
+
const parsed = JSON.parse(raw);
|
|
61945
|
+
if (typeof parsed.verdict !== "string")
|
|
61946
|
+
return null;
|
|
61947
|
+
const pickRows = (arr) => (arr ?? []).filter((r) => typeof r?.id === "string" && typeof r?.status === "string").map((r) => ({ id: r.id, status: r.status }));
|
|
61948
|
+
const requirements = pickRows(parsed.requirements);
|
|
61949
|
+
const acceptanceCriteria = pickRows(parsed.acceptanceCriteria);
|
|
61950
|
+
if (requirements.length === 0 && acceptanceCriteria.length === 0)
|
|
61951
|
+
return null;
|
|
61952
|
+
return { verdict: parsed.verdict, requirements, acceptanceCriteria };
|
|
61953
|
+
} catch {
|
|
61954
|
+
return null;
|
|
61955
|
+
}
|
|
61956
|
+
}
|
|
61484
61957
|
};
|
|
61485
61958
|
});
|
|
61486
61959
|
|
|
61960
|
+
// ../../packages/app/src/services/task-locator.ts
|
|
61961
|
+
import { resolve as resolvePath5 } from "path";
|
|
61962
|
+
async function readDirIfPresent(fs3, dir) {
|
|
61963
|
+
try {
|
|
61964
|
+
return await fs3.readDir(dir);
|
|
61965
|
+
} catch (error51) {
|
|
61966
|
+
const code = error51.code;
|
|
61967
|
+
if (code === "ENOENT" || code === "ENOTDIR")
|
|
61968
|
+
return [];
|
|
61969
|
+
throw error51;
|
|
61970
|
+
}
|
|
61971
|
+
}
|
|
61972
|
+
|
|
61973
|
+
class TaskLocator {
|
|
61974
|
+
fs;
|
|
61975
|
+
dirs;
|
|
61976
|
+
constructor(source) {
|
|
61977
|
+
this.fs = source.fs;
|
|
61978
|
+
if ("dirs" in source) {
|
|
61979
|
+
this.dirs = [...new Set(source.dirs)];
|
|
61980
|
+
return;
|
|
61981
|
+
}
|
|
61982
|
+
const folderKeys = source.foldersConfig ? Object.keys(source.foldersConfig.folders) : [];
|
|
61983
|
+
this.dirs = [...new Set([source.tasksDir, ...folderKeys.map((key) => source.fs.resolve(key))])];
|
|
61984
|
+
}
|
|
61985
|
+
static forSingleDir(fs3, dir) {
|
|
61986
|
+
return new TaskLocator({ fs: fs3, tasksDir: dir });
|
|
61987
|
+
}
|
|
61988
|
+
static forDirs(fs3, dirs) {
|
|
61989
|
+
return new TaskLocator({ fs: fs3, dirs });
|
|
61990
|
+
}
|
|
61991
|
+
folderDirs() {
|
|
61992
|
+
return this.dirs;
|
|
61993
|
+
}
|
|
61994
|
+
async findByWbs(wbs) {
|
|
61995
|
+
const prefix = `${wbs}_`;
|
|
61996
|
+
for (const dir of this.folderDirs()) {
|
|
61997
|
+
for (const name of await readDirIfPresent(this.fs, dir)) {
|
|
61998
|
+
if (name.startsWith(prefix) && name.endsWith(".md")) {
|
|
61999
|
+
return { wbs, name, filePath: `${dir}/${name}` };
|
|
62000
|
+
}
|
|
62001
|
+
}
|
|
62002
|
+
}
|
|
62003
|
+
return null;
|
|
62004
|
+
}
|
|
62005
|
+
async findPathByWbs(wbs) {
|
|
62006
|
+
return (await this.findByWbs(wbs))?.filePath ?? null;
|
|
62007
|
+
}
|
|
62008
|
+
async exactMatch(target) {
|
|
62009
|
+
const normalized = resolvePath5(target);
|
|
62010
|
+
for (const dir of this.folderDirs()) {
|
|
62011
|
+
for (const name of await readDirIfPresent(this.fs, dir)) {
|
|
62012
|
+
const captured = TASK_FILENAME_RE.exec(name);
|
|
62013
|
+
if (captured === null)
|
|
62014
|
+
continue;
|
|
62015
|
+
const filePath = `${dir}/${name}`;
|
|
62016
|
+
if (resolvePath5(filePath) === normalized) {
|
|
62017
|
+
return { wbs: captured[1], name, filePath };
|
|
62018
|
+
}
|
|
62019
|
+
}
|
|
62020
|
+
}
|
|
62021
|
+
return null;
|
|
62022
|
+
}
|
|
62023
|
+
}
|
|
62024
|
+
var TASK_FILENAME_RE;
|
|
62025
|
+
var init_task_locator = __esm(() => {
|
|
62026
|
+
TASK_FILENAME_RE = /^(\d{4})_(.+)\.md$/;
|
|
62027
|
+
});
|
|
62028
|
+
|
|
61487
62029
|
// ../../packages/app/src/services/feature-service.ts
|
|
61488
62030
|
function stripLeadingSectionHeader(body, sectionName) {
|
|
61489
62031
|
const match = body.match(/^(\s*)#{1,6}\s+(.+?)\s*(?:\n|$)/);
|
|
@@ -61674,7 +62216,8 @@ class FeatureService {
|
|
|
61674
62216
|
const checkSvc = new FeatureCheckService(this.ctx.fs);
|
|
61675
62217
|
const res = await checkSvc.check(feature.filePath, featureId2, {
|
|
61676
62218
|
featuresDir: this.ctx.featuresDir,
|
|
61677
|
-
tasksDir: this.ctx.tasksDir
|
|
62219
|
+
tasksDir: this.ctx.tasksDir,
|
|
62220
|
+
runDir: defaultVerdictRunDir(this.ctx.tasksDir)
|
|
61678
62221
|
});
|
|
61679
62222
|
const l4Errors = res.findings.filter((f) => f.layer === "L4" && f.severity === "error");
|
|
61680
62223
|
return { pass: l4Errors.length === 0, findings: res.findings };
|
|
@@ -61798,36 +62341,45 @@ class FeatureService {
|
|
|
61798
62341
|
results
|
|
61799
62342
|
};
|
|
61800
62343
|
}
|
|
62344
|
+
taskLocator() {
|
|
62345
|
+
return new TaskLocator({
|
|
62346
|
+
fs: this.ctx.fs,
|
|
62347
|
+
tasksDir: this.ctx.tasksDir,
|
|
62348
|
+
foldersConfig: this.ctx.foldersConfig
|
|
62349
|
+
});
|
|
62350
|
+
}
|
|
61801
62351
|
async collectTasksByFeature() {
|
|
61802
62352
|
const byFeature = new Map;
|
|
61803
|
-
|
|
61804
|
-
|
|
61805
|
-
names = await this.ctx.fs.readDir(this.ctx.tasksDir);
|
|
61806
|
-
} catch {
|
|
61807
|
-
return byFeature;
|
|
61808
|
-
}
|
|
61809
|
-
for (const name of names) {
|
|
61810
|
-
if (!/^\d{4}_.+\.md$/.test(name))
|
|
61811
|
-
continue;
|
|
61812
|
-
const wbs = name.match(/^(\d{4})_/)?.[1];
|
|
61813
|
-
if (!wbs)
|
|
61814
|
-
continue;
|
|
62353
|
+
for (const dir of this.taskLocator().folderDirs()) {
|
|
62354
|
+
let names;
|
|
61815
62355
|
try {
|
|
61816
|
-
|
|
61817
|
-
|
|
61818
|
-
|
|
61819
|
-
|
|
61820
|
-
|
|
62356
|
+
names = await this.ctx.fs.readDir(dir);
|
|
62357
|
+
} catch {
|
|
62358
|
+
continue;
|
|
62359
|
+
}
|
|
62360
|
+
for (const name of names) {
|
|
62361
|
+
if (!/^\d{4}_.+\.md$/.test(name))
|
|
61821
62362
|
continue;
|
|
61822
|
-
const
|
|
61823
|
-
|
|
61824
|
-
|
|
61825
|
-
|
|
61826
|
-
|
|
61827
|
-
|
|
61828
|
-
|
|
61829
|
-
|
|
61830
|
-
|
|
62363
|
+
const wbs = name.match(/^(\d{4})_/)?.[1];
|
|
62364
|
+
if (!wbs)
|
|
62365
|
+
continue;
|
|
62366
|
+
try {
|
|
62367
|
+
const raw = await this.ctx.fs.readFile(`${dir}/${name}`);
|
|
62368
|
+
const doc2 = MarkdownDocument.parse(raw, "task");
|
|
62369
|
+
const fm = doc2.frontmatterData ?? {};
|
|
62370
|
+
const fid = fm.feature_id ?? fm["feature-id"];
|
|
62371
|
+
if (fid === undefined)
|
|
62372
|
+
continue;
|
|
62373
|
+
const row = {
|
|
62374
|
+
wbs,
|
|
62375
|
+
name: fm.name ?? wbs,
|
|
62376
|
+
status: fm.status ?? "backlog"
|
|
62377
|
+
};
|
|
62378
|
+
const list = byFeature.get(fid) ?? [];
|
|
62379
|
+
list.push(row);
|
|
62380
|
+
byFeature.set(fid, list);
|
|
62381
|
+
} catch {}
|
|
62382
|
+
}
|
|
61831
62383
|
}
|
|
61832
62384
|
for (const list of byFeature.values()) {
|
|
61833
62385
|
list.sort((a2, b) => a2.wbs.localeCompare(b.wbs));
|
|
@@ -61925,26 +62477,29 @@ class FeatureService {
|
|
|
61925
62477
|
}
|
|
61926
62478
|
async tasksWithFeatureIds(ids) {
|
|
61927
62479
|
const out = [];
|
|
61928
|
-
|
|
61929
|
-
|
|
61930
|
-
names = await this.ctx.fs.readDir(this.ctx.tasksDir);
|
|
61931
|
-
} catch {
|
|
61932
|
-
return out;
|
|
61933
|
-
}
|
|
61934
|
-
for (const name of names) {
|
|
61935
|
-
if (!/^\d{4}_.+\.md$/.test(name))
|
|
61936
|
-
continue;
|
|
61937
|
-
const wbs = name.match(/^(\d{4})_/)?.[1];
|
|
61938
|
-
if (!wbs)
|
|
61939
|
-
continue;
|
|
62480
|
+
for (const dir of this.taskLocator().folderDirs()) {
|
|
62481
|
+
let names;
|
|
61940
62482
|
try {
|
|
61941
|
-
|
|
61942
|
-
|
|
61943
|
-
|
|
61944
|
-
|
|
61945
|
-
|
|
61946
|
-
}
|
|
61947
|
-
|
|
62483
|
+
names = await this.ctx.fs.readDir(dir);
|
|
62484
|
+
} catch {
|
|
62485
|
+
continue;
|
|
62486
|
+
}
|
|
62487
|
+
for (const name of names) {
|
|
62488
|
+
if (!/^\d{4}_.+\.md$/.test(name))
|
|
62489
|
+
continue;
|
|
62490
|
+
const wbs = name.match(/^(\d{4})_/)?.[1];
|
|
62491
|
+
if (!wbs)
|
|
62492
|
+
continue;
|
|
62493
|
+
try {
|
|
62494
|
+
const path9 = `${dir}/${name}`;
|
|
62495
|
+
const raw = await this.ctx.fs.readFile(path9);
|
|
62496
|
+
const fm = MarkdownDocument.parse(raw, "task").frontmatterData ?? {};
|
|
62497
|
+
const fid = fm.feature_id ?? fm["feature-id"];
|
|
62498
|
+
if (fid !== undefined && ids.has(fid)) {
|
|
62499
|
+
out.push({ wbs, path: path9, featureId: fid });
|
|
62500
|
+
}
|
|
62501
|
+
} catch {}
|
|
62502
|
+
}
|
|
61948
62503
|
}
|
|
61949
62504
|
out.sort((a2, b) => a2.wbs.localeCompare(b.wbs));
|
|
61950
62505
|
return out;
|
|
@@ -62120,6 +62675,7 @@ var FEATURE_FILE_RE;
|
|
|
62120
62675
|
var init_feature_service = __esm(() => {
|
|
62121
62676
|
init_src2();
|
|
62122
62677
|
init_feature_check();
|
|
62678
|
+
init_task_locator();
|
|
62123
62679
|
FEATURE_FILE_RE = /^([A-Z][1-9]*)_(.+)\.md$/;
|
|
62124
62680
|
});
|
|
62125
62681
|
|
|
@@ -63564,75 +64120,6 @@ var init_system_event_emitter = __esm(() => {
|
|
|
63564
64120
|
init_system_event_tap();
|
|
63565
64121
|
});
|
|
63566
64122
|
|
|
63567
|
-
// ../../packages/app/src/services/task-locator.ts
|
|
63568
|
-
import { resolve as resolvePath5 } from "path";
|
|
63569
|
-
async function readDirIfPresent(fs3, dir) {
|
|
63570
|
-
try {
|
|
63571
|
-
return await fs3.readDir(dir);
|
|
63572
|
-
} catch (error51) {
|
|
63573
|
-
const code = error51.code;
|
|
63574
|
-
if (code === "ENOENT" || code === "ENOTDIR")
|
|
63575
|
-
return [];
|
|
63576
|
-
throw error51;
|
|
63577
|
-
}
|
|
63578
|
-
}
|
|
63579
|
-
|
|
63580
|
-
class TaskLocator {
|
|
63581
|
-
fs;
|
|
63582
|
-
dirs;
|
|
63583
|
-
constructor(source) {
|
|
63584
|
-
this.fs = source.fs;
|
|
63585
|
-
if ("dirs" in source) {
|
|
63586
|
-
this.dirs = [...new Set(source.dirs)];
|
|
63587
|
-
return;
|
|
63588
|
-
}
|
|
63589
|
-
const folderKeys = source.foldersConfig ? Object.keys(source.foldersConfig.folders) : [];
|
|
63590
|
-
this.dirs = [...new Set([source.tasksDir, ...folderKeys.map((key) => source.fs.resolve(key))])];
|
|
63591
|
-
}
|
|
63592
|
-
static forSingleDir(fs3, dir) {
|
|
63593
|
-
return new TaskLocator({ fs: fs3, tasksDir: dir });
|
|
63594
|
-
}
|
|
63595
|
-
static forDirs(fs3, dirs) {
|
|
63596
|
-
return new TaskLocator({ fs: fs3, dirs });
|
|
63597
|
-
}
|
|
63598
|
-
folderDirs() {
|
|
63599
|
-
return this.dirs;
|
|
63600
|
-
}
|
|
63601
|
-
async findByWbs(wbs) {
|
|
63602
|
-
const prefix = `${wbs}_`;
|
|
63603
|
-
for (const dir of this.folderDirs()) {
|
|
63604
|
-
for (const name of await readDirIfPresent(this.fs, dir)) {
|
|
63605
|
-
if (name.startsWith(prefix) && name.endsWith(".md")) {
|
|
63606
|
-
return { wbs, name, filePath: `${dir}/${name}` };
|
|
63607
|
-
}
|
|
63608
|
-
}
|
|
63609
|
-
}
|
|
63610
|
-
return null;
|
|
63611
|
-
}
|
|
63612
|
-
async findPathByWbs(wbs) {
|
|
63613
|
-
return (await this.findByWbs(wbs))?.filePath ?? null;
|
|
63614
|
-
}
|
|
63615
|
-
async exactMatch(target) {
|
|
63616
|
-
const normalized = resolvePath5(target);
|
|
63617
|
-
for (const dir of this.folderDirs()) {
|
|
63618
|
-
for (const name of await readDirIfPresent(this.fs, dir)) {
|
|
63619
|
-
const captured = TASK_FILENAME_RE.exec(name);
|
|
63620
|
-
if (captured === null)
|
|
63621
|
-
continue;
|
|
63622
|
-
const filePath = `${dir}/${name}`;
|
|
63623
|
-
if (resolvePath5(filePath) === normalized) {
|
|
63624
|
-
return { wbs: captured[1], name, filePath };
|
|
63625
|
-
}
|
|
63626
|
-
}
|
|
63627
|
-
}
|
|
63628
|
-
return null;
|
|
63629
|
-
}
|
|
63630
|
-
}
|
|
63631
|
-
var TASK_FILENAME_RE;
|
|
63632
|
-
var init_task_locator = __esm(() => {
|
|
63633
|
-
TASK_FILENAME_RE = /^(\d{4})_(.+)\.md$/;
|
|
63634
|
-
});
|
|
63635
|
-
|
|
63636
64123
|
// ../../packages/app/src/services/task-check.ts
|
|
63637
64124
|
import { dirname as dirname9, join as join9 } from "path";
|
|
63638
64125
|
function isPlaceholderBody(body) {
|
|
@@ -63692,6 +64179,36 @@ function isProseOnlyReview(body) {
|
|
|
63692
64179
|
return !stripped.split(`
|
|
63693
64180
|
`).some((l) => l.includes("|"));
|
|
63694
64181
|
}
|
|
64182
|
+
function resolveProjectRootFromTasksDir(tasksDir) {
|
|
64183
|
+
const norm = tasksDir.replace(/\\/g, "/");
|
|
64184
|
+
if (/\/docs\/tasks\d*$/.test(norm) || /\/docs\/tasks$/.test(norm)) {
|
|
64185
|
+
return dirname9(dirname9(tasksDir));
|
|
64186
|
+
}
|
|
64187
|
+
return dirname9(tasksDir);
|
|
64188
|
+
}
|
|
64189
|
+
function extractBacktickLineAnchors(body) {
|
|
64190
|
+
const out = [];
|
|
64191
|
+
const re = /`([^`\n]+?:(\d+)(?:-(\d+))?)`/g;
|
|
64192
|
+
let m = re.exec(body);
|
|
64193
|
+
while (m !== null) {
|
|
64194
|
+
const raw = m[1] ?? "";
|
|
64195
|
+
const startStr = m[2];
|
|
64196
|
+
const endStr = m[3];
|
|
64197
|
+
if (startStr) {
|
|
64198
|
+
const pathPart = raw.replace(/:(\d+)(?:-(\d+))?$/, "");
|
|
64199
|
+
const hasExt = /\.\w{1,8}$/.test(pathPart.split("/").pop() ?? "");
|
|
64200
|
+
if (pathPart && !pathPart.includes("://") && hasExt) {
|
|
64201
|
+
const startLine = Number(startStr);
|
|
64202
|
+
const endLine = endStr !== undefined ? Number(endStr) : undefined;
|
|
64203
|
+
if (Number.isFinite(startLine) && startLine >= 1) {
|
|
64204
|
+
out.push({ raw, path: pathPart, startLine, endLine });
|
|
64205
|
+
}
|
|
64206
|
+
}
|
|
64207
|
+
}
|
|
64208
|
+
m = re.exec(body);
|
|
64209
|
+
}
|
|
64210
|
+
return out;
|
|
64211
|
+
}
|
|
63695
64212
|
function hasAdjacentFileLineColumns(body) {
|
|
63696
64213
|
const lines = body.split(`
|
|
63697
64214
|
`);
|
|
@@ -63754,7 +64271,7 @@ var init_task_check = __esm(() => {
|
|
|
63754
64271
|
this.runL3(doc2, entry, status, findings);
|
|
63755
64272
|
const tasksDir = dirname9(filePath);
|
|
63756
64273
|
const featuresDir = join9(dirname9(tasksDir), "features");
|
|
63757
|
-
await this.runL4(doc2, fm, findings, featuresDir, tasksDir);
|
|
64274
|
+
await this.runL4(doc2, fm, status, findings, featuresDir, tasksDir);
|
|
63758
64275
|
await this.runL4Rollup(doc2, wbs, status, findings, tasksDir);
|
|
63759
64276
|
if (status !== "done" && status !== "cancelled") {
|
|
63760
64277
|
await this.runL4Readiness(doc2, fm, wbs, status, findings, tasksDir);
|
|
@@ -63762,6 +64279,26 @@ var init_task_check = __esm(() => {
|
|
|
63762
64279
|
return { wbs, ...this.summarizeWithStatus(status, findings, strict, options?.severityOverrides) };
|
|
63763
64280
|
}
|
|
63764
64281
|
runL3(doc2, entry, status, findings) {
|
|
64282
|
+
const reqBodyRaw = doc2.getSection("Requirements");
|
|
64283
|
+
if (reqBodyRaw !== null && isPlaceholderBody(reqBodyRaw)) {
|
|
64284
|
+
findings.push({
|
|
64285
|
+
layer: "L3",
|
|
64286
|
+
code: FINDING_CODES.L3_REQUIREMENTS_EMPTY,
|
|
64287
|
+
severity: "error",
|
|
64288
|
+
section: "Requirements",
|
|
64289
|
+
message: "Requirements is placeholder-only \u2014 a task with no requirements is unverifiable"
|
|
64290
|
+
});
|
|
64291
|
+
}
|
|
64292
|
+
const acBodyRaw = doc2.getSection("Acceptance Criteria");
|
|
64293
|
+
if (acBodyRaw !== null && isPlaceholderBody(stripAcFence(acBodyRaw))) {
|
|
64294
|
+
findings.push({
|
|
64295
|
+
layer: "L3",
|
|
64296
|
+
code: FINDING_CODES.L3_AC_EMPTY,
|
|
64297
|
+
severity: "error",
|
|
64298
|
+
section: "Acceptance Criteria",
|
|
64299
|
+
message: "Acceptance Criteria is placeholder-only \u2014 populate with real scenarios"
|
|
64300
|
+
});
|
|
64301
|
+
}
|
|
63765
64302
|
const reqBody = doc2.getSection("Requirements");
|
|
63766
64303
|
if (reqBody !== null && !isPlaceholderBody(reqBody)) {
|
|
63767
64304
|
const blocks = reqBody.trim().split(/\n\s*\n/).filter((b) => b.trim().length > 0);
|
|
@@ -63853,7 +64390,7 @@ var init_task_check = __esm(() => {
|
|
|
63853
64390
|
}
|
|
63854
64391
|
}
|
|
63855
64392
|
}
|
|
63856
|
-
async runL4(doc2, fm, findings, featuresDir, tasksDir) {
|
|
64393
|
+
async runL4(doc2, fm, status, findings, featuresDir, tasksDir) {
|
|
63857
64394
|
const template = typeof fm.template === "string" ? fm.template : DEFAULT_TASK_VARIANT;
|
|
63858
64395
|
if (template === DEFAULT_TASK_VARIANT) {
|
|
63859
64396
|
const designBody = doc2.getSection("Design");
|
|
@@ -63867,6 +64404,7 @@ var init_task_check = __esm(() => {
|
|
|
63867
64404
|
});
|
|
63868
64405
|
}
|
|
63869
64406
|
}
|
|
64407
|
+
await this.checkLineAnchors(doc2, tasksDir, findings);
|
|
63870
64408
|
const featureId2 = fm.feature_id ?? fm["feature-id"];
|
|
63871
64409
|
const parentWbs = fm.parent_wbs ?? fm["parent-wbs"];
|
|
63872
64410
|
const deps = fm.dependencies;
|
|
@@ -63882,7 +64420,9 @@ var init_task_check = __esm(() => {
|
|
|
63882
64420
|
});
|
|
63883
64421
|
} else {
|
|
63884
64422
|
const featureStatus = await this.readFeatureStatus(featurePath);
|
|
63885
|
-
|
|
64423
|
+
const featureTerminal = featureStatus === "done" || featureStatus === "cancelled";
|
|
64424
|
+
const taskTerminal = status === "done" || status === "cancelled";
|
|
64425
|
+
if (featureTerminal && !taskTerminal) {
|
|
63886
64426
|
findings.push({
|
|
63887
64427
|
layer: "L4",
|
|
63888
64428
|
code: FINDING_CODES.L4_FEATURE_TERMINAL,
|
|
@@ -64100,6 +64640,54 @@ var init_task_check = __esm(() => {
|
|
|
64100
64640
|
return null;
|
|
64101
64641
|
}
|
|
64102
64642
|
}
|
|
64643
|
+
async checkLineAnchors(doc2, tasksDir, findings) {
|
|
64644
|
+
const projectRoot = resolveProjectRootFromTasksDir(tasksDir);
|
|
64645
|
+
for (const section of ["Testing", "Solution"]) {
|
|
64646
|
+
const body = doc2.getSection(section);
|
|
64647
|
+
if (body === null || isPlaceholderBody(body))
|
|
64648
|
+
continue;
|
|
64649
|
+
const citations = extractBacktickLineAnchors(body);
|
|
64650
|
+
let reported = 0;
|
|
64651
|
+
for (const cite of citations) {
|
|
64652
|
+
if (reported >= 5)
|
|
64653
|
+
break;
|
|
64654
|
+
const abs = join9(projectRoot, cite.path);
|
|
64655
|
+
let exists2 = false;
|
|
64656
|
+
try {
|
|
64657
|
+
exists2 = await this.fs.exists(abs);
|
|
64658
|
+
} catch {
|
|
64659
|
+
exists2 = false;
|
|
64660
|
+
}
|
|
64661
|
+
if (!exists2) {
|
|
64662
|
+
findings.push({
|
|
64663
|
+
layer: "L4",
|
|
64664
|
+
code: FINDING_CODES.L4_STALE_LINE_ANCHOR,
|
|
64665
|
+
severity: "warning",
|
|
64666
|
+
section,
|
|
64667
|
+
message: `Stale line anchor \`${cite.raw}\` \u2014 file not found at ${cite.path} (from project root)`
|
|
64668
|
+
});
|
|
64669
|
+
reported++;
|
|
64670
|
+
continue;
|
|
64671
|
+
}
|
|
64672
|
+
try {
|
|
64673
|
+
const raw = await this.fs.readFile(abs);
|
|
64674
|
+
const lineCount = raw.split(`
|
|
64675
|
+
`).length;
|
|
64676
|
+
const end = cite.endLine ?? cite.startLine;
|
|
64677
|
+
if (cite.startLine < 1 || end > lineCount) {
|
|
64678
|
+
findings.push({
|
|
64679
|
+
layer: "L4",
|
|
64680
|
+
code: FINDING_CODES.L4_STALE_LINE_ANCHOR,
|
|
64681
|
+
severity: "warning",
|
|
64682
|
+
section,
|
|
64683
|
+
message: `Stale line anchor \`${cite.raw}\` \u2014 line ${cite.startLine}${cite.endLine ? `-${cite.endLine}` : ""} outside file (${lineCount} lines)`
|
|
64684
|
+
});
|
|
64685
|
+
reported++;
|
|
64686
|
+
}
|
|
64687
|
+
} catch {}
|
|
64688
|
+
}
|
|
64689
|
+
}
|
|
64690
|
+
}
|
|
64103
64691
|
async findChildren(tasksDir, wbs) {
|
|
64104
64692
|
const kids = [];
|
|
64105
64693
|
for (const dir of this.locatorFor(tasksDir).folderDirs()) {
|
|
@@ -64503,9 +65091,24 @@ function renderCreatedTaskContent(params) {
|
|
|
64503
65091
|
if (params.tags !== undefined && params.tags.length > 0) {
|
|
64504
65092
|
content = patchFrontmatterField(content, "tags", `[${params.tags.map((tag) => JSON.stringify(tag)).join(", ")}]`);
|
|
64505
65093
|
}
|
|
65094
|
+
const sectionPatches = {};
|
|
64506
65095
|
if ((params.requirements ?? "").trim() !== "") {
|
|
65096
|
+
sectionPatches.Requirements = bulletizeRequirements(params.requirements ?? "");
|
|
65097
|
+
}
|
|
65098
|
+
if ((params.design ?? "").trim() !== "") {
|
|
65099
|
+
sectionPatches.Design = (params.design ?? "").trim();
|
|
65100
|
+
}
|
|
65101
|
+
if ((params.plan ?? "").trim() !== "") {
|
|
65102
|
+
sectionPatches.Plan = (params.plan ?? "").trim();
|
|
65103
|
+
}
|
|
65104
|
+
if ((params.acceptanceCriteria ?? "").trim() !== "") {
|
|
65105
|
+
sectionPatches["Acceptance Criteria"] = (params.acceptanceCriteria ?? "").trim();
|
|
65106
|
+
}
|
|
65107
|
+
if (Object.keys(sectionPatches).length > 0) {
|
|
64507
65108
|
const doc2 = MarkdownDocument.parse(content, "task");
|
|
64508
|
-
|
|
65109
|
+
for (const [section, body] of Object.entries(sectionPatches)) {
|
|
65110
|
+
doc2.replaceSection(section, body);
|
|
65111
|
+
}
|
|
64509
65112
|
content = doc2.serialize();
|
|
64510
65113
|
}
|
|
64511
65114
|
return content;
|
|
@@ -64586,6 +65189,26 @@ class TaskService {
|
|
|
64586
65189
|
const templateBodies = this.ctx.resolveTemplateBodies?.(variant) ?? {};
|
|
64587
65190
|
return { ...templateBodies, ...taskBodies };
|
|
64588
65191
|
}
|
|
65192
|
+
async findDuplicateFollowUp(featureId2, title, withinSec) {
|
|
65193
|
+
const siblings = await this.list({ featureId: featureId2 });
|
|
65194
|
+
const now = Date.now();
|
|
65195
|
+
const lowerTitle = title.toLowerCase();
|
|
65196
|
+
for (const t of siblings) {
|
|
65197
|
+
if ((t.name ?? "").toLowerCase() !== lowerTitle)
|
|
65198
|
+
continue;
|
|
65199
|
+
const createdAt = t.frontmatter?.created_at;
|
|
65200
|
+
if (typeof createdAt !== "string")
|
|
65201
|
+
continue;
|
|
65202
|
+
const createdMs = Date.parse(createdAt);
|
|
65203
|
+
if (Number.isNaN(createdMs))
|
|
65204
|
+
continue;
|
|
65205
|
+
const ageSec = (now - createdMs) / 1000;
|
|
65206
|
+
if (ageSec >= 0 && ageSec <= withinSec) {
|
|
65207
|
+
return { wbs: t.wbs, name: t.name };
|
|
65208
|
+
}
|
|
65209
|
+
}
|
|
65210
|
+
return null;
|
|
65211
|
+
}
|
|
64589
65212
|
async create(params) {
|
|
64590
65213
|
const folder = this.ctx.tasksDir;
|
|
64591
65214
|
let background = "";
|
|
@@ -64595,6 +65218,12 @@ class TaskService {
|
|
|
64595
65218
|
const variant = params.template ?? (params.featureId !== undefined ? "feature-impl" : DEFAULT_TASK_VARIANT);
|
|
64596
65219
|
const status = params.status ?? (params.featureId !== undefined ? "todo" : "backlog");
|
|
64597
65220
|
return this.writeService.createAllocated(folder, async () => {
|
|
65221
|
+
if (params.dedupeWithinSec !== undefined && params.featureId !== undefined) {
|
|
65222
|
+
const collision = await this.findDuplicateFollowUp(params.featureId, params.title, params.dedupeWithinSec);
|
|
65223
|
+
if (collision !== null) {
|
|
65224
|
+
throw new DuplicateFollowUpError(collision.wbs, collision.name, params.title);
|
|
65225
|
+
}
|
|
65226
|
+
}
|
|
64598
65227
|
const wbs = await this.allocateWbs();
|
|
64599
65228
|
const slug = this.slugify(params.title);
|
|
64600
65229
|
const filePath = this.resolveTaskPath(wbs, slug);
|
|
@@ -64996,7 +65625,7 @@ ${issues}`);
|
|
|
64996
65625
|
if (!background && item.feature_id !== undefined && item.feature_id !== null) {
|
|
64997
65626
|
background = await this.deriveBackground(item.feature_id);
|
|
64998
65627
|
}
|
|
64999
|
-
const hasSpec = background !== "" || (item.requirements ?? "").trim() !== "";
|
|
65628
|
+
const hasSpec = background !== "" || (item.requirements ?? "").trim() !== "" || (item.design ?? "").trim() !== "" || (item.plan ?? "").trim() !== "" || (item.acceptance_criteria ?? "").trim() !== "";
|
|
65000
65629
|
const status = hasSpec ? "todo" : "backlog";
|
|
65001
65630
|
const variant = item.template ?? (item.feature_id !== undefined && item.feature_id !== null ? "feature-impl" : DEFAULT_TASK_VARIANT);
|
|
65002
65631
|
return this.writeService.createAllocated(folder, async () => {
|
|
@@ -65018,7 +65647,10 @@ ${issues}`);
|
|
|
65018
65647
|
parentWbs: item.parent_wbs ?? undefined,
|
|
65019
65648
|
priority: item.priority,
|
|
65020
65649
|
tags: item.tags,
|
|
65021
|
-
requirements: item.requirements
|
|
65650
|
+
requirements: item.requirements,
|
|
65651
|
+
design: item.design,
|
|
65652
|
+
plan: item.plan,
|
|
65653
|
+
acceptanceCriteria: item.acceptance_criteria
|
|
65022
65654
|
});
|
|
65023
65655
|
const ref2 = { kind: "task", id: wbs, filePath, folder };
|
|
65024
65656
|
return { ref: ref2, content: content2 };
|
|
@@ -65042,6 +65674,15 @@ ${issues}`);
|
|
|
65042
65674
|
if ((item.requirements ?? "").trim() !== "") {
|
|
65043
65675
|
taskBodies.Requirements = bulletizeRequirements(item.requirements ?? "");
|
|
65044
65676
|
}
|
|
65677
|
+
if ((item.design ?? "").trim() !== "") {
|
|
65678
|
+
taskBodies.Design = (item.design ?? "").trim();
|
|
65679
|
+
}
|
|
65680
|
+
if ((item.plan ?? "").trim() !== "") {
|
|
65681
|
+
taskBodies.Plan = (item.plan ?? "").trim();
|
|
65682
|
+
}
|
|
65683
|
+
if ((item.acceptance_criteria ?? "").trim() !== "") {
|
|
65684
|
+
taskBodies["Acceptance Criteria"] = (item.acceptance_criteria ?? "").trim();
|
|
65685
|
+
}
|
|
65045
65686
|
const content = buildTaskSkeleton({
|
|
65046
65687
|
wbs,
|
|
65047
65688
|
title: item.name,
|
|
@@ -65223,7 +65864,7 @@ ${block}` : block);
|
|
|
65223
65864
|
return title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60);
|
|
65224
65865
|
}
|
|
65225
65866
|
}
|
|
65226
|
-
var DependencyMutationError, SectionMutationError, ROSTER_START = "<!-- AUTO-GENERATED by spur task refresh-roster -->", ROSTER_END = "<!-- END AUTO-GENERATED -->", ROSTER_REGION_RE, TASK_ACTION_COMMANDS, DEFAULT_CREATION_SECTIONS;
|
|
65867
|
+
var DependencyMutationError, SectionMutationError, DuplicateFollowUpError, ROSTER_START = "<!-- AUTO-GENERATED by spur task refresh-roster -->", ROSTER_END = "<!-- END AUTO-GENERATED -->", ROSTER_REGION_RE, TASK_ACTION_COMMANDS, DEFAULT_CREATION_SECTIONS;
|
|
65227
65868
|
var init_task_service = __esm(() => {
|
|
65228
65869
|
init_src2();
|
|
65229
65870
|
init_task_locator();
|
|
@@ -65244,6 +65885,18 @@ var init_task_service = __esm(() => {
|
|
|
65244
65885
|
this.code = code;
|
|
65245
65886
|
}
|
|
65246
65887
|
};
|
|
65888
|
+
DuplicateFollowUpError = class DuplicateFollowUpError extends Error {
|
|
65889
|
+
existingWbs;
|
|
65890
|
+
existingName;
|
|
65891
|
+
attemptedName;
|
|
65892
|
+
constructor(existingWbs, existingName, attemptedName) {
|
|
65893
|
+
super(`duplicate-follow-up: task ${existingWbs} ("${existingName}") already exists under this feature ` + `with an identical name. Reuse ${existingWbs} or pass --allow-duplicate-name to override.`);
|
|
65894
|
+
this.name = "DuplicateFollowUpError";
|
|
65895
|
+
this.existingWbs = existingWbs;
|
|
65896
|
+
this.existingName = existingName;
|
|
65897
|
+
this.attemptedName = attemptedName;
|
|
65898
|
+
}
|
|
65899
|
+
};
|
|
65247
65900
|
ROSTER_REGION_RE = /<!--[ \t]*AUTO-GENERATED[^>]*-->[\s\S]*?<!--[ \t]*END[ \t]*AUTO-GENERATED[^>]*-->/g;
|
|
65248
65901
|
TASK_ACTION_COMMANDS = {
|
|
65249
65902
|
refine: (wbs) => `/sp:dev-refine ${wbs} --auto`,
|
|
@@ -65446,6 +66099,50 @@ function extractChecks(_text, taskCheckPassed, acceptanceCriteria) {
|
|
|
65446
66099
|
}
|
|
65447
66100
|
return checks4;
|
|
65448
66101
|
}
|
|
66102
|
+
function classifyTaskOutcome(taskStatus, verdict) {
|
|
66103
|
+
const status = String(taskStatus).toLowerCase();
|
|
66104
|
+
if (NOT_STARTED_STATUSES[status]) {
|
|
66105
|
+
return "NOT-STARTED";
|
|
66106
|
+
}
|
|
66107
|
+
const v = String(verdict ?? "UNKNOWN").toUpperCase();
|
|
66108
|
+
if (v === "PASS" || v === "PARTIAL" || v === "FAIL")
|
|
66109
|
+
return v;
|
|
66110
|
+
return "UNKNOWN";
|
|
66111
|
+
}
|
|
66112
|
+
function aggregateBatchVerdicts(results) {
|
|
66113
|
+
const notStarted = results.filter((r) => r.outcome === "NOT-STARTED");
|
|
66114
|
+
const rolledUp = results.filter((r) => r.outcome !== "NOT-STARTED");
|
|
66115
|
+
const counts = {
|
|
66116
|
+
PASS: rolledUp.filter((r) => r.outcome === "PASS").length,
|
|
66117
|
+
PARTIAL: rolledUp.filter((r) => r.outcome === "PARTIAL").length,
|
|
66118
|
+
FAIL: rolledUp.filter((r) => r.outcome === "FAIL").length,
|
|
66119
|
+
UNKNOWN: rolledUp.filter((r) => r.outcome === "UNKNOWN").length
|
|
66120
|
+
};
|
|
66121
|
+
let verdict;
|
|
66122
|
+
if (rolledUp.length === 0) {
|
|
66123
|
+
verdict = "UNKNOWN";
|
|
66124
|
+
} else if (counts.FAIL > 0) {
|
|
66125
|
+
verdict = "FAIL";
|
|
66126
|
+
} else if (counts.PARTIAL > 0 || counts.UNKNOWN > 0) {
|
|
66127
|
+
verdict = "PARTIAL";
|
|
66128
|
+
} else {
|
|
66129
|
+
verdict = "PASS";
|
|
66130
|
+
}
|
|
66131
|
+
const summary = `${counts.PASS} PASS, ${counts.PARTIAL} PARTIAL, ${counts.FAIL} FAIL, ${notStarted.length} NOT-STARTED (excluded)`;
|
|
66132
|
+
return { verdict, rolledUp, notStarted, summary };
|
|
66133
|
+
}
|
|
66134
|
+
var NOT_STARTED_STATUSES;
|
|
66135
|
+
var init_task_verdict = __esm(() => {
|
|
66136
|
+
NOT_STARTED_STATUSES = {
|
|
66137
|
+
backlog: true,
|
|
66138
|
+
todo: true,
|
|
66139
|
+
wip: false,
|
|
66140
|
+
testing: false,
|
|
66141
|
+
blocked: true,
|
|
66142
|
+
done: false,
|
|
66143
|
+
cancelled: false
|
|
66144
|
+
};
|
|
66145
|
+
});
|
|
65449
66146
|
|
|
65450
66147
|
// ../../packages/app/src/services/team-service.ts
|
|
65451
66148
|
import { join as join10 } from "path";
|
|
@@ -66098,6 +66795,247 @@ var init_token_ledger_watcher = __esm(() => {
|
|
|
66098
66795
|
init_token_ledger_service();
|
|
66099
66796
|
});
|
|
66100
66797
|
|
|
66798
|
+
// ../../packages/app/src/workflow/steering.ts
|
|
66799
|
+
class WorkflowSteeringController {
|
|
66800
|
+
onAck;
|
|
66801
|
+
secrets;
|
|
66802
|
+
allowedActors;
|
|
66803
|
+
onState;
|
|
66804
|
+
active;
|
|
66805
|
+
seen = new Set;
|
|
66806
|
+
constructor(onAck, secrets = [], allowedActors = new Set(["operator"]), onState) {
|
|
66807
|
+
this.onAck = onAck;
|
|
66808
|
+
this.secrets = secrets;
|
|
66809
|
+
this.allowedActors = allowedActors;
|
|
66810
|
+
this.onState = onState;
|
|
66811
|
+
}
|
|
66812
|
+
get snapshot() {
|
|
66813
|
+
const active = this.active;
|
|
66814
|
+
return active === undefined ? undefined : {
|
|
66815
|
+
runId: active.runId,
|
|
66816
|
+
actionId: active.actionId,
|
|
66817
|
+
state: active.state,
|
|
66818
|
+
version: active.version
|
|
66819
|
+
};
|
|
66820
|
+
}
|
|
66821
|
+
begin(runId, actionId, policy) {
|
|
66822
|
+
this.active = {
|
|
66823
|
+
runId,
|
|
66824
|
+
actionId,
|
|
66825
|
+
state: "running",
|
|
66826
|
+
version: 1,
|
|
66827
|
+
attempts: 1,
|
|
66828
|
+
lastOk: false,
|
|
66829
|
+
policy,
|
|
66830
|
+
controller: new AbortController
|
|
66831
|
+
};
|
|
66832
|
+
this.publishState(this.active);
|
|
66833
|
+
return this.active.controller.signal;
|
|
66834
|
+
}
|
|
66835
|
+
async boundary(ok) {
|
|
66836
|
+
const active = this.requireActive();
|
|
66837
|
+
active.lastOk = ok;
|
|
66838
|
+
if (active.controller.signal.aborted)
|
|
66839
|
+
return { operation: "abort" };
|
|
66840
|
+
if (!active.policy.boundary)
|
|
66841
|
+
return { operation: "continue" };
|
|
66842
|
+
active.state = "boundary";
|
|
66843
|
+
active.version += 1;
|
|
66844
|
+
this.publishState(active);
|
|
66845
|
+
return await new Promise((resolve2) => {
|
|
66846
|
+
const settle = (decision) => {
|
|
66847
|
+
clearTimeout(timer);
|
|
66848
|
+
resolve2(decision);
|
|
66849
|
+
};
|
|
66850
|
+
const timer = setTimeout(() => {
|
|
66851
|
+
if (active.resolve !== settle)
|
|
66852
|
+
return;
|
|
66853
|
+
active.resolve = undefined;
|
|
66854
|
+
this.acceptDefault(active, resolve2);
|
|
66855
|
+
}, active.policy.timeoutMs);
|
|
66856
|
+
timer.unref?.();
|
|
66857
|
+
active.resolve = settle;
|
|
66858
|
+
});
|
|
66859
|
+
}
|
|
66860
|
+
nextAttempt() {
|
|
66861
|
+
const active = this.requireActive();
|
|
66862
|
+
active.attempts += 1;
|
|
66863
|
+
active.state = "running";
|
|
66864
|
+
active.version += 1;
|
|
66865
|
+
active.controller = new AbortController;
|
|
66866
|
+
this.publishState(active);
|
|
66867
|
+
return active.controller.signal;
|
|
66868
|
+
}
|
|
66869
|
+
complete() {
|
|
66870
|
+
const active = this.active;
|
|
66871
|
+
if (active === undefined)
|
|
66872
|
+
return;
|
|
66873
|
+
active.state = "completed";
|
|
66874
|
+
active.version += 1;
|
|
66875
|
+
active.resolve = undefined;
|
|
66876
|
+
this.publishState(active);
|
|
66877
|
+
}
|
|
66878
|
+
submit(command) {
|
|
66879
|
+
const active = this.active;
|
|
66880
|
+
if (command.commandId.trim() === "")
|
|
66881
|
+
return this.reject(command, active, "command id is required");
|
|
66882
|
+
if (this.seen.has(command.commandId))
|
|
66883
|
+
return this.reject(command, active, "duplicate command");
|
|
66884
|
+
this.seen.add(command.commandId);
|
|
66885
|
+
if (active === undefined)
|
|
66886
|
+
return this.reject(command, active, "no active action");
|
|
66887
|
+
if (!this.allowedActors.has(command.actor))
|
|
66888
|
+
return this.reject(command, active, "unauthorized actor");
|
|
66889
|
+
const deadlineMs = Date.parse(command.deadlineAt);
|
|
66890
|
+
if (!Number.isFinite(deadlineMs))
|
|
66891
|
+
return this.reject(command, active, "invalid command deadline");
|
|
66892
|
+
if (deadlineMs < Date.now())
|
|
66893
|
+
return this.reject(command, active, "command deadline elapsed");
|
|
66894
|
+
if (command.runId !== active.runId || command.actionId !== active.actionId) {
|
|
66895
|
+
return this.reject(command, active, "target does not match the active action");
|
|
66896
|
+
}
|
|
66897
|
+
if (command.expectedState !== active.state || command.expectedVersion !== active.version) {
|
|
66898
|
+
return this.reject(command, active, "stale state or version");
|
|
66899
|
+
}
|
|
66900
|
+
if (active.state === "completed") {
|
|
66901
|
+
return this.reject(command, active, "completed action history is immutable");
|
|
66902
|
+
}
|
|
66903
|
+
if (command.operation === "abort") {
|
|
66904
|
+
active.controller.abort();
|
|
66905
|
+
active.resolve?.({ operation: "abort" });
|
|
66906
|
+
active.resolve = undefined;
|
|
66907
|
+
return this.accept(command, active);
|
|
66908
|
+
}
|
|
66909
|
+
if (active.state !== "boundary" || active.resolve === undefined) {
|
|
66910
|
+
return this.reject(command, active, "action is not paused at a steering boundary");
|
|
66911
|
+
}
|
|
66912
|
+
if (command.operation === "retry") {
|
|
66913
|
+
const retry = active.policy.retry;
|
|
66914
|
+
if (active.lastOk)
|
|
66915
|
+
return this.reject(command, active, "retry requires a failed attempt");
|
|
66916
|
+
if (retry === undefined || retry.idempotent !== true) {
|
|
66917
|
+
return this.reject(command, active, "unsafe retry: no explicit idempotent retry policy");
|
|
66918
|
+
}
|
|
66919
|
+
if (active.attempts >= retry.maxAttempts) {
|
|
66920
|
+
return this.reject(command, active, "retry limit reached");
|
|
66921
|
+
}
|
|
66922
|
+
}
|
|
66923
|
+
if (command.operation === "note" && (command.note === undefined || command.note.trim() === "")) {
|
|
66924
|
+
return this.reject(command, active, "note text is required");
|
|
66925
|
+
}
|
|
66926
|
+
const note = command.operation === "note" && command.note !== undefined ? redactAndBound(command.note, this.secrets, 1024) : undefined;
|
|
66927
|
+
active.resolve({ operation: command.operation, ...note !== undefined ? { note } : {} });
|
|
66928
|
+
active.resolve = undefined;
|
|
66929
|
+
return this.accept(command, active, note);
|
|
66930
|
+
}
|
|
66931
|
+
submitLine(line, deadlineMs = 30000) {
|
|
66932
|
+
const active = this.active;
|
|
66933
|
+
if (active === undefined)
|
|
66934
|
+
return;
|
|
66935
|
+
const trimmed = line.trim();
|
|
66936
|
+
const [rawOperation, ...rest] = trimmed.split(/\s+/);
|
|
66937
|
+
if (!["continue", "note", "retry", "abort"].includes(rawOperation ?? ""))
|
|
66938
|
+
return;
|
|
66939
|
+
const operation = rawOperation;
|
|
66940
|
+
return this.submit({
|
|
66941
|
+
commandId: crypto.randomUUID(),
|
|
66942
|
+
runId: active.runId,
|
|
66943
|
+
actionId: active.actionId,
|
|
66944
|
+
expectedState: active.state,
|
|
66945
|
+
expectedVersion: active.version,
|
|
66946
|
+
operation,
|
|
66947
|
+
...operation === "note" ? { note: rest.join(" ") } : {},
|
|
66948
|
+
actor: "operator",
|
|
66949
|
+
deadlineAt: new Date(Date.now() + deadlineMs).toISOString()
|
|
66950
|
+
});
|
|
66951
|
+
}
|
|
66952
|
+
acceptDefault(active, resolve2) {
|
|
66953
|
+
const command = {
|
|
66954
|
+
commandId: crypto.randomUUID(),
|
|
66955
|
+
runId: active.runId,
|
|
66956
|
+
actionId: active.actionId,
|
|
66957
|
+
expectedState: active.state,
|
|
66958
|
+
expectedVersion: active.version,
|
|
66959
|
+
operation: "continue",
|
|
66960
|
+
actor: "system-timeout",
|
|
66961
|
+
deadlineAt: new Date().toISOString()
|
|
66962
|
+
};
|
|
66963
|
+
const ack = {
|
|
66964
|
+
schemaVersion: 1,
|
|
66965
|
+
commandId: command.commandId,
|
|
66966
|
+
runId: command.runId,
|
|
66967
|
+
actionId: command.actionId,
|
|
66968
|
+
operation: command.operation,
|
|
66969
|
+
actor: command.actor,
|
|
66970
|
+
accepted: true,
|
|
66971
|
+
state: active.state,
|
|
66972
|
+
version: active.version,
|
|
66973
|
+
reason: "boundary timeout defaulted to continue",
|
|
66974
|
+
at: new Date().toISOString()
|
|
66975
|
+
};
|
|
66976
|
+
this.onAck?.(ack);
|
|
66977
|
+
resolve2({ operation: "continue" });
|
|
66978
|
+
}
|
|
66979
|
+
accept(command, active, note) {
|
|
66980
|
+
return this.publish({
|
|
66981
|
+
schemaVersion: 1,
|
|
66982
|
+
commandId: command.commandId,
|
|
66983
|
+
runId: command.runId,
|
|
66984
|
+
actionId: command.actionId,
|
|
66985
|
+
operation: command.operation,
|
|
66986
|
+
actor: command.actor,
|
|
66987
|
+
accepted: true,
|
|
66988
|
+
state: active.state,
|
|
66989
|
+
version: active.version,
|
|
66990
|
+
...note !== undefined ? { note } : {},
|
|
66991
|
+
at: new Date().toISOString()
|
|
66992
|
+
});
|
|
66993
|
+
}
|
|
66994
|
+
reject(command, active, reason) {
|
|
66995
|
+
return this.publish({
|
|
66996
|
+
schemaVersion: 1,
|
|
66997
|
+
commandId: command.commandId,
|
|
66998
|
+
runId: command.runId,
|
|
66999
|
+
actionId: command.actionId,
|
|
67000
|
+
operation: command.operation,
|
|
67001
|
+
actor: command.actor,
|
|
67002
|
+
accepted: false,
|
|
67003
|
+
state: active?.state ?? "completed",
|
|
67004
|
+
version: active?.version ?? 0,
|
|
67005
|
+
reason,
|
|
67006
|
+
at: new Date().toISOString()
|
|
67007
|
+
});
|
|
67008
|
+
}
|
|
67009
|
+
publish(ack) {
|
|
67010
|
+
this.onAck?.(ack);
|
|
67011
|
+
return ack;
|
|
67012
|
+
}
|
|
67013
|
+
requireActive() {
|
|
67014
|
+
if (this.active === undefined)
|
|
67015
|
+
throw new Error("no active steering action");
|
|
67016
|
+
return this.active;
|
|
67017
|
+
}
|
|
67018
|
+
publishState(active) {
|
|
67019
|
+
this.onState?.({
|
|
67020
|
+
runId: active.runId,
|
|
67021
|
+
actionId: active.actionId,
|
|
67022
|
+
state: active.state,
|
|
67023
|
+
version: active.version
|
|
67024
|
+
});
|
|
67025
|
+
}
|
|
67026
|
+
}
|
|
67027
|
+
function parseSteeringPolicy(options) {
|
|
67028
|
+
const boundary2 = options.steeringBoundary === true;
|
|
67029
|
+
const timeoutMs = typeof options.steeringTimeoutMs === "number" && Number.isFinite(options.steeringTimeoutMs) && Number.isInteger(options.steeringTimeoutMs) && options.steeringTimeoutMs > 0 ? Math.min(options.steeringTimeoutMs, MAX_STEERING_TIMEOUT_MS) : 30000;
|
|
67030
|
+
const rawRetry = options.retryPolicy;
|
|
67031
|
+
const retry = typeof rawRetry === "object" && rawRetry !== null && "idempotent" in rawRetry && rawRetry.idempotent === true && "maxAttempts" in rawRetry && typeof rawRetry.maxAttempts === "number" && Number.isFinite(rawRetry.maxAttempts) && Number.isInteger(rawRetry.maxAttempts) && rawRetry.maxAttempts > 1 ? { idempotent: true, maxAttempts: Math.min(rawRetry.maxAttempts, MAX_STEERING_ATTEMPTS) } : undefined;
|
|
67032
|
+
return { boundary: boundary2, timeoutMs, ...retry !== undefined ? { retry } : {} };
|
|
67033
|
+
}
|
|
67034
|
+
var MAX_STEERING_TIMEOUT_MS = 300000, MAX_STEERING_ATTEMPTS = 10;
|
|
67035
|
+
var init_steering = __esm(() => {
|
|
67036
|
+
init_agent_execution();
|
|
67037
|
+
});
|
|
67038
|
+
|
|
66101
67039
|
// ../../packages/app/src/workflow/actions/agent-run.ts
|
|
66102
67040
|
import { execFile } from "child_process";
|
|
66103
67041
|
import { existsSync as existsSync7 } from "fs";
|
|
@@ -66106,9 +67044,13 @@ import { dirname as dirname11, isAbsolute as isAbsolute2, join as join12 } from
|
|
|
66106
67044
|
import { promisify as promisify3 } from "util";
|
|
66107
67045
|
|
|
66108
67046
|
class AgentRunActionRunner {
|
|
67047
|
+
observabilityBus;
|
|
67048
|
+
steeringController;
|
|
66109
67049
|
kind = KIND;
|
|
66110
67050
|
agentService;
|
|
66111
|
-
constructor(agentService) {
|
|
67051
|
+
constructor(agentService, observabilityBus, steeringController) {
|
|
67052
|
+
this.observabilityBus = observabilityBus;
|
|
67053
|
+
this.steeringController = steeringController;
|
|
66112
67054
|
this.agentService = agentService;
|
|
66113
67055
|
}
|
|
66114
67056
|
async execute(options, context4) {
|
|
@@ -66151,7 +67093,44 @@ class AgentRunActionRunner {
|
|
|
66151
67093
|
const expectFile = asOptionalString(options.expectFile);
|
|
66152
67094
|
const capture = asOptionalBoolean(options.capture) || answerFile !== undefined;
|
|
66153
67095
|
const agentLabel = agent ?? "<default>";
|
|
66154
|
-
const
|
|
67096
|
+
const observer = this.observabilityBus === undefined ? undefined : (event2) => {
|
|
67097
|
+
this.observabilityBus?.emit("workflow.agent", event2);
|
|
67098
|
+
};
|
|
67099
|
+
const actionId = context4.actionId ?? `${context4.runId}:${context4.stateOrNodeId}`;
|
|
67100
|
+
const steeringPolicy = parseSteeringPolicy(options);
|
|
67101
|
+
let steeringSignal = this.steeringController?.begin(context4.runId, actionId, steeringPolicy);
|
|
67102
|
+
let steeringNote;
|
|
67103
|
+
let traced;
|
|
67104
|
+
while (true) {
|
|
67105
|
+
traced = await this.agentService.runTraced(input, flags, undefined, {
|
|
67106
|
+
correlation: {
|
|
67107
|
+
runId: context4.runId,
|
|
67108
|
+
executionId: crypto.randomUUID(),
|
|
67109
|
+
actionId
|
|
67110
|
+
},
|
|
67111
|
+
...observer !== undefined ? { observer } : {},
|
|
67112
|
+
...steeringSignal !== undefined ? { signal: steeringSignal } : {}
|
|
67113
|
+
});
|
|
67114
|
+
if (this.steeringController === undefined)
|
|
67115
|
+
break;
|
|
67116
|
+
const decision = await this.steeringController.boundary(traced.exitCode === 0);
|
|
67117
|
+
if (decision.operation === "retry") {
|
|
67118
|
+
steeringSignal = this.steeringController.nextAttempt();
|
|
67119
|
+
continue;
|
|
67120
|
+
}
|
|
67121
|
+
if (decision.operation === "note")
|
|
67122
|
+
steeringNote = decision.note;
|
|
67123
|
+
if (decision.operation === "abort" && traced.exitCode === 0) {
|
|
67124
|
+
traced = {
|
|
67125
|
+
...traced,
|
|
67126
|
+
exitCode: 3,
|
|
67127
|
+
signal: "STEERING_ABORT",
|
|
67128
|
+
message: "aborted at steering boundary"
|
|
67129
|
+
};
|
|
67130
|
+
}
|
|
67131
|
+
break;
|
|
67132
|
+
}
|
|
67133
|
+
this.steeringController?.complete();
|
|
66155
67134
|
const { exitCode, stdout: answer } = traced;
|
|
66156
67135
|
const ok = exitCode === 0;
|
|
66157
67136
|
const invocation = traced.invocation;
|
|
@@ -66179,7 +67158,10 @@ class AgentRunActionRunner {
|
|
|
66179
67158
|
ok,
|
|
66180
67159
|
data: buildResultData(exitCode, agentLabel, capture, answer, invocation),
|
|
66181
67160
|
error: error51,
|
|
66182
|
-
setVars: ok ? {
|
|
67161
|
+
setVars: ok ? {
|
|
67162
|
+
__agentSession: "open",
|
|
67163
|
+
...steeringNote !== undefined ? { __steeringNote: steeringNote } : {}
|
|
67164
|
+
} : undefined
|
|
66183
67165
|
};
|
|
66184
67166
|
}
|
|
66185
67167
|
}
|
|
@@ -66287,6 +67269,7 @@ ${text4.slice(text4.length - maxChars)}`;
|
|
|
66287
67269
|
}
|
|
66288
67270
|
var execFileAsync, PARTIAL_ARTIFACT_TAIL_CHARS = 4000, KIND = "agent.run";
|
|
66289
67271
|
var init_agent_run = __esm(() => {
|
|
67272
|
+
init_steering();
|
|
66290
67273
|
execFileAsync = promisify3(execFile);
|
|
66291
67274
|
});
|
|
66292
67275
|
|
|
@@ -66815,7 +67798,7 @@ var init_rule_check = __esm(() => {
|
|
|
66815
67798
|
// ../../packages/app/src/workflow/builtins.ts
|
|
66816
67799
|
function registerSpurBuiltins(host, options) {
|
|
66817
67800
|
const fileSystem = options.fileSystem ?? createNodeFileSystem3();
|
|
66818
|
-
host.registerAction(new AgentRunActionRunner(options.agentService), "builtin");
|
|
67801
|
+
host.registerAction(new AgentRunActionRunner(options.agentService, options.observabilityBus, options.steeringController), "builtin");
|
|
66819
67802
|
host.registerAction(new RuleCheckActionRunner(options.ruleService), "builtin");
|
|
66820
67803
|
host.registerAction(new FileExistsActionRunner(fileSystem), "builtin");
|
|
66821
67804
|
host.registerAction(new FileReadActionRunner(fileSystem), "builtin");
|
|
@@ -66841,56 +67824,125 @@ var init_builtins2 = __esm(() => {
|
|
|
66841
67824
|
});
|
|
66842
67825
|
|
|
66843
67826
|
// ../../packages/app/src/workflow/observability.ts
|
|
67827
|
+
function bounded(value) {
|
|
67828
|
+
const redacted = value.replace(SECRET_PATTERN2, "[REDACTED]");
|
|
67829
|
+
return redacted.length <= MAX_FIELD_LENGTH ? redacted : `${redacted.slice(0, MAX_FIELD_LENGTH)}\u2026`;
|
|
67830
|
+
}
|
|
67831
|
+
function projectActionMetadata(kind, options) {
|
|
67832
|
+
if (options === undefined)
|
|
67833
|
+
return;
|
|
67834
|
+
const metadata = {};
|
|
67835
|
+
if (typeof options.agent === "string" && options.agent !== "")
|
|
67836
|
+
metadata.agent = bounded(options.agent);
|
|
67837
|
+
if (typeof options.model === "string" && options.model !== "")
|
|
67838
|
+
metadata.model = bounded(options.model);
|
|
67839
|
+
if (typeof options.timeoutMs === "number" && Number.isFinite(options.timeoutMs)) {
|
|
67840
|
+
metadata.timeoutMs = Math.max(0, options.timeoutMs);
|
|
67841
|
+
}
|
|
67842
|
+
const input = typeof options.input === "string" ? options.input.trim() : "";
|
|
67843
|
+
if (kind === "agent.run" && input !== "") {
|
|
67844
|
+
const command = input.startsWith("/") ? input.split(/\s+/, 1)[0] : undefined;
|
|
67845
|
+
metadata.invocation = command === undefined ? `[prompt ${input.length} chars]` : bounded(command);
|
|
67846
|
+
} else if (kind === "shell" && typeof options.command === "string") {
|
|
67847
|
+
metadata.invocation = "[shell command redacted]";
|
|
67848
|
+
}
|
|
67849
|
+
return Object.keys(metadata).length === 0 ? undefined : metadata;
|
|
67850
|
+
}
|
|
67851
|
+
function projectResult(result) {
|
|
67852
|
+
if (result === undefined)
|
|
67853
|
+
return;
|
|
67854
|
+
if (typeof result !== "object" || result === null)
|
|
67855
|
+
return { usage: "unavailable" };
|
|
67856
|
+
const error51 = "error" in result && typeof result.error === "string" ? bounded(result.error) : undefined;
|
|
67857
|
+
return { ...error51 !== undefined ? { error: error51 } : {}, usage: "unavailable" };
|
|
67858
|
+
}
|
|
67859
|
+
|
|
66844
67860
|
class ObservableWorkflowAdapter {
|
|
66845
67861
|
inner;
|
|
66846
67862
|
bus;
|
|
67863
|
+
sequences = new Map;
|
|
67864
|
+
workflowNames = new Map;
|
|
67865
|
+
actions = new Map;
|
|
66847
67866
|
constructor(inner, bus) {
|
|
66848
67867
|
this.inner = inner;
|
|
66849
67868
|
this.bus = bus;
|
|
66850
67869
|
}
|
|
66851
67870
|
async createRun(record2) {
|
|
66852
67871
|
await this.inner.createRun(record2);
|
|
67872
|
+
this.workflowNames.set(record2.id, record2.workflow_name);
|
|
66853
67873
|
await this.bus.emit("workflow.run.started", {
|
|
66854
|
-
|
|
66855
|
-
workflowName: record2.workflow_name
|
|
66856
|
-
at: now()
|
|
67874
|
+
...this.envelope(record2.id),
|
|
67875
|
+
workflowName: record2.workflow_name
|
|
66857
67876
|
});
|
|
66858
67877
|
}
|
|
66859
67878
|
async finalizeRun(runId, status, completedAt) {
|
|
66860
67879
|
await this.inner.finalizeRun(runId, status, completedAt);
|
|
66861
|
-
await this.bus.emit("workflow.run.finalized", { runId,
|
|
67880
|
+
await this.bus.emit("workflow.run.finalized", { ...this.envelope(runId, completedAt), status });
|
|
66862
67881
|
}
|
|
66863
67882
|
async savePhase(runId, phase, status) {
|
|
66864
67883
|
await this.inner.savePhase(runId, phase, status);
|
|
66865
|
-
await this.bus.emit("workflow.phase", { runId, phase, status
|
|
67884
|
+
await this.bus.emit("workflow.phase", { ...this.envelope(runId), phase, status });
|
|
66866
67885
|
}
|
|
66867
67886
|
async saveTransition(runId, from, to, trigger) {
|
|
66868
67887
|
await this.inner.saveTransition(runId, from, to, trigger);
|
|
66869
|
-
await this.bus.emit("workflow.transition", { runId, from, to, trigger
|
|
67888
|
+
await this.bus.emit("workflow.transition", { ...this.envelope(runId), from, to, trigger });
|
|
66870
67889
|
}
|
|
66871
67890
|
async commitTransition(runId, from, to, trigger, _state, _data, phase) {
|
|
66872
67891
|
await this.inner.commitTransition(runId, from, to, trigger, _state, _data, phase);
|
|
66873
|
-
await this.bus.emit("workflow.transition", { runId, from, to, trigger
|
|
67892
|
+
await this.bus.emit("workflow.transition", { ...this.envelope(runId), from, to, trigger });
|
|
66874
67893
|
if (phase) {
|
|
66875
|
-
await this.bus.emit("workflow.phase", {
|
|
67894
|
+
await this.bus.emit("workflow.phase", {
|
|
67895
|
+
...this.envelope(runId),
|
|
67896
|
+
phase: phase.phase,
|
|
67897
|
+
status: phase.status
|
|
67898
|
+
});
|
|
66876
67899
|
}
|
|
66877
67900
|
}
|
|
66878
|
-
async saveActionStart(runId, node, kind) {
|
|
66879
|
-
const actionId = await this.inner.saveActionStart(runId, node, kind);
|
|
66880
|
-
|
|
67901
|
+
async saveActionStart(runId, node, kind, options) {
|
|
67902
|
+
const actionId = await this.inner.saveActionStart(runId, node, kind, options);
|
|
67903
|
+
this.actions.set(actionId, { runId, node, kind });
|
|
67904
|
+
const metadata = projectActionMetadata(kind, options);
|
|
67905
|
+
await this.bus.emit("workflow.action.started", {
|
|
67906
|
+
...this.envelope(runId),
|
|
67907
|
+
actionId,
|
|
67908
|
+
node,
|
|
67909
|
+
kind,
|
|
67910
|
+
...metadata !== undefined ? { metadata } : {}
|
|
67911
|
+
});
|
|
66881
67912
|
return actionId;
|
|
66882
67913
|
}
|
|
66883
67914
|
async saveActionFinalize(actionId, status, durationMs, ok, result, redactor) {
|
|
66884
67915
|
await this.inner.saveActionFinalize(actionId, status, durationMs, ok, result, redactor);
|
|
67916
|
+
const action = this.actions.get(actionId);
|
|
67917
|
+
if (action === undefined) {
|
|
67918
|
+
return;
|
|
67919
|
+
}
|
|
67920
|
+
this.actions.delete(actionId);
|
|
67921
|
+
const projected = projectResult(result);
|
|
66885
67922
|
await this.bus.emit("workflow.action.finished", {
|
|
66886
|
-
runId
|
|
67923
|
+
...this.envelope(action.runId),
|
|
66887
67924
|
actionId,
|
|
66888
67925
|
status,
|
|
66889
67926
|
durationMs,
|
|
66890
67927
|
ok,
|
|
66891
|
-
|
|
67928
|
+
node: action.node,
|
|
67929
|
+
kind: action.kind,
|
|
67930
|
+
...projected !== undefined ? { result: projected } : {}
|
|
66892
67931
|
});
|
|
66893
67932
|
}
|
|
67933
|
+
envelope(runId, at = now()) {
|
|
67934
|
+
const sequence = (this.sequences.get(runId) ?? 0) + 1;
|
|
67935
|
+
this.sequences.set(runId, sequence);
|
|
67936
|
+
const workflowName = this.workflowNames.get(runId);
|
|
67937
|
+
return {
|
|
67938
|
+
schemaVersion: 1,
|
|
67939
|
+
eventId: crypto.randomUUID(),
|
|
67940
|
+
sequence,
|
|
67941
|
+
runId,
|
|
67942
|
+
...workflowName !== undefined ? { workflowName } : {},
|
|
67943
|
+
at
|
|
67944
|
+
};
|
|
67945
|
+
}
|
|
66894
67946
|
saveWorkflowState(runId, state, data) {
|
|
66895
67947
|
return this.inner.saveWorkflowState(runId, state, data);
|
|
66896
67948
|
}
|
|
@@ -66912,11 +67964,17 @@ class ObservableWorkflowAdapter {
|
|
|
66912
67964
|
loadCurrentState(runId) {
|
|
66913
67965
|
return this.inner.loadCurrentState(runId);
|
|
66914
67966
|
}
|
|
67967
|
+
loadLatestStateSnapshot(runId) {
|
|
67968
|
+
return this.inner.loadLatestStateSnapshot(runId);
|
|
67969
|
+
}
|
|
66915
67970
|
listPausedRuns(options) {
|
|
66916
67971
|
return this.inner.listPausedRuns(options);
|
|
66917
67972
|
}
|
|
66918
67973
|
}
|
|
66919
|
-
var now = () => new Date().toISOString();
|
|
67974
|
+
var now = () => new Date().toISOString(), MAX_FIELD_LENGTH = 256, SECRET_PATTERN2;
|
|
67975
|
+
var init_observability = __esm(() => {
|
|
67976
|
+
SECRET_PATTERN2 = /(?:sk-[a-z0-9_-]{8,}|(?:api[_-]?key|token|secret|password)\s*[:=]\s*\S+|bearer\s+\S+)/gi;
|
|
67977
|
+
});
|
|
66920
67978
|
|
|
66921
67979
|
// ../../packages/app/src/services/workflow-service.ts
|
|
66922
67980
|
import { access as access2, lstat, readdir as readdir3, readFile as readFile2, realpath } from "fs/promises";
|
|
@@ -67011,14 +68069,16 @@ class WorkflowAppService {
|
|
|
67011
68069
|
const eventsBus = this.ctx.events?.();
|
|
67012
68070
|
const svc = await this.createEngineService({
|
|
67013
68071
|
recordSelfPid: opts.recordSelfPid === true,
|
|
67014
|
-
events: eventsBus
|
|
68072
|
+
events: eventsBus,
|
|
68073
|
+
steeringController: opts.steeringController
|
|
67015
68074
|
});
|
|
67016
68075
|
const runId = opts.runId ?? crypto.randomUUID();
|
|
67017
68076
|
const isDry = opts.dryRun === true;
|
|
68077
|
+
const runVars = { ...opts.vars ?? {}, __runId: runId };
|
|
67018
68078
|
const result = await svc.runFile(file2, {
|
|
67019
68079
|
workdir: this.ctx.cwd,
|
|
67020
68080
|
runId,
|
|
67021
|
-
|
|
68081
|
+
vars: runVars,
|
|
67022
68082
|
...isDry ? { dryRun: true } : {},
|
|
67023
68083
|
...eventsBus !== undefined ? { events: bridgeEventBus(eventsBus) } : {}
|
|
67024
68084
|
});
|
|
@@ -67026,6 +68086,7 @@ class WorkflowAppService {
|
|
|
67026
68086
|
const db2 = await this.ctx.getDb();
|
|
67027
68087
|
await new RunDao(db2).stampMetadata(runId, { dryRun: true });
|
|
67028
68088
|
}
|
|
68089
|
+
await this.stampFailureReason(runId, result);
|
|
67029
68090
|
await this.maybeLinkPipelineRun(file2, runId, opts);
|
|
67030
68091
|
return result;
|
|
67031
68092
|
}
|
|
@@ -67106,8 +68167,16 @@ class WorkflowAppService {
|
|
|
67106
68167
|
throw new Error(`Cannot resume run "${runId}": workflow definition "${target.workflow_name}" not found in the workflow search paths.`);
|
|
67107
68168
|
}
|
|
67108
68169
|
const result = await svc.resumeRun(workflow, runId, { workdir: this.ctx.cwd });
|
|
68170
|
+
await this.stampFailureReason(runId, result);
|
|
67109
68171
|
return result;
|
|
67110
68172
|
}
|
|
68173
|
+
async stampFailureReason(runId, result) {
|
|
68174
|
+
if (result.status !== "failed" || typeof result.reason !== "string" || result.reason === "") {
|
|
68175
|
+
return;
|
|
68176
|
+
}
|
|
68177
|
+
const db2 = await this.ctx.getDb();
|
|
68178
|
+
await new RunDao(db2).stampFailureReason(runId, result.reason);
|
|
68179
|
+
}
|
|
67111
68180
|
async resolveWorkflowDefByName(name) {
|
|
67112
68181
|
const listing = await this.list();
|
|
67113
68182
|
const entry = listing.entries.find((e) => e.name === name && e.valid);
|
|
@@ -67233,19 +68302,21 @@ class WorkflowAppService {
|
|
|
67233
68302
|
}
|
|
67234
68303
|
async createEngineService(opts = {}) {
|
|
67235
68304
|
const host = createDefaultWorkflowEngineHost();
|
|
68305
|
+
const bus = this.ctx.observabilityBus?.();
|
|
67236
68306
|
registerSpurBuiltins(host, {
|
|
67237
68307
|
agentService: this.ctx.agentService(),
|
|
67238
68308
|
ruleService: this.ctx.ruleService(),
|
|
67239
68309
|
hitlResponder: this.ctx.hitlResponder(),
|
|
67240
68310
|
httpRequester: this.ctx.httpRequester?.(),
|
|
67241
|
-
hostAllowlist: this.ctx.hostAllowlist?.()
|
|
68311
|
+
hostAllowlist: this.ctx.hostAllowlist?.(),
|
|
68312
|
+
...bus !== undefined ? { observabilityBus: bus } : {},
|
|
68313
|
+
...opts.steeringController !== undefined ? { steeringController: opts.steeringController } : {}
|
|
67242
68314
|
});
|
|
67243
68315
|
const db2 = await this.ctx.getDb();
|
|
67244
68316
|
let persistence2 = new DbWorkflowPersistenceAdapter(db2);
|
|
67245
68317
|
if (opts.recordSelfPid === true) {
|
|
67246
68318
|
persistence2 = withSelfPidRecording(persistence2, db2);
|
|
67247
68319
|
}
|
|
67248
|
-
const bus = this.ctx.observabilityBus?.();
|
|
67249
68320
|
const adapter = bus ? new ObservableWorkflowAdapter(persistence2, bus) : persistence2;
|
|
67250
68321
|
return new WorkflowService(host, adapter);
|
|
67251
68322
|
}
|
|
@@ -67311,9 +68382,13 @@ async function extractWorkflowMeta(filePath) {
|
|
|
67311
68382
|
}
|
|
67312
68383
|
function rowToTraceEntry(row) {
|
|
67313
68384
|
let isDryRun = false;
|
|
68385
|
+
let failureReason;
|
|
67314
68386
|
try {
|
|
67315
68387
|
const meta3 = JSON.parse(row.metadata_json);
|
|
67316
68388
|
isDryRun = meta3.dryRun === true;
|
|
68389
|
+
if (typeof meta3.failureReason === "string" && meta3.failureReason !== "") {
|
|
68390
|
+
failureReason = meta3.failureReason;
|
|
68391
|
+
}
|
|
67317
68392
|
} catch {}
|
|
67318
68393
|
return {
|
|
67319
68394
|
runId: row.id,
|
|
@@ -67322,7 +68397,8 @@ function rowToTraceEntry(row) {
|
|
|
67322
68397
|
status: row.status,
|
|
67323
68398
|
startedAt: row.started_at,
|
|
67324
68399
|
completedAt: row.completed_at,
|
|
67325
|
-
isDryRun
|
|
68400
|
+
isDryRun,
|
|
68401
|
+
...failureReason !== undefined ? { failureReason } : {}
|
|
67326
68402
|
};
|
|
67327
68403
|
}
|
|
67328
68404
|
var TASK_PIPELINE_WORKFLOW = "task-pipeline", EMBEDDED_SCHEMA_PREFIX = "\x00embedded-spur", SPUR_SCHEMA_MANIFEST = "@gobing-ai/spur/package.json", PIPELINE_LINK_KIND = "pipeline";
|
|
@@ -67331,6 +68407,7 @@ var init_workflow_service = __esm(() => {
|
|
|
67331
68407
|
init_dist7();
|
|
67332
68408
|
init_dist5();
|
|
67333
68409
|
init_builtins2();
|
|
68410
|
+
init_observability();
|
|
67334
68411
|
});
|
|
67335
68412
|
|
|
67336
68413
|
// ../../packages/app/src/workflow/lifecycle-adapter.ts
|
|
@@ -67478,19 +68555,72 @@ var init_lifecycle_adapter = __esm(() => {
|
|
|
67478
68555
|
});
|
|
67479
68556
|
|
|
67480
68557
|
// ../../packages/app/src/workflow/step-reporter.ts
|
|
67481
|
-
function renderStepLine(event2) {
|
|
68558
|
+
function renderStepLine(event2, options = {}) {
|
|
68559
|
+
const detail = options.detail ?? "invocation";
|
|
68560
|
+
if (isAgentExecution(event2)) {
|
|
68561
|
+
if (event2.kind === "output") {
|
|
68562
|
+
if (detail === "minimal")
|
|
68563
|
+
return null;
|
|
68564
|
+
const label = event2.stream === "stderr" ? "stderr" : "stdout";
|
|
68565
|
+
return `[run ${event2.runId}] ${label}> ${event2.chunk.replace(/\s+$/, "")}`;
|
|
68566
|
+
}
|
|
68567
|
+
if (event2.kind === "heartbeat") {
|
|
68568
|
+
if (detail === "minimal")
|
|
68569
|
+
return null;
|
|
68570
|
+
const budget = event2.timeoutMs === undefined ? "unbounded" : `${formatDuration(Math.max(0, event2.timeoutMs - event2.elapsedMs))} remaining`;
|
|
68571
|
+
return `[run ${event2.runId}] \u2026 agent execution \xB7 elapsed=${formatDuration(event2.elapsedMs)} \xB7 budget=${budget}`;
|
|
68572
|
+
}
|
|
68573
|
+
if (event2.kind === "dropped") {
|
|
68574
|
+
return detail === "minimal" ? null : `[run ${event2.runId}] \u2026 output pressure \xB7 dropped=${event2.chunks} chunks`;
|
|
68575
|
+
}
|
|
68576
|
+
if (event2.kind === "started") {
|
|
68577
|
+
if (detail === "minimal")
|
|
68578
|
+
return null;
|
|
68579
|
+
const model = event2.model === undefined ? "" : `(${event2.model})`;
|
|
68580
|
+
const full2 = detail === "full" ? ` \xB7 execution=${event2.executionId}` : "";
|
|
68581
|
+
return `[run ${event2.runId}] agent=${event2.agent}${model} => ${event2.invocation}${full2}`;
|
|
68582
|
+
}
|
|
68583
|
+
const mark = event2.outcome === "done" ? "\u2713" : "\u2717";
|
|
68584
|
+
const full = detail === "full" ? ` \xB7 execution=${event2.executionId}` : "";
|
|
68585
|
+
return detail === "minimal" ? null : `[run ${event2.runId}] ${mark} agent ${event2.outcome} (${formatDuration(event2.durationMs)}) \xB7 usage ${event2.usage}${event2.reason ? ` \xB7 ${event2.reason}` : ""}${full}`;
|
|
68586
|
+
}
|
|
67482
68587
|
if (isActionFinished(event2)) {
|
|
67483
68588
|
const mark = event2.ok ? "\u2713" : "\u2717";
|
|
67484
|
-
|
|
68589
|
+
if (detail === "minimal")
|
|
68590
|
+
return ` ${mark} ${event2.status} (${formatDuration(event2.durationMs)})`;
|
|
68591
|
+
const failure = event2.result?.error === undefined ? "" : ` \xB7 ${event2.result.error}`;
|
|
68592
|
+
const full = detail === "full" ? ` \xB7 action=${event2.actionId} \xB7 seq=${event2.sequence}` : "";
|
|
68593
|
+
return `[run ${event2.runId}] ${mark} ${event2.node}/${event2.kind} (${formatDuration(event2.durationMs)}) \xB7 usage ${event2.result?.usage ?? "unavailable"}${failure}${full}`;
|
|
67485
68594
|
}
|
|
67486
68595
|
if (isActionStarted(event2)) {
|
|
67487
|
-
|
|
68596
|
+
if (detail === "minimal")
|
|
68597
|
+
return ` \u2192 ${event2.node}: ${event2.kind}\u2026`;
|
|
68598
|
+
const agent = event2.metadata?.agent ?? "unavailable";
|
|
68599
|
+
const model = event2.metadata?.model ?? "unavailable";
|
|
68600
|
+
const invocation = event2.metadata?.invocation ?? "unavailable";
|
|
68601
|
+
const timeout = event2.metadata?.timeoutMs === undefined ? "unbounded" : formatDuration(event2.metadata.timeoutMs);
|
|
68602
|
+
const full = detail === "full" ? ` \xB7 action=${event2.actionId} \xB7 seq=${event2.sequence}` : "";
|
|
68603
|
+
return `[run ${event2.runId}] \u2192 ${event2.node}/${event2.kind} \xB7 agent=${agent} \xB7 model=${model} => ${invocation} \xB7 timeout=${timeout}${full}`;
|
|
67488
68604
|
}
|
|
67489
68605
|
if (isPhase(event2)) {
|
|
67490
|
-
return `\u25B6 ${event2.phase} [${event2.status}]`;
|
|
68606
|
+
return detail === "minimal" ? `\u25B6 ${event2.phase} [${event2.status}]` : `[run ${event2.runId}] \u25B6 ${event2.phase} [${event2.status}]`;
|
|
68607
|
+
}
|
|
68608
|
+
if (isTransition(event2)) {
|
|
68609
|
+
if (detail !== "full")
|
|
68610
|
+
return null;
|
|
68611
|
+
return `[run ${event2.runId}] \u21AA ${event2.from} \u2192 ${event2.to}${event2.trigger ? ` [${event2.trigger}]` : ""} \xB7 seq=${event2.sequence}`;
|
|
67491
68612
|
}
|
|
67492
68613
|
return null;
|
|
67493
68614
|
}
|
|
68615
|
+
function renderActionHeartbeat(event2, elapsedMs, options = {}) {
|
|
68616
|
+
const detail = options.detail ?? "invocation";
|
|
68617
|
+
if (detail === "minimal")
|
|
68618
|
+
return null;
|
|
68619
|
+
const elapsed = formatDuration(elapsedMs);
|
|
68620
|
+
const budget = event2.metadata?.timeoutMs === undefined ? "unbounded" : `${formatDuration(Math.max(0, event2.metadata.timeoutMs - elapsedMs))} remaining`;
|
|
68621
|
+
const full = detail === "full" ? ` \xB7 action=${event2.actionId}` : "";
|
|
68622
|
+
return `[run ${event2.runId}] \u2026 ${event2.node}/${event2.kind} \xB7 elapsed=${elapsed} \xB7 budget=${budget}${full}`;
|
|
68623
|
+
}
|
|
67494
68624
|
function renderRunPlan(def) {
|
|
67495
68625
|
const steps = def.kind === "transition-flow" ? def.nodes.map((n2) => n2.id) : def.states.map((s) => s.id);
|
|
67496
68626
|
return `plan: ${steps.join(" \u2192 ")}`;
|
|
@@ -67503,7 +68633,49 @@ function formatDuration(ms) {
|
|
|
67503
68633
|
const seconds = totalSeconds % 60;
|
|
67504
68634
|
return `${minutes}m ${seconds}s`;
|
|
67505
68635
|
}
|
|
67506
|
-
var isActionStarted = (e) => ("kind" in e) && ("node" in e), isActionFinished = (e) => ("durationMs" in e) && ("ok" in e), isPhase = (e) => ("phase" in e);
|
|
68636
|
+
var isAgentExecution = (e) => ("executionId" in e), isActionStarted = (e) => ("kind" in e) && ("node" in e), isActionFinished = (e) => ("durationMs" in e) && ("ok" in e), isPhase = (e) => ("phase" in e), isTransition = (e) => ("from" in e) && ("to" in e);
|
|
68637
|
+
|
|
68638
|
+
// ../../packages/app/src/workflow/trace-writer.ts
|
|
68639
|
+
import { appendFile, mkdir as mkdir2 } from "fs/promises";
|
|
68640
|
+
import { dirname as dirname12, join as join14 } from "path";
|
|
68641
|
+
|
|
68642
|
+
class WorkflowTraceWriter {
|
|
68643
|
+
path;
|
|
68644
|
+
sequence = 0;
|
|
68645
|
+
pending = Promise.resolve();
|
|
68646
|
+
constructor(cwd, runId) {
|
|
68647
|
+
const safeRunId = runId.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
68648
|
+
this.path = join14(cwd, ".spur", "runs", "workflow", `${safeRunId}.jsonl`);
|
|
68649
|
+
}
|
|
68650
|
+
attach(bus) {
|
|
68651
|
+
bus.on("workflow.run.started", (event2) => this.enqueue("workflow.run.started", event2));
|
|
68652
|
+
bus.on("workflow.run.finalized", (event2) => this.enqueue("workflow.run.finalized", event2));
|
|
68653
|
+
bus.on("workflow.phase", (event2) => this.enqueue("workflow.phase", event2));
|
|
68654
|
+
bus.on("workflow.transition", (event2) => this.enqueue("workflow.transition", event2));
|
|
68655
|
+
bus.on("workflow.action.started", (event2) => this.enqueue("workflow.action.started", event2));
|
|
68656
|
+
bus.on("workflow.action.finished", (event2) => this.enqueue("workflow.action.finished", event2));
|
|
68657
|
+
bus.on("workflow.agent", (event2) => this.enqueue("workflow.agent", event2));
|
|
68658
|
+
bus.on("workflow.steering", (event2) => this.enqueue("workflow.steering", event2));
|
|
68659
|
+
}
|
|
68660
|
+
async flush() {
|
|
68661
|
+
await this.pending;
|
|
68662
|
+
}
|
|
68663
|
+
enqueue(type, event2) {
|
|
68664
|
+
this.sequence += 1;
|
|
68665
|
+
const line = `${JSON.stringify({
|
|
68666
|
+
traceSchemaVersion: 1,
|
|
68667
|
+
traceSequence: this.sequence,
|
|
68668
|
+
type,
|
|
68669
|
+
event: event2
|
|
68670
|
+
})}
|
|
68671
|
+
`;
|
|
68672
|
+
this.pending = this.pending.then(async () => {
|
|
68673
|
+
await mkdir2(dirname12(this.path), { recursive: true });
|
|
68674
|
+
await appendFile(this.path, line, "utf8");
|
|
68675
|
+
});
|
|
68676
|
+
}
|
|
68677
|
+
}
|
|
68678
|
+
var init_trace_writer = () => {};
|
|
67507
68679
|
|
|
67508
68680
|
// ../../packages/app/src/index.ts
|
|
67509
68681
|
var exports_src2 = {};
|
|
@@ -67517,11 +68689,14 @@ __export(exports_src2, {
|
|
|
67517
68689
|
renderSolutionFromDiff: () => renderSolutionFromDiff,
|
|
67518
68690
|
renderRunPlan: () => renderRunPlan,
|
|
67519
68691
|
renderReview: () => renderReview,
|
|
68692
|
+
renderActionHeartbeat: () => renderActionHeartbeat,
|
|
67520
68693
|
registerSystemEventTap: () => registerSystemEventTap,
|
|
67521
68694
|
registerSpurBuiltins: () => registerSpurBuiltins,
|
|
68695
|
+
redactAndBound: () => redactAndBound,
|
|
67522
68696
|
readVerdictArtifact: () => readVerdictArtifact,
|
|
67523
68697
|
readVerdict: () => readVerdict,
|
|
67524
68698
|
parseVerdict: () => parseVerdict,
|
|
68699
|
+
parseSteeringPolicy: () => parseSteeringPolicy,
|
|
67525
68700
|
parsePsOutput: () => parsePsOutput,
|
|
67526
68701
|
parseLedgerLine: () => parseLedgerLine,
|
|
67527
68702
|
parseEtimeToSeconds: () => parseEtimeToSeconds,
|
|
@@ -67537,9 +68712,14 @@ __export(exports_src2, {
|
|
|
67537
68712
|
evaluateDoneTransition: () => evaluateDoneTransition,
|
|
67538
68713
|
deriveVerdict: () => deriveVerdict,
|
|
67539
68714
|
createPsProcessInspector: () => createPsProcessInspector,
|
|
68715
|
+
configuredSecretValues: () => configuredSecretValues,
|
|
67540
68716
|
computeAggregate: () => computeAggregate,
|
|
68717
|
+
classifyTaskOutcome: () => classifyTaskOutcome,
|
|
67541
68718
|
clampToolUseLimit: () => clampToolUseLimit,
|
|
67542
68719
|
bridgeEventBus: () => bridgeEventBus,
|
|
68720
|
+
aggregateBatchVerdicts: () => aggregateBatchVerdicts,
|
|
68721
|
+
WorkflowTraceWriter: () => WorkflowTraceWriter,
|
|
68722
|
+
WorkflowSteeringController: () => WorkflowSteeringController,
|
|
67543
68723
|
WorkflowAppService: () => WorkflowAppService,
|
|
67544
68724
|
UnsupportedProcessPlatformError: () => UnsupportedProcessPlatformError,
|
|
67545
68725
|
TokenLedgerWatcher: () => TokenLedgerWatcher,
|
|
@@ -67588,17 +68768,20 @@ __export(exports_src2, {
|
|
|
67588
68768
|
FeatureCheckService: () => FeatureCheckService,
|
|
67589
68769
|
FINDING_CODES: () => FINDING_CODES,
|
|
67590
68770
|
FEATURE_LIFECYCLE_PROFILE: () => FEATURE_LIFECYCLE_PROFILE,
|
|
68771
|
+
DuplicateFollowUpError: () => DuplicateFollowUpError,
|
|
67591
68772
|
DependencyMutationError: () => DependencyMutationError,
|
|
67592
68773
|
DEFAULT_FEATURE_MATRIX: () => DEFAULT_FEATURE_MATRIX,
|
|
67593
68774
|
CorpusMigrator: () => CorpusMigrator,
|
|
67594
68775
|
BusPlanningEventEmitter: () => BusPlanningEventEmitter,
|
|
67595
68776
|
AgentService: () => AgentService,
|
|
67596
68777
|
AgentRunActionRunner: () => AgentRunActionRunner,
|
|
68778
|
+
AgentExecutionLifecycle: () => AgentExecutionLifecycle,
|
|
67597
68779
|
ALL_FINDING_CODES: () => ALL_FINDING_CODES
|
|
67598
68780
|
});
|
|
67599
68781
|
var init_src3 = __esm(() => {
|
|
67600
68782
|
init_planning_folders();
|
|
67601
68783
|
init_errors5();
|
|
68784
|
+
init_agent_execution();
|
|
67602
68785
|
init_agent_service();
|
|
67603
68786
|
init_corpus_migrator();
|
|
67604
68787
|
init_event_names();
|
|
@@ -67619,6 +68802,7 @@ var init_src3 = __esm(() => {
|
|
|
67619
68802
|
init_task_record();
|
|
67620
68803
|
init_task_scaffold();
|
|
67621
68804
|
init_task_service();
|
|
68805
|
+
init_task_verdict();
|
|
67622
68806
|
init_team_service();
|
|
67623
68807
|
init_token_ledger_service();
|
|
67624
68808
|
init_token_ledger_watcher();
|
|
@@ -67630,6 +68814,9 @@ var init_src3 = __esm(() => {
|
|
|
67630
68814
|
init_rule_check();
|
|
67631
68815
|
init_builtins2();
|
|
67632
68816
|
init_lifecycle_adapter();
|
|
68817
|
+
init_observability();
|
|
68818
|
+
init_steering();
|
|
68819
|
+
init_trace_writer();
|
|
67633
68820
|
});
|
|
67634
68821
|
|
|
67635
68822
|
// ../../node_modules/.bun/sisteransi@1.0.5/node_modules/sisteransi/src/index.js
|
|
@@ -67710,19 +68897,19 @@ var {
|
|
|
67710
68897
|
init_src();
|
|
67711
68898
|
init_loader();
|
|
67712
68899
|
|
|
67713
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
68900
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/application-node.js
|
|
67714
68901
|
init_dist4();
|
|
67715
68902
|
init_dist5();
|
|
67716
68903
|
import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync5 } from "fs";
|
|
67717
68904
|
import { dirname as dirname5 } from "path";
|
|
67718
68905
|
|
|
67719
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
68906
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/application/index.js
|
|
67720
68907
|
init_default_observers();
|
|
67721
68908
|
init_event_bus();
|
|
67722
68909
|
init_file_observer();
|
|
67723
68910
|
init_logger3();
|
|
67724
68911
|
|
|
67725
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
68912
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/scheduler/noop.js
|
|
67726
68913
|
class NoopSchedulerAdapter {
|
|
67727
68914
|
constructor() {}
|
|
67728
68915
|
register(_cron, _action) {}
|
|
@@ -67730,7 +68917,7 @@ class NoopSchedulerAdapter {
|
|
|
67730
68917
|
async stop() {}
|
|
67731
68918
|
}
|
|
67732
68919
|
|
|
67733
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
68920
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/scheduler/factory.js
|
|
67734
68921
|
function initScheduler(adapter, cronEntries) {
|
|
67735
68922
|
const resolved = adapter ?? new NoopSchedulerAdapter;
|
|
67736
68923
|
if (cronEntries) {
|
|
@@ -67741,7 +68928,7 @@ function initScheduler(adapter, cronEntries) {
|
|
|
67741
68928
|
return resolved;
|
|
67742
68929
|
}
|
|
67743
68930
|
|
|
67744
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
68931
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/application/plugins/builtins.js
|
|
67745
68932
|
init_logger3();
|
|
67746
68933
|
init_metrics();
|
|
67747
68934
|
init_sdk();
|
|
@@ -67834,7 +69021,7 @@ function dbPlugin(db2) {
|
|
|
67834
69021
|
};
|
|
67835
69022
|
}
|
|
67836
69023
|
|
|
67837
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
69024
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/application/plugins/host.js
|
|
67838
69025
|
init_logger3();
|
|
67839
69026
|
|
|
67840
69027
|
class PluginHost {
|
|
@@ -67922,7 +69109,7 @@ class PluginHost {
|
|
|
67922
69109
|
}
|
|
67923
69110
|
}
|
|
67924
69111
|
|
|
67925
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
69112
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/application/index.js
|
|
67926
69113
|
async function performShutdown(state, reason) {
|
|
67927
69114
|
if (state.stopped)
|
|
67928
69115
|
return;
|
|
@@ -68033,10 +69220,10 @@ async function runApplication(options) {
|
|
|
68033
69220
|
}
|
|
68034
69221
|
}
|
|
68035
69222
|
|
|
68036
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
69223
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/application-node.js
|
|
68037
69224
|
init_scheduler_node();
|
|
68038
69225
|
|
|
68039
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
69226
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
|
|
68040
69227
|
var import_api14 = __toESM(require_src(), 1);
|
|
68041
69228
|
|
|
68042
69229
|
// ../../node_modules/.bun/@opentelemetry+exporter-metrics-otlp-http@0.218.0+e40b0dfdd726a224/node_modules/@opentelemetry/exporter-metrics-otlp-http/build/esm/OTLPMetricExporterBase.js
|
|
@@ -71052,7 +72239,7 @@ class OTLPTraceExporter extends import_otlp_exporter_base2.OTLPExporterBase {
|
|
|
71052
72239
|
}), JsonTraceSerializer));
|
|
71053
72240
|
}
|
|
71054
72241
|
}
|
|
71055
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
72242
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
|
|
71056
72243
|
var import_resources2 = __toESM(require_src4(), 1);
|
|
71057
72244
|
var import_sdk_trace_node = __toESM(require_src8(), 1);
|
|
71058
72245
|
var import_semantic_conventions = __toESM(require_src2(), 1);
|
|
@@ -71103,7 +72290,7 @@ async function shutdownNodeTelemetry() {
|
|
|
71103
72290
|
await Promise.all(pending);
|
|
71104
72291
|
}
|
|
71105
72292
|
|
|
71106
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
72293
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.14+a32276a722fab3c8/node_modules/@gobing-ai/ts-infra/dist/application-node.js
|
|
71107
72294
|
class ConfigValidationError extends Error {
|
|
71108
72295
|
constructor(message) {
|
|
71109
72296
|
super(message);
|
|
@@ -75194,7 +76381,7 @@ init_loader();
|
|
|
75194
76381
|
init_src2();
|
|
75195
76382
|
import { existsSync as existsSync8 } from "fs";
|
|
75196
76383
|
import { homedir as homedir4 } from "os";
|
|
75197
|
-
import { join as
|
|
76384
|
+
import { join as join15, resolve as resolve3 } from "path";
|
|
75198
76385
|
|
|
75199
76386
|
// src/workflow/resolve-spur-bin.ts
|
|
75200
76387
|
import { basename as basename2 } from "path";
|
|
@@ -75212,22 +76399,22 @@ function resolveSpurBin() {
|
|
|
75212
76399
|
}
|
|
75213
76400
|
|
|
75214
76401
|
// src/workflow/make-lifecycle-adapter.ts
|
|
75215
|
-
var GLOBAL_CONFIG_DIR =
|
|
76402
|
+
var GLOBAL_CONFIG_DIR = join15(".config", "spur");
|
|
75216
76403
|
function globalConfigRoot(context4) {
|
|
75217
76404
|
const override = context4.env.SPUR_GLOBAL_RULES_DIR;
|
|
75218
|
-
return override !== undefined && override.length > 0 ? resolve3(context4.cwd, override) :
|
|
76405
|
+
return override !== undefined && override.length > 0 ? resolve3(context4.cwd, override) : join15(homedir4(), GLOBAL_CONFIG_DIR);
|
|
75219
76406
|
}
|
|
75220
76407
|
function resolveWorkflowPath(context4, profile) {
|
|
75221
76408
|
const bundledRoot = bundledConfigRoot();
|
|
75222
76409
|
if (bundledRoot !== null) {
|
|
75223
|
-
const bundledPath =
|
|
76410
|
+
const bundledPath = join15(bundledRoot, "workflows", `${profile.workflowName}.yaml`);
|
|
75224
76411
|
if (existsSync8(bundledPath))
|
|
75225
76412
|
return bundledPath;
|
|
75226
76413
|
}
|
|
75227
|
-
const projectPath =
|
|
76414
|
+
const projectPath = join15(context4.cwd, ".spur", "workflows", `${profile.workflowName}.yaml`);
|
|
75228
76415
|
if (existsSync8(projectPath))
|
|
75229
76416
|
return projectPath;
|
|
75230
|
-
const globalPath =
|
|
76417
|
+
const globalPath = join15(globalConfigRoot(context4), "workflows", `${profile.workflowName}.yaml`);
|
|
75231
76418
|
if (existsSync8(globalPath))
|
|
75232
76419
|
return globalPath;
|
|
75233
76420
|
return null;
|
|
@@ -75482,6 +76669,7 @@ function registerFeatureCommand(program2, context4) {
|
|
|
75482
76669
|
strict,
|
|
75483
76670
|
featuresDir,
|
|
75484
76671
|
tasksDir,
|
|
76672
|
+
runDir: context4.fs.resolve(".spur/run"),
|
|
75485
76673
|
severityOverrides: resolved.severityOverrides
|
|
75486
76674
|
});
|
|
75487
76675
|
results.push(result);
|
|
@@ -75554,7 +76742,13 @@ async function makeService(context4, folderOverride) {
|
|
|
75554
76742
|
...lifecycle ? { lifecycle } : {},
|
|
75555
76743
|
emitter: makePlanningEmitter(context4)
|
|
75556
76744
|
});
|
|
75557
|
-
return new FeatureService({
|
|
76745
|
+
return new FeatureService({
|
|
76746
|
+
fs: context4.fs,
|
|
76747
|
+
writeService,
|
|
76748
|
+
featuresDir,
|
|
76749
|
+
tasksDir,
|
|
76750
|
+
foldersConfig: resolved.foldersConfig
|
|
76751
|
+
});
|
|
75558
76752
|
}
|
|
75559
76753
|
async function assertFeatureCheckPass(context4, id, folderOverride, strict) {
|
|
75560
76754
|
const resolved = await resolvePlanningFolders(context4.fs);
|
|
@@ -75622,13 +76816,13 @@ init_loader();
|
|
|
75622
76816
|
init_src2();
|
|
75623
76817
|
init_dist10();
|
|
75624
76818
|
import { homedir as homedir5 } from "os";
|
|
75625
|
-
import { join as
|
|
76819
|
+
import { join as join16, resolve as resolve4 } from "path";
|
|
75626
76820
|
|
|
75627
76821
|
// src/config.ts
|
|
75628
76822
|
var CLI_CONFIG = {
|
|
75629
76823
|
binaryName: "spur",
|
|
75630
76824
|
binaryLabel: "spur",
|
|
75631
|
-
binaryVersion: "0.3.
|
|
76825
|
+
binaryVersion: "0.3.25",
|
|
75632
76826
|
configDir: ".spur",
|
|
75633
76827
|
configFile: ".spur/config.yaml",
|
|
75634
76828
|
databaseFile: ".spur/spur.db"
|
|
@@ -75679,8 +76873,8 @@ var SCAFFOLD_MANIFEST = [
|
|
|
75679
76873
|
];
|
|
75680
76874
|
|
|
75681
76875
|
// src/commands/init.ts
|
|
75682
|
-
var GLOBAL_CONFIG_DIR2 =
|
|
75683
|
-
var GLOBAL_RULES_DIR2 =
|
|
76876
|
+
var GLOBAL_CONFIG_DIR2 = join16(".config", "spur");
|
|
76877
|
+
var GLOBAL_RULES_DIR2 = join16(GLOBAL_CONFIG_DIR2, "rules");
|
|
75684
76878
|
var GLOBAL_CONFIG_EXAMPLE = "config.example.yaml";
|
|
75685
76879
|
var GLOBAL_CONFIG_FILE2 = "config.yaml";
|
|
75686
76880
|
var INDEXED_CONTEXT_MARKER = "## Indexed context";
|
|
@@ -75711,7 +76905,7 @@ If \`.spur/context/\` is absent, proceed normally. Never block work on its absen
|
|
|
75711
76905
|
`;
|
|
75712
76906
|
function globalRulesRoot(context4) {
|
|
75713
76907
|
const override = context4.env.SPUR_GLOBAL_RULES_DIR;
|
|
75714
|
-
return override !== undefined && override.length > 0 ? resolve4(context4.cwd, override) :
|
|
76908
|
+
return override !== undefined && override.length > 0 ? resolve4(context4.cwd, override) : join16(homedir5(), GLOBAL_RULES_DIR2);
|
|
75715
76909
|
}
|
|
75716
76910
|
async function writeIfNew(context4, path9, content, force, result) {
|
|
75717
76911
|
if (!force && await context4.fs.exists(path9)) {
|
|
@@ -75728,11 +76922,11 @@ async function seedGlobalRules(context4) {
|
|
|
75728
76922
|
const target = globalRulesRoot(context4);
|
|
75729
76923
|
let written = 0;
|
|
75730
76924
|
for (const relPath of await listBundledRuleFiles()) {
|
|
75731
|
-
const destination =
|
|
76925
|
+
const destination = join16(target, relPath);
|
|
75732
76926
|
if (await context4.fs.exists(destination))
|
|
75733
76927
|
continue;
|
|
75734
|
-
await context4.fs.ensureDir(
|
|
75735
|
-
await context4.fs.writeFile(destination, await context4.fs.readFile(
|
|
76928
|
+
await context4.fs.ensureDir(join16(target, ...relPath.split("/").slice(0, -1)));
|
|
76929
|
+
await context4.fs.writeFile(destination, await context4.fs.readFile(join16(source, relPath)));
|
|
75736
76930
|
written += 1;
|
|
75737
76931
|
}
|
|
75738
76932
|
return written;
|
|
@@ -75742,20 +76936,20 @@ async function seedGlobalConfig(context4) {
|
|
|
75742
76936
|
if (source === null)
|
|
75743
76937
|
return 0;
|
|
75744
76938
|
const globalOverride = context4.env.SPUR_GLOBAL_RULES_DIR;
|
|
75745
|
-
const target = globalOverride !== undefined && globalOverride.length > 0 ? resolve4(context4.cwd, globalOverride) :
|
|
76939
|
+
const target = globalOverride !== undefined && globalOverride.length > 0 ? resolve4(context4.cwd, globalOverride) : join16(homedir5(), GLOBAL_CONFIG_DIR2);
|
|
75746
76940
|
let written = 0;
|
|
75747
76941
|
for (const relPath of listBundledConfigFiles()) {
|
|
75748
76942
|
if (relPath === GLOBAL_CONFIG_EXAMPLE)
|
|
75749
76943
|
continue;
|
|
75750
|
-
const destination =
|
|
76944
|
+
const destination = join16(target, relPath);
|
|
75751
76945
|
if (await context4.fs.exists(destination))
|
|
75752
76946
|
continue;
|
|
75753
|
-
await context4.fs.ensureDir(
|
|
75754
|
-
await context4.fs.writeFile(destination, await context4.fs.readFile(
|
|
76947
|
+
await context4.fs.ensureDir(join16(target, ...relPath.split("/").slice(0, -1)));
|
|
76948
|
+
await context4.fs.writeFile(destination, await context4.fs.readFile(join16(source, relPath)));
|
|
75755
76949
|
written += 1;
|
|
75756
76950
|
}
|
|
75757
|
-
const examplePath =
|
|
75758
|
-
const globalConfigPath =
|
|
76951
|
+
const examplePath = join16(source, GLOBAL_CONFIG_EXAMPLE);
|
|
76952
|
+
const globalConfigPath = join16(target, GLOBAL_CONFIG_FILE2);
|
|
75759
76953
|
if (await context4.fs.exists(examplePath) && !await context4.fs.exists(globalConfigPath)) {
|
|
75760
76954
|
await context4.fs.ensureDir(target);
|
|
75761
76955
|
await context4.fs.writeFile(globalConfigPath, await context4.fs.readFile(examplePath));
|
|
@@ -75769,7 +76963,7 @@ function registerInitCommand(program2, context4) {
|
|
|
75769
76963
|
const force = options.force === true;
|
|
75770
76964
|
const minimal = options.minimal === true;
|
|
75771
76965
|
const projectName = options.name ?? "default";
|
|
75772
|
-
const configPath =
|
|
76966
|
+
const configPath = join16(context4.cwd, CLI_CONFIG.configFile);
|
|
75773
76967
|
if (!force && await context4.fs.exists(configPath)) {
|
|
75774
76968
|
const message = `Already initialized: ${CLI_CONFIG.configFile}. Use --force to overwrite.`;
|
|
75775
76969
|
context4.output.write(json3 ? toJson2({ ok: false, reason: "already-initialized", config: CLI_CONFIG.configFile }) : message);
|
|
@@ -75782,7 +76976,7 @@ function registerInitCommand(program2, context4) {
|
|
|
75782
76976
|
`# Generated by \`spur init\``,
|
|
75783
76977
|
"",
|
|
75784
76978
|
'$schema: "@gobing-ai/spur/schemas/spur-config.schema.json"',
|
|
75785
|
-
`version: "1"`,
|
|
76979
|
+
`version: "1.1"`,
|
|
75786
76980
|
`name: ${projectName}`,
|
|
75787
76981
|
"",
|
|
75788
76982
|
"bootstrap:",
|
|
@@ -75804,13 +76998,13 @@ function registerInitCommand(program2, context4) {
|
|
|
75804
76998
|
].join(`
|
|
75805
76999
|
`)}
|
|
75806
77000
|
`;
|
|
75807
|
-
await context4.fs.ensureDir(
|
|
77001
|
+
await context4.fs.ensureDir(join16(context4.cwd, CLI_CONFIG.configDir));
|
|
75808
77002
|
await context4.fs.writeFile(configPath, configYaml);
|
|
75809
77003
|
result.created.push(configPath);
|
|
75810
|
-
const agentsDir =
|
|
77004
|
+
const agentsDir = join16(context4.cwd, CLI_CONFIG.configDir, "agents");
|
|
75811
77005
|
await context4.fs.ensureDir(agentsDir);
|
|
75812
|
-
await writeIfNew(context4,
|
|
75813
|
-
const gitignorePath =
|
|
77006
|
+
await writeIfNew(context4, join16(agentsDir, ".gitkeep"), "", force, result);
|
|
77007
|
+
const gitignorePath = join16(context4.cwd, ".gitignore");
|
|
75814
77008
|
const contextEntry = ".spur/context/";
|
|
75815
77009
|
if (await context4.fs.exists(gitignorePath)) {
|
|
75816
77010
|
const existing = await context4.fs.readFile(gitignorePath);
|
|
@@ -75832,20 +77026,20 @@ ${contextEntry}
|
|
|
75832
77026
|
for (const relPath of listBundledProjectSeedFiles()) {
|
|
75833
77027
|
if (relPath.startsWith("templates/docs/"))
|
|
75834
77028
|
continue;
|
|
75835
|
-
const sourcePath =
|
|
77029
|
+
const sourcePath = join16(configRoot, relPath);
|
|
75836
77030
|
if (!await context4.fs.exists(sourcePath))
|
|
75837
77031
|
continue;
|
|
75838
|
-
const targetPath =
|
|
75839
|
-
await context4.fs.ensureDir(
|
|
77032
|
+
const targetPath = join16(context4.cwd, CLI_CONFIG.configDir, relPath);
|
|
77033
|
+
await context4.fs.ensureDir(join16(targetPath, ".."));
|
|
75840
77034
|
await writeIfNew(context4, targetPath, await context4.fs.readFile(sourcePath), force, result);
|
|
75841
77035
|
}
|
|
75842
77036
|
for (const entry of SCAFFOLD_MANIFEST) {
|
|
75843
|
-
const sourcePath =
|
|
77037
|
+
const sourcePath = join16(configRoot, entry.source);
|
|
75844
77038
|
if (!await context4.fs.exists(sourcePath))
|
|
75845
77039
|
continue;
|
|
75846
|
-
const baseDir = entry.root === true ? context4.cwd :
|
|
75847
|
-
const targetPath =
|
|
75848
|
-
await context4.fs.ensureDir(
|
|
77040
|
+
const baseDir = entry.root === true ? context4.cwd : join16(context4.cwd, CLI_CONFIG.configDir);
|
|
77041
|
+
const targetPath = join16(baseDir, entry.target);
|
|
77042
|
+
await context4.fs.ensureDir(join16(targetPath, ".."));
|
|
75849
77043
|
const entryForce = entry.preserve === true ? false : force;
|
|
75850
77044
|
let body = await context4.fs.readFile(sourcePath);
|
|
75851
77045
|
if (entry.target === "AGENTS.md") {
|
|
@@ -75858,7 +77052,7 @@ ${contextEntry}
|
|
|
75858
77052
|
}
|
|
75859
77053
|
}
|
|
75860
77054
|
}
|
|
75861
|
-
const agentsMdPath =
|
|
77055
|
+
const agentsMdPath = join16(context4.cwd, "AGENTS.md");
|
|
75862
77056
|
if (await context4.fs.exists(agentsMdPath)) {
|
|
75863
77057
|
const existing = await context4.fs.readFile(agentsMdPath);
|
|
75864
77058
|
if (!existing.includes(INDEXED_CONTEXT_MARKER)) {
|
|
@@ -76036,10 +77230,10 @@ function parseInterval2(raw) {
|
|
|
76036
77230
|
|
|
76037
77231
|
// src/commands/migrate.ts
|
|
76038
77232
|
init_src2();
|
|
76039
|
-
import { join as
|
|
77233
|
+
import { join as join17 } from "path";
|
|
76040
77234
|
function registerMigrateCommand(program2, context4) {
|
|
76041
77235
|
program2.command("migrate").summary("apply CLI-owned schema migrations").option("--json", "Output machine-readable JSON").action(async (options) => {
|
|
76042
|
-
const migrations = await loadSqlMigrations(
|
|
77236
|
+
const migrations = await loadSqlMigrations(join17(context4.cwd, "drizzle")).catch(() => {
|
|
76043
77237
|
return;
|
|
76044
77238
|
});
|
|
76045
77239
|
const applied = await applyCliMigrations(await context4.getDb(), migrations);
|
|
@@ -76291,7 +77485,7 @@ function formatTraceDetail(detail) {
|
|
|
76291
77485
|
|
|
76292
77486
|
// src/commands/serve.ts
|
|
76293
77487
|
init_src();
|
|
76294
|
-
import { join as
|
|
77488
|
+
import { join as join21 } from "path";
|
|
76295
77489
|
|
|
76296
77490
|
// ../server/src/index.ts
|
|
76297
77491
|
init_src();
|
|
@@ -76301,11 +77495,11 @@ init_src3();
|
|
|
76301
77495
|
init_src();
|
|
76302
77496
|
init_loader();
|
|
76303
77497
|
init_src2();
|
|
76304
|
-
import { dirname as
|
|
77498
|
+
import { dirname as dirname14, isAbsolute as isAbsolute3, join as join20 } from "path";
|
|
76305
77499
|
init_dist5();
|
|
76306
77500
|
|
|
76307
77501
|
// ../server/src/bootstrap.ts
|
|
76308
|
-
import { join as
|
|
77502
|
+
import { join as join18 } from "path";
|
|
76309
77503
|
|
|
76310
77504
|
// ../../node_modules/.bun/radash@12.1.1/node_modules/radash/dist/esm/async.mjs
|
|
76311
77505
|
var guard = (func, shouldGuard) => {
|
|
@@ -84945,7 +86139,7 @@ function createApp(appRt, opts) {
|
|
|
84945
86139
|
app.use("*", async (c3, next) => {
|
|
84946
86140
|
const pathname = c3.req.path === "/" ? "/index.html" : c3.req.path;
|
|
84947
86141
|
try {
|
|
84948
|
-
const file2 = Bun.file(
|
|
86142
|
+
const file2 = Bun.file(join18(webDistPath, pathname));
|
|
84949
86143
|
if (await file2.exists()) {
|
|
84950
86144
|
const headers = new Headers({ "content-type": file2.type });
|
|
84951
86145
|
return new Response(file2.stream(), { headers });
|
|
@@ -84958,7 +86152,7 @@ function createApp(appRt, opts) {
|
|
|
84958
86152
|
return c3.json({ error: "Not Found" }, 404);
|
|
84959
86153
|
}
|
|
84960
86154
|
try {
|
|
84961
|
-
const indexFile = Bun.file(
|
|
86155
|
+
const indexFile = Bun.file(join18(webDistPath, "index.html"));
|
|
84962
86156
|
if (await indexFile.exists()) {
|
|
84963
86157
|
return new Response(indexFile.stream(), {
|
|
84964
86158
|
headers: { "content-type": "text/html; charset=utf-8" }
|
|
@@ -84979,7 +86173,7 @@ init_src3();
|
|
|
84979
86173
|
init_src();
|
|
84980
86174
|
init_src2();
|
|
84981
86175
|
init_dist5();
|
|
84982
|
-
import { dirname as
|
|
86176
|
+
import { dirname as dirname13, join as join19 } from "path";
|
|
84983
86177
|
var NOOP_OUTPUT = { write: (_s) => {}, error: (_s) => {} };
|
|
84984
86178
|
|
|
84985
86179
|
class LazyPlanningEventEmitter {
|
|
@@ -85014,7 +86208,7 @@ class NotConfiguredError extends Error {
|
|
|
85014
86208
|
function createServerContext(appRt, options) {
|
|
85015
86209
|
const cwd = options.cwd;
|
|
85016
86210
|
const fs3 = options.fs;
|
|
85017
|
-
const dbUrl = options.dbUrl ??
|
|
86211
|
+
const dbUrl = options.dbUrl ?? join19(cwd, DEFAULT_DATABASE_URL);
|
|
85018
86212
|
const eventsBus = options.eventsBus ?? appRt.events;
|
|
85019
86213
|
const jobQueueEnabled = options.jobQueueEnabled ?? false;
|
|
85020
86214
|
const folders = options.folders ?? DEFAULT_PLANNING_FOLDERS;
|
|
@@ -85048,7 +86242,7 @@ function createServerContext(appRt, options) {
|
|
|
85048
86242
|
if (!dbPromise) {
|
|
85049
86243
|
const created = (async () => {
|
|
85050
86244
|
if (dbUrl !== IN_MEMORY_DATABASE_URL) {
|
|
85051
|
-
await fs3.ensureDir(
|
|
86245
|
+
await fs3.ensureDir(dirname13(dbUrl));
|
|
85052
86246
|
}
|
|
85053
86247
|
return createMigratedDbViaRuntime({ url: dbUrl });
|
|
85054
86248
|
})();
|
|
@@ -85085,6 +86279,7 @@ function createServerContext(appRt, options) {
|
|
|
85085
86279
|
writeService: new PlanningWriteService({ fs: fs3, projectName: "spur", emitter: lazyEmitter }),
|
|
85086
86280
|
featuresDir: folders.featuresDir,
|
|
85087
86281
|
tasksDir: folders.tasksDir,
|
|
86282
|
+
foldersConfig: folders.foldersConfig,
|
|
85088
86283
|
projectName: "spur"
|
|
85089
86284
|
});
|
|
85090
86285
|
}
|
|
@@ -85314,15 +86509,15 @@ async function runTaskActionJob(ctx, env, payload, createAgentService = createTa
|
|
|
85314
86509
|
}
|
|
85315
86510
|
}
|
|
85316
86511
|
async function resolveWebDistPath(configuredPath) {
|
|
85317
|
-
const candidates = configuredPath && configuredPath.trim() !== "" ? [isAbsolute3(configuredPath) ? configuredPath :
|
|
85318
|
-
|
|
85319
|
-
|
|
85320
|
-
|
|
85321
|
-
|
|
85322
|
-
|
|
86512
|
+
const candidates = configuredPath && configuredPath.trim() !== "" ? [isAbsolute3(configuredPath) ? configuredPath : join20(process.cwd(), configuredPath)] : [
|
|
86513
|
+
join20(process.cwd(), "dist/web"),
|
|
86514
|
+
join20(import.meta.dir, "web"),
|
|
86515
|
+
join20(dirname14(process.execPath), "web"),
|
|
86516
|
+
join20(dirname14(process.execPath), "../web"),
|
|
86517
|
+
join20(import.meta.dir, "../../../dist/web")
|
|
85323
86518
|
];
|
|
85324
86519
|
for (const candidate of candidates) {
|
|
85325
|
-
if (await Bun.file(
|
|
86520
|
+
if (await Bun.file(join20(candidate, "index.html")).exists()) {
|
|
85326
86521
|
return candidate;
|
|
85327
86522
|
}
|
|
85328
86523
|
}
|
|
@@ -85338,7 +86533,7 @@ async function startServer(options, deps = defaultDeps) {
|
|
|
85338
86533
|
async start(appRt) {
|
|
85339
86534
|
const fs3 = deps.createNodeFileSystem(process.cwd());
|
|
85340
86535
|
if (options.dbUrl && options.dbUrl !== IN_MEMORY_DATABASE_URL) {
|
|
85341
|
-
await fs3.ensureDir(
|
|
86536
|
+
await fs3.ensureDir(dirname14(options.dbUrl));
|
|
85342
86537
|
}
|
|
85343
86538
|
let scheduler3;
|
|
85344
86539
|
if (bootConfig.scheduler.enabled) {
|
|
@@ -85452,7 +86647,7 @@ if (false) {}
|
|
|
85452
86647
|
|
|
85453
86648
|
// src/commands/serve.ts
|
|
85454
86649
|
function resolveServeDbUrl(cwd, env, configuredUrl) {
|
|
85455
|
-
return env.DATABASE_URL === undefined ?
|
|
86650
|
+
return env.DATABASE_URL === undefined ? join21(cwd, DEFAULT_DATABASE_URL) : configuredUrl;
|
|
85456
86651
|
}
|
|
85457
86652
|
function registerServeCommand(program2, context4) {
|
|
85458
86653
|
program2.command("serve").summary("start the Spur web server (local fallback)").option("--port <n>", "Server port (env: PORT, default: 3000)", parseInt).option("--host <addr>", "Bind address (env: HOST, default: localhost)").option("--no-open", "Skip opening the browser").option("--cwd <path>", "Working directory", context4.cwd).option("--json", "Output { port, url, pid } and exit").action(async (options) => {
|
|
@@ -85491,7 +86686,7 @@ function registerServeCommand(program2, context4) {
|
|
|
85491
86686
|
}
|
|
85492
86687
|
|
|
85493
86688
|
// src/commands/status.ts
|
|
85494
|
-
import { join as
|
|
86689
|
+
import { join as join22 } from "path";
|
|
85495
86690
|
|
|
85496
86691
|
// src/errors.ts
|
|
85497
86692
|
class CommandError extends Error {
|
|
@@ -85562,8 +86757,8 @@ function registerStatusCommand(program2, context4) {
|
|
|
85562
86757
|
}
|
|
85563
86758
|
async function runStatusCore(path9, options, context4) {
|
|
85564
86759
|
const [packageJsonExists, spurConfigExists, git, agentSpecs] = await Promise.all([
|
|
85565
|
-
context4.fs.exists(
|
|
85566
|
-
context4.fs.exists(
|
|
86760
|
+
context4.fs.exists(join22(context4.cwd, "package.json")),
|
|
86761
|
+
context4.fs.exists(join22(context4.cwd, ".spur", "config.yaml")),
|
|
85567
86762
|
gitContext(context4.cwd),
|
|
85568
86763
|
listAgentSpecIds(context4)
|
|
85569
86764
|
]);
|
|
@@ -85591,14 +86786,14 @@ async function runStatusCore(path9, options, context4) {
|
|
|
85591
86786
|
return status.ok ? 0 : 1;
|
|
85592
86787
|
}
|
|
85593
86788
|
async function listAgentSpecIds(context4) {
|
|
85594
|
-
const dir =
|
|
86789
|
+
const dir = join22(context4.cwd, ".spur", "agents");
|
|
85595
86790
|
if (!await context4.fs.exists(dir))
|
|
85596
86791
|
return [];
|
|
85597
86792
|
const entries = await context4.fs.readDir(dir);
|
|
85598
86793
|
return entries.filter((entry) => entry.endsWith(".yaml") || entry.endsWith(".yml")).map((entry) => entry.replace(/\.ya?ml$/, "")).sort();
|
|
85599
86794
|
}
|
|
85600
86795
|
async function readTargetStatus(context4, targetPath) {
|
|
85601
|
-
const resolved =
|
|
86796
|
+
const resolved = join22(context4.cwd, targetPath);
|
|
85602
86797
|
const stat2 = await context4.fs.stat(resolved);
|
|
85603
86798
|
if (stat2 === null)
|
|
85604
86799
|
throw new CommandError(`status failed: path does not exist at ${resolved}`);
|
|
@@ -85610,7 +86805,7 @@ init_src3();
|
|
|
85610
86805
|
init_loader();
|
|
85611
86806
|
init_src2();
|
|
85612
86807
|
import { existsSync as existsSync9, readFileSync as readFileSync8 } from "fs";
|
|
85613
|
-
import { join as
|
|
86808
|
+
import { join as join23 } from "path";
|
|
85614
86809
|
// schemas/section-matrix.schema.json
|
|
85615
86810
|
var section_matrix_schema_default = {
|
|
85616
86811
|
$schema: "http://json-schema.org/draft-07/schema#",
|
|
@@ -85695,7 +86890,7 @@ var spur_config_schema_default = {
|
|
|
85695
86890
|
},
|
|
85696
86891
|
version: {
|
|
85697
86892
|
type: "string",
|
|
85698
|
-
description: "Config schema version.
|
|
86893
|
+
description: "Config schema version (string, not integer). Current recommended: '1.1' (ADR-033 executor tiers + planning blocks). '1' remains accepted for backward compatibility."
|
|
85699
86894
|
},
|
|
85700
86895
|
name: {
|
|
85701
86896
|
type: "string",
|
|
@@ -85812,15 +87007,15 @@ var spur_config_schema_default = {
|
|
|
85812
87007
|
},
|
|
85813
87008
|
tier: {
|
|
85814
87009
|
type: "string",
|
|
85815
|
-
enum: ["cheap", "standard", "capable"],
|
|
85816
|
-
description: "Capability tier for stage-registry adaptive model routing (ADR-033). A stage starts on the cheapest eligible executor meeting its model_policy min_tier
|
|
87010
|
+
enum: ["cheap", "standard", "capable-1", "capable-2", "capable-3"],
|
|
87011
|
+
description: "Capability tier for stage-registry adaptive model routing (ADR-033, 0343). Live values: cheap | standard | capable-1 | capable-2 | capable-3 (1=low output quality, 3=high within the capable band). A stage starts on the cheapest eligible executor meeting its model_policy min_tier. Bare legacy `capable` is accepted at runtime (zod preprocess \u2192 capable-1) during the deprecation window but is not part of this editor enum."
|
|
85817
87012
|
}
|
|
85818
87013
|
}
|
|
85819
87014
|
}
|
|
85820
87015
|
},
|
|
85821
87016
|
"default-by-phase": {
|
|
85822
87017
|
type: "object",
|
|
85823
|
-
description: "
|
|
87018
|
+
description: "DEPRECATED (ADR-033). Backward-compat map of dev phase (e.g. dev-run, dev-review) to executor selector. Prefer executor `tier` + stage-registry model_policy. When present, a matching phase mapping is still authoritative (fail-fast; no fall back to `default`) and shadows stage routing for that phase.",
|
|
85824
87019
|
additionalProperties: {
|
|
85825
87020
|
type: "string"
|
|
85826
87021
|
}
|
|
@@ -86201,7 +87396,7 @@ function renderMigrationReport(report, dryRun, corpusDir) {
|
|
|
86201
87396
|
}
|
|
86202
87397
|
function registerTaskCommand(program2, context4) {
|
|
86203
87398
|
const task = program2.command("task").summary("manage tasks");
|
|
86204
|
-
task.command("create").summary("Create a new task with race-safe WBS allocation.").argument("<title>", "Task title").option("--feature <id>", "Feature ID for traceability and Goal\u2192Background derivation").option("--parent <wbs>", "Parent WBS for sub-task grouping").option("--template <variant>", `Template variant (${TASK_VARIANTS.join("|")})`).option("--folder <path>", "Custom tasks folder").option("--json", "Output machine-readable JSON").action(async (title2, options) => {
|
|
87399
|
+
task.command("create").summary("Create a new task with race-safe WBS allocation.").argument("<title>", "Task title").option("--feature <id>", "Feature ID for traceability and Goal\u2192Background derivation").option("--parent <wbs>", "Parent WBS for sub-task grouping").option("--template <variant>", `Template variant (${TASK_VARIANTS.join("|")})`).option("--folder <path>", "Custom tasks folder").option("--dedupe-within <seconds>", "Refuse creation if an existing task under the same feature has an identical name created within the last N seconds (task 0341 R4)", (v) => Number.parseInt(v, 10)).option("--allow-duplicate-name", "Override the --dedupe-within guard (creates anyway)").option("--json", "Output machine-readable JSON").action(async (title2, options) => {
|
|
86205
87400
|
if (options.template !== undefined && !TASK_VARIANTS.includes(options.template)) {
|
|
86206
87401
|
context4.output.error(`Unknown template variant "${options.template}". Valid: ${TASK_VARIANTS.join(", ")}`);
|
|
86207
87402
|
context4.setExitCode(2);
|
|
@@ -86213,7 +87408,8 @@ function registerTaskCommand(program2, context4) {
|
|
|
86213
87408
|
title: title2,
|
|
86214
87409
|
featureId: options.feature,
|
|
86215
87410
|
parentWbs: options.parent,
|
|
86216
|
-
template: options.template
|
|
87411
|
+
template: options.template,
|
|
87412
|
+
dedupeWithinSec: options.allowDuplicateName ? undefined : options.dedupeWithin
|
|
86217
87413
|
});
|
|
86218
87414
|
if (options.json) {
|
|
86219
87415
|
context4.output.write(toJson2(result));
|
|
@@ -86221,8 +87417,13 @@ function registerTaskCommand(program2, context4) {
|
|
|
86221
87417
|
context4.output.write(`Created task ${result.ref.id}: ${result.ref.filePath}`);
|
|
86222
87418
|
}
|
|
86223
87419
|
} catch (err) {
|
|
86224
|
-
|
|
86225
|
-
|
|
87420
|
+
if (err instanceof DuplicateFollowUpError) {
|
|
87421
|
+
context4.output.error(err.message);
|
|
87422
|
+
context4.setExitCode(3);
|
|
87423
|
+
} else {
|
|
87424
|
+
context4.output.error(String(err));
|
|
87425
|
+
context4.setExitCode(1);
|
|
87426
|
+
}
|
|
86226
87427
|
}
|
|
86227
87428
|
});
|
|
86228
87429
|
task.command("show").summary("Show a task by WBS.").argument("<wbs>", "Task WBS number").option("--folder <path>", "Custom tasks folder").option("--json", "Output machine-readable JSON").action(async (wbs, options) => {
|
|
@@ -86288,7 +87489,7 @@ ${result.content}`);
|
|
|
86288
87489
|
let forcedDoneVerdict;
|
|
86289
87490
|
if (status === "done") {
|
|
86290
87491
|
const current = await svc.show(wbs);
|
|
86291
|
-
const verdictDir = options.verdictDir ??
|
|
87492
|
+
const verdictDir = options.verdictDir ?? join23(context4.cwd, ".spur", "run");
|
|
86292
87493
|
const loaded = await readVerdictArtifact(context4.fs, verdictDir, wbs);
|
|
86293
87494
|
const guardOutcome = evaluateDoneTransition({
|
|
86294
87495
|
wbs,
|
|
@@ -86312,10 +87513,10 @@ ${result.content}`);
|
|
|
86312
87513
|
context4.setExitCode(1);
|
|
86313
87514
|
return;
|
|
86314
87515
|
}
|
|
86315
|
-
if (guardOutcome.reason === "forced"
|
|
87516
|
+
if (guardOutcome.reason === "forced") {
|
|
86316
87517
|
forcedDone = true;
|
|
86317
87518
|
forcedDoneReason = options.reason;
|
|
86318
|
-
forcedDoneVerdict = loaded.artifact
|
|
87519
|
+
forcedDoneVerdict = loaded.artifact?.verdict ?? "UNKNOWN";
|
|
86319
87520
|
}
|
|
86320
87521
|
}
|
|
86321
87522
|
const result = await svc.updateStatus(wbs, status);
|
|
@@ -86605,6 +87806,53 @@ ${result.content}`);
|
|
|
86605
87806
|
context4.setExitCode(1);
|
|
86606
87807
|
}
|
|
86607
87808
|
});
|
|
87809
|
+
task.command("verifyall-aggregate").summary("Aggregate per-task verify outcomes into a deterministic batch verdict (verifyall).").description("Reads a JSON array of per-task outcomes ({wbs,outcome}) and emits the batch " + "verdict with NOT-STARTED tasks excluded from the rollup. Replaces agent-discretion " + "rollup prose (dev-operations.md \xA73a) with deterministic code (task 0341).").option("--from-file <path>", "Path to JSON array of {wbs,outcome[,reason]} rows").option("--json", "Output machine-readable JSON").action(async (options) => {
|
|
87810
|
+
const inputPath = options.fromFile ?? ".spur/run/verifyall-batch-input.json";
|
|
87811
|
+
let raw2;
|
|
87812
|
+
try {
|
|
87813
|
+
raw2 = readFileSync8(inputPath, "utf-8");
|
|
87814
|
+
} catch {
|
|
87815
|
+
context4.output.error(`Batch input file not found: ${inputPath}`);
|
|
87816
|
+
context4.setExitCode(1);
|
|
87817
|
+
return;
|
|
87818
|
+
}
|
|
87819
|
+
let rows;
|
|
87820
|
+
try {
|
|
87821
|
+
const parsed = JSON.parse(raw2);
|
|
87822
|
+
if (!Array.isArray(parsed)) {
|
|
87823
|
+
throw new Error("expected a JSON array");
|
|
87824
|
+
}
|
|
87825
|
+
rows = parsed;
|
|
87826
|
+
} catch (err) {
|
|
87827
|
+
context4.output.error(`Invalid batch input JSON: ${String(err)}`);
|
|
87828
|
+
context4.setExitCode(1);
|
|
87829
|
+
return;
|
|
87830
|
+
}
|
|
87831
|
+
const results = rows.map((r2) => {
|
|
87832
|
+
const outcome = r2.outcome.toUpperCase();
|
|
87833
|
+
if (!["PASS", "PARTIAL", "FAIL", "NOT-STARTED", "UNKNOWN"].includes(outcome)) {
|
|
87834
|
+
throw new Error(`Invalid outcome for ${r2.wbs}: ${r2.outcome}`);
|
|
87835
|
+
}
|
|
87836
|
+
return {
|
|
87837
|
+
wbs: r2.wbs,
|
|
87838
|
+
outcome,
|
|
87839
|
+
reason: r2.reason
|
|
87840
|
+
};
|
|
87841
|
+
});
|
|
87842
|
+
const aggregation = aggregateBatchVerdicts(results);
|
|
87843
|
+
if (options.json) {
|
|
87844
|
+
context4.output.write(JSON.stringify(aggregation, null, 2));
|
|
87845
|
+
} else {
|
|
87846
|
+
context4.output.write(`Batch verdict: ${aggregation.verdict}`);
|
|
87847
|
+
context4.output.write(aggregation.summary);
|
|
87848
|
+
if (aggregation.notStarted.length > 0) {
|
|
87849
|
+
context4.output.write(`NOT-STARTED (excluded from rollup): ${aggregation.notStarted.map((r2) => r2.wbs).join(", ")}`);
|
|
87850
|
+
}
|
|
87851
|
+
}
|
|
87852
|
+
if (aggregation.verdict === "FAIL") {
|
|
87853
|
+
context4.setExitCode(1);
|
|
87854
|
+
}
|
|
87855
|
+
});
|
|
86608
87856
|
task.command("check").summary("Validate a task file through the four-layer check (design \xA73).").argument("[wbs]", "Task WBS number (validates all tasks in the folder when omitted)").option("--strict", "Elevate ALL warnings to failures").option("--strict-core", "Gate variant: fail only on hard-core errors (the testing\u2192done guard)").option("--folder <path>", "Custom tasks folder").option("--json", "Output machine-readable JSON").action(async (wbs, options) => {
|
|
86609
87857
|
const svc = await makeCheckService(context4);
|
|
86610
87858
|
const json3 = options.json === true;
|
|
@@ -86782,7 +88030,7 @@ function loadTemplateContent(projectRoot, variant) {
|
|
|
86782
88030
|
return templateContentCache.get(variant);
|
|
86783
88031
|
if (templateMissSet.has(variant))
|
|
86784
88032
|
return;
|
|
86785
|
-
const localPath =
|
|
88033
|
+
const localPath = join23(projectRoot, ".spur", "tasks", "templates", `${variant}.md`);
|
|
86786
88034
|
if (existsSync9(localPath)) {
|
|
86787
88035
|
const content = readFileSync8(localPath, "utf8");
|
|
86788
88036
|
templateContentCache.set(variant, content);
|
|
@@ -86790,7 +88038,7 @@ function loadTemplateContent(projectRoot, variant) {
|
|
|
86790
88038
|
}
|
|
86791
88039
|
const root = bundledConfigRoot();
|
|
86792
88040
|
if (root !== null) {
|
|
86793
|
-
const templatePath =
|
|
88041
|
+
const templatePath = join23(root, "templates", "task", `${variant}.md`);
|
|
86794
88042
|
if (existsSync9(templatePath)) {
|
|
86795
88043
|
const content = readFileSync8(templatePath, "utf8");
|
|
86796
88044
|
templateContentCache.set(variant, content);
|
|
@@ -86806,13 +88054,13 @@ function loadTemplateBodies(projectRoot, variant) {
|
|
|
86806
88054
|
if (cached2 !== undefined)
|
|
86807
88055
|
return cached2;
|
|
86808
88056
|
let bodies = {};
|
|
86809
|
-
const localPath =
|
|
88057
|
+
const localPath = join23(projectRoot, ".spur", "tasks", "templates", `${variant}.md`);
|
|
86810
88058
|
if (existsSync9(localPath)) {
|
|
86811
88059
|
bodies = extractTemplateBodies(readFileSync8(localPath, "utf8"));
|
|
86812
88060
|
} else {
|
|
86813
88061
|
const root = bundledConfigRoot();
|
|
86814
88062
|
if (root !== null) {
|
|
86815
|
-
const templatePath =
|
|
88063
|
+
const templatePath = join23(root, "templates", "task", `${variant}.md`);
|
|
86816
88064
|
if (existsSync9(templatePath)) {
|
|
86817
88065
|
bodies = extractTemplateBodies(readFileSync8(templatePath, "utf8"));
|
|
86818
88066
|
}
|
|
@@ -86854,7 +88102,7 @@ async function loadSectionMatrix(projectRoot) {
|
|
|
86854
88102
|
return promise2;
|
|
86855
88103
|
}
|
|
86856
88104
|
async function loadSectionMatrixUncached(projectRoot) {
|
|
86857
|
-
const localPath =
|
|
88105
|
+
const localPath = join23(projectRoot, ".spur", "tasks", "section-matrix.yaml");
|
|
86858
88106
|
if (existsSync9(localPath)) {
|
|
86859
88107
|
const data = await loadStructuredSpurConfig(localPath, {
|
|
86860
88108
|
validateJsonSchema: true,
|
|
@@ -86864,7 +88112,7 @@ async function loadSectionMatrixUncached(projectRoot) {
|
|
|
86864
88112
|
}
|
|
86865
88113
|
const root = bundledConfigRoot();
|
|
86866
88114
|
if (root !== null) {
|
|
86867
|
-
const matrixPath =
|
|
88115
|
+
const matrixPath = join23(root, "tasks", "section-matrix.yaml");
|
|
86868
88116
|
if (existsSync9(matrixPath)) {
|
|
86869
88117
|
const data = await loadStructuredSpurConfig(matrixPath, {
|
|
86870
88118
|
validateJsonSchema: true,
|
|
@@ -87124,6 +88372,8 @@ init_dist7();
|
|
|
87124
88372
|
init_dist6();
|
|
87125
88373
|
import { spawn as spawn2 } from "child_process";
|
|
87126
88374
|
import { resolve as resolve5 } from "path";
|
|
88375
|
+
import { createInterface } from "readline";
|
|
88376
|
+
import { setTimeout as sleep3 } from "timers/promises";
|
|
87127
88377
|
function parseVars(raw2) {
|
|
87128
88378
|
if (raw2 === undefined) {
|
|
87129
88379
|
return;
|
|
@@ -87146,6 +88396,11 @@ function parseVars(raw2) {
|
|
|
87146
88396
|
}
|
|
87147
88397
|
return vars;
|
|
87148
88398
|
}
|
|
88399
|
+
function submitSteeringLine(controller, output2, line) {
|
|
88400
|
+
const ack = controller.submitLine(line);
|
|
88401
|
+
if (ack === undefined)
|
|
88402
|
+
output2.error(`[steer] ignored command: ${line}`);
|
|
88403
|
+
}
|
|
87149
88404
|
async function resolveWorkflowPaths(cwd) {
|
|
87150
88405
|
try {
|
|
87151
88406
|
const config4 = await loadSpurConfig(cwd, { embeddedSchemas: EMBEDDED_SPUR_SCHEMAS });
|
|
@@ -87178,19 +88433,47 @@ ${result.errors.map((m) => ` - ${m}`).join(`
|
|
|
87178
88433
|
}
|
|
87179
88434
|
context4.setExitCode(result.valid ? 0 : 1);
|
|
87180
88435
|
});
|
|
87181
|
-
workflow.command("run").description("Execute a workflow definition.").argument("<file>", "Workflow YAML file").option("--run-id <id>", "Persisted run id for workflow run").option("--vars <json>", `Per-run variable overrides as a JSON object, e.g. '{"taskId":"0042"}'`).option("--dry-run", "Validate and walk transitions without executing actions").option("--async", "Start the workflow in the background and exit immediately \u2014 monitor with `spur workflow trace <run-id>`").option("--no-plan", "Suppress the run-start plan preview (synchronous runs only)").option("--json", "Output machine-readable JSON where supported").action(async (file2, options) => {
|
|
88436
|
+
workflow.command("run").description("Execute a workflow definition.").argument("<file>", "Workflow YAML file").option("--run-id <id>", "Persisted run id for workflow run").option("--vars <json>", `Per-run variable overrides as a JSON object, e.g. '{"taskId":"0042"}'`).option("--dry-run", "Validate and walk transitions without executing actions").option("--async", "Start the workflow in the background and exit immediately \u2014 monitor with `spur workflow trace <run-id>`").option("--no-plan", "Suppress the run-start plan preview (synchronous runs only)").option("--quiet", "Suppress plan and per-step progress; keep the final summary").option("--silent", "Suppress all routine output; errors still set a non-zero exit status").option("--verbose", "Include transitions and correlation diagnostics in human progress").option("--detail <level>", "Human detail level: minimal, invocation, or full").option("--trace-file", "Append a redacted schema-versioned JSONL trace under .spur/runs/workflow/").option("--steer", "Accept local in-process steering commands on stdin at declared action boundaries").option("--json", "Output machine-readable JSON where supported").action(async (file2, options) => {
|
|
88437
|
+
const json3 = options.json === true;
|
|
88438
|
+
const silent = !json3 && options.silent === true;
|
|
88439
|
+
const quiet = !json3 && options.quiet === true;
|
|
88440
|
+
if (!json3 && options.quiet === true && options.verbose === true) {
|
|
88441
|
+
context4.output.error("--quiet and --verbose are mutually exclusive");
|
|
88442
|
+
context4.setExitCode(2);
|
|
88443
|
+
return;
|
|
88444
|
+
}
|
|
88445
|
+
if (!json3 && options.silent === true && (options.quiet === true || options.verbose === true)) {
|
|
88446
|
+
context4.output.error("--silent cannot be combined with --quiet or --verbose");
|
|
88447
|
+
context4.setExitCode(2);
|
|
88448
|
+
return;
|
|
88449
|
+
}
|
|
88450
|
+
if (options.steer === true && (json3 || options.async === true)) {
|
|
88451
|
+
context4.output.error("--steer is synchronous and in-process; it cannot be combined with --json or --async");
|
|
88452
|
+
context4.setExitCode(2);
|
|
88453
|
+
return;
|
|
88454
|
+
}
|
|
88455
|
+
const requestedDetail = options.detail;
|
|
88456
|
+
if (requestedDetail !== undefined && !["minimal", "invocation", "full"].includes(requestedDetail)) {
|
|
88457
|
+
context4.output.error("--detail must be one of: minimal, invocation, full");
|
|
88458
|
+
context4.setExitCode(2);
|
|
88459
|
+
return;
|
|
88460
|
+
}
|
|
88461
|
+
const detail = options.verbose === true ? "full" : requestedDetail ?? "invocation";
|
|
87182
88462
|
if (options.async) {
|
|
87183
|
-
const
|
|
88463
|
+
const runId2 = options.runId || crypto.randomUUID();
|
|
87184
88464
|
const spurParts = resolveSpurBin().split(" ");
|
|
87185
88465
|
const spurBin = spurParts[0] ?? process.execPath;
|
|
87186
88466
|
const spurArgs = spurParts.slice(1);
|
|
87187
|
-
const cmd = [...spurArgs, "workflow", "run", file2, "--run-id",
|
|
88467
|
+
const cmd = [...spurArgs, "workflow", "run", file2, "--run-id", runId2];
|
|
87188
88468
|
if (options.vars) {
|
|
87189
88469
|
cmd.push("--vars", options.vars);
|
|
87190
88470
|
}
|
|
87191
88471
|
if (options.dryRun) {
|
|
87192
88472
|
cmd.push("--dry-run");
|
|
87193
88473
|
}
|
|
88474
|
+
if (options.traceFile) {
|
|
88475
|
+
cmd.push("--trace-file");
|
|
88476
|
+
}
|
|
87194
88477
|
try {
|
|
87195
88478
|
const child = spawn2(spurBin, cmd, {
|
|
87196
88479
|
stdio: "ignore",
|
|
@@ -87200,50 +88483,121 @@ ${result.errors.map((m) => ` - ${m}`).join(`
|
|
|
87200
88483
|
child.unref();
|
|
87201
88484
|
} catch {
|
|
87202
88485
|
const result2 = await makeSvc(options.json).run(file2, {
|
|
87203
|
-
runId,
|
|
88486
|
+
runId: runId2,
|
|
87204
88487
|
vars: { spurBin: resolveSpurBin(), ...parseVars(options.vars) },
|
|
87205
88488
|
dryRun: options.dryRun || undefined
|
|
87206
88489
|
});
|
|
87207
|
-
|
|
88490
|
+
if (json3)
|
|
88491
|
+
context4.output.write(toJson2(result2));
|
|
88492
|
+
else if (!silent) {
|
|
88493
|
+
context4.output.write(`workflow ${result2.status}: ${result2.workflowName} -> ${result2.finalState} (async spawn failed, ran sync)`);
|
|
88494
|
+
}
|
|
87208
88495
|
context4.setExitCode(result2.status === "done" ? 0 : 1);
|
|
87209
88496
|
return;
|
|
87210
88497
|
}
|
|
87211
|
-
const asyncResult = { runId, status: "started", workflowName: file2 };
|
|
87212
|
-
|
|
87213
|
-
|
|
88498
|
+
const asyncResult = { runId: runId2, status: "started", workflowName: file2 };
|
|
88499
|
+
if (json3)
|
|
88500
|
+
context4.output.write(toJson2(asyncResult));
|
|
88501
|
+
else if (!silent) {
|
|
88502
|
+
context4.output.write(`Started async run: ${runId2}
|
|
88503
|
+
Monitor with: spur workflow trace ${runId2} --follow`);
|
|
88504
|
+
}
|
|
87214
88505
|
context4.setExitCode(0);
|
|
87215
88506
|
return;
|
|
87216
88507
|
}
|
|
87217
88508
|
const vars = { spurBin: resolveSpurBin(), ...parseVars(options.vars) };
|
|
87218
|
-
const
|
|
88509
|
+
const runId = options.runId || crypto.randomUUID();
|
|
88510
|
+
const humanProgress = !json3 && !quiet && !silent;
|
|
87219
88511
|
let bus;
|
|
87220
|
-
|
|
88512
|
+
let traceWriter;
|
|
88513
|
+
const heartbeats = new Map;
|
|
88514
|
+
if (humanProgress || options.traceFile === true || options.steer === true) {
|
|
88515
|
+
bus = new EventBus;
|
|
88516
|
+
}
|
|
88517
|
+
if (options.traceFile === true && bus !== undefined) {
|
|
88518
|
+
traceWriter = new WorkflowTraceWriter(context4.cwd, runId);
|
|
88519
|
+
traceWriter.attach(bus);
|
|
88520
|
+
}
|
|
88521
|
+
if (humanProgress && bus !== undefined) {
|
|
88522
|
+
context4.output.write(`Run: ${runId}`);
|
|
87221
88523
|
if (options.plan !== false) {
|
|
87222
88524
|
try {
|
|
87223
88525
|
const def = await loadWorkflowDef(resolve5(context4.cwd, file2), { validateSchema: false });
|
|
87224
88526
|
context4.output.write(renderRunPlan(def));
|
|
87225
88527
|
} catch {}
|
|
87226
88528
|
}
|
|
87227
|
-
bus = new EventBus;
|
|
87228
88529
|
const report = (event2) => {
|
|
87229
|
-
const line = renderStepLine(event2);
|
|
88530
|
+
const line = renderStepLine(event2, { detail });
|
|
87230
88531
|
if (line !== null)
|
|
87231
88532
|
context4.output.write(line);
|
|
87232
88533
|
};
|
|
87233
88534
|
bus.on("workflow.phase", report);
|
|
87234
|
-
|
|
87235
|
-
|
|
88535
|
+
if (detail === "full")
|
|
88536
|
+
bus.on("workflow.transition", report);
|
|
88537
|
+
bus.on("workflow.action.started", (event2) => {
|
|
88538
|
+
report(event2);
|
|
88539
|
+
const startedAt2 = Date.parse(event2.at);
|
|
88540
|
+
const timer = setInterval(() => {
|
|
88541
|
+
const line = renderActionHeartbeat(event2, Math.max(0, Date.now() - startedAt2), { detail });
|
|
88542
|
+
if (line !== null)
|
|
88543
|
+
context4.output.write(line);
|
|
88544
|
+
}, 30000);
|
|
88545
|
+
timer.unref?.();
|
|
88546
|
+
heartbeats.set(event2.actionId, timer);
|
|
88547
|
+
});
|
|
88548
|
+
bus.on("workflow.action.finished", (event2) => {
|
|
88549
|
+
const timer = heartbeats.get(event2.actionId);
|
|
88550
|
+
if (timer !== undefined)
|
|
88551
|
+
clearInterval(timer);
|
|
88552
|
+
heartbeats.delete(event2.actionId);
|
|
88553
|
+
report(event2);
|
|
88554
|
+
});
|
|
88555
|
+
bus.on("workflow.agent", (event2) => {
|
|
88556
|
+
if (event2.kind === "started" && event2.actionId !== undefined) {
|
|
88557
|
+
const timer = heartbeats.get(event2.actionId);
|
|
88558
|
+
if (timer !== undefined)
|
|
88559
|
+
clearInterval(timer);
|
|
88560
|
+
heartbeats.delete(event2.actionId);
|
|
88561
|
+
}
|
|
88562
|
+
report(event2);
|
|
88563
|
+
});
|
|
88564
|
+
}
|
|
88565
|
+
const steeringController = options.steer === true ? new WorkflowSteeringController((ack) => {
|
|
88566
|
+
bus?.emit("workflow.steering", ack);
|
|
88567
|
+
context4.output.write(`[steer] ${ack.accepted ? "ack" : "nack"} ${ack.operation} \xB7 ${ack.reason ?? `version=${ack.version}`}`);
|
|
88568
|
+
}, configuredSecretValues(context4.env), new Set(["operator"]), (snapshot) => {
|
|
88569
|
+
if (snapshot.state === "boundary") {
|
|
88570
|
+
context4.output.write(`[steer] boundary action=${snapshot.actionId} version=${snapshot.version} \xB7 commands: continue | note <text> | retry | abort`);
|
|
88571
|
+
}
|
|
88572
|
+
}) : undefined;
|
|
88573
|
+
const steeringInput = steeringController === undefined ? undefined : createInterface({ input: process.stdin, terminal: process.stdin.isTTY === true });
|
|
88574
|
+
if (steeringInput !== undefined && steeringController !== undefined) {
|
|
88575
|
+
steeringInput.on("line", submitSteeringLine.bind(undefined, steeringController, context4.output));
|
|
88576
|
+
}
|
|
88577
|
+
let result;
|
|
88578
|
+
try {
|
|
88579
|
+
result = await makeSvc(json3, bus).run(file2, {
|
|
88580
|
+
runId,
|
|
88581
|
+
vars,
|
|
88582
|
+
dryRun: options.dryRun || undefined,
|
|
88583
|
+
recordSelfPid: process.env.SPUR_ASYNC_WORKER === "1",
|
|
88584
|
+
...steeringController !== undefined ? { steeringController } : {}
|
|
88585
|
+
});
|
|
88586
|
+
} finally {
|
|
88587
|
+
for (const timer of heartbeats.values())
|
|
88588
|
+
clearInterval(timer);
|
|
88589
|
+
heartbeats.clear();
|
|
88590
|
+
await traceWriter?.flush();
|
|
88591
|
+
steeringInput?.close();
|
|
88592
|
+
}
|
|
88593
|
+
if (json3)
|
|
88594
|
+
context4.output.write(toJson2(result));
|
|
88595
|
+
else if (!silent) {
|
|
88596
|
+
context4.output.write(`workflow ${result.status}: ${result.workflowName} -> ${result.finalState}${typeof result.reason === "string" ? ` \u2014 ${result.reason}` : ""}`);
|
|
87236
88597
|
}
|
|
87237
|
-
const result = await makeSvc(options.json, bus).run(file2, {
|
|
87238
|
-
runId: options.runId || undefined,
|
|
87239
|
-
vars,
|
|
87240
|
-
dryRun: options.dryRun || undefined,
|
|
87241
|
-
recordSelfPid: process.env.SPUR_ASYNC_WORKER === "1"
|
|
87242
|
-
});
|
|
87243
|
-
context4.output.write(options.json ? toJson2(result) : `workflow ${result.status}: ${result.workflowName} -> ${result.finalState}`);
|
|
87244
88598
|
context4.setExitCode(result.status === "done" ? 0 : 1);
|
|
87245
88599
|
});
|
|
87246
|
-
workflow.command("continue").description("Resume a paused (HITL) workflow run. Omit run-id to resume the most recent paused run.").argument("[run-id]", "Run ID to resume (default: the most recent paused run)").option("--yes", "
|
|
88600
|
+
workflow.command("continue").description("Resume a paused (HITL) workflow run. Omit run-id to resume the most recent paused run.").argument("[run-id]", "Run ID to resume (default: the most recent paused run)").option("--yes", "Skip the CLI resume confirmation (does not set the persisted HITL answer)").option("--json", "Output machine-readable JSON where supported").action(async (runId, options) => {
|
|
87247
88601
|
const json3 = options.json === true;
|
|
87248
88602
|
const svc = makeSvc(json3);
|
|
87249
88603
|
try {
|
|
@@ -87329,7 +88683,7 @@ Monitor with: spur workflow trace ${runId}`);
|
|
|
87329
88683
|
context4.output.write(formatListHuman(result));
|
|
87330
88684
|
}
|
|
87331
88685
|
});
|
|
87332
|
-
workflow.command("trace").description("Show persisted workflow run history.").argument("[run-id]", "Run ID for per-run timeline detail").option("--workflow <name>", "Filter by workflow name").option("--status <status>", "Filter by status: done, failed, running").option("--since <iso-date>", "Filter runs started on or after this date").option("--last <n>", "Limit results (default 20)", "20").option("--json", "Output machine-readable JSON where supported").action(async (runId, options) => {
|
|
88686
|
+
workflow.command("trace").description("Show persisted workflow run history.").argument("[run-id]", "Run ID for per-run timeline detail").option("--workflow <name>", "Filter by workflow name").option("--status <status>", "Filter by status: done, failed, running").option("--since <iso-date>", "Filter runs started on or after this date").option("--last <n>", "Limit results (default 20)", "20").option("--follow", "Replay a run timeline and poll persisted state until it becomes terminal").option("--poll <ms>", "Follow polling interval in milliseconds", "1000").option("--json", "Output machine-readable JSON where supported").action(async (runId, options) => {
|
|
87333
88687
|
const svc = makeSvc();
|
|
87334
88688
|
const last = parseInt(options.last, 10);
|
|
87335
88689
|
if (Number.isNaN(last) || last < 1) {
|
|
@@ -87337,11 +88691,31 @@ Monitor with: spur workflow trace ${runId}`);
|
|
|
87337
88691
|
context4.setExitCode(1);
|
|
87338
88692
|
return;
|
|
87339
88693
|
}
|
|
88694
|
+
const pollMs = parseInt(options.poll, 10);
|
|
88695
|
+
if (Number.isNaN(pollMs) || pollMs < 50) {
|
|
88696
|
+
context4.output.error("--poll must be an integer of at least 50ms");
|
|
88697
|
+
context4.setExitCode(1);
|
|
88698
|
+
return;
|
|
88699
|
+
}
|
|
88700
|
+
if (options.follow === true && runId === undefined) {
|
|
88701
|
+
context4.output.error("--follow requires a run-id");
|
|
88702
|
+
context4.setExitCode(1);
|
|
88703
|
+
return;
|
|
88704
|
+
}
|
|
88705
|
+
if (options.follow === true && options.json === true) {
|
|
88706
|
+
context4.output.error("--follow is a human streaming mode and cannot be combined with --json");
|
|
88707
|
+
context4.setExitCode(1);
|
|
88708
|
+
return;
|
|
88709
|
+
}
|
|
87340
88710
|
if (options.status !== undefined && !["done", "failed", "running"].includes(options.status)) {
|
|
87341
88711
|
context4.output.error("--status must be one of: done, failed, running");
|
|
87342
88712
|
context4.setExitCode(1);
|
|
87343
88713
|
return;
|
|
87344
88714
|
}
|
|
88715
|
+
if (options.follow === true && runId !== undefined) {
|
|
88716
|
+
await followTrace(svc, runId, pollMs, (line) => context4.output.write(line));
|
|
88717
|
+
return;
|
|
88718
|
+
}
|
|
87345
88719
|
const result = runId ? await svc.trace(runId) : await svc.trace({
|
|
87346
88720
|
workflow: options.workflow,
|
|
87347
88721
|
status: options.status,
|
|
@@ -87404,22 +88778,14 @@ function formatTraceList2(result) {
|
|
|
87404
88778
|
function formatTraceTimeline(result) {
|
|
87405
88779
|
const { run, events: events2 } = result;
|
|
87406
88780
|
const dryLabel = run.isDryRun ? " [DRY RUN]" : "";
|
|
88781
|
+
const reasonLabel = run.failureReason ? ` \u2014 ${run.failureReason}` : "";
|
|
87407
88782
|
const lines = [
|
|
87408
|
-
`Run: ${run.runId} \u2014 ${run.workflowName} (${run.mode}) \u2014 ${run.status}${dryLabel}`,
|
|
88783
|
+
`Run: ${run.runId} \u2014 ${run.workflowName} (${run.mode}) \u2014 ${run.status}${dryLabel}${reasonLabel}`,
|
|
87409
88784
|
`Started: ${run.startedAt} Completed: ${run.completedAt ?? "-"} Events: ${events2.length}`,
|
|
87410
88785
|
""
|
|
87411
88786
|
];
|
|
87412
88787
|
for (const event2 of events2) {
|
|
87413
|
-
|
|
87414
|
-
const ts = event2.startedAt ?? event2.completedAt ?? "";
|
|
87415
|
-
lines.push(` ${event2.phase.padEnd(20)} ${event2.status.padEnd(10)} ${ts}`);
|
|
87416
|
-
} else if (event2.kind === "transition") {
|
|
87417
|
-
const guard2 = event2.trigger ? ` [${event2.trigger}]` : "";
|
|
87418
|
-
lines.push(` \u2192 ${event2.to}${guard2}`);
|
|
87419
|
-
} else {
|
|
87420
|
-
const costSuffix = formatActionCost(event2);
|
|
87421
|
-
lines.push(` \u26A1 ${event2.actionKind.padEnd(15)} ${event2.duration.padEnd(6)}${event2.label}${costSuffix}`);
|
|
87422
|
-
}
|
|
88788
|
+
lines.push(formatTimelineEvent(event2));
|
|
87423
88789
|
}
|
|
87424
88790
|
const hasUnjoinedCost = events2.some((e) => e.kind === "action" && e.cost !== undefined && e.cost.totals.records === 0);
|
|
87425
88791
|
if (hasUnjoinedCost) {
|
|
@@ -87428,6 +88794,56 @@ function formatTraceTimeline(result) {
|
|
|
87428
88794
|
return lines.join(`
|
|
87429
88795
|
`).trimEnd();
|
|
87430
88796
|
}
|
|
88797
|
+
function formatTimelineEvent(event2) {
|
|
88798
|
+
if (event2.kind === "phase") {
|
|
88799
|
+
const ts = event2.startedAt ?? event2.completedAt ?? "";
|
|
88800
|
+
return ` ${event2.phase.padEnd(20)} ${event2.status.padEnd(10)} ${ts}`;
|
|
88801
|
+
}
|
|
88802
|
+
if (event2.kind === "transition") {
|
|
88803
|
+
const guard2 = event2.trigger ? ` [${event2.trigger}]` : "";
|
|
88804
|
+
return ` \u2192 ${event2.to}${guard2}`;
|
|
88805
|
+
}
|
|
88806
|
+
const costSuffix = formatActionCost(event2);
|
|
88807
|
+
return ` \u26A1 ${event2.actionKind.padEnd(15)} ${event2.duration.padEnd(6)}${event2.label}${costSuffix}`;
|
|
88808
|
+
}
|
|
88809
|
+
async function followTrace(service, runId, pollMs, write, wait = (ms) => sleep3(ms)) {
|
|
88810
|
+
let missingAttempts = 0;
|
|
88811
|
+
let timeline;
|
|
88812
|
+
while (true) {
|
|
88813
|
+
try {
|
|
88814
|
+
timeline = await service.trace(runId);
|
|
88815
|
+
break;
|
|
88816
|
+
} catch (error51) {
|
|
88817
|
+
if (!String(error51).includes("Run not found") || missingAttempts >= 20)
|
|
88818
|
+
throw error51;
|
|
88819
|
+
missingAttempts++;
|
|
88820
|
+
await wait(pollMs);
|
|
88821
|
+
}
|
|
88822
|
+
}
|
|
88823
|
+
write(formatTraceTimeline(timeline));
|
|
88824
|
+
const seen = new Set(timeline.events.map((event2) => JSON.stringify(event2)));
|
|
88825
|
+
if (isTerminalTraceStatus(timeline.run.status))
|
|
88826
|
+
return;
|
|
88827
|
+
while (true) {
|
|
88828
|
+
await wait(pollMs);
|
|
88829
|
+
const next = await service.trace(runId);
|
|
88830
|
+
for (const event2 of next.events) {
|
|
88831
|
+
const fingerprint2 = JSON.stringify(event2);
|
|
88832
|
+
if (seen.has(fingerprint2))
|
|
88833
|
+
continue;
|
|
88834
|
+
seen.add(fingerprint2);
|
|
88835
|
+
write(formatTimelineEvent(event2));
|
|
88836
|
+
}
|
|
88837
|
+
if (isTerminalTraceStatus(next.run.status)) {
|
|
88838
|
+
const reason = next.run.failureReason ? ` \u2014 ${next.run.failureReason}` : "";
|
|
88839
|
+
write(`Run finalized: ${next.run.status}${reason}`);
|
|
88840
|
+
return;
|
|
88841
|
+
}
|
|
88842
|
+
}
|
|
88843
|
+
}
|
|
88844
|
+
function isTerminalTraceStatus(status) {
|
|
88845
|
+
return status !== "running" && status !== "pending";
|
|
88846
|
+
}
|
|
87431
88847
|
function formatActionCost(event2) {
|
|
87432
88848
|
if (event2.kind !== "action")
|
|
87433
88849
|
return "";
|
|
@@ -87448,7 +88864,7 @@ init_src3();
|
|
|
87448
88864
|
init_src();
|
|
87449
88865
|
init_src2();
|
|
87450
88866
|
init_dist5();
|
|
87451
|
-
import { dirname as
|
|
88867
|
+
import { dirname as dirname15, join as join24, resolve as resolve6 } from "path";
|
|
87452
88868
|
import { isatty as isatty4 } from "tty";
|
|
87453
88869
|
|
|
87454
88870
|
// ../../node_modules/.bun/@clack+core@1.4.1/node_modules/@clack/core/dist/index.mjs
|
|
@@ -88862,10 +90278,10 @@ function createCliContext(options) {
|
|
|
88862
90278
|
function noopSetExitCode(_code) {}
|
|
88863
90279
|
async function createMigratedDbAdapter(cwd = process.cwd(), env = process.env, dbUrl) {
|
|
88864
90280
|
const config4 = buildConfigFromEnv(env);
|
|
88865
|
-
const configuredUrl = env.DATABASE_URL === undefined ?
|
|
90281
|
+
const configuredUrl = env.DATABASE_URL === undefined ? join24(cwd, DEFAULT_DATABASE_URL) : config4.database.url;
|
|
88866
90282
|
const url2 = dbUrl ?? configuredUrl;
|
|
88867
90283
|
if (url2 !== IN_MEMORY_DATABASE_URL) {
|
|
88868
|
-
await createNodeFileSystem3().ensureDir(
|
|
90284
|
+
await createNodeFileSystem3().ensureDir(dirname15(url2));
|
|
88869
90285
|
}
|
|
88870
90286
|
return createMigratedDb({ url: url2 });
|
|
88871
90287
|
}
|
|
@@ -88950,7 +90366,7 @@ function bannerText() {
|
|
|
88950
90366
|
}
|
|
88951
90367
|
async function runCli() {
|
|
88952
90368
|
const argv = process.argv.slice(2);
|
|
88953
|
-
if (!argv.
|
|
90369
|
+
if (!argv.some((arg) => arg === "--json" || arg === "--quiet" || arg === "--silent")) {
|
|
88954
90370
|
consoleOutput.write(bannerText());
|
|
88955
90371
|
}
|
|
88956
90372
|
return main();
|