@gobing-ai/spur 0.3.9 → 0.3.11
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/rules/boundary/sp-runtime-path.yaml +4 -0
- package/config/rules/typescript/guarded-happy-dom-register.yaml +14 -36
- package/config/workflows/feature-dev.yaml +5 -5
- package/config/workflows/idea-pipeline.yaml +2 -2
- package/config/workflows/task-pipeline.yaml +1 -1
- package/package.json +9 -9
- package/schemas/spur-config.schema.json +64 -0
- package/spur.js +2012 -383
- package/web/_astro/BoardApp.CXm9NttC.js +1 -0
- package/web/_astro/{BoardApp.DjpO2XHn.js → BoardApp.DDpBMmZh.js} +106 -105
- package/web/_astro/{TaskDetail.DilpuD7R.js → TaskDetail.BuXwnD5s.js} +1 -1
- package/web/_astro/{arc.KcqIior8.js → arc.ROFFfvlC.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.BTFU70BY.js → architectureDiagram-3BPJPVTR.BF8jS1C7.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.apx49Oy9.js → blockDiagram-GPEHLZMM.BAZd0UR-.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.BM-J4juX.js → c4Diagram-AAUBKEIU.BQiuu65q.js} +1 -1
- package/web/_astro/channel.e58tDmJn.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.K6z7IYZU.js → chunk-2J33WTMH.CaZ7Cj2C.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.BDYhxKa0.js → chunk-4BX2VUAB.Dl95s7jh.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.BnNOxqnI.js → chunk-55IACEB6.BS6cwIjQ.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.DNeg6N7v.js → chunk-727SXJPM.BodG8be9.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.BjILBkba.js → chunk-AQP2D5EJ.D7bElS24.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.DQ5UvvsV.js → chunk-FMBD7UC4.B4QCK-dI.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.Yn1OvRJs.js → chunk-ND2GUHAM.X1msYFei.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.UErqHgqw.js → chunk-QZHKN3VN.B2c4-Dz1.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.BmjVF7iZ.js → classDiagram-4FO5ZUOK.b8-sWDxa.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.BmjVF7iZ.js → classDiagram-v2-Q7XG4LA2.b8-sWDxa.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.iKBxnkbb.js → cose-bilkent-S5V4N54A.CT4xXx1C.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.OwnCCrs6.js → dagre-BM42HDAG.DAukBvJI.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.DCdcffxE.js → diagram-2AECGRRQ.iAkt-am3.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.Ai-LvmVW.js → diagram-5GNKFQAL.BbKJ0fPo.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.B6e21QDN.js → diagram-KO2AKTUF.DmAKP2Me.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.oPfqy1fq.js → diagram-LMA3HP47.CJzAaFxI.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.Dh5QRDCE.js → diagram-OG6HWLK6.z2Yhlt_S.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.DpBiOcO3.js → erDiagram-TEJ5UH35.C1inBaHt.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.NbMxFlVk.js → flowDiagram-I6XJVG4X.D6y2SP1V.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.JgZ3fDME.js → ganttDiagram-6RSMTGT7.BWgsQaJO.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.oMjFeZRt.js → gitGraphDiagram-PVQCEYII.So8AZT3S.js} +1 -1
- package/web/_astro/index.BaoJPQzM.css +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.kaio3YzK.js → infoDiagram-5YYISTIA.alTk5ecq.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.CXQfMyeF.js → ishikawaDiagram-YF4QCWOH.X82FajaS.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.AvNKMzx6.js → journeyDiagram-JHISSGLW.74uvU6ld.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.kv3cZGdE.js → kanban-definition-UN3LZRKU.D6BjF9UG.js} +1 -1
- package/web/_astro/{linear.CfLoHWjz.js → linear.BpRIYzdb.js} +1 -1
- package/web/_astro/{mermaid.core.BSV8pBn-.js → mermaid.core.fdUDKzul.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.CbL_3b32.js → mindmap-definition-RKZ34NQL.Df5SdMrH.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.5BXdOLRb.js → pieDiagram-4H26LBE5.xNCa7QSz.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.krXYbhlh.js → quadrantDiagram-W4KKPZXB.C_3DSB9b.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.COO4LapZ.js → requirementDiagram-4Y6WPE33.C2MFScI8.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.BvL0Jbdx.js → sankeyDiagram-5OEKKPKP.DEy6YHUG.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.Dk7Tu15E.js → sequenceDiagram-3UESZ5HK.CdQjeOkf.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.Cqh_KmEW.js → stateDiagram-AJRCARHV.C-j_0D_L.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.WapPgDCy.js → stateDiagram-v2-BHNVJYJU.BMzYaYSQ.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.CEVdiX0n.js → timeline-definition-PNZ67QCA.BaAa5dDC.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.Cd9A63eF.js → vennDiagram-CIIHVFJN.GZL7T0cb.js} +1 -1
- package/web/_astro/{wardley-L42UT6IY.DEiaHiIT.js → wardley-L42UT6IY.STDdK5oO.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.B7nGP61E.js → wardleyDiagram-YWT4CUSO.BJLlSFei.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.Bq8CHmxC.js → xychartDiagram-2RQKCTM6.CRGBFqsD.js} +1 -1
- package/web/index.html +2 -2
- package/web/_astro/BoardApp.Bcfvp2GH.js +0 -1
- package/web/_astro/channel.vSp82e1U.js +0 -1
- package/web/_astro/index.CA3GTZM6.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.10/node_modules/@gobing-ai/ts-utils/dist/errors.js
|
|
51
51
|
function isAppError(error) {
|
|
52
52
|
return error instanceof AppError;
|
|
53
53
|
}
|
|
@@ -75,7 +75,7 @@ var init_errors = __esm(() => {
|
|
|
75
75
|
};
|
|
76
76
|
});
|
|
77
77
|
|
|
78
|
-
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.
|
|
78
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.10/node_modules/@gobing-ai/ts-utils/dist/api-response.js
|
|
79
79
|
var API_ERROR_CODES, ERROR_CODE_TO_HTTP, CLIENT_SAFE_CODES;
|
|
80
80
|
var init_api_response = __esm(() => {
|
|
81
81
|
init_errors();
|
|
@@ -98,10 +98,10 @@ var init_api_response = __esm(() => {
|
|
|
98
98
|
CLIENT_SAFE_CODES = new Set([ErrorCode.NotFound, ErrorCode.Validation, ErrorCode.Conflict]);
|
|
99
99
|
});
|
|
100
100
|
|
|
101
|
-
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.
|
|
101
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.10/node_modules/@gobing-ai/ts-utils/dist/cursor.js
|
|
102
102
|
var init_cursor = () => {};
|
|
103
103
|
|
|
104
|
-
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.
|
|
104
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.10/node_modules/@gobing-ai/ts-utils/dist/object.js
|
|
105
105
|
function isPlainObject(value) {
|
|
106
106
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
107
107
|
}
|
|
@@ -117,7 +117,7 @@ function deepMerge(target, source) {
|
|
|
117
117
|
return result;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.
|
|
120
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.10/node_modules/@gobing-ai/ts-utils/dist/output.js
|
|
121
121
|
function processStream(name) {
|
|
122
122
|
const proc = globalThis.process;
|
|
123
123
|
const stream = proc?.[name];
|
|
@@ -138,7 +138,7 @@ function echoError(message, target = defaultStderrTarget ?? processStream("stder
|
|
|
138
138
|
}
|
|
139
139
|
var defaultStdoutTarget, defaultStderrTarget;
|
|
140
140
|
|
|
141
|
-
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.
|
|
141
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.10/node_modules/@gobing-ai/ts-utils/dist/index.js
|
|
142
142
|
var init_dist = __esm(() => {
|
|
143
143
|
init_api_response();
|
|
144
144
|
init_cursor();
|
|
@@ -21760,7 +21760,10 @@ var init_zod = __esm(() => {
|
|
|
21760
21760
|
init_external();
|
|
21761
21761
|
});
|
|
21762
21762
|
|
|
21763
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
21763
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+170d5985e987c687/node_modules/@gobing-ai/ts-runtime/dist/config.js
|
|
21764
|
+
function getProcessEnv() {
|
|
21765
|
+
return process.env;
|
|
21766
|
+
}
|
|
21764
21767
|
function interpolateEnv(value) {
|
|
21765
21768
|
return value.replace(ENV_INTERPOLATION_RE, (_match, name) => process.env[name] ?? `\${${name}}`);
|
|
21766
21769
|
}
|
|
@@ -21835,7 +21838,7 @@ var init_config = __esm(() => {
|
|
|
21835
21838
|
};
|
|
21836
21839
|
});
|
|
21837
21840
|
|
|
21838
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
21841
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+170d5985e987c687/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
|
|
21839
21842
|
import { appendFileSync, cpSync, createReadStream, createWriteStream, existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "fs";
|
|
21840
21843
|
import { dirname, resolve as resolvePath } from "path";
|
|
21841
21844
|
function createNodeFileSystem(root) {
|
|
@@ -21922,6 +21925,17 @@ function findProjectRoot(startDir) {
|
|
|
21922
21925
|
}
|
|
21923
21926
|
var init_file_system_node = () => {};
|
|
21924
21927
|
|
|
21928
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+170d5985e987c687/node_modules/@gobing-ai/ts-runtime/dist/db-errors.js
|
|
21929
|
+
var DbModuleNotInstalledError;
|
|
21930
|
+
var init_db_errors = __esm(() => {
|
|
21931
|
+
DbModuleNotInstalledError = class DbModuleNotInstalledError extends Error {
|
|
21932
|
+
constructor(message = "@gobing-ai/ts-db is not installed. It is an optional peer of @gobing-ai/ts-runtime, required only for createDbAdapter on node-bun. Install it (`bun add @gobing-ai/ts-db`) or, when bundling, mark `@gobing-ai/ts-db` external.", options) {
|
|
21933
|
+
super(message, options);
|
|
21934
|
+
this.name = "DbModuleNotInstalledError";
|
|
21935
|
+
}
|
|
21936
|
+
};
|
|
21937
|
+
});
|
|
21938
|
+
|
|
21925
21939
|
// ../../node_modules/.bun/is-plain-obj@4.1.0/node_modules/is-plain-obj/index.js
|
|
21926
21940
|
function isPlainObject4(value) {
|
|
21927
21941
|
if (typeof value !== "object" || value === null) {
|
|
@@ -29102,10 +29116,10 @@ var init_execa = __esm(() => {
|
|
|
29102
29116
|
} = getIpcExport());
|
|
29103
29117
|
});
|
|
29104
29118
|
|
|
29105
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29119
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+170d5985e987c687/node_modules/@gobing-ai/ts-runtime/dist/process-executor.js
|
|
29106
29120
|
import { isatty } from "tty";
|
|
29107
29121
|
|
|
29108
|
-
class
|
|
29122
|
+
class NodeProcessExecutor {
|
|
29109
29123
|
config;
|
|
29110
29124
|
constructor(config2 = {}) {
|
|
29111
29125
|
this.config = config2;
|
|
@@ -29126,13 +29140,21 @@ class ProcessExecutor {
|
|
|
29126
29140
|
signal: options.signal
|
|
29127
29141
|
});
|
|
29128
29142
|
const startedAt = Date.now();
|
|
29143
|
+
const startedIso = new Date(startedAt).toISOString();
|
|
29144
|
+
const registryId = this.beginRegistry(options.command, args, {
|
|
29145
|
+
label: options.label,
|
|
29146
|
+
source: options.source ?? "one-shot",
|
|
29147
|
+
teamId: options.teamId,
|
|
29148
|
+
agentId: options.agentId,
|
|
29149
|
+
startedAt: startedIso
|
|
29150
|
+
});
|
|
29129
29151
|
this.emitProcessEvent("process.started", {
|
|
29130
29152
|
command: options.command,
|
|
29131
29153
|
args,
|
|
29132
29154
|
exitCode: null,
|
|
29133
29155
|
durationMs: 0,
|
|
29134
29156
|
reason: "exit",
|
|
29135
|
-
timestamp:
|
|
29157
|
+
timestamp: startedIso,
|
|
29136
29158
|
...options.label !== undefined ? { label: options.label } : {}
|
|
29137
29159
|
});
|
|
29138
29160
|
try {
|
|
@@ -29146,6 +29168,7 @@ class ProcessExecutor {
|
|
|
29146
29168
|
...result.signalDescription !== undefined ? { signal: result.signalDescription } : {},
|
|
29147
29169
|
durationMs: result.durationMs
|
|
29148
29170
|
};
|
|
29171
|
+
this.completeRegistry(registryId, processResult.exitCode);
|
|
29149
29172
|
this.emitExitedFromResult(options, processResult, result);
|
|
29150
29173
|
return processResult;
|
|
29151
29174
|
} catch (error51) {
|
|
@@ -29159,6 +29182,7 @@ class ProcessExecutor {
|
|
|
29159
29182
|
...failed.signalDescription !== undefined ? { signal: failed.signalDescription } : failed.signal !== undefined ? { signal: failed.signal } : {},
|
|
29160
29183
|
durationMs: failed.durationMs ?? Date.now() - startedAt
|
|
29161
29184
|
};
|
|
29185
|
+
this.completeRegistry(registryId, processResult.exitCode);
|
|
29162
29186
|
this.emitExitedFromResult(options, processResult, error51, error51);
|
|
29163
29187
|
if (options.rejectOnError)
|
|
29164
29188
|
throw error51;
|
|
@@ -29172,15 +29196,23 @@ class ProcessExecutor {
|
|
|
29172
29196
|
}).catch(() => {
|
|
29173
29197
|
return;
|
|
29174
29198
|
});
|
|
29199
|
+
const startedAt = Date.now();
|
|
29200
|
+
const startedIso = new Date(startedAt).toISOString();
|
|
29201
|
+
const registryId = this.beginRegistry(options.command, args, {
|
|
29202
|
+
label: options.label,
|
|
29203
|
+
source: options.source ?? "other",
|
|
29204
|
+
teamId: options.teamId,
|
|
29205
|
+
agentId: options.agentId,
|
|
29206
|
+
startedAt: startedIso
|
|
29207
|
+
});
|
|
29175
29208
|
try {
|
|
29176
|
-
const startedAt = Date.now();
|
|
29177
29209
|
this.emitProcessEvent("process.started", {
|
|
29178
29210
|
command: options.command,
|
|
29179
29211
|
args,
|
|
29180
29212
|
exitCode: null,
|
|
29181
29213
|
durationMs: 0,
|
|
29182
29214
|
reason: "exit",
|
|
29183
|
-
timestamp:
|
|
29215
|
+
timestamp: startedIso,
|
|
29184
29216
|
...options.label !== undefined ? { label: options.label } : {}
|
|
29185
29217
|
});
|
|
29186
29218
|
const subprocess = Bun.spawn({
|
|
@@ -29191,13 +29223,20 @@ class ProcessExecutor {
|
|
|
29191
29223
|
...options.cwd !== undefined ? { cwd: options.cwd } : {},
|
|
29192
29224
|
...options.env !== undefined ? { env: options.env } : {}
|
|
29193
29225
|
});
|
|
29194
|
-
|
|
29226
|
+
const pipe2 = new BunPipeProcess(subprocess);
|
|
29227
|
+
if (pipe2.pid !== null) {
|
|
29228
|
+
this.config.registry?.update(registryId, { pid: pipe2.pid });
|
|
29229
|
+
}
|
|
29230
|
+
return new ObservedPipeProcess(pipe2, this.config.events, {
|
|
29195
29231
|
command: options.command,
|
|
29196
29232
|
args,
|
|
29197
29233
|
startedAt,
|
|
29234
|
+
registry: this.config.registry,
|
|
29235
|
+
registryId,
|
|
29198
29236
|
...options.label !== undefined ? { label: options.label } : {}
|
|
29199
29237
|
});
|
|
29200
29238
|
} catch (error51) {
|
|
29239
|
+
this.completeRegistry(registryId, null);
|
|
29201
29240
|
this.emitProcessEvent("process.exited", {
|
|
29202
29241
|
command: options.command,
|
|
29203
29242
|
args,
|
|
@@ -29216,6 +29255,28 @@ class ProcessExecutor {
|
|
|
29216
29255
|
return await fn();
|
|
29217
29256
|
return await this.config.tracer.traceAsync(name, async () => await fn());
|
|
29218
29257
|
}
|
|
29258
|
+
beginRegistry(command, args, meta3) {
|
|
29259
|
+
const registry2 = this.config.registry;
|
|
29260
|
+
if (!registry2)
|
|
29261
|
+
return "";
|
|
29262
|
+
return registry2.begin({
|
|
29263
|
+
command,
|
|
29264
|
+
args,
|
|
29265
|
+
source: meta3.source,
|
|
29266
|
+
startedAt: meta3.startedAt,
|
|
29267
|
+
...meta3.label !== undefined ? { label: meta3.label } : {},
|
|
29268
|
+
...meta3.teamId !== undefined ? { teamId: meta3.teamId } : {},
|
|
29269
|
+
...meta3.agentId !== undefined ? { agentId: meta3.agentId } : {}
|
|
29270
|
+
});
|
|
29271
|
+
}
|
|
29272
|
+
completeRegistry(id, exitCode, pid) {
|
|
29273
|
+
if (!id || !this.config.registry)
|
|
29274
|
+
return;
|
|
29275
|
+
this.config.registry.complete(id, {
|
|
29276
|
+
exitCode,
|
|
29277
|
+
...pid !== undefined ? { pid } : {}
|
|
29278
|
+
});
|
|
29279
|
+
}
|
|
29219
29280
|
emitExitedFromResult(options, result, completion, error51) {
|
|
29220
29281
|
const reason = isTimedOut(completion) ? "timeout" : result.signal !== undefined ? "signal" : error51 ? "error" : "exit";
|
|
29221
29282
|
this.emitProcessEvent("process.exited", {
|
|
@@ -29242,6 +29303,12 @@ class ObservedPipeProcess {
|
|
|
29242
29303
|
constructor(inner, events, context) {
|
|
29243
29304
|
this.inner = inner;
|
|
29244
29305
|
this.exited = inner.exited.then((exitCode) => {
|
|
29306
|
+
if (context.registry && context.registryId) {
|
|
29307
|
+
context.registry.complete(context.registryId, {
|
|
29308
|
+
exitCode,
|
|
29309
|
+
...inner.pid !== null ? { pid: inner.pid } : {}
|
|
29310
|
+
});
|
|
29311
|
+
}
|
|
29245
29312
|
events?.emit("process.exited", {
|
|
29246
29313
|
command: context.command,
|
|
29247
29314
|
args: context.args,
|
|
@@ -29342,7 +29409,67 @@ var init_process_executor = __esm(() => {
|
|
|
29342
29409
|
init_execa();
|
|
29343
29410
|
});
|
|
29344
29411
|
|
|
29345
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29412
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+170d5985e987c687/node_modules/@gobing-ai/ts-runtime/dist/runtime-node-bun.js
|
|
29413
|
+
function getNodeFileSystem() {
|
|
29414
|
+
if (!_nodeFileSystem)
|
|
29415
|
+
_nodeFileSystem = createNodeFileSystem();
|
|
29416
|
+
return _nodeFileSystem;
|
|
29417
|
+
}
|
|
29418
|
+
async function loadNodeConfig(options) {
|
|
29419
|
+
const fs = getNodeFileSystem();
|
|
29420
|
+
const raw = await readYamlConfig(fs);
|
|
29421
|
+
return buildConfigFromObject(raw ?? {}, options);
|
|
29422
|
+
}
|
|
29423
|
+
async function readYamlConfig(fs) {
|
|
29424
|
+
const candidates = [getProcessEnv().CONFIG_PATH, "config/config.yaml", "config/config.example.yaml"].filter((p) => typeof p === "string" && p.length > 0);
|
|
29425
|
+
for (const candidate of candidates) {
|
|
29426
|
+
const resolved = fs.resolve(candidate);
|
|
29427
|
+
if (await fs.exists(resolved)) {
|
|
29428
|
+
const content = await fs.readFile(resolved);
|
|
29429
|
+
try {
|
|
29430
|
+
return $parse(content);
|
|
29431
|
+
} catch {}
|
|
29432
|
+
}
|
|
29433
|
+
}
|
|
29434
|
+
return null;
|
|
29435
|
+
}
|
|
29436
|
+
var _nodeFileSystem, nodeBunFactory;
|
|
29437
|
+
var init_runtime_node_bun = __esm(() => {
|
|
29438
|
+
init_dist2();
|
|
29439
|
+
init_config();
|
|
29440
|
+
init_db_errors();
|
|
29441
|
+
init_file_system_node();
|
|
29442
|
+
init_process_executor();
|
|
29443
|
+
nodeBunFactory = {
|
|
29444
|
+
runtimeName: "node-bun",
|
|
29445
|
+
capabilities: {
|
|
29446
|
+
hasFilesystem: true,
|
|
29447
|
+
hasProcessExecution: true,
|
|
29448
|
+
hasPersistentStorage: true,
|
|
29449
|
+
hasSqlDatabase: true
|
|
29450
|
+
},
|
|
29451
|
+
createFileSystem: () => getNodeFileSystem(),
|
|
29452
|
+
createProcessExecutor: (config2) => new NodeProcessExecutor(config2),
|
|
29453
|
+
async loadConfig(options) {
|
|
29454
|
+
return loadNodeConfig(options);
|
|
29455
|
+
},
|
|
29456
|
+
async createDbAdapter(config2) {
|
|
29457
|
+
const tsDbSpec = "@gobing-ai/ts-db";
|
|
29458
|
+
let mod;
|
|
29459
|
+
try {
|
|
29460
|
+
mod = await import(tsDbSpec);
|
|
29461
|
+
} catch (cause) {
|
|
29462
|
+
throw new DbModuleNotInstalledError(undefined, { cause });
|
|
29463
|
+
}
|
|
29464
|
+
if (typeof mod.createDbAdapter !== "function") {
|
|
29465
|
+
throw new DbModuleNotInstalledError("@gobing-ai/ts-db is installed but does not export createDbAdapter \u2014 the installed version may be incompatible or partial.");
|
|
29466
|
+
}
|
|
29467
|
+
return mod.createDbAdapter({ driver: "bun-sqlite", url: config2.url });
|
|
29468
|
+
}
|
|
29469
|
+
};
|
|
29470
|
+
});
|
|
29471
|
+
|
|
29472
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+170d5985e987c687/node_modules/@gobing-ai/ts-runtime/dist/context.js
|
|
29346
29473
|
class RuntimeContext {
|
|
29347
29474
|
scope;
|
|
29348
29475
|
runtimeName;
|
|
@@ -29360,7 +29487,7 @@ class RuntimeContext {
|
|
|
29360
29487
|
this.register("config", options.services?.config ?? buildConfigFromObject({}));
|
|
29361
29488
|
this.register("fileSystem", options.services?.fileSystem ?? createNodeFileSystem());
|
|
29362
29489
|
if (this.capabilities.hasProcessExecution && options.services?.processExecutor === undefined) {
|
|
29363
|
-
this.register("processExecutor",
|
|
29490
|
+
this.register("processExecutor", nodeBunFactory.createProcessExecutor());
|
|
29364
29491
|
}
|
|
29365
29492
|
for (const [key, value] of Object.entries(options.services ?? {})) {
|
|
29366
29493
|
if (value !== undefined) {
|
|
@@ -29409,10 +29536,10 @@ function isDisposable(value) {
|
|
|
29409
29536
|
var init_context = __esm(() => {
|
|
29410
29537
|
init_config();
|
|
29411
29538
|
init_file_system_node();
|
|
29412
|
-
|
|
29539
|
+
init_runtime_node_bun();
|
|
29413
29540
|
});
|
|
29414
29541
|
|
|
29415
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29542
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+170d5985e987c687/node_modules/@gobing-ai/ts-runtime/dist/path.js
|
|
29416
29543
|
function normalizeSeparators(path6) {
|
|
29417
29544
|
return path6.replaceAll("\\", "/");
|
|
29418
29545
|
}
|
|
@@ -29473,17 +29600,17 @@ var init_path = __esm(() => {
|
|
|
29473
29600
|
SEP = globalThis.process?.platform === "win32" ? "\\" : "/";
|
|
29474
29601
|
});
|
|
29475
29602
|
|
|
29476
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29603
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+170d5985e987c687/node_modules/@gobing-ai/ts-runtime/dist/schema-validation.js
|
|
29477
29604
|
var REMOTE_SCHEMA_MAX_BYTES;
|
|
29478
29605
|
var init_schema_validation = __esm(() => {
|
|
29479
29606
|
init_dist2();
|
|
29480
29607
|
REMOTE_SCHEMA_MAX_BYTES = 5 * 1024 * 1024;
|
|
29481
29608
|
});
|
|
29482
29609
|
|
|
29483
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29610
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+170d5985e987c687/node_modules/@gobing-ai/ts-runtime/dist/types.js
|
|
29484
29611
|
var init_types = () => {};
|
|
29485
29612
|
|
|
29486
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29613
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+170d5985e987c687/node_modules/@gobing-ai/ts-runtime/dist/index.js
|
|
29487
29614
|
var init_dist3 = __esm(() => {
|
|
29488
29615
|
init_config();
|
|
29489
29616
|
init_context();
|
|
@@ -29492,7 +29619,7 @@ var init_dist3 = __esm(() => {
|
|
|
29492
29619
|
init_types();
|
|
29493
29620
|
});
|
|
29494
29621
|
|
|
29495
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29622
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+170d5985e987c687/node_modules/@gobing-ai/ts-runtime/dist/bun-sqlite.js
|
|
29496
29623
|
import { Database } from "bun:sqlite";
|
|
29497
29624
|
var init_bun_sqlite = () => {};
|
|
29498
29625
|
|
|
@@ -33684,7 +33811,7 @@ var init_bun_sqlite2 = __esm(() => {
|
|
|
33684
33811
|
init_session2();
|
|
33685
33812
|
});
|
|
33686
33813
|
|
|
33687
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
33814
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/schema/inbox-messages.js
|
|
33688
33815
|
var inboxMessages;
|
|
33689
33816
|
var init_inbox_messages = __esm(() => {
|
|
33690
33817
|
init_sqlite_core();
|
|
@@ -33703,7 +33830,7 @@ var init_inbox_messages = __esm(() => {
|
|
|
33703
33830
|
}, (table2) => [index("idx_inbox_messages_to_status").on(table2.toId, table2.status)]);
|
|
33704
33831
|
});
|
|
33705
33832
|
|
|
33706
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
33833
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/schema/common.js
|
|
33707
33834
|
function nowTimestamp() {
|
|
33708
33835
|
return Date.now();
|
|
33709
33836
|
}
|
|
@@ -33732,7 +33859,7 @@ var init_common3 = __esm(() => {
|
|
|
33732
33859
|
appendOnlyColumns = buildAppendOnlyColumns();
|
|
33733
33860
|
});
|
|
33734
33861
|
|
|
33735
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
33862
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/schema/queue-jobs.js
|
|
33736
33863
|
var queueJobs;
|
|
33737
33864
|
var init_queue_jobs = __esm(() => {
|
|
33738
33865
|
init_sqlite_core();
|
|
@@ -33752,7 +33879,7 @@ var init_queue_jobs = __esm(() => {
|
|
|
33752
33879
|
}, (table2) => [index("queue_jobs_ready_idx").on(table2.status, table2.nextRetryAt, table2.createdAt)]);
|
|
33753
33880
|
});
|
|
33754
33881
|
|
|
33755
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
33882
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/schema/runtime.js
|
|
33756
33883
|
var exports_runtime = {};
|
|
33757
33884
|
__export(exports_runtime, {
|
|
33758
33885
|
queueJobs: () => queueJobs,
|
|
@@ -33763,7 +33890,7 @@ var init_runtime = __esm(() => {
|
|
|
33763
33890
|
init_queue_jobs();
|
|
33764
33891
|
});
|
|
33765
33892
|
|
|
33766
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
33893
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/adapters/bun-sqlite.js
|
|
33767
33894
|
var exports_bun_sqlite = {};
|
|
33768
33895
|
__export(exports_bun_sqlite, {
|
|
33769
33896
|
BunSqliteAdapter: () => BunSqliteAdapter
|
|
@@ -34052,7 +34179,7 @@ var init_d1 = __esm(() => {
|
|
|
34052
34179
|
init_session3();
|
|
34053
34180
|
});
|
|
34054
34181
|
|
|
34055
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34182
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/adapters/d1.js
|
|
34056
34183
|
var exports_d1 = {};
|
|
34057
34184
|
__export(exports_d1, {
|
|
34058
34185
|
D1Adapter: () => D1Adapter
|
|
@@ -34116,7 +34243,7 @@ var init_d12 = __esm(() => {
|
|
|
34116
34243
|
init_runtime();
|
|
34117
34244
|
});
|
|
34118
34245
|
|
|
34119
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34246
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/adapter.js
|
|
34120
34247
|
async function createDbAdapter(config3) {
|
|
34121
34248
|
switch (config3.driver) {
|
|
34122
34249
|
case "bun-sqlite": {
|
|
@@ -34156,7 +34283,7 @@ var init_drizzle_orm = __esm(() => {
|
|
|
34156
34283
|
init_view_common();
|
|
34157
34284
|
});
|
|
34158
34285
|
|
|
34159
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34286
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/query-spec.js
|
|
34160
34287
|
function compilePredicate(predicate) {
|
|
34161
34288
|
if ("and" in predicate) {
|
|
34162
34289
|
const parts = predicate.and.map(compilePredicate).filter((p) => p !== undefined);
|
|
@@ -34194,7 +34321,7 @@ var init_query_spec = __esm(() => {
|
|
|
34194
34321
|
};
|
|
34195
34322
|
});
|
|
34196
34323
|
|
|
34197
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34324
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/base-dao.js
|
|
34198
34325
|
function asSelectQuery(query) {
|
|
34199
34326
|
return query;
|
|
34200
34327
|
}
|
|
@@ -34236,7 +34363,7 @@ var init_base_dao = __esm(() => {
|
|
|
34236
34363
|
init_query_spec();
|
|
34237
34364
|
});
|
|
34238
34365
|
|
|
34239
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34366
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/embedded-migrations.js
|
|
34240
34367
|
var embeddedMigrations;
|
|
34241
34368
|
var init_embedded_migrations = __esm(() => {
|
|
34242
34369
|
embeddedMigrations = [
|
|
@@ -34268,7 +34395,7 @@ var init_embedded_migrations = __esm(() => {
|
|
|
34268
34395
|
];
|
|
34269
34396
|
});
|
|
34270
34397
|
|
|
34271
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34398
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/entity-dao.js
|
|
34272
34399
|
var EntityDao;
|
|
34273
34400
|
var init_entity_dao = __esm(() => {
|
|
34274
34401
|
init_drizzle_orm();
|
|
@@ -34430,18 +34557,24 @@ var init_entity_dao = __esm(() => {
|
|
|
34430
34557
|
};
|
|
34431
34558
|
});
|
|
34432
34559
|
|
|
34433
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34560
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/inbox-message-dao.js
|
|
34561
|
+
function isPromiseLike(value) {
|
|
34562
|
+
return value !== null && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
|
|
34563
|
+
}
|
|
34434
34564
|
var InboxMessageDao;
|
|
34435
34565
|
var init_inbox_message_dao = __esm(() => {
|
|
34436
34566
|
init_drizzle_orm();
|
|
34437
34567
|
init_entity_dao();
|
|
34438
34568
|
init_inbox_messages();
|
|
34439
34569
|
InboxMessageDao = class InboxMessageDao extends EntityDao {
|
|
34440
|
-
|
|
34570
|
+
events;
|
|
34571
|
+
constructor(adapter, options = {}) {
|
|
34441
34572
|
super(adapter, inboxMessages, [inboxMessages.id], "inbox_messages");
|
|
34573
|
+
this.events = options.events;
|
|
34442
34574
|
}
|
|
34443
34575
|
async enqueue(fromId, toId, body, inReplyTo) {
|
|
34444
34576
|
const id = crypto.randomUUID();
|
|
34577
|
+
const now = this.now();
|
|
34445
34578
|
await this.create({
|
|
34446
34579
|
id,
|
|
34447
34580
|
fromId,
|
|
@@ -34449,8 +34582,17 @@ var init_inbox_message_dao = __esm(() => {
|
|
|
34449
34582
|
body,
|
|
34450
34583
|
status: "queued",
|
|
34451
34584
|
injectAttempts: 0,
|
|
34585
|
+
createdAt: now,
|
|
34586
|
+
updatedAt: now,
|
|
34452
34587
|
...inReplyTo !== undefined ? { inReplyTo } : {}
|
|
34453
34588
|
});
|
|
34589
|
+
this.emitEvent("message.enqueued", {
|
|
34590
|
+
id,
|
|
34591
|
+
fromId,
|
|
34592
|
+
toId,
|
|
34593
|
+
...inReplyTo !== undefined ? { inReplyTo } : {},
|
|
34594
|
+
timestamp: now
|
|
34595
|
+
});
|
|
34454
34596
|
return id;
|
|
34455
34597
|
}
|
|
34456
34598
|
async drainPending(toId) {
|
|
@@ -34467,19 +34609,48 @@ var init_inbox_message_dao = __esm(() => {
|
|
|
34467
34609
|
ORDER BY created_at
|
|
34468
34610
|
)
|
|
34469
34611
|
AND ${inboxMessages.status} = 'queued'`).returning();
|
|
34612
|
+
for (const row of rows) {
|
|
34613
|
+
this.emitEvent("message.injected", {
|
|
34614
|
+
id: row.id,
|
|
34615
|
+
fromId: row.fromId,
|
|
34616
|
+
toId: row.toId,
|
|
34617
|
+
inReplyTo: row.inReplyTo,
|
|
34618
|
+
injectAttempts: row.injectAttempts,
|
|
34619
|
+
timestamp: now
|
|
34620
|
+
});
|
|
34621
|
+
}
|
|
34470
34622
|
return rows;
|
|
34471
34623
|
}
|
|
34472
34624
|
async markDelivered(msgId) {
|
|
34473
|
-
|
|
34625
|
+
const now = this.now();
|
|
34626
|
+
const updated = await this.update(msgId, {
|
|
34474
34627
|
status: "delivered",
|
|
34475
|
-
deliveredAt:
|
|
34628
|
+
deliveredAt: now
|
|
34476
34629
|
});
|
|
34630
|
+
if (updated) {
|
|
34631
|
+
this.emitEvent("message.delivered", {
|
|
34632
|
+
id: updated.id,
|
|
34633
|
+
fromId: updated.fromId,
|
|
34634
|
+
toId: updated.toId,
|
|
34635
|
+
deliveredAt: now,
|
|
34636
|
+
timestamp: now
|
|
34637
|
+
});
|
|
34638
|
+
}
|
|
34477
34639
|
}
|
|
34478
34640
|
async markFailed(msgId, error51) {
|
|
34479
|
-
await this.update(msgId, {
|
|
34641
|
+
const updated = await this.update(msgId, {
|
|
34480
34642
|
status: "failed",
|
|
34481
34643
|
injectError: error51
|
|
34482
34644
|
});
|
|
34645
|
+
if (updated) {
|
|
34646
|
+
this.emitEvent("message.failed", {
|
|
34647
|
+
id: updated.id,
|
|
34648
|
+
fromId: updated.fromId,
|
|
34649
|
+
toId: updated.toId,
|
|
34650
|
+
error: error51,
|
|
34651
|
+
timestamp: updated.updatedAt
|
|
34652
|
+
});
|
|
34653
|
+
}
|
|
34483
34654
|
}
|
|
34484
34655
|
async inbox(toId, limit, offset) {
|
|
34485
34656
|
return this.list({
|
|
@@ -34500,6 +34671,16 @@ var init_inbox_message_dao = __esm(() => {
|
|
|
34500
34671
|
async getById(id) {
|
|
34501
34672
|
return this.findBy(inboxMessages.id, id);
|
|
34502
34673
|
}
|
|
34674
|
+
emitEvent(event, ...args) {
|
|
34675
|
+
if (!this.events)
|
|
34676
|
+
return;
|
|
34677
|
+
try {
|
|
34678
|
+
const pending = this.events.emit(event, ...args);
|
|
34679
|
+
if (isPromiseLike(pending)) {
|
|
34680
|
+
Promise.resolve(pending).catch(() => {});
|
|
34681
|
+
}
|
|
34682
|
+
} catch {}
|
|
34683
|
+
}
|
|
34503
34684
|
};
|
|
34504
34685
|
});
|
|
34505
34686
|
|
|
@@ -34549,7 +34730,7 @@ var init_migrator2 = __esm(() => {
|
|
|
34549
34730
|
init_migrator();
|
|
34550
34731
|
});
|
|
34551
34732
|
|
|
34552
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34733
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/migrate.js
|
|
34553
34734
|
async function ensureJournalTable(adapter, table3) {
|
|
34554
34735
|
await adapter.exec(`CREATE TABLE IF NOT EXISTS "${table3}" (` + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "hash text NOT NULL, " + "created_at numeric" + ")");
|
|
34555
34736
|
}
|
|
@@ -34624,7 +34805,7 @@ var init_migrate = __esm(() => {
|
|
|
34624
34805
|
init_embedded_migrations();
|
|
34625
34806
|
});
|
|
34626
34807
|
|
|
34627
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34808
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/queue-job-dao.js
|
|
34628
34809
|
var QueueJobDao;
|
|
34629
34810
|
var init_queue_job_dao = __esm(() => {
|
|
34630
34811
|
init_drizzle_orm();
|
|
@@ -34765,7 +34946,7 @@ var init_queue_job_dao = __esm(() => {
|
|
|
34765
34946
|
};
|
|
34766
34947
|
});
|
|
34767
34948
|
|
|
34768
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34949
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/index.js
|
|
34769
34950
|
var exports_dist = {};
|
|
34770
34951
|
__export(exports_dist, {
|
|
34771
34952
|
embeddedMigrations: () => embeddedMigrations,
|
|
@@ -36904,6 +37085,18 @@ var require_extra_typings = __commonJS((exports, module) => {
|
|
|
36904
37085
|
function folderPathWithDefault(defaultPath) {
|
|
36905
37086
|
return exports_external.preprocess((v) => v == null ? undefined : v, exports_external.string().default(defaultPath));
|
|
36906
37087
|
}
|
|
37088
|
+
function normalizeMember(member) {
|
|
37089
|
+
return typeof member === "string" ? { executor: member } : { ...member };
|
|
37090
|
+
}
|
|
37091
|
+
function resolveExecutor(name, agentConfig, opts) {
|
|
37092
|
+
const exec = agentConfig?.executors?.find((entry) => entry.name === name);
|
|
37093
|
+
if (exec !== undefined)
|
|
37094
|
+
return { agent: exec.agent, model: exec.model };
|
|
37095
|
+
if (opts?.isCanonicalAgent === undefined || opts.isCanonicalAgent(name)) {
|
|
37096
|
+
return { agent: name };
|
|
37097
|
+
}
|
|
37098
|
+
throw new Error(`Unknown executor or agent reference: "${name}"`);
|
|
37099
|
+
}
|
|
36907
37100
|
function parseEnvBoolean(value) {
|
|
36908
37101
|
if (value === undefined || value === "")
|
|
36909
37102
|
return;
|
|
@@ -36932,7 +37125,7 @@ function buildConfigFromEnv(env = process.env) {
|
|
|
36932
37125
|
}
|
|
36933
37126
|
});
|
|
36934
37127
|
}
|
|
36935
|
-
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, AgentConfigSchema, RulesConfigSchema, WorkflowsConfigSchema, RedactionConfigSchema, spurConfigSchema, configSchema2;
|
|
37128
|
+
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;
|
|
36936
37129
|
var init_src = __esm(() => {
|
|
36937
37130
|
init_zod();
|
|
36938
37131
|
SPUR_ENV_VARS = {
|
|
@@ -36959,24 +37152,81 @@ var init_src = __esm(() => {
|
|
|
36959
37152
|
agent: exports_external.string().min(1),
|
|
36960
37153
|
model: exports_external.string().min(1).optional()
|
|
36961
37154
|
});
|
|
37155
|
+
AGENT_ID_REGEX = /^[a-z][a-z0-9_-]{1,63}$/;
|
|
37156
|
+
TeamMemberConfigSchema = exports_external.union([
|
|
37157
|
+
exports_external.string().min(1),
|
|
37158
|
+
exports_external.object({
|
|
37159
|
+
executor: exports_external.string().min(1),
|
|
37160
|
+
id: exports_external.string().min(1).optional(),
|
|
37161
|
+
purpose: exports_external.string().optional(),
|
|
37162
|
+
workspace: exports_external.string().min(1).optional(),
|
|
37163
|
+
model: exports_external.string().min(1).optional(),
|
|
37164
|
+
autonomy: exports_external.string().optional(),
|
|
37165
|
+
systemPrompt: exports_external.string().optional(),
|
|
37166
|
+
command: exports_external.array(exports_external.string().min(1)).optional(),
|
|
37167
|
+
autostart: exports_external.boolean().optional()
|
|
37168
|
+
})
|
|
37169
|
+
]);
|
|
37170
|
+
TeamConfigSchema = exports_external.object({
|
|
37171
|
+
name: exports_external.string().min(1),
|
|
37172
|
+
work_dir: exports_external.string().min(1),
|
|
37173
|
+
autostart: exports_external.boolean().optional(),
|
|
37174
|
+
members: exports_external.array(TeamMemberConfigSchema).min(1)
|
|
37175
|
+
});
|
|
36962
37176
|
AgentConfigSchema = exports_external.object({
|
|
36963
37177
|
default: exports_external.string().optional(),
|
|
36964
37178
|
executors: exports_external.array(AgentExecutorConfigSchema).optional(),
|
|
36965
|
-
"default-by-phase": exports_external.record(exports_external.string(), exports_external.string()).optional()
|
|
37179
|
+
"default-by-phase": exports_external.record(exports_external.string(), exports_external.string()).optional(),
|
|
37180
|
+
team: exports_external.record(exports_external.string(), TeamConfigSchema).optional()
|
|
36966
37181
|
}).superRefine((value, ctx) => {
|
|
36967
37182
|
const executors = value.executors;
|
|
36968
|
-
if (executors
|
|
36969
|
-
|
|
36970
|
-
|
|
36971
|
-
|
|
36972
|
-
|
|
36973
|
-
|
|
36974
|
-
|
|
36975
|
-
|
|
36976
|
-
|
|
36977
|
-
}
|
|
37183
|
+
if (executors !== undefined) {
|
|
37184
|
+
const seen = new Set;
|
|
37185
|
+
for (const [index2, executor] of executors.entries()) {
|
|
37186
|
+
if (seen.has(executor.name)) {
|
|
37187
|
+
ctx.addIssue({
|
|
37188
|
+
code: exports_external.ZodIssueCode.custom,
|
|
37189
|
+
message: `Duplicate executor name: ${executor.name}`,
|
|
37190
|
+
path: ["executors", index2, "name"]
|
|
37191
|
+
});
|
|
37192
|
+
}
|
|
37193
|
+
seen.add(executor.name);
|
|
36978
37194
|
}
|
|
36979
|
-
|
|
37195
|
+
}
|
|
37196
|
+
const team = value.team;
|
|
37197
|
+
if (team === undefined)
|
|
37198
|
+
return;
|
|
37199
|
+
const seenComposed = new Set;
|
|
37200
|
+
for (const [teamId, teamConfig] of Object.entries(team)) {
|
|
37201
|
+
const seenLocal = new Set;
|
|
37202
|
+
teamConfig.members.forEach((member, index2) => {
|
|
37203
|
+
const ref = normalizeMember(member);
|
|
37204
|
+
const localId = ref.id ?? ref.executor;
|
|
37205
|
+
if (seenLocal.has(localId)) {
|
|
37206
|
+
ctx.addIssue({
|
|
37207
|
+
code: exports_external.ZodIssueCode.custom,
|
|
37208
|
+
message: `Duplicate team member id: ${localId} in team "${teamId}"`,
|
|
37209
|
+
path: ["team", teamId, "members", index2]
|
|
37210
|
+
});
|
|
37211
|
+
}
|
|
37212
|
+
seenLocal.add(localId);
|
|
37213
|
+
const composedId = `${teamId}-${localId}`;
|
|
37214
|
+
if (!AGENT_ID_REGEX.test(composedId)) {
|
|
37215
|
+
ctx.addIssue({
|
|
37216
|
+
code: exports_external.ZodIssueCode.custom,
|
|
37217
|
+
message: `Invalid composed agent id "${composedId}": team key "${teamId}" + member "${localId}" must match ^[a-z][a-z0-9_-]{1,63}$ (2-64 chars, lowercase).`,
|
|
37218
|
+
path: ["team", teamId, "members", index2]
|
|
37219
|
+
});
|
|
37220
|
+
}
|
|
37221
|
+
if (seenComposed.has(composedId)) {
|
|
37222
|
+
ctx.addIssue({
|
|
37223
|
+
code: exports_external.ZodIssueCode.custom,
|
|
37224
|
+
message: `Composed agent id "${composedId}" collides across teams \u2014 every <teamId>-<localId> must be globally unique (a hyphenated team key can overlap another team's member id).`,
|
|
37225
|
+
path: ["team", teamId, "members", index2]
|
|
37226
|
+
});
|
|
37227
|
+
}
|
|
37228
|
+
seenComposed.add(composedId);
|
|
37229
|
+
});
|
|
36980
37230
|
}
|
|
36981
37231
|
});
|
|
36982
37232
|
RulesConfigSchema = exports_external.object({
|
|
@@ -37018,7 +37268,7 @@ var init_src = __esm(() => {
|
|
|
37018
37268
|
});
|
|
37019
37269
|
});
|
|
37020
37270
|
|
|
37021
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37271
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/config.js
|
|
37022
37272
|
function parseYamlObject(text3) {
|
|
37023
37273
|
let parsed;
|
|
37024
37274
|
try {
|
|
@@ -37042,7 +37292,7 @@ function getNodeEnv() {
|
|
|
37042
37292
|
function isTestEnv() {
|
|
37043
37293
|
return getNodeEnv() === "test";
|
|
37044
37294
|
}
|
|
37045
|
-
function
|
|
37295
|
+
function getProcessEnv2() {
|
|
37046
37296
|
return process.env;
|
|
37047
37297
|
}
|
|
37048
37298
|
function getDatabaseUrl() {
|
|
@@ -37145,7 +37395,7 @@ var init_config2 = __esm(() => {
|
|
|
37145
37395
|
};
|
|
37146
37396
|
});
|
|
37147
37397
|
|
|
37148
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37398
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
|
|
37149
37399
|
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";
|
|
37150
37400
|
import { dirname as dirname2, resolve as resolvePath3 } from "path";
|
|
37151
37401
|
function createNodeFileSystem3(root) {
|
|
@@ -37232,16 +37482,16 @@ function findProjectRoot3(startDir) {
|
|
|
37232
37482
|
}
|
|
37233
37483
|
var init_file_system_node2 = () => {};
|
|
37234
37484
|
|
|
37235
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37236
|
-
var D1NotConfiguredError2,
|
|
37237
|
-
var
|
|
37485
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/db-errors.js
|
|
37486
|
+
var D1NotConfiguredError2, DbModuleNotInstalledError3;
|
|
37487
|
+
var init_db_errors2 = __esm(() => {
|
|
37238
37488
|
D1NotConfiguredError2 = class D1NotConfiguredError2 extends Error {
|
|
37239
37489
|
constructor(message = "D1 DbAdapter is not yet implemented; see the ts-db D1 round.") {
|
|
37240
37490
|
super(message);
|
|
37241
37491
|
this.name = "D1NotConfiguredError";
|
|
37242
37492
|
}
|
|
37243
37493
|
};
|
|
37244
|
-
|
|
37494
|
+
DbModuleNotInstalledError3 = class DbModuleNotInstalledError3 extends Error {
|
|
37245
37495
|
constructor(message = "@gobing-ai/ts-db is not installed. It is an optional peer of @gobing-ai/ts-runtime, required only for createDbAdapter on node-bun. Install it (`bun add @gobing-ai/ts-db`) or, when bundling, mark `@gobing-ai/ts-db` external.", options) {
|
|
37246
37496
|
super(message, options);
|
|
37247
37497
|
this.name = "DbModuleNotInstalledError";
|
|
@@ -37249,7 +37499,7 @@ var init_db_errors = __esm(() => {
|
|
|
37249
37499
|
};
|
|
37250
37500
|
});
|
|
37251
37501
|
|
|
37252
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37502
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/file-system-cf.js
|
|
37253
37503
|
function createCfFileSystem2() {
|
|
37254
37504
|
return {
|
|
37255
37505
|
getProjectRoot: () => "/bundle",
|
|
@@ -37288,7 +37538,7 @@ function createCfFileSystem2() {
|
|
|
37288
37538
|
}
|
|
37289
37539
|
var UNSUPPORTED = "FileSystem is not available on Cloudflare Workers. Use D1, KV, or R2 for persistent storage.";
|
|
37290
37540
|
|
|
37291
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37541
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/runtime-cf.js
|
|
37292
37542
|
var exports_runtime_cf = {};
|
|
37293
37543
|
__export(exports_runtime_cf, {
|
|
37294
37544
|
cloudflareWorkersFactory: () => cloudflareWorkersFactory2
|
|
@@ -37297,7 +37547,7 @@ var CONFIG_YAML_BINDING = "CONFIG_YAML", cloudflareWorkersFactory2;
|
|
|
37297
37547
|
var init_runtime_cf = __esm(() => {
|
|
37298
37548
|
init_dist2();
|
|
37299
37549
|
init_config2();
|
|
37300
|
-
|
|
37550
|
+
init_db_errors2();
|
|
37301
37551
|
cloudflareWorkersFactory2 = {
|
|
37302
37552
|
runtimeName: "cloudflare-workers",
|
|
37303
37553
|
capabilities: {
|
|
@@ -37326,10 +37576,10 @@ var init_runtime_cf = __esm(() => {
|
|
|
37326
37576
|
};
|
|
37327
37577
|
});
|
|
37328
37578
|
|
|
37329
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37579
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/process-executor.js
|
|
37330
37580
|
import { isatty as isatty2 } from "tty";
|
|
37331
37581
|
|
|
37332
|
-
class
|
|
37582
|
+
class NodeProcessExecutor3 {
|
|
37333
37583
|
config;
|
|
37334
37584
|
constructor(config3 = {}) {
|
|
37335
37585
|
this.config = config3;
|
|
@@ -37350,13 +37600,21 @@ class ProcessExecutor3 {
|
|
|
37350
37600
|
signal: options.signal
|
|
37351
37601
|
});
|
|
37352
37602
|
const startedAt = Date.now();
|
|
37603
|
+
const startedIso = new Date(startedAt).toISOString();
|
|
37604
|
+
const registryId = this.beginRegistry(options.command, args, {
|
|
37605
|
+
label: options.label,
|
|
37606
|
+
source: options.source ?? "one-shot",
|
|
37607
|
+
teamId: options.teamId,
|
|
37608
|
+
agentId: options.agentId,
|
|
37609
|
+
startedAt: startedIso
|
|
37610
|
+
});
|
|
37353
37611
|
this.emitProcessEvent("process.started", {
|
|
37354
37612
|
command: options.command,
|
|
37355
37613
|
args,
|
|
37356
37614
|
exitCode: null,
|
|
37357
37615
|
durationMs: 0,
|
|
37358
37616
|
reason: "exit",
|
|
37359
|
-
timestamp:
|
|
37617
|
+
timestamp: startedIso,
|
|
37360
37618
|
...options.label !== undefined ? { label: options.label } : {}
|
|
37361
37619
|
});
|
|
37362
37620
|
try {
|
|
@@ -37370,6 +37628,7 @@ class ProcessExecutor3 {
|
|
|
37370
37628
|
...result.signalDescription !== undefined ? { signal: result.signalDescription } : {},
|
|
37371
37629
|
durationMs: result.durationMs
|
|
37372
37630
|
};
|
|
37631
|
+
this.completeRegistry(registryId, processResult.exitCode);
|
|
37373
37632
|
this.emitExitedFromResult(options, processResult, result);
|
|
37374
37633
|
return processResult;
|
|
37375
37634
|
} catch (error51) {
|
|
@@ -37383,6 +37642,7 @@ class ProcessExecutor3 {
|
|
|
37383
37642
|
...failed.signalDescription !== undefined ? { signal: failed.signalDescription } : failed.signal !== undefined ? { signal: failed.signal } : {},
|
|
37384
37643
|
durationMs: failed.durationMs ?? Date.now() - startedAt
|
|
37385
37644
|
};
|
|
37645
|
+
this.completeRegistry(registryId, processResult.exitCode);
|
|
37386
37646
|
this.emitExitedFromResult(options, processResult, error51, error51);
|
|
37387
37647
|
if (options.rejectOnError)
|
|
37388
37648
|
throw error51;
|
|
@@ -37396,15 +37656,23 @@ class ProcessExecutor3 {
|
|
|
37396
37656
|
}).catch(() => {
|
|
37397
37657
|
return;
|
|
37398
37658
|
});
|
|
37659
|
+
const startedAt = Date.now();
|
|
37660
|
+
const startedIso = new Date(startedAt).toISOString();
|
|
37661
|
+
const registryId = this.beginRegistry(options.command, args, {
|
|
37662
|
+
label: options.label,
|
|
37663
|
+
source: options.source ?? "other",
|
|
37664
|
+
teamId: options.teamId,
|
|
37665
|
+
agentId: options.agentId,
|
|
37666
|
+
startedAt: startedIso
|
|
37667
|
+
});
|
|
37399
37668
|
try {
|
|
37400
|
-
const startedAt = Date.now();
|
|
37401
37669
|
this.emitProcessEvent("process.started", {
|
|
37402
37670
|
command: options.command,
|
|
37403
37671
|
args,
|
|
37404
37672
|
exitCode: null,
|
|
37405
37673
|
durationMs: 0,
|
|
37406
37674
|
reason: "exit",
|
|
37407
|
-
timestamp:
|
|
37675
|
+
timestamp: startedIso,
|
|
37408
37676
|
...options.label !== undefined ? { label: options.label } : {}
|
|
37409
37677
|
});
|
|
37410
37678
|
const subprocess = Bun.spawn({
|
|
@@ -37415,13 +37683,20 @@ class ProcessExecutor3 {
|
|
|
37415
37683
|
...options.cwd !== undefined ? { cwd: options.cwd } : {},
|
|
37416
37684
|
...options.env !== undefined ? { env: options.env } : {}
|
|
37417
37685
|
});
|
|
37418
|
-
|
|
37686
|
+
const pipe2 = new BunPipeProcess2(subprocess);
|
|
37687
|
+
if (pipe2.pid !== null) {
|
|
37688
|
+
this.config.registry?.update(registryId, { pid: pipe2.pid });
|
|
37689
|
+
}
|
|
37690
|
+
return new ObservedPipeProcess2(pipe2, this.config.events, {
|
|
37419
37691
|
command: options.command,
|
|
37420
37692
|
args,
|
|
37421
37693
|
startedAt,
|
|
37694
|
+
registry: this.config.registry,
|
|
37695
|
+
registryId,
|
|
37422
37696
|
...options.label !== undefined ? { label: options.label } : {}
|
|
37423
37697
|
});
|
|
37424
37698
|
} catch (error51) {
|
|
37699
|
+
this.completeRegistry(registryId, null);
|
|
37425
37700
|
this.emitProcessEvent("process.exited", {
|
|
37426
37701
|
command: options.command,
|
|
37427
37702
|
args,
|
|
@@ -37440,6 +37715,28 @@ class ProcessExecutor3 {
|
|
|
37440
37715
|
return await fn();
|
|
37441
37716
|
return await this.config.tracer.traceAsync(name, async () => await fn());
|
|
37442
37717
|
}
|
|
37718
|
+
beginRegistry(command, args, meta3) {
|
|
37719
|
+
const registry2 = this.config.registry;
|
|
37720
|
+
if (!registry2)
|
|
37721
|
+
return "";
|
|
37722
|
+
return registry2.begin({
|
|
37723
|
+
command,
|
|
37724
|
+
args,
|
|
37725
|
+
source: meta3.source,
|
|
37726
|
+
startedAt: meta3.startedAt,
|
|
37727
|
+
...meta3.label !== undefined ? { label: meta3.label } : {},
|
|
37728
|
+
...meta3.teamId !== undefined ? { teamId: meta3.teamId } : {},
|
|
37729
|
+
...meta3.agentId !== undefined ? { agentId: meta3.agentId } : {}
|
|
37730
|
+
});
|
|
37731
|
+
}
|
|
37732
|
+
completeRegistry(id, exitCode, pid) {
|
|
37733
|
+
if (!id || !this.config.registry)
|
|
37734
|
+
return;
|
|
37735
|
+
this.config.registry.complete(id, {
|
|
37736
|
+
exitCode,
|
|
37737
|
+
...pid !== undefined ? { pid } : {}
|
|
37738
|
+
});
|
|
37739
|
+
}
|
|
37443
37740
|
emitExitedFromResult(options, result, completion, error51) {
|
|
37444
37741
|
const reason = isTimedOut2(completion) ? "timeout" : result.signal !== undefined ? "signal" : error51 ? "error" : "exit";
|
|
37445
37742
|
this.emitProcessEvent("process.exited", {
|
|
@@ -37466,6 +37763,12 @@ class ObservedPipeProcess2 {
|
|
|
37466
37763
|
constructor(inner, events, context2) {
|
|
37467
37764
|
this.inner = inner;
|
|
37468
37765
|
this.exited = inner.exited.then((exitCode) => {
|
|
37766
|
+
if (context2.registry && context2.registryId) {
|
|
37767
|
+
context2.registry.complete(context2.registryId, {
|
|
37768
|
+
exitCode,
|
|
37769
|
+
...inner.pid !== null ? { pid: inner.pid } : {}
|
|
37770
|
+
});
|
|
37771
|
+
}
|
|
37469
37772
|
events?.emit("process.exited", {
|
|
37470
37773
|
command: context2.command,
|
|
37471
37774
|
args: context2.args,
|
|
@@ -37607,34 +37910,33 @@ function isTimedOut2(error51) {
|
|
|
37607
37910
|
function errorMessage2(error51) {
|
|
37608
37911
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
37609
37912
|
}
|
|
37610
|
-
var
|
|
37913
|
+
var ProcessExecutor2;
|
|
37611
37914
|
var init_process_executor2 = __esm(() => {
|
|
37612
37915
|
init_execa();
|
|
37613
|
-
|
|
37614
|
-
};
|
|
37916
|
+
ProcessExecutor2 = NodeProcessExecutor3;
|
|
37615
37917
|
});
|
|
37616
37918
|
|
|
37617
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37919
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/runtime-node-bun.js
|
|
37618
37920
|
var exports_runtime_node_bun = {};
|
|
37619
37921
|
__export(exports_runtime_node_bun, {
|
|
37620
|
-
nodeBunFactory: () =>
|
|
37922
|
+
nodeBunFactory: () => nodeBunFactory3,
|
|
37621
37923
|
_resetNodeFileSystem: () => _resetNodeFileSystem2
|
|
37622
37924
|
});
|
|
37623
|
-
function
|
|
37624
|
-
if (!
|
|
37625
|
-
|
|
37626
|
-
return
|
|
37925
|
+
function getNodeFileSystem2() {
|
|
37926
|
+
if (!_nodeFileSystem2)
|
|
37927
|
+
_nodeFileSystem2 = createNodeFileSystem3();
|
|
37928
|
+
return _nodeFileSystem2;
|
|
37627
37929
|
}
|
|
37628
37930
|
function _resetNodeFileSystem2() {
|
|
37629
|
-
|
|
37931
|
+
_nodeFileSystem2 = undefined;
|
|
37630
37932
|
}
|
|
37631
|
-
async function
|
|
37632
|
-
const fs2 =
|
|
37633
|
-
const raw = await
|
|
37933
|
+
async function loadNodeConfig2(options) {
|
|
37934
|
+
const fs2 = getNodeFileSystem2();
|
|
37935
|
+
const raw = await readYamlConfig2(fs2);
|
|
37634
37936
|
return buildConfigFromObject2(raw ?? {}, options);
|
|
37635
37937
|
}
|
|
37636
|
-
async function
|
|
37637
|
-
const candidates = [
|
|
37938
|
+
async function readYamlConfig2(fs2) {
|
|
37939
|
+
const candidates = [getProcessEnv2().CONFIG_PATH, "config/config.yaml", "config/config.example.yaml"].filter((p) => typeof p === "string" && p.length > 0);
|
|
37638
37940
|
for (const candidate of candidates) {
|
|
37639
37941
|
const resolved = fs2.resolve(candidate);
|
|
37640
37942
|
if (await fs2.exists(resolved)) {
|
|
@@ -37646,14 +37948,14 @@ async function readYamlConfig(fs2) {
|
|
|
37646
37948
|
}
|
|
37647
37949
|
return null;
|
|
37648
37950
|
}
|
|
37649
|
-
var
|
|
37650
|
-
var
|
|
37951
|
+
var _nodeFileSystem2, nodeBunFactory3;
|
|
37952
|
+
var init_runtime_node_bun2 = __esm(() => {
|
|
37651
37953
|
init_dist2();
|
|
37652
37954
|
init_config2();
|
|
37653
|
-
|
|
37955
|
+
init_db_errors2();
|
|
37654
37956
|
init_file_system_node2();
|
|
37655
37957
|
init_process_executor2();
|
|
37656
|
-
|
|
37958
|
+
nodeBunFactory3 = {
|
|
37657
37959
|
runtimeName: "node-bun",
|
|
37658
37960
|
capabilities: {
|
|
37659
37961
|
hasFilesystem: true,
|
|
@@ -37661,10 +37963,10 @@ var init_runtime_node_bun = __esm(() => {
|
|
|
37661
37963
|
hasPersistentStorage: true,
|
|
37662
37964
|
hasSqlDatabase: true
|
|
37663
37965
|
},
|
|
37664
|
-
createFileSystem: () =>
|
|
37665
|
-
createProcessExecutor: (config3) => new
|
|
37966
|
+
createFileSystem: () => getNodeFileSystem2(),
|
|
37967
|
+
createProcessExecutor: (config3) => new NodeProcessExecutor3(config3),
|
|
37666
37968
|
async loadConfig(options) {
|
|
37667
|
-
return
|
|
37969
|
+
return loadNodeConfig2(options);
|
|
37668
37970
|
},
|
|
37669
37971
|
async createDbAdapter(config3) {
|
|
37670
37972
|
const tsDbSpec = "@gobing-ai/ts-db";
|
|
@@ -37672,17 +37974,17 @@ var init_runtime_node_bun = __esm(() => {
|
|
|
37672
37974
|
try {
|
|
37673
37975
|
mod = await import(tsDbSpec);
|
|
37674
37976
|
} catch (cause) {
|
|
37675
|
-
throw new
|
|
37977
|
+
throw new DbModuleNotInstalledError3(undefined, { cause });
|
|
37676
37978
|
}
|
|
37677
37979
|
if (typeof mod.createDbAdapter !== "function") {
|
|
37678
|
-
throw new
|
|
37980
|
+
throw new DbModuleNotInstalledError3("@gobing-ai/ts-db is installed but does not export createDbAdapter \u2014 the installed version may be incompatible or partial.");
|
|
37679
37981
|
}
|
|
37680
37982
|
return mod.createDbAdapter({ driver: "bun-sqlite", url: config3.url });
|
|
37681
37983
|
}
|
|
37682
37984
|
};
|
|
37683
37985
|
});
|
|
37684
37986
|
|
|
37685
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37987
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/platform.js
|
|
37686
37988
|
function isCloudflareWorkerRuntime2() {
|
|
37687
37989
|
return globalThis.navigator?.userAgent?.startsWith("Cloudflare-Workers") ?? false;
|
|
37688
37990
|
}
|
|
@@ -37694,8 +37996,8 @@ async function loadRuntimeFactory2() {
|
|
|
37694
37996
|
const { cloudflareWorkersFactory: cloudflareWorkersFactory3 } = await Promise.resolve().then(() => (init_runtime_cf(), exports_runtime_cf));
|
|
37695
37997
|
factory = cloudflareWorkersFactory3;
|
|
37696
37998
|
} else {
|
|
37697
|
-
const { nodeBunFactory:
|
|
37698
|
-
factory =
|
|
37999
|
+
const { nodeBunFactory: nodeBunFactory4 } = await Promise.resolve().then(() => (init_runtime_node_bun2(), exports_runtime_node_bun));
|
|
38000
|
+
factory = nodeBunFactory4;
|
|
37699
38001
|
}
|
|
37700
38002
|
_factory = factory;
|
|
37701
38003
|
return factory;
|
|
@@ -37712,7 +38014,7 @@ function _resetRuntimeFactory2() {
|
|
|
37712
38014
|
}
|
|
37713
38015
|
var _factory, _runtimeName;
|
|
37714
38016
|
|
|
37715
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38017
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/context.js
|
|
37716
38018
|
class RuntimeContext2 {
|
|
37717
38019
|
scope;
|
|
37718
38020
|
runtimeName;
|
|
@@ -37730,7 +38032,7 @@ class RuntimeContext2 {
|
|
|
37730
38032
|
this.register("config", options.services?.config ?? buildConfigFromObject2({}));
|
|
37731
38033
|
this.register("fileSystem", options.services?.fileSystem ?? createNodeFileSystem3());
|
|
37732
38034
|
if (this.capabilities.hasProcessExecution && options.services?.processExecutor === undefined) {
|
|
37733
|
-
this.register("processExecutor",
|
|
38035
|
+
this.register("processExecutor", nodeBunFactory3.createProcessExecutor());
|
|
37734
38036
|
}
|
|
37735
38037
|
for (const [key, value] of Object.entries(options.services ?? {})) {
|
|
37736
38038
|
if (value !== undefined) {
|
|
@@ -37799,10 +38101,10 @@ function createRuntimeContext(options = {}) {
|
|
|
37799
38101
|
var init_context2 = __esm(() => {
|
|
37800
38102
|
init_config2();
|
|
37801
38103
|
init_file_system_node2();
|
|
37802
|
-
|
|
38104
|
+
init_runtime_node_bun2();
|
|
37803
38105
|
});
|
|
37804
38106
|
|
|
37805
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38107
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/path.js
|
|
37806
38108
|
function normalizeSeparators2(path7) {
|
|
37807
38109
|
return path7.replaceAll("\\", "/");
|
|
37808
38110
|
}
|
|
@@ -37925,7 +38227,7 @@ var init_path2 = __esm(() => {
|
|
|
37925
38227
|
SEP2 = globalThis.process?.platform === "win32" ? "\\" : "/";
|
|
37926
38228
|
});
|
|
37927
38229
|
|
|
37928
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38230
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/fs.js
|
|
37929
38231
|
async function ensureDirForFile2(path7, fs2 = createNodeFileSystem3()) {
|
|
37930
38232
|
await fs2.ensureDir(dirnamePath(path7));
|
|
37931
38233
|
}
|
|
@@ -37976,7 +38278,131 @@ var init_fs = __esm(() => {
|
|
|
37976
38278
|
init_path2();
|
|
37977
38279
|
});
|
|
37978
38280
|
|
|
37979
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38281
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/process-registry.js
|
|
38282
|
+
function allocateId() {
|
|
38283
|
+
nextIdSeq += 1;
|
|
38284
|
+
return `pe_${Date.now().toString(36)}_${nextIdSeq.toString(36)}`;
|
|
38285
|
+
}
|
|
38286
|
+
|
|
38287
|
+
class InMemoryProcessRegistry2 {
|
|
38288
|
+
maxEntries;
|
|
38289
|
+
byId = new Map;
|
|
38290
|
+
order = [];
|
|
38291
|
+
listeners = new Set;
|
|
38292
|
+
constructor(options = {}) {
|
|
38293
|
+
this.maxEntries = options.maxEntries ?? 1000;
|
|
38294
|
+
}
|
|
38295
|
+
listExecutions(filter) {
|
|
38296
|
+
const out = [];
|
|
38297
|
+
for (const id of this.order) {
|
|
38298
|
+
const exec = this.byId.get(id);
|
|
38299
|
+
if (!exec)
|
|
38300
|
+
continue;
|
|
38301
|
+
if (filter?.source !== undefined && exec.source !== filter.source)
|
|
38302
|
+
continue;
|
|
38303
|
+
if (filter?.running === true && exec.status !== "running")
|
|
38304
|
+
continue;
|
|
38305
|
+
if (filter?.running === false && exec.status !== "exited")
|
|
38306
|
+
continue;
|
|
38307
|
+
if (filter?.teamId !== undefined && exec.teamId !== filter.teamId)
|
|
38308
|
+
continue;
|
|
38309
|
+
if (filter?.agentId !== undefined && exec.agentId !== filter.agentId)
|
|
38310
|
+
continue;
|
|
38311
|
+
out.push(exec);
|
|
38312
|
+
}
|
|
38313
|
+
return out;
|
|
38314
|
+
}
|
|
38315
|
+
getExecution(id) {
|
|
38316
|
+
return this.byId.get(id);
|
|
38317
|
+
}
|
|
38318
|
+
subscribe(listener) {
|
|
38319
|
+
this.listeners.add(listener);
|
|
38320
|
+
return () => {
|
|
38321
|
+
this.listeners.delete(listener);
|
|
38322
|
+
};
|
|
38323
|
+
}
|
|
38324
|
+
begin(input) {
|
|
38325
|
+
const id = allocateId();
|
|
38326
|
+
const execution = {
|
|
38327
|
+
id,
|
|
38328
|
+
command: input.command,
|
|
38329
|
+
args: Object.freeze([...input.args ?? []]),
|
|
38330
|
+
source: input.source ?? "other",
|
|
38331
|
+
startedAt: input.startedAt ?? new Date().toISOString(),
|
|
38332
|
+
status: "running",
|
|
38333
|
+
...input.label !== undefined ? { label: input.label } : {},
|
|
38334
|
+
...input.teamId !== undefined ? { teamId: input.teamId } : {},
|
|
38335
|
+
...input.agentId !== undefined ? { agentId: input.agentId } : {},
|
|
38336
|
+
...input.pid !== undefined ? { pid: input.pid } : {}
|
|
38337
|
+
};
|
|
38338
|
+
this.byId.set(id, execution);
|
|
38339
|
+
this.order.push(id);
|
|
38340
|
+
this.enforceCap();
|
|
38341
|
+
this.emit({ type: "started", execution });
|
|
38342
|
+
return id;
|
|
38343
|
+
}
|
|
38344
|
+
update(id, patch) {
|
|
38345
|
+
const current = this.byId.get(id);
|
|
38346
|
+
if (!current)
|
|
38347
|
+
return;
|
|
38348
|
+
const next = {
|
|
38349
|
+
...current,
|
|
38350
|
+
...patch.pid !== undefined ? { pid: patch.pid } : {},
|
|
38351
|
+
...patch.label !== undefined ? { label: patch.label } : {}
|
|
38352
|
+
};
|
|
38353
|
+
this.byId.set(id, next);
|
|
38354
|
+
this.emit({ type: "updated", execution: next });
|
|
38355
|
+
}
|
|
38356
|
+
complete(id, update2 = {}) {
|
|
38357
|
+
const current = this.byId.get(id);
|
|
38358
|
+
if (!current)
|
|
38359
|
+
return;
|
|
38360
|
+
if (current.status === "exited") {
|
|
38361
|
+
if (update2.pid !== undefined && current.pid === undefined) {
|
|
38362
|
+
const patched = { ...current, pid: update2.pid };
|
|
38363
|
+
this.byId.set(id, patched);
|
|
38364
|
+
this.emit({ type: "updated", execution: patched });
|
|
38365
|
+
}
|
|
38366
|
+
return;
|
|
38367
|
+
}
|
|
38368
|
+
const next = {
|
|
38369
|
+
...current,
|
|
38370
|
+
status: "exited",
|
|
38371
|
+
exitedAt: update2.exitedAt ?? new Date().toISOString(),
|
|
38372
|
+
exitCode: update2.exitCode !== undefined ? update2.exitCode : null,
|
|
38373
|
+
...update2.pid !== undefined ? { pid: update2.pid } : {}
|
|
38374
|
+
};
|
|
38375
|
+
this.byId.set(id, next);
|
|
38376
|
+
this.emit({ type: "exited", execution: next });
|
|
38377
|
+
}
|
|
38378
|
+
clear() {
|
|
38379
|
+
this.byId.clear();
|
|
38380
|
+
this.order.length = 0;
|
|
38381
|
+
}
|
|
38382
|
+
emit(event) {
|
|
38383
|
+
for (const listener of this.listeners) {
|
|
38384
|
+
try {
|
|
38385
|
+
listener(event);
|
|
38386
|
+
} catch {}
|
|
38387
|
+
}
|
|
38388
|
+
}
|
|
38389
|
+
enforceCap() {
|
|
38390
|
+
while (this.order.length > this.maxEntries) {
|
|
38391
|
+
let dropIdx = this.order.findIndex((id) => this.byId.get(id)?.status === "exited");
|
|
38392
|
+
if (dropIdx < 0)
|
|
38393
|
+
dropIdx = 0;
|
|
38394
|
+
const [removed] = this.order.splice(dropIdx, 1);
|
|
38395
|
+
if (removed !== undefined)
|
|
38396
|
+
this.byId.delete(removed);
|
|
38397
|
+
}
|
|
38398
|
+
}
|
|
38399
|
+
}
|
|
38400
|
+
function createInMemoryProcessRegistry2(options) {
|
|
38401
|
+
return new InMemoryProcessRegistry2(options);
|
|
38402
|
+
}
|
|
38403
|
+
var nextIdSeq = 0;
|
|
38404
|
+
|
|
38405
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/schema-validation.js
|
|
37980
38406
|
async function loadStructuredConfig(path7, options = {}) {
|
|
37981
38407
|
const content = await (options.fileSystem ?? createNodeFileSystem3()).readFile(path7);
|
|
37982
38408
|
return await parseStructuredConfig(content, path7, options);
|
|
@@ -38253,10 +38679,10 @@ var init_schema_validation2 = __esm(() => {
|
|
|
38253
38679
|
defaultResolve = typeof Bun !== "undefined" ? (specifier, from) => Bun.resolveSync(specifier, from) : undefined;
|
|
38254
38680
|
});
|
|
38255
38681
|
|
|
38256
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38682
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/types.js
|
|
38257
38683
|
var init_types2 = () => {};
|
|
38258
38684
|
|
|
38259
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38685
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/index.js
|
|
38260
38686
|
var exports_dist2 = {};
|
|
38261
38687
|
__export(exports_dist2, {
|
|
38262
38688
|
writeJsonFile: () => writeJsonFile2,
|
|
@@ -38271,7 +38697,7 @@ __export(exports_dist2, {
|
|
|
38271
38697
|
parseStructuredConfig: () => parseStructuredConfig,
|
|
38272
38698
|
parseConfigYaml: () => parseConfigYaml,
|
|
38273
38699
|
normalizeSeparators: () => normalizeSeparators2,
|
|
38274
|
-
nodeBunFactory: () =>
|
|
38700
|
+
nodeBunFactory: () => nodeBunFactory3,
|
|
38275
38701
|
loadStructuredConfig: () => loadStructuredConfig,
|
|
38276
38702
|
loadRuntimeFactory: () => loadRuntimeFactory2,
|
|
38277
38703
|
joinPath: () => joinPath2,
|
|
@@ -38280,7 +38706,7 @@ __export(exports_dist2, {
|
|
|
38280
38706
|
isAbsolutePath: () => isAbsolutePath2,
|
|
38281
38707
|
interpolateTree: () => interpolateTree2,
|
|
38282
38708
|
interpolateEnv: () => interpolateEnv2,
|
|
38283
|
-
getProcessEnv: () =>
|
|
38709
|
+
getProcessEnv: () => getProcessEnv2,
|
|
38284
38710
|
getProcessCwd: () => getProcessCwd2,
|
|
38285
38711
|
getNodeEnv: () => getNodeEnv,
|
|
38286
38712
|
getHomeDir: () => getHomeDir,
|
|
@@ -38293,6 +38719,7 @@ __export(exports_dist2, {
|
|
|
38293
38719
|
createRuntimeContext: () => createRuntimeContext,
|
|
38294
38720
|
createNodeFileSystem: () => createNodeFileSystem3,
|
|
38295
38721
|
createLogStream: () => createLogStream2,
|
|
38722
|
+
createInMemoryProcessRegistry: () => createInMemoryProcessRegistry2,
|
|
38296
38723
|
createCfFileSystem: () => createCfFileSystem2,
|
|
38297
38724
|
configSchema: () => configSchema3,
|
|
38298
38725
|
cloudflareWorkersFactory: () => cloudflareWorkersFactory2,
|
|
@@ -38307,9 +38734,10 @@ __export(exports_dist2, {
|
|
|
38307
38734
|
StructuredConfigSchemaError: () => StructuredConfigSchemaError,
|
|
38308
38735
|
SEP: () => SEP2,
|
|
38309
38736
|
RuntimeContext: () => RuntimeContext2,
|
|
38310
|
-
ProcessExecutor: () =>
|
|
38311
|
-
NodeProcessExecutor: () =>
|
|
38312
|
-
|
|
38737
|
+
ProcessExecutor: () => ProcessExecutor2,
|
|
38738
|
+
NodeProcessExecutor: () => NodeProcessExecutor3,
|
|
38739
|
+
InMemoryProcessRegistry: () => InMemoryProcessRegistry2,
|
|
38740
|
+
DbModuleNotInstalledError: () => DbModuleNotInstalledError3,
|
|
38313
38741
|
D1NotConfiguredError: () => D1NotConfiguredError2,
|
|
38314
38742
|
ConfigLoadError: () => ConfigLoadError2,
|
|
38315
38743
|
BunSyncProcessExecutor: () => BunSyncProcessExecutor2,
|
|
@@ -38317,12 +38745,12 @@ __export(exports_dist2, {
|
|
|
38317
38745
|
});
|
|
38318
38746
|
var init_dist5 = __esm(() => {
|
|
38319
38747
|
init_context2();
|
|
38320
|
-
|
|
38748
|
+
init_db_errors2();
|
|
38321
38749
|
init_file_system_node2();
|
|
38322
38750
|
init_fs();
|
|
38323
38751
|
init_process_executor2();
|
|
38324
38752
|
init_runtime_cf();
|
|
38325
|
-
|
|
38753
|
+
init_runtime_node_bun2();
|
|
38326
38754
|
init_process_executor2();
|
|
38327
38755
|
init_config2();
|
|
38328
38756
|
init_context2();
|
|
@@ -38467,6 +38895,27 @@ async function loadSpurConfig(cwd = process.cwd(), opts) {
|
|
|
38467
38895
|
promise2.catch(() => spurConfigCache.delete(key));
|
|
38468
38896
|
return promise2;
|
|
38469
38897
|
}
|
|
38898
|
+
function expandTilde(path8) {
|
|
38899
|
+
if (path8 === "~")
|
|
38900
|
+
return homedir();
|
|
38901
|
+
if (path8.startsWith("~/"))
|
|
38902
|
+
return join2(homedir(), path8.slice(2));
|
|
38903
|
+
return path8;
|
|
38904
|
+
}
|
|
38905
|
+
function expandTeamTildes(config4) {
|
|
38906
|
+
const teams = config4.agent?.team;
|
|
38907
|
+
if (teams === undefined)
|
|
38908
|
+
return config4;
|
|
38909
|
+
const expanded = {};
|
|
38910
|
+
for (const [teamId, team] of Object.entries(teams)) {
|
|
38911
|
+
expanded[teamId] = {
|
|
38912
|
+
...team,
|
|
38913
|
+
work_dir: expandTilde(team.work_dir),
|
|
38914
|
+
members: team.members.map((member) => typeof member === "string" || member.workspace === undefined ? member : { ...member, workspace: expandTilde(member.workspace) })
|
|
38915
|
+
};
|
|
38916
|
+
}
|
|
38917
|
+
return { ...config4, agent: { ...config4.agent, team: expanded } };
|
|
38918
|
+
}
|
|
38470
38919
|
async function loadSpurConfigFile(configPath, opts, validateJsonSchema2) {
|
|
38471
38920
|
let raw;
|
|
38472
38921
|
if (validateJsonSchema2) {
|
|
@@ -38490,7 +38939,7 @@ async function loadSpurConfigFile(configPath, opts, validateJsonSchema2) {
|
|
|
38490
38939
|
const text3 = await nodeFs.readFile(resolved);
|
|
38491
38940
|
raw = $parse(text3) ?? {};
|
|
38492
38941
|
}
|
|
38493
|
-
return spurConfigSchema.parse(raw);
|
|
38942
|
+
return expandTeamTildes(spurConfigSchema.parse(raw));
|
|
38494
38943
|
}
|
|
38495
38944
|
async function loadStructuredSpurConfig(configPath, opts) {
|
|
38496
38945
|
const validateJsonSchema2 = opts?.validateJsonSchema ?? true;
|
|
@@ -40382,7 +40831,7 @@ var init_mod = __esm(() => {
|
|
|
40382
40831
|
init_config3();
|
|
40383
40832
|
});
|
|
40384
40833
|
|
|
40385
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
40834
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/logger.js
|
|
40386
40835
|
function toLogTapeLevel(level) {
|
|
40387
40836
|
return level === "warn" ? "warning" : level;
|
|
40388
40837
|
}
|
|
@@ -41935,7 +42384,7 @@ var require_src = __commonJS((exports) => {
|
|
|
41935
42384
|
};
|
|
41936
42385
|
});
|
|
41937
42386
|
|
|
41938
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
42387
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/telemetry/sdk.js
|
|
41939
42388
|
function getTelemetryConfig(configPartial = {}) {
|
|
41940
42389
|
return {
|
|
41941
42390
|
enabled: configPartial.enabled ?? CONFIG_DEFAULTS.enabled,
|
|
@@ -41971,7 +42420,7 @@ var init_sdk = __esm(() => {
|
|
|
41971
42420
|
resolvedConfig = getTelemetryConfig();
|
|
41972
42421
|
});
|
|
41973
42422
|
|
|
41974
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
42423
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/telemetry/tracing.js
|
|
41975
42424
|
function isSuppressed(tracer2) {
|
|
41976
42425
|
return tracer2 === undefined && !getResolvedConfig().enabled;
|
|
41977
42426
|
}
|
|
@@ -42011,7 +42460,7 @@ var init_tracing2 = __esm(() => {
|
|
|
42011
42460
|
import_api2 = __toESM(require_src(), 1);
|
|
42012
42461
|
});
|
|
42013
42462
|
|
|
42014
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
42463
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/telemetry/metrics.js
|
|
42015
42464
|
function getMeter() {
|
|
42016
42465
|
return import_api3.metrics.getMeter(METER_NAME, METER_VERSION);
|
|
42017
42466
|
}
|
|
@@ -42108,7 +42557,7 @@ var init_metrics = __esm(() => {
|
|
|
42108
42557
|
instruments = {};
|
|
42109
42558
|
});
|
|
42110
42559
|
|
|
42111
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
42560
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/event-bus/event-bus.js
|
|
42112
42561
|
function busLogger() {
|
|
42113
42562
|
if (!_busLogger)
|
|
42114
42563
|
_busLogger = getLogger2("event-bus");
|
|
@@ -42353,7 +42802,7 @@ var init_event_bus = __esm(() => {
|
|
|
42353
42802
|
init_metrics();
|
|
42354
42803
|
});
|
|
42355
42804
|
|
|
42356
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
42805
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/event-bus/default-observers.js
|
|
42357
42806
|
function obsLogger() {
|
|
42358
42807
|
if (!_obsLogger)
|
|
42359
42808
|
_obsLogger = getLogger2("event-bus.observers");
|
|
@@ -42417,7 +42866,105 @@ var init_default_observers = __esm(() => {
|
|
|
42417
42866
|
init_event_bus();
|
|
42418
42867
|
});
|
|
42419
42868
|
|
|
42420
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
42869
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/event-bus/file-observer.js
|
|
42870
|
+
function parentDir(filePath) {
|
|
42871
|
+
const idx = filePath.lastIndexOf("/");
|
|
42872
|
+
return idx <= 0 ? "." : filePath.slice(0, idx);
|
|
42873
|
+
}
|
|
42874
|
+
function isPromiseLike2(value) {
|
|
42875
|
+
return value !== null && typeof value === "object" && "then" in value;
|
|
42876
|
+
}
|
|
42877
|
+
function attachFileObserver(lifecycleBus, filePath, writer) {
|
|
42878
|
+
const logger2 = getLogger2("event-bus.file-observer");
|
|
42879
|
+
const ensureResult = writer.ensureDir(parentDir(filePath));
|
|
42880
|
+
let ready = !isPromiseLike2(ensureResult);
|
|
42881
|
+
let pending = isPromiseLike2(ensureResult);
|
|
42882
|
+
let setupFailed = false;
|
|
42883
|
+
let sequence = 0;
|
|
42884
|
+
let writeChain = isPromiseLike2(ensureResult) ? Promise.resolve(ensureResult).then(() => {
|
|
42885
|
+
ready = true;
|
|
42886
|
+
}).catch((error51) => {
|
|
42887
|
+
setupFailed = true;
|
|
42888
|
+
logger2.warn("failed to prepare event bus file observer directory", {
|
|
42889
|
+
filePath,
|
|
42890
|
+
error: error51 instanceof Error ? error51.message : String(error51)
|
|
42891
|
+
});
|
|
42892
|
+
}) : Promise.resolve();
|
|
42893
|
+
function setPending(next) {
|
|
42894
|
+
const current = ++sequence;
|
|
42895
|
+
pending = true;
|
|
42896
|
+
writeChain = next.catch((error51) => {
|
|
42897
|
+
logger2.warn("failed to append event bus lifecycle event", {
|
|
42898
|
+
filePath,
|
|
42899
|
+
error: error51 instanceof Error ? error51.message : String(error51)
|
|
42900
|
+
});
|
|
42901
|
+
}).finally(() => {
|
|
42902
|
+
if (sequence === current)
|
|
42903
|
+
pending = false;
|
|
42904
|
+
});
|
|
42905
|
+
}
|
|
42906
|
+
function writeLine2(line) {
|
|
42907
|
+
const content = `${JSON.stringify(line)}
|
|
42908
|
+
`;
|
|
42909
|
+
if (setupFailed)
|
|
42910
|
+
return;
|
|
42911
|
+
if (ready && !pending) {
|
|
42912
|
+
const result = writer.appendFile(filePath, content);
|
|
42913
|
+
if (isPromiseLike2(result)) {
|
|
42914
|
+
setPending(Promise.resolve(result));
|
|
42915
|
+
}
|
|
42916
|
+
return;
|
|
42917
|
+
}
|
|
42918
|
+
setPending(writeChain.then(() => {
|
|
42919
|
+
if (setupFailed)
|
|
42920
|
+
return;
|
|
42921
|
+
return writer.appendFile(filePath, content);
|
|
42922
|
+
}));
|
|
42923
|
+
}
|
|
42924
|
+
lifecycleBus.on("bus.emit.done", (d) => {
|
|
42925
|
+
const payload = d.detail !== null && typeof d.detail === "object" && !Array.isArray(d.detail) ? d.detail : undefined;
|
|
42926
|
+
writeLine2({
|
|
42927
|
+
ts: new Date().toISOString(),
|
|
42928
|
+
lifecycle: "bus.emit.done",
|
|
42929
|
+
event: d.event,
|
|
42930
|
+
syncCount: d.syncCount,
|
|
42931
|
+
asyncCount: d.asyncCount,
|
|
42932
|
+
emitDurationMs: d.emitDurationMs,
|
|
42933
|
+
errors: d.errors,
|
|
42934
|
+
...payload && Object.keys(payload).length > 0 ? { payload } : {}
|
|
42935
|
+
});
|
|
42936
|
+
});
|
|
42937
|
+
lifecycleBus.on("bus.emit.noop", (d) => {
|
|
42938
|
+
writeLine2({
|
|
42939
|
+
ts: new Date().toISOString(),
|
|
42940
|
+
lifecycle: "bus.emit.noop",
|
|
42941
|
+
event: d.event
|
|
42942
|
+
});
|
|
42943
|
+
});
|
|
42944
|
+
lifecycleBus.on("bus.handler.error", (d) => {
|
|
42945
|
+
writeLine2({
|
|
42946
|
+
ts: new Date().toISOString(),
|
|
42947
|
+
lifecycle: "bus.handler.error",
|
|
42948
|
+
event: d.event,
|
|
42949
|
+
mode: d.mode,
|
|
42950
|
+
error: d.error
|
|
42951
|
+
});
|
|
42952
|
+
});
|
|
42953
|
+
lifecycleBus.on("bus.handler.async.enqueued", (d) => {
|
|
42954
|
+
writeLine2({
|
|
42955
|
+
ts: new Date().toISOString(),
|
|
42956
|
+
lifecycle: "bus.handler.async.enqueued",
|
|
42957
|
+
event: d.event,
|
|
42958
|
+
jobId: d.jobId,
|
|
42959
|
+
handlerCount: d.handlerCount
|
|
42960
|
+
});
|
|
42961
|
+
});
|
|
42962
|
+
}
|
|
42963
|
+
var init_file_observer = __esm(() => {
|
|
42964
|
+
init_logger3();
|
|
42965
|
+
});
|
|
42966
|
+
|
|
42967
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/scheduler/node.js
|
|
42421
42968
|
function parseInterval(cron) {
|
|
42422
42969
|
const trimmed = cron.trim();
|
|
42423
42970
|
const num = Number(trimmed);
|
|
@@ -42491,7 +43038,7 @@ var init_node3 = __esm(() => {
|
|
|
42491
43038
|
init_metrics();
|
|
42492
43039
|
});
|
|
42493
43040
|
|
|
42494
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
43041
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/scheduler-node.js
|
|
42495
43042
|
var exports_scheduler_node = {};
|
|
42496
43043
|
__export(exports_scheduler_node, {
|
|
42497
43044
|
NodeSchedulerAdapter: () => NodeSchedulerAdapter
|
|
@@ -45425,10 +45972,10 @@ var require_default_service_name = __commonJS((exports) => {
|
|
|
45425
45972
|
var require_utils5 = __commonJS((exports) => {
|
|
45426
45973
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45427
45974
|
exports.isPromiseLike = undefined;
|
|
45428
|
-
var
|
|
45975
|
+
var isPromiseLike3 = (val) => {
|
|
45429
45976
|
return val !== null && typeof val === "object" && typeof val.then === "function";
|
|
45430
45977
|
};
|
|
45431
|
-
exports.isPromiseLike =
|
|
45978
|
+
exports.isPromiseLike = isPromiseLike3;
|
|
45432
45979
|
});
|
|
45433
45980
|
|
|
45434
45981
|
// ../../node_modules/.bun/@opentelemetry+resources@2.7.1+e40b0dfdd726a224/node_modules/@opentelemetry/resources/build/src/ResourceImpl.js
|
|
@@ -48747,7 +49294,12 @@ var init_errors5 = __esm(() => {
|
|
|
48747
49294
|
};
|
|
48748
49295
|
});
|
|
48749
49296
|
|
|
48750
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
49297
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/event-bus/index.js
|
|
49298
|
+
var init_event_bus2 = __esm(() => {
|
|
49299
|
+
init_event_bus();
|
|
49300
|
+
});
|
|
49301
|
+
|
|
49302
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/api-client.js
|
|
48751
49303
|
function sanitizeUrlForObservability(url2) {
|
|
48752
49304
|
try {
|
|
48753
49305
|
const parsed = new URL(url2);
|
|
@@ -48809,7 +49361,7 @@ class APIClient {
|
|
|
48809
49361
|
this.defaultHeaders = config4.defaultHeaders ?? {};
|
|
48810
49362
|
this.timeout = config4.timeout ?? 30000;
|
|
48811
49363
|
this.fetchFn = config4.fetch ?? globalThis.fetch;
|
|
48812
|
-
this.events = config4.events;
|
|
49364
|
+
this.events = config4.events ?? (config4.lifecycleBus ? new EventBus({ lifecycleBus: config4.lifecycleBus }) : undefined);
|
|
48813
49365
|
}
|
|
48814
49366
|
buildUrl(path9) {
|
|
48815
49367
|
return `${this.baseUrl}${path9.startsWith("/") ? path9 : `/${path9}`}`;
|
|
@@ -48960,6 +49512,7 @@ class APIClient {
|
|
|
48960
49512
|
}
|
|
48961
49513
|
var import_api15, import_semantic_conventions2, APIError;
|
|
48962
49514
|
var init_api_client = __esm(() => {
|
|
49515
|
+
init_event_bus2();
|
|
48963
49516
|
init_metrics();
|
|
48964
49517
|
init_tracing2();
|
|
48965
49518
|
import_api15 = __toESM(require_src(), 1);
|
|
@@ -48976,17 +49529,12 @@ var init_api_client = __esm(() => {
|
|
|
48976
49529
|
};
|
|
48977
49530
|
});
|
|
48978
49531
|
|
|
48979
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
48980
|
-
var init_event_bus2 = __esm(() => {
|
|
48981
|
-
init_event_bus();
|
|
48982
|
-
});
|
|
48983
|
-
|
|
48984
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.8+e2482bee662d08ad/node_modules/@gobing-ai/ts-infra/dist/telemetry/index.js
|
|
49532
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/telemetry/index.js
|
|
48985
49533
|
var init_telemetry = __esm(() => {
|
|
48986
49534
|
init_tracing2();
|
|
48987
49535
|
});
|
|
48988
49536
|
|
|
48989
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
49537
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/index.js
|
|
48990
49538
|
var init_dist6 = __esm(() => {
|
|
48991
49539
|
init_api_client();
|
|
48992
49540
|
init_event_bus2();
|
|
@@ -48994,7 +49542,7 @@ var init_dist6 = __esm(() => {
|
|
|
48994
49542
|
init_telemetry();
|
|
48995
49543
|
});
|
|
48996
49544
|
|
|
48997
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
49545
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.10+443204d2f30aef7a/node_modules/@gobing-ai/ts-ai-runner/dist/agents/shims.js
|
|
48998
49546
|
function resolveAgentName(input) {
|
|
48999
49547
|
if (isCanonicalName(input))
|
|
49000
49548
|
return input;
|
|
@@ -49245,7 +49793,7 @@ var init_shims = __esm(() => {
|
|
|
49245
49793
|
ALIAS_TO_CANONICAL = Object.fromEntries(Object.values(AGENT_SHIMS).flatMap((shim) => (shim.aliases ?? []).map((alias3) => [alias3, shim.name])));
|
|
49246
49794
|
});
|
|
49247
49795
|
|
|
49248
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
49796
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.10+443204d2f30aef7a/node_modules/@gobing-ai/ts-ai-runner/dist/identity.js
|
|
49249
49797
|
function buildIdentityPreamble(ctx) {
|
|
49250
49798
|
const sections = [
|
|
49251
49799
|
`You are agent \`${ctx.agentId}\` (${ctx.agentType}) in workspace \`${ctx.workspace}\`.`
|
|
@@ -49305,7 +49853,7 @@ var init_identity = __esm(() => {
|
|
|
49305
49853
|
init_dist5();
|
|
49306
49854
|
});
|
|
49307
49855
|
|
|
49308
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
49856
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.10+443204d2f30aef7a/node_modules/@gobing-ai/ts-ai-runner/dist/slash-command.js
|
|
49309
49857
|
function isClaudeStyleSlashCommand(input) {
|
|
49310
49858
|
return SLASH_COMMAND_RE.test(input);
|
|
49311
49859
|
}
|
|
@@ -49333,19 +49881,22 @@ var init_slash_command = __esm(() => {
|
|
|
49333
49881
|
SLASH_COMMAND_RE = /^\/([a-zA-Z0-9._-]+):([a-zA-Z0-9._-]+)(\s.*)?$/;
|
|
49334
49882
|
});
|
|
49335
49883
|
|
|
49336
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
49884
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.10+443204d2f30aef7a/node_modules/@gobing-ai/ts-ai-runner/dist/ai-runner.js
|
|
49337
49885
|
class AiRunner {
|
|
49338
49886
|
processExecutor;
|
|
49339
49887
|
defaultCwd;
|
|
49340
49888
|
defaultTimeout;
|
|
49341
49889
|
logger;
|
|
49342
49890
|
events;
|
|
49891
|
+
processEvents;
|
|
49343
49892
|
constructor(options = {}) {
|
|
49344
|
-
|
|
49345
|
-
|
|
49893
|
+
const processEvents = options.processEvents ?? (options.lifecycleBus ? new EventBus({ lifecycleBus: options.lifecycleBus }) : undefined);
|
|
49894
|
+
const events = options.events ?? (options.lifecycleBus ? new EventBus({ lifecycleBus: options.lifecycleBus }) : undefined);
|
|
49895
|
+
this.processExecutor = options.processExecutor ?? nodeBunFactory3.createProcessExecutor({
|
|
49896
|
+
...processEvents !== undefined ? {
|
|
49346
49897
|
events: {
|
|
49347
49898
|
emit: (event, detail) => {
|
|
49348
|
-
|
|
49899
|
+
processEvents?.emit(event, detail);
|
|
49349
49900
|
}
|
|
49350
49901
|
}
|
|
49351
49902
|
} : {},
|
|
@@ -49356,7 +49907,8 @@ class AiRunner {
|
|
|
49356
49907
|
this.defaultCwd = options.defaultCwd;
|
|
49357
49908
|
this.defaultTimeout = options.defaultTimeout;
|
|
49358
49909
|
this.logger = options.logger ?? getLogger2("ai-runner");
|
|
49359
|
-
this.events =
|
|
49910
|
+
this.events = events;
|
|
49911
|
+
this.processEvents = processEvents;
|
|
49360
49912
|
}
|
|
49361
49913
|
runHelpCommand(agent, options = {}) {
|
|
49362
49914
|
return this.invoke(agent, "help", getAgentShim(agent).getHelpCommand(), options, true);
|
|
@@ -49447,7 +49999,7 @@ var init_ai_runner = __esm(() => {
|
|
|
49447
49999
|
init_slash_command();
|
|
49448
50000
|
});
|
|
49449
50001
|
|
|
49450
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
50002
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.10+443204d2f30aef7a/node_modules/@gobing-ai/ts-ai-runner/dist/agent-detector.js
|
|
49451
50003
|
class AgentDetector {
|
|
49452
50004
|
runner;
|
|
49453
50005
|
timeout;
|
|
@@ -49523,7 +50075,7 @@ var init_agent_detector = __esm(() => {
|
|
|
49523
50075
|
VERSION_PATTERN = /(?<version>\d+\.\d+(?:\.\d+)?)/;
|
|
49524
50076
|
});
|
|
49525
50077
|
|
|
49526
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
50078
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.10+443204d2f30aef7a/node_modules/@gobing-ai/ts-ai-runner/dist/agent-spec.js
|
|
49527
50079
|
function validateAgentId(id) {
|
|
49528
50080
|
if (!/^[a-z][a-z0-9_-]{1,63}$/.test(id)) {
|
|
49529
50081
|
throw new ValueError(`Invalid agent id "${id}": expected 2-64 chars, lowercase alphanumeric, "_" or "-"`);
|
|
@@ -49620,12 +50172,12 @@ var init_agent_spec = __esm(() => {
|
|
|
49620
50172
|
};
|
|
49621
50173
|
});
|
|
49622
50174
|
|
|
49623
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
50175
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.10+443204d2f30aef7a/node_modules/@gobing-ai/ts-ai-runner/dist/agents/auth-shims.js
|
|
49624
50176
|
function isNonEmpty(value) {
|
|
49625
50177
|
return value !== undefined && value.trim().length > 0;
|
|
49626
50178
|
}
|
|
49627
50179
|
async function isAuthenticated(agent, ctx) {
|
|
49628
|
-
const env = ctx.env ??
|
|
50180
|
+
const env = ctx.env ?? getProcessEnv2();
|
|
49629
50181
|
const fs3 = ctx.fileSystem;
|
|
49630
50182
|
const timeout = ctx.timeout ?? DEFAULT_AUTH_TIMEOUT_MS;
|
|
49631
50183
|
const home = env.HOME || env.USERPROFILE || "";
|
|
@@ -49725,7 +50277,7 @@ var init_auth_shims = __esm(() => {
|
|
|
49725
50277
|
};
|
|
49726
50278
|
});
|
|
49727
50279
|
|
|
49728
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
50280
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.10+443204d2f30aef7a/node_modules/@gobing-ai/ts-ai-runner/dist/model-health-probe.js
|
|
49729
50281
|
class ModelHealthProbeRegistry {
|
|
49730
50282
|
probes = new Map;
|
|
49731
50283
|
register(providerPrefix, probe) {
|
|
@@ -49833,7 +50385,7 @@ var init_model_health_probe = __esm(() => {
|
|
|
49833
50385
|
};
|
|
49834
50386
|
});
|
|
49835
50387
|
|
|
49836
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
50388
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.10+443204d2f30aef7a/node_modules/@gobing-ai/ts-ai-runner/dist/doctor-runner.js
|
|
49837
50389
|
class DoctorRunner {
|
|
49838
50390
|
detector;
|
|
49839
50391
|
runner;
|
|
@@ -49848,7 +50400,7 @@ class DoctorRunner {
|
|
|
49848
50400
|
this.runner = options.runner ?? new AiRunner;
|
|
49849
50401
|
this.detector = options.agentDetector ?? new AgentDetector({ runner: this.runner });
|
|
49850
50402
|
this.timeout = options.timeout ?? DEFAULT_TIMEOUT_MS2;
|
|
49851
|
-
this.env = options.env ??
|
|
50403
|
+
this.env = options.env ?? getProcessEnv2();
|
|
49852
50404
|
this.fs = options.fileSystem ?? createNodeFileSystem3();
|
|
49853
50405
|
this.logger = options.logger ?? getLogger2("doctor");
|
|
49854
50406
|
this.executors = options.executors ?? [];
|
|
@@ -49970,15 +50522,15 @@ var init_doctor_runner = __esm(() => {
|
|
|
49970
50522
|
init_model_health_probe();
|
|
49971
50523
|
});
|
|
49972
50524
|
|
|
49973
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
50525
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.10+443204d2f30aef7a/node_modules/@gobing-ai/ts-ai-runner/dist/events.js
|
|
49974
50526
|
var init_events = () => {};
|
|
49975
50527
|
|
|
49976
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
50528
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.10+443204d2f30aef7a/node_modules/@gobing-ai/ts-ai-runner/dist/messages.js
|
|
49977
50529
|
function formatMessage(msg) {
|
|
49978
50530
|
return `[task from=${msg.fromId ?? "operator"} id=${msg.id}] ${msg.body}`;
|
|
49979
50531
|
}
|
|
49980
50532
|
|
|
49981
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
50533
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.10+443204d2f30aef7a/node_modules/@gobing-ai/ts-ai-runner/dist/team-agent-process.js
|
|
49982
50534
|
import { Buffer as Buffer5 } from "buffer";
|
|
49983
50535
|
|
|
49984
50536
|
class TeamAgentProcess {
|
|
@@ -49997,7 +50549,7 @@ class TeamAgentProcess {
|
|
|
49997
50549
|
this.command = options.command;
|
|
49998
50550
|
this.env = options.env;
|
|
49999
50551
|
this.cwd = options.cwd ?? options.spec.workspace;
|
|
50000
|
-
this.processExecutor = options.processExecutor ??
|
|
50552
|
+
this.processExecutor = options.processExecutor ?? nodeBunFactory3.createProcessExecutor();
|
|
50001
50553
|
this.logger = options.logger ?? getLogger2("team-agent");
|
|
50002
50554
|
}
|
|
50003
50555
|
async start() {
|
|
@@ -50112,7 +50664,7 @@ var init_team_agent_process = __esm(() => {
|
|
|
50112
50664
|
init_dist5();
|
|
50113
50665
|
});
|
|
50114
50666
|
|
|
50115
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
50667
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.10+443204d2f30aef7a/node_modules/@gobing-ai/ts-ai-runner/dist/team-orchestrator.js
|
|
50116
50668
|
class TeamOrchestrator {
|
|
50117
50669
|
configDir;
|
|
50118
50670
|
inbox;
|
|
@@ -50124,7 +50676,7 @@ class TeamOrchestrator {
|
|
|
50124
50676
|
this.configDir = configDir;
|
|
50125
50677
|
this.inbox = inbox;
|
|
50126
50678
|
this.processFactory = options.processFactory ?? ((processOptions) => new TeamAgentProcess(processOptions));
|
|
50127
|
-
this.events = options.events ?? new EventBus;
|
|
50679
|
+
this.events = options.events ?? (options.lifecycleBus ? new EventBus({ lifecycleBus: options.lifecycleBus }) : new EventBus);
|
|
50128
50680
|
}
|
|
50129
50681
|
async loadSpecs() {
|
|
50130
50682
|
this.specs = await loadAgentSpecs(this.configDir);
|
|
@@ -50241,7 +50793,7 @@ var init_team_orchestrator = __esm(() => {
|
|
|
50241
50793
|
init_team_agent_process();
|
|
50242
50794
|
});
|
|
50243
50795
|
|
|
50244
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
50796
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.10+443204d2f30aef7a/node_modules/@gobing-ai/ts-ai-runner/dist/index.js
|
|
50245
50797
|
var exports_dist3 = {};
|
|
50246
50798
|
__export(exports_dist3, {
|
|
50247
50799
|
validateAgentId: () => validateAgentId,
|
|
@@ -50310,7 +50862,12 @@ class AgentService {
|
|
|
50310
50862
|
}
|
|
50311
50863
|
async resolve(flags, deps) {
|
|
50312
50864
|
const outputPolicy = { mode: "buffered" };
|
|
50313
|
-
const runner = deps?.runner ?? new AiRunner({
|
|
50865
|
+
const runner = deps?.runner ?? new AiRunner({
|
|
50866
|
+
processExecutor: new NodeProcessExecutor3({
|
|
50867
|
+
output: outputPolicy,
|
|
50868
|
+
...this.ctx.processRegistry !== undefined ? { registry: this.ctx.processRegistry } : {}
|
|
50869
|
+
})
|
|
50870
|
+
});
|
|
50314
50871
|
const detector = deps?.detector ?? new AgentDetector({ runner });
|
|
50315
50872
|
const doctorRunner = deps?.doctorRunner ?? new DoctorRunner({ agentDetector: detector, runner, env: this.ctx.env });
|
|
50316
50873
|
return this.resolveAgent(undefined, flags, doctorRunner);
|
|
@@ -50405,7 +50962,10 @@ class AgentService {
|
|
|
50405
50962
|
const jsonOutput = silent || booleanFlag(flags, "json");
|
|
50406
50963
|
const outputPolicy = jsonOutput ? { mode: "buffered" } : { mode: "stream", isTTY: isatty3(1) };
|
|
50407
50964
|
const runner = deps?.runner ?? new AiRunner({
|
|
50408
|
-
processExecutor: new
|
|
50965
|
+
processExecutor: new NodeProcessExecutor3({
|
|
50966
|
+
output: outputPolicy,
|
|
50967
|
+
...this.ctx.processRegistry !== undefined ? { registry: this.ctx.processRegistry } : {}
|
|
50968
|
+
}),
|
|
50409
50969
|
...this.ctx.events !== undefined ? { events: bridgeEventBus(this.ctx.events) } : {},
|
|
50410
50970
|
...this.ctx.events !== undefined ? { processEvents: bridgeEventBus(this.ctx.events) } : {}
|
|
50411
50971
|
});
|
|
@@ -51156,7 +51716,10 @@ function tryParseFeature(content) {
|
|
|
51156
51716
|
if (!content.includes("Feature:") && !content.includes("Scenario:")) {
|
|
51157
51717
|
return null;
|
|
51158
51718
|
}
|
|
51159
|
-
|
|
51719
|
+
const toParse = content.includes("Feature:") || !content.includes("Scenario:") ? content : `Feature: __coverage_wrapper__
|
|
51720
|
+
|
|
51721
|
+
${content}`;
|
|
51722
|
+
return parseFeature(toParse);
|
|
51160
51723
|
}
|
|
51161
51724
|
var init_coverage = () => {};
|
|
51162
51725
|
|
|
@@ -51698,7 +52261,7 @@ var init_drizzle_zod = __esm(() => {
|
|
|
51698
52261
|
};
|
|
51699
52262
|
});
|
|
51700
52263
|
|
|
51701
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
52264
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/schema/drizzle-internals.js
|
|
51702
52265
|
function sqlExpressionToText(value) {
|
|
51703
52266
|
if (typeof value !== "object" || value === null || !("queryChunks" in value)) {
|
|
51704
52267
|
return;
|
|
@@ -51721,7 +52284,7 @@ function getDrizzleTableName(table3) {
|
|
|
51721
52284
|
return String(table3[nameSym]);
|
|
51722
52285
|
}
|
|
51723
52286
|
|
|
51724
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
52287
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/schema/ddl.js
|
|
51725
52288
|
function quoteIdent(name) {
|
|
51726
52289
|
return `"${name.replace(/"/g, '""')}"`;
|
|
51727
52290
|
}
|
|
@@ -51815,7 +52378,7 @@ var init_ddl = __esm(() => {
|
|
|
51815
52378
|
init_sqlite_core();
|
|
51816
52379
|
});
|
|
51817
52380
|
|
|
51818
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
52381
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/schema/define-table.js
|
|
51819
52382
|
function defineTable(name, columns2) {
|
|
51820
52383
|
const table3 = sqliteTable(name, columns2);
|
|
51821
52384
|
let insert2;
|
|
@@ -51849,7 +52412,7 @@ var init_define_table = __esm(() => {
|
|
|
51849
52412
|
init_ddl();
|
|
51850
52413
|
});
|
|
51851
52414
|
|
|
51852
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
52415
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.10+86b80a818ad2648a/node_modules/@gobing-ai/ts-db/dist/schema/index.js
|
|
51853
52416
|
var init_schema = __esm(() => {
|
|
51854
52417
|
init_sqlite_core();
|
|
51855
52418
|
init_define_table();
|
|
@@ -52404,7 +52967,7 @@ var init_dao = __esm(() => {
|
|
|
52404
52967
|
init_workspace_dao();
|
|
52405
52968
|
});
|
|
52406
52969
|
|
|
52407
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
52970
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/errors.js
|
|
52408
52971
|
var WorkflowValidationError, FSMError, RunCollisionError, WorkflowResumeError;
|
|
52409
52972
|
var init_errors6 = __esm(() => {
|
|
52410
52973
|
WorkflowValidationError = class WorkflowValidationError extends Error {
|
|
@@ -52439,7 +53002,7 @@ var init_errors6 = __esm(() => {
|
|
|
52439
53002
|
};
|
|
52440
53003
|
});
|
|
52441
53004
|
|
|
52442
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53005
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/run-lifecycle.js
|
|
52443
53006
|
function runtimeBuiltins(workflowName, stateOrNodeId, runId, transitionsTaken, mode) {
|
|
52444
53007
|
return {
|
|
52445
53008
|
workflow: workflowName,
|
|
@@ -52452,7 +53015,7 @@ function runtimeBuiltins(workflowName, stateOrNodeId, runId, transitionsTaken, m
|
|
|
52452
53015
|
runtime: mode
|
|
52453
53016
|
};
|
|
52454
53017
|
}
|
|
52455
|
-
function allowedEnv(names, source =
|
|
53018
|
+
function allowedEnv(names, source = getProcessEnv2()) {
|
|
52456
53019
|
return Object.fromEntries(names.flatMap((name) => source[name] === undefined ? [] : [[name, source[name]]]));
|
|
52457
53020
|
}
|
|
52458
53021
|
|
|
@@ -52470,7 +53033,7 @@ class RunLifecycle {
|
|
|
52470
53033
|
this.runId = runId;
|
|
52471
53034
|
this.externalKey = externalKey;
|
|
52472
53035
|
this.persistence = deps.persistence;
|
|
52473
|
-
this.events = deps.events;
|
|
53036
|
+
this.events = deps.events ?? (deps.lifecycleBus ? new EventBus({ lifecycleBus: deps.lifecycleBus }) : undefined);
|
|
52474
53037
|
this.logger = (deps.logger ?? getLogger2("workflow")).child({ runId, workflow: workflowName, mode });
|
|
52475
53038
|
}
|
|
52476
53039
|
static forExternalTransition(workflowName, runId, deps, externalKey) {
|
|
@@ -52688,7 +53251,7 @@ var init_run_lifecycle = __esm(() => {
|
|
|
52688
53251
|
];
|
|
52689
53252
|
});
|
|
52690
53253
|
|
|
52691
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53254
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/schema.js
|
|
52692
53255
|
var RESERVED_VAR_NAMES, IDENTIFIER, VarsSchema, EnvSchema, ActionDefSchema, GuardDefSchema, StateMachineWorkflowDefSchema, TransitionFlowWorkflowDefSchema, WorkflowDefSchema;
|
|
52693
53256
|
var init_schema2 = __esm(() => {
|
|
52694
53257
|
init_zod();
|
|
@@ -52772,7 +53335,7 @@ var init_schema2 = __esm(() => {
|
|
|
52772
53335
|
WorkflowDefSchema = exports_external.union([StateMachineWorkflowDefSchema, TransitionFlowWorkflowDefSchema]);
|
|
52773
53336
|
});
|
|
52774
53337
|
|
|
52775
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53338
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/config.js
|
|
52776
53339
|
async function loadWorkflowDef(path9, options = {}) {
|
|
52777
53340
|
return parseWorkflowDef(await loadStructuredConfig(path9, options), path9);
|
|
52778
53341
|
}
|
|
@@ -52931,7 +53494,7 @@ var init_config4 = __esm(() => {
|
|
|
52931
53494
|
RUNTIME_TEMPLATE_NAMESPACES = new Set(RUNTIME_BUILTIN_KEYS);
|
|
52932
53495
|
});
|
|
52933
53496
|
|
|
52934
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
53497
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/extension/capability-registry.js
|
|
52935
53498
|
class CapabilityRegistry {
|
|
52936
53499
|
kind;
|
|
52937
53500
|
capabilities = new Map;
|
|
@@ -52962,7 +53525,7 @@ class CapabilityRegistry {
|
|
|
52962
53525
|
}
|
|
52963
53526
|
}
|
|
52964
53527
|
|
|
52965
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
53528
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-path.js
|
|
52966
53529
|
function assertRelativeExtensionPath(path9, options = {}) {
|
|
52967
53530
|
const where = options.sourceName !== undefined ? ` declared by "${options.sourceName}"` : "";
|
|
52968
53531
|
if (/^([/\\]|[A-Za-z]:[/\\])/.test(path9)) {
|
|
@@ -52973,23 +53536,27 @@ function assertRelativeExtensionPath(path9, options = {}) {
|
|
|
52973
53536
|
}
|
|
52974
53537
|
}
|
|
52975
53538
|
|
|
52976
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
53539
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-loader.js
|
|
52977
53540
|
var init_extension_loader = () => {};
|
|
52978
53541
|
|
|
52979
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
53542
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/extension/index.js
|
|
52980
53543
|
var init_extension = __esm(() => {
|
|
52981
53544
|
init_extension_loader();
|
|
52982
53545
|
});
|
|
52983
53546
|
|
|
52984
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
53547
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.10+f5990ac4de041c52/node_modules/@gobing-ai/ts-runtime/dist/extension.js
|
|
52985
53548
|
var init_extension2 = __esm(() => {
|
|
52986
53549
|
init_extension();
|
|
52987
53550
|
});
|
|
52988
53551
|
|
|
52989
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53552
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/host.js
|
|
52990
53553
|
class WorkflowEngineHost {
|
|
53554
|
+
lifecycleBus;
|
|
52991
53555
|
actions = new CapabilityRegistry("workflow action");
|
|
52992
53556
|
guards = new CapabilityRegistry("workflow guard");
|
|
53557
|
+
constructor(lifecycleBus) {
|
|
53558
|
+
this.lifecycleBus = lifecycleBus;
|
|
53559
|
+
}
|
|
52993
53560
|
registerAction(action, origin2 = "extension") {
|
|
52994
53561
|
this.actions.register(action.kind, action, origin2);
|
|
52995
53562
|
return this;
|
|
@@ -53032,11 +53599,11 @@ class WorkflowEngineHost {
|
|
|
53032
53599
|
}
|
|
53033
53600
|
}
|
|
53034
53601
|
function createDefaultWorkflowEngineHost(options = {}) {
|
|
53035
|
-
const host = new WorkflowEngineHost;
|
|
53602
|
+
const host = new WorkflowEngineHost(options.lifecycleBus);
|
|
53036
53603
|
host.registerAction(new NoteActionRunner, "builtin");
|
|
53037
|
-
host.registerAction(new ShellActionRunner(options.processExecutor ??
|
|
53604
|
+
host.registerAction(new ShellActionRunner(options.processExecutor ?? nodeBunFactory3.createProcessExecutor()), "builtin");
|
|
53038
53605
|
host.registerAction(new EventEmitActionRunner, "builtin");
|
|
53039
|
-
host.registerGuard(new ShellGuardRunner(options.processExecutor ??
|
|
53606
|
+
host.registerGuard(new ShellGuardRunner(options.processExecutor ?? nodeBunFactory3.createProcessExecutor()), "builtin");
|
|
53040
53607
|
host.registerGuard({ kind: "always", evaluate: async () => true }, "builtin");
|
|
53041
53608
|
host.registerGuard({ kind: "never", evaluate: async () => false }, "builtin");
|
|
53042
53609
|
host.registerGuard({
|
|
@@ -53151,7 +53718,7 @@ var init_host = __esm(() => {
|
|
|
53151
53718
|
init_errors6();
|
|
53152
53719
|
});
|
|
53153
53720
|
|
|
53154
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53721
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/schema-sql.js
|
|
53155
53722
|
var WORKFLOW_ENGINE_SCHEMA_SQL;
|
|
53156
53723
|
var init_schema_sql = __esm(() => {
|
|
53157
53724
|
WORKFLOW_ENGINE_SCHEMA_SQL = `
|
|
@@ -53224,7 +53791,7 @@ CREATE TABLE IF NOT EXISTS action_runs (
|
|
|
53224
53791
|
`.trim();
|
|
53225
53792
|
});
|
|
53226
53793
|
|
|
53227
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53794
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/persistence.js
|
|
53228
53795
|
async function applyWorkflowEngineSchema(db2) {
|
|
53229
53796
|
for (const statement of WORKFLOW_ENGINE_SCHEMA_SQL.split(";")) {
|
|
53230
53797
|
const sql4 = statement.trim();
|
|
@@ -53492,7 +54059,7 @@ var init_persistence = __esm(() => {
|
|
|
53492
54059
|
init_schema_sql();
|
|
53493
54060
|
});
|
|
53494
54061
|
|
|
53495
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
54062
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/variables.js
|
|
53496
54063
|
function mergeVars(workflowVars = {}, overrideVars = {}) {
|
|
53497
54064
|
return { ...workflowVars, ...overrideVars };
|
|
53498
54065
|
}
|
|
@@ -53552,7 +54119,7 @@ var init_variables = __esm(() => {
|
|
|
53552
54119
|
TEMPLATE_REF = /\$\{([^}]+)\}/g;
|
|
53553
54120
|
});
|
|
53554
54121
|
|
|
53555
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
54122
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/action-step.js
|
|
53556
54123
|
async function runActionStep(action, vars, deps) {
|
|
53557
54124
|
const { host, persistence, lifecycle, stateOrNodeId, runId } = deps;
|
|
53558
54125
|
const resolved = resolveTemplates(action.options ?? {}, {
|
|
@@ -53609,7 +54176,7 @@ var init_action_step = __esm(() => {
|
|
|
53609
54176
|
init_variables();
|
|
53610
54177
|
});
|
|
53611
54178
|
|
|
53612
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
54179
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/state-machine.js
|
|
53613
54180
|
class StateMachineDriver {
|
|
53614
54181
|
options;
|
|
53615
54182
|
constructor(options) {
|
|
@@ -53743,7 +54310,7 @@ var init_state_machine = __esm(() => {
|
|
|
53743
54310
|
EMPTY_OUTCOME = { outcome: "completed", result: undefined };
|
|
53744
54311
|
});
|
|
53745
54312
|
|
|
53746
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
54313
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/transition-flow.js
|
|
53747
54314
|
class TransitionFlowDriver {
|
|
53748
54315
|
options;
|
|
53749
54316
|
constructor(options) {
|
|
@@ -53861,23 +54428,35 @@ var init_transition_flow = __esm(() => {
|
|
|
53861
54428
|
init_variables();
|
|
53862
54429
|
});
|
|
53863
54430
|
|
|
53864
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
54431
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/service.js
|
|
53865
54432
|
class WorkflowService {
|
|
53866
54433
|
host;
|
|
53867
54434
|
persistence;
|
|
53868
54435
|
runLocks = new Map;
|
|
53869
|
-
|
|
54436
|
+
lifecycleBus;
|
|
54437
|
+
constructor(host, persistence, lifecycleBus) {
|
|
53870
54438
|
this.host = host;
|
|
53871
54439
|
this.persistence = persistence;
|
|
54440
|
+
this.lifecycleBus = lifecycleBus ?? host.lifecycleBus;
|
|
54441
|
+
}
|
|
54442
|
+
resolveEvents(events2) {
|
|
54443
|
+
return events2 ?? (this.lifecycleBus ? new EventBus({ lifecycleBus: this.lifecycleBus }) : undefined);
|
|
53872
54444
|
}
|
|
53873
54445
|
async load(path9) {
|
|
53874
54446
|
return await loadWorkflowDef(path9);
|
|
53875
54447
|
}
|
|
53876
54448
|
async run(workflow, options = {}) {
|
|
54449
|
+
const events2 = this.resolveEvents(options.events);
|
|
53877
54450
|
if (workflow.kind === "transition-flow") {
|
|
53878
|
-
return await new TransitionFlowDriver({ host: this.host, persistence: this.persistence }).run(workflow,
|
|
54451
|
+
return await new TransitionFlowDriver({ host: this.host, persistence: this.persistence }).run(workflow, {
|
|
54452
|
+
...options,
|
|
54453
|
+
events: events2
|
|
54454
|
+
});
|
|
53879
54455
|
}
|
|
53880
|
-
return await new StateMachineDriver({ host: this.host, persistence: this.persistence }).run(workflow,
|
|
54456
|
+
return await new StateMachineDriver({ host: this.host, persistence: this.persistence }).run(workflow, {
|
|
54457
|
+
...options,
|
|
54458
|
+
events: events2
|
|
54459
|
+
});
|
|
53881
54460
|
}
|
|
53882
54461
|
async runFile(path9, options = {}) {
|
|
53883
54462
|
return await this.run(await this.load(path9), options);
|
|
@@ -53920,7 +54499,7 @@ class WorkflowService {
|
|
|
53920
54499
|
const run = await this.persistence.loadRun(runId);
|
|
53921
54500
|
const extKey = run?.external_key ?? undefined;
|
|
53922
54501
|
const result = await this.persistence.reseedRun(runId, newState);
|
|
53923
|
-
options?.events?.emit("workflow.run.reseeded", {
|
|
54502
|
+
this.resolveEvents(options?.events)?.emit("workflow.run.reseeded", {
|
|
53924
54503
|
runId,
|
|
53925
54504
|
fromState: result.fromState ?? "",
|
|
53926
54505
|
toState: result.toState,
|
|
@@ -53941,17 +54520,18 @@ class WorkflowService {
|
|
|
53941
54520
|
}
|
|
53942
54521
|
const extKey = run.external_key ?? undefined;
|
|
53943
54522
|
await this.persistence.finalizeRun(runId, "running", "");
|
|
53944
|
-
options?.events
|
|
54523
|
+
const events2 = this.resolveEvents(options?.events);
|
|
54524
|
+
events2?.emit("workflow.run.resumed", { runId, node: currentState, externalKey: extKey });
|
|
53945
54525
|
if (workflow.kind === "transition-flow") {
|
|
53946
54526
|
return await new TransitionFlowDriver({
|
|
53947
54527
|
host: this.host,
|
|
53948
54528
|
persistence: this.persistence
|
|
53949
|
-
}).resume(workflow, runId, currentState, extKey, options);
|
|
54529
|
+
}).resume(workflow, runId, currentState, extKey, { ...options, events: events2 });
|
|
53950
54530
|
}
|
|
53951
54531
|
return await new StateMachineDriver({
|
|
53952
54532
|
host: this.host,
|
|
53953
54533
|
persistence: this.persistence
|
|
53954
|
-
}).resume(workflow, runId, currentState, extKey, options);
|
|
54534
|
+
}).resume(workflow, runId, currentState, extKey, { ...options, events: events2 });
|
|
53955
54535
|
}
|
|
53956
54536
|
async listPausedRuns(options) {
|
|
53957
54537
|
return await this.persistence.listPausedRuns(options);
|
|
@@ -53984,10 +54564,11 @@ class WorkflowService {
|
|
|
53984
54564
|
detail: `No state recorded for run "${runId}"`
|
|
53985
54565
|
};
|
|
53986
54566
|
}
|
|
53987
|
-
const
|
|
54567
|
+
const events2 = this.resolveEvents(options?.events);
|
|
54568
|
+
const lifecycle = RunLifecycle.forExternalTransition(workflow.name, runId, { persistence: this.persistence, events: events2 }, extKey);
|
|
53988
54569
|
const transition = workflow.transitions.find((t) => t.from === currentState && t.to === toState);
|
|
53989
54570
|
if (transition === undefined) {
|
|
53990
|
-
return this.denyTransition(
|
|
54571
|
+
return this.denyTransition(events2, runId, currentState, toState, extKey, {
|
|
53991
54572
|
reason: "no-such-transition",
|
|
53992
54573
|
detail: `No transition from "${currentState}" to "${toState}"`
|
|
53993
54574
|
});
|
|
@@ -54005,7 +54586,7 @@ class WorkflowService {
|
|
|
54005
54586
|
});
|
|
54006
54587
|
lifecycle.guardEvaluated(currentState, toState, transition.guard.kind, guardResult.passed);
|
|
54007
54588
|
if (!guardResult.passed) {
|
|
54008
|
-
return this.denyTransition(
|
|
54589
|
+
return this.denyTransition(events2, runId, currentState, toState, extKey, {
|
|
54009
54590
|
reason: "guard-failed",
|
|
54010
54591
|
detail: `Guard "${transition.guard.kind}" denied transition from "${currentState}" to "${toState}"`,
|
|
54011
54592
|
guardKind: transition.guard.kind,
|
|
@@ -54015,7 +54596,7 @@ class WorkflowService {
|
|
|
54015
54596
|
}
|
|
54016
54597
|
const trigger = transition.trigger ?? null;
|
|
54017
54598
|
await lifecycle.commitHop(currentState, toState, trigger, 0);
|
|
54018
|
-
|
|
54599
|
+
events2?.emit("workflow.transition.requested", {
|
|
54019
54600
|
runId,
|
|
54020
54601
|
from: currentState,
|
|
54021
54602
|
to: toState,
|
|
@@ -54024,8 +54605,8 @@ class WorkflowService {
|
|
|
54024
54605
|
});
|
|
54025
54606
|
return { allowed: true, fromState: currentState, toState };
|
|
54026
54607
|
}
|
|
54027
|
-
denyTransition(
|
|
54028
|
-
|
|
54608
|
+
denyTransition(events2, runId, from, to, externalKey, denial) {
|
|
54609
|
+
events2?.emit("workflow.transition.denied", {
|
|
54029
54610
|
runId,
|
|
54030
54611
|
from,
|
|
54031
54612
|
to,
|
|
@@ -54036,6 +54617,7 @@ class WorkflowService {
|
|
|
54036
54617
|
}
|
|
54037
54618
|
}
|
|
54038
54619
|
var init_service = __esm(() => {
|
|
54620
|
+
init_dist6();
|
|
54039
54621
|
init_config4();
|
|
54040
54622
|
init_errors6();
|
|
54041
54623
|
init_run_lifecycle();
|
|
@@ -54044,7 +54626,7 @@ var init_service = __esm(() => {
|
|
|
54044
54626
|
init_variables();
|
|
54045
54627
|
});
|
|
54046
54628
|
|
|
54047
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
54629
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/index.js
|
|
54048
54630
|
var init_dist8 = __esm(() => {
|
|
54049
54631
|
init_config4();
|
|
54050
54632
|
init_host();
|
|
@@ -54053,7 +54635,7 @@ var init_dist8 = __esm(() => {
|
|
|
54053
54635
|
init_service();
|
|
54054
54636
|
});
|
|
54055
54637
|
|
|
54056
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
54638
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.10+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/errors.js
|
|
54057
54639
|
var HistoryImportError;
|
|
54058
54640
|
var init_errors7 = __esm(() => {
|
|
54059
54641
|
HistoryImportError = class HistoryImportError extends Error {
|
|
@@ -54066,7 +54648,7 @@ var init_errors7 = __esm(() => {
|
|
|
54066
54648
|
};
|
|
54067
54649
|
});
|
|
54068
54650
|
|
|
54069
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
54651
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.10+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/hash.js
|
|
54070
54652
|
import { createHash } from "crypto";
|
|
54071
54653
|
function stableJson(value) {
|
|
54072
54654
|
if (Array.isArray(value)) {
|
|
@@ -54083,7 +54665,7 @@ function sha256(value) {
|
|
|
54083
54665
|
}
|
|
54084
54666
|
var init_hash = () => {};
|
|
54085
54667
|
|
|
54086
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
54668
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.10+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/redaction.js
|
|
54087
54669
|
function redactValue(value, rules = DEFAULT_REDACTION_RULES) {
|
|
54088
54670
|
if (typeof value === "string") {
|
|
54089
54671
|
return rules.reduce((current, rule) => current.replace(rule.pattern, rule.replacement), value);
|
|
@@ -54120,7 +54702,7 @@ var init_redaction = __esm(() => {
|
|
|
54120
54702
|
];
|
|
54121
54703
|
});
|
|
54122
54704
|
|
|
54123
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
54705
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.10+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/schema-sql.js
|
|
54124
54706
|
var HISTORY_IMPORT_SCHEMA_SQL;
|
|
54125
54707
|
var init_schema_sql2 = __esm(() => {
|
|
54126
54708
|
HISTORY_IMPORT_SCHEMA_SQL = `
|
|
@@ -54207,7 +54789,7 @@ CREATE TABLE IF NOT EXISTS history_etl_openclaw (
|
|
|
54207
54789
|
`.trim();
|
|
54208
54790
|
});
|
|
54209
54791
|
|
|
54210
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
54792
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.10+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/sources.js
|
|
54211
54793
|
function firstString(...values) {
|
|
54212
54794
|
for (const value of values) {
|
|
54213
54795
|
if (typeof value === "string" && value.length > 0)
|
|
@@ -54295,7 +54877,7 @@ var init_sources = __esm(() => {
|
|
|
54295
54877
|
};
|
|
54296
54878
|
});
|
|
54297
54879
|
|
|
54298
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
54880
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.10+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/importer.js
|
|
54299
54881
|
async function applyHistoryImportSchema(db2) {
|
|
54300
54882
|
for (const statement of HISTORY_IMPORT_SCHEMA_SQL.split(";")) {
|
|
54301
54883
|
const sql4 = statement.trim();
|
|
@@ -54532,13 +55114,13 @@ var init_importer = __esm(() => {
|
|
|
54532
55114
|
VALID_TABLE_NAME = /^history_etl_[a-z_]+$/;
|
|
54533
55115
|
});
|
|
54534
55116
|
|
|
54535
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
55117
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.10+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/index.js
|
|
54536
55118
|
var init_dist9 = __esm(() => {
|
|
54537
55119
|
init_importer();
|
|
54538
55120
|
init_schema_sql2();
|
|
54539
55121
|
});
|
|
54540
55122
|
|
|
54541
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
55123
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/config/extensions.js
|
|
54542
55124
|
function collectExtensions(sourceName, sourceDir, extensions) {
|
|
54543
55125
|
if (extensions === undefined)
|
|
54544
55126
|
return [];
|
|
@@ -54554,7 +55136,7 @@ var init_extensions = __esm(() => {
|
|
|
54554
55136
|
init_dist5();
|
|
54555
55137
|
});
|
|
54556
55138
|
|
|
54557
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
55139
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/types.js
|
|
54558
55140
|
function createFinding(rule, message, filePath, extras = {}) {
|
|
54559
55141
|
return {
|
|
54560
55142
|
ruleId: rule.id,
|
|
@@ -54625,7 +55207,7 @@ var init_types3 = __esm(() => {
|
|
|
54625
55207
|
});
|
|
54626
55208
|
});
|
|
54627
55209
|
|
|
54628
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
55210
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/config/loader.js
|
|
54629
55211
|
async function loadPreset(name, options) {
|
|
54630
55212
|
const merged = await buildMergedRoots(options.roots.map((root) => resolvePath4(root)), options.fileSystem);
|
|
54631
55213
|
const presetPath = findMergedPreset(merged, name);
|
|
@@ -54840,7 +55422,7 @@ var init_loader2 = __esm(() => {
|
|
|
54840
55422
|
FIX_MODE_AUTHORITY = { none: 0, suggest: 1, auto: 2 };
|
|
54841
55423
|
});
|
|
54842
55424
|
|
|
54843
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
55425
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/fixers/test-stub-fixer.js
|
|
54844
55426
|
function normalizeFindingPath(filePath) {
|
|
54845
55427
|
if (!filePath || isAbsolutePath2(filePath))
|
|
54846
55428
|
return null;
|
|
@@ -54905,7 +55487,7 @@ var init_test_stub_fixer = __esm(() => {
|
|
|
54905
55487
|
realFileSystem = createNodeFileSystem3();
|
|
54906
55488
|
});
|
|
54907
55489
|
|
|
54908
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
55490
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/fixers/fixers.js
|
|
54909
55491
|
function registerBuiltinFixers(host, exec) {
|
|
54910
55492
|
const regexFixer = new RegexFixerProvider;
|
|
54911
55493
|
const pathFixer = new PathFixerProvider;
|
|
@@ -55108,7 +55690,7 @@ var init_fixers = __esm(() => {
|
|
|
55108
55690
|
};
|
|
55109
55691
|
});
|
|
55110
55692
|
|
|
55111
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
55693
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/config-access.js
|
|
55112
55694
|
function stringArray(value) {
|
|
55113
55695
|
return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : undefined;
|
|
55114
55696
|
}
|
|
@@ -55146,7 +55728,7 @@ function parseInlineFlags(source) {
|
|
|
55146
55728
|
return { flags, rest: source.slice(match[0].length) };
|
|
55147
55729
|
}
|
|
55148
55730
|
|
|
55149
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
55731
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/glob-match.js
|
|
55150
55732
|
function matchesAny(path9, patterns) {
|
|
55151
55733
|
if (patterns === undefined || patterns.length === 0)
|
|
55152
55734
|
return true;
|
|
@@ -55194,7 +55776,7 @@ function escapeRegExp(value) {
|
|
|
55194
55776
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
55195
55777
|
}
|
|
55196
55778
|
|
|
55197
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
55779
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/file-discovery.js
|
|
55198
55780
|
async function discoverFiles2(options) {
|
|
55199
55781
|
const fs3 = options.fs ?? createNodeFileSystem3();
|
|
55200
55782
|
const allFiles = await walkDir2(options.workdir, fs3, DEFAULT_EXCLUDES);
|
|
@@ -55222,12 +55804,12 @@ var init_file_discovery = __esm(() => {
|
|
|
55222
55804
|
DEFAULT_EXCLUDES = new Set([".git", "node_modules", "dist", ".coverage", ".astro", ".wrangler"]);
|
|
55223
55805
|
});
|
|
55224
55806
|
|
|
55225
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
55807
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/file-utils.js
|
|
55226
55808
|
var init_file_utils = __esm(() => {
|
|
55227
55809
|
init_file_discovery();
|
|
55228
55810
|
});
|
|
55229
55811
|
|
|
55230
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
55812
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/agent-detection-evaluator.js
|
|
55231
55813
|
class AgentDetectionEvaluator {
|
|
55232
55814
|
detector;
|
|
55233
55815
|
constructor(detector = new AgentDetector) {
|
|
@@ -55255,7 +55837,7 @@ var init_agent_detection_evaluator = __esm(() => {
|
|
|
55255
55837
|
init_file_utils();
|
|
55256
55838
|
});
|
|
55257
55839
|
|
|
55258
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
55840
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/coverage-gate-evaluator.js
|
|
55259
55841
|
class CoverageGateEvaluator {
|
|
55260
55842
|
constructor() {}
|
|
55261
55843
|
async evaluate(rule, context4) {
|
|
@@ -55339,10 +55921,10 @@ var init_coverage_gate_evaluator = __esm(() => {
|
|
|
55339
55921
|
init_file_utils();
|
|
55340
55922
|
});
|
|
55341
55923
|
|
|
55342
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
55924
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/exit-code-evaluator.js
|
|
55343
55925
|
class ExitCodeEvaluator {
|
|
55344
55926
|
executor;
|
|
55345
|
-
constructor(executor =
|
|
55927
|
+
constructor(executor = nodeBunFactory3.createProcessExecutor()) {
|
|
55346
55928
|
this.executor = executor;
|
|
55347
55929
|
}
|
|
55348
55930
|
async evaluate(rule, context4) {
|
|
@@ -55375,7 +55957,7 @@ var init_exit_code_evaluator = __esm(() => {
|
|
|
55375
55957
|
init_file_utils();
|
|
55376
55958
|
});
|
|
55377
55959
|
|
|
55378
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
55960
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/forbidden-import-evaluator.js
|
|
55379
55961
|
class ForbiddenImportEvaluator {
|
|
55380
55962
|
constructor() {}
|
|
55381
55963
|
async evaluate(rule, context4) {
|
|
@@ -55456,7 +56038,7 @@ var init_forbidden_import_evaluator = __esm(() => {
|
|
|
55456
56038
|
init_file_utils();
|
|
55457
56039
|
});
|
|
55458
56040
|
|
|
55459
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56041
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/import-boundary-evaluator.js
|
|
55460
56042
|
class ImportBoundaryEvaluator {
|
|
55461
56043
|
async evaluate(rule, context4) {
|
|
55462
56044
|
const config4 = rule.evaluator.config ?? {};
|
|
@@ -55549,7 +56131,7 @@ var init_import_boundary_evaluator = __esm(() => {
|
|
|
55549
56131
|
init_file_utils();
|
|
55550
56132
|
});
|
|
55551
56133
|
|
|
55552
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56134
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/path-evaluator.js
|
|
55553
56135
|
class PathEvaluator {
|
|
55554
56136
|
constructor() {}
|
|
55555
56137
|
async evaluate(rule, context4) {
|
|
@@ -55610,7 +56192,7 @@ var init_path_evaluator = __esm(() => {
|
|
|
55610
56192
|
init_file_utils();
|
|
55611
56193
|
});
|
|
55612
56194
|
|
|
55613
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56195
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/regex-evaluator.js
|
|
55614
56196
|
class RegexEvaluator {
|
|
55615
56197
|
constructor() {}
|
|
55616
56198
|
async evaluate(rule, context4) {
|
|
@@ -55688,10 +56270,10 @@ var init_regex_evaluator = __esm(() => {
|
|
|
55688
56270
|
init_file_utils();
|
|
55689
56271
|
});
|
|
55690
56272
|
|
|
55691
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56273
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/ripgrep-evaluator.js
|
|
55692
56274
|
class RipgrepEvaluator {
|
|
55693
56275
|
executor;
|
|
55694
|
-
constructor(executor =
|
|
56276
|
+
constructor(executor = nodeBunFactory3.createProcessExecutor()) {
|
|
55695
56277
|
this.executor = executor;
|
|
55696
56278
|
}
|
|
55697
56279
|
async evaluate(rule, context4) {
|
|
@@ -55781,7 +56363,7 @@ var init_ripgrep_evaluator = __esm(() => {
|
|
|
55781
56363
|
init_file_utils();
|
|
55782
56364
|
});
|
|
55783
56365
|
|
|
55784
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56366
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/schema-artifact-evaluator.js
|
|
55785
56367
|
class SchemaArtifactEvaluator {
|
|
55786
56368
|
constructor() {}
|
|
55787
56369
|
async evaluate(rule, context4) {
|
|
@@ -55859,7 +56441,7 @@ var init_schema_artifact_evaluator = __esm(() => {
|
|
|
55859
56441
|
init_file_utils();
|
|
55860
56442
|
});
|
|
55861
56443
|
|
|
55862
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56444
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/secrets-scanner-evaluator.js
|
|
55863
56445
|
class SecretsScannerEvaluator {
|
|
55864
56446
|
constructor() {}
|
|
55865
56447
|
async evaluate(rule, context4) {
|
|
@@ -55927,10 +56509,10 @@ var init_secrets_scanner_evaluator = __esm(() => {
|
|
|
55927
56509
|
ALL_CATEGORIES = Object.keys(BUILTIN_PATTERNS);
|
|
55928
56510
|
});
|
|
55929
56511
|
|
|
55930
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56512
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/sg-evaluator.js
|
|
55931
56513
|
class SgEvaluator {
|
|
55932
56514
|
executor;
|
|
55933
|
-
constructor(executor =
|
|
56515
|
+
constructor(executor = nodeBunFactory3.createProcessExecutor()) {
|
|
55934
56516
|
this.executor = executor;
|
|
55935
56517
|
}
|
|
55936
56518
|
async evaluate(rule, context4) {
|
|
@@ -56024,7 +56606,7 @@ var init_sg_evaluator = __esm(() => {
|
|
|
56024
56606
|
init_file_utils();
|
|
56025
56607
|
});
|
|
56026
56608
|
|
|
56027
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56609
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/resolvers/test-path-resolver.js
|
|
56028
56610
|
class TypeScriptTestPathResolver {
|
|
56029
56611
|
name = "typescript";
|
|
56030
56612
|
constructor() {}
|
|
@@ -56107,7 +56689,7 @@ function testify(rel) {
|
|
|
56107
56689
|
return `${dir}test_${base2}`;
|
|
56108
56690
|
}
|
|
56109
56691
|
|
|
56110
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56692
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/test-location-evaluator.js
|
|
56111
56693
|
class TestLocationEvaluator {
|
|
56112
56694
|
resolvers;
|
|
56113
56695
|
constructor(resolvers) {
|
|
@@ -56182,7 +56764,7 @@ var init_test_location_evaluator = __esm(() => {
|
|
|
56182
56764
|
TYPESCRIPT_FALLBACK = new TypeScriptTestPathResolver;
|
|
56183
56765
|
});
|
|
56184
56766
|
|
|
56185
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56767
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/tsdoc-export-evaluator.js
|
|
56186
56768
|
class TsdocExportEvaluator {
|
|
56187
56769
|
constructor() {}
|
|
56188
56770
|
async evaluate(rule, context4) {
|
|
@@ -56267,7 +56849,7 @@ var init_tsdoc_export_evaluator = __esm(() => {
|
|
|
56267
56849
|
};
|
|
56268
56850
|
});
|
|
56269
56851
|
|
|
56270
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56852
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/json.js
|
|
56271
56853
|
class JsonFormatter {
|
|
56272
56854
|
constructor() {}
|
|
56273
56855
|
format(result) {
|
|
@@ -56275,7 +56857,7 @@ class JsonFormatter {
|
|
|
56275
56857
|
}
|
|
56276
56858
|
}
|
|
56277
56859
|
|
|
56278
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56860
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/text.js
|
|
56279
56861
|
class TextFormatter {
|
|
56280
56862
|
constructor() {}
|
|
56281
56863
|
format(result) {
|
|
@@ -56289,7 +56871,7 @@ class TextFormatter {
|
|
|
56289
56871
|
}
|
|
56290
56872
|
}
|
|
56291
56873
|
|
|
56292
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56874
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/host/builtins.js
|
|
56293
56875
|
function registerBuiltins(host, executor) {
|
|
56294
56876
|
const path9 = new PathEvaluator;
|
|
56295
56877
|
host.evaluators.register("regex", new RegexEvaluator, "builtin");
|
|
@@ -56329,7 +56911,7 @@ var init_builtins = __esm(() => {
|
|
|
56329
56911
|
init_tsdoc_export_evaluator();
|
|
56330
56912
|
});
|
|
56331
56913
|
|
|
56332
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56914
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/host/rule-engine-host.js
|
|
56333
56915
|
class RuleEngineHost {
|
|
56334
56916
|
evaluators;
|
|
56335
56917
|
formatters;
|
|
@@ -56346,7 +56928,7 @@ var init_rule_engine_host = __esm(() => {
|
|
|
56346
56928
|
init_extension2();
|
|
56347
56929
|
});
|
|
56348
56930
|
|
|
56349
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56931
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/engine.js
|
|
56350
56932
|
class RuleEngine {
|
|
56351
56933
|
host;
|
|
56352
56934
|
events;
|
|
@@ -56359,7 +56941,7 @@ class RuleEngine {
|
|
|
56359
56941
|
this.host = options.host ?? new RuleEngineHost;
|
|
56360
56942
|
registerBuiltins(this.host, options.processExecutor);
|
|
56361
56943
|
registerBuiltinFixers(this.host, options.processExecutor);
|
|
56362
|
-
this.events = options.events;
|
|
56944
|
+
this.events = options.events ?? (options.lifecycleBus ? new EventBus({ lifecycleBus: options.lifecycleBus }) : undefined);
|
|
56363
56945
|
this.logger = options.logger ?? getLogger2("rule-engine");
|
|
56364
56946
|
this.persistence = options.persistence;
|
|
56365
56947
|
this.runId = options.runId ?? crypto.randomUUID();
|
|
@@ -56517,7 +57099,7 @@ var init_engine = __esm(() => {
|
|
|
56517
57099
|
init_types3();
|
|
56518
57100
|
});
|
|
56519
57101
|
|
|
56520
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
57102
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/host/bundled-rules.js
|
|
56521
57103
|
async function bundledRulesRoot() {
|
|
56522
57104
|
if (cachedRoot2 !== undefined)
|
|
56523
57105
|
return cachedRoot2;
|
|
@@ -56568,7 +57150,7 @@ var init_bundled_rules = __esm(() => {
|
|
|
56568
57150
|
init_dist5();
|
|
56569
57151
|
});
|
|
56570
57152
|
|
|
56571
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
57153
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/db-adapter.js
|
|
56572
57154
|
class DbRulePersistenceAdapter {
|
|
56573
57155
|
db;
|
|
56574
57156
|
constructor(db2) {
|
|
@@ -56602,7 +57184,7 @@ class DbRulePersistenceAdapter {
|
|
|
56602
57184
|
}
|
|
56603
57185
|
}
|
|
56604
57186
|
|
|
56605
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
57187
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/schema.js
|
|
56606
57188
|
var RULE_ENGINE_SCHEMA_SQL = `
|
|
56607
57189
|
CREATE TABLE IF NOT EXISTS rule_runs (
|
|
56608
57190
|
id TEXT PRIMARY KEY,
|
|
@@ -56648,10 +57230,10 @@ CREATE TABLE IF NOT EXISTS rule_eval_runs (
|
|
|
56648
57230
|
CREATE INDEX IF NOT EXISTS idx_rule_eval_runs_run_id ON rule_eval_runs (run_id);
|
|
56649
57231
|
`;
|
|
56650
57232
|
|
|
56651
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
57233
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/index.js
|
|
56652
57234
|
var init_persistence2 = () => {};
|
|
56653
57235
|
|
|
56654
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
57236
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.10+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/index.js
|
|
56655
57237
|
var init_dist10 = __esm(() => {
|
|
56656
57238
|
init_extensions();
|
|
56657
57239
|
init_loader2();
|
|
@@ -56850,7 +57432,7 @@ ${SYSTEM_EVENTS_SCHEMA_SQL}
|
|
|
56850
57432
|
];
|
|
56851
57433
|
});
|
|
56852
57434
|
|
|
56853
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
57435
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/job-queue/db-job-queue.js
|
|
56854
57436
|
function queueLogger() {
|
|
56855
57437
|
if (!_queueLogger)
|
|
56856
57438
|
_queueLogger = getLogger2("job-queue");
|
|
@@ -57078,7 +57660,7 @@ var init_db_job_queue = __esm(() => {
|
|
|
57078
57660
|
init_tracing2();
|
|
57079
57661
|
});
|
|
57080
57662
|
|
|
57081
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
57663
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/job-queue-db.js
|
|
57082
57664
|
var exports_job_queue_db = {};
|
|
57083
57665
|
__export(exports_job_queue_db, {
|
|
57084
57666
|
DBQueueConsumer: () => DBQueueConsumer,
|
|
@@ -60515,7 +61097,7 @@ var init_rule_service = __esm(() => {
|
|
|
60515
61097
|
function defaultWrapperArgv(agentId) {
|
|
60516
61098
|
return {
|
|
60517
61099
|
command: process.execPath,
|
|
60518
|
-
args: [process.argv[1] ?? "apps/cli/src/index.ts", "agent", "
|
|
61100
|
+
args: [process.argv[1] ?? "apps/cli/src/index.ts", "agent", "loop", "--agent", agentId]
|
|
60519
61101
|
};
|
|
60520
61102
|
}
|
|
60521
61103
|
|
|
@@ -60528,6 +61110,8 @@ class SupervisorService {
|
|
|
60528
61110
|
ringBuffers = new Map;
|
|
60529
61111
|
specsPromise;
|
|
60530
61112
|
frameSeq = 0;
|
|
61113
|
+
restartAttempts = new Map;
|
|
61114
|
+
restartTimers = new Map;
|
|
60531
61115
|
constructor(options) {
|
|
60532
61116
|
this.processExecutor = options.processExecutor;
|
|
60533
61117
|
this.eventBus = options.eventBus;
|
|
@@ -60565,12 +61149,17 @@ class SupervisorService {
|
|
|
60565
61149
|
throw new Error(`No agent spec found for "${agentId}"`);
|
|
60566
61150
|
}
|
|
60567
61151
|
const { command, args } = this.resolveCommand(spec);
|
|
61152
|
+
const teamTag = spec.tags.find((t) => t.startsWith("team:"));
|
|
61153
|
+
const teamId = teamTag ? teamTag.slice("team:".length) : null;
|
|
60568
61154
|
const frames = [];
|
|
60569
61155
|
this.ringBuffers.set(agentId, frames);
|
|
60570
61156
|
const pipeOpts = {
|
|
60571
61157
|
command,
|
|
60572
61158
|
args,
|
|
60573
61159
|
label: `agent:${agentId}`,
|
|
61160
|
+
source: "supervisor",
|
|
61161
|
+
agentId,
|
|
61162
|
+
...teamId ? { teamId } : {},
|
|
60574
61163
|
env: Object.fromEntries(Object.entries(process.env).filter(([, v]) => v !== undefined))
|
|
60575
61164
|
};
|
|
60576
61165
|
const handle = this.processExecutor.runStreaming(pipeOpts);
|
|
@@ -60580,22 +61169,35 @@ class SupervisorService {
|
|
|
60580
61169
|
pid,
|
|
60581
61170
|
status: "running",
|
|
60582
61171
|
startedAt: new Date().toISOString(),
|
|
60583
|
-
ringBuffer: frames
|
|
61172
|
+
ringBuffer: frames,
|
|
61173
|
+
teamId
|
|
60584
61174
|
};
|
|
60585
61175
|
this.processes.set(agentId, { handle, entry });
|
|
61176
|
+
this.restartAttempts.delete(agentId);
|
|
60586
61177
|
this.pipeStream(handle.stdout, "stdout", agentId, frames);
|
|
60587
61178
|
this.pipeStream(handle.stderr, "stderr", agentId, frames);
|
|
60588
61179
|
this.emit("process.spawned", { agentId, pid });
|
|
60589
|
-
handle.exited.then((code) => {
|
|
60590
|
-
entry.status = "exited";
|
|
61180
|
+
handle.exited.then(async (code) => {
|
|
60591
61181
|
entry.exitCode = code;
|
|
60592
|
-
const keepForMs = 60000;
|
|
60593
|
-
setTimeout(() => {
|
|
60594
|
-
if (this.processes.get(agentId)?.entry === entry) {
|
|
60595
|
-
this.processes.delete(agentId);
|
|
60596
|
-
}
|
|
60597
|
-
}, keepForMs);
|
|
60598
61182
|
this.emit("process.exited", { agentId, pid, exitCode: code });
|
|
61183
|
+
if (code === 0 || entry.status === "stopped") {
|
|
61184
|
+
entry.status = "exited";
|
|
61185
|
+
this.scheduleCleanup(agentId, entry);
|
|
61186
|
+
return;
|
|
61187
|
+
}
|
|
61188
|
+
const attempts = (this.restartAttempts.get(agentId) ?? 0) + 1;
|
|
61189
|
+
this.restartAttempts.set(agentId, attempts);
|
|
61190
|
+
if (attempts > MAX_RESTART_ATTEMPTS) {
|
|
61191
|
+
entry.status = "errored";
|
|
61192
|
+
this.scheduleCleanup(agentId, entry);
|
|
61193
|
+
return;
|
|
61194
|
+
}
|
|
61195
|
+
entry.status = "errored";
|
|
61196
|
+
const delay = attempts >= RESTART_BACKOFF_SCHEDULE.length ? MAX_RESTART_BACKOFF : RESTART_BACKOFF_SCHEDULE[attempts - 1] ?? 1000;
|
|
61197
|
+
this.restartTimers.set(agentId, setTimeout(() => {
|
|
61198
|
+
this.restartTimers.delete(agentId);
|
|
61199
|
+
this.start(agentId).catch(() => {});
|
|
61200
|
+
}, delay));
|
|
60599
61201
|
});
|
|
60600
61202
|
return entry;
|
|
60601
61203
|
}
|
|
@@ -60618,6 +61220,12 @@ class SupervisorService {
|
|
|
60618
61220
|
await proc.handle.exited.catch(() => {});
|
|
60619
61221
|
}
|
|
60620
61222
|
proc.entry.status = "stopped";
|
|
61223
|
+
const timer = this.restartTimers.get(agentId);
|
|
61224
|
+
if (timer) {
|
|
61225
|
+
clearTimeout(timer);
|
|
61226
|
+
this.restartTimers.delete(agentId);
|
|
61227
|
+
}
|
|
61228
|
+
this.restartAttempts.delete(agentId);
|
|
60621
61229
|
this.emit("process.stopped", { agentId, pid: proc.entry.pid });
|
|
60622
61230
|
}
|
|
60623
61231
|
async startAutostart(ids) {
|
|
@@ -60638,12 +61246,22 @@ class SupervisorService {
|
|
|
60638
61246
|
const running = Array.from(this.processes.keys()).filter((id) => this.processes.get(id)?.entry.status === "running");
|
|
60639
61247
|
await Promise.all(running.map((id) => this.stop(id)));
|
|
60640
61248
|
}
|
|
61249
|
+
scheduleCleanup(agentId, entry) {
|
|
61250
|
+
const keepForMs = 60000;
|
|
61251
|
+
setTimeout(() => {
|
|
61252
|
+
if (this.processes.get(agentId)?.entry === entry) {
|
|
61253
|
+
this.processes.delete(agentId);
|
|
61254
|
+
}
|
|
61255
|
+
}, keepForMs);
|
|
61256
|
+
}
|
|
60641
61257
|
async loadSpecs() {
|
|
60642
61258
|
this.specsPromise ??= Promise.resolve().then(() => (init_dist7(), exports_dist3)).then((m) => m.loadAgentSpecs(this.configDir));
|
|
60643
61259
|
return this.specsPromise;
|
|
60644
61260
|
}
|
|
60645
61261
|
resolveCommand(spec) {
|
|
60646
|
-
const
|
|
61262
|
+
const configCommand = Array.isArray(spec.config?.command) ? spec.config.command : undefined;
|
|
61263
|
+
const topLevel = spec.command;
|
|
61264
|
+
const raw = configCommand ?? topLevel;
|
|
60647
61265
|
if (raw && raw.length > 0) {
|
|
60648
61266
|
return { command: raw[0] ?? "", args: raw.slice(1) };
|
|
60649
61267
|
}
|
|
@@ -60690,7 +61308,10 @@ class SupervisorService {
|
|
|
60690
61308
|
} catch {}
|
|
60691
61309
|
}
|
|
60692
61310
|
}
|
|
60693
|
-
var DEFAULT_RING_BUFFER_SIZE = 500;
|
|
61311
|
+
var DEFAULT_RING_BUFFER_SIZE = 500, MAX_RESTART_ATTEMPTS = 5, RESTART_BACKOFF_SCHEDULE, MAX_RESTART_BACKOFF = 30000;
|
|
61312
|
+
var init_supervisor_service = __esm(() => {
|
|
61313
|
+
RESTART_BACKOFF_SCHEDULE = [1000, 2000, 4000, 8000, 16000];
|
|
61314
|
+
});
|
|
60694
61315
|
|
|
60695
61316
|
// ../../packages/app/src/services/system-event-tap.ts
|
|
60696
61317
|
function registerSystemEventTap(bus, dao2, logger3, options = {}) {
|
|
@@ -60765,6 +61386,41 @@ var init_system_event_tap = __esm(() => {
|
|
|
60765
61386
|
init_event_names();
|
|
60766
61387
|
});
|
|
60767
61388
|
|
|
61389
|
+
// ../../packages/app/src/services/system-event-emitter.ts
|
|
61390
|
+
class SystemEventEmitter {
|
|
61391
|
+
dao;
|
|
61392
|
+
logger;
|
|
61393
|
+
constructor(dao2, logger3) {
|
|
61394
|
+
this.dao = dao2;
|
|
61395
|
+
this.logger = logger3;
|
|
61396
|
+
}
|
|
61397
|
+
async emit(event2) {
|
|
61398
|
+
const entry = systemEventCatalogEntry(event2.event);
|
|
61399
|
+
if (!entry)
|
|
61400
|
+
return;
|
|
61401
|
+
try {
|
|
61402
|
+
await this.dao.insert({
|
|
61403
|
+
id: createId("sev"),
|
|
61404
|
+
event_name: entry.name,
|
|
61405
|
+
occurred_at: event2.at,
|
|
61406
|
+
actor: extractSystemEventActor(event2),
|
|
61407
|
+
payload_json: safeStringify(normalizeSystemEventPayload(entry, event2))
|
|
61408
|
+
});
|
|
61409
|
+
await this.dao.prune(SYSTEM_EVENTS_CAP);
|
|
61410
|
+
} catch (error51) {
|
|
61411
|
+
this.logger.warn("system_events emitter: persist failed", {
|
|
61412
|
+
event: event2.event,
|
|
61413
|
+
error: error51 instanceof Error ? `${error51.name}: ${error51.message}` : String(error51)
|
|
61414
|
+
});
|
|
61415
|
+
}
|
|
61416
|
+
}
|
|
61417
|
+
}
|
|
61418
|
+
var init_system_event_emitter = __esm(() => {
|
|
61419
|
+
init_src2();
|
|
61420
|
+
init_event_names();
|
|
61421
|
+
init_system_event_tap();
|
|
61422
|
+
});
|
|
61423
|
+
|
|
60768
61424
|
// ../../packages/app/src/services/task-check.ts
|
|
60769
61425
|
import { dirname as dirname9, join as join9 } from "path";
|
|
60770
61426
|
function isPlaceholderBody(body) {
|
|
@@ -62336,6 +62992,27 @@ class TeamService {
|
|
|
62336
62992
|
count: rows.length
|
|
62337
62993
|
};
|
|
62338
62994
|
}
|
|
62995
|
+
async drainPending(agentId) {
|
|
62996
|
+
validateAgentId(agentId);
|
|
62997
|
+
const dao2 = await this.inboxDao();
|
|
62998
|
+
const rows = await dao2.drainPending(agentId);
|
|
62999
|
+
return {
|
|
63000
|
+
messages: rows.map((row) => ({
|
|
63001
|
+
id: row.id,
|
|
63002
|
+
fromId: row.fromId,
|
|
63003
|
+
body: row.body,
|
|
63004
|
+
status: row.status,
|
|
63005
|
+
createdAt: new Date(row.createdAt).toISOString(),
|
|
63006
|
+
inReplyTo: row.inReplyTo
|
|
63007
|
+
})),
|
|
63008
|
+
count: rows.length
|
|
63009
|
+
};
|
|
63010
|
+
}
|
|
63011
|
+
async countPending(agentId) {
|
|
63012
|
+
validateAgentId(agentId);
|
|
63013
|
+
const dao2 = await this.inboxDao();
|
|
63014
|
+
return dao2.countPending(agentId);
|
|
63015
|
+
}
|
|
62339
63016
|
async listRecent(limit = 50) {
|
|
62340
63017
|
const dao2 = await this.inboxRecentDao();
|
|
62341
63018
|
const rows = await dao2.listRecent(limit);
|
|
@@ -62436,6 +63113,131 @@ class TeamService {
|
|
|
62436
63113
|
peers
|
|
62437
63114
|
});
|
|
62438
63115
|
}
|
|
63116
|
+
async listTeams() {
|
|
63117
|
+
const specs = await loadAgentSpecs(this.configDir);
|
|
63118
|
+
const config4 = await this.loadTeamConfig();
|
|
63119
|
+
const teams = new Map;
|
|
63120
|
+
if (config4?.agent?.team) {
|
|
63121
|
+
for (const [teamId, teamConfig] of Object.entries(config4.agent.team)) {
|
|
63122
|
+
teams.set(teamId, {
|
|
63123
|
+
teamId,
|
|
63124
|
+
name: teamConfig.name,
|
|
63125
|
+
members: [],
|
|
63126
|
+
specs: []
|
|
63127
|
+
});
|
|
63128
|
+
}
|
|
63129
|
+
}
|
|
63130
|
+
const untethered = [];
|
|
63131
|
+
for (const spec of specs) {
|
|
63132
|
+
const teamTag = spec.tags?.find((t) => t.startsWith("team:"));
|
|
63133
|
+
if (teamTag) {
|
|
63134
|
+
const teamId = teamTag.slice("team:".length);
|
|
63135
|
+
const entry = teams.get(teamId);
|
|
63136
|
+
if (entry) {
|
|
63137
|
+
entry.specs.push(spec);
|
|
63138
|
+
} else {
|
|
63139
|
+
teams.set(teamId, {
|
|
63140
|
+
teamId,
|
|
63141
|
+
name: teamId,
|
|
63142
|
+
members: [],
|
|
63143
|
+
specs: [spec]
|
|
63144
|
+
});
|
|
63145
|
+
}
|
|
63146
|
+
} else {
|
|
63147
|
+
untethered.push(spec);
|
|
63148
|
+
}
|
|
63149
|
+
}
|
|
63150
|
+
if (untethered.length > 0) {
|
|
63151
|
+
teams.set("__untethered__", {
|
|
63152
|
+
teamId: "__untethered__",
|
|
63153
|
+
name: "Untethered",
|
|
63154
|
+
members: [],
|
|
63155
|
+
specs: untethered
|
|
63156
|
+
});
|
|
63157
|
+
}
|
|
63158
|
+
return Array.from(teams.values());
|
|
63159
|
+
}
|
|
63160
|
+
async materializeTeam(teamId, opts) {
|
|
63161
|
+
const config4 = await this.loadTeamConfig();
|
|
63162
|
+
const teamConfig = config4?.agent?.team?.[teamId];
|
|
63163
|
+
if (!teamConfig) {
|
|
63164
|
+
throw new Error(`Team "${teamId}" not found in agent.team config`);
|
|
63165
|
+
}
|
|
63166
|
+
const agentConfig = config4?.agent;
|
|
63167
|
+
const specs = await loadAgentSpecs(this.configDir);
|
|
63168
|
+
const existingTeamSpecs = specs.filter((s) => s.tags?.includes(`team:${teamId}`) && s.tags?.includes("spur:generated"));
|
|
63169
|
+
const desiredMembers = teamConfig.members.map((m) => normalizeMember(m));
|
|
63170
|
+
const desiredIds = new Set;
|
|
63171
|
+
const toUpsert = [];
|
|
63172
|
+
for (const member of desiredMembers) {
|
|
63173
|
+
const localId = member.id ?? member.executor;
|
|
63174
|
+
const composedId = `${teamId}-${localId}`;
|
|
63175
|
+
desiredIds.add(composedId);
|
|
63176
|
+
const existing = specs.find((s) => s.id === composedId);
|
|
63177
|
+
if (existing && !existing.tags?.includes("spur:generated"))
|
|
63178
|
+
continue;
|
|
63179
|
+
const resolved = resolveExecutor(member.executor, agentConfig);
|
|
63180
|
+
const spec = {
|
|
63181
|
+
id: composedId,
|
|
63182
|
+
name: member.purpose ?? composedId,
|
|
63183
|
+
type: resolved.agent,
|
|
63184
|
+
workspace: member.workspace ?? teamConfig.work_dir,
|
|
63185
|
+
purpose: member.purpose && member.purpose.length > 0 ? member.purpose : `${resolved.agent} agent`,
|
|
63186
|
+
tags: [`team:${teamId}`, "spur:generated"],
|
|
63187
|
+
config: {
|
|
63188
|
+
...resolved.model !== undefined ? { model: resolved.model } : {},
|
|
63189
|
+
...member.systemPrompt !== undefined ? { systemPrompt: member.systemPrompt } : {},
|
|
63190
|
+
...member.command !== undefined ? { command: member.command } : {},
|
|
63191
|
+
...member.autonomy !== undefined ? { autonomy: member.autonomy } : {}
|
|
63192
|
+
},
|
|
63193
|
+
...member.autostart !== undefined ? { autoStart: member.autostart } : {}
|
|
63194
|
+
};
|
|
63195
|
+
toUpsert.push(spec);
|
|
63196
|
+
}
|
|
63197
|
+
const orphaned = existingTeamSpecs.filter((s) => !desiredIds.has(s.id));
|
|
63198
|
+
if (opts?.check) {
|
|
63199
|
+
return {
|
|
63200
|
+
teamId,
|
|
63201
|
+
upserted: toUpsert.map((s) => s.id),
|
|
63202
|
+
orphaned: orphaned.map((s) => s.id),
|
|
63203
|
+
written: false
|
|
63204
|
+
};
|
|
63205
|
+
}
|
|
63206
|
+
for (const spec of toUpsert) {
|
|
63207
|
+
await saveAgentSpec(spec, this.configDir);
|
|
63208
|
+
}
|
|
63209
|
+
for (const spec of orphaned) {
|
|
63210
|
+
await deleteAgentSpec(spec.id, this.configDir);
|
|
63211
|
+
}
|
|
63212
|
+
return {
|
|
63213
|
+
teamId,
|
|
63214
|
+
upserted: toUpsert.map((s) => s.id),
|
|
63215
|
+
orphaned: orphaned.map((s) => s.id),
|
|
63216
|
+
written: true
|
|
63217
|
+
};
|
|
63218
|
+
}
|
|
63219
|
+
async teardownTeam(teamId, opts) {
|
|
63220
|
+
const specs = await loadAgentSpecs(this.configDir);
|
|
63221
|
+
const teamSpecs = specs.filter((s) => s.tags?.includes(`team:${teamId}`));
|
|
63222
|
+
const generated = teamSpecs.filter((s) => s.tags?.includes("spur:generated"));
|
|
63223
|
+
if (opts?.purge) {
|
|
63224
|
+
for (const spec of generated) {
|
|
63225
|
+
await deleteAgentSpec(spec.id, this.configDir);
|
|
63226
|
+
}
|
|
63227
|
+
}
|
|
63228
|
+
return {
|
|
63229
|
+
teamId,
|
|
63230
|
+
purged: opts?.purge ? generated.map((s) => s.id) : [],
|
|
63231
|
+
stopped: teamSpecs.map((s) => s.id)
|
|
63232
|
+
};
|
|
63233
|
+
}
|
|
63234
|
+
async loadTeamConfig() {
|
|
63235
|
+
try {
|
|
63236
|
+
return await loadSpurConfig(this.ctx.cwd);
|
|
63237
|
+
} catch {
|
|
63238
|
+
return null;
|
|
63239
|
+
}
|
|
63240
|
+
}
|
|
62439
63241
|
async inboxDao() {
|
|
62440
63242
|
const db2 = await this.ctx.getDb();
|
|
62441
63243
|
return new InboxMessageDao(db2);
|
|
@@ -62476,17 +63278,312 @@ class TeamService {
|
|
|
62476
63278
|
return null;
|
|
62477
63279
|
}
|
|
62478
63280
|
}
|
|
63281
|
+
function resolveAutostartSet(config4, envAutostart) {
|
|
63282
|
+
const ids = new Set;
|
|
63283
|
+
const teams = config4?.agent?.team;
|
|
63284
|
+
if (teams) {
|
|
63285
|
+
for (const [teamId, teamConfig] of Object.entries(teams)) {
|
|
63286
|
+
for (const member of teamConfig.members) {
|
|
63287
|
+
const ref = normalizeMember(member);
|
|
63288
|
+
const localId = ref.id ?? ref.executor;
|
|
63289
|
+
const composedId = `${teamId}-${localId}`;
|
|
63290
|
+
const effective = ref.autostart ?? teamConfig.autostart ?? false;
|
|
63291
|
+
if (effective)
|
|
63292
|
+
ids.add(composedId);
|
|
63293
|
+
}
|
|
63294
|
+
}
|
|
63295
|
+
}
|
|
63296
|
+
if (envAutostart) {
|
|
63297
|
+
for (const id of envAutostart.split(",").map((s) => s.trim()).filter(Boolean)) {
|
|
63298
|
+
ids.add(id);
|
|
63299
|
+
}
|
|
63300
|
+
}
|
|
63301
|
+
return Array.from(ids).sort();
|
|
63302
|
+
}
|
|
62479
63303
|
var init_team_service = __esm(() => {
|
|
63304
|
+
init_src();
|
|
63305
|
+
init_loader();
|
|
62480
63306
|
init_src2();
|
|
62481
63307
|
init_dist7();
|
|
62482
63308
|
init_planning_folders();
|
|
62483
63309
|
});
|
|
62484
63310
|
|
|
63311
|
+
// ../../packages/app/src/services/token-ledger-service.ts
|
|
63312
|
+
import { closeSync as closeSync2, existsSync as existsSync5, fstatSync, openSync as openSync2, readSync } from "fs";
|
|
63313
|
+
import { join as join11 } from "path";
|
|
63314
|
+
function isSparseToolActivity(events2) {
|
|
63315
|
+
return events2.length === 0 || !events2.some((e) => TOOL_ACTIVITY_TYPES.has(e.type));
|
|
63316
|
+
}
|
|
63317
|
+
function clampToolUseLimit(raw) {
|
|
63318
|
+
if (raw === undefined || !Number.isFinite(raw) || raw <= 0) {
|
|
63319
|
+
return TOKEN_LEDGER_DEFAULT_LIMIT;
|
|
63320
|
+
}
|
|
63321
|
+
return Math.min(Math.floor(raw), TOKEN_LEDGER_MAX_LIMIT);
|
|
63322
|
+
}
|
|
63323
|
+
function parseLedgerLine(line) {
|
|
63324
|
+
const trimmed = line.trim();
|
|
63325
|
+
if (!trimmed)
|
|
63326
|
+
return null;
|
|
63327
|
+
try {
|
|
63328
|
+
const obj = JSON.parse(trimmed);
|
|
63329
|
+
if (typeof obj.ts !== "string" || typeof obj.session !== "string" || typeof obj.type !== "string") {
|
|
63330
|
+
return null;
|
|
63331
|
+
}
|
|
63332
|
+
const event2 = {
|
|
63333
|
+
ts: obj.ts,
|
|
63334
|
+
session: obj.session,
|
|
63335
|
+
type: obj.type
|
|
63336
|
+
};
|
|
63337
|
+
if (typeof obj.file === "string")
|
|
63338
|
+
event2.file = obj.file;
|
|
63339
|
+
if (typeof obj.summary === "string")
|
|
63340
|
+
event2.summary = obj.summary;
|
|
63341
|
+
if (typeof obj.tokens === "number" && Number.isFinite(obj.tokens) && obj.tokens >= 0) {
|
|
63342
|
+
event2.tokens = obj.tokens;
|
|
63343
|
+
}
|
|
63344
|
+
if (typeof obj.action === "string")
|
|
63345
|
+
event2.action = obj.action;
|
|
63346
|
+
if (typeof obj.sessionId === "string")
|
|
63347
|
+
event2.sessionId = obj.sessionId;
|
|
63348
|
+
if (typeof obj.agent === "string")
|
|
63349
|
+
event2.agent = obj.agent;
|
|
63350
|
+
if (typeof obj.model === "string")
|
|
63351
|
+
event2.model = obj.model;
|
|
63352
|
+
if (obj.totals !== null && typeof obj.totals === "object") {
|
|
63353
|
+
const t = obj.totals;
|
|
63354
|
+
if (typeof t.reads === "number" && typeof t.writes === "number" && typeof t.tokens === "number") {
|
|
63355
|
+
event2.totals = { reads: t.reads, writes: t.writes, tokens: t.tokens };
|
|
63356
|
+
}
|
|
63357
|
+
}
|
|
63358
|
+
return event2;
|
|
63359
|
+
} catch {
|
|
63360
|
+
return null;
|
|
63361
|
+
}
|
|
63362
|
+
}
|
|
63363
|
+
function tailTokenLedgerFile(filePath, limit, chunkSize = DEFAULT_CHUNK, before) {
|
|
63364
|
+
if (!existsSync5(filePath)) {
|
|
63365
|
+
return { events: [], truncated: false };
|
|
63366
|
+
}
|
|
63367
|
+
const target = limit + 1;
|
|
63368
|
+
const fd = openSync2(filePath, "r");
|
|
63369
|
+
try {
|
|
63370
|
+
const { size } = fstatSync(fd);
|
|
63371
|
+
if (size === 0)
|
|
63372
|
+
return { events: [], truncated: false };
|
|
63373
|
+
let pos = size;
|
|
63374
|
+
let carry = "";
|
|
63375
|
+
const events2 = [];
|
|
63376
|
+
while (pos > 0 && events2.length < target) {
|
|
63377
|
+
const n2 = Math.min(chunkSize, pos);
|
|
63378
|
+
pos -= n2;
|
|
63379
|
+
const buf = Buffer.alloc(n2);
|
|
63380
|
+
readSync(fd, buf, 0, n2, pos);
|
|
63381
|
+
const text4 = buf.toString("utf8") + carry;
|
|
63382
|
+
const parts = text4.split(`
|
|
63383
|
+
`);
|
|
63384
|
+
if (pos > 0) {
|
|
63385
|
+
carry = parts.shift() ?? "";
|
|
63386
|
+
} else {
|
|
63387
|
+
carry = "";
|
|
63388
|
+
}
|
|
63389
|
+
for (let i2 = parts.length - 1;i2 >= 0; i2--) {
|
|
63390
|
+
const evt = parseLedgerLine(parts[i2] ?? "");
|
|
63391
|
+
if (!evt)
|
|
63392
|
+
continue;
|
|
63393
|
+
if (before !== undefined && evt.ts >= before)
|
|
63394
|
+
continue;
|
|
63395
|
+
events2.push(evt);
|
|
63396
|
+
if (events2.length >= target)
|
|
63397
|
+
break;
|
|
63398
|
+
}
|
|
63399
|
+
}
|
|
63400
|
+
const truncated = events2.length > limit;
|
|
63401
|
+
return {
|
|
63402
|
+
events: events2.slice(0, limit),
|
|
63403
|
+
truncated
|
|
63404
|
+
};
|
|
63405
|
+
} finally {
|
|
63406
|
+
closeSync2(fd);
|
|
63407
|
+
}
|
|
63408
|
+
}
|
|
63409
|
+
|
|
63410
|
+
class TokenLedgerService {
|
|
63411
|
+
ledgerPath;
|
|
63412
|
+
chunkSize;
|
|
63413
|
+
constructor(options) {
|
|
63414
|
+
this.ledgerPath = options.ledgerPath ?? join11(options.cwd, TOKEN_LEDGER_RELATIVE_PATH);
|
|
63415
|
+
this.chunkSize = options.chunkSize ?? DEFAULT_CHUNK;
|
|
63416
|
+
}
|
|
63417
|
+
get path() {
|
|
63418
|
+
return this.ledgerPath;
|
|
63419
|
+
}
|
|
63420
|
+
snapshot(limitRawOrOpts, maybeBefore) {
|
|
63421
|
+
let limitRaw;
|
|
63422
|
+
let before;
|
|
63423
|
+
if (typeof limitRawOrOpts === "object" && limitRawOrOpts !== null) {
|
|
63424
|
+
limitRaw = limitRawOrOpts.limit;
|
|
63425
|
+
before = limitRawOrOpts.before;
|
|
63426
|
+
} else {
|
|
63427
|
+
limitRaw = limitRawOrOpts;
|
|
63428
|
+
before = maybeBefore;
|
|
63429
|
+
}
|
|
63430
|
+
if (before !== undefined && (typeof before !== "string" || before.length === 0)) {
|
|
63431
|
+
before = undefined;
|
|
63432
|
+
}
|
|
63433
|
+
const limit = clampToolUseLimit(limitRaw);
|
|
63434
|
+
const capturedAt = new Date().toISOString();
|
|
63435
|
+
const { events: raw, truncated } = tailTokenLedgerFile(this.ledgerPath, limit, this.chunkSize, before);
|
|
63436
|
+
const events2 = raw.map((e, seq) => ({ ...e, seq }));
|
|
63437
|
+
const sparseToolActivity = isSparseToolActivity(events2);
|
|
63438
|
+
const oldest = events2.length > 0 ? events2[events2.length - 1] : undefined;
|
|
63439
|
+
const nextBefore = truncated && oldest ? oldest.ts : null;
|
|
63440
|
+
return {
|
|
63441
|
+
events: events2,
|
|
63442
|
+
count: events2.length,
|
|
63443
|
+
limit,
|
|
63444
|
+
truncated,
|
|
63445
|
+
path: this.ledgerPath,
|
|
63446
|
+
capturedAt,
|
|
63447
|
+
sparseToolActivity,
|
|
63448
|
+
nextBefore
|
|
63449
|
+
};
|
|
63450
|
+
}
|
|
63451
|
+
}
|
|
63452
|
+
var TOOL_ACTIVITY_TYPES, TOKEN_LEDGER_DEFAULT_LIMIT = 200, TOKEN_LEDGER_MAX_LIMIT = 1000, TOKEN_LEDGER_RELATIVE_PATH, DEFAULT_CHUNK;
|
|
63453
|
+
var init_token_ledger_service = __esm(() => {
|
|
63454
|
+
TOOL_ACTIVITY_TYPES = new Set(["read", "write", "bash", "grep", "glob"]);
|
|
63455
|
+
TOKEN_LEDGER_RELATIVE_PATH = join11(".spur", "context", "token-ledger.jsonl");
|
|
63456
|
+
DEFAULT_CHUNK = 64 * 1024;
|
|
63457
|
+
});
|
|
63458
|
+
|
|
63459
|
+
// ../../packages/app/src/services/token-ledger-watcher.ts
|
|
63460
|
+
import { closeSync as closeSync3, existsSync as existsSync6, fstatSync as fstatSync2, openSync as openSync3, readSync as readSync2, watch } from "fs";
|
|
63461
|
+
|
|
63462
|
+
class TokenLedgerWatcher {
|
|
63463
|
+
ledgerPath;
|
|
63464
|
+
debounceMs;
|
|
63465
|
+
listeners = new Set;
|
|
63466
|
+
watcher;
|
|
63467
|
+
offset = 0;
|
|
63468
|
+
debounceTimer;
|
|
63469
|
+
started = false;
|
|
63470
|
+
carry = "";
|
|
63471
|
+
constructor(options) {
|
|
63472
|
+
this.ledgerPath = options.ledgerPath;
|
|
63473
|
+
this.debounceMs = options.debounceMs ?? 50;
|
|
63474
|
+
}
|
|
63475
|
+
start() {
|
|
63476
|
+
if (this.started)
|
|
63477
|
+
return;
|
|
63478
|
+
this.started = true;
|
|
63479
|
+
this.offset = this.currentSize();
|
|
63480
|
+
try {
|
|
63481
|
+
const target = existsSync6(this.ledgerPath) ? this.ledgerPath : this.parentDir();
|
|
63482
|
+
this.watcher = watch(target, () => this.schedulePoll());
|
|
63483
|
+
} catch {
|
|
63484
|
+
this.watcher = undefined;
|
|
63485
|
+
}
|
|
63486
|
+
}
|
|
63487
|
+
stop() {
|
|
63488
|
+
this.started = false;
|
|
63489
|
+
if (this.debounceTimer)
|
|
63490
|
+
clearTimeout(this.debounceTimer);
|
|
63491
|
+
this.debounceTimer = undefined;
|
|
63492
|
+
try {
|
|
63493
|
+
this.watcher?.close();
|
|
63494
|
+
} catch {}
|
|
63495
|
+
this.watcher = undefined;
|
|
63496
|
+
this.listeners.clear();
|
|
63497
|
+
}
|
|
63498
|
+
subscribe(listener) {
|
|
63499
|
+
this.listeners.add(listener);
|
|
63500
|
+
if (!this.started)
|
|
63501
|
+
this.start();
|
|
63502
|
+
return () => {
|
|
63503
|
+
this.listeners.delete(listener);
|
|
63504
|
+
if (this.listeners.size === 0)
|
|
63505
|
+
this.stop();
|
|
63506
|
+
};
|
|
63507
|
+
}
|
|
63508
|
+
get subscriberCount() {
|
|
63509
|
+
return this.listeners.size;
|
|
63510
|
+
}
|
|
63511
|
+
parentDir() {
|
|
63512
|
+
const idx = Math.max(this.ledgerPath.lastIndexOf("/"), this.ledgerPath.lastIndexOf("\\"));
|
|
63513
|
+
return idx > 0 ? this.ledgerPath.slice(0, idx) : ".";
|
|
63514
|
+
}
|
|
63515
|
+
currentSize() {
|
|
63516
|
+
if (!existsSync6(this.ledgerPath))
|
|
63517
|
+
return 0;
|
|
63518
|
+
try {
|
|
63519
|
+
const fd = openSync3(this.ledgerPath, "r");
|
|
63520
|
+
try {
|
|
63521
|
+
return fstatSync2(fd).size;
|
|
63522
|
+
} finally {
|
|
63523
|
+
closeSync3(fd);
|
|
63524
|
+
}
|
|
63525
|
+
} catch {
|
|
63526
|
+
return 0;
|
|
63527
|
+
}
|
|
63528
|
+
}
|
|
63529
|
+
schedulePoll() {
|
|
63530
|
+
if (this.debounceTimer)
|
|
63531
|
+
clearTimeout(this.debounceTimer);
|
|
63532
|
+
this.debounceTimer = setTimeout(() => {
|
|
63533
|
+
this.debounceTimer = undefined;
|
|
63534
|
+
this.pollNewBytes();
|
|
63535
|
+
}, this.debounceMs);
|
|
63536
|
+
}
|
|
63537
|
+
pollNewBytes() {
|
|
63538
|
+
if (!existsSync6(this.ledgerPath)) {
|
|
63539
|
+
this.offset = 0;
|
|
63540
|
+
this.carry = "";
|
|
63541
|
+
return;
|
|
63542
|
+
}
|
|
63543
|
+
let size;
|
|
63544
|
+
try {
|
|
63545
|
+
const fd = openSync3(this.ledgerPath, "r");
|
|
63546
|
+
try {
|
|
63547
|
+
size = fstatSync2(fd).size;
|
|
63548
|
+
if (size < this.offset) {
|
|
63549
|
+
this.offset = 0;
|
|
63550
|
+
this.carry = "";
|
|
63551
|
+
}
|
|
63552
|
+
if (size === this.offset)
|
|
63553
|
+
return;
|
|
63554
|
+
const len = size - this.offset;
|
|
63555
|
+
const buf = Buffer.alloc(len);
|
|
63556
|
+
readSync2(fd, buf, 0, len, this.offset);
|
|
63557
|
+
this.offset = size;
|
|
63558
|
+
const text4 = this.carry + buf.toString("utf8");
|
|
63559
|
+
const parts = text4.split(`
|
|
63560
|
+
`);
|
|
63561
|
+
this.carry = parts.pop() ?? "";
|
|
63562
|
+
for (const line of parts) {
|
|
63563
|
+
const evt = parseLedgerLine(line);
|
|
63564
|
+
if (!evt)
|
|
63565
|
+
continue;
|
|
63566
|
+
for (const listener of this.listeners) {
|
|
63567
|
+
try {
|
|
63568
|
+
listener(evt);
|
|
63569
|
+
} catch {}
|
|
63570
|
+
}
|
|
63571
|
+
}
|
|
63572
|
+
} finally {
|
|
63573
|
+
closeSync3(fd);
|
|
63574
|
+
}
|
|
63575
|
+
} catch {}
|
|
63576
|
+
}
|
|
63577
|
+
}
|
|
63578
|
+
var init_token_ledger_watcher = __esm(() => {
|
|
63579
|
+
init_token_ledger_service();
|
|
63580
|
+
});
|
|
63581
|
+
|
|
62485
63582
|
// ../../packages/app/src/workflow/actions/agent-run.ts
|
|
62486
63583
|
import { execFile } from "child_process";
|
|
62487
|
-
import { existsSync as
|
|
63584
|
+
import { existsSync as existsSync7 } from "fs";
|
|
62488
63585
|
import { mkdir, writeFile } from "fs/promises";
|
|
62489
|
-
import { dirname as dirname10, isAbsolute as isAbsolute2, join as
|
|
63586
|
+
import { dirname as dirname10, isAbsolute as isAbsolute2, join as join12 } from "path";
|
|
62490
63587
|
import { promisify as promisify3 } from "util";
|
|
62491
63588
|
|
|
62492
63589
|
class AgentRunActionRunner {
|
|
@@ -62540,13 +63637,13 @@ class AgentRunActionRunner {
|
|
|
62540
63637
|
const { exitCode: exitCode2, answer } = captured;
|
|
62541
63638
|
const ok2 = exitCode2 === 0;
|
|
62542
63639
|
if (answerFile !== undefined) {
|
|
62543
|
-
const target = isAbsolute2(answerFile) ? answerFile :
|
|
63640
|
+
const target = isAbsolute2(answerFile) ? answerFile : join12(cwd, answerFile);
|
|
62544
63641
|
await mkdir(dirname10(target), { recursive: true });
|
|
62545
63642
|
await writeFile(target, answer, "utf8");
|
|
62546
63643
|
}
|
|
62547
63644
|
if (ok2 && expectFile !== undefined) {
|
|
62548
|
-
const target = isAbsolute2(expectFile) ? expectFile :
|
|
62549
|
-
if (!
|
|
63645
|
+
const target = isAbsolute2(expectFile) ? expectFile : join12(cwd, expectFile);
|
|
63646
|
+
if (!existsSync7(target)) {
|
|
62550
63647
|
return {
|
|
62551
63648
|
ok: false,
|
|
62552
63649
|
data: { exitCode: exitCode2, agent: agentLabel, answer },
|
|
@@ -62567,8 +63664,8 @@ class AgentRunActionRunner {
|
|
|
62567
63664
|
const exitCode = await this.agentService.run(input, flags);
|
|
62568
63665
|
const ok = exitCode === 0;
|
|
62569
63666
|
if (ok && expectFile !== undefined) {
|
|
62570
|
-
const target = isAbsolute2(expectFile) ? expectFile :
|
|
62571
|
-
if (!
|
|
63667
|
+
const target = isAbsolute2(expectFile) ? expectFile : join12(cwd, expectFile);
|
|
63668
|
+
if (!existsSync7(target)) {
|
|
62572
63669
|
return {
|
|
62573
63670
|
ok: false,
|
|
62574
63671
|
data: { exitCode, agent: agentLabel },
|
|
@@ -62645,7 +63742,7 @@ async function writePartialWorkArtifact(context4, agentLabel, model, captured, c
|
|
|
62645
63742
|
""
|
|
62646
63743
|
].join(`
|
|
62647
63744
|
`);
|
|
62648
|
-
const target =
|
|
63745
|
+
const target = join12(cwd, ".spur", "run", `${context4.runId}-${context4.stateOrNodeId}-partial.md`);
|
|
62649
63746
|
await mkdir(dirname10(target), { recursive: true });
|
|
62650
63747
|
await writeFile(target, body, "utf8");
|
|
62651
63748
|
} catch {}
|
|
@@ -63309,7 +64406,7 @@ var now = () => new Date().toISOString();
|
|
|
63309
64406
|
// ../../packages/app/src/services/workflow-service.ts
|
|
63310
64407
|
import { access as access2, lstat, readdir as readdir3, readFile as readFile2, realpath } from "fs/promises";
|
|
63311
64408
|
import { homedir as homedir3 } from "os";
|
|
63312
|
-
import { join as
|
|
64409
|
+
import { join as join13, resolve as resolve3 } from "path";
|
|
63313
64410
|
function signalSubprocess(pid) {
|
|
63314
64411
|
try {
|
|
63315
64412
|
process.kill(-pid, "SIGTERM");
|
|
@@ -63513,7 +64610,7 @@ class WorkflowAppService {
|
|
|
63513
64610
|
}
|
|
63514
64611
|
async list(workflowPaths = [".spur/workflows/"]) {
|
|
63515
64612
|
const projectRoot = this.ctx.cwd;
|
|
63516
|
-
const globalRoot =
|
|
64613
|
+
const globalRoot = join13(homedir3(), ".config", "spur");
|
|
63517
64614
|
const layers = [];
|
|
63518
64615
|
const entries = [];
|
|
63519
64616
|
const scannedPaths = new Set;
|
|
@@ -63849,8 +64946,10 @@ var isActionStarted = (e) => ("kind" in e) && ("node" in e), isActionFinished =
|
|
|
63849
64946
|
// ../../packages/app/src/index.ts
|
|
63850
64947
|
var exports_src2 = {};
|
|
63851
64948
|
__export(exports_src2, {
|
|
64949
|
+
tailTokenLedgerFile: () => tailTokenLedgerFile,
|
|
63852
64950
|
systemEventCatalogEntry: () => systemEventCatalogEntry,
|
|
63853
64951
|
resolvePlanningFolders: () => resolvePlanningFolders,
|
|
64952
|
+
resolveAutostartSet: () => resolveAutostartSet,
|
|
63854
64953
|
renderTesting: () => renderTesting,
|
|
63855
64954
|
renderStepLine: () => renderStepLine,
|
|
63856
64955
|
renderSolutionFromDiff: () => renderSolutionFromDiff,
|
|
@@ -63861,6 +64960,7 @@ __export(exports_src2, {
|
|
|
63861
64960
|
readVerdict: () => readVerdict,
|
|
63862
64961
|
parseVerdict: () => parseVerdict,
|
|
63863
64962
|
parsePsOutput: () => parsePsOutput,
|
|
64963
|
+
parseLedgerLine: () => parseLedgerLine,
|
|
63864
64964
|
parseEtimeToSeconds: () => parseEtimeToSeconds,
|
|
63865
64965
|
normalizeSystemEventPayload: () => normalizeSystemEventPayload,
|
|
63866
64966
|
hitlConfirmDefault: () => hitlConfirmDefault,
|
|
@@ -63868,14 +64968,21 @@ __export(exports_src2, {
|
|
|
63868
64968
|
extractSystemEventActor: () => extractSystemEventActor,
|
|
63869
64969
|
deriveVerdict: () => deriveVerdict,
|
|
63870
64970
|
createPsProcessInspector: () => createPsProcessInspector,
|
|
64971
|
+
clampToolUseLimit: () => clampToolUseLimit,
|
|
63871
64972
|
bridgeEventBus: () => bridgeEventBus,
|
|
63872
64973
|
WorkflowAppService: () => WorkflowAppService,
|
|
63873
64974
|
UnsupportedProcessPlatformError: () => UnsupportedProcessPlatformError,
|
|
64975
|
+
TokenLedgerWatcher: () => TokenLedgerWatcher,
|
|
64976
|
+
TokenLedgerService: () => TokenLedgerService,
|
|
63874
64977
|
TeamService: () => TeamService,
|
|
63875
64978
|
TaskService: () => TaskService,
|
|
63876
64979
|
TaskCheckService: () => TaskCheckService,
|
|
64980
|
+
TOKEN_LEDGER_RELATIVE_PATH: () => TOKEN_LEDGER_RELATIVE_PATH,
|
|
64981
|
+
TOKEN_LEDGER_MAX_LIMIT: () => TOKEN_LEDGER_MAX_LIMIT,
|
|
64982
|
+
TOKEN_LEDGER_DEFAULT_LIMIT: () => TOKEN_LEDGER_DEFAULT_LIMIT,
|
|
63877
64983
|
TASK_LIFECYCLE_PROFILE: () => TASK_LIFECYCLE_PROFILE,
|
|
63878
64984
|
TASK_ACTION_COMMANDS: () => TASK_ACTION_COMMANDS,
|
|
64985
|
+
SystemEventEmitter: () => SystemEventEmitter,
|
|
63879
64986
|
SupervisorService: () => SupervisorService,
|
|
63880
64987
|
SYSTEM_EVENT_STREAMED_NAMES: () => SYSTEM_EVENT_STREAMED_NAMES,
|
|
63881
64988
|
SYSTEM_EVENT_PREFIXES: () => SYSTEM_EVENT_PREFIXES,
|
|
@@ -63927,11 +65034,15 @@ var init_src3 = __esm(() => {
|
|
|
63927
65034
|
init_process_inspector();
|
|
63928
65035
|
init_process_inventory_service();
|
|
63929
65036
|
init_rule_service();
|
|
65037
|
+
init_supervisor_service();
|
|
65038
|
+
init_system_event_emitter();
|
|
63930
65039
|
init_system_event_tap();
|
|
63931
65040
|
init_task_check();
|
|
63932
65041
|
init_task_record();
|
|
63933
65042
|
init_task_service();
|
|
63934
65043
|
init_team_service();
|
|
65044
|
+
init_token_ledger_service();
|
|
65045
|
+
init_token_ledger_watcher();
|
|
63935
65046
|
init_workflow_service();
|
|
63936
65047
|
init_agent_run();
|
|
63937
65048
|
init_file_exists();
|
|
@@ -64020,18 +65131,19 @@ var {
|
|
|
64020
65131
|
init_src();
|
|
64021
65132
|
init_loader();
|
|
64022
65133
|
|
|
64023
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
65134
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/application-node.js
|
|
64024
65135
|
init_dist4();
|
|
64025
65136
|
init_dist5();
|
|
64026
65137
|
import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync5 } from "fs";
|
|
64027
65138
|
import { dirname as dirname5 } from "path";
|
|
64028
65139
|
|
|
64029
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
65140
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/application/index.js
|
|
64030
65141
|
init_default_observers();
|
|
64031
65142
|
init_event_bus();
|
|
65143
|
+
init_file_observer();
|
|
64032
65144
|
init_logger3();
|
|
64033
65145
|
|
|
64034
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
65146
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/scheduler/noop.js
|
|
64035
65147
|
class NoopSchedulerAdapter {
|
|
64036
65148
|
constructor() {}
|
|
64037
65149
|
register(_cron, _action) {}
|
|
@@ -64039,7 +65151,7 @@ class NoopSchedulerAdapter {
|
|
|
64039
65151
|
async stop() {}
|
|
64040
65152
|
}
|
|
64041
65153
|
|
|
64042
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
65154
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/scheduler/factory.js
|
|
64043
65155
|
function initScheduler(adapter, cronEntries) {
|
|
64044
65156
|
const resolved = adapter ?? new NoopSchedulerAdapter;
|
|
64045
65157
|
if (cronEntries) {
|
|
@@ -64050,7 +65162,7 @@ function initScheduler(adapter, cronEntries) {
|
|
|
64050
65162
|
return resolved;
|
|
64051
65163
|
}
|
|
64052
65164
|
|
|
64053
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
65165
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/application/plugins/builtins.js
|
|
64054
65166
|
init_logger3();
|
|
64055
65167
|
init_metrics();
|
|
64056
65168
|
init_sdk();
|
|
@@ -64143,7 +65255,7 @@ function dbPlugin(db2) {
|
|
|
64143
65255
|
};
|
|
64144
65256
|
}
|
|
64145
65257
|
|
|
64146
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
65258
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/application/plugins/host.js
|
|
64147
65259
|
init_logger3();
|
|
64148
65260
|
|
|
64149
65261
|
class PluginHost {
|
|
@@ -64231,7 +65343,7 @@ class PluginHost {
|
|
|
64231
65343
|
}
|
|
64232
65344
|
}
|
|
64233
65345
|
|
|
64234
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
65346
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/application/index.js
|
|
64235
65347
|
async function performShutdown(state, reason) {
|
|
64236
65348
|
if (state.stopped)
|
|
64237
65349
|
return;
|
|
@@ -64266,6 +65378,9 @@ async function runApplication(options) {
|
|
|
64266
65378
|
const eventsEnabled = options.config?.events?.enabled ?? true;
|
|
64267
65379
|
const eventsLifecycle = options.config?.events?.lifecycle ?? true;
|
|
64268
65380
|
const eventsDefaultObservers = options.config?.events?.defaultObservers ?? true;
|
|
65381
|
+
const eventsFileObserver = options.config?.events?.fileObserver ?? true;
|
|
65382
|
+
const fileObserverWriter = options.services?.fileObserverWriter;
|
|
65383
|
+
const eventsFilePath = options.config?.events?.filePath ?? (fileObserverWriter !== undefined ? "logs/system-events.jsonl" : undefined);
|
|
64269
65384
|
const state = {
|
|
64270
65385
|
app: undefined,
|
|
64271
65386
|
stopped: false,
|
|
@@ -64278,6 +65393,13 @@ async function runApplication(options) {
|
|
|
64278
65393
|
if (lifecycleBus && eventsDefaultObservers) {
|
|
64279
65394
|
attachDefaultObservers(lifecycleBus);
|
|
64280
65395
|
}
|
|
65396
|
+
let fileObserverAttached = false;
|
|
65397
|
+
let fileObserverPath;
|
|
65398
|
+
if (lifecycleBus && eventsFileObserver && eventsFilePath !== undefined && fileObserverWriter !== undefined) {
|
|
65399
|
+
attachFileObserver(lifecycleBus, eventsFilePath, fileObserverWriter);
|
|
65400
|
+
fileObserverAttached = true;
|
|
65401
|
+
fileObserverPath = eventsFilePath;
|
|
65402
|
+
}
|
|
64281
65403
|
const events = options.services?.events ?? options.config?.events?.bus ?? new EventBus({ lifecycleBus });
|
|
64282
65404
|
const db2 = options.services?.db;
|
|
64283
65405
|
let scheduler3;
|
|
@@ -64291,7 +65413,13 @@ async function runApplication(options) {
|
|
|
64291
65413
|
pluginHost.register(telemetryPlugin(telemetryConfig));
|
|
64292
65414
|
const resolvedConfig2 = {
|
|
64293
65415
|
logging: loggingConfig,
|
|
64294
|
-
events: {
|
|
65416
|
+
events: {
|
|
65417
|
+
enabled: eventsEnabled,
|
|
65418
|
+
lifecycle: eventsLifecycle,
|
|
65419
|
+
defaultObservers: eventsDefaultObservers,
|
|
65420
|
+
fileObserver: fileObserverAttached,
|
|
65421
|
+
...fileObserverPath !== undefined ? { filePath: fileObserverPath } : {}
|
|
65422
|
+
},
|
|
64295
65423
|
telemetry: telemetryConfig,
|
|
64296
65424
|
scheduler: schedulerConfig
|
|
64297
65425
|
};
|
|
@@ -64326,10 +65454,10 @@ async function runApplication(options) {
|
|
|
64326
65454
|
}
|
|
64327
65455
|
}
|
|
64328
65456
|
|
|
64329
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
65457
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/application-node.js
|
|
64330
65458
|
init_scheduler_node();
|
|
64331
65459
|
|
|
64332
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
65460
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
|
|
64333
65461
|
var import_api14 = __toESM(require_src(), 1);
|
|
64334
65462
|
|
|
64335
65463
|
// ../../node_modules/.bun/@opentelemetry+exporter-metrics-otlp-http@0.218.0+e40b0dfdd726a224/node_modules/@opentelemetry/exporter-metrics-otlp-http/build/esm/OTLPMetricExporterBase.js
|
|
@@ -67345,7 +68473,7 @@ class OTLPTraceExporter extends import_otlp_exporter_base2.OTLPExporterBase {
|
|
|
67345
68473
|
}), JsonTraceSerializer));
|
|
67346
68474
|
}
|
|
67347
68475
|
}
|
|
67348
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
68476
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
|
|
67349
68477
|
var import_resources2 = __toESM(require_src4(), 1);
|
|
67350
68478
|
var import_sdk_trace_node = __toESM(require_src8(), 1);
|
|
67351
68479
|
var import_semantic_conventions = __toESM(require_src2(), 1);
|
|
@@ -67396,7 +68524,7 @@ async function shutdownNodeTelemetry() {
|
|
|
67396
68524
|
await Promise.all(pending);
|
|
67397
68525
|
}
|
|
67398
68526
|
|
|
67399
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
68527
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.10+8e607bbe3266e5fa/node_modules/@gobing-ai/ts-infra/dist/application-node.js
|
|
67400
68528
|
class ConfigValidationError extends Error {
|
|
67401
68529
|
constructor(message) {
|
|
67402
68530
|
super(message);
|
|
@@ -67476,10 +68604,12 @@ async function runNodeApplication(options) {
|
|
|
67476
68604
|
const yamlLog = yamlBootstrap.logging;
|
|
67477
68605
|
const yamlTel = yamlBootstrap.telemetry;
|
|
67478
68606
|
const yamlSched = yamlBootstrap.scheduler;
|
|
68607
|
+
const yamlEvents = yamlBootstrap.events;
|
|
67479
68608
|
const databaseOpts = yamlBootstrap.database ?? {};
|
|
67480
68609
|
const loggingOpts = { ...yamlLog, ...options.config?.logging };
|
|
67481
68610
|
const telemetryOpts = { ...yamlTel, ...options.config?.telemetry };
|
|
67482
68611
|
const schedulerOpts = { ...yamlSched, ...options.config?.scheduler };
|
|
68612
|
+
const eventsOpts = { ...yamlEvents, ...options.config?.events };
|
|
67483
68613
|
const logFilePath = yamlBootstrap.logging?.filePath;
|
|
67484
68614
|
const loggingConfig = typeof logFilePath === "string" ? { ...loggingOpts, fileSink: createFileSink(logFilePath) } : loggingOpts;
|
|
67485
68615
|
const schedulerConfig = {};
|
|
@@ -67524,10 +68654,31 @@ async function runNodeApplication(options) {
|
|
|
67524
68654
|
throw new ConfigValidationError(`database.enabled is true but driver ${driver3 ? `"${driver3}"` : "is missing"} is not supported ` + `(expected "bun-sqlite"). Provide a supported driver or inject a DbAdapter via services.db.`);
|
|
67525
68655
|
}
|
|
67526
68656
|
}
|
|
68657
|
+
const injectedFileSystem = createNodeFileSystem3();
|
|
68658
|
+
const fileObserverWriter = options.services?.fileObserverWriter ?? {
|
|
68659
|
+
ensureDir: (dir) => {
|
|
68660
|
+
mkdirSync3(dir, { recursive: true });
|
|
68661
|
+
},
|
|
68662
|
+
appendFile: (path8, content) => {
|
|
68663
|
+
appendFileSync4(path8, content);
|
|
68664
|
+
}
|
|
68665
|
+
};
|
|
68666
|
+
const eventsFilePath = eventsOpts.filePath ?? injectedFileSystem.resolve("logs", "system-events.jsonl");
|
|
68667
|
+
const eventsConfig = {
|
|
68668
|
+
...eventsOpts,
|
|
68669
|
+
filePath: eventsFilePath,
|
|
68670
|
+
...eventsOpts.fileObserver === false ? {} : { fileObserver: true }
|
|
68671
|
+
};
|
|
67527
68672
|
return await runApplication({
|
|
67528
|
-
config: {
|
|
68673
|
+
config: {
|
|
68674
|
+
...options.config,
|
|
68675
|
+
logging: loggingConfig,
|
|
68676
|
+
telemetry: telemetryOpts,
|
|
68677
|
+
scheduler: schedulerConfig,
|
|
68678
|
+
events: eventsConfig
|
|
68679
|
+
},
|
|
67529
68680
|
appConfig: loadedAppConfig,
|
|
67530
|
-
services: { ...options.services, ...dbAdapter ? { db: dbAdapter } : {} },
|
|
68681
|
+
services: { ...options.services, fileObserverWriter, ...dbAdapter ? { db: dbAdapter } : {} },
|
|
67531
68682
|
start: options.start,
|
|
67532
68683
|
stop: options.stop,
|
|
67533
68684
|
plugins: plugins.length ? plugins : undefined
|
|
@@ -71198,6 +72349,20 @@ function registerAgentCommand(program2, context4) {
|
|
|
71198
72349
|
const code = await runAgentRun(prompt, context4, flags);
|
|
71199
72350
|
context4.setExitCode(code);
|
|
71200
72351
|
});
|
|
72352
|
+
agent.command("loop").description("Run the persistent self-draining loop for a team member (used by the supervisor).").requiredOption("--agent <id>", "Agent spec id / message recipient").option("--poll <ms>", "Idle poll interval in milliseconds", String(DEFAULT_LOOP_POLL_MS)).action(async (options) => {
|
|
72353
|
+
const controller = new AbortController;
|
|
72354
|
+
const onSignal = () => controller.abort();
|
|
72355
|
+
process.on("SIGINT", onSignal);
|
|
72356
|
+
process.on("SIGTERM", onSignal);
|
|
72357
|
+
try {
|
|
72358
|
+
const flags = commanderOptionsToFlags(options);
|
|
72359
|
+
const code = await runAgentLoop(context4, flags, { signal: controller.signal });
|
|
72360
|
+
context4.setExitCode(code);
|
|
72361
|
+
} finally {
|
|
72362
|
+
process.off("SIGINT", onSignal);
|
|
72363
|
+
process.off("SIGTERM", onSignal);
|
|
72364
|
+
}
|
|
72365
|
+
});
|
|
71201
72366
|
agent.command("create").description("Write a team agent spec to .spur/agents/<id>.yaml.").option("--type <agent-type>", "Agent spec type for create").option("--tags <a,b>", "Team identity tags").option("--system-prompt <text>", "Team identity system prompt").option("--name <name>", "Agent name").option("--workspace <path>", "Workspace path").option("--purpose <text>", "Team identity purpose").option("--auto-start", "Auto-start flag").option("--model <name>", "Agent model argument").option("--autonomy <level>", "Autonomy level").option("--no-identity-preamble", "Disable identity preamble").option("--json", "Output machine-readable JSON").argument("<id>", "Agent spec id").action(async (id, options) => {
|
|
71202
72367
|
const flags = commanderOptionsToFlags(options);
|
|
71203
72368
|
const code = await runAgentCreate(id, context4, flags);
|
|
@@ -71362,7 +72527,7 @@ async function drainIntoPrompt(prompt, context4, flags) {
|
|
|
71362
72527
|
const team = new TeamService(context4);
|
|
71363
72528
|
const spec = (await team.listAgentSpecs()).find((entry) => entry.id === recipient);
|
|
71364
72529
|
const flagsOut = spec === undefined ? flags : { ...flags, agent: spec.type };
|
|
71365
|
-
const inbox = await team.
|
|
72530
|
+
const inbox = await team.drainPending(recipient);
|
|
71366
72531
|
if (inbox.count === 0)
|
|
71367
72532
|
return { prompt, flags: flagsOut };
|
|
71368
72533
|
const header = inbox.messages.map((m) => `- ${m.fromId ?? "operator"}: ${m.body}`).join(`
|
|
@@ -71374,17 +72539,83 @@ ${header}`;
|
|
|
71374
72539
|
${prompt}`;
|
|
71375
72540
|
return { prompt: merged, flags: flagsOut };
|
|
71376
72541
|
}
|
|
72542
|
+
var DEFAULT_LOOP_POLL_MS = 2000;
|
|
72543
|
+
function parseLoopPoll(raw) {
|
|
72544
|
+
if (typeof raw !== "string")
|
|
72545
|
+
return DEFAULT_LOOP_POLL_MS;
|
|
72546
|
+
const n2 = Number.parseInt(raw, 10);
|
|
72547
|
+
return Number.isFinite(n2) && n2 > 0 ? n2 : DEFAULT_LOOP_POLL_MS;
|
|
72548
|
+
}
|
|
72549
|
+
function loopSleep(ms, signal) {
|
|
72550
|
+
return new Promise((resolve4) => {
|
|
72551
|
+
if (signal?.aborted) {
|
|
72552
|
+
resolve4();
|
|
72553
|
+
return;
|
|
72554
|
+
}
|
|
72555
|
+
const timer = setTimeout(resolve4, ms);
|
|
72556
|
+
signal?.addEventListener("abort", () => {
|
|
72557
|
+
clearTimeout(timer);
|
|
72558
|
+
resolve4();
|
|
72559
|
+
}, { once: true });
|
|
72560
|
+
});
|
|
72561
|
+
}
|
|
72562
|
+
async function runAgentLoop(context4, flags, runtime = {}, deps) {
|
|
72563
|
+
const recipient = typeof flags.agent === "string" ? flags.agent : "";
|
|
72564
|
+
if (recipient === "" || recipient === "auto") {
|
|
72565
|
+
context4.output.error("agent loop requires an explicit --agent <id>");
|
|
72566
|
+
return 2;
|
|
72567
|
+
}
|
|
72568
|
+
const pollMs = parseLoopPoll(flags.poll);
|
|
72569
|
+
const sleep2 = runtime.sleep ?? ((ms) => loopSleep(ms, runtime.signal));
|
|
72570
|
+
const svc = context4.agentService();
|
|
72571
|
+
let iteration = 0;
|
|
72572
|
+
while (!runtime.signal?.aborted && (runtime.maxIterations === undefined || iteration < runtime.maxIterations)) {
|
|
72573
|
+
const { prompt, flags: rewritten } = await drainIntoPrompt(undefined, context4, { ...flags, drain: true });
|
|
72574
|
+
if (prompt !== undefined) {
|
|
72575
|
+
await svc.run(prompt, rewritten, deps);
|
|
72576
|
+
} else {
|
|
72577
|
+
await sleep2(pollMs);
|
|
72578
|
+
}
|
|
72579
|
+
iteration++;
|
|
72580
|
+
}
|
|
72581
|
+
return 0;
|
|
72582
|
+
}
|
|
71377
72583
|
|
|
71378
72584
|
// src/commands/feature.ts
|
|
71379
72585
|
init_src3();
|
|
71380
72586
|
|
|
72587
|
+
// src/planning-emitter.ts
|
|
72588
|
+
init_src3();
|
|
72589
|
+
init_src2();
|
|
72590
|
+
function makeWarnLogger(context4) {
|
|
72591
|
+
return {
|
|
72592
|
+
warn: (msg, data) => {
|
|
72593
|
+
context4.output.error(`${msg}${data ? ` ${JSON.stringify(data)}` : ""}`);
|
|
72594
|
+
}
|
|
72595
|
+
};
|
|
72596
|
+
}
|
|
72597
|
+
function makePlanningEmitter(context4) {
|
|
72598
|
+
let cached2;
|
|
72599
|
+
const logger3 = makeWarnLogger(context4);
|
|
72600
|
+
return {
|
|
72601
|
+
async emit(event2) {
|
|
72602
|
+
try {
|
|
72603
|
+
cached2 ??= new SystemEventEmitter(new SystemEventDao(await context4.getDb()), logger3);
|
|
72604
|
+
await cached2.emit(event2);
|
|
72605
|
+
} catch (error51) {
|
|
72606
|
+
context4.output.error(`system_events emitter: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
72607
|
+
}
|
|
72608
|
+
}
|
|
72609
|
+
};
|
|
72610
|
+
}
|
|
72611
|
+
|
|
71381
72612
|
// src/workflow/make-lifecycle-adapter.ts
|
|
71382
72613
|
init_src3();
|
|
71383
72614
|
init_loader();
|
|
71384
72615
|
init_src2();
|
|
71385
|
-
import { existsSync as
|
|
72616
|
+
import { existsSync as existsSync8 } from "fs";
|
|
71386
72617
|
import { homedir as homedir4 } from "os";
|
|
71387
|
-
import { join as
|
|
72618
|
+
import { join as join14, resolve as resolve4 } from "path";
|
|
71388
72619
|
|
|
71389
72620
|
// src/workflow/resolve-spur-bin.ts
|
|
71390
72621
|
import { basename as basename2 } from "path";
|
|
@@ -71402,23 +72633,23 @@ function resolveSpurBin() {
|
|
|
71402
72633
|
}
|
|
71403
72634
|
|
|
71404
72635
|
// src/workflow/make-lifecycle-adapter.ts
|
|
71405
|
-
var GLOBAL_CONFIG_DIR =
|
|
72636
|
+
var GLOBAL_CONFIG_DIR = join14(".config", "spur");
|
|
71406
72637
|
function globalConfigRoot(context4) {
|
|
71407
72638
|
const override = context4.env.SPUR_GLOBAL_RULES_DIR;
|
|
71408
|
-
return override !== undefined && override.length > 0 ? resolve4(context4.cwd, override) :
|
|
72639
|
+
return override !== undefined && override.length > 0 ? resolve4(context4.cwd, override) : join14(homedir4(), GLOBAL_CONFIG_DIR);
|
|
71409
72640
|
}
|
|
71410
72641
|
function resolveWorkflowPath(context4, profile) {
|
|
71411
72642
|
const bundledRoot = bundledConfigRoot();
|
|
71412
72643
|
if (bundledRoot !== null) {
|
|
71413
|
-
const bundledPath =
|
|
71414
|
-
if (
|
|
72644
|
+
const bundledPath = join14(bundledRoot, "workflows", `${profile.workflowName}.yaml`);
|
|
72645
|
+
if (existsSync8(bundledPath))
|
|
71415
72646
|
return bundledPath;
|
|
71416
72647
|
}
|
|
71417
|
-
const projectPath =
|
|
71418
|
-
if (
|
|
72648
|
+
const projectPath = join14(context4.cwd, ".spur", "workflows", `${profile.workflowName}.yaml`);
|
|
72649
|
+
if (existsSync8(projectPath))
|
|
71419
72650
|
return projectPath;
|
|
71420
|
-
const globalPath =
|
|
71421
|
-
if (
|
|
72651
|
+
const globalPath = join14(globalConfigRoot(context4), "workflows", `${profile.workflowName}.yaml`);
|
|
72652
|
+
if (existsSync8(globalPath))
|
|
71422
72653
|
return globalPath;
|
|
71423
72654
|
return null;
|
|
71424
72655
|
}
|
|
@@ -71701,7 +72932,8 @@ async function makeService(context4, folderOverride) {
|
|
|
71701
72932
|
const lifecycle = makeLifecycleAdapter(context4, FEATURE_LIFECYCLE_PROFILE);
|
|
71702
72933
|
const writeService = new PlanningWriteService({
|
|
71703
72934
|
fs: context4.fs,
|
|
71704
|
-
...lifecycle ? { lifecycle } : {}
|
|
72935
|
+
...lifecycle ? { lifecycle } : {},
|
|
72936
|
+
emitter: makePlanningEmitter(context4)
|
|
71705
72937
|
});
|
|
71706
72938
|
return new FeatureService({ fs: context4.fs, writeService, featuresDir, tasksDir });
|
|
71707
72939
|
}
|
|
@@ -71771,13 +73003,13 @@ init_loader();
|
|
|
71771
73003
|
init_src2();
|
|
71772
73004
|
init_dist10();
|
|
71773
73005
|
import { homedir as homedir5 } from "os";
|
|
71774
|
-
import { join as
|
|
73006
|
+
import { join as join15, resolve as resolve5 } from "path";
|
|
71775
73007
|
|
|
71776
73008
|
// src/config.ts
|
|
71777
73009
|
var CLI_CONFIG = {
|
|
71778
73010
|
binaryName: "spur",
|
|
71779
73011
|
binaryLabel: "spur",
|
|
71780
|
-
binaryVersion: "0.3.
|
|
73012
|
+
binaryVersion: "0.3.11",
|
|
71781
73013
|
configDir: ".spur",
|
|
71782
73014
|
configFile: ".spur/config.yaml",
|
|
71783
73015
|
databaseFile: ".spur/spur.db"
|
|
@@ -71828,8 +73060,8 @@ var SCAFFOLD_MANIFEST = [
|
|
|
71828
73060
|
];
|
|
71829
73061
|
|
|
71830
73062
|
// src/commands/init.ts
|
|
71831
|
-
var GLOBAL_CONFIG_DIR2 =
|
|
71832
|
-
var GLOBAL_RULES_DIR2 =
|
|
73063
|
+
var GLOBAL_CONFIG_DIR2 = join15(".config", "spur");
|
|
73064
|
+
var GLOBAL_RULES_DIR2 = join15(GLOBAL_CONFIG_DIR2, "rules");
|
|
71833
73065
|
var GLOBAL_CONFIG_EXAMPLE = "config.example.yaml";
|
|
71834
73066
|
var GLOBAL_CONFIG_FILE2 = "config.yaml";
|
|
71835
73067
|
var INDEXED_CONTEXT_MARKER = "## Indexed context";
|
|
@@ -71856,7 +73088,7 @@ If \`.spur/context/\` is absent, proceed normally. Never block work on its absen
|
|
|
71856
73088
|
`;
|
|
71857
73089
|
function globalRulesRoot(context4) {
|
|
71858
73090
|
const override = context4.env.SPUR_GLOBAL_RULES_DIR;
|
|
71859
|
-
return override !== undefined && override.length > 0 ? resolve5(context4.cwd, override) :
|
|
73091
|
+
return override !== undefined && override.length > 0 ? resolve5(context4.cwd, override) : join15(homedir5(), GLOBAL_RULES_DIR2);
|
|
71860
73092
|
}
|
|
71861
73093
|
async function writeIfNew(context4, path9, content, force, result) {
|
|
71862
73094
|
if (!force && await context4.fs.exists(path9)) {
|
|
@@ -71873,11 +73105,11 @@ async function seedGlobalRules(context4) {
|
|
|
71873
73105
|
const target = globalRulesRoot(context4);
|
|
71874
73106
|
let written = 0;
|
|
71875
73107
|
for (const relPath of await listBundledRuleFiles()) {
|
|
71876
|
-
const destination =
|
|
73108
|
+
const destination = join15(target, relPath);
|
|
71877
73109
|
if (await context4.fs.exists(destination))
|
|
71878
73110
|
continue;
|
|
71879
|
-
await context4.fs.ensureDir(
|
|
71880
|
-
await context4.fs.writeFile(destination, await context4.fs.readFile(
|
|
73111
|
+
await context4.fs.ensureDir(join15(target, ...relPath.split("/").slice(0, -1)));
|
|
73112
|
+
await context4.fs.writeFile(destination, await context4.fs.readFile(join15(source, relPath)));
|
|
71881
73113
|
written += 1;
|
|
71882
73114
|
}
|
|
71883
73115
|
return written;
|
|
@@ -71887,20 +73119,20 @@ async function seedGlobalConfig(context4) {
|
|
|
71887
73119
|
if (source === null)
|
|
71888
73120
|
return 0;
|
|
71889
73121
|
const globalOverride = context4.env.SPUR_GLOBAL_RULES_DIR;
|
|
71890
|
-
const target = globalOverride !== undefined && globalOverride.length > 0 ? resolve5(context4.cwd, globalOverride) :
|
|
73122
|
+
const target = globalOverride !== undefined && globalOverride.length > 0 ? resolve5(context4.cwd, globalOverride) : join15(homedir5(), GLOBAL_CONFIG_DIR2);
|
|
71891
73123
|
let written = 0;
|
|
71892
73124
|
for (const relPath of listBundledConfigFiles()) {
|
|
71893
73125
|
if (relPath === GLOBAL_CONFIG_EXAMPLE)
|
|
71894
73126
|
continue;
|
|
71895
|
-
const destination =
|
|
73127
|
+
const destination = join15(target, relPath);
|
|
71896
73128
|
if (await context4.fs.exists(destination))
|
|
71897
73129
|
continue;
|
|
71898
|
-
await context4.fs.ensureDir(
|
|
71899
|
-
await context4.fs.writeFile(destination, await context4.fs.readFile(
|
|
73130
|
+
await context4.fs.ensureDir(join15(target, ...relPath.split("/").slice(0, -1)));
|
|
73131
|
+
await context4.fs.writeFile(destination, await context4.fs.readFile(join15(source, relPath)));
|
|
71900
73132
|
written += 1;
|
|
71901
73133
|
}
|
|
71902
|
-
const examplePath =
|
|
71903
|
-
const globalConfigPath =
|
|
73134
|
+
const examplePath = join15(source, GLOBAL_CONFIG_EXAMPLE);
|
|
73135
|
+
const globalConfigPath = join15(target, GLOBAL_CONFIG_FILE2);
|
|
71904
73136
|
if (await context4.fs.exists(examplePath) && !await context4.fs.exists(globalConfigPath)) {
|
|
71905
73137
|
await context4.fs.ensureDir(target);
|
|
71906
73138
|
await context4.fs.writeFile(globalConfigPath, await context4.fs.readFile(examplePath));
|
|
@@ -71914,7 +73146,7 @@ function registerInitCommand(program2, context4) {
|
|
|
71914
73146
|
const force = options.force === true;
|
|
71915
73147
|
const minimal = options.minimal === true;
|
|
71916
73148
|
const projectName = options.name ?? "default";
|
|
71917
|
-
const configPath =
|
|
73149
|
+
const configPath = join15(context4.cwd, CLI_CONFIG.configFile);
|
|
71918
73150
|
if (!force && await context4.fs.exists(configPath)) {
|
|
71919
73151
|
const message = `Already initialized: ${CLI_CONFIG.configFile}. Use --force to overwrite.`;
|
|
71920
73152
|
context4.output.write(json3 ? toJson2({ ok: false, reason: "already-initialized", config: CLI_CONFIG.configFile }) : message);
|
|
@@ -71949,13 +73181,13 @@ function registerInitCommand(program2, context4) {
|
|
|
71949
73181
|
].join(`
|
|
71950
73182
|
`)}
|
|
71951
73183
|
`;
|
|
71952
|
-
await context4.fs.ensureDir(
|
|
73184
|
+
await context4.fs.ensureDir(join15(context4.cwd, CLI_CONFIG.configDir));
|
|
71953
73185
|
await context4.fs.writeFile(configPath, configYaml);
|
|
71954
73186
|
result.created.push(configPath);
|
|
71955
|
-
const agentsDir =
|
|
73187
|
+
const agentsDir = join15(context4.cwd, CLI_CONFIG.configDir, "agents");
|
|
71956
73188
|
await context4.fs.ensureDir(agentsDir);
|
|
71957
|
-
await writeIfNew(context4,
|
|
71958
|
-
const gitignorePath =
|
|
73189
|
+
await writeIfNew(context4, join15(agentsDir, ".gitkeep"), "", force, result);
|
|
73190
|
+
const gitignorePath = join15(context4.cwd, ".gitignore");
|
|
71959
73191
|
const contextEntry = ".spur/context/";
|
|
71960
73192
|
if (await context4.fs.exists(gitignorePath)) {
|
|
71961
73193
|
const existing = await context4.fs.readFile(gitignorePath);
|
|
@@ -71975,20 +73207,20 @@ ${contextEntry}
|
|
|
71975
73207
|
const configRoot = bundledConfigRoot();
|
|
71976
73208
|
if (configRoot !== null) {
|
|
71977
73209
|
for (const relPath of listBundledProjectSeedFiles()) {
|
|
71978
|
-
const sourcePath =
|
|
73210
|
+
const sourcePath = join15(configRoot, relPath);
|
|
71979
73211
|
if (!await context4.fs.exists(sourcePath))
|
|
71980
73212
|
continue;
|
|
71981
|
-
const targetPath =
|
|
71982
|
-
await context4.fs.ensureDir(
|
|
73213
|
+
const targetPath = join15(context4.cwd, CLI_CONFIG.configDir, relPath);
|
|
73214
|
+
await context4.fs.ensureDir(join15(targetPath, ".."));
|
|
71983
73215
|
await writeIfNew(context4, targetPath, await context4.fs.readFile(sourcePath), force, result);
|
|
71984
73216
|
}
|
|
71985
73217
|
for (const entry of SCAFFOLD_MANIFEST) {
|
|
71986
|
-
const sourcePath =
|
|
73218
|
+
const sourcePath = join15(configRoot, entry.source);
|
|
71987
73219
|
if (!await context4.fs.exists(sourcePath))
|
|
71988
73220
|
continue;
|
|
71989
|
-
const baseDir = entry.root === true ? context4.cwd :
|
|
71990
|
-
const targetPath =
|
|
71991
|
-
await context4.fs.ensureDir(
|
|
73221
|
+
const baseDir = entry.root === true ? context4.cwd : join15(context4.cwd, CLI_CONFIG.configDir);
|
|
73222
|
+
const targetPath = join15(baseDir, entry.target);
|
|
73223
|
+
await context4.fs.ensureDir(join15(targetPath, ".."));
|
|
71992
73224
|
const entryForce = entry.preserve === true ? false : force;
|
|
71993
73225
|
let body = await context4.fs.readFile(sourcePath);
|
|
71994
73226
|
if (entry.target === "AGENTS.md") {
|
|
@@ -71998,7 +73230,7 @@ ${contextEntry}
|
|
|
71998
73230
|
}
|
|
71999
73231
|
}
|
|
72000
73232
|
}
|
|
72001
|
-
const agentsMdPath =
|
|
73233
|
+
const agentsMdPath = join15(context4.cwd, "AGENTS.md");
|
|
72002
73234
|
if (await context4.fs.exists(agentsMdPath)) {
|
|
72003
73235
|
const existing = await context4.fs.readFile(agentsMdPath);
|
|
72004
73236
|
if (!existing.includes(INDEXED_CONTEXT_MARKER)) {
|
|
@@ -72176,10 +73408,10 @@ function parseInterval2(raw) {
|
|
|
72176
73408
|
|
|
72177
73409
|
// src/commands/migrate.ts
|
|
72178
73410
|
init_src2();
|
|
72179
|
-
import { join as
|
|
73411
|
+
import { join as join16 } from "path";
|
|
72180
73412
|
function registerMigrateCommand(program2, context4) {
|
|
72181
73413
|
program2.command("migrate").summary("apply CLI-owned schema migrations").option("--json", "Output machine-readable JSON").action(async (options) => {
|
|
72182
|
-
const migrations = await loadSqlMigrations(
|
|
73414
|
+
const migrations = await loadSqlMigrations(join16(context4.cwd, "drizzle")).catch(() => {
|
|
72183
73415
|
return;
|
|
72184
73416
|
});
|
|
72185
73417
|
const applied = await applyCliMigrations(await context4.getDb(), migrations);
|
|
@@ -72431,7 +73663,7 @@ function formatTraceDetail(detail) {
|
|
|
72431
73663
|
|
|
72432
73664
|
// src/commands/serve.ts
|
|
72433
73665
|
init_src();
|
|
72434
|
-
import { join as
|
|
73666
|
+
import { join as join20 } from "path";
|
|
72435
73667
|
|
|
72436
73668
|
// ../server/src/index.ts
|
|
72437
73669
|
init_src();
|
|
@@ -72441,11 +73673,11 @@ init_src3();
|
|
|
72441
73673
|
init_src();
|
|
72442
73674
|
init_loader();
|
|
72443
73675
|
init_src2();
|
|
72444
|
-
import { dirname as dirname12, isAbsolute as isAbsolute3, join as
|
|
73676
|
+
import { dirname as dirname12, isAbsolute as isAbsolute3, join as join19 } from "path";
|
|
72445
73677
|
init_dist5();
|
|
72446
73678
|
|
|
72447
73679
|
// ../server/src/bootstrap.ts
|
|
72448
|
-
import { join as
|
|
73680
|
+
import { join as join17 } from "path";
|
|
72449
73681
|
|
|
72450
73682
|
// ../../node_modules/.bun/radash@12.1.1/node_modules/radash/dist/esm/async.mjs
|
|
72451
73683
|
var guard = (func, shouldGuard) => {
|
|
@@ -78549,23 +79781,128 @@ function parseLimit(raw2, fallback) {
|
|
|
78549
79781
|
|
|
78550
79782
|
// ../server/src/modules/observability/index.ts
|
|
78551
79783
|
init_src3();
|
|
79784
|
+
var ledgerWatcher;
|
|
79785
|
+
var watcherPath;
|
|
79786
|
+
function getLedgerWatcher(path9) {
|
|
79787
|
+
if (!ledgerWatcher || watcherPath !== path9) {
|
|
79788
|
+
ledgerWatcher?.stop();
|
|
79789
|
+
ledgerWatcher = new TokenLedgerWatcher({ ledgerPath: path9 });
|
|
79790
|
+
watcherPath = path9;
|
|
79791
|
+
ledgerWatcher.start();
|
|
79792
|
+
}
|
|
79793
|
+
return ledgerWatcher;
|
|
79794
|
+
}
|
|
79795
|
+
function toolUseSsePayload(event2) {
|
|
79796
|
+
return {
|
|
79797
|
+
type: "tool-use",
|
|
79798
|
+
occurredAt: event2.ts,
|
|
79799
|
+
event: event2
|
|
79800
|
+
};
|
|
79801
|
+
}
|
|
79802
|
+
function handleProcesses(ctx) {
|
|
79803
|
+
return async (c3) => {
|
|
79804
|
+
try {
|
|
79805
|
+
const snapshot = await ctx.processInventory().snapshot();
|
|
79806
|
+
return c3.json(snapshot);
|
|
79807
|
+
} catch (err) {
|
|
79808
|
+
if (err instanceof UnsupportedProcessPlatformError) {
|
|
79809
|
+
return c3.json({ error: err.message, code: err.code }, 501);
|
|
79810
|
+
}
|
|
79811
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
79812
|
+
return c3.json({ error: message }, 500);
|
|
79813
|
+
}
|
|
79814
|
+
};
|
|
79815
|
+
}
|
|
79816
|
+
function handleToolUseGet(ctx) {
|
|
79817
|
+
return (c3) => {
|
|
79818
|
+
try {
|
|
79819
|
+
const limitParam = c3.req.query("limit");
|
|
79820
|
+
let limitRaw;
|
|
79821
|
+
if (limitParam !== undefined) {
|
|
79822
|
+
const parsed = Number.parseInt(limitParam, 10);
|
|
79823
|
+
if (!Number.isNaN(parsed))
|
|
79824
|
+
limitRaw = parsed;
|
|
79825
|
+
}
|
|
79826
|
+
const before = c3.req.query("before") ?? undefined;
|
|
79827
|
+
const limit = clampToolUseLimit(limitRaw);
|
|
79828
|
+
const snapshot = ctx.tokenLedger().snapshot({ limit, before });
|
|
79829
|
+
return c3.json(snapshot);
|
|
79830
|
+
} catch (err) {
|
|
79831
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
79832
|
+
return c3.json({ error: message }, 500);
|
|
79833
|
+
}
|
|
79834
|
+
};
|
|
79835
|
+
}
|
|
79836
|
+
function handleToolUseStream(ctx) {
|
|
79837
|
+
return (c3) => {
|
|
79838
|
+
const closed = { current: false };
|
|
79839
|
+
let heartbeatInterval;
|
|
79840
|
+
let unsubscribe;
|
|
79841
|
+
const signal = c3.req.raw.signal;
|
|
79842
|
+
let closeController = () => {};
|
|
79843
|
+
const teardown = () => {
|
|
79844
|
+
if (closed.current)
|
|
79845
|
+
return;
|
|
79846
|
+
closed.current = true;
|
|
79847
|
+
if (heartbeatInterval)
|
|
79848
|
+
clearInterval(heartbeatInterval);
|
|
79849
|
+
try {
|
|
79850
|
+
unsubscribe?.();
|
|
79851
|
+
} catch {}
|
|
79852
|
+
signal.removeEventListener("abort", teardown);
|
|
79853
|
+
closeController();
|
|
79854
|
+
};
|
|
79855
|
+
const stream = new ReadableStream({
|
|
79856
|
+
start(controller) {
|
|
79857
|
+
const encoder = new TextEncoder;
|
|
79858
|
+
closeController = () => {
|
|
79859
|
+
try {
|
|
79860
|
+
controller.close();
|
|
79861
|
+
} catch {}
|
|
79862
|
+
};
|
|
79863
|
+
if (signal.aborted) {
|
|
79864
|
+
teardown();
|
|
79865
|
+
return;
|
|
79866
|
+
}
|
|
79867
|
+
signal.addEventListener("abort", teardown);
|
|
79868
|
+
heartbeatInterval = setInterval(sendSseKeepalive, 15000, closed, controller, encoder);
|
|
79869
|
+
enqueueSseFrame(closed, controller, encoder, {
|
|
79870
|
+
type: "connected",
|
|
79871
|
+
occurredAt: new Date().toISOString()
|
|
79872
|
+
});
|
|
79873
|
+
try {
|
|
79874
|
+
const path9 = ctx.tokenLedger().path;
|
|
79875
|
+
const watcher = getLedgerWatcher(path9);
|
|
79876
|
+
unsubscribe = watcher.subscribe((event2) => {
|
|
79877
|
+
if (!enqueueSseFrame(closed, controller, encoder, toolUseSsePayload(event2)))
|
|
79878
|
+
teardown();
|
|
79879
|
+
});
|
|
79880
|
+
} catch {
|
|
79881
|
+
enqueueSseFrame(closed, controller, encoder, {
|
|
79882
|
+
type: "error",
|
|
79883
|
+
error: "ledger watch unavailable",
|
|
79884
|
+
occurredAt: new Date().toISOString()
|
|
79885
|
+
});
|
|
79886
|
+
}
|
|
79887
|
+
},
|
|
79888
|
+
cancel() {
|
|
79889
|
+
teardown();
|
|
79890
|
+
}
|
|
79891
|
+
});
|
|
79892
|
+
return c3.newResponse(stream, 200, {
|
|
79893
|
+
"Content-Type": "text/event-stream",
|
|
79894
|
+
"Cache-Control": "no-cache"
|
|
79895
|
+
});
|
|
79896
|
+
};
|
|
79897
|
+
}
|
|
78552
79898
|
var observabilityModule = {
|
|
78553
79899
|
name: "observability",
|
|
78554
79900
|
mount(app, ctx) {
|
|
78555
79901
|
if (!ctx)
|
|
78556
79902
|
return;
|
|
78557
|
-
app.get("/api/observability/processes",
|
|
78558
|
-
|
|
78559
|
-
|
|
78560
|
-
return c3.json(snapshot);
|
|
78561
|
-
} catch (err) {
|
|
78562
|
-
if (err instanceof UnsupportedProcessPlatformError) {
|
|
78563
|
-
return c3.json({ error: err.message, code: err.code }, 501);
|
|
78564
|
-
}
|
|
78565
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
78566
|
-
return c3.json({ error: message }, 500);
|
|
78567
|
-
}
|
|
78568
|
-
});
|
|
79903
|
+
app.get("/api/observability/processes", handleProcesses(ctx));
|
|
79904
|
+
app.get("/api/observability/tool-use", handleToolUseGet(ctx));
|
|
79905
|
+
app.get("/api/observability/tool-use/stream", handleToolUseStream(ctx));
|
|
78569
79906
|
}
|
|
78570
79907
|
};
|
|
78571
79908
|
|
|
@@ -78686,9 +80023,29 @@ var teamModule = {
|
|
|
78686
80023
|
pid: p2.pid,
|
|
78687
80024
|
status: p2.status,
|
|
78688
80025
|
startedAt: p2.startedAt,
|
|
78689
|
-
exitCode: p2.exitCode ?? null
|
|
80026
|
+
exitCode: p2.exitCode ?? null,
|
|
80027
|
+
teamId: p2.teamId ?? null
|
|
78690
80028
|
}));
|
|
78691
|
-
|
|
80029
|
+
const executions = ctx.processRegistry().listExecutions().map((e) => ({
|
|
80030
|
+
id: e.id,
|
|
80031
|
+
label: e.label ?? e.command,
|
|
80032
|
+
command: e.command,
|
|
80033
|
+
args: [...e.args],
|
|
80034
|
+
pid: e.pid ?? null,
|
|
80035
|
+
status: e.status,
|
|
80036
|
+
startedAt: e.startedAt,
|
|
80037
|
+
exitedAt: e.exitedAt ?? null,
|
|
80038
|
+
exitCode: e.exitCode ?? null,
|
|
80039
|
+
source: e.source,
|
|
80040
|
+
teamId: e.teamId ?? null,
|
|
80041
|
+
agentId: e.agentId ?? null
|
|
80042
|
+
}));
|
|
80043
|
+
return c3.json({
|
|
80044
|
+
processes,
|
|
80045
|
+
count: processes.length,
|
|
80046
|
+
executions,
|
|
80047
|
+
executionsCount: executions.length
|
|
80048
|
+
});
|
|
78692
80049
|
});
|
|
78693
80050
|
app.post("/api/team/agents/:id/start", async (c3) => {
|
|
78694
80051
|
const id = c3.req.param("id");
|
|
@@ -78805,6 +80162,79 @@ var teamModule = {
|
|
|
78805
80162
|
"Cache-Control": "no-cache"
|
|
78806
80163
|
});
|
|
78807
80164
|
});
|
|
80165
|
+
app.get("/api/team/teams", async (c3) => {
|
|
80166
|
+
if (!ctx.teamService)
|
|
80167
|
+
return c3.json({ error: "team API requires Bun server context" }, 503);
|
|
80168
|
+
const svc = ctx.teamService();
|
|
80169
|
+
const supervisor = ctx.supervisor();
|
|
80170
|
+
const teams = await svc.listTeams();
|
|
80171
|
+
const processes = supervisor.list();
|
|
80172
|
+
const enriched = teams.map((team) => ({
|
|
80173
|
+
teamId: team.teamId,
|
|
80174
|
+
name: team.name,
|
|
80175
|
+
members: team.specs.map((spec) => {
|
|
80176
|
+
const proc = processes.find((p2) => p2.agentId === spec.id);
|
|
80177
|
+
return {
|
|
80178
|
+
id: spec.id,
|
|
80179
|
+
type: spec.type,
|
|
80180
|
+
status: proc?.status ?? "unknown",
|
|
80181
|
+
autoStart: spec.autoStart === true,
|
|
80182
|
+
...proc?.pid !== undefined ? { pid: proc.pid } : {}
|
|
80183
|
+
};
|
|
80184
|
+
})
|
|
80185
|
+
}));
|
|
80186
|
+
return c3.json({ teams: enriched, count: enriched.length });
|
|
80187
|
+
});
|
|
80188
|
+
app.post("/api/team/:team/up", async (c3) => {
|
|
80189
|
+
if (!ctx.teamService)
|
|
80190
|
+
return c3.json({ error: "team API requires Bun server context" }, 503);
|
|
80191
|
+
const teamId = c3.req.param("team");
|
|
80192
|
+
const check2 = c3.req.query("check") === "true";
|
|
80193
|
+
const svc = ctx.teamService();
|
|
80194
|
+
const materialized = await svc.materializeTeam(teamId, { check: check2 });
|
|
80195
|
+
if (check2) {
|
|
80196
|
+
return c3.json({ materialized, started: [] });
|
|
80197
|
+
}
|
|
80198
|
+
const supervisor = ctx.supervisor();
|
|
80199
|
+
const autostartIds = new Set((await svc.listAgentSpecs()).filter((spec) => spec.autoStart === true).map((spec) => spec.id));
|
|
80200
|
+
const started = [];
|
|
80201
|
+
for (const id of materialized.upserted) {
|
|
80202
|
+
if (!autostartIds.has(id))
|
|
80203
|
+
continue;
|
|
80204
|
+
try {
|
|
80205
|
+
const entry = await supervisor.start(id);
|
|
80206
|
+
started.push({ id, ok: true, ...entry.pid !== null ? { pid: entry.pid } : {} });
|
|
80207
|
+
} catch {
|
|
80208
|
+
started.push({ id, ok: false });
|
|
80209
|
+
}
|
|
80210
|
+
}
|
|
80211
|
+
return c3.json({ materialized, started });
|
|
80212
|
+
});
|
|
80213
|
+
app.post("/api/team/:team/down", async (c3) => {
|
|
80214
|
+
if (!ctx.teamService)
|
|
80215
|
+
return c3.json({ error: "team API requires Bun server context" }, 503);
|
|
80216
|
+
const teamId = c3.req.param("team");
|
|
80217
|
+
const purge = c3.req.query("purge") === "true";
|
|
80218
|
+
const svc = ctx.teamService();
|
|
80219
|
+
const supervisor = ctx.supervisor();
|
|
80220
|
+
const teams = await svc.listTeams();
|
|
80221
|
+
const team = teams.find((t) => t.teamId === teamId);
|
|
80222
|
+
const stopped = [];
|
|
80223
|
+
if (team) {
|
|
80224
|
+
for (const spec of team.specs) {
|
|
80225
|
+
const proc = supervisor.get(spec.id);
|
|
80226
|
+
if (proc?.status === "running") {
|
|
80227
|
+
await supervisor.stop(spec.id);
|
|
80228
|
+
stopped.push(spec.id);
|
|
80229
|
+
}
|
|
80230
|
+
}
|
|
80231
|
+
}
|
|
80232
|
+
const result = await svc.teardownTeam(teamId, { purge });
|
|
80233
|
+
return c3.json({ stopped, purged: result.purged });
|
|
80234
|
+
});
|
|
80235
|
+
app.get("/api/team/health", (c3) => {
|
|
80236
|
+
return c3.json({ ok: true });
|
|
80237
|
+
});
|
|
78808
80238
|
}
|
|
78809
80239
|
};
|
|
78810
80240
|
|
|
@@ -80803,7 +82233,7 @@ function createApp(appRt, opts) {
|
|
|
80803
82233
|
app.use("*", async (c3, next) => {
|
|
80804
82234
|
const pathname = c3.req.path === "/" ? "/index.html" : c3.req.path;
|
|
80805
82235
|
try {
|
|
80806
|
-
const file2 = Bun.file(
|
|
82236
|
+
const file2 = Bun.file(join17(webDistPath, pathname));
|
|
80807
82237
|
if (await file2.exists()) {
|
|
80808
82238
|
const headers = new Headers({ "content-type": file2.type });
|
|
80809
82239
|
return new Response(file2.stream(), { headers });
|
|
@@ -80816,7 +82246,7 @@ function createApp(appRt, opts) {
|
|
|
80816
82246
|
return c3.json({ error: "Not Found" }, 404);
|
|
80817
82247
|
}
|
|
80818
82248
|
try {
|
|
80819
|
-
const indexFile = Bun.file(
|
|
82249
|
+
const indexFile = Bun.file(join17(webDistPath, "index.html"));
|
|
80820
82250
|
if (await indexFile.exists()) {
|
|
80821
82251
|
return new Response(indexFile.stream(), {
|
|
80822
82252
|
headers: { "content-type": "text/html; charset=utf-8" }
|
|
@@ -80837,7 +82267,7 @@ init_src3();
|
|
|
80837
82267
|
init_src();
|
|
80838
82268
|
init_src2();
|
|
80839
82269
|
init_dist5();
|
|
80840
|
-
import { dirname as dirname11, join as
|
|
82270
|
+
import { dirname as dirname11, join as join18 } from "path";
|
|
80841
82271
|
var NOOP_OUTPUT = { write: (_s) => {}, error: (_s) => {} };
|
|
80842
82272
|
|
|
80843
82273
|
class LazyPlanningEventEmitter {
|
|
@@ -80872,7 +82302,7 @@ class NotConfiguredError extends Error {
|
|
|
80872
82302
|
function createServerContext(appRt, options) {
|
|
80873
82303
|
const cwd = options.cwd;
|
|
80874
82304
|
const fs3 = options.fs;
|
|
80875
|
-
const dbUrl = options.dbUrl ??
|
|
82305
|
+
const dbUrl = options.dbUrl ?? join18(cwd, DEFAULT_DATABASE_URL);
|
|
80876
82306
|
const eventsBus = options.eventsBus ?? appRt.events;
|
|
80877
82307
|
const jobQueueEnabled = options.jobQueueEnabled ?? false;
|
|
80878
82308
|
const folders = options.folders ?? DEFAULT_PLANNING_FOLDERS;
|
|
@@ -80890,6 +82320,8 @@ function createServerContext(appRt, options) {
|
|
|
80890
82320
|
let teamSvc;
|
|
80891
82321
|
let supervisorSvc;
|
|
80892
82322
|
let processInventorySvc;
|
|
82323
|
+
let processRegistrySvc;
|
|
82324
|
+
let tokenLedgerSvc;
|
|
80893
82325
|
let agentSvc;
|
|
80894
82326
|
let ruleSvc;
|
|
80895
82327
|
let workflowSvc;
|
|
@@ -80959,9 +82391,13 @@ function createServerContext(appRt, options) {
|
|
|
80959
82391
|
}
|
|
80960
82392
|
return teamSvc;
|
|
80961
82393
|
},
|
|
82394
|
+
processRegistry() {
|
|
82395
|
+
processRegistrySvc ??= createInMemoryProcessRegistry2();
|
|
82396
|
+
return processRegistrySvc;
|
|
82397
|
+
},
|
|
80962
82398
|
supervisor() {
|
|
80963
82399
|
if (!supervisorSvc) {
|
|
80964
|
-
const pe = new
|
|
82400
|
+
const pe = new NodeProcessExecutor3({ registry: this.processRegistry() });
|
|
80965
82401
|
supervisorSvc = new SupervisorService({
|
|
80966
82402
|
processExecutor: pe,
|
|
80967
82403
|
eventBus: bridgeEventBus(eventsBus),
|
|
@@ -80980,12 +82416,19 @@ function createServerContext(appRt, options) {
|
|
|
80980
82416
|
}
|
|
80981
82417
|
return processInventorySvc;
|
|
80982
82418
|
},
|
|
82419
|
+
tokenLedger() {
|
|
82420
|
+
if (!tokenLedgerSvc) {
|
|
82421
|
+
tokenLedgerSvc = new TokenLedgerService({ cwd });
|
|
82422
|
+
}
|
|
82423
|
+
return tokenLedgerSvc;
|
|
82424
|
+
},
|
|
80983
82425
|
agentService() {
|
|
80984
82426
|
agentSvc ??= new AgentService({
|
|
80985
82427
|
cwd,
|
|
80986
82428
|
env: options.env ?? {},
|
|
80987
82429
|
output: NOOP_OUTPUT,
|
|
80988
|
-
events: bridgeEventBus(eventsBus)
|
|
82430
|
+
events: bridgeEventBus(eventsBus),
|
|
82431
|
+
processRegistry: this.processRegistry()
|
|
80989
82432
|
});
|
|
80990
82433
|
return agentSvc;
|
|
80991
82434
|
},
|
|
@@ -81159,15 +82602,15 @@ async function runTaskActionJob(ctx, env, payload, createAgentService = createTa
|
|
|
81159
82602
|
}
|
|
81160
82603
|
}
|
|
81161
82604
|
async function resolveWebDistPath(configuredPath) {
|
|
81162
|
-
const candidates = configuredPath && configuredPath.trim() !== "" ? [isAbsolute3(configuredPath) ? configuredPath :
|
|
81163
|
-
|
|
81164
|
-
|
|
81165
|
-
|
|
81166
|
-
|
|
81167
|
-
|
|
82605
|
+
const candidates = configuredPath && configuredPath.trim() !== "" ? [isAbsolute3(configuredPath) ? configuredPath : join19(process.cwd(), configuredPath)] : [
|
|
82606
|
+
join19(process.cwd(), "dist/web"),
|
|
82607
|
+
join19(import.meta.dir, "web"),
|
|
82608
|
+
join19(dirname12(process.execPath), "web"),
|
|
82609
|
+
join19(dirname12(process.execPath), "../web"),
|
|
82610
|
+
join19(import.meta.dir, "../../../dist/web")
|
|
81168
82611
|
];
|
|
81169
82612
|
for (const candidate of candidates) {
|
|
81170
|
-
if (await Bun.file(
|
|
82613
|
+
if (await Bun.file(join19(candidate, "index.html")).exists()) {
|
|
81171
82614
|
return candidate;
|
|
81172
82615
|
}
|
|
81173
82616
|
}
|
|
@@ -81205,11 +82648,13 @@ async function startServer(options, deps = defaultDeps) {
|
|
|
81205
82648
|
bootConfig
|
|
81206
82649
|
});
|
|
81207
82650
|
let jobWorker;
|
|
81208
|
-
|
|
82651
|
+
const autostartConfig = await loadSpurConfig(process.cwd()).catch(() => null);
|
|
82652
|
+
const autostartIds = resolveAutostartSet(autostartConfig, env.SPUR_TEAM_AUTOSTART);
|
|
82653
|
+
if (autostartIds.length > 0) {
|
|
81209
82654
|
try {
|
|
81210
82655
|
const supervisor = ctx.supervisor();
|
|
81211
|
-
await supervisor.startAutostart(
|
|
81212
|
-
appRt.logger.info("Autostart agents spawned", { ids:
|
|
82656
|
+
await supervisor.startAutostart(autostartIds);
|
|
82657
|
+
appRt.logger.info("Autostart agents spawned", { ids: autostartIds });
|
|
81213
82658
|
} catch (error51) {
|
|
81214
82659
|
appRt.logger.error("Autostart failed \u2014 server will continue but supervised agents are not running", {
|
|
81215
82660
|
error: String(error51)
|
|
@@ -81295,7 +82740,7 @@ if (false) {}
|
|
|
81295
82740
|
|
|
81296
82741
|
// src/commands/serve.ts
|
|
81297
82742
|
function resolveServeDbUrl(cwd, env, configuredUrl) {
|
|
81298
|
-
return env.DATABASE_URL === undefined ?
|
|
82743
|
+
return env.DATABASE_URL === undefined ? join20(cwd, DEFAULT_DATABASE_URL) : configuredUrl;
|
|
81299
82744
|
}
|
|
81300
82745
|
function registerServeCommand(program2, context4) {
|
|
81301
82746
|
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) => {
|
|
@@ -81334,7 +82779,7 @@ function registerServeCommand(program2, context4) {
|
|
|
81334
82779
|
}
|
|
81335
82780
|
|
|
81336
82781
|
// src/commands/status.ts
|
|
81337
|
-
import { join as
|
|
82782
|
+
import { join as join21 } from "path";
|
|
81338
82783
|
|
|
81339
82784
|
// src/errors.ts
|
|
81340
82785
|
class CommandError extends Error {
|
|
@@ -81362,7 +82807,7 @@ function errorMessage4(error51) {
|
|
|
81362
82807
|
// src/git-context.ts
|
|
81363
82808
|
init_dist5();
|
|
81364
82809
|
async function gitContext(cwd) {
|
|
81365
|
-
const executor = new
|
|
82810
|
+
const executor = new NodeProcessExecutor3({ defaultTimeout: 5000, defaultMaxOutput: 128000 });
|
|
81366
82811
|
const root = await executor.run({
|
|
81367
82812
|
command: "git",
|
|
81368
82813
|
args: ["rev-parse", "--show-toplevel"],
|
|
@@ -81405,8 +82850,8 @@ function registerStatusCommand(program2, context4) {
|
|
|
81405
82850
|
}
|
|
81406
82851
|
async function runStatusCore(path9, options, context4) {
|
|
81407
82852
|
const [packageJsonExists, spurConfigExists, git, agentSpecs] = await Promise.all([
|
|
81408
|
-
context4.fs.exists(
|
|
81409
|
-
context4.fs.exists(
|
|
82853
|
+
context4.fs.exists(join21(context4.cwd, "package.json")),
|
|
82854
|
+
context4.fs.exists(join21(context4.cwd, ".spur", "config.yaml")),
|
|
81410
82855
|
gitContext(context4.cwd),
|
|
81411
82856
|
listAgentSpecIds(context4)
|
|
81412
82857
|
]);
|
|
@@ -81434,14 +82879,14 @@ async function runStatusCore(path9, options, context4) {
|
|
|
81434
82879
|
return status.ok ? 0 : 1;
|
|
81435
82880
|
}
|
|
81436
82881
|
async function listAgentSpecIds(context4) {
|
|
81437
|
-
const dir =
|
|
82882
|
+
const dir = join21(context4.cwd, ".spur", "agents");
|
|
81438
82883
|
if (!await context4.fs.exists(dir))
|
|
81439
82884
|
return [];
|
|
81440
82885
|
const entries = await context4.fs.readDir(dir);
|
|
81441
82886
|
return entries.filter((entry) => entry.endsWith(".yaml") || entry.endsWith(".yml")).map((entry) => entry.replace(/\.ya?ml$/, "")).sort();
|
|
81442
82887
|
}
|
|
81443
82888
|
async function readTargetStatus(context4, targetPath) {
|
|
81444
|
-
const resolved =
|
|
82889
|
+
const resolved = join21(context4.cwd, targetPath);
|
|
81445
82890
|
const stat2 = await context4.fs.stat(resolved);
|
|
81446
82891
|
if (stat2 === null)
|
|
81447
82892
|
throw new CommandError(`status failed: path does not exist at ${resolved}`);
|
|
@@ -81452,8 +82897,8 @@ async function readTargetStatus(context4, targetPath) {
|
|
|
81452
82897
|
init_src3();
|
|
81453
82898
|
init_loader();
|
|
81454
82899
|
init_src2();
|
|
81455
|
-
import { existsSync as
|
|
81456
|
-
import { join as
|
|
82900
|
+
import { existsSync as existsSync9, readFileSync as readFileSync8 } from "fs";
|
|
82901
|
+
import { join as join22 } from "path";
|
|
81457
82902
|
// schemas/section-matrix.schema.json
|
|
81458
82903
|
var section_matrix_schema_default = {
|
|
81459
82904
|
$schema: "http://json-schema.org/draft-07/schema#",
|
|
@@ -81662,6 +83107,70 @@ var spur_config_schema_default = {
|
|
|
81662
83107
|
additionalProperties: {
|
|
81663
83108
|
type: "string"
|
|
81664
83109
|
}
|
|
83110
|
+
},
|
|
83111
|
+
team: {
|
|
83112
|
+
type: "object",
|
|
83113
|
+
description: "Declarative agent teams keyed by team id (the map key is the teamId). Each team materializes a roster of agent specs (feature M). Mirrors @gobing-ai/spur-config TeamConfigSchema (Zod is SSOT).",
|
|
83114
|
+
additionalProperties: {
|
|
83115
|
+
type: "object",
|
|
83116
|
+
required: ["name", "work_dir", "members"],
|
|
83117
|
+
properties: {
|
|
83118
|
+
name: {
|
|
83119
|
+
type: "string",
|
|
83120
|
+
minLength: 1,
|
|
83121
|
+
description: "Human-readable team label."
|
|
83122
|
+
},
|
|
83123
|
+
work_dir: {
|
|
83124
|
+
type: "string",
|
|
83125
|
+
minLength: 1,
|
|
83126
|
+
description: "Default member workspace. A leading `~` is tilde-expanded at load."
|
|
83127
|
+
},
|
|
83128
|
+
autostart: {
|
|
83129
|
+
type: "boolean",
|
|
83130
|
+
description: "Team-wide autostart default; per-member autostart overrides (effective = member.autostart ?? team.autostart ?? false)."
|
|
83131
|
+
},
|
|
83132
|
+
members: {
|
|
83133
|
+
type: "array",
|
|
83134
|
+
minItems: 1,
|
|
83135
|
+
description: "Roster of member references (>= 1). A bare string is shorthand for { executor: <string> }; the composed agent id is <teamId>-<id ?? executor>.",
|
|
83136
|
+
items: {
|
|
83137
|
+
oneOf: [
|
|
83138
|
+
{ type: "string", minLength: 1 },
|
|
83139
|
+
{
|
|
83140
|
+
type: "object",
|
|
83141
|
+
required: ["executor"],
|
|
83142
|
+
properties: {
|
|
83143
|
+
executor: {
|
|
83144
|
+
type: "string",
|
|
83145
|
+
minLength: 1,
|
|
83146
|
+
description: "Executor name \u2014 resolved against agent.executors first, else a raw canonical agent type."
|
|
83147
|
+
},
|
|
83148
|
+
id: {
|
|
83149
|
+
type: "string",
|
|
83150
|
+
minLength: 1,
|
|
83151
|
+
description: "Local member id; composed id is <teamId>-<id ?? executor> (must match ^[a-z][a-z0-9_-]{1,63}$)."
|
|
83152
|
+
},
|
|
83153
|
+
purpose: { type: "string" },
|
|
83154
|
+
workspace: {
|
|
83155
|
+
type: "string",
|
|
83156
|
+
minLength: 1,
|
|
83157
|
+
description: "Per-member workspace override. A leading `~` is tilde-expanded at load."
|
|
83158
|
+
},
|
|
83159
|
+
model: { type: "string", minLength: 1 },
|
|
83160
|
+
autonomy: { type: "string" },
|
|
83161
|
+
systemPrompt: { type: "string" },
|
|
83162
|
+
command: {
|
|
83163
|
+
type: "array",
|
|
83164
|
+
items: { type: "string", minLength: 1 }
|
|
83165
|
+
},
|
|
83166
|
+
autostart: { type: "boolean" }
|
|
83167
|
+
}
|
|
83168
|
+
}
|
|
83169
|
+
]
|
|
83170
|
+
}
|
|
83171
|
+
}
|
|
83172
|
+
}
|
|
83173
|
+
}
|
|
81665
83174
|
}
|
|
81666
83175
|
}
|
|
81667
83176
|
},
|
|
@@ -82308,7 +83817,8 @@ async function makeService2(context4, folderOverride, noLifecycle = false) {
|
|
|
82308
83817
|
const lifecycle = noLifecycle ? undefined : makeLifecycleAdapter(context4, TASK_LIFECYCLE_PROFILE);
|
|
82309
83818
|
const writeService = new PlanningWriteService({
|
|
82310
83819
|
fs: context4.fs,
|
|
82311
|
-
...lifecycle ? { lifecycle } : {}
|
|
83820
|
+
...lifecycle ? { lifecycle } : {},
|
|
83821
|
+
emitter: makePlanningEmitter(context4)
|
|
82312
83822
|
});
|
|
82313
83823
|
return new TaskService({
|
|
82314
83824
|
fs: context4.fs,
|
|
@@ -82327,16 +83837,16 @@ function loadTemplateContent(projectRoot, variant) {
|
|
|
82327
83837
|
return templateContentCache.get(variant);
|
|
82328
83838
|
if (templateMissSet.has(variant))
|
|
82329
83839
|
return;
|
|
82330
|
-
const localPath =
|
|
82331
|
-
if (
|
|
83840
|
+
const localPath = join22(projectRoot, ".spur", "tasks", "templates", `${variant}.md`);
|
|
83841
|
+
if (existsSync9(localPath)) {
|
|
82332
83842
|
const content = readFileSync8(localPath, "utf8");
|
|
82333
83843
|
templateContentCache.set(variant, content);
|
|
82334
83844
|
return content;
|
|
82335
83845
|
}
|
|
82336
83846
|
const root = bundledConfigRoot();
|
|
82337
83847
|
if (root !== null) {
|
|
82338
|
-
const templatePath =
|
|
82339
|
-
if (
|
|
83848
|
+
const templatePath = join22(root, "templates", "task", `${variant}.md`);
|
|
83849
|
+
if (existsSync9(templatePath)) {
|
|
82340
83850
|
const content = readFileSync8(templatePath, "utf8");
|
|
82341
83851
|
templateContentCache.set(variant, content);
|
|
82342
83852
|
return content;
|
|
@@ -82351,14 +83861,14 @@ function loadTemplateBodies(projectRoot, variant) {
|
|
|
82351
83861
|
if (cached2 !== undefined)
|
|
82352
83862
|
return cached2;
|
|
82353
83863
|
let bodies = {};
|
|
82354
|
-
const localPath =
|
|
82355
|
-
if (
|
|
83864
|
+
const localPath = join22(projectRoot, ".spur", "tasks", "templates", `${variant}.md`);
|
|
83865
|
+
if (existsSync9(localPath)) {
|
|
82356
83866
|
bodies = extractTemplateBodies(readFileSync8(localPath, "utf8"));
|
|
82357
83867
|
} else {
|
|
82358
83868
|
const root = bundledConfigRoot();
|
|
82359
83869
|
if (root !== null) {
|
|
82360
|
-
const templatePath =
|
|
82361
|
-
if (
|
|
83870
|
+
const templatePath = join22(root, "templates", "task", `${variant}.md`);
|
|
83871
|
+
if (existsSync9(templatePath)) {
|
|
82362
83872
|
bodies = extractTemplateBodies(readFileSync8(templatePath, "utf8"));
|
|
82363
83873
|
}
|
|
82364
83874
|
}
|
|
@@ -82392,8 +83902,8 @@ async function loadSectionMatrix(projectRoot) {
|
|
|
82392
83902
|
return promise2;
|
|
82393
83903
|
}
|
|
82394
83904
|
async function loadSectionMatrixUncached(projectRoot) {
|
|
82395
|
-
const localPath =
|
|
82396
|
-
if (
|
|
83905
|
+
const localPath = join22(projectRoot, ".spur", "tasks", "section-matrix.yaml");
|
|
83906
|
+
if (existsSync9(localPath)) {
|
|
82397
83907
|
const data = await loadStructuredSpurConfig(localPath, {
|
|
82398
83908
|
validateJsonSchema: true,
|
|
82399
83909
|
embeddedSchemas: EMBEDDED_SPUR_SCHEMAS
|
|
@@ -82402,8 +83912,8 @@ async function loadSectionMatrixUncached(projectRoot) {
|
|
|
82402
83912
|
}
|
|
82403
83913
|
const root = bundledConfigRoot();
|
|
82404
83914
|
if (root !== null) {
|
|
82405
|
-
const matrixPath =
|
|
82406
|
-
if (
|
|
83915
|
+
const matrixPath = join22(root, "tasks", "section-matrix.yaml");
|
|
83916
|
+
if (existsSync9(matrixPath)) {
|
|
82407
83917
|
const data = await loadStructuredSpurConfig(matrixPath, {
|
|
82408
83918
|
validateJsonSchema: true,
|
|
82409
83919
|
embeddedSchemas: EMBEDDED_SPUR_SCHEMAS
|
|
@@ -82436,8 +83946,16 @@ function registerTeamCommand(program2, context4) {
|
|
|
82436
83946
|
const code = await runTeamAssign(taskId, agentId, context4);
|
|
82437
83947
|
context4.setExitCode(code);
|
|
82438
83948
|
});
|
|
82439
|
-
noun.command("status").description("List agent specs and their run status.").option("--json", "Output machine-readable JSON").action(async (options) => {
|
|
82440
|
-
const code = await runTeamStatus(options, context4);
|
|
83949
|
+
noun.command("status").description("List agent specs and their run status; --by-team groups by team (0258 R4).").option("--json", "Output machine-readable JSON").option("--by-team", "Group specs by their agent.team.<id> membership").option("--server <url>", "Server API URL for live run status", DEFAULT_SERVER).action(async (options) => {
|
|
83950
|
+
const code = options.byTeam ? await runTeamStatusGrouped(options, context4) : await runTeamStatus(options, context4);
|
|
83951
|
+
context4.setExitCode(code);
|
|
83952
|
+
});
|
|
83953
|
+
noun.command("up").description("Materialize a team roster into agent specs; best-effort start when spur serve is reachable.").argument("<team>", "Team id (agent.team.<team>)").option("--check", "Dry-run: show the add/prune diff without writing").option("--server <url>", "Server API URL", DEFAULT_SERVER).option("--json", "Output machine-readable JSON").action(async (team, options) => {
|
|
83954
|
+
const code = await runTeamUp(team, options, context4);
|
|
83955
|
+
context4.setExitCode(code);
|
|
83956
|
+
});
|
|
83957
|
+
noun.command("down").description("Tear down a team: stop members; --purge also removes generated specs.").argument("<team>", "Team id").option("--purge", "Also delete spur:generated specs (never manual / ref:)").option("--server <url>", "Server API URL", DEFAULT_SERVER).option("--json", "Output machine-readable JSON").action(async (team, options) => {
|
|
83958
|
+
const code = await runTeamDown(team, options, context4);
|
|
82441
83959
|
context4.setExitCode(code);
|
|
82442
83960
|
});
|
|
82443
83961
|
noun.command("start").description("Start a supervised agent process (requires spur serve).").argument("<agent-id>", "Agent spec id").option("--server <url>", "Server API URL", DEFAULT_SERVER).option("--json", "Output machine-readable JSON").action(async (agentId, options) => {
|
|
@@ -82459,18 +83977,59 @@ async function runTeamStatus(options, context4) {
|
|
|
82459
83977
|
const svc = new TeamService(context4);
|
|
82460
83978
|
const json3 = options.json === true;
|
|
82461
83979
|
const status = await svc.getStatus();
|
|
82462
|
-
if (json3) {
|
|
82463
|
-
context4.output.write(toJson2(status));
|
|
82464
|
-
return 0;
|
|
82465
|
-
}
|
|
82466
83980
|
if (status.agents.length === 0) {
|
|
82467
83981
|
context4.output.write("No agent specs found in .spur/agents/");
|
|
82468
83982
|
return 0;
|
|
82469
83983
|
}
|
|
83984
|
+
const live = await fetchServerProcesses(options.server);
|
|
83985
|
+
if (live === null) {
|
|
83986
|
+
context4.output.error(`Cannot reach server at ${options.server} \u2014 showing local specs as stopped. Is spur serve running?`);
|
|
83987
|
+
} else {
|
|
83988
|
+
for (const agent of status.agents) {
|
|
83989
|
+
const proc = live.get(agent.id);
|
|
83990
|
+
if (proc) {
|
|
83991
|
+
agent.status = proc.status;
|
|
83992
|
+
agent.pid = proc.pid ?? undefined;
|
|
83993
|
+
}
|
|
83994
|
+
}
|
|
83995
|
+
}
|
|
83996
|
+
if (json3) {
|
|
83997
|
+
context4.output.write(toJson2(status));
|
|
83998
|
+
return 0;
|
|
83999
|
+
}
|
|
82470
84000
|
context4.output.write(status.agents.map(formatStatusLine).join(`
|
|
82471
84001
|
`));
|
|
82472
84002
|
return 0;
|
|
82473
84003
|
}
|
|
84004
|
+
function mapServerStatus(status) {
|
|
84005
|
+
switch (status) {
|
|
84006
|
+
case "running":
|
|
84007
|
+
return "running";
|
|
84008
|
+
case "errored":
|
|
84009
|
+
return "errored";
|
|
84010
|
+
case "stopped":
|
|
84011
|
+
case "exited":
|
|
84012
|
+
return "stopped";
|
|
84013
|
+
default:
|
|
84014
|
+
return "unknown";
|
|
84015
|
+
}
|
|
84016
|
+
}
|
|
84017
|
+
async function fetchServerProcesses(server) {
|
|
84018
|
+
try {
|
|
84019
|
+
const url2 = `${server}/team/processes`;
|
|
84020
|
+
const res = await teamFetch(url2, { method: "GET" });
|
|
84021
|
+
if (!res.ok)
|
|
84022
|
+
return null;
|
|
84023
|
+
const body = await res.json();
|
|
84024
|
+
const map3 = new Map;
|
|
84025
|
+
for (const proc of body.processes ?? []) {
|
|
84026
|
+
map3.set(proc.agentId, { status: mapServerStatus(proc.status), pid: proc.pid ?? null });
|
|
84027
|
+
}
|
|
84028
|
+
return map3;
|
|
84029
|
+
} catch {
|
|
84030
|
+
return null;
|
|
84031
|
+
}
|
|
84032
|
+
}
|
|
82474
84033
|
async function performTeamStart(agentId, options) {
|
|
82475
84034
|
try {
|
|
82476
84035
|
const url2 = `${options.server}/team/agents/${encodeURIComponent(agentId)}/start`;
|
|
@@ -82535,6 +84094,76 @@ function formatStatusLine(agent) {
|
|
|
82535
84094
|
const pid = agent.pid === undefined ? "" : ` pid=${agent.pid}`;
|
|
82536
84095
|
return `${agent.status} ${agent.id} ${agent.type} ${agent.purpose}${pid}`;
|
|
82537
84096
|
}
|
|
84097
|
+
async function runTeamStatusGrouped(options, context4) {
|
|
84098
|
+
const teams = await new TeamService(context4).listTeams();
|
|
84099
|
+
if (options.json === true) {
|
|
84100
|
+
context4.output.write(toJson2({ teams }));
|
|
84101
|
+
return 0;
|
|
84102
|
+
}
|
|
84103
|
+
if (teams.length === 0) {
|
|
84104
|
+
context4.output.write("No teams or agent specs found");
|
|
84105
|
+
return 0;
|
|
84106
|
+
}
|
|
84107
|
+
context4.output.write(teams.map(formatTeamBlock).join(`
|
|
84108
|
+
`));
|
|
84109
|
+
return 0;
|
|
84110
|
+
}
|
|
84111
|
+
function formatTeamBlock(team) {
|
|
84112
|
+
const header = team.name && team.name !== team.teamId ? `# ${team.teamId} (${team.name})` : `# ${team.teamId}`;
|
|
84113
|
+
const rows = team.specs.map((spec) => ` ${spec.id} ${spec.type} ${spec.purpose}`);
|
|
84114
|
+
return [header, ...rows].join(`
|
|
84115
|
+
`);
|
|
84116
|
+
}
|
|
84117
|
+
async function runTeamUp(team, options, context4) {
|
|
84118
|
+
const svc = new TeamService(context4);
|
|
84119
|
+
let result;
|
|
84120
|
+
try {
|
|
84121
|
+
result = await svc.materializeTeam(team, { check: options.check === true });
|
|
84122
|
+
} catch (error51) {
|
|
84123
|
+
context4.output.error(error51 instanceof Error ? error51.message : String(error51));
|
|
84124
|
+
return 1;
|
|
84125
|
+
}
|
|
84126
|
+
const started = [];
|
|
84127
|
+
if (options.check !== true && result.upserted.length > 0) {
|
|
84128
|
+
const specs = await svc.listAgentSpecs();
|
|
84129
|
+
const autostart = specs.filter((spec) => spec.autoStart === true && result.upserted.includes(spec.id));
|
|
84130
|
+
for (const spec of autostart) {
|
|
84131
|
+
const res = await performTeamStart(spec.id, { server: options.server });
|
|
84132
|
+
if ("ok" in res && res.ok === true)
|
|
84133
|
+
started.push(spec.id);
|
|
84134
|
+
}
|
|
84135
|
+
}
|
|
84136
|
+
if (options.json === true) {
|
|
84137
|
+
context4.output.write(toJson2({ ...result, started }));
|
|
84138
|
+
} else {
|
|
84139
|
+
const verb = options.check === true ? "would materialize" : "materialized";
|
|
84140
|
+
const startNote = started.length > 0 ? `, started ${started.length}` : "";
|
|
84141
|
+
context4.output.write(`team ${team}: ${verb} ${result.upserted.length} member(s), prune ${result.orphaned.length}${startNote}`);
|
|
84142
|
+
}
|
|
84143
|
+
return 0;
|
|
84144
|
+
}
|
|
84145
|
+
async function runTeamDown(team, options, context4) {
|
|
84146
|
+
const svc = new TeamService(context4);
|
|
84147
|
+
let result;
|
|
84148
|
+
try {
|
|
84149
|
+
result = await svc.teardownTeam(team, { purge: options.purge === true });
|
|
84150
|
+
} catch (error51) {
|
|
84151
|
+
context4.output.error(error51 instanceof Error ? error51.message : String(error51));
|
|
84152
|
+
return 1;
|
|
84153
|
+
}
|
|
84154
|
+
const stopped = [];
|
|
84155
|
+
for (const id of result.stopped) {
|
|
84156
|
+
const res = await performTeamStop(id, { server: options.server });
|
|
84157
|
+
if ("ok" in res && res.ok === true)
|
|
84158
|
+
stopped.push(id);
|
|
84159
|
+
}
|
|
84160
|
+
if (options.json === true) {
|
|
84161
|
+
context4.output.write(toJson2({ ...result, stopped }));
|
|
84162
|
+
} else {
|
|
84163
|
+
context4.output.write(`team ${team}: stopped ${stopped.length}, purged ${result.purged.length}`);
|
|
84164
|
+
}
|
|
84165
|
+
return 0;
|
|
84166
|
+
}
|
|
82538
84167
|
|
|
82539
84168
|
// src/commands/workflow.ts
|
|
82540
84169
|
init_src3();
|
|
@@ -82848,7 +84477,7 @@ init_src3();
|
|
|
82848
84477
|
init_src();
|
|
82849
84478
|
init_src2();
|
|
82850
84479
|
init_dist5();
|
|
82851
|
-
import { dirname as dirname13, join as
|
|
84480
|
+
import { dirname as dirname13, join as join23, resolve as resolve7 } from "path";
|
|
82852
84481
|
import { isatty as isatty4 } from "tty";
|
|
82853
84482
|
|
|
82854
84483
|
// ../../node_modules/.bun/@clack+core@1.4.1/node_modules/@clack/core/dist/index.mjs
|
|
@@ -84262,7 +85891,7 @@ function createCliContext(options) {
|
|
|
84262
85891
|
function noopSetExitCode(_code) {}
|
|
84263
85892
|
async function createMigratedDbAdapter(cwd = process.cwd(), env = process.env, dbUrl) {
|
|
84264
85893
|
const config4 = buildConfigFromEnv(env);
|
|
84265
|
-
const configuredUrl = env.DATABASE_URL === undefined ?
|
|
85894
|
+
const configuredUrl = env.DATABASE_URL === undefined ? join23(cwd, DEFAULT_DATABASE_URL) : config4.database.url;
|
|
84266
85895
|
const url2 = dbUrl ?? configuredUrl;
|
|
84267
85896
|
if (url2 !== IN_MEMORY_DATABASE_URL) {
|
|
84268
85897
|
await createNodeFileSystem3().ensureDir(dirname13(url2));
|