@gobing-ai/spur 0.3.35 → 0.3.36
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/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.23/node_modules/@gobing-ai/ts-utils/dist/errors.js
|
|
51
51
|
var ErrorCode;
|
|
52
52
|
var init_errors = __esm(() => {
|
|
53
53
|
ErrorCode = {
|
|
@@ -58,7 +58,7 @@ var init_errors = __esm(() => {
|
|
|
58
58
|
};
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
-
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.
|
|
61
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.23/node_modules/@gobing-ai/ts-utils/dist/api-response.js
|
|
62
62
|
var API_ERROR_CODES, ERROR_CODE_TO_HTTP, CLIENT_SAFE_CODES;
|
|
63
63
|
var init_api_response = __esm(() => {
|
|
64
64
|
init_errors();
|
|
@@ -81,10 +81,10 @@ var init_api_response = __esm(() => {
|
|
|
81
81
|
CLIENT_SAFE_CODES = new Set([ErrorCode.NotFound, ErrorCode.Validation, ErrorCode.Conflict]);
|
|
82
82
|
});
|
|
83
83
|
|
|
84
|
-
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.
|
|
84
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.23/node_modules/@gobing-ai/ts-utils/dist/cursor.js
|
|
85
85
|
var init_cursor = () => {};
|
|
86
86
|
|
|
87
|
-
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.
|
|
87
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.23/node_modules/@gobing-ai/ts-utils/dist/object.js
|
|
88
88
|
function isPlainObject(value) {
|
|
89
89
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
90
90
|
}
|
|
@@ -102,7 +102,7 @@ function deepMerge(target, source) {
|
|
|
102
102
|
return result;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.
|
|
105
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.23/node_modules/@gobing-ai/ts-utils/dist/output.js
|
|
106
106
|
function processStream(name) {
|
|
107
107
|
const proc = globalThis.process;
|
|
108
108
|
const stream = proc?.[name];
|
|
@@ -123,7 +123,7 @@ function echoError(message, target = defaultStderrTarget ?? processStream("stder
|
|
|
123
123
|
}
|
|
124
124
|
var defaultStdoutTarget, defaultStderrTarget;
|
|
125
125
|
|
|
126
|
-
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.
|
|
126
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.23/node_modules/@gobing-ai/ts-utils/dist/index.js
|
|
127
127
|
var init_dist = __esm(() => {
|
|
128
128
|
init_api_response();
|
|
129
129
|
init_cursor();
|
|
@@ -21745,7 +21745,7 @@ var init_zod = __esm(() => {
|
|
|
21745
21745
|
init_external();
|
|
21746
21746
|
});
|
|
21747
21747
|
|
|
21748
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
21748
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+7af9b447ef75eadf/node_modules/@gobing-ai/ts-runtime/dist/config.js
|
|
21749
21749
|
function getProcessEnv() {
|
|
21750
21750
|
return process.env;
|
|
21751
21751
|
}
|
|
@@ -21823,7 +21823,7 @@ var init_config = __esm(() => {
|
|
|
21823
21823
|
};
|
|
21824
21824
|
});
|
|
21825
21825
|
|
|
21826
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
21826
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+7af9b447ef75eadf/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
|
|
21827
21827
|
import { appendFileSync, cpSync, createReadStream, createWriteStream, existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "fs";
|
|
21828
21828
|
import { dirname, resolve as resolvePath } from "path";
|
|
21829
21829
|
function createNodeFileSystem(root, paths) {
|
|
@@ -21910,7 +21910,7 @@ function findProjectRoot(startDir) {
|
|
|
21910
21910
|
}
|
|
21911
21911
|
var init_file_system_node = () => {};
|
|
21912
21912
|
|
|
21913
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
21913
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+7af9b447ef75eadf/node_modules/@gobing-ai/ts-runtime/dist/db-errors.js
|
|
21914
21914
|
var DbModuleNotInstalledError;
|
|
21915
21915
|
var init_db_errors = __esm(() => {
|
|
21916
21916
|
DbModuleNotInstalledError = class DbModuleNotInstalledError extends Error {
|
|
@@ -29121,7 +29121,7 @@ var init_execa = __esm(() => {
|
|
|
29121
29121
|
} = getIpcExport());
|
|
29122
29122
|
});
|
|
29123
29123
|
|
|
29124
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29124
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+7af9b447ef75eadf/node_modules/@gobing-ai/ts-runtime/dist/process-executor.js
|
|
29125
29125
|
import { isatty } from "tty";
|
|
29126
29126
|
|
|
29127
29127
|
class NodeProcessExecutor {
|
|
@@ -29460,7 +29460,7 @@ var init_process_executor = __esm(() => {
|
|
|
29460
29460
|
init_execa();
|
|
29461
29461
|
});
|
|
29462
29462
|
|
|
29463
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29463
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+7af9b447ef75eadf/node_modules/@gobing-ai/ts-runtime/dist/runtime-node-bun.js
|
|
29464
29464
|
function getNodeFileSystem() {
|
|
29465
29465
|
if (!_nodeFileSystem)
|
|
29466
29466
|
_nodeFileSystem = createNodeFileSystem();
|
|
@@ -29520,7 +29520,7 @@ var init_runtime_node_bun = __esm(() => {
|
|
|
29520
29520
|
};
|
|
29521
29521
|
});
|
|
29522
29522
|
|
|
29523
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29523
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+7af9b447ef75eadf/node_modules/@gobing-ai/ts-runtime/dist/context.js
|
|
29524
29524
|
class RuntimeContext {
|
|
29525
29525
|
scope;
|
|
29526
29526
|
runtimeName;
|
|
@@ -29590,7 +29590,7 @@ var init_context = __esm(() => {
|
|
|
29590
29590
|
init_runtime_node_bun();
|
|
29591
29591
|
});
|
|
29592
29592
|
|
|
29593
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29593
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+7af9b447ef75eadf/node_modules/@gobing-ai/ts-runtime/dist/path.js
|
|
29594
29594
|
function normalizeSeparators(path6) {
|
|
29595
29595
|
return path6.replaceAll("\\", "/");
|
|
29596
29596
|
}
|
|
@@ -29651,17 +29651,17 @@ var init_path = __esm(() => {
|
|
|
29651
29651
|
SEP = globalThis.process?.platform === "win32" ? "\\" : "/";
|
|
29652
29652
|
});
|
|
29653
29653
|
|
|
29654
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29654
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+7af9b447ef75eadf/node_modules/@gobing-ai/ts-runtime/dist/schema-validation.js
|
|
29655
29655
|
var REMOTE_SCHEMA_MAX_BYTES;
|
|
29656
29656
|
var init_schema_validation = __esm(() => {
|
|
29657
29657
|
init_dist2();
|
|
29658
29658
|
REMOTE_SCHEMA_MAX_BYTES = 5 * 1024 * 1024;
|
|
29659
29659
|
});
|
|
29660
29660
|
|
|
29661
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29661
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+7af9b447ef75eadf/node_modules/@gobing-ai/ts-runtime/dist/types.js
|
|
29662
29662
|
var init_types = () => {};
|
|
29663
29663
|
|
|
29664
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29664
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+7af9b447ef75eadf/node_modules/@gobing-ai/ts-runtime/dist/index.js
|
|
29665
29665
|
var init_dist3 = __esm(() => {
|
|
29666
29666
|
init_config();
|
|
29667
29667
|
init_context();
|
|
@@ -29670,7 +29670,7 @@ var init_dist3 = __esm(() => {
|
|
|
29670
29670
|
init_types();
|
|
29671
29671
|
});
|
|
29672
29672
|
|
|
29673
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
29673
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+7af9b447ef75eadf/node_modules/@gobing-ai/ts-runtime/dist/bun-sqlite.js
|
|
29674
29674
|
import { Database } from "bun:sqlite";
|
|
29675
29675
|
var init_bun_sqlite = () => {};
|
|
29676
29676
|
|
|
@@ -33862,7 +33862,7 @@ var init_bun_sqlite2 = __esm(() => {
|
|
|
33862
33862
|
init_session2();
|
|
33863
33863
|
});
|
|
33864
33864
|
|
|
33865
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
33865
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/schema/inbox-messages.js
|
|
33866
33866
|
var inboxMessages;
|
|
33867
33867
|
var init_inbox_messages = __esm(() => {
|
|
33868
33868
|
init_sqlite_core();
|
|
@@ -33881,7 +33881,7 @@ var init_inbox_messages = __esm(() => {
|
|
|
33881
33881
|
}, (table2) => [index("idx_inbox_messages_to_status").on(table2.toId, table2.status)]);
|
|
33882
33882
|
});
|
|
33883
33883
|
|
|
33884
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
33884
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/schema/common.js
|
|
33885
33885
|
function nowTimestamp() {
|
|
33886
33886
|
return Date.now();
|
|
33887
33887
|
}
|
|
@@ -33910,7 +33910,7 @@ var init_common3 = __esm(() => {
|
|
|
33910
33910
|
appendOnlyColumns = buildAppendOnlyColumns();
|
|
33911
33911
|
});
|
|
33912
33912
|
|
|
33913
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
33913
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/schema/queue-jobs.js
|
|
33914
33914
|
var queueJobs;
|
|
33915
33915
|
var init_queue_jobs = __esm(() => {
|
|
33916
33916
|
init_sqlite_core();
|
|
@@ -33930,7 +33930,7 @@ var init_queue_jobs = __esm(() => {
|
|
|
33930
33930
|
}, (table2) => [index("queue_jobs_ready_idx").on(table2.status, table2.nextRetryAt, table2.createdAt)]);
|
|
33931
33931
|
});
|
|
33932
33932
|
|
|
33933
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
33933
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/schema/runtime.js
|
|
33934
33934
|
var exports_runtime = {};
|
|
33935
33935
|
__export(exports_runtime, {
|
|
33936
33936
|
queueJobs: () => queueJobs,
|
|
@@ -33941,7 +33941,7 @@ var init_runtime = __esm(() => {
|
|
|
33941
33941
|
init_queue_jobs();
|
|
33942
33942
|
});
|
|
33943
33943
|
|
|
33944
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
33944
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/adapters/bun-sqlite.js
|
|
33945
33945
|
var exports_bun_sqlite = {};
|
|
33946
33946
|
__export(exports_bun_sqlite, {
|
|
33947
33947
|
BunSqliteAdapter: () => BunSqliteAdapter
|
|
@@ -34232,7 +34232,7 @@ var init_d1 = __esm(() => {
|
|
|
34232
34232
|
init_session3();
|
|
34233
34233
|
});
|
|
34234
34234
|
|
|
34235
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34235
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/adapters/d1.js
|
|
34236
34236
|
var exports_d1 = {};
|
|
34237
34237
|
__export(exports_d1, {
|
|
34238
34238
|
D1Adapter: () => D1Adapter
|
|
@@ -34296,7 +34296,7 @@ var init_d12 = __esm(() => {
|
|
|
34296
34296
|
init_runtime();
|
|
34297
34297
|
});
|
|
34298
34298
|
|
|
34299
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34299
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/adapter.js
|
|
34300
34300
|
async function createDbAdapter(config3) {
|
|
34301
34301
|
switch (config3.driver) {
|
|
34302
34302
|
case "bun-sqlite": {
|
|
@@ -34336,7 +34336,7 @@ var init_drizzle_orm = __esm(() => {
|
|
|
34336
34336
|
init_view_common();
|
|
34337
34337
|
});
|
|
34338
34338
|
|
|
34339
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34339
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/query-spec.js
|
|
34340
34340
|
function compilePredicate(predicate) {
|
|
34341
34341
|
if ("and" in predicate) {
|
|
34342
34342
|
const parts = predicate.and.map(compilePredicate).filter((p) => p !== undefined);
|
|
@@ -34374,7 +34374,7 @@ var init_query_spec = __esm(() => {
|
|
|
34374
34374
|
};
|
|
34375
34375
|
});
|
|
34376
34376
|
|
|
34377
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34377
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/base-dao.js
|
|
34378
34378
|
function asSelectQuery(query) {
|
|
34379
34379
|
return query;
|
|
34380
34380
|
}
|
|
@@ -34416,7 +34416,7 @@ var init_base_dao = __esm(() => {
|
|
|
34416
34416
|
init_query_spec();
|
|
34417
34417
|
});
|
|
34418
34418
|
|
|
34419
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34419
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/embedded-migrations.js
|
|
34420
34420
|
var embeddedMigrations;
|
|
34421
34421
|
var init_embedded_migrations = __esm(() => {
|
|
34422
34422
|
embeddedMigrations = [
|
|
@@ -34448,7 +34448,7 @@ var init_embedded_migrations = __esm(() => {
|
|
|
34448
34448
|
];
|
|
34449
34449
|
});
|
|
34450
34450
|
|
|
34451
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34451
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/entity-dao.js
|
|
34452
34452
|
var EntityDao;
|
|
34453
34453
|
var init_entity_dao = __esm(() => {
|
|
34454
34454
|
init_drizzle_orm();
|
|
@@ -34610,7 +34610,7 @@ var init_entity_dao = __esm(() => {
|
|
|
34610
34610
|
};
|
|
34611
34611
|
});
|
|
34612
34612
|
|
|
34613
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34613
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/inbox-message-dao.js
|
|
34614
34614
|
function isPromiseLike(value) {
|
|
34615
34615
|
return value !== null && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
|
|
34616
34616
|
}
|
|
@@ -34783,7 +34783,7 @@ var init_migrator2 = __esm(() => {
|
|
|
34783
34783
|
init_migrator();
|
|
34784
34784
|
});
|
|
34785
34785
|
|
|
34786
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34786
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/migrate.js
|
|
34787
34787
|
async function ensureJournalTable(adapter, table3) {
|
|
34788
34788
|
await adapter.exec(`CREATE TABLE IF NOT EXISTS "${table3}" (` + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "hash text NOT NULL, " + "created_at numeric" + ")");
|
|
34789
34789
|
}
|
|
@@ -34858,7 +34858,7 @@ var init_migrate = __esm(() => {
|
|
|
34858
34858
|
init_embedded_migrations();
|
|
34859
34859
|
});
|
|
34860
34860
|
|
|
34861
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
34861
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/queue-job-dao.js
|
|
34862
34862
|
var QueueJobDao;
|
|
34863
34863
|
var init_queue_job_dao = __esm(() => {
|
|
34864
34864
|
init_drizzle_orm();
|
|
@@ -34999,7 +34999,7 @@ var init_queue_job_dao = __esm(() => {
|
|
|
34999
34999
|
};
|
|
35000
35000
|
});
|
|
35001
35001
|
|
|
35002
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
35002
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/index.js
|
|
35003
35003
|
var exports_dist = {};
|
|
35004
35004
|
__export(exports_dist, {
|
|
35005
35005
|
embeddedMigrations: () => embeddedMigrations,
|
|
@@ -37487,7 +37487,7 @@ var init_src = __esm(() => {
|
|
|
37487
37487
|
});
|
|
37488
37488
|
});
|
|
37489
37489
|
|
|
37490
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37490
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/config.js
|
|
37491
37491
|
function parseYamlObject(text3) {
|
|
37492
37492
|
let parsed;
|
|
37493
37493
|
try {
|
|
@@ -37614,7 +37614,7 @@ var init_config2 = __esm(() => {
|
|
|
37614
37614
|
};
|
|
37615
37615
|
});
|
|
37616
37616
|
|
|
37617
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37617
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
|
|
37618
37618
|
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";
|
|
37619
37619
|
import { dirname as dirname2, resolve as resolvePath3 } from "path";
|
|
37620
37620
|
function createNodeFileSystem3(root, paths) {
|
|
@@ -37701,7 +37701,7 @@ function findProjectRoot3(startDir) {
|
|
|
37701
37701
|
}
|
|
37702
37702
|
var init_file_system_node2 = () => {};
|
|
37703
37703
|
|
|
37704
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37704
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/db-errors.js
|
|
37705
37705
|
var D1NotConfiguredError2, DbModuleNotInstalledError3;
|
|
37706
37706
|
var init_db_errors2 = __esm(() => {
|
|
37707
37707
|
D1NotConfiguredError2 = class D1NotConfiguredError2 extends Error {
|
|
@@ -37718,7 +37718,7 @@ var init_db_errors2 = __esm(() => {
|
|
|
37718
37718
|
};
|
|
37719
37719
|
});
|
|
37720
37720
|
|
|
37721
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37721
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/file-system-cf.js
|
|
37722
37722
|
function createCfFileSystem2() {
|
|
37723
37723
|
return {
|
|
37724
37724
|
getProjectRoot: () => "/bundle",
|
|
@@ -37757,7 +37757,7 @@ function createCfFileSystem2() {
|
|
|
37757
37757
|
}
|
|
37758
37758
|
var UNSUPPORTED = "FileSystem is not available on Cloudflare Workers. Use D1, KV, or R2 for persistent storage.";
|
|
37759
37759
|
|
|
37760
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37760
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/runtime-cf.js
|
|
37761
37761
|
var exports_runtime_cf = {};
|
|
37762
37762
|
__export(exports_runtime_cf, {
|
|
37763
37763
|
cloudflareWorkersFactory: () => cloudflareWorkersFactory2
|
|
@@ -37795,7 +37795,7 @@ var init_runtime_cf = __esm(() => {
|
|
|
37795
37795
|
};
|
|
37796
37796
|
});
|
|
37797
37797
|
|
|
37798
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
37798
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/process-executor.js
|
|
37799
37799
|
import { isatty as isatty2 } from "tty";
|
|
37800
37800
|
|
|
37801
37801
|
class NodeProcessExecutor3 {
|
|
@@ -38181,7 +38181,7 @@ var init_process_executor2 = __esm(() => {
|
|
|
38181
38181
|
ProcessExecutor2 = NodeProcessExecutor3;
|
|
38182
38182
|
});
|
|
38183
38183
|
|
|
38184
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38184
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/runtime-node-bun.js
|
|
38185
38185
|
var exports_runtime_node_bun = {};
|
|
38186
38186
|
__export(exports_runtime_node_bun, {
|
|
38187
38187
|
nodeBunFactory: () => nodeBunFactory3,
|
|
@@ -38249,7 +38249,7 @@ var init_runtime_node_bun2 = __esm(() => {
|
|
|
38249
38249
|
};
|
|
38250
38250
|
});
|
|
38251
38251
|
|
|
38252
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38252
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/platform.js
|
|
38253
38253
|
function isCloudflareWorkerRuntime2() {
|
|
38254
38254
|
return globalThis.navigator?.userAgent?.startsWith("Cloudflare-Workers") ?? false;
|
|
38255
38255
|
}
|
|
@@ -38279,7 +38279,7 @@ function _resetRuntimeFactory2() {
|
|
|
38279
38279
|
}
|
|
38280
38280
|
var _factory, _runtimeName;
|
|
38281
38281
|
|
|
38282
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38282
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/context.js
|
|
38283
38283
|
class RuntimeContext2 {
|
|
38284
38284
|
scope;
|
|
38285
38285
|
runtimeName;
|
|
@@ -38369,7 +38369,7 @@ var init_context2 = __esm(() => {
|
|
|
38369
38369
|
init_runtime_node_bun2();
|
|
38370
38370
|
});
|
|
38371
38371
|
|
|
38372
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38372
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/path.js
|
|
38373
38373
|
function normalizeSeparators2(path7) {
|
|
38374
38374
|
return path7.replaceAll("\\", "/");
|
|
38375
38375
|
}
|
|
@@ -38492,7 +38492,7 @@ var init_path2 = __esm(() => {
|
|
|
38492
38492
|
SEP2 = globalThis.process?.platform === "win32" ? "\\" : "/";
|
|
38493
38493
|
});
|
|
38494
38494
|
|
|
38495
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38495
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/fs.js
|
|
38496
38496
|
async function ensureDirForFile2(path7, fs2 = createNodeFileSystem3()) {
|
|
38497
38497
|
await fs2.ensureDir(dirnamePath(path7));
|
|
38498
38498
|
}
|
|
@@ -38543,7 +38543,7 @@ var init_fs = __esm(() => {
|
|
|
38543
38543
|
init_path2();
|
|
38544
38544
|
});
|
|
38545
38545
|
|
|
38546
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38546
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/process-registry.js
|
|
38547
38547
|
function allocateId() {
|
|
38548
38548
|
nextIdSeq += 1;
|
|
38549
38549
|
return `pe_${Date.now().toString(36)}_${nextIdSeq.toString(36)}`;
|
|
@@ -38667,7 +38667,7 @@ function createInMemoryProcessRegistry2(options) {
|
|
|
38667
38667
|
}
|
|
38668
38668
|
var nextIdSeq = 0;
|
|
38669
38669
|
|
|
38670
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38670
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/runtime-paths.js
|
|
38671
38671
|
function ambientRuntimePaths2() {
|
|
38672
38672
|
const cwd = getProcessCwd2();
|
|
38673
38673
|
return { cwd, home: getHomeDir() ?? cwd };
|
|
@@ -38677,7 +38677,7 @@ var init_runtime_paths = __esm(() => {
|
|
|
38677
38677
|
init_path2();
|
|
38678
38678
|
});
|
|
38679
38679
|
|
|
38680
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38680
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/schema-validation.js
|
|
38681
38681
|
async function loadStructuredConfig(path7, options = {}) {
|
|
38682
38682
|
const content = await (options.fileSystem ?? createNodeFileSystem3()).readFile(path7);
|
|
38683
38683
|
return await parseStructuredConfig(content, path7, options);
|
|
@@ -38954,10 +38954,10 @@ var init_schema_validation2 = __esm(() => {
|
|
|
38954
38954
|
defaultResolve = typeof Bun !== "undefined" ? (specifier, from) => Bun.resolveSync(specifier, from) : undefined;
|
|
38955
38955
|
});
|
|
38956
38956
|
|
|
38957
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38957
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/types.js
|
|
38958
38958
|
var init_types2 = () => {};
|
|
38959
38959
|
|
|
38960
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
38960
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/index.js
|
|
38961
38961
|
var exports_dist2 = {};
|
|
38962
38962
|
__export(exports_dist2, {
|
|
38963
38963
|
writeJsonFile: () => writeJsonFile2,
|
|
@@ -41108,7 +41108,7 @@ var init_mod = __esm(() => {
|
|
|
41108
41108
|
init_config3();
|
|
41109
41109
|
});
|
|
41110
41110
|
|
|
41111
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
41111
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/logger.js
|
|
41112
41112
|
function toLogTapeLevel(level) {
|
|
41113
41113
|
return level === "warn" ? "warning" : level;
|
|
41114
41114
|
}
|
|
@@ -42661,7 +42661,7 @@ var require_src = __commonJS((exports) => {
|
|
|
42661
42661
|
};
|
|
42662
42662
|
});
|
|
42663
42663
|
|
|
42664
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
42664
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/telemetry/sdk.js
|
|
42665
42665
|
function getTelemetryConfig(configPartial = {}) {
|
|
42666
42666
|
return {
|
|
42667
42667
|
enabled: configPartial.enabled ?? CONFIG_DEFAULTS.enabled,
|
|
@@ -42697,7 +42697,7 @@ var init_sdk = __esm(() => {
|
|
|
42697
42697
|
resolvedConfig = getTelemetryConfig();
|
|
42698
42698
|
});
|
|
42699
42699
|
|
|
42700
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
42700
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/telemetry/tracing.js
|
|
42701
42701
|
function isSuppressed(tracer2) {
|
|
42702
42702
|
return tracer2 === undefined && !getResolvedConfig().enabled;
|
|
42703
42703
|
}
|
|
@@ -42737,7 +42737,7 @@ var init_tracing2 = __esm(() => {
|
|
|
42737
42737
|
import_api2 = __toESM(require_src(), 1);
|
|
42738
42738
|
});
|
|
42739
42739
|
|
|
42740
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
42740
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/telemetry/metrics.js
|
|
42741
42741
|
function getMeter() {
|
|
42742
42742
|
return import_api3.metrics.getMeter(METER_NAME, METER_VERSION);
|
|
42743
42743
|
}
|
|
@@ -42834,7 +42834,7 @@ var init_metrics = __esm(() => {
|
|
|
42834
42834
|
instruments = {};
|
|
42835
42835
|
});
|
|
42836
42836
|
|
|
42837
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
42837
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/event-bus/event-bus.js
|
|
42838
42838
|
function busLogger() {
|
|
42839
42839
|
if (!_busLogger)
|
|
42840
42840
|
_busLogger = getLogger2("event-bus");
|
|
@@ -43079,7 +43079,7 @@ var init_event_bus = __esm(() => {
|
|
|
43079
43079
|
init_metrics();
|
|
43080
43080
|
});
|
|
43081
43081
|
|
|
43082
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
43082
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/event-bus/default-observers.js
|
|
43083
43083
|
function obsLogger() {
|
|
43084
43084
|
if (!_obsLogger)
|
|
43085
43085
|
_obsLogger = getLogger2("event-bus.observers");
|
|
@@ -43143,7 +43143,7 @@ var init_default_observers = __esm(() => {
|
|
|
43143
43143
|
init_event_bus();
|
|
43144
43144
|
});
|
|
43145
43145
|
|
|
43146
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
43146
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/event-bus/file-observer.js
|
|
43147
43147
|
function parentDir(filePath) {
|
|
43148
43148
|
const idx = filePath.lastIndexOf("/");
|
|
43149
43149
|
return idx <= 0 ? "." : filePath.slice(0, idx);
|
|
@@ -43241,7 +43241,7 @@ var init_file_observer = __esm(() => {
|
|
|
43241
43241
|
init_logger3();
|
|
43242
43242
|
});
|
|
43243
43243
|
|
|
43244
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
43244
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/internals/drain.js
|
|
43245
43245
|
function settleWithin(promise2, deadline) {
|
|
43246
43246
|
const remaining = deadline - Date.now();
|
|
43247
43247
|
if (remaining <= 0)
|
|
@@ -43256,7 +43256,7 @@ function settleWithin(promise2, deadline) {
|
|
|
43256
43256
|
return settled;
|
|
43257
43257
|
}
|
|
43258
43258
|
|
|
43259
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
43259
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/scheduler/node.js
|
|
43260
43260
|
function parseInterval(cron) {
|
|
43261
43261
|
const trimmed = cron.trim();
|
|
43262
43262
|
const num = Number(trimmed);
|
|
@@ -43349,7 +43349,7 @@ var init_node3 = __esm(() => {
|
|
|
43349
43349
|
init_metrics();
|
|
43350
43350
|
});
|
|
43351
43351
|
|
|
43352
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
43352
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/scheduler-node.js
|
|
43353
43353
|
var exports_scheduler_node = {};
|
|
43354
43354
|
__export(exports_scheduler_node, {
|
|
43355
43355
|
NodeSchedulerAdapter: () => NodeSchedulerAdapter
|
|
@@ -50209,6 +50209,23 @@ var init_workflow_run_log_sink = __esm(() => {
|
|
|
50209
50209
|
];
|
|
50210
50210
|
});
|
|
50211
50211
|
|
|
50212
|
+
// ../../packages/domain/src/analytics/artifact.ts
|
|
50213
|
+
import { createHash } from "crypto";
|
|
50214
|
+
function selectorDigest(selector) {
|
|
50215
|
+
const canonical = {
|
|
50216
|
+
runId: selector.runId ?? null,
|
|
50217
|
+
sessionId: selector.sessionId ?? null,
|
|
50218
|
+
since: selector.since ?? null,
|
|
50219
|
+
sources: selector.sources ? [...selector.sources].sort() : null,
|
|
50220
|
+
taskWbs: selector.taskWbs ?? null,
|
|
50221
|
+
until: selector.until ?? null
|
|
50222
|
+
};
|
|
50223
|
+
const json2 = JSON.stringify(canonical);
|
|
50224
|
+
return createHash("sha256").update(json2).digest("hex").slice(0, 8);
|
|
50225
|
+
}
|
|
50226
|
+
var HISTORY_ARTIFACT_SCHEMA_VERSION = 1;
|
|
50227
|
+
var init_artifact = () => {};
|
|
50228
|
+
|
|
50212
50229
|
// ../../packages/domain/src/analytics/models.ts
|
|
50213
50230
|
function resolvePricing(model) {
|
|
50214
50231
|
if (model === undefined || model.length === 0)
|
|
@@ -50255,51 +50272,6 @@ function computeRecordCost(record2) {
|
|
|
50255
50272
|
const costUsd = record2.inputTokens / 1e6 * pricing.inputPricePer1M + record2.outputTokens / 1e6 * pricing.outputPricePer1M;
|
|
50256
50273
|
return { ...record2, costUsd };
|
|
50257
50274
|
}
|
|
50258
|
-
function emptyTotals() {
|
|
50259
|
-
return {
|
|
50260
|
-
inputTokens: 0,
|
|
50261
|
-
outputTokens: 0,
|
|
50262
|
-
cacheReadTokens: 0,
|
|
50263
|
-
cacheCreationTokens: 0,
|
|
50264
|
-
costUsd: 0,
|
|
50265
|
-
records: 0,
|
|
50266
|
-
recordsWithUsage: 0
|
|
50267
|
-
};
|
|
50268
|
-
}
|
|
50269
|
-
function accumulate(bucket, record2) {
|
|
50270
|
-
bucket.inputTokens += record2.inputTokens;
|
|
50271
|
-
bucket.outputTokens += record2.outputTokens;
|
|
50272
|
-
bucket.cacheReadTokens += record2.cacheReadTokens;
|
|
50273
|
-
bucket.cacheCreationTokens += record2.cacheCreationTokens;
|
|
50274
|
-
bucket.costUsd += record2.costUsd;
|
|
50275
|
-
bucket.records += 1;
|
|
50276
|
-
if (record2.usageReported)
|
|
50277
|
-
bucket.recordsWithUsage += 1;
|
|
50278
|
-
}
|
|
50279
|
-
function aggregateCosts(records) {
|
|
50280
|
-
const summary = {
|
|
50281
|
-
totals: emptyTotals(),
|
|
50282
|
-
bySource: {},
|
|
50283
|
-
byModel: {},
|
|
50284
|
-
daily: []
|
|
50285
|
-
};
|
|
50286
|
-
const dailyMap = new Map;
|
|
50287
|
-
for (const record2 of records) {
|
|
50288
|
-
accumulate(summary.totals, record2);
|
|
50289
|
-
summary.bySource[record2.source] ??= emptyTotals();
|
|
50290
|
-
accumulate(summary.bySource[record2.source], record2);
|
|
50291
|
-
summary.byModel[record2.model] ??= emptyTotals();
|
|
50292
|
-
accumulate(summary.byModel[record2.model], record2);
|
|
50293
|
-
let dailyEntry = dailyMap.get(record2.date);
|
|
50294
|
-
if (dailyEntry === undefined) {
|
|
50295
|
-
dailyEntry = { date: record2.date, ...emptyTotals() };
|
|
50296
|
-
dailyMap.set(record2.date, dailyEntry);
|
|
50297
|
-
}
|
|
50298
|
-
accumulate(dailyEntry, record2);
|
|
50299
|
-
}
|
|
50300
|
-
summary.daily = [...dailyMap.values()].sort(byDateAsc);
|
|
50301
|
-
return summary;
|
|
50302
|
-
}
|
|
50303
50275
|
function cacheHitRatio(totals) {
|
|
50304
50276
|
if (totals.recordsWithUsage === 0)
|
|
50305
50277
|
return null;
|
|
@@ -50334,9 +50306,6 @@ function formatSummary(summary) {
|
|
|
50334
50306
|
function formatRatio(ratio) {
|
|
50335
50307
|
return ratio === null ? "n/a" : `${(ratio * 100).toFixed(1)}%`;
|
|
50336
50308
|
}
|
|
50337
|
-
function byDateAsc(a2, b) {
|
|
50338
|
-
return a2.date.localeCompare(b.date);
|
|
50339
|
-
}
|
|
50340
50309
|
function byCostDesc([, a2], [, b]) {
|
|
50341
50310
|
return b.costUsd - a2.costUsd;
|
|
50342
50311
|
}
|
|
@@ -50344,6 +50313,177 @@ var init_costs = __esm(() => {
|
|
|
50344
50313
|
init_models();
|
|
50345
50314
|
});
|
|
50346
50315
|
|
|
50316
|
+
// ../../packages/domain/src/analytics/forensic-query.ts
|
|
50317
|
+
function buildMessageWhere(sel) {
|
|
50318
|
+
const clauses = [];
|
|
50319
|
+
const params = [];
|
|
50320
|
+
if (sel.since != null) {
|
|
50321
|
+
clauses.push("m.ts >= ?");
|
|
50322
|
+
params.push(sel.since);
|
|
50323
|
+
}
|
|
50324
|
+
if (sel.until != null) {
|
|
50325
|
+
clauses.push("m.ts <= ?");
|
|
50326
|
+
params.push(sel.until);
|
|
50327
|
+
}
|
|
50328
|
+
if (sel.sources != null && sel.sources.length > 0) {
|
|
50329
|
+
clauses.push(`m.source IN (${sel.sources.map(() => "?").join(", ")})`);
|
|
50330
|
+
params.push(...sel.sources);
|
|
50331
|
+
}
|
|
50332
|
+
if (sel.sessionId != null) {
|
|
50333
|
+
clauses.push("m.session_id = ?");
|
|
50334
|
+
params.push(sel.sessionId);
|
|
50335
|
+
}
|
|
50336
|
+
if (sel.runId != null) {
|
|
50337
|
+
clauses.push("m.provenance = 'spur-run'");
|
|
50338
|
+
clauses.push("m.run_id = ?");
|
|
50339
|
+
params.push(sel.runId);
|
|
50340
|
+
}
|
|
50341
|
+
if (sel.taskWbs != null) {
|
|
50342
|
+
clauses.push("m.provenance = 'spur-run'");
|
|
50343
|
+
clauses.push("m.task_wbs = ?");
|
|
50344
|
+
params.push(sel.taskWbs);
|
|
50345
|
+
}
|
|
50346
|
+
return { where: clauses.length > 0 ? `WHERE ${clauses.join(" AND ")}` : "", params };
|
|
50347
|
+
}
|
|
50348
|
+
async function messageRollup(db2, sel) {
|
|
50349
|
+
const { where, params } = buildMessageWhere(sel);
|
|
50350
|
+
return db2.queryAll(`SELECT m.source AS source, m.model AS model, DATE(m.ts) AS day,
|
|
50351
|
+
COUNT(*) AS messages,
|
|
50352
|
+
SUM(m.input_tokens) AS inputTokens,
|
|
50353
|
+
SUM(m.output_tokens) AS outputTokens,
|
|
50354
|
+
SUM(m.cache_read_tokens) AS cacheReadTokens,
|
|
50355
|
+
SUM(m.cache_write_tokens) AS cacheWriteTokens,
|
|
50356
|
+
SUM(m.cost_usd) AS costUsd,
|
|
50357
|
+
SUM(CASE WHEN m.input_tokens IS NOT NULL OR m.output_tokens IS NOT NULL THEN 1 ELSE 0 END) AS recordsWithUsage
|
|
50358
|
+
FROM history_message m
|
|
50359
|
+
${where}
|
|
50360
|
+
GROUP BY m.source, m.model, DATE(m.ts)`, ...params);
|
|
50361
|
+
}
|
|
50362
|
+
async function toolRollup(db2, sel) {
|
|
50363
|
+
const { where, params } = buildMessageWhere(sel);
|
|
50364
|
+
return db2.queryAll(`SELECT m.source AS source, m.model AS model, DATE(m.ts) AS day,
|
|
50365
|
+
COUNT(*) AS toolCalls,
|
|
50366
|
+
SUM(tc.duration_ms) AS durationMs,
|
|
50367
|
+
SUM(tc.duration_ms IS NULL) AS durationUnmeasured
|
|
50368
|
+
FROM history_tool_call tc
|
|
50369
|
+
JOIN history_message m ON m.record_hash = tc.message_hash
|
|
50370
|
+
${where}
|
|
50371
|
+
GROUP BY m.source, m.model, DATE(m.ts)`, ...params);
|
|
50372
|
+
}
|
|
50373
|
+
async function byTool(db2, sel, top) {
|
|
50374
|
+
const { where, params } = buildMessageWhere(sel);
|
|
50375
|
+
return db2.queryAll(`SELECT tc.tool_name AS toolName,
|
|
50376
|
+
COUNT(*) AS calls,
|
|
50377
|
+
SUM(tc.status = 'error') AS errors,
|
|
50378
|
+
SUM(tc.duration_ms) AS durationMsTotal,
|
|
50379
|
+
CAST(AVG(tc.duration_ms) AS INT) AS durationMsMean,
|
|
50380
|
+
MAX(tc.duration_ms) AS durationMsMax,
|
|
50381
|
+
SUM(tc.duration_ms IS NULL) AS durationUnmeasured,
|
|
50382
|
+
SUM(tc.result_bytes) AS resultBytes
|
|
50383
|
+
FROM history_tool_call tc
|
|
50384
|
+
JOIN history_message m ON m.record_hash = tc.message_hash
|
|
50385
|
+
${where}
|
|
50386
|
+
GROUP BY tc.tool_name
|
|
50387
|
+
ORDER BY durationMsTotal DESC
|
|
50388
|
+
LIMIT ?`, ...params, top);
|
|
50389
|
+
}
|
|
50390
|
+
async function bySession(db2, sel, top) {
|
|
50391
|
+
const { where, params } = buildMessageWhere(sel);
|
|
50392
|
+
const msgRows = await db2.queryAll(`SELECT m.session_id AS sessionId, m.source AS source,
|
|
50393
|
+
MIN(m.ts) AS startedAt,
|
|
50394
|
+
COUNT(*) AS messages,
|
|
50395
|
+
SUM(m.input_tokens + m.output_tokens) AS tokens,
|
|
50396
|
+
SUM(m.cost_usd) AS costUsd
|
|
50397
|
+
FROM history_message m
|
|
50398
|
+
${where}
|
|
50399
|
+
GROUP BY m.session_id, m.source
|
|
50400
|
+
ORDER BY tokens DESC
|
|
50401
|
+
LIMIT ?`, ...params, top);
|
|
50402
|
+
if (msgRows.length === 0)
|
|
50403
|
+
return [];
|
|
50404
|
+
const toolRows = await db2.queryAll(`SELECT m.session_id AS sessionId, m.source AS source,
|
|
50405
|
+
tc.tool_name AS toolName,
|
|
50406
|
+
COUNT(*) AS cnt
|
|
50407
|
+
FROM history_tool_call tc
|
|
50408
|
+
JOIN history_message m ON m.record_hash = tc.message_hash
|
|
50409
|
+
${where}
|
|
50410
|
+
GROUP BY m.session_id, m.source, tc.tool_name`, ...params);
|
|
50411
|
+
const toolMap = new Map;
|
|
50412
|
+
for (const row of toolRows) {
|
|
50413
|
+
const key = `${row.sessionId}\x00${row.source}`;
|
|
50414
|
+
let tools = toolMap.get(key);
|
|
50415
|
+
if (!tools) {
|
|
50416
|
+
tools = new Map;
|
|
50417
|
+
toolMap.set(key, tools);
|
|
50418
|
+
}
|
|
50419
|
+
tools.set(row.toolName, (tools.get(row.toolName) ?? 0) + row.cnt);
|
|
50420
|
+
}
|
|
50421
|
+
return msgRows.map((msg) => {
|
|
50422
|
+
const key = `${msg.sessionId}\x00${msg.source}`;
|
|
50423
|
+
const tools = toolMap.get(key);
|
|
50424
|
+
let toolCalls = 0;
|
|
50425
|
+
let topTool = null;
|
|
50426
|
+
let maxCount = -1;
|
|
50427
|
+
if (tools) {
|
|
50428
|
+
for (const [name, count3] of tools) {
|
|
50429
|
+
toolCalls += count3;
|
|
50430
|
+
if (topTool === null || count3 > maxCount || count3 === maxCount && name < topTool) {
|
|
50431
|
+
maxCount = count3;
|
|
50432
|
+
topTool = name;
|
|
50433
|
+
}
|
|
50434
|
+
}
|
|
50435
|
+
}
|
|
50436
|
+
return {
|
|
50437
|
+
sessionId: msg.sessionId,
|
|
50438
|
+
source: msg.source,
|
|
50439
|
+
startedAt: msg.startedAt,
|
|
50440
|
+
messages: msg.messages,
|
|
50441
|
+
toolCalls,
|
|
50442
|
+
topTool,
|
|
50443
|
+
tokens: msg.tokens,
|
|
50444
|
+
costUsd: msg.costUsd
|
|
50445
|
+
};
|
|
50446
|
+
});
|
|
50447
|
+
}
|
|
50448
|
+
async function loops(db2, sel) {
|
|
50449
|
+
const { where, params } = buildMessageWhere(sel);
|
|
50450
|
+
const extra = where === "" ? "WHERE tc.args_digest IS NOT NULL" : `${where} AND tc.args_digest IS NOT NULL`;
|
|
50451
|
+
return db2.queryAll(`SELECT tc.session_id AS sessionId, tc.tool_name AS toolName,
|
|
50452
|
+
tc.args_digest AS argsDigest,
|
|
50453
|
+
COUNT(*) AS repeats,
|
|
50454
|
+
MIN(tc.seq) AS firstSeq,
|
|
50455
|
+
MAX(tc.seq) AS lastSeq
|
|
50456
|
+
FROM history_tool_call tc
|
|
50457
|
+
JOIN history_message m ON m.record_hash = tc.message_hash
|
|
50458
|
+
${extra}
|
|
50459
|
+
GROUP BY tc.session_id, tc.tool_name, tc.args_digest
|
|
50460
|
+
HAVING COUNT(*) >= 3
|
|
50461
|
+
ORDER BY repeats DESC`, ...params);
|
|
50462
|
+
}
|
|
50463
|
+
async function drift(db2, sel) {
|
|
50464
|
+
const { where, params } = buildMessageWhere(sel);
|
|
50465
|
+
const extra = where === "" ? "WHERE m.disposition = 'unknown'" : `${where} AND m.disposition = 'unknown'`;
|
|
50466
|
+
return db2.queryAll(`SELECT m.source AS source, m.record_type AS recordType, COUNT(*) AS n
|
|
50467
|
+
FROM history_message m
|
|
50468
|
+
${extra}
|
|
50469
|
+
GROUP BY m.source, m.record_type
|
|
50470
|
+
ORDER BY n DESC`, ...params);
|
|
50471
|
+
}
|
|
50472
|
+
async function sourceSummary(db2, sel) {
|
|
50473
|
+
const { where, params } = buildMessageWhere(sel);
|
|
50474
|
+
return db2.queryAll(`SELECT m.source AS source,
|
|
50475
|
+
COUNT(DISTINCT m.source_file) AS files,
|
|
50476
|
+
COUNT(*) AS messages,
|
|
50477
|
+
MAX(m.imported_at) AS lastImportedAt
|
|
50478
|
+
FROM history_message m
|
|
50479
|
+
${where}
|
|
50480
|
+
GROUP BY m.source`, ...params);
|
|
50481
|
+
}
|
|
50482
|
+
async function countCheckpointsBySource(db2, source) {
|
|
50483
|
+
const row = await db2.queryFirst("SELECT COUNT(*) AS cnt FROM history_import_checkpoint WHERE source = ?", source);
|
|
50484
|
+
return row?.cnt ?? 0;
|
|
50485
|
+
}
|
|
50486
|
+
|
|
50347
50487
|
// ../../packages/domain/src/analytics/query.ts
|
|
50348
50488
|
function parsePayload(raw, table3) {
|
|
50349
50489
|
try {
|
|
@@ -50358,18 +50498,6 @@ async function queryEtlRecords(db2, sourceTable, since) {
|
|
|
50358
50498
|
const rows = since !== undefined ? await db2.queryAll(`SELECT payload_json FROM ${sourceTable} WHERE imported_at >= ?`, since) : await db2.queryAll(`SELECT payload_json FROM ${sourceTable}`);
|
|
50359
50499
|
return rows.map((row) => parsePayload(row.payload_json, sourceTable));
|
|
50360
50500
|
}
|
|
50361
|
-
async function queryAllEtlRecords(db2, since) {
|
|
50362
|
-
const results = [];
|
|
50363
|
-
for (const table3 of SOURCE_TABLES) {
|
|
50364
|
-
const source = table3.replace("history_etl_", "");
|
|
50365
|
-
const rows = since !== undefined ? await db2.queryAll(`SELECT payload_json FROM ${table3} WHERE imported_at >= ?`, since) : await db2.queryAll(`SELECT payload_json FROM ${table3}`);
|
|
50366
|
-
for (const row of rows) {
|
|
50367
|
-
const payload = parsePayload(row.payload_json, table3);
|
|
50368
|
-
results.push(etlToCostRecord(payload, source));
|
|
50369
|
-
}
|
|
50370
|
-
}
|
|
50371
|
-
return results;
|
|
50372
|
-
}
|
|
50373
50501
|
function extractClaudeTokens(payload) {
|
|
50374
50502
|
const usage = payload.usage;
|
|
50375
50503
|
const absent = {
|
|
@@ -50393,26 +50521,6 @@ function extractClaudeTokens(payload) {
|
|
|
50393
50521
|
usageReported: true
|
|
50394
50522
|
};
|
|
50395
50523
|
}
|
|
50396
|
-
function etlToCostRecord(payload, source) {
|
|
50397
|
-
const tokens = extractClaudeTokens(payload);
|
|
50398
|
-
if (tokens.inputTokens === 0 && tokens.outputTokens === 0) {
|
|
50399
|
-
const contentLength = payload.content?.length ?? 0;
|
|
50400
|
-
if (contentLength > 0) {
|
|
50401
|
-
tokens.outputTokens = Math.ceil(contentLength / 4);
|
|
50402
|
-
}
|
|
50403
|
-
}
|
|
50404
|
-
return {
|
|
50405
|
-
source,
|
|
50406
|
-
date: payload.created_at?.slice(0, 10) ?? "unknown",
|
|
50407
|
-
model: payload.model ?? "unknown",
|
|
50408
|
-
inputTokens: tokens.inputTokens,
|
|
50409
|
-
outputTokens: tokens.outputTokens,
|
|
50410
|
-
cacheReadTokens: tokens.cacheReadTokens,
|
|
50411
|
-
cacheCreationTokens: tokens.cacheCreationTokens,
|
|
50412
|
-
usageReported: tokens.usageReported,
|
|
50413
|
-
costUsd: 0
|
|
50414
|
-
};
|
|
50415
|
-
}
|
|
50416
50524
|
var SOURCE_TABLES;
|
|
50417
50525
|
var init_query2 = __esm(() => {
|
|
50418
50526
|
SOURCE_TABLES = [
|
|
@@ -50422,10 +50530,144 @@ var init_query2 = __esm(() => {
|
|
|
50422
50530
|
"history_etl_gemini",
|
|
50423
50531
|
"history_etl_opencode",
|
|
50424
50532
|
"history_etl_antigravity",
|
|
50425
|
-
"history_etl_openclaw"
|
|
50533
|
+
"history_etl_openclaw",
|
|
50534
|
+
"history_etl_omp",
|
|
50535
|
+
"history_etl_grok",
|
|
50536
|
+
"history_etl_agy"
|
|
50426
50537
|
];
|
|
50427
50538
|
});
|
|
50428
50539
|
|
|
50540
|
+
// ../../packages/domain/src/analytics/render-report.ts
|
|
50541
|
+
function assertArtifactVersion(actualVersion, artifactPath, expectedVersion = HISTORY_ARTIFACT_SCHEMA_VERSION) {
|
|
50542
|
+
if (actualVersion !== expectedVersion) {
|
|
50543
|
+
throw new ArtifactVersionError(artifactPath, expectedVersion, actualVersion);
|
|
50544
|
+
}
|
|
50545
|
+
}
|
|
50546
|
+
function fmtDur(ms) {
|
|
50547
|
+
return ms >= 1000 ? `${(ms / 1000).toFixed(1)}s` : `${Math.round(ms)}ms`;
|
|
50548
|
+
}
|
|
50549
|
+
function fmtDurOrNa(ms, bucket) {
|
|
50550
|
+
const allUnmeasured = bucket.toolCalls > 0 && bucket.durationUnmeasured === bucket.toolCalls;
|
|
50551
|
+
return allUnmeasured ? "n/a" : fmtDur(ms);
|
|
50552
|
+
}
|
|
50553
|
+
function fmtBytes(bytes) {
|
|
50554
|
+
if (bytes >= 1e6)
|
|
50555
|
+
return `${(bytes / 1e6).toFixed(1)} MB`;
|
|
50556
|
+
if (bytes >= 1000)
|
|
50557
|
+
return `${(bytes / 1000).toFixed(1)} KB`;
|
|
50558
|
+
return `${bytes} B`;
|
|
50559
|
+
}
|
|
50560
|
+
function artifactToSummary(artifact) {
|
|
50561
|
+
return {
|
|
50562
|
+
totals: artifact.totals,
|
|
50563
|
+
bySource: artifact.bySource,
|
|
50564
|
+
byModel: artifact.byModel,
|
|
50565
|
+
daily: artifact.daily
|
|
50566
|
+
};
|
|
50567
|
+
}
|
|
50568
|
+
function renderByTool(artifact) {
|
|
50569
|
+
const lines = ["Per-tool time \xB7 calls \xB7 result bytes:"];
|
|
50570
|
+
if (artifact.byTool.length === 0) {
|
|
50571
|
+
lines.push(" (no tool calls in selection)");
|
|
50572
|
+
return lines;
|
|
50573
|
+
}
|
|
50574
|
+
for (const t of artifact.byTool) {
|
|
50575
|
+
const bucket = { durationUnmeasured: t.durationUnmeasured, toolCalls: t.calls };
|
|
50576
|
+
lines.push(` ${t.toolName.slice(0, 26).padEnd(26)} ` + `${String(t.calls).padStart(6)} calls ${String(t.errors).padStart(5)} err ` + `${fmtDurOrNa(t.durationMsTotal, bucket).padStart(8)} total ` + `${fmtDurOrNa(t.durationMsMean, bucket).padStart(7)} mean ` + `${fmtDurOrNa(t.durationMsMax, bucket).padStart(7)} max ` + `${fmtBytes(t.resultBytes).padStart(9)}`);
|
|
50577
|
+
}
|
|
50578
|
+
return lines;
|
|
50579
|
+
}
|
|
50580
|
+
function renderLoops(artifact) {
|
|
50581
|
+
const lines = [`Detected loops (${artifact.loops.length}):`];
|
|
50582
|
+
if (artifact.loops.length === 0) {
|
|
50583
|
+
lines.push(" (none detected)");
|
|
50584
|
+
return lines;
|
|
50585
|
+
}
|
|
50586
|
+
for (const l of artifact.loops) {
|
|
50587
|
+
lines.push(` ${l.toolName.slice(0, 22).padEnd(22)} x${String(l.repeats).padStart(3)} ` + `${l.sessionId.slice(0, 16)} args ${l.argsDigest} seq ${l.firstSeq}-${l.lastSeq}`);
|
|
50588
|
+
}
|
|
50589
|
+
return lines;
|
|
50590
|
+
}
|
|
50591
|
+
function renderBySession(artifact) {
|
|
50592
|
+
const lines = [`Session leaderboard (${artifact.bySession.length}):`];
|
|
50593
|
+
if (artifact.bySession.length === 0) {
|
|
50594
|
+
lines.push(" (no sessions in selection)");
|
|
50595
|
+
return lines;
|
|
50596
|
+
}
|
|
50597
|
+
for (const s of artifact.bySession) {
|
|
50598
|
+
const tokens = (s.tokens / 1e6).toFixed(1);
|
|
50599
|
+
lines.push(` ${s.sessionId.slice(0, 18).padEnd(18)} ` + `${s.source.slice(0, 8).padEnd(8)} ` + `${String(s.messages).padStart(5)} msg ${String(s.toolCalls).padStart(5)} calls ` + `${tokens.padStart(6)}M tok $${s.costUsd.toFixed(2).padStart(7)}` + (s.topTool ? ` top: ${s.topTool}` : ""));
|
|
50600
|
+
}
|
|
50601
|
+
return lines;
|
|
50602
|
+
}
|
|
50603
|
+
function renderCoverage(artifact) {
|
|
50604
|
+
const lines = ["Coverage:"];
|
|
50605
|
+
if (artifact.coverage.length === 0) {
|
|
50606
|
+
lines.push(" (no sources)");
|
|
50607
|
+
return lines;
|
|
50608
|
+
}
|
|
50609
|
+
for (const c3 of artifact.coverage) {
|
|
50610
|
+
lines.push(` ${c3.source.slice(0, 12).padEnd(12)} ${c3.status.padEnd(7)} ` + `${String(c3.files).padStart(5)} files ${String(c3.messages).padStart(6)} msg ` + `${String(c3.toolCalls).padStart(6)} calls ${String(c3.unknownRecords).padStart(5)} unknown`);
|
|
50611
|
+
}
|
|
50612
|
+
return lines;
|
|
50613
|
+
}
|
|
50614
|
+
function renderReport(artifact) {
|
|
50615
|
+
const lines = [];
|
|
50616
|
+
lines.push(`History report \u2014 generated ${artifact.generatedAt}`);
|
|
50617
|
+
lines.push(`spur ${artifact.spurVersion} \xB7 schema v${artifact.schemaVersion}`);
|
|
50618
|
+
lines.push("");
|
|
50619
|
+
lines.push(formatSummary(artifactToSummary(artifact)));
|
|
50620
|
+
lines.push("");
|
|
50621
|
+
lines.push(...renderByTool(artifact));
|
|
50622
|
+
lines.push("");
|
|
50623
|
+
lines.push(...renderLoops(artifact));
|
|
50624
|
+
lines.push("");
|
|
50625
|
+
lines.push(...renderBySession(artifact));
|
|
50626
|
+
lines.push("");
|
|
50627
|
+
lines.push(...renderCoverage(artifact));
|
|
50628
|
+
return lines.join(`
|
|
50629
|
+
`);
|
|
50630
|
+
}
|
|
50631
|
+
function renderMarkdown(artifact) {
|
|
50632
|
+
const header = `<!-- Generated by spur history report \xB7 schema v${artifact.schemaVersion} \xB7 ${artifact.generatedAt} -->`;
|
|
50633
|
+
const body = renderReport(artifact);
|
|
50634
|
+
return `${header}
|
|
50635
|
+
|
|
50636
|
+
\`\`\`
|
|
50637
|
+
${body}
|
|
50638
|
+
\`\`\`
|
|
50639
|
+
`;
|
|
50640
|
+
}
|
|
50641
|
+
function isStale(generatedAt, now2, thresholdHours = STALENESS_THRESHOLD_HOURS) {
|
|
50642
|
+
const ageMs = now2.getTime() - new Date(generatedAt).getTime();
|
|
50643
|
+
return ageMs > thresholdHours * 60 * 60 * 1000;
|
|
50644
|
+
}
|
|
50645
|
+
function stalenessBanner(generatedAt, now2, thresholdHours = STALENESS_THRESHOLD_HOURS) {
|
|
50646
|
+
if (!isStale(generatedAt, now2, thresholdHours))
|
|
50647
|
+
return null;
|
|
50648
|
+
const ageHours = (now2.getTime() - new Date(generatedAt).getTime()) / (60 * 60 * 1000);
|
|
50649
|
+
const readable2 = ageHours >= 24 ? `${(ageHours / 24).toFixed(1)} days` : `${Math.round(ageHours)} hours`;
|
|
50650
|
+
return `\u26A0 STALE ARTIFACT \u2014 generated ${readable2} ago (threshold ${thresholdHours}h).
|
|
50651
|
+
` + "Re-run `spur history analyze` to refresh. This banner means the daily loop may have stopped.\n";
|
|
50652
|
+
}
|
|
50653
|
+
var ArtifactVersionError, STALENESS_THRESHOLD_HOURS = 36;
|
|
50654
|
+
var init_render_report = __esm(() => {
|
|
50655
|
+
init_artifact();
|
|
50656
|
+
init_costs();
|
|
50657
|
+
ArtifactVersionError = class ArtifactVersionError extends Error {
|
|
50658
|
+
artifactPath;
|
|
50659
|
+
expectedVersion;
|
|
50660
|
+
actualVersion;
|
|
50661
|
+
constructor(artifactPath, expectedVersion, actualVersion) {
|
|
50662
|
+
super(`Artifact ${artifactPath} has schemaVersion ${actualVersion}; this renderer understands version ${expectedVersion} only. ` + "Re-run `spur history analyze` to regenerate, or install a newer Spur.");
|
|
50663
|
+
this.name = "ArtifactVersionError";
|
|
50664
|
+
this.artifactPath = artifactPath;
|
|
50665
|
+
this.expectedVersion = expectedVersion;
|
|
50666
|
+
this.actualVersion = actualVersion;
|
|
50667
|
+
}
|
|
50668
|
+
};
|
|
50669
|
+
});
|
|
50670
|
+
|
|
50429
50671
|
// ../../packages/domain/src/analytics/run-cost.ts
|
|
50430
50672
|
function extractSessionId(action) {
|
|
50431
50673
|
if (!action.result_json)
|
|
@@ -50503,17 +50745,56 @@ function actionCost(matchedRecords, source) {
|
|
|
50503
50745
|
}
|
|
50504
50746
|
const costRecords = [];
|
|
50505
50747
|
for (const payload of matchedRecords) {
|
|
50506
|
-
|
|
50507
|
-
costRecords.push(computeRecordCost(record2));
|
|
50748
|
+
costRecords.push(computeRecordCost(payloadToCostRecord(payload, source)));
|
|
50508
50749
|
}
|
|
50509
|
-
const
|
|
50510
|
-
const cacheHit = cacheHitRatio(
|
|
50750
|
+
const totals = foldTotals(costRecords);
|
|
50751
|
+
const cacheHit = cacheHitRatio(totals);
|
|
50511
50752
|
return {
|
|
50512
|
-
totals
|
|
50753
|
+
totals,
|
|
50513
50754
|
cacheHit,
|
|
50514
50755
|
estimated: false
|
|
50515
50756
|
};
|
|
50516
50757
|
}
|
|
50758
|
+
function foldTotals(records) {
|
|
50759
|
+
const totals = {
|
|
50760
|
+
inputTokens: 0,
|
|
50761
|
+
outputTokens: 0,
|
|
50762
|
+
cacheReadTokens: 0,
|
|
50763
|
+
cacheWriteTokens: 0,
|
|
50764
|
+
costUsd: 0,
|
|
50765
|
+
records: 0,
|
|
50766
|
+
recordsWithUsage: 0,
|
|
50767
|
+
messages: 0,
|
|
50768
|
+
toolCalls: 0,
|
|
50769
|
+
durationMs: 0,
|
|
50770
|
+
durationUnmeasured: 0
|
|
50771
|
+
};
|
|
50772
|
+
for (const record2 of records) {
|
|
50773
|
+
totals.inputTokens += record2.inputTokens;
|
|
50774
|
+
totals.outputTokens += record2.outputTokens;
|
|
50775
|
+
totals.cacheReadTokens += record2.cacheReadTokens;
|
|
50776
|
+
totals.cacheWriteTokens += record2.cacheCreationTokens;
|
|
50777
|
+
totals.costUsd += record2.costUsd;
|
|
50778
|
+
totals.records += 1;
|
|
50779
|
+
if (record2.usageReported)
|
|
50780
|
+
totals.recordsWithUsage += 1;
|
|
50781
|
+
}
|
|
50782
|
+
return totals;
|
|
50783
|
+
}
|
|
50784
|
+
function payloadToCostRecord(payload, source) {
|
|
50785
|
+
const tokens = extractClaudeTokens(payload);
|
|
50786
|
+
return {
|
|
50787
|
+
source,
|
|
50788
|
+
date: payload.created_at?.slice(0, 10) ?? "unknown",
|
|
50789
|
+
model: payload.model ?? "unknown",
|
|
50790
|
+
inputTokens: tokens.inputTokens,
|
|
50791
|
+
outputTokens: tokens.outputTokens,
|
|
50792
|
+
cacheReadTokens: tokens.cacheReadTokens,
|
|
50793
|
+
cacheCreationTokens: tokens.cacheCreationTokens,
|
|
50794
|
+
usageReported: tokens.usageReported,
|
|
50795
|
+
costUsd: 0
|
|
50796
|
+
};
|
|
50797
|
+
}
|
|
50517
50798
|
function actionCostEstimated(matchedRecords, source) {
|
|
50518
50799
|
const cost = actionCost(matchedRecords, source);
|
|
50519
50800
|
return matchedRecords.length === 0 ? cost : { ...cost, estimated: true };
|
|
@@ -50527,10 +50808,14 @@ var init_run_cost = __esm(() => {
|
|
|
50527
50808
|
inputTokens: 0,
|
|
50528
50809
|
outputTokens: 0,
|
|
50529
50810
|
cacheReadTokens: 0,
|
|
50530
|
-
|
|
50811
|
+
cacheWriteTokens: 0,
|
|
50531
50812
|
costUsd: 0,
|
|
50532
50813
|
records: 0,
|
|
50533
|
-
recordsWithUsage: 0
|
|
50814
|
+
recordsWithUsage: 0,
|
|
50815
|
+
messages: 0,
|
|
50816
|
+
toolCalls: 0,
|
|
50817
|
+
durationMs: 0,
|
|
50818
|
+
durationUnmeasured: 0
|
|
50534
50819
|
},
|
|
50535
50820
|
cacheHit: null,
|
|
50536
50821
|
estimated: false
|
|
@@ -50539,9 +50824,11 @@ var init_run_cost = __esm(() => {
|
|
|
50539
50824
|
|
|
50540
50825
|
// ../../packages/domain/src/analytics/index.ts
|
|
50541
50826
|
var init_analytics = __esm(() => {
|
|
50827
|
+
init_artifact();
|
|
50542
50828
|
init_costs();
|
|
50543
50829
|
init_models();
|
|
50544
50830
|
init_query2();
|
|
50831
|
+
init_render_report();
|
|
50545
50832
|
init_run_cost();
|
|
50546
50833
|
});
|
|
50547
50834
|
|
|
@@ -51495,7 +51782,7 @@ var init_drizzle_zod = __esm(() => {
|
|
|
51495
51782
|
};
|
|
51496
51783
|
});
|
|
51497
51784
|
|
|
51498
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
51785
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/schema/drizzle-internals.js
|
|
51499
51786
|
function sqlExpressionToText(value) {
|
|
51500
51787
|
if (typeof value !== "object" || value === null || !("queryChunks" in value)) {
|
|
51501
51788
|
return;
|
|
@@ -51518,7 +51805,7 @@ function getDrizzleTableName(table3) {
|
|
|
51518
51805
|
return String(table3[nameSym]);
|
|
51519
51806
|
}
|
|
51520
51807
|
|
|
51521
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
51808
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/schema/ddl.js
|
|
51522
51809
|
function quoteIdent(name) {
|
|
51523
51810
|
return `"${name.replace(/"/g, '""')}"`;
|
|
51524
51811
|
}
|
|
@@ -51612,7 +51899,7 @@ var init_ddl = __esm(() => {
|
|
|
51612
51899
|
init_sqlite_core();
|
|
51613
51900
|
});
|
|
51614
51901
|
|
|
51615
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
51902
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/schema/define-table.js
|
|
51616
51903
|
function defineTable(name, columns2) {
|
|
51617
51904
|
const table3 = sqliteTable(name, columns2);
|
|
51618
51905
|
let insert2;
|
|
@@ -51646,7 +51933,7 @@ var init_define_table = __esm(() => {
|
|
|
51646
51933
|
init_ddl();
|
|
51647
51934
|
});
|
|
51648
51935
|
|
|
51649
|
-
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.
|
|
51936
|
+
// ../../node_modules/.bun/@gobing-ai+ts-db@0.4.23+d18ad408e4d1e377/node_modules/@gobing-ai/ts-db/dist/schema/index.js
|
|
51650
51937
|
var init_schema = __esm(() => {
|
|
51651
51938
|
init_sqlite_core();
|
|
51652
51939
|
init_define_table();
|
|
@@ -52271,7 +52558,7 @@ var init_dao = __esm(() => {
|
|
|
52271
52558
|
init_workspace_dao();
|
|
52272
52559
|
});
|
|
52273
52560
|
|
|
52274
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
52561
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/errors.js
|
|
52275
52562
|
var WorkflowValidationError, FSMError, RunCollisionError, WorkflowResumeError;
|
|
52276
52563
|
var init_errors6 = __esm(() => {
|
|
52277
52564
|
WorkflowValidationError = class WorkflowValidationError extends Error {
|
|
@@ -52306,12 +52593,12 @@ var init_errors6 = __esm(() => {
|
|
|
52306
52593
|
};
|
|
52307
52594
|
});
|
|
52308
52595
|
|
|
52309
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
52596
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/event-bus/index.js
|
|
52310
52597
|
var init_event_bus2 = __esm(() => {
|
|
52311
52598
|
init_event_bus();
|
|
52312
52599
|
});
|
|
52313
52600
|
|
|
52314
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
52601
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/api-client.js
|
|
52315
52602
|
function sanitizeUrlForObservability(url2) {
|
|
52316
52603
|
try {
|
|
52317
52604
|
const parsed = new URL(url2);
|
|
@@ -52541,12 +52828,12 @@ var init_api_client = __esm(() => {
|
|
|
52541
52828
|
};
|
|
52542
52829
|
});
|
|
52543
52830
|
|
|
52544
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
52831
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/telemetry/index.js
|
|
52545
52832
|
var init_telemetry = __esm(() => {
|
|
52546
52833
|
init_tracing2();
|
|
52547
52834
|
});
|
|
52548
52835
|
|
|
52549
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
52836
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/index.js
|
|
52550
52837
|
var init_dist6 = __esm(() => {
|
|
52551
52838
|
init_api_client();
|
|
52552
52839
|
init_event_bus2();
|
|
@@ -52554,7 +52841,7 @@ var init_dist6 = __esm(() => {
|
|
|
52554
52841
|
init_telemetry();
|
|
52555
52842
|
});
|
|
52556
52843
|
|
|
52557
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
52844
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/run-lifecycle.js
|
|
52558
52845
|
function runtimeBuiltins(workflowName, stateOrNodeId, runId, transitionsTaken, mode) {
|
|
52559
52846
|
return {
|
|
52560
52847
|
workflow: workflowName,
|
|
@@ -52813,7 +53100,7 @@ var init_run_lifecycle = __esm(() => {
|
|
|
52813
53100
|
];
|
|
52814
53101
|
});
|
|
52815
53102
|
|
|
52816
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53103
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/schema.js
|
|
52817
53104
|
var RESERVED_VAR_NAMES, IDENTIFIER, VarsSchema, EnvSchema, ActionDefSchema, GuardDefSchema, StateMachineWorkflowDefSchema, TransitionFlowWorkflowDefSchema, WorkflowDefSchema;
|
|
52818
53105
|
var init_schema2 = __esm(() => {
|
|
52819
53106
|
init_zod();
|
|
@@ -52898,7 +53185,7 @@ var init_schema2 = __esm(() => {
|
|
|
52898
53185
|
WorkflowDefSchema = exports_external.union([StateMachineWorkflowDefSchema, TransitionFlowWorkflowDefSchema]);
|
|
52899
53186
|
});
|
|
52900
53187
|
|
|
52901
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53188
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/config.js
|
|
52902
53189
|
async function loadWorkflowDef(path9, options = {}) {
|
|
52903
53190
|
return parseWorkflowDef(await loadStructuredConfig(path9, options), path9);
|
|
52904
53191
|
}
|
|
@@ -53065,7 +53352,7 @@ var init_config4 = __esm(() => {
|
|
|
53065
53352
|
RUNTIME_TEMPLATE_NAMESPACES = new Set(RUNTIME_BUILTIN_KEYS);
|
|
53066
53353
|
});
|
|
53067
53354
|
|
|
53068
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
53355
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/extension/capability-registry.js
|
|
53069
53356
|
class CapabilityRegistry {
|
|
53070
53357
|
kind;
|
|
53071
53358
|
capabilities = new Map;
|
|
@@ -53096,7 +53383,7 @@ class CapabilityRegistry {
|
|
|
53096
53383
|
}
|
|
53097
53384
|
}
|
|
53098
53385
|
|
|
53099
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
53386
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-path.js
|
|
53100
53387
|
function assertRelativeExtensionPath(path9, options = {}) {
|
|
53101
53388
|
const where = options.sourceName !== undefined ? ` declared by "${options.sourceName}"` : "";
|
|
53102
53389
|
if (/^([/\\]|[A-Za-z]:[/\\])/.test(path9)) {
|
|
@@ -53107,20 +53394,20 @@ function assertRelativeExtensionPath(path9, options = {}) {
|
|
|
53107
53394
|
}
|
|
53108
53395
|
}
|
|
53109
53396
|
|
|
53110
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
53397
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/extension/extension-loader.js
|
|
53111
53398
|
var init_extension_loader = () => {};
|
|
53112
53399
|
|
|
53113
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
53400
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/extension/index.js
|
|
53114
53401
|
var init_extension = __esm(() => {
|
|
53115
53402
|
init_extension_loader();
|
|
53116
53403
|
});
|
|
53117
53404
|
|
|
53118
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.
|
|
53405
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.23+b3390312fcba4228/node_modules/@gobing-ai/ts-runtime/dist/extension.js
|
|
53119
53406
|
var init_extension2 = __esm(() => {
|
|
53120
53407
|
init_extension();
|
|
53121
53408
|
});
|
|
53122
53409
|
|
|
53123
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53410
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/host.js
|
|
53124
53411
|
class WorkflowEngineHost {
|
|
53125
53412
|
lifecycleBus;
|
|
53126
53413
|
actions = new CapabilityRegistry("workflow action");
|
|
@@ -53289,7 +53576,7 @@ var init_host = __esm(() => {
|
|
|
53289
53576
|
init_errors6();
|
|
53290
53577
|
});
|
|
53291
53578
|
|
|
53292
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53579
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/schema-sql.js
|
|
53293
53580
|
var WORKFLOW_ENGINE_SCHEMA_SQL;
|
|
53294
53581
|
var init_schema_sql = __esm(() => {
|
|
53295
53582
|
WORKFLOW_ENGINE_SCHEMA_SQL = `
|
|
@@ -53362,7 +53649,7 @@ CREATE TABLE IF NOT EXISTS action_runs (
|
|
|
53362
53649
|
`.trim();
|
|
53363
53650
|
});
|
|
53364
53651
|
|
|
53365
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53652
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/persistence.js
|
|
53366
53653
|
async function applyWorkflowEngineSchema(db2) {
|
|
53367
53654
|
for (const statement of WORKFLOW_ENGINE_SCHEMA_SQL.split(";")) {
|
|
53368
53655
|
const sql4 = statement.trim();
|
|
@@ -53651,7 +53938,7 @@ var init_persistence = __esm(() => {
|
|
|
53651
53938
|
init_schema_sql();
|
|
53652
53939
|
});
|
|
53653
53940
|
|
|
53654
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
53941
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/variables.js
|
|
53655
53942
|
function mergeVars(workflowVars = {}, overrideVars = {}) {
|
|
53656
53943
|
return { ...workflowVars, ...overrideVars };
|
|
53657
53944
|
}
|
|
@@ -53711,7 +53998,7 @@ var init_variables = __esm(() => {
|
|
|
53711
53998
|
TEMPLATE_REF = /\$\{([^}]+)\}/g;
|
|
53712
53999
|
});
|
|
53713
54000
|
|
|
53714
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
54001
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/action-step.js
|
|
53715
54002
|
async function runActionStep(action, vars, deps) {
|
|
53716
54003
|
const { host, persistence, lifecycle, stateOrNodeId, runId } = deps;
|
|
53717
54004
|
const resolved = resolveTemplates(action.options ?? {}, {
|
|
@@ -53769,7 +54056,7 @@ var init_action_step = __esm(() => {
|
|
|
53769
54056
|
init_variables();
|
|
53770
54057
|
});
|
|
53771
54058
|
|
|
53772
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
54059
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/state-machine.js
|
|
53773
54060
|
class StateMachineDriver {
|
|
53774
54061
|
options;
|
|
53775
54062
|
constructor(options) {
|
|
@@ -53905,7 +54192,7 @@ var init_state_machine = __esm(() => {
|
|
|
53905
54192
|
EMPTY_OUTCOME = { outcome: "completed", result: undefined };
|
|
53906
54193
|
});
|
|
53907
54194
|
|
|
53908
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
54195
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/transition-flow.js
|
|
53909
54196
|
class TransitionFlowDriver {
|
|
53910
54197
|
options;
|
|
53911
54198
|
constructor(options) {
|
|
@@ -54024,7 +54311,7 @@ var init_transition_flow = __esm(() => {
|
|
|
54024
54311
|
init_variables();
|
|
54025
54312
|
});
|
|
54026
54313
|
|
|
54027
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
54314
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/service.js
|
|
54028
54315
|
class WorkflowService {
|
|
54029
54316
|
host;
|
|
54030
54317
|
persistence;
|
|
@@ -54241,7 +54528,7 @@ var init_service = __esm(() => {
|
|
|
54241
54528
|
init_variables();
|
|
54242
54529
|
});
|
|
54243
54530
|
|
|
54244
|
-
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.
|
|
54531
|
+
// ../../node_modules/.bun/@gobing-ai+ts-dual-workflow-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-dual-workflow-engine/dist/index.js
|
|
54245
54532
|
var init_dist7 = __esm(() => {
|
|
54246
54533
|
init_config4();
|
|
54247
54534
|
init_host();
|
|
@@ -54250,8 +54537,8 @@ var init_dist7 = __esm(() => {
|
|
|
54250
54537
|
init_service();
|
|
54251
54538
|
});
|
|
54252
54539
|
|
|
54253
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
54254
|
-
import { createHash } from "crypto";
|
|
54540
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.23+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/hash.js
|
|
54541
|
+
import { createHash as createHash2 } from "crypto";
|
|
54255
54542
|
function stableJson(value) {
|
|
54256
54543
|
if (Array.isArray(value)) {
|
|
54257
54544
|
return `[${value.map((entry) => entry === undefined ? "null" : stableJson(entry)).join(",")}]`;
|
|
@@ -54263,11 +54550,11 @@ function stableJson(value) {
|
|
|
54263
54550
|
return JSON.stringify(value) ?? "null";
|
|
54264
54551
|
}
|
|
54265
54552
|
function sha256(value) {
|
|
54266
|
-
return
|
|
54553
|
+
return createHash2("sha256").update(stableJson(value)).digest("hex");
|
|
54267
54554
|
}
|
|
54268
54555
|
var init_hash = () => {};
|
|
54269
54556
|
|
|
54270
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
54557
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.23+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/errors.js
|
|
54271
54558
|
var HistoryImportError;
|
|
54272
54559
|
var init_errors7 = __esm(() => {
|
|
54273
54560
|
HistoryImportError = class HistoryImportError extends Error {
|
|
@@ -54280,7 +54567,7 @@ var init_errors7 = __esm(() => {
|
|
|
54280
54567
|
};
|
|
54281
54568
|
});
|
|
54282
54569
|
|
|
54283
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
54570
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.23+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/schema-sql.js
|
|
54284
54571
|
var HISTORY_IMPORT_SCHEMA_SQL;
|
|
54285
54572
|
var init_schema_sql2 = __esm(() => {
|
|
54286
54573
|
HISTORY_IMPORT_SCHEMA_SQL = `
|
|
@@ -54424,7 +54711,7 @@ CREATE INDEX IF NOT EXISTS idx_history_tool_call_message_hash
|
|
|
54424
54711
|
`.trim();
|
|
54425
54712
|
});
|
|
54426
54713
|
|
|
54427
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
54714
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.23+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/mappers.js
|
|
54428
54715
|
function identityFieldMap(keys) {
|
|
54429
54716
|
const map2 = {};
|
|
54430
54717
|
for (const key of keys) {
|
|
@@ -55357,7 +55644,7 @@ var init_mappers = __esm(() => {
|
|
|
55357
55644
|
GROK_SCHEMA = passthroughSchema;
|
|
55358
55645
|
});
|
|
55359
55646
|
|
|
55360
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
55647
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.23+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/sources.js
|
|
55361
55648
|
function firstString(...values) {
|
|
55362
55649
|
for (const value of values) {
|
|
55363
55650
|
if (typeof value === "string" && value.length > 0)
|
|
@@ -55511,7 +55798,7 @@ var init_sources = __esm(() => {
|
|
|
55511
55798
|
};
|
|
55512
55799
|
});
|
|
55513
55800
|
|
|
55514
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
55801
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.23+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/jsonl-importer-dao.js
|
|
55515
55802
|
function targetTableFor(table3) {
|
|
55516
55803
|
if (!VALID_TABLE_NAME.test(table3)) {
|
|
55517
55804
|
throw new HistoryImportError(`Invalid history ETL target table: ${table3}`, { table: table3 });
|
|
@@ -55662,7 +55949,7 @@ var init_jsonl_importer_dao = __esm(() => {
|
|
|
55662
55949
|
_ensuredTables = new Set;
|
|
55663
55950
|
});
|
|
55664
55951
|
|
|
55665
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
55952
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.23+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/redaction.js
|
|
55666
55953
|
function redactValue(value, rules = DEFAULT_REDACTION_RULES) {
|
|
55667
55954
|
if (typeof value === "string") {
|
|
55668
55955
|
return rules.reduce((current, rule) => current.replace(rule.pattern, rule.replacement), value);
|
|
@@ -55699,7 +55986,7 @@ var init_redaction = __esm(() => {
|
|
|
55699
55986
|
];
|
|
55700
55987
|
});
|
|
55701
55988
|
|
|
55702
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
55989
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.23+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/importer.js
|
|
55703
55990
|
async function runJsonlImport(source, options) {
|
|
55704
55991
|
const definition = resolveSourceDefinition(source);
|
|
55705
55992
|
const resolvedSource = definition.source;
|
|
@@ -55862,7 +56149,7 @@ function normalizeRecord(definition, raw, context4) {
|
|
|
55862
56149
|
}
|
|
55863
56150
|
async function discoverFiles(definition, roots, files, fileSystem, paths) {
|
|
55864
56151
|
if (files !== undefined && files.length > 0) {
|
|
55865
|
-
return files.map((file2) => resolvePath4(file2)).sort();
|
|
56152
|
+
return files.map((file2) => resolvePath4(file2)).map((file2) => normalizeSourceFilePath(file2, fileSystem)).sort();
|
|
55866
56153
|
}
|
|
55867
56154
|
const ambient = paths ?? ambientRuntimePaths2();
|
|
55868
56155
|
const resolvedRoots = roots !== undefined ? roots.map((root) => resolvePath4(ambient.cwd, root)) : definition.defaultRoots.map((root) => resolvePath4(ambient.home, root));
|
|
@@ -55875,16 +56162,25 @@ async function discoverFiles(definition, roots, files, fileSystem, paths) {
|
|
|
55875
56162
|
continue;
|
|
55876
56163
|
if (stat.isFile()) {
|
|
55877
56164
|
if (matchesPattern(root, definition.filePatterns))
|
|
55878
|
-
found.add(root);
|
|
56165
|
+
found.add(normalizeSourceFilePath(root, fileSystem));
|
|
55879
56166
|
continue;
|
|
55880
56167
|
}
|
|
55881
56168
|
for (const file2 of await walkDir2(root, fileSystem)) {
|
|
55882
56169
|
if (matchesPattern(file2, definition.filePatterns))
|
|
55883
|
-
found.add(file2);
|
|
56170
|
+
found.add(normalizeSourceFilePath(file2, fileSystem));
|
|
55884
56171
|
}
|
|
55885
56172
|
}
|
|
55886
56173
|
return [...found].sort();
|
|
55887
56174
|
}
|
|
56175
|
+
function normalizeSourceFilePath(path9, fileSystem) {
|
|
56176
|
+
if (!fileSystem.realPath)
|
|
56177
|
+
return path9;
|
|
56178
|
+
try {
|
|
56179
|
+
return fileSystem.realPath(path9);
|
|
56180
|
+
} catch {
|
|
56181
|
+
return path9;
|
|
56182
|
+
}
|
|
56183
|
+
}
|
|
55888
56184
|
function matchesPattern(path9, patterns) {
|
|
55889
56185
|
return patterns.some((pattern) => {
|
|
55890
56186
|
if (pattern === "*.jsonl")
|
|
@@ -55912,13 +56208,13 @@ var init_importer = __esm(() => {
|
|
|
55912
56208
|
init_sources();
|
|
55913
56209
|
});
|
|
55914
56210
|
|
|
55915
|
-
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.
|
|
56211
|
+
// ../../node_modules/.bun/@gobing-ai+ts-llm-jsonl-importer@0.4.23+d5c29f764bf0e6e0/node_modules/@gobing-ai/ts-llm-jsonl-importer/dist/index.js
|
|
55916
56212
|
var init_dist8 = __esm(() => {
|
|
55917
56213
|
init_importer();
|
|
55918
56214
|
init_schema_sql2();
|
|
55919
56215
|
});
|
|
55920
56216
|
|
|
55921
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56217
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/config/extensions.js
|
|
55922
56218
|
function collectExtensions(sourceName, sourceDir, extensions) {
|
|
55923
56219
|
if (extensions === undefined)
|
|
55924
56220
|
return [];
|
|
@@ -55934,7 +56230,7 @@ var init_extensions = __esm(() => {
|
|
|
55934
56230
|
init_dist5();
|
|
55935
56231
|
});
|
|
55936
56232
|
|
|
55937
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56233
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/types.js
|
|
55938
56234
|
function createFinding(rule, message, filePath, extras = {}) {
|
|
55939
56235
|
return {
|
|
55940
56236
|
ruleId: rule.id,
|
|
@@ -56005,7 +56301,7 @@ var init_types3 = __esm(() => {
|
|
|
56005
56301
|
});
|
|
56006
56302
|
});
|
|
56007
56303
|
|
|
56008
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56304
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/config/loader.js
|
|
56009
56305
|
async function loadPreset(name, options) {
|
|
56010
56306
|
const merged = await buildMergedRoots(options.roots.map((root) => resolvePath4(root)), options.fileSystem);
|
|
56011
56307
|
const presetPath = findMergedPreset(merged, name);
|
|
@@ -56220,7 +56516,7 @@ var init_loader2 = __esm(() => {
|
|
|
56220
56516
|
FIX_MODE_AUTHORITY = { none: 0, suggest: 1, auto: 2 };
|
|
56221
56517
|
});
|
|
56222
56518
|
|
|
56223
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56519
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/fixers/test-stub-fixer.js
|
|
56224
56520
|
function normalizeFindingPath(filePath) {
|
|
56225
56521
|
if (!filePath || isAbsolutePath2(filePath))
|
|
56226
56522
|
return null;
|
|
@@ -56285,7 +56581,7 @@ var init_test_stub_fixer = __esm(() => {
|
|
|
56285
56581
|
realFileSystem = createNodeFileSystem3();
|
|
56286
56582
|
});
|
|
56287
56583
|
|
|
56288
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
56584
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/fixers/fixers.js
|
|
56289
56585
|
function registerBuiltinFixers(host, exec) {
|
|
56290
56586
|
const regexFixer = new RegexFixerProvider;
|
|
56291
56587
|
const pathFixer = new PathFixerProvider;
|
|
@@ -56488,7 +56784,7 @@ var init_fixers = __esm(() => {
|
|
|
56488
56784
|
};
|
|
56489
56785
|
});
|
|
56490
56786
|
|
|
56491
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
56787
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.23+60034aec79d6ac9d/node_modules/@gobing-ai/ts-ai-runner/dist/agents/shims.js
|
|
56492
56788
|
function getAgentSessionCapability(agent) {
|
|
56493
56789
|
return AGENT_SESSION_CAPABILITY[agent];
|
|
56494
56790
|
}
|
|
@@ -56780,7 +57076,7 @@ var init_shims = __esm(() => {
|
|
|
56780
57076
|
ALIAS_TO_CANONICAL = Object.fromEntries(Object.values(AGENT_SHIMS).flatMap((shim) => (shim.aliases ?? []).map((alias3) => [alias3, shim.name])));
|
|
56781
57077
|
});
|
|
56782
57078
|
|
|
56783
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
57079
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.23+60034aec79d6ac9d/node_modules/@gobing-ai/ts-ai-runner/dist/identity.js
|
|
56784
57080
|
function buildIdentityPreamble(ctx) {
|
|
56785
57081
|
const sections = [
|
|
56786
57082
|
`You are agent \`${ctx.agentId}\` (${ctx.agentType}) in workspace \`${ctx.workspace}\`.`
|
|
@@ -56840,7 +57136,7 @@ var init_identity = __esm(() => {
|
|
|
56840
57136
|
init_dist5();
|
|
56841
57137
|
});
|
|
56842
57138
|
|
|
56843
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
57139
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.23+60034aec79d6ac9d/node_modules/@gobing-ai/ts-ai-runner/dist/slash-command.js
|
|
56844
57140
|
function isClaudeStyleSlashCommand(input) {
|
|
56845
57141
|
return SLASH_COMMAND_RE.test(input);
|
|
56846
57142
|
}
|
|
@@ -56868,7 +57164,7 @@ var init_slash_command = __esm(() => {
|
|
|
56868
57164
|
SLASH_COMMAND_RE = /^\/([a-zA-Z0-9._-]+):([a-zA-Z0-9._-]+)(\s.*)?$/;
|
|
56869
57165
|
});
|
|
56870
57166
|
|
|
56871
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
57167
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.23+60034aec79d6ac9d/node_modules/@gobing-ai/ts-ai-runner/dist/ai-runner.js
|
|
56872
57168
|
function buildCorrelationEnv(correlation) {
|
|
56873
57169
|
return {
|
|
56874
57170
|
[AGENT_RUN_ID_ENV]: correlation.runId,
|
|
@@ -57004,7 +57300,7 @@ var init_ai_runner = __esm(() => {
|
|
|
57004
57300
|
init_slash_command();
|
|
57005
57301
|
});
|
|
57006
57302
|
|
|
57007
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
57303
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.23+60034aec79d6ac9d/node_modules/@gobing-ai/ts-ai-runner/dist/agent-detector.js
|
|
57008
57304
|
class AgentDetector {
|
|
57009
57305
|
runner;
|
|
57010
57306
|
timeout;
|
|
@@ -57080,7 +57376,7 @@ var init_agent_detector = __esm(() => {
|
|
|
57080
57376
|
VERSION_PATTERN = /(?<version>\d+\.\d+(?:\.\d+)?)/;
|
|
57081
57377
|
});
|
|
57082
57378
|
|
|
57083
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
57379
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.23+60034aec79d6ac9d/node_modules/@gobing-ai/ts-ai-runner/dist/agent-spec.js
|
|
57084
57380
|
function validateAgentId(id) {
|
|
57085
57381
|
if (!/^[a-z][a-z0-9_-]{1,63}$/.test(id)) {
|
|
57086
57382
|
throw new ValueError(`Invalid agent id "${id}": expected 2-64 chars, lowercase alphanumeric, "_" or "-"`);
|
|
@@ -57177,7 +57473,7 @@ var init_agent_spec = __esm(() => {
|
|
|
57177
57473
|
};
|
|
57178
57474
|
});
|
|
57179
57475
|
|
|
57180
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
57476
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.23+60034aec79d6ac9d/node_modules/@gobing-ai/ts-ai-runner/dist/agents/auth-shims.js
|
|
57181
57477
|
function isNonEmpty(value) {
|
|
57182
57478
|
return value !== undefined && value.trim().length > 0;
|
|
57183
57479
|
}
|
|
@@ -57282,7 +57578,7 @@ var init_auth_shims = __esm(() => {
|
|
|
57282
57578
|
};
|
|
57283
57579
|
});
|
|
57284
57580
|
|
|
57285
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
57581
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.23+60034aec79d6ac9d/node_modules/@gobing-ai/ts-ai-runner/dist/model-health-probe.js
|
|
57286
57582
|
class ModelHealthProbeRegistry {
|
|
57287
57583
|
probes = new Map;
|
|
57288
57584
|
register(providerPrefix, probe) {
|
|
@@ -57390,7 +57686,7 @@ var init_model_health_probe = __esm(() => {
|
|
|
57390
57686
|
};
|
|
57391
57687
|
});
|
|
57392
57688
|
|
|
57393
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
57689
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.23+60034aec79d6ac9d/node_modules/@gobing-ai/ts-ai-runner/dist/doctor-runner.js
|
|
57394
57690
|
class DoctorRunner {
|
|
57395
57691
|
detector;
|
|
57396
57692
|
runner;
|
|
@@ -57527,15 +57823,15 @@ var init_doctor_runner = __esm(() => {
|
|
|
57527
57823
|
init_model_health_probe();
|
|
57528
57824
|
});
|
|
57529
57825
|
|
|
57530
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
57826
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.23+60034aec79d6ac9d/node_modules/@gobing-ai/ts-ai-runner/dist/events.js
|
|
57531
57827
|
var init_events = () => {};
|
|
57532
57828
|
|
|
57533
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
57829
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.23+60034aec79d6ac9d/node_modules/@gobing-ai/ts-ai-runner/dist/messages.js
|
|
57534
57830
|
function formatMessage(msg) {
|
|
57535
57831
|
return `[task from=${msg.fromId ?? "operator"} id=${msg.id}] ${msg.body}`;
|
|
57536
57832
|
}
|
|
57537
57833
|
|
|
57538
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
57834
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.23+60034aec79d6ac9d/node_modules/@gobing-ai/ts-ai-runner/dist/team-agent-process.js
|
|
57539
57835
|
import { Buffer as Buffer5 } from "buffer";
|
|
57540
57836
|
|
|
57541
57837
|
class TeamAgentProcess {
|
|
@@ -57669,7 +57965,7 @@ var init_team_agent_process = __esm(() => {
|
|
|
57669
57965
|
init_dist5();
|
|
57670
57966
|
});
|
|
57671
57967
|
|
|
57672
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
57968
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.23+60034aec79d6ac9d/node_modules/@gobing-ai/ts-ai-runner/dist/team-orchestrator.js
|
|
57673
57969
|
class TeamOrchestrator {
|
|
57674
57970
|
configDir;
|
|
57675
57971
|
inbox;
|
|
@@ -57798,7 +58094,7 @@ var init_team_orchestrator = __esm(() => {
|
|
|
57798
58094
|
init_team_agent_process();
|
|
57799
58095
|
});
|
|
57800
58096
|
|
|
57801
|
-
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.
|
|
58097
|
+
// ../../node_modules/.bun/@gobing-ai+ts-ai-runner@0.4.23+60034aec79d6ac9d/node_modules/@gobing-ai/ts-ai-runner/dist/index.js
|
|
57802
58098
|
var exports_dist3 = {};
|
|
57803
58099
|
__export(exports_dist3, {
|
|
57804
58100
|
validateAgentId: () => validateAgentId,
|
|
@@ -57850,7 +58146,7 @@ var init_dist9 = __esm(() => {
|
|
|
57850
58146
|
init_team_orchestrator();
|
|
57851
58147
|
});
|
|
57852
58148
|
|
|
57853
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
58149
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/config-access.js
|
|
57854
58150
|
function stringArray(value) {
|
|
57855
58151
|
return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : undefined;
|
|
57856
58152
|
}
|
|
@@ -57888,7 +58184,7 @@ function parseInlineFlags(source) {
|
|
|
57888
58184
|
return { flags, rest: source.slice(match[0].length) };
|
|
57889
58185
|
}
|
|
57890
58186
|
|
|
57891
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
58187
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/glob-match.js
|
|
57892
58188
|
function matchesAny(path9, patterns) {
|
|
57893
58189
|
if (patterns === undefined || patterns.length === 0)
|
|
57894
58190
|
return true;
|
|
@@ -57936,7 +58232,7 @@ function escapeRegExp(value) {
|
|
|
57936
58232
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
57937
58233
|
}
|
|
57938
58234
|
|
|
57939
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
58235
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/file-discovery.js
|
|
57940
58236
|
async function discoverFiles2(options) {
|
|
57941
58237
|
const fs3 = options.fs ?? createNodeFileSystem3();
|
|
57942
58238
|
const allFiles = await walkDir2(options.workdir, fs3, DEFAULT_EXCLUDES);
|
|
@@ -57964,12 +58260,12 @@ var init_file_discovery = __esm(() => {
|
|
|
57964
58260
|
DEFAULT_EXCLUDES = new Set([".git", "node_modules", "dist", ".coverage", ".astro", ".wrangler"]);
|
|
57965
58261
|
});
|
|
57966
58262
|
|
|
57967
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
58263
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/file-utils.js
|
|
57968
58264
|
var init_file_utils = __esm(() => {
|
|
57969
58265
|
init_file_discovery();
|
|
57970
58266
|
});
|
|
57971
58267
|
|
|
57972
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
58268
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/agent-detection-evaluator.js
|
|
57973
58269
|
class AgentDetectionEvaluator {
|
|
57974
58270
|
detector;
|
|
57975
58271
|
constructor(detector = new AgentDetector) {
|
|
@@ -57997,7 +58293,7 @@ var init_agent_detection_evaluator = __esm(() => {
|
|
|
57997
58293
|
init_file_utils();
|
|
57998
58294
|
});
|
|
57999
58295
|
|
|
58000
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
58296
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/coverage-gate-evaluator.js
|
|
58001
58297
|
class CoverageGateEvaluator {
|
|
58002
58298
|
constructor() {}
|
|
58003
58299
|
async evaluate(rule, context4) {
|
|
@@ -58081,7 +58377,7 @@ var init_coverage_gate_evaluator = __esm(() => {
|
|
|
58081
58377
|
init_file_utils();
|
|
58082
58378
|
});
|
|
58083
58379
|
|
|
58084
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
58380
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/exit-code-evaluator.js
|
|
58085
58381
|
class ExitCodeEvaluator {
|
|
58086
58382
|
executor;
|
|
58087
58383
|
constructor(executor = nodeBunFactory3.createProcessExecutor()) {
|
|
@@ -58117,7 +58413,7 @@ var init_exit_code_evaluator = __esm(() => {
|
|
|
58117
58413
|
init_file_utils();
|
|
58118
58414
|
});
|
|
58119
58415
|
|
|
58120
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
58416
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/forbidden-import-evaluator.js
|
|
58121
58417
|
class ForbiddenImportEvaluator {
|
|
58122
58418
|
constructor() {}
|
|
58123
58419
|
async evaluate(rule, context4) {
|
|
@@ -58198,7 +58494,7 @@ var init_forbidden_import_evaluator = __esm(() => {
|
|
|
58198
58494
|
init_file_utils();
|
|
58199
58495
|
});
|
|
58200
58496
|
|
|
58201
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
58497
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/import-boundary-evaluator.js
|
|
58202
58498
|
class ImportBoundaryEvaluator {
|
|
58203
58499
|
async evaluate(rule, context4) {
|
|
58204
58500
|
const config4 = rule.evaluator.config ?? {};
|
|
@@ -58291,7 +58587,7 @@ var init_import_boundary_evaluator = __esm(() => {
|
|
|
58291
58587
|
init_file_utils();
|
|
58292
58588
|
});
|
|
58293
58589
|
|
|
58294
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
58590
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/path-evaluator.js
|
|
58295
58591
|
class PathEvaluator {
|
|
58296
58592
|
constructor() {}
|
|
58297
58593
|
async evaluate(rule, context4) {
|
|
@@ -58352,7 +58648,7 @@ var init_path_evaluator = __esm(() => {
|
|
|
58352
58648
|
init_file_utils();
|
|
58353
58649
|
});
|
|
58354
58650
|
|
|
58355
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
58651
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/regex-evaluator.js
|
|
58356
58652
|
class RegexEvaluator {
|
|
58357
58653
|
constructor() {}
|
|
58358
58654
|
async evaluate(rule, context4) {
|
|
@@ -58430,7 +58726,7 @@ var init_regex_evaluator = __esm(() => {
|
|
|
58430
58726
|
init_file_utils();
|
|
58431
58727
|
});
|
|
58432
58728
|
|
|
58433
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
58729
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/ripgrep-evaluator.js
|
|
58434
58730
|
class RipgrepEvaluator {
|
|
58435
58731
|
executor;
|
|
58436
58732
|
constructor(executor = nodeBunFactory3.createProcessExecutor()) {
|
|
@@ -58523,7 +58819,7 @@ var init_ripgrep_evaluator = __esm(() => {
|
|
|
58523
58819
|
init_file_utils();
|
|
58524
58820
|
});
|
|
58525
58821
|
|
|
58526
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
58822
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/schema-artifact-evaluator.js
|
|
58527
58823
|
class SchemaArtifactEvaluator {
|
|
58528
58824
|
constructor() {}
|
|
58529
58825
|
async evaluate(rule, context4) {
|
|
@@ -58601,7 +58897,7 @@ var init_schema_artifact_evaluator = __esm(() => {
|
|
|
58601
58897
|
init_file_utils();
|
|
58602
58898
|
});
|
|
58603
58899
|
|
|
58604
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
58900
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/secrets-scanner-evaluator.js
|
|
58605
58901
|
class SecretsScannerEvaluator {
|
|
58606
58902
|
constructor() {}
|
|
58607
58903
|
async evaluate(rule, context4) {
|
|
@@ -58669,7 +58965,7 @@ var init_secrets_scanner_evaluator = __esm(() => {
|
|
|
58669
58965
|
ALL_CATEGORIES = Object.keys(BUILTIN_PATTERNS);
|
|
58670
58966
|
});
|
|
58671
58967
|
|
|
58672
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
58968
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/sg-evaluator.js
|
|
58673
58969
|
class SgEvaluator {
|
|
58674
58970
|
executor;
|
|
58675
58971
|
constructor(executor = nodeBunFactory3.createProcessExecutor()) {
|
|
@@ -58766,7 +59062,7 @@ var init_sg_evaluator = __esm(() => {
|
|
|
58766
59062
|
init_file_utils();
|
|
58767
59063
|
});
|
|
58768
59064
|
|
|
58769
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
59065
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/resolvers/test-path-resolver.js
|
|
58770
59066
|
class TypeScriptTestPathResolver {
|
|
58771
59067
|
name = "typescript";
|
|
58772
59068
|
constructor() {}
|
|
@@ -58849,7 +59145,7 @@ function testify(rel) {
|
|
|
58849
59145
|
return `${dir}test_${base2}`;
|
|
58850
59146
|
}
|
|
58851
59147
|
|
|
58852
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
59148
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/test-location-evaluator.js
|
|
58853
59149
|
class TestLocationEvaluator {
|
|
58854
59150
|
resolvers;
|
|
58855
59151
|
constructor(resolvers) {
|
|
@@ -58924,7 +59220,7 @@ var init_test_location_evaluator = __esm(() => {
|
|
|
58924
59220
|
TYPESCRIPT_FALLBACK = new TypeScriptTestPathResolver;
|
|
58925
59221
|
});
|
|
58926
59222
|
|
|
58927
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
59223
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/evaluators/tsdoc-export-evaluator.js
|
|
58928
59224
|
class TsdocExportEvaluator {
|
|
58929
59225
|
constructor() {}
|
|
58930
59226
|
async evaluate(rule, context4) {
|
|
@@ -59009,7 +59305,7 @@ var init_tsdoc_export_evaluator = __esm(() => {
|
|
|
59009
59305
|
};
|
|
59010
59306
|
});
|
|
59011
59307
|
|
|
59012
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
59308
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/json.js
|
|
59013
59309
|
class JsonFormatter {
|
|
59014
59310
|
constructor() {}
|
|
59015
59311
|
format(result) {
|
|
@@ -59017,7 +59313,7 @@ class JsonFormatter {
|
|
|
59017
59313
|
}
|
|
59018
59314
|
}
|
|
59019
59315
|
|
|
59020
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
59316
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/formatters/text.js
|
|
59021
59317
|
class TextFormatter {
|
|
59022
59318
|
constructor() {}
|
|
59023
59319
|
format(result) {
|
|
@@ -59031,7 +59327,7 @@ class TextFormatter {
|
|
|
59031
59327
|
}
|
|
59032
59328
|
}
|
|
59033
59329
|
|
|
59034
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
59330
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/host/builtins.js
|
|
59035
59331
|
function registerBuiltins(host, executor) {
|
|
59036
59332
|
const path9 = new PathEvaluator;
|
|
59037
59333
|
host.evaluators.register("regex", new RegexEvaluator, "builtin");
|
|
@@ -59071,7 +59367,7 @@ var init_builtins = __esm(() => {
|
|
|
59071
59367
|
init_tsdoc_export_evaluator();
|
|
59072
59368
|
});
|
|
59073
59369
|
|
|
59074
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
59370
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/host/rule-engine-host.js
|
|
59075
59371
|
class RuleEngineHost {
|
|
59076
59372
|
evaluators;
|
|
59077
59373
|
formatters;
|
|
@@ -59088,7 +59384,7 @@ var init_rule_engine_host = __esm(() => {
|
|
|
59088
59384
|
init_extension2();
|
|
59089
59385
|
});
|
|
59090
59386
|
|
|
59091
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
59387
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/engine.js
|
|
59092
59388
|
class RuleEngine {
|
|
59093
59389
|
host;
|
|
59094
59390
|
events;
|
|
@@ -59259,7 +59555,7 @@ var init_engine = __esm(() => {
|
|
|
59259
59555
|
init_types3();
|
|
59260
59556
|
});
|
|
59261
59557
|
|
|
59262
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
59558
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/host/bundled-rules.js
|
|
59263
59559
|
async function bundledRulesRoot() {
|
|
59264
59560
|
if (cachedRoot2 !== undefined)
|
|
59265
59561
|
return cachedRoot2;
|
|
@@ -59310,7 +59606,7 @@ var init_bundled_rules = __esm(() => {
|
|
|
59310
59606
|
init_dist5();
|
|
59311
59607
|
});
|
|
59312
59608
|
|
|
59313
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
59609
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/db-adapter.js
|
|
59314
59610
|
class DbRulePersistenceAdapter {
|
|
59315
59611
|
db;
|
|
59316
59612
|
constructor(db2) {
|
|
@@ -59344,7 +59640,7 @@ class DbRulePersistenceAdapter {
|
|
|
59344
59640
|
}
|
|
59345
59641
|
}
|
|
59346
59642
|
|
|
59347
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
59643
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/schema.js
|
|
59348
59644
|
var RULE_ENGINE_SCHEMA_SQL = `
|
|
59349
59645
|
CREATE TABLE IF NOT EXISTS rule_runs (
|
|
59350
59646
|
id TEXT PRIMARY KEY,
|
|
@@ -59390,10 +59686,10 @@ CREATE TABLE IF NOT EXISTS rule_eval_runs (
|
|
|
59390
59686
|
CREATE INDEX IF NOT EXISTS idx_rule_eval_runs_run_id ON rule_eval_runs (run_id);
|
|
59391
59687
|
`;
|
|
59392
59688
|
|
|
59393
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
59689
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/persistence/index.js
|
|
59394
59690
|
var init_persistence2 = () => {};
|
|
59395
59691
|
|
|
59396
|
-
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.
|
|
59692
|
+
// ../../node_modules/.bun/@gobing-ai+ts-rule-engine@0.4.23+eb8900f44f4776f9/node_modules/@gobing-ai/ts-rule-engine/dist/index.js
|
|
59397
59693
|
var init_dist10 = __esm(() => {
|
|
59398
59694
|
init_extensions();
|
|
59399
59695
|
init_loader2();
|
|
@@ -59564,6 +59860,8 @@ ALTER TABLE system_events ADD COLUMN sequence INTEGER;
|
|
|
59564
59860
|
|
|
59565
59861
|
CREATE INDEX IF NOT EXISTS idx_system_events_run_id ON system_events (run_id);
|
|
59566
59862
|
CREATE INDEX IF NOT EXISTS idx_system_events_entity ON system_events (entity_kind, entity_id);
|
|
59863
|
+
`, HISTORY_MESSAGE_RUN_INDEX_SCHEMA_SQL = `
|
|
59864
|
+
CREATE INDEX IF NOT EXISTS idx_history_message_provenance_run ON history_message (provenance, run_id);
|
|
59567
59865
|
`, CLI_MIGRATIONS, CLI_MIGRATION_FILE_MARKER = "_spur_cli_";
|
|
59568
59866
|
var init_migrations = __esm(() => {
|
|
59569
59867
|
init_dist7();
|
|
@@ -59609,11 +59907,12 @@ ${SYSTEM_EVENTS_SCHEMA_SQL}
|
|
|
59609
59907
|
id: "0008_spur_cli_system_events_correlation",
|
|
59610
59908
|
sql: SYSTEM_EVENTS_CORRELATION_COLUMNS_SCHEMA_SQL,
|
|
59611
59909
|
addColumnIfMissing: { table: "system_events", column: "sequence" }
|
|
59612
|
-
}
|
|
59910
|
+
},
|
|
59911
|
+
{ id: "0009_spur_cli_history_message_run_idx", sql: HISTORY_MESSAGE_RUN_INDEX_SCHEMA_SQL }
|
|
59613
59912
|
];
|
|
59614
59913
|
});
|
|
59615
59914
|
|
|
59616
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
59915
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/job-queue/db-job-queue.js
|
|
59617
59916
|
function queueLogger() {
|
|
59618
59917
|
if (!_queueLogger)
|
|
59619
59918
|
_queueLogger = getLogger2("job-queue");
|
|
@@ -59890,7 +60189,7 @@ var init_db_job_queue = __esm(() => {
|
|
|
59890
60189
|
init_tracing2();
|
|
59891
60190
|
});
|
|
59892
60191
|
|
|
59893
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
60192
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/job-queue-db.js
|
|
59894
60193
|
var exports_job_queue_db = {};
|
|
59895
60194
|
__export(exports_job_queue_db, {
|
|
59896
60195
|
DBQueueConsumer: () => DBQueueConsumer,
|
|
@@ -59939,9 +60238,9 @@ var init_db2 = __esm(() => {
|
|
|
59939
60238
|
});
|
|
59940
60239
|
|
|
59941
60240
|
// ../../packages/domain/src/envelope/fingerprint.ts
|
|
59942
|
-
import { createHash as
|
|
60241
|
+
import { createHash as createHash3 } from "crypto";
|
|
59943
60242
|
function computeContentHash(content) {
|
|
59944
|
-
return
|
|
60243
|
+
return createHash3("sha256").update(content, "utf-8").digest("hex");
|
|
59945
60244
|
}
|
|
59946
60245
|
var init_fingerprint = () => {};
|
|
59947
60246
|
|
|
@@ -60690,7 +60989,7 @@ function attributeWithoutTelemetry(layers, capturedLayers) {
|
|
|
60690
60989
|
}
|
|
60691
60990
|
|
|
60692
60991
|
// ../../packages/domain/src/envelope/invalidation.ts
|
|
60693
|
-
import { createHash as
|
|
60992
|
+
import { createHash as createHash4 } from "crypto";
|
|
60694
60993
|
function computeInvalidationFingerprint(trigger) {
|
|
60695
60994
|
if (trigger.kind === "tool-output")
|
|
60696
60995
|
return null;
|
|
@@ -60714,7 +61013,7 @@ function computeInvalidationFingerprint(trigger) {
|
|
|
60714
61013
|
default:
|
|
60715
61014
|
return null;
|
|
60716
61015
|
}
|
|
60717
|
-
return
|
|
61016
|
+
return createHash4("sha256").update(raw, "utf-8").digest("hex");
|
|
60718
61017
|
}
|
|
60719
61018
|
function checkLayerStale(layer, freshFingerprint) {
|
|
60720
61019
|
if (freshFingerprint === null) {
|
|
@@ -60890,7 +61189,7 @@ function isProcessAlive(pid) {
|
|
|
60890
61189
|
return false;
|
|
60891
61190
|
}
|
|
60892
61191
|
}
|
|
60893
|
-
function
|
|
61192
|
+
function isStale2(meta3, ttlMs) {
|
|
60894
61193
|
if (meta3.pid > 0 && !isProcessAlive(meta3.pid))
|
|
60895
61194
|
return true;
|
|
60896
61195
|
if (Date.now() - meta3.ts > ttlMs)
|
|
@@ -60946,7 +61245,7 @@ function acquireLock(path9, _fs, ttlMs, label) {
|
|
|
60946
61245
|
}
|
|
60947
61246
|
const raw = readLockFileSync(path9);
|
|
60948
61247
|
const existing = raw === null ? { pid: 0, ts: 0 } : parseLockContent(raw);
|
|
60949
|
-
if (raw !== null && !
|
|
61248
|
+
if (raw !== null && !isStale2(existing, ttlMs)) {
|
|
60950
61249
|
throw new Error(`Cannot acquire ${label} lock at ${path9}: held by pid ${existing.pid} (age ${Date.now() - existing.ts}ms)`);
|
|
60951
61250
|
}
|
|
60952
61251
|
staleWarning = `Broke stale ${label} lock at ${path9} (pid ${existing.pid}, age ${Date.now() - existing.ts}ms)`;
|
|
@@ -61013,7 +61312,7 @@ function inspectLock(folder, entityId, fs3, ttlMs = DEFAULT_LOCK_TTL_MS) {
|
|
|
61013
61312
|
if (!meta3)
|
|
61014
61313
|
return null;
|
|
61015
61314
|
return {
|
|
61016
|
-
stale:
|
|
61315
|
+
stale: isStale2(meta3, ttlMs),
|
|
61017
61316
|
age: Date.now() - meta3.ts,
|
|
61018
61317
|
pid: meta3.pid
|
|
61019
61318
|
};
|
|
@@ -61933,6 +62232,7 @@ __export(exports_src, {
|
|
|
61933
62232
|
validateStageRegistry: () => validateStageRegistry,
|
|
61934
62233
|
validateStageRecord: () => validateStageRecord,
|
|
61935
62234
|
validateAcceptanceCriteria: () => validateAcceptanceCriteria,
|
|
62235
|
+
toolRollup: () => toolRollup,
|
|
61936
62236
|
taskStatusIcon: () => taskStatusIcon,
|
|
61937
62237
|
taskSnapshotSchema: () => taskSnapshotSchema,
|
|
61938
62238
|
taskFrontmatterSchema: () => taskFrontmatterSchema,
|
|
@@ -61940,6 +62240,7 @@ __export(exports_src, {
|
|
|
61940
62240
|
taskBatchItemSchema: () => taskBatchItemSchema,
|
|
61941
62241
|
subprocessExecutionSchema: () => subprocessExecutionSchema,
|
|
61942
62242
|
stripAcFence: () => stripAcFence,
|
|
62243
|
+
stalenessBanner: () => stalenessBanner,
|
|
61943
62244
|
stageSchemaVersionSchema: () => stageSchemaVersionSchema,
|
|
61944
62245
|
stageRetryPolicySchema: () => stageRetryPolicySchema,
|
|
61945
62246
|
stageRecordSchema: () => stageRecordSchema,
|
|
@@ -61949,17 +62250,20 @@ __export(exports_src, {
|
|
|
61949
62250
|
stageContextLayerSchema: () => stageContextLayerSchema,
|
|
61950
62251
|
stageArtifactSchema: () => stageArtifactSchema,
|
|
61951
62252
|
stablePrefixesMatch: () => stablePrefixesMatch,
|
|
62253
|
+
sourceSummary: () => sourceSummary,
|
|
61952
62254
|
serializeStablePrefix: () => serializeStablePrefix,
|
|
61953
62255
|
serializeLayer: () => serializeLayer,
|
|
61954
62256
|
serializeEnvelope: () => serializeEnvelope,
|
|
62257
|
+
selectorDigest: () => selectorDigest,
|
|
61955
62258
|
sectionMatrixSchema: () => sectionMatrixSchema,
|
|
61956
62259
|
scaffoldFeatureScenarios: () => scaffoldFeatureScenarios,
|
|
61957
62260
|
resolvePricing: () => resolvePricing,
|
|
61958
62261
|
renderTaskTemplate: () => renderTaskTemplate,
|
|
61959
62262
|
renderScenarioStub: () => renderScenarioStub,
|
|
62263
|
+
renderReport: () => renderReport,
|
|
62264
|
+
renderMarkdown: () => renderMarkdown,
|
|
61960
62265
|
readLockMetadata: () => readLockMetadata,
|
|
61961
62266
|
queryEtlRecords: () => queryEtlRecords,
|
|
61962
|
-
queryAllEtlRecords: () => queryAllEtlRecords,
|
|
61963
62267
|
projectSnapshotSchema: () => projectSnapshotSchema,
|
|
61964
62268
|
passAllResolver: () => passAllResolver,
|
|
61965
62269
|
parseStageRecord: () => parseStageRecord,
|
|
@@ -61973,13 +62277,16 @@ __export(exports_src, {
|
|
|
61973
62277
|
normalizeTaskStatus: () => normalizeTaskStatus,
|
|
61974
62278
|
normalizeFeatureStatus: () => normalizeFeatureStatus,
|
|
61975
62279
|
normalizeCapabilityTier: () => normalizeCapabilityTier,
|
|
62280
|
+
messageRollup: () => messageRollup,
|
|
61976
62281
|
mergeStubs: () => mergeStubs,
|
|
61977
62282
|
matrixEntrySchema: () => matrixEntrySchema,
|
|
61978
62283
|
matchEtlPayloads: () => matchEtlPayloads,
|
|
61979
62284
|
matchEtlForAction: () => matchEtlForAction,
|
|
62285
|
+
loops: () => loops,
|
|
61980
62286
|
loadSqlMigrations: () => loadSqlMigrations,
|
|
61981
62287
|
loadAllEtlPayloads: () => loadAllEtlPayloads,
|
|
61982
62288
|
isTierEligible: () => isTierEligible,
|
|
62289
|
+
isStale: () => isStale,
|
|
61983
62290
|
isCompatibleStageVersion: () => isCompatibleStageVersion,
|
|
61984
62291
|
irreversibleExecutionSchema: () => irreversibleExecutionSchema,
|
|
61985
62292
|
inspectLock: () => inspectLock,
|
|
@@ -61994,6 +62301,7 @@ __export(exports_src, {
|
|
|
61994
62301
|
getNextFallback: () => getNextFallback,
|
|
61995
62302
|
getCanonicalStage: () => getCanonicalStage,
|
|
61996
62303
|
formatSummary: () => formatSummary,
|
|
62304
|
+
formatRatio: () => formatRatio,
|
|
61997
62305
|
featureStatusIcon: () => featureStatusIcon,
|
|
61998
62306
|
featureSnapshotSchema: () => featureSnapshotSchema,
|
|
61999
62307
|
featureFrontmatterSchema: () => featureFrontmatterSchema,
|
|
@@ -62003,13 +62311,13 @@ __export(exports_src, {
|
|
|
62003
62311
|
extractHistoryEvents: () => extractHistoryEvents,
|
|
62004
62312
|
extractClaudeTokens: () => extractClaudeTokens,
|
|
62005
62313
|
executionKindSchema: () => executionKindSchema,
|
|
62006
|
-
etlToCostRecord: () => etlToCostRecord,
|
|
62007
62314
|
escapeYamlValue: () => escapeYamlValue,
|
|
62008
62315
|
escapeYamlArrayElement: () => escapeYamlArrayElement,
|
|
62009
62316
|
envelopeSizeBudgetSchema: () => envelopeSizeBudgetSchema,
|
|
62010
62317
|
envelopeSchema: () => envelopeSchema,
|
|
62011
62318
|
envelopeProvenanceSchema: () => envelopeProvenanceSchema,
|
|
62012
62319
|
envelopeLayerSchema: () => envelopeLayerSchema,
|
|
62320
|
+
drift: () => drift,
|
|
62013
62321
|
deterministicExecutionSchema: () => deterministicExecutionSchema,
|
|
62014
62322
|
dbHealthCheck: () => dbHealthCheck,
|
|
62015
62323
|
createQueueConsumer: () => createQueueConsumer,
|
|
@@ -62018,6 +62326,7 @@ __export(exports_src, {
|
|
|
62018
62326
|
createJobQueue: () => createJobQueue,
|
|
62019
62327
|
createId: () => createId,
|
|
62020
62328
|
createBoundaryContext: () => createBoundaryContext,
|
|
62329
|
+
countCheckpointsBySource: () => countCheckpointsBySource,
|
|
62021
62330
|
computeSnapshotHash: () => computeSnapshotHash,
|
|
62022
62331
|
computeRecordCost: () => computeRecordCost,
|
|
62023
62332
|
computeInvalidationFingerprint: () => computeInvalidationFingerprint,
|
|
@@ -62028,18 +62337,22 @@ __export(exports_src, {
|
|
|
62028
62337
|
capabilityTierSchema: () => capabilityTierSchema,
|
|
62029
62338
|
canonicalJson: () => canonicalJson,
|
|
62030
62339
|
cacheHitRatio: () => cacheHitRatio,
|
|
62340
|
+
byTool: () => byTool,
|
|
62341
|
+
bySession: () => bySession,
|
|
62031
62342
|
bumpStageSchemaMinor: () => bumpStageSchemaMinor,
|
|
62032
62343
|
bumpStageSchemaMajor: () => bumpStageSchemaMajor,
|
|
62033
62344
|
buildTaskSkeleton: () => buildTaskSkeleton,
|
|
62034
62345
|
buildStageLayers: () => buildStageLayers,
|
|
62346
|
+
buildMessageWhere: () => buildMessageWhere,
|
|
62035
62347
|
attributeWithoutTelemetry: () => attributeWithoutTelemetry,
|
|
62036
62348
|
attributeFreshVsReused: () => attributeFreshVsReused,
|
|
62037
62349
|
atomicWriteAsync: () => atomicWriteAsync,
|
|
62038
62350
|
atomicWrite: () => atomicWrite,
|
|
62351
|
+
assertArtifactVersion: () => assertArtifactVersion,
|
|
62352
|
+
artifactToSummary: () => artifactToSummary,
|
|
62039
62353
|
artifactFingerprintsMatch: () => artifactFingerprintsMatch,
|
|
62040
62354
|
applyCliMigrations: () => applyCliMigrations,
|
|
62041
62355
|
appendDisclosurePlaceholders: () => appendDisclosurePlaceholders,
|
|
62042
|
-
aggregateCosts: () => aggregateCosts,
|
|
62043
62356
|
actionCostEstimated: () => actionCostEstimated,
|
|
62044
62357
|
actionCost: () => actionCost,
|
|
62045
62358
|
acquireEntityLock: () => acquireEntityLock,
|
|
@@ -62062,6 +62375,7 @@ __export(exports_src, {
|
|
|
62062
62375
|
StageRegistryError: () => StageRegistryError,
|
|
62063
62376
|
SYSTEM_EVENTS_SCHEMA_SQL: () => SYSTEM_EVENTS_SCHEMA_SQL,
|
|
62064
62377
|
SYSTEM_EVENTS_CORRELATION_COLUMNS_SCHEMA_SQL: () => SYSTEM_EVENTS_CORRELATION_COLUMNS_SCHEMA_SQL,
|
|
62378
|
+
STALENESS_THRESHOLD_HOURS: () => STALENESS_THRESHOLD_HOURS,
|
|
62065
62379
|
STAGE_REGISTRY_SCHEMA_VERSION: () => STAGE_REGISTRY_SCHEMA_VERSION,
|
|
62066
62380
|
STAGE_ID_PATTERN: () => STAGE_ID_PATTERN,
|
|
62067
62381
|
STABLE_LAYER_NAMES: () => STABLE_LAYER_NAMES,
|
|
@@ -62085,6 +62399,7 @@ __export(exports_src, {
|
|
|
62085
62399
|
InboxRecentDao: () => InboxRecentDao,
|
|
62086
62400
|
InboxMessageDao: () => InboxMessageDao,
|
|
62087
62401
|
INBOX_MESSAGES_SCHEMA_SQL: () => INBOX_MESSAGES_SCHEMA_SQL,
|
|
62402
|
+
HISTORY_ARTIFACT_SCHEMA_VERSION: () => HISTORY_ARTIFACT_SCHEMA_VERSION,
|
|
62088
62403
|
FEATURE_STATUS_ICONS: () => FEATURE_STATUS_ICONS,
|
|
62089
62404
|
FEATURE_STATUSES: () => FEATURE_STATUSES,
|
|
62090
62405
|
FEATURE_ID_PATTERN: () => FEATURE_ID_PATTERN,
|
|
@@ -62100,6 +62415,7 @@ __export(exports_src, {
|
|
|
62100
62415
|
CLI_MIGRATIONS: () => CLI_MIGRATIONS,
|
|
62101
62416
|
CAPABILITY_TIERS: () => CAPABILITY_TIERS,
|
|
62102
62417
|
CACHEABILITY_CLASSES: () => CACHEABILITY_CLASSES,
|
|
62418
|
+
ArtifactVersionError: () => ArtifactVersionError,
|
|
62103
62419
|
ArtifactDao: () => ArtifactDao,
|
|
62104
62420
|
ActionRunDao: () => ActionRunDao,
|
|
62105
62421
|
AUTHORITY_LANES: () => AUTHORITY_LANES,
|
|
@@ -63471,6 +63787,9 @@ var init_event_names = __esm(() => {
|
|
|
63471
63787
|
event("team.member.assigned", "team", "team"),
|
|
63472
63788
|
event("team.member.started", "team", "team"),
|
|
63473
63789
|
event("team.member.stopped", "team", "team"),
|
|
63790
|
+
event("history.import.completed", "history", "history-import"),
|
|
63791
|
+
event("history.analyze.completed", "history", "history-analyze"),
|
|
63792
|
+
event("history.daily.failed", "history", "history-daily"),
|
|
63474
63793
|
event("rule.run.start", "rule", "rule"),
|
|
63475
63794
|
event("rule.eval.start", "rule", "rule"),
|
|
63476
63795
|
event("rule.eval.done", "rule", "rule"),
|
|
@@ -65001,6 +65320,19 @@ var init_feature_service = __esm(() => {
|
|
|
65001
65320
|
});
|
|
65002
65321
|
|
|
65003
65322
|
// ../../packages/app/src/services/history-service.ts
|
|
65323
|
+
import {
|
|
65324
|
+
existsSync as existsSync5,
|
|
65325
|
+
mkdirSync as mkdirSync6,
|
|
65326
|
+
readdirSync as readdirSync5,
|
|
65327
|
+
readFileSync as readFileSync8,
|
|
65328
|
+
readlinkSync,
|
|
65329
|
+
rmSync as rmSync3,
|
|
65330
|
+
symlinkSync,
|
|
65331
|
+
unlinkSync as unlinkSync2,
|
|
65332
|
+
writeFileSync as writeFileSync4
|
|
65333
|
+
} from "fs";
|
|
65334
|
+
import { dirname as dirname9, isAbsolute, join as join10, resolve } from "path";
|
|
65335
|
+
|
|
65004
65336
|
class HistoryService {
|
|
65005
65337
|
ctx;
|
|
65006
65338
|
constructor(ctx) {
|
|
@@ -65017,12 +65349,372 @@ class HistoryService {
|
|
|
65017
65349
|
dryRun: opts.dryRun ?? false
|
|
65018
65350
|
});
|
|
65019
65351
|
}
|
|
65020
|
-
async analyze(
|
|
65352
|
+
async analyze(selector, opts = {}) {
|
|
65353
|
+
const top = opts.top ?? 20;
|
|
65354
|
+
const db2 = await this.ctx.getDb();
|
|
65355
|
+
const [mRows, tRows, toolRows, sessionRows, loopRows, driftRows, sourceRows] = await Promise.all([
|
|
65356
|
+
messageRollup(db2, selector),
|
|
65357
|
+
toolRollup(db2, selector),
|
|
65358
|
+
byTool(db2, selector, top),
|
|
65359
|
+
bySession(db2, selector, top),
|
|
65360
|
+
loops(db2, selector),
|
|
65361
|
+
drift(db2, selector),
|
|
65362
|
+
sourceSummary(db2, selector)
|
|
65363
|
+
]);
|
|
65364
|
+
const totals = foldTotals2(mRows, tRows);
|
|
65365
|
+
const bySource = foldGrouped(mRows, tRows, (m) => m.source, (t) => t.source);
|
|
65366
|
+
const byModel = foldGrouped(mRows, tRows, (m) => m.model ?? "unknown", (t) => t.model ?? "unknown");
|
|
65367
|
+
const byDay = foldGrouped(mRows, tRows, (m) => m.day ?? "", (t) => t.day ?? "");
|
|
65368
|
+
const daily = Object.entries(byDay).map(([date6, totals2]) => ({ date: date6, ...totals2 })).sort((a2, b) => a2.date.localeCompare(b.date));
|
|
65369
|
+
const coverage = buildCoverage(sourceRows, tRows, driftRows, opts.coverageErrors, opts.importCoverage);
|
|
65370
|
+
const artifact = {
|
|
65371
|
+
schemaVersion: HISTORY_ARTIFACT_SCHEMA_VERSION,
|
|
65372
|
+
generatedAt: new Date().toISOString(),
|
|
65373
|
+
spurVersion: opts.spurVersion ?? "",
|
|
65374
|
+
selector: { ...selector, sources: selector.sources ? [...selector.sources] : null },
|
|
65375
|
+
coverage,
|
|
65376
|
+
totals,
|
|
65377
|
+
bySource,
|
|
65378
|
+
byModel,
|
|
65379
|
+
daily,
|
|
65380
|
+
byTool: toolRows.map((r) => ({
|
|
65381
|
+
toolName: r.toolName,
|
|
65382
|
+
calls: r.calls,
|
|
65383
|
+
errors: r.errors,
|
|
65384
|
+
durationMsTotal: r.durationMsTotal ?? 0,
|
|
65385
|
+
durationMsMean: r.durationMsMean ?? 0,
|
|
65386
|
+
durationMsMax: r.durationMsMax ?? 0,
|
|
65387
|
+
durationUnmeasured: r.durationUnmeasured,
|
|
65388
|
+
resultBytes: r.resultBytes ?? 0
|
|
65389
|
+
})),
|
|
65390
|
+
bySession: sessionRows.map((r) => ({
|
|
65391
|
+
sessionId: r.sessionId,
|
|
65392
|
+
source: r.source,
|
|
65393
|
+
startedAt: r.startedAt,
|
|
65394
|
+
messages: r.messages,
|
|
65395
|
+
toolCalls: r.toolCalls,
|
|
65396
|
+
tokens: r.tokens ?? 0,
|
|
65397
|
+
costUsd: r.costUsd ?? 0,
|
|
65398
|
+
topTool: r.topTool
|
|
65399
|
+
})),
|
|
65400
|
+
loops: loopRows,
|
|
65401
|
+
warnings: [...buildWarnings(driftRows, coverage), ...opts.extraWarnings ?? []]
|
|
65402
|
+
};
|
|
65403
|
+
if (opts.out !== undefined || opts.cwd !== undefined) {
|
|
65404
|
+
writeArtifact(artifact, { out: opts.out, cwd: opts.cwd ?? process.cwd() });
|
|
65405
|
+
}
|
|
65406
|
+
return artifact;
|
|
65407
|
+
}
|
|
65408
|
+
async importAll(opts = {}) {
|
|
65409
|
+
const sources = (opts.sources ?? SOURCES).map((s2) => parseSource(s2));
|
|
65410
|
+
const timeoutMs = opts.sourceTimeout ?? DEFAULT_SOURCE_TIMEOUT_MS;
|
|
65411
|
+
const entries = [];
|
|
65412
|
+
const warnings = [];
|
|
65413
|
+
for (const source of sources) {
|
|
65414
|
+
const { coverageEntry, sourceWarnings } = await this.importOneIsolated(source, opts, timeoutMs);
|
|
65415
|
+
entries.push(coverageEntry);
|
|
65416
|
+
warnings.push(...sourceWarnings);
|
|
65417
|
+
}
|
|
65418
|
+
return { entries, exitCode: computeExitCode(entries), warnings };
|
|
65419
|
+
}
|
|
65420
|
+
async daily(opts = {}) {
|
|
65421
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
65422
|
+
const fanOut = await this.importAll({
|
|
65423
|
+
sources: opts.sources,
|
|
65424
|
+
sourceTimeout: opts.sourceTimeout,
|
|
65425
|
+
root: opts.root
|
|
65426
|
+
});
|
|
65427
|
+
const selector = {
|
|
65428
|
+
since: opts.since ?? null,
|
|
65429
|
+
until: opts.until ?? null,
|
|
65430
|
+
sources: null,
|
|
65431
|
+
sessionId: null,
|
|
65432
|
+
runId: null,
|
|
65433
|
+
taskWbs: null
|
|
65434
|
+
};
|
|
65435
|
+
const artifact = await this.analyze(selector, {
|
|
65436
|
+
spurVersion: opts.spurVersion,
|
|
65437
|
+
cwd,
|
|
65438
|
+
importCoverage: fanOut.entries,
|
|
65439
|
+
extraWarnings: fanOut.warnings
|
|
65440
|
+
});
|
|
65441
|
+
const pruned = pruneReports(cwd, REPORT_RETENTION_DAYS);
|
|
65442
|
+
return { fanOut, artifact, pruned };
|
|
65443
|
+
}
|
|
65444
|
+
async importOneIsolated(source, opts, timeoutMs) {
|
|
65021
65445
|
const db2 = await this.ctx.getDb();
|
|
65022
|
-
const
|
|
65023
|
-
const
|
|
65024
|
-
|
|
65446
|
+
const sourceWarnings = [];
|
|
65447
|
+
const checkpointCount = await countCheckpointsBySource(db2, source);
|
|
65448
|
+
const wasNonEmpty = checkpointCount > 0;
|
|
65449
|
+
try {
|
|
65450
|
+
const importPromise = this.import(source, {
|
|
65451
|
+
file: opts.file,
|
|
65452
|
+
root: opts.root,
|
|
65453
|
+
mode: opts.mode ?? (opts.file !== undefined && opts.file.length > 0 ? "force-file" : "incremental"),
|
|
65454
|
+
dryRun: opts.dryRun
|
|
65455
|
+
});
|
|
65456
|
+
const abort = new AbortController;
|
|
65457
|
+
const timer = setTimeout(() => abort.abort(new Error(`source '${source}' exceeded ${timeoutMs}ms timeout`)), timeoutMs);
|
|
65458
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
65459
|
+
abort.signal.addEventListener("abort", () => reject(abort.signal.reason));
|
|
65460
|
+
});
|
|
65461
|
+
let result;
|
|
65462
|
+
try {
|
|
65463
|
+
result = await Promise.race([importPromise, timeoutPromise]);
|
|
65464
|
+
} finally {
|
|
65465
|
+
clearTimeout(timer);
|
|
65466
|
+
}
|
|
65467
|
+
const status = result.scannedFiles === 0 ? "empty" : "ok";
|
|
65468
|
+
if (status === "empty" && wasNonEmpty) {
|
|
65469
|
+
sourceWarnings.push({
|
|
65470
|
+
code: "source-was-nonempty",
|
|
65471
|
+
source,
|
|
65472
|
+
detail: `source '${source}' previously had checkpoint rows but discovered 0 files`
|
|
65473
|
+
});
|
|
65474
|
+
}
|
|
65475
|
+
const coverageEntry = {
|
|
65476
|
+
source,
|
|
65477
|
+
status,
|
|
65478
|
+
files: result.scannedFiles,
|
|
65479
|
+
messages: result.importedRecords,
|
|
65480
|
+
toolCalls: 0,
|
|
65481
|
+
unknownRecords: result.unknownRecords,
|
|
65482
|
+
lastImportedAt: null,
|
|
65483
|
+
parseErrors: result.parseErrors.length,
|
|
65484
|
+
validationErrors: result.validationErrors.length,
|
|
65485
|
+
parseErrorSamples: result.parseErrors.slice(0, MAX_ERROR_SAMPLES).map(formatIssue),
|
|
65486
|
+
validationErrorSamples: result.validationErrors.slice(0, MAX_ERROR_SAMPLES).map(formatIssue)
|
|
65487
|
+
};
|
|
65488
|
+
return { coverageEntry, sourceWarnings };
|
|
65489
|
+
} catch (e) {
|
|
65490
|
+
const detail = e.message;
|
|
65491
|
+
sourceWarnings.push({ code: "source-failed", source, detail });
|
|
65492
|
+
return {
|
|
65493
|
+
coverageEntry: {
|
|
65494
|
+
source,
|
|
65495
|
+
status: "failed",
|
|
65496
|
+
files: 0,
|
|
65497
|
+
messages: 0,
|
|
65498
|
+
toolCalls: 0,
|
|
65499
|
+
unknownRecords: 0,
|
|
65500
|
+
lastImportedAt: null,
|
|
65501
|
+
parseErrors: 0,
|
|
65502
|
+
validationErrors: 0,
|
|
65503
|
+
parseErrorSamples: [],
|
|
65504
|
+
validationErrorSamples: []
|
|
65505
|
+
},
|
|
65506
|
+
sourceWarnings
|
|
65507
|
+
};
|
|
65508
|
+
}
|
|
65509
|
+
}
|
|
65510
|
+
}
|
|
65511
|
+
function emptyTotals() {
|
|
65512
|
+
return {
|
|
65513
|
+
inputTokens: 0,
|
|
65514
|
+
outputTokens: 0,
|
|
65515
|
+
cacheReadTokens: 0,
|
|
65516
|
+
cacheWriteTokens: 0,
|
|
65517
|
+
costUsd: 0,
|
|
65518
|
+
records: 0,
|
|
65519
|
+
recordsWithUsage: 0,
|
|
65520
|
+
messages: 0,
|
|
65521
|
+
toolCalls: 0,
|
|
65522
|
+
durationMs: 0,
|
|
65523
|
+
durationUnmeasured: 0
|
|
65524
|
+
};
|
|
65525
|
+
}
|
|
65526
|
+
function foldMessage(bucket, row) {
|
|
65527
|
+
bucket.messages += row.messages;
|
|
65528
|
+
bucket.records += row.messages;
|
|
65529
|
+
bucket.inputTokens += row.inputTokens ?? 0;
|
|
65530
|
+
bucket.outputTokens += row.outputTokens ?? 0;
|
|
65531
|
+
bucket.cacheReadTokens += row.cacheReadTokens ?? 0;
|
|
65532
|
+
bucket.cacheWriteTokens += row.cacheWriteTokens ?? 0;
|
|
65533
|
+
bucket.costUsd += row.costUsd ?? 0;
|
|
65534
|
+
bucket.recordsWithUsage += row.recordsWithUsage;
|
|
65535
|
+
}
|
|
65536
|
+
function foldTool(bucket, row) {
|
|
65537
|
+
bucket.toolCalls += row.toolCalls;
|
|
65538
|
+
bucket.durationMs += row.durationMs ?? 0;
|
|
65539
|
+
bucket.durationUnmeasured += row.durationUnmeasured;
|
|
65540
|
+
}
|
|
65541
|
+
function foldTotals2(mRows, tRows) {
|
|
65542
|
+
const totals = emptyTotals();
|
|
65543
|
+
for (const row of mRows)
|
|
65544
|
+
foldMessage(totals, row);
|
|
65545
|
+
for (const row of tRows)
|
|
65546
|
+
foldTool(totals, row);
|
|
65547
|
+
return totals;
|
|
65548
|
+
}
|
|
65549
|
+
function foldGrouped(mRows, tRows, mKey, tKey) {
|
|
65550
|
+
const map2 = {};
|
|
65551
|
+
for (const row of mRows) {
|
|
65552
|
+
const key = mKey(row);
|
|
65553
|
+
const bucket = map2[key] ?? emptyTotals();
|
|
65554
|
+
map2[key] = bucket;
|
|
65555
|
+
foldMessage(bucket, row);
|
|
65556
|
+
}
|
|
65557
|
+
for (const row of tRows) {
|
|
65558
|
+
const key = tKey(row);
|
|
65559
|
+
const bucket = map2[key] ?? emptyTotals();
|
|
65560
|
+
map2[key] = bucket;
|
|
65561
|
+
foldTool(bucket, row);
|
|
65025
65562
|
}
|
|
65563
|
+
return map2;
|
|
65564
|
+
}
|
|
65565
|
+
function buildCoverage(sourceRows, tRows, driftRows, coverageErrors, importCoverage) {
|
|
65566
|
+
if (importCoverage !== undefined) {
|
|
65567
|
+
const toolCounts2 = {};
|
|
65568
|
+
for (const row of tRows)
|
|
65569
|
+
toolCounts2[row.source] = (toolCounts2[row.source] ?? 0) + row.toolCalls;
|
|
65570
|
+
const unknownCounts2 = {};
|
|
65571
|
+
for (const row of driftRows)
|
|
65572
|
+
unknownCounts2[row.source] = (unknownCounts2[row.source] ?? 0) + row.n;
|
|
65573
|
+
const sqlBySource = new Map;
|
|
65574
|
+
for (const row of sourceRows)
|
|
65575
|
+
sqlBySource.set(row.source, row);
|
|
65576
|
+
return importCoverage.map((imp) => {
|
|
65577
|
+
if (imp.status === "ok") {
|
|
65578
|
+
const sql4 = sqlBySource.get(imp.source);
|
|
65579
|
+
return {
|
|
65580
|
+
source: imp.source,
|
|
65581
|
+
status: "ok",
|
|
65582
|
+
files: sql4?.files ?? imp.files,
|
|
65583
|
+
messages: sql4?.messages ?? imp.messages,
|
|
65584
|
+
toolCalls: toolCounts2[imp.source] ?? 0,
|
|
65585
|
+
unknownRecords: unknownCounts2[imp.source] ?? 0,
|
|
65586
|
+
lastImportedAt: sql4?.lastImportedAt ?? null,
|
|
65587
|
+
parseErrors: imp.parseErrors,
|
|
65588
|
+
validationErrors: imp.validationErrors,
|
|
65589
|
+
parseErrorSamples: imp.parseErrorSamples,
|
|
65590
|
+
validationErrorSamples: imp.validationErrorSamples
|
|
65591
|
+
};
|
|
65592
|
+
}
|
|
65593
|
+
return imp;
|
|
65594
|
+
});
|
|
65595
|
+
}
|
|
65596
|
+
const toolCounts = {};
|
|
65597
|
+
for (const row of tRows)
|
|
65598
|
+
toolCounts[row.source] = (toolCounts[row.source] ?? 0) + row.toolCalls;
|
|
65599
|
+
const unknownCounts = {};
|
|
65600
|
+
for (const row of driftRows)
|
|
65601
|
+
unknownCounts[row.source] = (unknownCounts[row.source] ?? 0) + row.n;
|
|
65602
|
+
return sourceRows.map((s2) => {
|
|
65603
|
+
const err = coverageErrors?.[s2.source] ?? { parseErrors: [], validationErrors: [] };
|
|
65604
|
+
return {
|
|
65605
|
+
source: s2.source,
|
|
65606
|
+
status: s2.messages > 0 ? "ok" : "empty",
|
|
65607
|
+
files: s2.files,
|
|
65608
|
+
messages: s2.messages,
|
|
65609
|
+
toolCalls: toolCounts[s2.source] ?? 0,
|
|
65610
|
+
unknownRecords: unknownCounts[s2.source] ?? 0,
|
|
65611
|
+
lastImportedAt: s2.lastImportedAt,
|
|
65612
|
+
parseErrors: err.parseErrors.length,
|
|
65613
|
+
validationErrors: err.validationErrors.length,
|
|
65614
|
+
parseErrorSamples: err.parseErrors,
|
|
65615
|
+
validationErrorSamples: err.validationErrors
|
|
65616
|
+
};
|
|
65617
|
+
});
|
|
65618
|
+
}
|
|
65619
|
+
function buildWarnings(driftRows, coverage) {
|
|
65620
|
+
const warnings = [];
|
|
65621
|
+
const driftBySource = new Map;
|
|
65622
|
+
for (const row of driftRows)
|
|
65623
|
+
driftBySource.set(row.source, (driftBySource.get(row.source) ?? 0) + row.n);
|
|
65624
|
+
for (const [source, n2] of driftBySource) {
|
|
65625
|
+
warnings.push({ code: "unknown-drift", source, detail: `${n2} records with unknown disposition` });
|
|
65626
|
+
}
|
|
65627
|
+
for (const entry of coverage) {
|
|
65628
|
+
if (entry.status === "empty") {
|
|
65629
|
+
warnings.push({ code: "source-empty", source: entry.source, detail: "0 messages discovered" });
|
|
65630
|
+
}
|
|
65631
|
+
}
|
|
65632
|
+
return warnings;
|
|
65633
|
+
}
|
|
65634
|
+
function writeArtifact(artifact, opts) {
|
|
65635
|
+
const { artifactPath, sidecarPath } = resolveArtifactPaths(artifact, opts);
|
|
65636
|
+
const { bounded: bounded2, overflow } = boundCoverage(artifact.coverage);
|
|
65637
|
+
mkdirSync6(dirname9(artifactPath), { recursive: true });
|
|
65638
|
+
writeFileSync4(artifactPath, JSON.stringify({ ...artifact, coverage: bounded2 }, null, 2));
|
|
65639
|
+
if (overflow.length > 0) {
|
|
65640
|
+
mkdirSync6(dirname9(sidecarPath), { recursive: true });
|
|
65641
|
+
writeFileSync4(sidecarPath, `${overflow.map((line) => JSON.stringify(line)).join(`
|
|
65642
|
+
`)}
|
|
65643
|
+
`);
|
|
65644
|
+
}
|
|
65645
|
+
if (opts.out === undefined) {
|
|
65646
|
+
updateLatestPointer(opts, artifactPath);
|
|
65647
|
+
}
|
|
65648
|
+
return { artifactPath, sidecarPath };
|
|
65649
|
+
}
|
|
65650
|
+
function resolveArtifactPaths(artifact, opts) {
|
|
65651
|
+
if (opts.out !== undefined) {
|
|
65652
|
+
const out = resolve(opts.out);
|
|
65653
|
+
return { artifactPath: out, sidecarPath: `${out.replace(/\.json$/, "")}.errors.jsonl` };
|
|
65654
|
+
}
|
|
65655
|
+
const base2 = resolve(opts.cwd, ".spur", "reports", "history");
|
|
65656
|
+
const dateDir = join10(base2, artifact.generatedAt.slice(0, 10));
|
|
65657
|
+
const name = `analyze-${selectorDigest(artifact.selector)}`;
|
|
65658
|
+
return { artifactPath: join10(dateDir, `${name}.json`), sidecarPath: join10(dateDir, `${name}.errors.jsonl`) };
|
|
65659
|
+
}
|
|
65660
|
+
function boundCoverage(coverage) {
|
|
65661
|
+
const overflow = [];
|
|
65662
|
+
const bounded2 = coverage.map((entry) => {
|
|
65663
|
+
const pe = entry.parseErrorSamples;
|
|
65664
|
+
const ve = entry.validationErrorSamples;
|
|
65665
|
+
for (const sample of pe.slice(MAX_ERROR_SAMPLES)) {
|
|
65666
|
+
overflow.push({ source: entry.source, kind: "parse", sample });
|
|
65667
|
+
}
|
|
65668
|
+
for (const sample of ve.slice(MAX_ERROR_SAMPLES)) {
|
|
65669
|
+
overflow.push({ source: entry.source, kind: "validation", sample });
|
|
65670
|
+
}
|
|
65671
|
+
return {
|
|
65672
|
+
...entry,
|
|
65673
|
+
parseErrorSamples: pe.slice(0, MAX_ERROR_SAMPLES),
|
|
65674
|
+
validationErrorSamples: ve.slice(0, MAX_ERROR_SAMPLES)
|
|
65675
|
+
};
|
|
65676
|
+
});
|
|
65677
|
+
return { bounded: bounded2, overflow };
|
|
65678
|
+
}
|
|
65679
|
+
function updateLatestPointer(opts, artifactPath) {
|
|
65680
|
+
const base2 = resolve(opts.cwd, ".spur", "reports", "history");
|
|
65681
|
+
const latest = join10(base2, "latest.json");
|
|
65682
|
+
mkdirSync6(base2, { recursive: true });
|
|
65683
|
+
if (existsSync5(latest))
|
|
65684
|
+
unlinkSync2(latest);
|
|
65685
|
+
symlinkSync(artifactPath, latest);
|
|
65686
|
+
}
|
|
65687
|
+
function resolveArtifactPath(explicitPath, cwd) {
|
|
65688
|
+
if (explicitPath !== undefined && explicitPath.length > 0) {
|
|
65689
|
+
return { path: resolve(explicitPath), resolution: "explicit" };
|
|
65690
|
+
}
|
|
65691
|
+
const latest = resolve(cwd, ".spur", "reports", "history", "latest.json");
|
|
65692
|
+
if (!existsSync5(latest)) {
|
|
65693
|
+
throw new Error(`No artifact path given and no latest pointer at ${latest}. ` + "Run `spur history analyze` first, or pass an explicit artifact path.");
|
|
65694
|
+
}
|
|
65695
|
+
const target = readlinkSync(latest);
|
|
65696
|
+
const resolved = isAbsolute(target) ? target : resolve(dirname9(latest), target);
|
|
65697
|
+
if (!existsSync5(resolved)) {
|
|
65698
|
+
throw new Error(`Latest pointer ${latest} \u2192 ${resolved}, but the target does not exist.`);
|
|
65699
|
+
}
|
|
65700
|
+
return { path: resolved, resolution: "pointer" };
|
|
65701
|
+
}
|
|
65702
|
+
function runHistoryReport(opts) {
|
|
65703
|
+
const { path: artifactPath, resolution } = resolveArtifactPath(opts.path, opts.cwd);
|
|
65704
|
+
const raw = readFileSync8(artifactPath, "utf8");
|
|
65705
|
+
let parsed;
|
|
65706
|
+
try {
|
|
65707
|
+
parsed = JSON.parse(raw);
|
|
65708
|
+
} catch (e) {
|
|
65709
|
+
throw new Error(`Artifact ${artifactPath} is not valid JSON: ${e.message}`);
|
|
65710
|
+
}
|
|
65711
|
+
const artifact = parsed;
|
|
65712
|
+
assertArtifactVersion(artifact.schemaVersion ?? -1, artifactPath);
|
|
65713
|
+
const report = renderReport(artifact);
|
|
65714
|
+
const markdown = renderMarkdown(artifact);
|
|
65715
|
+
const markdownPath = artifactPath.endsWith(".json") ? artifactPath.replace(/\.json$/, ".md") : `${artifactPath}.md`;
|
|
65716
|
+
writeFileSync4(markdownPath, markdown);
|
|
65717
|
+
return { report, artifactPath, resolution, markdownPath, artifact };
|
|
65026
65718
|
}
|
|
65027
65719
|
function parseSource(value) {
|
|
65028
65720
|
if (SOURCES.includes(value)) {
|
|
@@ -65036,7 +65728,43 @@ function parseMode(value) {
|
|
|
65036
65728
|
}
|
|
65037
65729
|
throw new Error(`Invalid history import mode "${value}". Expected one of: ${MODES.join(", ")}`);
|
|
65038
65730
|
}
|
|
65039
|
-
|
|
65731
|
+
function computeExitCode(entries) {
|
|
65732
|
+
const failed = entries.filter((e) => e.status === "failed").length;
|
|
65733
|
+
if (failed === 0)
|
|
65734
|
+
return 0;
|
|
65735
|
+
if (failed === entries.length)
|
|
65736
|
+
return 1;
|
|
65737
|
+
return 2;
|
|
65738
|
+
}
|
|
65739
|
+
function formatIssue(issue2) {
|
|
65740
|
+
return `${issue2.sourceFile}:${issue2.sourceLine}: ${issue2.reason}`;
|
|
65741
|
+
}
|
|
65742
|
+
function pruneReports(cwd, retentionDays = REPORT_RETENTION_DAYS, now2 = new Date) {
|
|
65743
|
+
const dir = join10(cwd, ".spur", "reports", "history");
|
|
65744
|
+
let entries;
|
|
65745
|
+
try {
|
|
65746
|
+
entries = readdirSync5(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
65747
|
+
} catch {
|
|
65748
|
+
return [];
|
|
65749
|
+
}
|
|
65750
|
+
const cutoff = new Date(now2);
|
|
65751
|
+
cutoff.setHours(0, 0, 0, 0);
|
|
65752
|
+
cutoff.setDate(cutoff.getDate() - retentionDays);
|
|
65753
|
+
const pruned = [];
|
|
65754
|
+
for (const name of entries) {
|
|
65755
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(name))
|
|
65756
|
+
continue;
|
|
65757
|
+
const entryDate = new Date(`${name}T00:00:00`);
|
|
65758
|
+
if (entryDate >= cutoff)
|
|
65759
|
+
continue;
|
|
65760
|
+
try {
|
|
65761
|
+
rmSync3(join10(dir, name), { recursive: true, force: true });
|
|
65762
|
+
pruned.push(name);
|
|
65763
|
+
} catch {}
|
|
65764
|
+
}
|
|
65765
|
+
return pruned.sort((a2, b) => a2.localeCompare(b));
|
|
65766
|
+
}
|
|
65767
|
+
var SOURCES, MODES, MAX_ERROR_SAMPLES = 20, DEFAULT_SOURCE_TIMEOUT_MS = 600000, REPORT_RETENTION_DAYS = 90;
|
|
65040
65768
|
var init_history_service = __esm(() => {
|
|
65041
65769
|
init_src2();
|
|
65042
65770
|
init_dist8();
|
|
@@ -65596,41 +66324,41 @@ var init_process_inventory_service = __esm(() => {
|
|
|
65596
66324
|
});
|
|
65597
66325
|
|
|
65598
66326
|
// ../../packages/app/src/services/project-registry.ts
|
|
65599
|
-
import { existsSync as
|
|
66327
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync7, readFileSync as readFileSync9, realpathSync as realpathSync3, renameSync as renameSync4, rmSync as rmSync4, writeFileSync as writeFileSync5 } from "fs";
|
|
65600
66328
|
import { connect, createServer } from "net";
|
|
65601
66329
|
import { homedir as homedir3 } from "os";
|
|
65602
|
-
import { dirname as
|
|
66330
|
+
import { dirname as dirname10, join as join11, resolve as resolve2 } from "path";
|
|
65603
66331
|
function normalizeProjectPath(pathInput) {
|
|
65604
66332
|
const trimmed = pathInput.trim();
|
|
65605
66333
|
let expanded = trimmed;
|
|
65606
66334
|
if (trimmed === "~") {
|
|
65607
66335
|
expanded = homedir3();
|
|
65608
66336
|
} else if (trimmed.startsWith("~/")) {
|
|
65609
|
-
expanded =
|
|
66337
|
+
expanded = join11(homedir3(), trimmed.slice(2));
|
|
65610
66338
|
} else {
|
|
65611
|
-
expanded =
|
|
66339
|
+
expanded = resolve2(trimmed);
|
|
65612
66340
|
}
|
|
65613
66341
|
try {
|
|
65614
|
-
if (
|
|
66342
|
+
if (existsSync6(expanded)) {
|
|
65615
66343
|
return realpathSync3(expanded);
|
|
65616
66344
|
}
|
|
65617
66345
|
} catch {}
|
|
65618
66346
|
return expanded;
|
|
65619
66347
|
}
|
|
65620
66348
|
async function isPortLiveOnHost(port, host, timeoutMs) {
|
|
65621
|
-
return new Promise((
|
|
66349
|
+
return new Promise((resolve3) => {
|
|
65622
66350
|
const socket = connect({ port, host, timeout: timeoutMs });
|
|
65623
66351
|
socket.on("connect", () => {
|
|
65624
66352
|
socket.destroy();
|
|
65625
|
-
|
|
66353
|
+
resolve3(true);
|
|
65626
66354
|
});
|
|
65627
66355
|
socket.on("timeout", () => {
|
|
65628
66356
|
socket.destroy();
|
|
65629
|
-
|
|
66357
|
+
resolve3(false);
|
|
65630
66358
|
});
|
|
65631
66359
|
socket.on("error", () => {
|
|
65632
66360
|
socket.destroy();
|
|
65633
|
-
|
|
66361
|
+
resolve3(false);
|
|
65634
66362
|
});
|
|
65635
66363
|
});
|
|
65636
66364
|
}
|
|
@@ -65646,12 +66374,12 @@ async function isPortLive(port, timeoutMs = 200) {
|
|
|
65646
66374
|
async function isPortAvailable(port) {
|
|
65647
66375
|
if (port <= 0 || port > 65535)
|
|
65648
66376
|
return false;
|
|
65649
|
-
return new Promise((
|
|
66377
|
+
return new Promise((resolve3) => {
|
|
65650
66378
|
const server = createServer();
|
|
65651
66379
|
server.unref();
|
|
65652
|
-
server.on("error", () =>
|
|
66380
|
+
server.on("error", () => resolve3(false));
|
|
65653
66381
|
server.listen({ port, host: "127.0.0.1" }, () => {
|
|
65654
|
-
server.close(() =>
|
|
66382
|
+
server.close(() => resolve3(true));
|
|
65655
66383
|
});
|
|
65656
66384
|
});
|
|
65657
66385
|
}
|
|
@@ -65664,15 +66392,15 @@ class ProjectRegistry {
|
|
|
65664
66392
|
this.lockDir = `${this.filePath}.lock`;
|
|
65665
66393
|
}
|
|
65666
66394
|
async withLock(fn) {
|
|
65667
|
-
const lockParent =
|
|
65668
|
-
if (!
|
|
65669
|
-
|
|
66395
|
+
const lockParent = dirname10(this.lockDir);
|
|
66396
|
+
if (!existsSync6(lockParent)) {
|
|
66397
|
+
mkdirSync7(lockParent, { recursive: true });
|
|
65670
66398
|
}
|
|
65671
66399
|
const maxTries = 50;
|
|
65672
66400
|
let acquired = false;
|
|
65673
66401
|
for (let i2 = 0;i2 < maxTries; i2++) {
|
|
65674
66402
|
try {
|
|
65675
|
-
|
|
66403
|
+
mkdirSync7(this.lockDir);
|
|
65676
66404
|
acquired = true;
|
|
65677
66405
|
break;
|
|
65678
66406
|
} catch {
|
|
@@ -65681,8 +66409,8 @@ class ProjectRegistry {
|
|
|
65681
66409
|
}
|
|
65682
66410
|
if (!acquired) {
|
|
65683
66411
|
try {
|
|
65684
|
-
|
|
65685
|
-
|
|
66412
|
+
rmSync4(this.lockDir, { recursive: true, force: true });
|
|
66413
|
+
mkdirSync7(this.lockDir);
|
|
65686
66414
|
acquired = true;
|
|
65687
66415
|
} catch {
|
|
65688
66416
|
throw new Error(`Failed to acquire lock for project registry: ${this.lockDir}`);
|
|
@@ -65693,17 +66421,17 @@ class ProjectRegistry {
|
|
|
65693
66421
|
} finally {
|
|
65694
66422
|
if (acquired) {
|
|
65695
66423
|
try {
|
|
65696
|
-
|
|
66424
|
+
rmSync4(this.lockDir, { recursive: true, force: true });
|
|
65697
66425
|
} catch {}
|
|
65698
66426
|
}
|
|
65699
66427
|
}
|
|
65700
66428
|
}
|
|
65701
66429
|
readRaw() {
|
|
65702
|
-
if (!
|
|
66430
|
+
if (!existsSync6(this.filePath)) {
|
|
65703
66431
|
return { schema_version: 1, projects: [] };
|
|
65704
66432
|
}
|
|
65705
66433
|
try {
|
|
65706
|
-
const raw =
|
|
66434
|
+
const raw = readFileSync9(this.filePath, "utf-8");
|
|
65707
66435
|
const json3 = JSON.parse(raw);
|
|
65708
66436
|
return projectsFileSchema.parse(json3);
|
|
65709
66437
|
} catch {
|
|
@@ -65711,13 +66439,13 @@ class ProjectRegistry {
|
|
|
65711
66439
|
}
|
|
65712
66440
|
}
|
|
65713
66441
|
writeRaw(data) {
|
|
65714
|
-
const parentDir2 =
|
|
65715
|
-
if (!
|
|
65716
|
-
|
|
66442
|
+
const parentDir2 = dirname10(this.filePath);
|
|
66443
|
+
if (!existsSync6(parentDir2)) {
|
|
66444
|
+
mkdirSync7(parentDir2, { recursive: true });
|
|
65717
66445
|
}
|
|
65718
66446
|
const tmpFile = `${this.filePath}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
65719
66447
|
const content = JSON.stringify(data, null, 2);
|
|
65720
|
-
|
|
66448
|
+
writeFileSync5(tmpFile, content, "utf-8");
|
|
65721
66449
|
renameSync4(tmpFile, this.filePath);
|
|
65722
66450
|
}
|
|
65723
66451
|
async healTildePaths() {
|
|
@@ -65848,8 +66576,8 @@ var init_project_registry = __esm(() => {
|
|
|
65848
66576
|
});
|
|
65849
66577
|
|
|
65850
66578
|
// ../../packages/app/src/services/project-start.ts
|
|
65851
|
-
import { existsSync as
|
|
65852
|
-
import { basename as basename2, resolve as
|
|
66579
|
+
import { existsSync as existsSync7 } from "fs";
|
|
66580
|
+
import { basename as basename2, resolve as resolve3 } from "path";
|
|
65853
66581
|
function shQuote(value) {
|
|
65854
66582
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
65855
66583
|
}
|
|
@@ -65865,7 +66593,7 @@ function setDetachedServeSpawnForTests(spawn2) {
|
|
|
65865
66593
|
testDetachedServeSpawn = spawn2;
|
|
65866
66594
|
}
|
|
65867
66595
|
function resolveSpurServeCommand() {
|
|
65868
|
-
if (process.env.SPUR_CLI_PATH &&
|
|
66596
|
+
if (process.env.SPUR_CLI_PATH && existsSync7(process.env.SPUR_CLI_PATH)) {
|
|
65869
66597
|
return [process.execPath, process.env.SPUR_CLI_PATH];
|
|
65870
66598
|
}
|
|
65871
66599
|
const argv1 = process.argv[1];
|
|
@@ -65875,8 +66603,8 @@ function resolveSpurServeCommand() {
|
|
|
65875
66603
|
return [process.execPath, argv1];
|
|
65876
66604
|
}
|
|
65877
66605
|
}
|
|
65878
|
-
const monorepoCli =
|
|
65879
|
-
if (
|
|
66606
|
+
const monorepoCli = resolve3(process.cwd(), "apps/cli/src/index.ts");
|
|
66607
|
+
if (existsSync7(monorepoCli)) {
|
|
65880
66608
|
return [process.execPath, monorepoCli];
|
|
65881
66609
|
}
|
|
65882
66610
|
const fromPath = typeof Bun !== "undefined" && typeof Bun.which === "function" ? Bun.which("spur") : null;
|
|
@@ -65889,14 +66617,14 @@ async function startRegisteredProject(registry2, target, options = {}) {
|
|
|
65889
66617
|
let entry = await registry2.getByName(target) ?? await registry2.getByPath(target);
|
|
65890
66618
|
if (!entry) {
|
|
65891
66619
|
const absPath = normalizeProjectPath(target);
|
|
65892
|
-
if (
|
|
66620
|
+
if (existsSync7(absPath)) {
|
|
65893
66621
|
entry = await registry2.upsert({ path: absPath, name: basename2(absPath), port: 0 });
|
|
65894
66622
|
} else {
|
|
65895
66623
|
throw new Error(`Project not found in registry: "${target}"`);
|
|
65896
66624
|
}
|
|
65897
66625
|
}
|
|
65898
66626
|
const projectPath = normalizeProjectPath(entry.path);
|
|
65899
|
-
if (!
|
|
66627
|
+
if (!existsSync7(projectPath)) {
|
|
65900
66628
|
throw new Error(`Project path does not exist: "${entry.path}" (resolved to ${projectPath}). Update ~/.config/spur/projects.json.`);
|
|
65901
66629
|
}
|
|
65902
66630
|
if (projectPath !== entry.path) {
|
|
@@ -65987,7 +66715,7 @@ var init_project_start = __esm(() => {
|
|
|
65987
66715
|
|
|
65988
66716
|
// ../../packages/app/src/services/rule-service.ts
|
|
65989
66717
|
import { homedir as homedir4 } from "os";
|
|
65990
|
-
import { delimiter, join as
|
|
66718
|
+
import { delimiter, join as join12, relative as relative2, resolve as resolve4 } from "path";
|
|
65991
66719
|
|
|
65992
66720
|
class RuleService {
|
|
65993
66721
|
context;
|
|
@@ -66166,22 +66894,22 @@ ${ruleIds.join(`
|
|
|
66166
66894
|
if (envValue !== undefined && envValue.length > 0) {
|
|
66167
66895
|
for (const entry of envValue.split(delimiter)) {
|
|
66168
66896
|
if (entry.length > 0) {
|
|
66169
|
-
layers.push({ id: "env-override", path:
|
|
66897
|
+
layers.push({ id: "env-override", path: resolve4(cwd, entry), priority: -10 });
|
|
66170
66898
|
}
|
|
66171
66899
|
}
|
|
66172
66900
|
}
|
|
66173
|
-
layers.push({ id: "local", path:
|
|
66901
|
+
layers.push({ id: "local", path: resolve4(cwd, LOCAL_RULES_DIR), priority: 0 });
|
|
66174
66902
|
const globalOverride = env.SPUR_GLOBAL_RULES_DIR;
|
|
66175
66903
|
const hasGlobalOverride = globalOverride !== undefined && globalOverride.length > 0;
|
|
66176
66904
|
layers.push({
|
|
66177
66905
|
id: "global",
|
|
66178
|
-
path: hasGlobalOverride ?
|
|
66906
|
+
path: hasGlobalOverride ? resolve4(cwd, globalOverride) : join12(homedir4(), GLOBAL_RULES_DIR),
|
|
66179
66907
|
priority: 10
|
|
66180
66908
|
});
|
|
66181
66909
|
if (opts.includeBundled && !hasGlobalOverride) {
|
|
66182
66910
|
const bundledConfig = bundledConfigRoot();
|
|
66183
66911
|
if (bundledConfig !== null) {
|
|
66184
|
-
layers.push({ id: "bundled-config", path:
|
|
66912
|
+
layers.push({ id: "bundled-config", path: join12(bundledConfig, "rules"), priority: 15 });
|
|
66185
66913
|
}
|
|
66186
66914
|
const bundled = await bundledRulesRoot();
|
|
66187
66915
|
if (bundled !== null)
|
|
@@ -66331,7 +67059,7 @@ ${ruleIds.join(`
|
|
|
66331
67059
|
async collectValidationErrors(source, validateSchema) {
|
|
66332
67060
|
const { cwd, fs: fs3 } = this.context;
|
|
66333
67061
|
if (source.kind === "file") {
|
|
66334
|
-
const absolute =
|
|
67062
|
+
const absolute = resolve4(cwd, source.value);
|
|
66335
67063
|
if (!await fs3.exists(absolute))
|
|
66336
67064
|
return [`File not found: ${absolute}`];
|
|
66337
67065
|
try {
|
|
@@ -66355,7 +67083,7 @@ ${ruleIds.join(`
|
|
|
66355
67083
|
const { fs: fs3 } = this.context;
|
|
66356
67084
|
for (const root of await this.ruleRoots()) {
|
|
66357
67085
|
for (const ext of ["yaml", "yml", "json"]) {
|
|
66358
|
-
if (await fs3.exists(
|
|
67086
|
+
if (await fs3.exists(join12(root, `${name}.${ext}`)))
|
|
66359
67087
|
return true;
|
|
66360
67088
|
}
|
|
66361
67089
|
}
|
|
@@ -66391,7 +67119,7 @@ ${ruleIds.join(`
|
|
|
66391
67119
|
for (const layer of await this.existingRuleSourceLayers()) {
|
|
66392
67120
|
const entries = await this.context.fs.readDir(layer.path);
|
|
66393
67121
|
const named = entries.map((entry) => ({ entry, name: entry.match(/^([\w-]+)\.(?:ya?ml|json)$/i)?.[1] ?? "" })).filter(({ name }) => name.length > 0);
|
|
66394
|
-
const stats = await Promise.all(named.map(({ entry }) => this.context.fs.stat(
|
|
67122
|
+
const stats = await Promise.all(named.map(({ entry }) => this.context.fs.stat(join12(layer.path, entry))));
|
|
66395
67123
|
named.forEach(({ name }, i2) => {
|
|
66396
67124
|
if (stats[i2]?.isFile())
|
|
66397
67125
|
candidates.add(name);
|
|
@@ -66413,7 +67141,7 @@ ${ruleIds.join(`
|
|
|
66413
67141
|
for (const layer of layers) {
|
|
66414
67142
|
for (const file2 of await this.listRuleFilesInLayer(layer.path)) {
|
|
66415
67143
|
if (!merged.has(file2))
|
|
66416
|
-
merged.set(file2, { absolutePath:
|
|
67144
|
+
merged.set(file2, { absolutePath: join12(layer.path, file2), source: layer.id });
|
|
66417
67145
|
}
|
|
66418
67146
|
}
|
|
66419
67147
|
const files = [];
|
|
@@ -66481,7 +67209,7 @@ ${ruleIds.join(`
|
|
|
66481
67209
|
for (const entry of entries.sort()) {
|
|
66482
67210
|
if (entry === "presets")
|
|
66483
67211
|
continue;
|
|
66484
|
-
const stat = await this.context.fs.stat(
|
|
67212
|
+
const stat = await this.context.fs.stat(join12(root, entry));
|
|
66485
67213
|
if (stat?.isDirectory())
|
|
66486
67214
|
dirs.push(entry);
|
|
66487
67215
|
}
|
|
@@ -66489,12 +67217,12 @@ ${ruleIds.join(`
|
|
|
66489
67217
|
}
|
|
66490
67218
|
async listRuleFiles(root, relativeDir) {
|
|
66491
67219
|
const { fs: fs3 } = this.context;
|
|
66492
|
-
const dir =
|
|
67220
|
+
const dir = join12(root, relativeDir);
|
|
66493
67221
|
const entries = await fs3.readDir(dir);
|
|
66494
67222
|
const files = [];
|
|
66495
67223
|
for (const entry of entries.sort()) {
|
|
66496
|
-
const relativePath2 = relativeDir.length === 0 ? entry :
|
|
66497
|
-
const absolutePath =
|
|
67224
|
+
const relativePath2 = relativeDir.length === 0 ? entry : join12(relativeDir, entry);
|
|
67225
|
+
const absolutePath = join12(root, relativePath2);
|
|
66498
67226
|
const stat = await fs3.stat(absolutePath);
|
|
66499
67227
|
if (stat?.isDirectory()) {
|
|
66500
67228
|
files.push(...await this.listRuleFiles(root, relativePath2));
|
|
@@ -66519,8 +67247,8 @@ var init_rule_service = __esm(() => {
|
|
|
66519
67247
|
init_src2();
|
|
66520
67248
|
init_dist6();
|
|
66521
67249
|
init_dist10();
|
|
66522
|
-
LOCAL_RULES_DIR =
|
|
66523
|
-
GLOBAL_RULES_DIR =
|
|
67250
|
+
LOCAL_RULES_DIR = join12(".spur", "rules");
|
|
67251
|
+
GLOBAL_RULES_DIR = join12(".config", "spur", "rules");
|
|
66524
67252
|
SEVERITY_RANK2 = {
|
|
66525
67253
|
info: 0,
|
|
66526
67254
|
warning: 1,
|
|
@@ -66879,10 +67607,10 @@ class SupervisorService {
|
|
|
66879
67607
|
proc.handle.kill("SIGTERM");
|
|
66880
67608
|
let timedOut = false;
|
|
66881
67609
|
const exitPromise = proc.handle.exited;
|
|
66882
|
-
const timeout = new Promise((
|
|
67610
|
+
const timeout = new Promise((resolve5) => {
|
|
66883
67611
|
setTimeout(() => {
|
|
66884
67612
|
timedOut = true;
|
|
66885
|
-
|
|
67613
|
+
resolve5();
|
|
66886
67614
|
}, 3000);
|
|
66887
67615
|
});
|
|
66888
67616
|
await Promise.race([exitPromise, timeout]);
|
|
@@ -67154,7 +67882,7 @@ var init_system_event_emitter = __esm(() => {
|
|
|
67154
67882
|
});
|
|
67155
67883
|
|
|
67156
67884
|
// ../../packages/app/src/services/task-check.ts
|
|
67157
|
-
import { dirname as
|
|
67885
|
+
import { dirname as dirname11, join as join13 } from "path";
|
|
67158
67886
|
function isPlaceholderBody(body) {
|
|
67159
67887
|
const stripped = body.replace(/<!--[\s\S]*?-->/g, "").replace(/^\s*>\s*TBD\s*$/gim, "").trim();
|
|
67160
67888
|
return stripped.length === 0;
|
|
@@ -67215,9 +67943,9 @@ function isProseOnlyReview(body) {
|
|
|
67215
67943
|
function resolveProjectRootFromTasksDir(tasksDir) {
|
|
67216
67944
|
const norm = tasksDir.replace(/\\/g, "/");
|
|
67217
67945
|
if (/\/docs\/tasks\d*$/.test(norm) || /\/docs\/tasks$/.test(norm)) {
|
|
67218
|
-
return
|
|
67946
|
+
return dirname11(dirname11(tasksDir));
|
|
67219
67947
|
}
|
|
67220
|
-
return
|
|
67948
|
+
return dirname11(tasksDir);
|
|
67221
67949
|
}
|
|
67222
67950
|
function extractBacktickLineAnchors(body) {
|
|
67223
67951
|
const out = [];
|
|
@@ -67302,9 +68030,9 @@ var init_task_check = __esm(() => {
|
|
|
67302
68030
|
const entry = this.resolveMatrixEntry(variant, status);
|
|
67303
68031
|
this.runL2(doc2, entry, findings);
|
|
67304
68032
|
this.runL3(doc2, entry, status, findings);
|
|
67305
|
-
const tasksDir =
|
|
67306
|
-
const featuresDir =
|
|
67307
|
-
await this.runL4(doc2, fm, status, findings, featuresDir, tasksDir);
|
|
68033
|
+
const tasksDir = dirname11(filePath);
|
|
68034
|
+
const featuresDir = join13(dirname11(tasksDir), "features");
|
|
68035
|
+
await this.runL4(doc2, fm, status, findings, featuresDir, tasksDir, wbs);
|
|
67308
68036
|
await this.runL4Rollup(doc2, wbs, status, findings, tasksDir);
|
|
67309
68037
|
if (status !== "done" && status !== "cancelled") {
|
|
67310
68038
|
await this.runL4Readiness(doc2, fm, wbs, status, findings, tasksDir);
|
|
@@ -67491,7 +68219,10 @@ var init_task_check = __esm(() => {
|
|
|
67491
68219
|
}
|
|
67492
68220
|
}
|
|
67493
68221
|
}
|
|
67494
|
-
async runL4(doc2, fm, status, findings, featuresDir, tasksDir) {
|
|
68222
|
+
async runL4(doc2, fm, status, findings, featuresDir, tasksDir, wbs) {
|
|
68223
|
+
if (status === "testing" || status === "done") {
|
|
68224
|
+
await this.checkVerdictArtifact(wbs, tasksDir, findings);
|
|
68225
|
+
}
|
|
67495
68226
|
const template = typeof fm.template === "string" ? fm.template : DEFAULT_TASK_VARIANT;
|
|
67496
68227
|
if (template === DEFAULT_TASK_VARIANT) {
|
|
67497
68228
|
const designBody = doc2.getSection("Design");
|
|
@@ -67642,9 +68373,11 @@ var init_task_check = __esm(() => {
|
|
|
67642
68373
|
});
|
|
67643
68374
|
}
|
|
67644
68375
|
}
|
|
68376
|
+
const declaredSet = new Set(declaredDeps);
|
|
67645
68377
|
const directDeps = [...new Set([...declaredDeps, ...proseDeps.map((d) => d.wbs)])].filter((dep) => dep !== wbs);
|
|
67646
68378
|
for (const depWbs of directDeps) {
|
|
67647
|
-
|
|
68379
|
+
const proseSeeded = !declaredSet.has(depWbs);
|
|
68380
|
+
await this.checkDependencyReadiness(depWbs, wbs, findings, tasksDir, new Set([wbs]), false, proseSeeded);
|
|
67648
68381
|
}
|
|
67649
68382
|
this.checkGateLanguage(doc2, findings);
|
|
67650
68383
|
}
|
|
@@ -67663,33 +68396,51 @@ var init_task_check = __esm(() => {
|
|
|
67663
68396
|
}
|
|
67664
68397
|
extractProsePrerequisites(doc2) {
|
|
67665
68398
|
const refs = [];
|
|
68399
|
+
const headRe = /(?:depends on|depends upon|gated on|blocked by|waiting for)\b[^.;\n]{0,40}?\b(\d{4})\b/gi;
|
|
68400
|
+
const listRe = /\s*(?:,|and)\s*(?:tasks?\s+)?(\d{4})\b/gi;
|
|
67666
68401
|
for (const section of ["Background", "Requirements", "Design", "Acceptance Criteria", "Plan"]) {
|
|
67667
68402
|
const body = doc2.getSection(section);
|
|
67668
68403
|
if (body === null)
|
|
67669
68404
|
continue;
|
|
68405
|
+
let inFence = false;
|
|
67670
68406
|
for (const line of body.split(`
|
|
67671
68407
|
`)) {
|
|
67672
|
-
|
|
67673
|
-
|
|
68408
|
+
if (/^\s*```/.test(line)) {
|
|
68409
|
+
inFence = !inFence;
|
|
68410
|
+
continue;
|
|
68411
|
+
}
|
|
68412
|
+
if (inFence)
|
|
68413
|
+
continue;
|
|
68414
|
+
if (/^\s*\|/.test(line))
|
|
67674
68415
|
continue;
|
|
67675
|
-
|
|
67676
|
-
|
|
68416
|
+
const cleaned = line.replace(/`[^`]*`/g, " ");
|
|
68417
|
+
headRe.lastIndex = 0;
|
|
68418
|
+
for (let head = headRe.exec(cleaned);head !== null; head = headRe.exec(cleaned)) {
|
|
68419
|
+
const wbs = head[1];
|
|
67677
68420
|
if (wbs !== undefined)
|
|
67678
68421
|
refs.push({ wbs, section });
|
|
68422
|
+
listRe.lastIndex = headRe.lastIndex;
|
|
68423
|
+
for (let cont = listRe.exec(cleaned);cont !== null; cont = listRe.exec(cleaned)) {
|
|
68424
|
+
const cw = cont[1];
|
|
68425
|
+
if (cw !== undefined)
|
|
68426
|
+
refs.push({ wbs: cw, section });
|
|
68427
|
+
}
|
|
67679
68428
|
}
|
|
67680
68429
|
}
|
|
67681
68430
|
}
|
|
67682
68431
|
return refs;
|
|
67683
68432
|
}
|
|
67684
|
-
async checkDependencyReadiness(depWbs, rootWbs, findings, tasksDir, seen, transitive) {
|
|
68433
|
+
async checkDependencyReadiness(depWbs, rootWbs, findings, tasksDir, seen, transitive, proseSeeded = false) {
|
|
67685
68434
|
if (seen.has(depWbs)) {
|
|
67686
|
-
|
|
67687
|
-
|
|
67688
|
-
|
|
67689
|
-
|
|
67690
|
-
|
|
67691
|
-
|
|
67692
|
-
|
|
68435
|
+
if (!proseSeeded) {
|
|
68436
|
+
findings.push({
|
|
68437
|
+
layer: "L4",
|
|
68438
|
+
code: FINDING_CODES.L4_PREREQUISITE_CYCLE,
|
|
68439
|
+
severity: "warning",
|
|
68440
|
+
section: "",
|
|
68441
|
+
message: `Prerequisite cycle detected while checking ${rootWbs}: ${[...seen, depWbs].join(" -> ")}`
|
|
68442
|
+
});
|
|
68443
|
+
}
|
|
67693
68444
|
return;
|
|
67694
68445
|
}
|
|
67695
68446
|
const dep = await this.readTaskSnapshot(tasksDir, depWbs);
|
|
@@ -67707,7 +68458,7 @@ var init_task_check = __esm(() => {
|
|
|
67707
68458
|
const nextSeen = new Set(seen);
|
|
67708
68459
|
nextSeen.add(depWbs);
|
|
67709
68460
|
for (const childDep of dep.dependencies) {
|
|
67710
|
-
await this.checkDependencyReadiness(childDep, rootWbs, findings, tasksDir, nextSeen, true);
|
|
68461
|
+
await this.checkDependencyReadiness(childDep, rootWbs, findings, tasksDir, nextSeen, true, proseSeeded);
|
|
67711
68462
|
}
|
|
67712
68463
|
}
|
|
67713
68464
|
checkGateLanguage(doc2, findings) {
|
|
@@ -67753,7 +68504,7 @@ var init_task_check = __esm(() => {
|
|
|
67753
68504
|
for (const cite of citations) {
|
|
67754
68505
|
if (reported >= 5)
|
|
67755
68506
|
break;
|
|
67756
|
-
const abs =
|
|
68507
|
+
const abs = join13(projectRoot, cite.path);
|
|
67757
68508
|
let exists2 = false;
|
|
67758
68509
|
try {
|
|
67759
68510
|
exists2 = await this.fs.exists(abs);
|
|
@@ -67867,6 +68618,38 @@ var init_task_check = __esm(() => {
|
|
|
67867
68618
|
async findTaskFile(tasksDir, wbs) {
|
|
67868
68619
|
return await this.locatorFor(tasksDir).findPathByWbs(wbs);
|
|
67869
68620
|
}
|
|
68621
|
+
async checkVerdictArtifact(wbs, tasksDir, findings) {
|
|
68622
|
+
const projectRoot = resolveProjectRootFromTasksDir(tasksDir);
|
|
68623
|
+
const runDir = join13(projectRoot, ".spur", "run");
|
|
68624
|
+
const loaded = await readVerdictArtifact(this.fs, runDir, wbs);
|
|
68625
|
+
if (loaded.artifact === undefined) {
|
|
68626
|
+
if (loaded.readError && loaded.readError !== "artifact is missing") {
|
|
68627
|
+
findings.push({
|
|
68628
|
+
layer: "L4",
|
|
68629
|
+
code: FINDING_CODES.L4_MALFORMED_VERDICT_ARTIFACT,
|
|
68630
|
+
severity: "error",
|
|
68631
|
+
section: "Testing",
|
|
68632
|
+
message: `Verdict artifact at ${loaded.path} is malformed: ${loaded.readError}`
|
|
68633
|
+
});
|
|
68634
|
+
}
|
|
68635
|
+
return;
|
|
68636
|
+
}
|
|
68637
|
+
const artifact = loaded.artifact;
|
|
68638
|
+
const reqs = artifact.requirements ?? [];
|
|
68639
|
+
const acs = artifact.acceptanceCriteria ?? [];
|
|
68640
|
+
const isUnknown = artifact.verdict === "UNKNOWN";
|
|
68641
|
+
const isEmpty = reqs.length === 0 && acs.length === 0;
|
|
68642
|
+
if (isUnknown || isEmpty) {
|
|
68643
|
+
const reason = isUnknown ? "verdict is UNKNOWN" : "requirements and AC are empty";
|
|
68644
|
+
findings.push({
|
|
68645
|
+
layer: "L4",
|
|
68646
|
+
code: FINDING_CODES.L4_MALFORMED_VERDICT_ARTIFACT,
|
|
68647
|
+
severity: "error",
|
|
68648
|
+
section: "Testing",
|
|
68649
|
+
message: `Verdict artifact at ${loaded.path} is malformed: ${reason}`
|
|
68650
|
+
});
|
|
68651
|
+
}
|
|
68652
|
+
}
|
|
67870
68653
|
};
|
|
67871
68654
|
});
|
|
67872
68655
|
|
|
@@ -68070,7 +68853,7 @@ var init_task_record = __esm(() => {
|
|
|
68070
68853
|
});
|
|
68071
68854
|
|
|
68072
68855
|
// ../../packages/app/src/services/task-scaffold.ts
|
|
68073
|
-
import { dirname as
|
|
68856
|
+
import { dirname as dirname12 } from "path";
|
|
68074
68857
|
|
|
68075
68858
|
class TaskScaffoldService {
|
|
68076
68859
|
ctx;
|
|
@@ -68113,7 +68896,7 @@ class TaskScaffoldService {
|
|
|
68113
68896
|
fileExists = false;
|
|
68114
68897
|
}
|
|
68115
68898
|
const mergeResult = mergeStubs(existingContent, stubs);
|
|
68116
|
-
const dir =
|
|
68899
|
+
const dir = dirname12(targetFile);
|
|
68117
68900
|
await this.ctx.fs.ensureDir(dir);
|
|
68118
68901
|
if (mergeResult.created > 0 || !fileExists) {
|
|
68119
68902
|
await this.ctx.fs.writeFile(targetFile, mergeResult.content);
|
|
@@ -68145,7 +68928,7 @@ var init_task_scaffold = __esm(() => {
|
|
|
68145
68928
|
});
|
|
68146
68929
|
|
|
68147
68930
|
// ../../packages/app/src/services/task-service.ts
|
|
68148
|
-
import { isAbsolute, relative as relative3 } from "path";
|
|
68931
|
+
import { dirname as dirname13, isAbsolute as isAbsolute2, join as join14, relative as relative3 } from "path";
|
|
68149
68932
|
function patchFrontmatterField(rendered, key, value) {
|
|
68150
68933
|
const openIdx = rendered.indexOf("---");
|
|
68151
68934
|
if (openIdx === -1)
|
|
@@ -68615,7 +69398,56 @@ class TaskService {
|
|
|
68615
69398
|
const raw = await this.ctx.fs.readFile(sourceFile);
|
|
68616
69399
|
const body = stripLeadingSectionHeader2(raw, sectionName);
|
|
68617
69400
|
const ref = { kind: "task", id: wbs, filePath, folder: this.ctx.tasksDir };
|
|
68618
|
-
|
|
69401
|
+
const result = await this.writeService.updateSection(ref, sectionName, body);
|
|
69402
|
+
if (sectionName === "Acceptance Criteria") {
|
|
69403
|
+
const warnings = await this.checkAcSubsetWarning(filePath, body);
|
|
69404
|
+
if (warnings.length > 0) {
|
|
69405
|
+
return {
|
|
69406
|
+
...result,
|
|
69407
|
+
warnings: [...result.warnings ?? [], ...warnings]
|
|
69408
|
+
};
|
|
69409
|
+
}
|
|
69410
|
+
}
|
|
69411
|
+
return result;
|
|
69412
|
+
}
|
|
69413
|
+
async checkAcSubsetWarning(taskFilePath, acBody) {
|
|
69414
|
+
try {
|
|
69415
|
+
const raw = await this.ctx.fs.readFile(taskFilePath);
|
|
69416
|
+
const doc2 = MarkdownDocument.parse(raw, "task");
|
|
69417
|
+
const fm = doc2.frontmatterData ?? {};
|
|
69418
|
+
const featureId2 = fm.feature_id ?? fm["feature-id"];
|
|
69419
|
+
if (!featureId2 || featureId2.length === 0)
|
|
69420
|
+
return [];
|
|
69421
|
+
const tasksDir = dirname13(taskFilePath);
|
|
69422
|
+
const featuresDir = join14(tasksDir, "..", "features");
|
|
69423
|
+
const featurePath = await (async () => {
|
|
69424
|
+
try {
|
|
69425
|
+
for (const name of await this.ctx.fs.readDir(featuresDir)) {
|
|
69426
|
+
if (name.startsWith(`${featureId2}_`) && name.endsWith(".md")) {
|
|
69427
|
+
return `${featuresDir}/${name}`;
|
|
69428
|
+
}
|
|
69429
|
+
}
|
|
69430
|
+
} catch {}
|
|
69431
|
+
return null;
|
|
69432
|
+
})();
|
|
69433
|
+
if (featurePath === null)
|
|
69434
|
+
return [];
|
|
69435
|
+
const featureRaw = await this.ctx.fs.readFile(featurePath);
|
|
69436
|
+
const featureDoc = MarkdownDocument.parse(featureRaw, "feature");
|
|
69437
|
+
const featureAc = stripAcFence(featureDoc.getSection("Acceptance Criteria") ?? "");
|
|
69438
|
+
if (!featureAc.trim())
|
|
69439
|
+
return [];
|
|
69440
|
+
const taskAc = stripAcFence(acBody);
|
|
69441
|
+
const taskChecklist = parseChecklist(taskAc);
|
|
69442
|
+
const coverage = checkAcCoverage(featureAc, taskAc, taskChecklist);
|
|
69443
|
+
const warnings = [];
|
|
69444
|
+
for (const scenario of coverage.uncovered) {
|
|
69445
|
+
warnings.push(`Task scenario "${scenario}" is not in feature "${featureId2}"'s AC (DD-09 subset rule)`);
|
|
69446
|
+
}
|
|
69447
|
+
return warnings;
|
|
69448
|
+
} catch {
|
|
69449
|
+
return [];
|
|
69450
|
+
}
|
|
68619
69451
|
}
|
|
68620
69452
|
async record(wbs, opts = {}) {
|
|
68621
69453
|
const filePath = await this.resolveTaskFile(wbs);
|
|
@@ -69014,7 +69846,7 @@ ${block}` : block);
|
|
|
69014
69846
|
const root = this.ctx.fs.resolve(".");
|
|
69015
69847
|
const candidate = this.ctx.fs.resolve(folder);
|
|
69016
69848
|
const rel = relative3(root, candidate);
|
|
69017
|
-
if (rel.startsWith("..") ||
|
|
69849
|
+
if (rel.startsWith("..") || isAbsolute2(rel)) {
|
|
69018
69850
|
throw new Error(`Invalid folder: ${folder} escapes the planning workspace`);
|
|
69019
69851
|
}
|
|
69020
69852
|
return candidate;
|
|
@@ -69346,7 +70178,7 @@ var init_task_verdict = __esm(() => {
|
|
|
69346
70178
|
});
|
|
69347
70179
|
|
|
69348
70180
|
// ../../packages/app/src/services/team-service.ts
|
|
69349
|
-
import { join as
|
|
70181
|
+
import { join as join15 } from "path";
|
|
69350
70182
|
|
|
69351
70183
|
class TeamService {
|
|
69352
70184
|
ctx;
|
|
@@ -69354,7 +70186,7 @@ class TeamService {
|
|
|
69354
70186
|
orchestratorPromise;
|
|
69355
70187
|
constructor(ctx) {
|
|
69356
70188
|
this.ctx = ctx;
|
|
69357
|
-
this.configDir =
|
|
70189
|
+
this.configDir = join15(ctx.cwd, ".spur", "agents");
|
|
69358
70190
|
}
|
|
69359
70191
|
async sendMessage(fromId, toId, body, replyTo) {
|
|
69360
70192
|
validateAgentId(toId);
|
|
@@ -69764,7 +70596,7 @@ class TeamService {
|
|
|
69764
70596
|
async resolveTaskFile(taskId) {
|
|
69765
70597
|
const fs3 = this.ctx.fs;
|
|
69766
70598
|
const { foldersConfig } = await resolvePlanningFolders(fs3);
|
|
69767
|
-
const dirs = [...new Set([foldersConfig.active_folder, ...Object.keys(foldersConfig.folders)])].map((dir) =>
|
|
70599
|
+
const dirs = [...new Set([foldersConfig.active_folder, ...Object.keys(foldersConfig.folders)])].map((dir) => join15(this.ctx.cwd, dir));
|
|
69768
70600
|
return await TaskLocator.forDirs(fs3, dirs).findPathByWbs(taskId);
|
|
69769
70601
|
}
|
|
69770
70602
|
}
|
|
@@ -69800,8 +70632,8 @@ var init_team_service = __esm(() => {
|
|
|
69800
70632
|
});
|
|
69801
70633
|
|
|
69802
70634
|
// ../../packages/app/src/services/token-ledger-service.ts
|
|
69803
|
-
import { closeSync as closeSync3, existsSync as
|
|
69804
|
-
import { join as
|
|
70635
|
+
import { closeSync as closeSync3, existsSync as existsSync8, fstatSync, openSync as openSync3, readSync } from "fs";
|
|
70636
|
+
import { join as join16 } from "path";
|
|
69805
70637
|
function isSparseToolActivity(events2) {
|
|
69806
70638
|
return events2.length === 0 || !events2.some((e) => TOOL_ACTIVITY_TYPES.has(e.type));
|
|
69807
70639
|
}
|
|
@@ -69852,7 +70684,7 @@ function parseLedgerLine(line) {
|
|
|
69852
70684
|
}
|
|
69853
70685
|
}
|
|
69854
70686
|
function tailTokenLedgerFile(filePath, limit, chunkSize = DEFAULT_CHUNK, before) {
|
|
69855
|
-
if (!
|
|
70687
|
+
if (!existsSync8(filePath)) {
|
|
69856
70688
|
return { events: [], truncated: false };
|
|
69857
70689
|
}
|
|
69858
70690
|
const target = limit + 1;
|
|
@@ -69902,7 +70734,7 @@ class TokenLedgerService {
|
|
|
69902
70734
|
ledgerPath;
|
|
69903
70735
|
chunkSize;
|
|
69904
70736
|
constructor(options) {
|
|
69905
|
-
this.ledgerPath = options.ledgerPath ??
|
|
70737
|
+
this.ledgerPath = options.ledgerPath ?? join16(options.cwd, TOKEN_LEDGER_RELATIVE_PATH);
|
|
69906
70738
|
this.chunkSize = options.chunkSize ?? DEFAULT_CHUNK;
|
|
69907
70739
|
}
|
|
69908
70740
|
get path() {
|
|
@@ -69943,12 +70775,12 @@ class TokenLedgerService {
|
|
|
69943
70775
|
var TOOL_ACTIVITY_TYPES, TOKEN_LEDGER_DEFAULT_LIMIT = 200, TOKEN_LEDGER_MAX_LIMIT = 1000, TOKEN_LEDGER_RELATIVE_PATH, DEFAULT_CHUNK;
|
|
69944
70776
|
var init_token_ledger_service = __esm(() => {
|
|
69945
70777
|
TOOL_ACTIVITY_TYPES = new Set(["read", "write", "bash", "grep", "glob"]);
|
|
69946
|
-
TOKEN_LEDGER_RELATIVE_PATH =
|
|
70778
|
+
TOKEN_LEDGER_RELATIVE_PATH = join16(".spur", "context", "token-ledger.jsonl");
|
|
69947
70779
|
DEFAULT_CHUNK = 64 * 1024;
|
|
69948
70780
|
});
|
|
69949
70781
|
|
|
69950
70782
|
// ../../packages/app/src/services/token-ledger-watcher.ts
|
|
69951
|
-
import { closeSync as closeSync4, existsSync as
|
|
70783
|
+
import { closeSync as closeSync4, existsSync as existsSync9, fstatSync as fstatSync2, openSync as openSync4, readSync as readSync2, watch } from "fs";
|
|
69952
70784
|
|
|
69953
70785
|
class TokenLedgerWatcher {
|
|
69954
70786
|
ledgerPath;
|
|
@@ -69969,7 +70801,7 @@ class TokenLedgerWatcher {
|
|
|
69969
70801
|
this.started = true;
|
|
69970
70802
|
this.offset = this.currentSize();
|
|
69971
70803
|
try {
|
|
69972
|
-
const target =
|
|
70804
|
+
const target = existsSync9(this.ledgerPath) ? this.ledgerPath : this.parentDir();
|
|
69973
70805
|
this.watcher = watch(target, () => this.schedulePoll());
|
|
69974
70806
|
} catch {
|
|
69975
70807
|
this.watcher = undefined;
|
|
@@ -70004,7 +70836,7 @@ class TokenLedgerWatcher {
|
|
|
70004
70836
|
return idx > 0 ? this.ledgerPath.slice(0, idx) : ".";
|
|
70005
70837
|
}
|
|
70006
70838
|
currentSize() {
|
|
70007
|
-
if (!
|
|
70839
|
+
if (!existsSync9(this.ledgerPath))
|
|
70008
70840
|
return 0;
|
|
70009
70841
|
try {
|
|
70010
70842
|
const fd = openSync4(this.ledgerPath, "r");
|
|
@@ -70026,7 +70858,7 @@ class TokenLedgerWatcher {
|
|
|
70026
70858
|
}, this.debounceMs);
|
|
70027
70859
|
}
|
|
70028
70860
|
pollNewBytes() {
|
|
70029
|
-
if (!
|
|
70861
|
+
if (!existsSync9(this.ledgerPath)) {
|
|
70030
70862
|
this.offset = 0;
|
|
70031
70863
|
this.carry = "";
|
|
70032
70864
|
return;
|
|
@@ -70117,16 +70949,16 @@ class WorkflowSteeringController {
|
|
|
70117
70949
|
active.state = "boundary";
|
|
70118
70950
|
active.version += 1;
|
|
70119
70951
|
this.publishState(active);
|
|
70120
|
-
return await new Promise((
|
|
70952
|
+
return await new Promise((resolve5) => {
|
|
70121
70953
|
const settle = (decision) => {
|
|
70122
70954
|
clearTimeout(timer);
|
|
70123
|
-
|
|
70955
|
+
resolve5(decision);
|
|
70124
70956
|
};
|
|
70125
70957
|
const timer = setTimeout(() => {
|
|
70126
70958
|
if (active.resolve !== settle)
|
|
70127
70959
|
return;
|
|
70128
70960
|
active.resolve = undefined;
|
|
70129
|
-
this.acceptDefault(active,
|
|
70961
|
+
this.acceptDefault(active, resolve5);
|
|
70130
70962
|
}, active.policy.timeoutMs);
|
|
70131
70963
|
timer.unref?.();
|
|
70132
70964
|
active.resolve = settle;
|
|
@@ -70224,7 +71056,7 @@ class WorkflowSteeringController {
|
|
|
70224
71056
|
deadlineAt: new Date(Date.now() + deadlineMs).toISOString()
|
|
70225
71057
|
});
|
|
70226
71058
|
}
|
|
70227
|
-
acceptDefault(active,
|
|
71059
|
+
acceptDefault(active, resolve5) {
|
|
70228
71060
|
const command = {
|
|
70229
71061
|
commandId: crypto.randomUUID(),
|
|
70230
71062
|
runId: active.runId,
|
|
@@ -70249,7 +71081,7 @@ class WorkflowSteeringController {
|
|
|
70249
71081
|
at: new Date().toISOString()
|
|
70250
71082
|
};
|
|
70251
71083
|
this.onAck?.(ack);
|
|
70252
|
-
|
|
71084
|
+
resolve5({ operation: "continue" });
|
|
70253
71085
|
}
|
|
70254
71086
|
accept(command, active, note) {
|
|
70255
71087
|
return this.publish({
|
|
@@ -70312,7 +71144,7 @@ var init_steering = __esm(() => {
|
|
|
70312
71144
|
});
|
|
70313
71145
|
|
|
70314
71146
|
// ../../packages/app/src/workflow/actions/agent-run.ts
|
|
70315
|
-
import { dirname as
|
|
71147
|
+
import { dirname as dirname14, isAbsolute as isAbsolute3, join as join17 } from "path";
|
|
70316
71148
|
|
|
70317
71149
|
class AgentRunActionRunner {
|
|
70318
71150
|
observabilityBus;
|
|
@@ -70342,11 +71174,11 @@ class AgentRunActionRunner {
|
|
|
70342
71174
|
let sessionDir = asOptionalString(context4.vars.__agentSessionDir);
|
|
70343
71175
|
if (affinityOn) {
|
|
70344
71176
|
if (!sessionDir || prevAgent && prevAgent !== targetAgentDir) {
|
|
70345
|
-
sessionDir =
|
|
71177
|
+
sessionDir = join17(cwd, ".spur", "run", context4.runId, "agent-sessions", targetAgentDir);
|
|
70346
71178
|
}
|
|
70347
71179
|
} else {
|
|
70348
71180
|
if (!sessionDir) {
|
|
70349
|
-
sessionDir =
|
|
71181
|
+
sessionDir = join17(cwd, ".spur", "run", context4.runId, "agent-sessions", targetAgentDir);
|
|
70350
71182
|
}
|
|
70351
71183
|
}
|
|
70352
71184
|
const storedSessionId = asOptionalString(context4.vars.__agentSessionId);
|
|
@@ -70447,13 +71279,13 @@ class AgentRunActionRunner {
|
|
|
70447
71279
|
const ok = exitCode === 0;
|
|
70448
71280
|
const invocation = traced.invocation;
|
|
70449
71281
|
if (capture && answerFile !== undefined) {
|
|
70450
|
-
const target =
|
|
71282
|
+
const target = isAbsolute3(answerFile) ? answerFile : join17(cwd, answerFile);
|
|
70451
71283
|
const fs3 = createNodeFileSystem3(cwd);
|
|
70452
|
-
await fs3.ensureDir(
|
|
71284
|
+
await fs3.ensureDir(dirname14(target));
|
|
70453
71285
|
await fs3.writeFile(target, answer);
|
|
70454
71286
|
}
|
|
70455
71287
|
if (ok && expectFile !== undefined) {
|
|
70456
|
-
const target =
|
|
71288
|
+
const target = isAbsolute3(expectFile) ? expectFile : join17(cwd, expectFile);
|
|
70457
71289
|
const fs3 = createNodeFileSystem3(cwd);
|
|
70458
71290
|
if (!await fs3.exists(target)) {
|
|
70459
71291
|
return {
|
|
@@ -70479,7 +71311,7 @@ class AgentRunActionRunner {
|
|
|
70479
71311
|
const resolvedAgent = invocation?.agent ?? targetAgentDir;
|
|
70480
71312
|
let resolvedSessionDir = sessionDir;
|
|
70481
71313
|
if (ok && affinityOn && resolvedAgent !== targetAgentDir && !context4.vars.__agentSessionDir) {
|
|
70482
|
-
resolvedSessionDir =
|
|
71314
|
+
resolvedSessionDir = join17(cwd, ".spur", "run", context4.runId, "agent-sessions", resolvedAgent);
|
|
70483
71315
|
}
|
|
70484
71316
|
let discoveredSessionId = storedSessionId;
|
|
70485
71317
|
if (ok && affinityOn && resolvedSessionDir && !discoveredSessionId) {
|
|
@@ -70487,9 +71319,9 @@ class AgentRunActionRunner {
|
|
|
70487
71319
|
}
|
|
70488
71320
|
if (ok && affinityOn && resolvedSessionDir) {
|
|
70489
71321
|
try {
|
|
70490
|
-
const sidecarPath =
|
|
71322
|
+
const sidecarPath = join17(cwd, ".spur", "run", `${context4.runId}-agent-session.json`);
|
|
70491
71323
|
const fs3 = createNodeFileSystem3(cwd);
|
|
70492
|
-
await fs3.ensureDir(
|
|
71324
|
+
await fs3.ensureDir(dirname14(sidecarPath));
|
|
70493
71325
|
await fs3.writeFile(sidecarPath, JSON.stringify({
|
|
70494
71326
|
agent: resolvedAgent,
|
|
70495
71327
|
sessionId: discoveredSessionId ?? null,
|
|
@@ -70527,7 +71359,7 @@ async function discoverSessionId(sessionDir) {
|
|
|
70527
71359
|
let newestFile;
|
|
70528
71360
|
let newestMtime = 0;
|
|
70529
71361
|
for (const entry of jsonEntries) {
|
|
70530
|
-
const fullPath =
|
|
71362
|
+
const fullPath = join17(sessionDir, entry);
|
|
70531
71363
|
const st = await fs3.stat(fullPath);
|
|
70532
71364
|
if (st?.isFile() && st.mtimeMs > newestMtime) {
|
|
70533
71365
|
newestMtime = st.mtimeMs;
|
|
@@ -70622,9 +71454,9 @@ async function writePartialWorkArtifact(context4, agentLabel, model, traced, cwd
|
|
|
70622
71454
|
try {
|
|
70623
71455
|
const fs4 = createNodeFileSystem3(cwd);
|
|
70624
71456
|
const locator = TaskLocator.forDirs(fs4, [
|
|
70625
|
-
|
|
70626
|
-
|
|
70627
|
-
|
|
71457
|
+
join17(cwd, "docs", "tasks3"),
|
|
71458
|
+
join17(cwd, "docs", "tasks2"),
|
|
71459
|
+
join17(cwd, "docs", "tasks")
|
|
70628
71460
|
]);
|
|
70629
71461
|
const hit = await locator.findByWbs(wbs);
|
|
70630
71462
|
if (hit) {
|
|
@@ -70679,9 +71511,9 @@ async function writePartialWorkArtifact(context4, agentLabel, model, traced, cwd
|
|
|
70679
71511
|
completedSection
|
|
70680
71512
|
].join(`
|
|
70681
71513
|
`);
|
|
70682
|
-
const target =
|
|
71514
|
+
const target = join17(cwd, ".spur", "run", `${context4.runId}-${context4.stateOrNodeId}-partial.md`);
|
|
70683
71515
|
const fs3 = createNodeFileSystem3(cwd);
|
|
70684
|
-
await fs3.ensureDir(
|
|
71516
|
+
await fs3.ensureDir(dirname14(target));
|
|
70685
71517
|
await fs3.writeFile(target, body);
|
|
70686
71518
|
} catch {}
|
|
70687
71519
|
}
|
|
@@ -71451,7 +72283,7 @@ var init_builtins2 = __esm(() => {
|
|
|
71451
72283
|
|
|
71452
72284
|
// ../../packages/app/src/services/workflow-service.ts
|
|
71453
72285
|
import { homedir as homedir5 } from "os";
|
|
71454
|
-
import { join as
|
|
72286
|
+
import { join as join18, resolve as resolve5 } from "path";
|
|
71455
72287
|
function signalSubprocess(pid) {
|
|
71456
72288
|
if (!Number.isInteger(pid) || pid <= 1)
|
|
71457
72289
|
return false;
|
|
@@ -71521,7 +72353,7 @@ class WorkflowAppService {
|
|
|
71521
72353
|
};
|
|
71522
72354
|
}
|
|
71523
72355
|
async validate(file2, opts = {}) {
|
|
71524
|
-
const absolute =
|
|
72356
|
+
const absolute = resolve5(this.ctx.cwd, file2);
|
|
71525
72357
|
if (!await fileExists(absolute)) {
|
|
71526
72358
|
return { ok: false, valid: false, file: file2, errors: [`File not found: ${absolute}`] };
|
|
71527
72359
|
}
|
|
@@ -71579,7 +72411,7 @@ class WorkflowAppService {
|
|
|
71579
72411
|
...opts.vars ?? {},
|
|
71580
72412
|
__runId: runId
|
|
71581
72413
|
};
|
|
71582
|
-
const absolute =
|
|
72414
|
+
const absolute = resolve5(this.ctx.cwd, file2);
|
|
71583
72415
|
const embedded = this.embeddedSchemaOptions();
|
|
71584
72416
|
const workflow = await loadWorkflowDef(absolute, {
|
|
71585
72417
|
validateSchema: true,
|
|
@@ -71606,7 +72438,7 @@ class WorkflowAppService {
|
|
|
71606
72438
|
return;
|
|
71607
72439
|
let workflowName;
|
|
71608
72440
|
try {
|
|
71609
|
-
const def = await loadWorkflowDef(
|
|
72441
|
+
const def = await loadWorkflowDef(resolve5(this.ctx.cwd, file2), { validateSchema: false });
|
|
71610
72442
|
workflowName = def.name;
|
|
71611
72443
|
} catch {
|
|
71612
72444
|
return;
|
|
@@ -71651,7 +72483,7 @@ class WorkflowAppService {
|
|
|
71651
72483
|
};
|
|
71652
72484
|
}
|
|
71653
72485
|
async cleanRunLogs(retentionDays = 30, dryRun = false) {
|
|
71654
|
-
const runDir =
|
|
72486
|
+
const runDir = join18(this.ctx.cwd, ".spur", "run");
|
|
71655
72487
|
const fs3 = createNodeFileSystem3();
|
|
71656
72488
|
const cutoffMs = Date.now() - retentionDays * 24 * 60 * 60 * 1000;
|
|
71657
72489
|
const reclaimed = [];
|
|
@@ -71663,7 +72495,7 @@ class WorkflowAppService {
|
|
|
71663
72495
|
return { retentionDays, dryRun, reclaimed, failures };
|
|
71664
72496
|
}
|
|
71665
72497
|
for (const name of entries) {
|
|
71666
|
-
const path9 =
|
|
72498
|
+
const path9 = join18(runDir, name);
|
|
71667
72499
|
const stat = await fs3.stat(path9);
|
|
71668
72500
|
if (stat === null || !stat.isFile() || stat.mtimeMs >= cutoffMs)
|
|
71669
72501
|
continue;
|
|
@@ -71731,7 +72563,7 @@ class WorkflowAppService {
|
|
|
71731
72563
|
if (entry === undefined)
|
|
71732
72564
|
return null;
|
|
71733
72565
|
for (const layer of listing.layers) {
|
|
71734
|
-
const abs =
|
|
72566
|
+
const abs = resolve5(layer.path, entry.path);
|
|
71735
72567
|
if (await fileExists(abs)) {
|
|
71736
72568
|
try {
|
|
71737
72569
|
return await loadWorkflowDef(abs, { validateSchema: false });
|
|
@@ -71742,12 +72574,12 @@ class WorkflowAppService {
|
|
|
71742
72574
|
}
|
|
71743
72575
|
async list(workflowPaths = [".spur/workflows/"]) {
|
|
71744
72576
|
const projectRoot = this.ctx.cwd;
|
|
71745
|
-
const globalRoot =
|
|
72577
|
+
const globalRoot = join18(homedir5(), ".config", "spur");
|
|
71746
72578
|
const layers = [];
|
|
71747
72579
|
const entries = [];
|
|
71748
72580
|
const scannedPaths = new Set;
|
|
71749
72581
|
for (const relPath of workflowPaths) {
|
|
71750
|
-
const absPath =
|
|
72582
|
+
const absPath = resolve5(projectRoot, relPath);
|
|
71751
72583
|
layers.push({ id: "project", path: absPath });
|
|
71752
72584
|
scannedPaths.add(absPath);
|
|
71753
72585
|
try {
|
|
@@ -71756,7 +72588,7 @@ class WorkflowAppService {
|
|
|
71756
72588
|
} catch {}
|
|
71757
72589
|
}
|
|
71758
72590
|
for (const relPath of workflowPaths) {
|
|
71759
|
-
const absPath =
|
|
72591
|
+
const absPath = resolve5(globalRoot, relPath);
|
|
71760
72592
|
if (scannedPaths.has(absPath))
|
|
71761
72593
|
continue;
|
|
71762
72594
|
layers.push({ id: "global", path: absPath });
|
|
@@ -71978,8 +72810,8 @@ async function resolveOutputLogConfig(cwd) {
|
|
|
71978
72810
|
}
|
|
71979
72811
|
}
|
|
71980
72812
|
async function outputArtifactForRun(cwd, runId) {
|
|
71981
|
-
const relative4 =
|
|
71982
|
-
return await fileExists(
|
|
72813
|
+
const relative4 = join18(".spur", "run", `${runId}.log`);
|
|
72814
|
+
return await fileExists(join18(cwd, relative4)) ? relative4 : undefined;
|
|
71983
72815
|
}
|
|
71984
72816
|
async function scanWorkflowFiles(rootPath, source) {
|
|
71985
72817
|
const entries = [];
|
|
@@ -71992,7 +72824,7 @@ async function scanWorkflowFiles(rootPath, source) {
|
|
|
71992
72824
|
async function walk3(dirPath) {
|
|
71993
72825
|
const names = await fs3.readDir(dirPath);
|
|
71994
72826
|
for (const name of names) {
|
|
71995
|
-
const fullPath =
|
|
72827
|
+
const fullPath = resolve5(dirPath, name);
|
|
71996
72828
|
const st = await fs3.stat(fullPath);
|
|
71997
72829
|
if (!st)
|
|
71998
72830
|
continue;
|
|
@@ -72215,7 +73047,7 @@ var init_lifecycle_adapter = __esm(() => {
|
|
|
72215
73047
|
});
|
|
72216
73048
|
|
|
72217
73049
|
// ../../packages/app/src/workflow/trace-writer.ts
|
|
72218
|
-
import { dirname as
|
|
73050
|
+
import { dirname as dirname15, join as join19 } from "path";
|
|
72219
73051
|
|
|
72220
73052
|
class WorkflowTraceWriter {
|
|
72221
73053
|
path;
|
|
@@ -72223,7 +73055,7 @@ class WorkflowTraceWriter {
|
|
|
72223
73055
|
pending = Promise.resolve();
|
|
72224
73056
|
constructor(cwd, runId) {
|
|
72225
73057
|
const safeRunId = runId.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
72226
|
-
this.path =
|
|
73058
|
+
this.path = join19(cwd, ".spur", "runs", "workflow", `${safeRunId}.jsonl`);
|
|
72227
73059
|
}
|
|
72228
73060
|
attach(bus) {
|
|
72229
73061
|
bus.on("workflow.run.started", (event2) => this.enqueue("workflow.run.started", event2));
|
|
@@ -72249,7 +73081,7 @@ class WorkflowTraceWriter {
|
|
|
72249
73081
|
`;
|
|
72250
73082
|
this.pending = this.pending.then(async () => {
|
|
72251
73083
|
const fs3 = createNodeFileSystem3();
|
|
72252
|
-
await fs3.ensureDir(
|
|
73084
|
+
await fs3.ensureDir(dirname15(this.path));
|
|
72253
73085
|
await fs3.appendFile(this.path, line);
|
|
72254
73086
|
});
|
|
72255
73087
|
}
|
|
@@ -72266,12 +73098,14 @@ __export(exports_src2, {
|
|
|
72266
73098
|
summarizeActionResult: () => summarizeActionResult,
|
|
72267
73099
|
startRegisteredProject: () => startRegisteredProject,
|
|
72268
73100
|
setDetachedServeSpawnForTests: () => setDetachedServeSpawnForTests,
|
|
73101
|
+
runHistoryReport: () => runHistoryReport,
|
|
72269
73102
|
resolveWorkflowLogRetentionDays: () => resolveWorkflowLogRetentionDays,
|
|
72270
73103
|
resolveSpurServeCommand: () => resolveSpurServeCommand,
|
|
72271
73104
|
resolveRetentionQuotas: () => resolveRetentionQuotas,
|
|
72272
73105
|
resolvePlanningFolders: () => resolvePlanningFolders,
|
|
72273
73106
|
resolveOutputLogConfig: () => resolveOutputLogConfig,
|
|
72274
73107
|
resolveAutostartSet: () => resolveAutostartSet,
|
|
73108
|
+
resolveArtifactPath: () => resolveArtifactPath,
|
|
72275
73109
|
renderTesting: () => renderTesting,
|
|
72276
73110
|
renderStepLine: () => renderStepLine,
|
|
72277
73111
|
renderSolutionFromDiff: () => renderSolutionFromDiff,
|
|
@@ -72283,6 +73117,7 @@ __export(exports_src2, {
|
|
|
72283
73117
|
redactAndBound: () => redactAndBound,
|
|
72284
73118
|
readVerdictArtifact: () => readVerdictArtifact,
|
|
72285
73119
|
readVerdict: () => readVerdict,
|
|
73120
|
+
pruneReports: () => pruneReports,
|
|
72286
73121
|
parseVerdict: () => parseVerdict,
|
|
72287
73122
|
parseSteeringPolicy: () => parseSteeringPolicy,
|
|
72288
73123
|
parsePsOutput: () => parsePsOutput,
|
|
@@ -72298,6 +73133,7 @@ __export(exports_src2, {
|
|
|
72298
73133
|
hitlAutoApproveEnabled: () => hitlAutoApproveEnabled,
|
|
72299
73134
|
hasPopulatedPriorityTable: () => hasPopulatedPriorityTable,
|
|
72300
73135
|
formatNoopMessage: () => formatNoopMessage,
|
|
73136
|
+
formatIssue: () => formatIssue,
|
|
72301
73137
|
formatDenialMessage: () => formatDenialMessage,
|
|
72302
73138
|
extractSystemEventCorrelation: () => extractSystemEventCorrelation,
|
|
72303
73139
|
extractSystemEventActor: () => extractSystemEventActor,
|
|
@@ -72309,6 +73145,7 @@ __export(exports_src2, {
|
|
|
72309
73145
|
decodeRunListCursor: () => decodeRunListCursor,
|
|
72310
73146
|
createPsProcessInspector: () => createPsProcessInspector,
|
|
72311
73147
|
configuredSecretValues: () => configuredSecretValues,
|
|
73148
|
+
computeExitCode: () => computeExitCode,
|
|
72312
73149
|
computeAggregate: () => computeAggregate,
|
|
72313
73150
|
classifyTaskOutcome: () => classifyTaskOutcome,
|
|
72314
73151
|
clampToolUseLimit: () => clampToolUseLimit,
|
|
@@ -72514,19 +73351,19 @@ var {
|
|
|
72514
73351
|
init_src();
|
|
72515
73352
|
init_loader();
|
|
72516
73353
|
|
|
72517
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
73354
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/application-node.js
|
|
72518
73355
|
init_dist4();
|
|
72519
73356
|
init_dist5();
|
|
72520
73357
|
import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync5 } from "fs";
|
|
72521
73358
|
import { dirname as dirname5 } from "path";
|
|
72522
73359
|
|
|
72523
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
73360
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/application/index.js
|
|
72524
73361
|
init_default_observers();
|
|
72525
73362
|
init_event_bus();
|
|
72526
73363
|
init_file_observer();
|
|
72527
73364
|
init_logger3();
|
|
72528
73365
|
|
|
72529
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
73366
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/scheduler/noop.js
|
|
72530
73367
|
class NoopSchedulerAdapter {
|
|
72531
73368
|
constructor() {}
|
|
72532
73369
|
register(_cron, _action) {}
|
|
@@ -72534,7 +73371,7 @@ class NoopSchedulerAdapter {
|
|
|
72534
73371
|
async stop() {}
|
|
72535
73372
|
}
|
|
72536
73373
|
|
|
72537
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
73374
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/scheduler/factory.js
|
|
72538
73375
|
function initScheduler(adapter, cronEntries) {
|
|
72539
73376
|
const resolved = adapter ?? new NoopSchedulerAdapter;
|
|
72540
73377
|
if (cronEntries) {
|
|
@@ -72545,7 +73382,7 @@ function initScheduler(adapter, cronEntries) {
|
|
|
72545
73382
|
return resolved;
|
|
72546
73383
|
}
|
|
72547
73384
|
|
|
72548
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
73385
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/application/plugins/builtins.js
|
|
72549
73386
|
init_logger3();
|
|
72550
73387
|
init_metrics();
|
|
72551
73388
|
init_sdk();
|
|
@@ -72638,7 +73475,7 @@ function dbPlugin(db2) {
|
|
|
72638
73475
|
};
|
|
72639
73476
|
}
|
|
72640
73477
|
|
|
72641
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
73478
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/application/plugins/host.js
|
|
72642
73479
|
init_logger3();
|
|
72643
73480
|
|
|
72644
73481
|
class PluginHost {
|
|
@@ -72726,7 +73563,7 @@ class PluginHost {
|
|
|
72726
73563
|
}
|
|
72727
73564
|
}
|
|
72728
73565
|
|
|
72729
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
73566
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/application/index.js
|
|
72730
73567
|
async function performShutdown(state, reason) {
|
|
72731
73568
|
if (state.stopped)
|
|
72732
73569
|
return;
|
|
@@ -72837,10 +73674,10 @@ async function runApplication(options) {
|
|
|
72837
73674
|
}
|
|
72838
73675
|
}
|
|
72839
73676
|
|
|
72840
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
73677
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/application-node.js
|
|
72841
73678
|
init_scheduler_node();
|
|
72842
73679
|
|
|
72843
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
73680
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
|
|
72844
73681
|
var import_api14 = __toESM(require_src(), 1);
|
|
72845
73682
|
|
|
72846
73683
|
// ../../node_modules/.bun/@opentelemetry+exporter-metrics-otlp-http@0.218.0+e40b0dfdd726a224/node_modules/@opentelemetry/exporter-metrics-otlp-http/build/esm/OTLPMetricExporterBase.js
|
|
@@ -75856,7 +76693,7 @@ class OTLPTraceExporter extends import_otlp_exporter_base2.OTLPExporterBase {
|
|
|
75856
76693
|
}), JsonTraceSerializer));
|
|
75857
76694
|
}
|
|
75858
76695
|
}
|
|
75859
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
76696
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/telemetry/otel-node.js
|
|
75860
76697
|
var import_resources2 = __toESM(require_src4(), 1);
|
|
75861
76698
|
var import_sdk_trace_node = __toESM(require_src8(), 1);
|
|
75862
76699
|
var import_semantic_conventions = __toESM(require_src2(), 1);
|
|
@@ -75907,7 +76744,7 @@ async function shutdownNodeTelemetry() {
|
|
|
75907
76744
|
await Promise.all(pending);
|
|
75908
76745
|
}
|
|
75909
76746
|
|
|
75910
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.
|
|
76747
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.4.23+ce44f9a234a378c3/node_modules/@gobing-ai/ts-infra/dist/application-node.js
|
|
75911
76748
|
class ConfigValidationError extends Error {
|
|
75912
76749
|
constructor(message) {
|
|
75913
76750
|
super(message);
|
|
@@ -79987,15 +80824,15 @@ function parseLoopPoll(raw) {
|
|
|
79987
80824
|
return Number.isFinite(n2) && n2 > 0 ? n2 : DEFAULT_LOOP_POLL_MS;
|
|
79988
80825
|
}
|
|
79989
80826
|
function loopSleep(ms, signal) {
|
|
79990
|
-
return new Promise((
|
|
80827
|
+
return new Promise((resolve6) => {
|
|
79991
80828
|
if (signal?.aborted) {
|
|
79992
|
-
|
|
80829
|
+
resolve6();
|
|
79993
80830
|
return;
|
|
79994
80831
|
}
|
|
79995
|
-
const timer = setTimeout(
|
|
80832
|
+
const timer = setTimeout(resolve6, ms);
|
|
79996
80833
|
signal?.addEventListener("abort", () => {
|
|
79997
80834
|
clearTimeout(timer);
|
|
79998
|
-
|
|
80835
|
+
resolve6();
|
|
79999
80836
|
}, { once: true });
|
|
80000
80837
|
});
|
|
80001
80838
|
}
|
|
@@ -80053,9 +80890,9 @@ function makePlanningEmitter(context4) {
|
|
|
80053
80890
|
init_src3();
|
|
80054
80891
|
init_loader();
|
|
80055
80892
|
init_src2();
|
|
80056
|
-
import { existsSync as
|
|
80893
|
+
import { existsSync as existsSync10 } from "fs";
|
|
80057
80894
|
import { homedir as homedir6 } from "os";
|
|
80058
|
-
import { join as
|
|
80895
|
+
import { join as join20, resolve as resolve6 } from "path";
|
|
80059
80896
|
|
|
80060
80897
|
// src/workflow/resolve-spur-bin.ts
|
|
80061
80898
|
import { basename as basename3 } from "path";
|
|
@@ -80073,23 +80910,23 @@ function resolveSpurBin() {
|
|
|
80073
80910
|
}
|
|
80074
80911
|
|
|
80075
80912
|
// src/workflow/make-lifecycle-adapter.ts
|
|
80076
|
-
var GLOBAL_CONFIG_DIR =
|
|
80913
|
+
var GLOBAL_CONFIG_DIR = join20(".config", "spur");
|
|
80077
80914
|
function globalConfigRoot(context4) {
|
|
80078
80915
|
const override = context4.env.SPUR_GLOBAL_RULES_DIR;
|
|
80079
|
-
return override !== undefined && override.length > 0 ?
|
|
80916
|
+
return override !== undefined && override.length > 0 ? resolve6(context4.cwd, override) : join20(homedir6(), GLOBAL_CONFIG_DIR);
|
|
80080
80917
|
}
|
|
80081
80918
|
function resolveWorkflowPath(context4, profile) {
|
|
80082
80919
|
const bundledRoot = bundledConfigRoot();
|
|
80083
80920
|
if (bundledRoot !== null) {
|
|
80084
|
-
const bundledPath =
|
|
80085
|
-
if (
|
|
80921
|
+
const bundledPath = join20(bundledRoot, "workflows", `${profile.workflowName}.yaml`);
|
|
80922
|
+
if (existsSync10(bundledPath))
|
|
80086
80923
|
return bundledPath;
|
|
80087
80924
|
}
|
|
80088
|
-
const projectPath =
|
|
80089
|
-
if (
|
|
80925
|
+
const projectPath = join20(context4.cwd, ".spur", "workflows", `${profile.workflowName}.yaml`);
|
|
80926
|
+
if (existsSync10(projectPath))
|
|
80090
80927
|
return projectPath;
|
|
80091
|
-
const globalPath =
|
|
80092
|
-
if (
|
|
80928
|
+
const globalPath = join20(globalConfigRoot(context4), "workflows", `${profile.workflowName}.yaml`);
|
|
80929
|
+
if (existsSync10(globalPath))
|
|
80093
80930
|
return globalPath;
|
|
80094
80931
|
return null;
|
|
80095
80932
|
}
|
|
@@ -80474,46 +81311,229 @@ async function assertFeatureCheckPass(context4, id, folderOverride, strict, asSt
|
|
|
80474
81311
|
// src/commands/history.ts
|
|
80475
81312
|
init_src3();
|
|
80476
81313
|
init_src2();
|
|
81314
|
+
init_dist6();
|
|
81315
|
+
|
|
81316
|
+
// src/config.ts
|
|
81317
|
+
var CLI_CONFIG = {
|
|
81318
|
+
binaryName: "spur",
|
|
81319
|
+
binaryLabel: "spur",
|
|
81320
|
+
binaryVersion: "0.3.36",
|
|
81321
|
+
configDir: ".spur",
|
|
81322
|
+
configFile: ".spur/config.yaml",
|
|
81323
|
+
databaseFile: ".spur/spur.db"
|
|
81324
|
+
};
|
|
81325
|
+
|
|
81326
|
+
// src/commands/history.ts
|
|
80477
81327
|
function registerHistoryCommand(program2, context4) {
|
|
80478
81328
|
const noun = program2.command("history").summary("import and analyze coding-agent history");
|
|
80479
|
-
noun.command("import").description("Import agent conversation JSONL.").option("--source <source>", "pi|claude|codex|gemini|opencode|antigravity|openclaw|omp|grok|agy", "
|
|
81329
|
+
noun.command("import").description("Import agent conversation JSONL. `--source all` fans out across all sources with " + "per-source failure isolation (task 0470). A single source is the n=1 case of " + "the same contract \u2014 never two import paths.").option("--source <source>", "pi|claude|codex|gemini|opencode|antigravity|openclaw|omp|grok|agy|all", "all").option("--file <path>", "Import one JSONL file (single-source only)").option("--root <path>", "Scan a history root").option("--mode <mode>", "full|incremental|force-file").option("--dry-run", "Scan without persisting imported records").option("--source-timeout <ms>", "Per-source timeout in milliseconds (default 600000 = 10 min)", "600000").option("--json", "Output machine-readable JSON where supported").action(async (options) => {
|
|
80480
81330
|
const svc = new HistoryService({ getDb: () => context4.getDb() });
|
|
80481
|
-
const
|
|
81331
|
+
const source = options.source ?? "all";
|
|
81332
|
+
if (options.file && source === "all") {
|
|
81333
|
+
context4.output.write(options.json ? toJson2({ status: "error", message: '--file requires a single --source, not "all".' }) : 'spur history import: --file requires a single --source, not "all".');
|
|
81334
|
+
context4.setExitCode(1);
|
|
81335
|
+
return;
|
|
81336
|
+
}
|
|
81337
|
+
const sourceTimeout = Number.parseInt(options.sourceTimeout ?? "600000", 10) || 600000;
|
|
81338
|
+
const mode = options.mode ?? (options.file ? "force-file" : "incremental");
|
|
81339
|
+
if (mode !== "full" && mode !== "incremental" && mode !== "force-file") {
|
|
81340
|
+
const modeMsg = `Invalid history import mode "${mode}". Expected one of: full, incremental, force-file`;
|
|
81341
|
+
if (options.json) {
|
|
81342
|
+
context4.output.write(toJson2({ status: "error", message: modeMsg }));
|
|
81343
|
+
} else {
|
|
81344
|
+
context4.output.error(modeMsg);
|
|
81345
|
+
}
|
|
81346
|
+
context4.setExitCode(1);
|
|
81347
|
+
return;
|
|
81348
|
+
}
|
|
81349
|
+
const fanOut = await svc.importAll({
|
|
81350
|
+
sources: source === "all" ? undefined : [source],
|
|
80482
81351
|
file: options.file || undefined,
|
|
80483
81352
|
root: options.root || undefined,
|
|
80484
|
-
mode
|
|
80485
|
-
dryRun: options.dryRun === true
|
|
81353
|
+
mode,
|
|
81354
|
+
dryRun: options.dryRun === true,
|
|
81355
|
+
sourceTimeout
|
|
80486
81356
|
});
|
|
80487
|
-
context4.output.write(options.json ? toJson2(
|
|
80488
|
-
|
|
80489
|
-
context4.setExitCode(code);
|
|
81357
|
+
context4.output.write(options.json ? toJson2(fanOut) : formatFanOutResult(fanOut));
|
|
81358
|
+
context4.setExitCode(fanOut.exitCode);
|
|
80490
81359
|
});
|
|
80491
|
-
noun.command("analyze").description("
|
|
81360
|
+
noun.command("analyze").description("Aggregate imported history with SQL and write a versioned JSON artifact (Q1-Q10 forensic query set).").option("--since <iso>", "Inclusive lower bound on message timestamp").option("--until <iso>", "Inclusive upper bound on message timestamp").option("--source <source>", "pi|claude|codex|gemini|opencode|antigravity|openclaw|omp|grok|agy|all", "all").option("--session <id>", "Narrow to a single session id").option("--run <runId>", "Narrow to a single workflow run id").option("--task <wbs>", "Narrow to a single task WBS").option("--top <n>", "Leaderboard depth for byTool/bySession", "20").option("--out <path>", "Write the artifact to this path instead of the dated reports dir").option("--json", "Emit the artifact as JSON instead of the human summary").action(async (options) => {
|
|
80492
81361
|
const svc = new HistoryService({ getDb: () => context4.getDb() });
|
|
80493
|
-
const
|
|
80494
|
-
|
|
81362
|
+
const source = options.source ?? "all";
|
|
81363
|
+
const selector = {
|
|
81364
|
+
since: options.since || null,
|
|
81365
|
+
until: options.until || null,
|
|
81366
|
+
sources: source === "all" ? null : [source],
|
|
81367
|
+
sessionId: options.session || null,
|
|
81368
|
+
runId: options.run || null,
|
|
81369
|
+
taskWbs: options.task || null
|
|
81370
|
+
};
|
|
81371
|
+
const artifact = await svc.analyze(selector, {
|
|
81372
|
+
top: Number.parseInt(options.top ?? "20", 10) || 20,
|
|
81373
|
+
spurVersion: CLI_CONFIG.binaryVersion,
|
|
81374
|
+
out: options.out || undefined,
|
|
81375
|
+
cwd: context4.cwd
|
|
81376
|
+
});
|
|
81377
|
+
context4.output.write(options.json ? toJson2(artifact) : formatSummary({
|
|
81378
|
+
totals: artifact.totals,
|
|
81379
|
+
bySource: artifact.bySource,
|
|
81380
|
+
byModel: artifact.byModel,
|
|
81381
|
+
daily: artifact.daily
|
|
81382
|
+
}));
|
|
80495
81383
|
});
|
|
80496
|
-
noun.command("report").description("
|
|
80497
|
-
|
|
80498
|
-
|
|
80499
|
-
|
|
80500
|
-
|
|
80501
|
-
|
|
80502
|
-
|
|
81384
|
+
noun.command("report").description("Render a previously-generated history artifact as a spend + forensic report. " + "Never opens the database \u2014 pure renderer of the analyze JSON.").argument("[path]", "Artifact JSON path (defaults to the latest.json pointer)").option("--json", "Emit the parsed artifact as JSON instead of the human report").action(async (pathArg, options) => {
|
|
81385
|
+
try {
|
|
81386
|
+
const { report, artifactPath, resolution, artifact } = runHistoryReport({
|
|
81387
|
+
path: pathArg,
|
|
81388
|
+
cwd: context4.cwd,
|
|
81389
|
+
now: new Date
|
|
81390
|
+
});
|
|
81391
|
+
if (options.json) {
|
|
81392
|
+
context4.output.write(toJson2(artifact));
|
|
81393
|
+
context4.setExitCode(0);
|
|
81394
|
+
return;
|
|
81395
|
+
}
|
|
81396
|
+
if (resolution === "pointer") {
|
|
81397
|
+
const banner = stalenessBanner(artifact.generatedAt, new Date);
|
|
81398
|
+
if (banner !== null)
|
|
81399
|
+
context4.output.write(banner);
|
|
81400
|
+
}
|
|
81401
|
+
context4.output.write(report);
|
|
81402
|
+
context4.output.write(`
|
|
81403
|
+
(artifact: ${artifactPath})
|
|
81404
|
+
`);
|
|
81405
|
+
context4.setExitCode(0);
|
|
81406
|
+
} catch (e) {
|
|
81407
|
+
const message = `spur history report failed: ${e.message}`;
|
|
81408
|
+
context4.output.write(options.json ? toJson2({ status: "error", message }) : message);
|
|
81409
|
+
context4.setExitCode(1);
|
|
81410
|
+
}
|
|
81411
|
+
});
|
|
81412
|
+
noun.command("daily").description("Run-once daily pipeline: import-all (fan-out, per-source isolation) \u2192 analyze \u2192 write " + "artifact \u2192 prune reports older than 90 days (task 0470 R6). Import uses checkpoint " + "resume, so a missed night self-heals on the next run with no gap and no double-count.").option("--since <iso>", "Inclusive lower bound on message timestamp for the report (not the import)").option("--until <iso>", "Inclusive upper bound on message timestamp for the report").option("--source-timeout <ms>", "Per-source import timeout in milliseconds (default 600000 = 10 min)", "600000").option("--root <path>", "History root override (default: per-source platform dir)").option("--json", "Emit the daily result as JSON").action(async (options) => {
|
|
81413
|
+
const svc = new HistoryService({ getDb: () => context4.getDb() });
|
|
81414
|
+
const sourceTimeout = Number.parseInt(options.sourceTimeout ?? "600000", 10) || 600000;
|
|
81415
|
+
const bus = new EventBus;
|
|
81416
|
+
const ledger = await attachSystemEventLedger(bus, context4);
|
|
81417
|
+
const startMs = Date.now();
|
|
81418
|
+
let result = null;
|
|
81419
|
+
let failure = null;
|
|
81420
|
+
try {
|
|
81421
|
+
result = await svc.daily({
|
|
81422
|
+
since: options.since || undefined,
|
|
81423
|
+
until: options.until || undefined,
|
|
81424
|
+
sourceTimeout,
|
|
81425
|
+
spurVersion: CLI_CONFIG.binaryVersion,
|
|
81426
|
+
cwd: context4.cwd,
|
|
81427
|
+
root: options.root || undefined
|
|
81428
|
+
});
|
|
81429
|
+
} catch (e) {
|
|
81430
|
+
failure = { exitCode: 1, detail: e instanceof Error ? e.message : String(e) };
|
|
81431
|
+
}
|
|
81432
|
+
const durationMs = Date.now() - startMs;
|
|
81433
|
+
try {
|
|
81434
|
+
if (failure !== null) {
|
|
81435
|
+
await bus.emit("history.daily.failed", {
|
|
81436
|
+
source: "history",
|
|
81437
|
+
renderer: "history-daily",
|
|
81438
|
+
detail: failure.detail,
|
|
81439
|
+
exitCode: failure.exitCode,
|
|
81440
|
+
durationMs
|
|
81441
|
+
});
|
|
81442
|
+
context4.setExitCode(1);
|
|
81443
|
+
} else if (result !== null) {
|
|
81444
|
+
const exitCode = result.fanOut.exitCode;
|
|
81445
|
+
let artifactPath;
|
|
81446
|
+
try {
|
|
81447
|
+
artifactPath = resolveArtifactPath(undefined, context4.cwd).path;
|
|
81448
|
+
} catch {
|
|
81449
|
+
artifactPath = undefined;
|
|
81450
|
+
}
|
|
81451
|
+
const entries = result.fanOut.entries;
|
|
81452
|
+
const sources = entries.length;
|
|
81453
|
+
const okSources = entries.filter((e) => e.status === "ok").length;
|
|
81454
|
+
const failedSources = entries.filter((e) => e.status === "failed").length;
|
|
81455
|
+
const files = entries.reduce((sum, e) => sum + e.files, 0);
|
|
81456
|
+
const messages2 = entries.reduce((sum, e) => sum + e.messages, 0);
|
|
81457
|
+
if (exitCode === 0) {
|
|
81458
|
+
await bus.emit("history.import.completed", {
|
|
81459
|
+
source: "history",
|
|
81460
|
+
renderer: "history-import",
|
|
81461
|
+
sources,
|
|
81462
|
+
okSources,
|
|
81463
|
+
failedSources,
|
|
81464
|
+
files,
|
|
81465
|
+
messages: messages2,
|
|
81466
|
+
durationMs,
|
|
81467
|
+
artifactPath
|
|
81468
|
+
});
|
|
81469
|
+
await bus.emit("history.analyze.completed", {
|
|
81470
|
+
source: "history",
|
|
81471
|
+
renderer: "history-analyze",
|
|
81472
|
+
artifactPath,
|
|
81473
|
+
totals: result.artifact.totals
|
|
81474
|
+
});
|
|
81475
|
+
} else {
|
|
81476
|
+
const failing = entries.filter((e) => e.status === "failed");
|
|
81477
|
+
await bus.emit("history.daily.failed", {
|
|
81478
|
+
source: "history",
|
|
81479
|
+
renderer: "history-daily",
|
|
81480
|
+
exitCode,
|
|
81481
|
+
sources,
|
|
81482
|
+
okSources,
|
|
81483
|
+
failedSources,
|
|
81484
|
+
detail: failing.length > 0 ? failing.map((e) => `${e.source}: ${e.parseErrors + e.validationErrors} errors`).join("; ") : "daily fan-out reported non-zero exit with no failing source",
|
|
81485
|
+
durationMs,
|
|
81486
|
+
artifactPath
|
|
81487
|
+
});
|
|
81488
|
+
}
|
|
81489
|
+
context4.setExitCode(exitCode);
|
|
81490
|
+
}
|
|
81491
|
+
} finally {
|
|
81492
|
+
ledger.unsubscribe();
|
|
81493
|
+
await ledger.flush();
|
|
81494
|
+
}
|
|
81495
|
+
if (failure !== null) {
|
|
81496
|
+
context4.output.write(options.json ? toJson2({ error: failure.detail }) : `history daily failed: ${failure.detail}`);
|
|
81497
|
+
return;
|
|
81498
|
+
}
|
|
81499
|
+
if (result === null) {
|
|
81500
|
+
context4.setExitCode(1);
|
|
81501
|
+
return;
|
|
81502
|
+
}
|
|
81503
|
+
context4.output.write(options.json ? toJson2(result) : formatDailyResult(result));
|
|
80503
81504
|
});
|
|
80504
81505
|
}
|
|
80505
|
-
function
|
|
80506
|
-
|
|
80507
|
-
|
|
80508
|
-
`
|
|
80509
|
-
|
|
80510
|
-
|
|
80511
|
-
|
|
80512
|
-
|
|
80513
|
-
|
|
80514
|
-
|
|
80515
|
-
|
|
80516
|
-
|
|
81506
|
+
function formatFanOutResult(r) {
|
|
81507
|
+
const lines = ["history import (fan-out)", "sources:"];
|
|
81508
|
+
for (const e of r.entries) {
|
|
81509
|
+
lines.push(` ${e.source}: ${e.status} (files=${e.files} messages=${e.messages})`);
|
|
81510
|
+
}
|
|
81511
|
+
if (r.warnings.length > 0) {
|
|
81512
|
+
lines.push("warnings:");
|
|
81513
|
+
for (const w of r.warnings) {
|
|
81514
|
+
lines.push(` [${w.code}] ${w.source ?? "-"}: ${w.detail}`);
|
|
81515
|
+
}
|
|
81516
|
+
}
|
|
81517
|
+
lines.push(`exit_code: ${r.exitCode}`);
|
|
81518
|
+
return lines.join(`
|
|
81519
|
+
`);
|
|
81520
|
+
}
|
|
81521
|
+
function formatDailyResult(r) {
|
|
81522
|
+
const lines = ["history daily"];
|
|
81523
|
+
lines.push("import:");
|
|
81524
|
+
for (const e of r.fanOut.entries) {
|
|
81525
|
+
lines.push(` ${e.source}: ${e.status} (files=${e.files} messages=${e.messages})`);
|
|
81526
|
+
}
|
|
81527
|
+
if (r.fanOut.warnings.length > 0) {
|
|
81528
|
+
lines.push("warnings:");
|
|
81529
|
+
for (const w of r.fanOut.warnings) {
|
|
81530
|
+
lines.push(` [${w.code}] ${w.source ?? "-"}: ${w.detail}`);
|
|
81531
|
+
}
|
|
81532
|
+
}
|
|
81533
|
+
lines.push(`artifact totals: messages=${r.artifact.totals.messages} toolCalls=${r.artifact.totals.toolCalls}`);
|
|
81534
|
+
lines.push(`pruned: ${r.pruned.length} report dir(s) older than 90 days`);
|
|
81535
|
+
lines.push(`exit_code: ${r.fanOut.exitCode}`);
|
|
81536
|
+
return lines.join(`
|
|
80517
81537
|
`);
|
|
80518
81538
|
}
|
|
80519
81539
|
|
|
@@ -80522,17 +81542,7 @@ init_loader();
|
|
|
80522
81542
|
init_src2();
|
|
80523
81543
|
init_dist10();
|
|
80524
81544
|
import { homedir as homedir7 } from "os";
|
|
80525
|
-
import { join as
|
|
80526
|
-
|
|
80527
|
-
// src/config.ts
|
|
80528
|
-
var CLI_CONFIG = {
|
|
80529
|
-
binaryName: "spur",
|
|
80530
|
-
binaryLabel: "spur",
|
|
80531
|
-
binaryVersion: "0.3.35",
|
|
80532
|
-
configDir: ".spur",
|
|
80533
|
-
configFile: ".spur/config.yaml",
|
|
80534
|
-
databaseFile: ".spur/spur.db"
|
|
80535
|
-
};
|
|
81545
|
+
import { join as join21, resolve as resolve7 } from "path";
|
|
80536
81546
|
|
|
80537
81547
|
// src/config/scaffold-manifest.ts
|
|
80538
81548
|
var SCAFFOLD_MANIFEST = [
|
|
@@ -80579,8 +81589,8 @@ var SCAFFOLD_MANIFEST = [
|
|
|
80579
81589
|
];
|
|
80580
81590
|
|
|
80581
81591
|
// src/commands/init.ts
|
|
80582
|
-
var GLOBAL_CONFIG_DIR2 =
|
|
80583
|
-
var GLOBAL_RULES_DIR2 =
|
|
81592
|
+
var GLOBAL_CONFIG_DIR2 = join21(".config", "spur");
|
|
81593
|
+
var GLOBAL_RULES_DIR2 = join21(GLOBAL_CONFIG_DIR2, "rules");
|
|
80584
81594
|
var GLOBAL_CONFIG_EXAMPLE = "config.example.yaml";
|
|
80585
81595
|
var GLOBAL_CONFIG_FILE2 = "config.yaml";
|
|
80586
81596
|
var INDEXED_CONTEXT_MARKER = "## Indexed context";
|
|
@@ -80611,7 +81621,7 @@ If \`.spur/context/\` is absent, proceed normally. Never block work on its absen
|
|
|
80611
81621
|
`;
|
|
80612
81622
|
function globalRulesRoot(context4) {
|
|
80613
81623
|
const override = context4.env.SPUR_GLOBAL_RULES_DIR;
|
|
80614
|
-
return override !== undefined && override.length > 0 ?
|
|
81624
|
+
return override !== undefined && override.length > 0 ? resolve7(context4.cwd, override) : join21(homedir7(), GLOBAL_RULES_DIR2);
|
|
80615
81625
|
}
|
|
80616
81626
|
async function writeIfNew(context4, path9, content, force, result) {
|
|
80617
81627
|
if (!force && await context4.fs.exists(path9)) {
|
|
@@ -80628,11 +81638,11 @@ async function seedGlobalRules(context4) {
|
|
|
80628
81638
|
const target = globalRulesRoot(context4);
|
|
80629
81639
|
let written = 0;
|
|
80630
81640
|
for (const relPath of await listBundledRuleFiles()) {
|
|
80631
|
-
const destination =
|
|
81641
|
+
const destination = join21(target, relPath);
|
|
80632
81642
|
if (await context4.fs.exists(destination))
|
|
80633
81643
|
continue;
|
|
80634
|
-
await context4.fs.ensureDir(
|
|
80635
|
-
await context4.fs.writeFile(destination, await context4.fs.readFile(
|
|
81644
|
+
await context4.fs.ensureDir(join21(target, ...relPath.split("/").slice(0, -1)));
|
|
81645
|
+
await context4.fs.writeFile(destination, await context4.fs.readFile(join21(source, relPath)));
|
|
80636
81646
|
written += 1;
|
|
80637
81647
|
}
|
|
80638
81648
|
return written;
|
|
@@ -80642,20 +81652,20 @@ async function seedGlobalConfig(context4) {
|
|
|
80642
81652
|
if (source === null)
|
|
80643
81653
|
return 0;
|
|
80644
81654
|
const globalOverride = context4.env.SPUR_GLOBAL_RULES_DIR;
|
|
80645
|
-
const target = globalOverride !== undefined && globalOverride.length > 0 ?
|
|
81655
|
+
const target = globalOverride !== undefined && globalOverride.length > 0 ? resolve7(context4.cwd, globalOverride) : join21(homedir7(), GLOBAL_CONFIG_DIR2);
|
|
80646
81656
|
let written = 0;
|
|
80647
81657
|
for (const relPath of listBundledConfigFiles()) {
|
|
80648
81658
|
if (relPath === GLOBAL_CONFIG_EXAMPLE)
|
|
80649
81659
|
continue;
|
|
80650
|
-
const destination =
|
|
81660
|
+
const destination = join21(target, relPath);
|
|
80651
81661
|
if (await context4.fs.exists(destination))
|
|
80652
81662
|
continue;
|
|
80653
|
-
await context4.fs.ensureDir(
|
|
80654
|
-
await context4.fs.writeFile(destination, await context4.fs.readFile(
|
|
81663
|
+
await context4.fs.ensureDir(join21(target, ...relPath.split("/").slice(0, -1)));
|
|
81664
|
+
await context4.fs.writeFile(destination, await context4.fs.readFile(join21(source, relPath)));
|
|
80655
81665
|
written += 1;
|
|
80656
81666
|
}
|
|
80657
|
-
const examplePath =
|
|
80658
|
-
const globalConfigPath =
|
|
81667
|
+
const examplePath = join21(source, GLOBAL_CONFIG_EXAMPLE);
|
|
81668
|
+
const globalConfigPath = join21(target, GLOBAL_CONFIG_FILE2);
|
|
80659
81669
|
if (await context4.fs.exists(examplePath) && !await context4.fs.exists(globalConfigPath)) {
|
|
80660
81670
|
await context4.fs.ensureDir(target);
|
|
80661
81671
|
await context4.fs.writeFile(globalConfigPath, await context4.fs.readFile(examplePath));
|
|
@@ -80669,7 +81679,7 @@ function registerInitCommand(program2, context4) {
|
|
|
80669
81679
|
const force = options.force === true;
|
|
80670
81680
|
const minimal = options.minimal === true;
|
|
80671
81681
|
const projectName = options.name ?? "default";
|
|
80672
|
-
const configPath =
|
|
81682
|
+
const configPath = join21(context4.cwd, CLI_CONFIG.configFile);
|
|
80673
81683
|
if (!force && await context4.fs.exists(configPath)) {
|
|
80674
81684
|
const message = `Already initialized: ${CLI_CONFIG.configFile}. Use --force to overwrite.`;
|
|
80675
81685
|
context4.output.write(json3 ? toJson2({ ok: false, reason: "already-initialized", config: CLI_CONFIG.configFile }) : message);
|
|
@@ -80704,13 +81714,13 @@ function registerInitCommand(program2, context4) {
|
|
|
80704
81714
|
].join(`
|
|
80705
81715
|
`)}
|
|
80706
81716
|
`;
|
|
80707
|
-
await context4.fs.ensureDir(
|
|
81717
|
+
await context4.fs.ensureDir(join21(context4.cwd, CLI_CONFIG.configDir));
|
|
80708
81718
|
await context4.fs.writeFile(configPath, configYaml);
|
|
80709
81719
|
result.created.push(configPath);
|
|
80710
|
-
const agentsDir =
|
|
81720
|
+
const agentsDir = join21(context4.cwd, CLI_CONFIG.configDir, "agents");
|
|
80711
81721
|
await context4.fs.ensureDir(agentsDir);
|
|
80712
|
-
await writeIfNew(context4,
|
|
80713
|
-
const gitignorePath =
|
|
81722
|
+
await writeIfNew(context4, join21(agentsDir, ".gitkeep"), "", force, result);
|
|
81723
|
+
const gitignorePath = join21(context4.cwd, ".gitignore");
|
|
80714
81724
|
const contextEntry = ".spur/context/";
|
|
80715
81725
|
if (await context4.fs.exists(gitignorePath)) {
|
|
80716
81726
|
const existing = await context4.fs.readFile(gitignorePath);
|
|
@@ -80732,20 +81742,20 @@ ${contextEntry}
|
|
|
80732
81742
|
for (const relPath of listBundledProjectSeedFiles()) {
|
|
80733
81743
|
if (relPath.startsWith("templates/docs/"))
|
|
80734
81744
|
continue;
|
|
80735
|
-
const sourcePath =
|
|
81745
|
+
const sourcePath = join21(configRoot, relPath);
|
|
80736
81746
|
if (!await context4.fs.exists(sourcePath))
|
|
80737
81747
|
continue;
|
|
80738
|
-
const targetPath =
|
|
80739
|
-
await context4.fs.ensureDir(
|
|
81748
|
+
const targetPath = join21(context4.cwd, CLI_CONFIG.configDir, relPath);
|
|
81749
|
+
await context4.fs.ensureDir(join21(targetPath, ".."));
|
|
80740
81750
|
await writeIfNew(context4, targetPath, await context4.fs.readFile(sourcePath), force, result);
|
|
80741
81751
|
}
|
|
80742
81752
|
for (const entry of SCAFFOLD_MANIFEST) {
|
|
80743
|
-
const sourcePath =
|
|
81753
|
+
const sourcePath = join21(configRoot, entry.source);
|
|
80744
81754
|
if (!await context4.fs.exists(sourcePath))
|
|
80745
81755
|
continue;
|
|
80746
|
-
const baseDir = entry.root === true ? context4.cwd :
|
|
80747
|
-
const targetPath =
|
|
80748
|
-
await context4.fs.ensureDir(
|
|
81756
|
+
const baseDir = entry.root === true ? context4.cwd : join21(context4.cwd, CLI_CONFIG.configDir);
|
|
81757
|
+
const targetPath = join21(baseDir, entry.target);
|
|
81758
|
+
await context4.fs.ensureDir(join21(targetPath, ".."));
|
|
80749
81759
|
const entryForce = entry.preserve === true ? false : force;
|
|
80750
81760
|
let body = await context4.fs.readFile(sourcePath);
|
|
80751
81761
|
if (entry.target === "AGENTS.md") {
|
|
@@ -80758,7 +81768,7 @@ ${contextEntry}
|
|
|
80758
81768
|
}
|
|
80759
81769
|
}
|
|
80760
81770
|
}
|
|
80761
|
-
const agentsMdPath =
|
|
81771
|
+
const agentsMdPath = join21(context4.cwd, "AGENTS.md");
|
|
80762
81772
|
if (await context4.fs.exists(agentsMdPath)) {
|
|
80763
81773
|
const existing = await context4.fs.readFile(agentsMdPath);
|
|
80764
81774
|
if (!existing.includes(INDEXED_CONTEXT_MARKER)) {
|
|
@@ -80915,15 +81925,15 @@ async function runMessageWatch(svc, output2, options, runtime = {}) {
|
|
|
80915
81925
|
}
|
|
80916
81926
|
}
|
|
80917
81927
|
function defaultSleep(ms, signal) {
|
|
80918
|
-
return new Promise((
|
|
81928
|
+
return new Promise((resolve8) => {
|
|
80919
81929
|
if (signal?.aborted) {
|
|
80920
|
-
|
|
81930
|
+
resolve8();
|
|
80921
81931
|
return;
|
|
80922
81932
|
}
|
|
80923
|
-
const timer = setTimeout(
|
|
81933
|
+
const timer = setTimeout(resolve8, ms);
|
|
80924
81934
|
signal?.addEventListener("abort", () => {
|
|
80925
81935
|
clearTimeout(timer);
|
|
80926
|
-
|
|
81936
|
+
resolve8();
|
|
80927
81937
|
}, { once: true });
|
|
80928
81938
|
});
|
|
80929
81939
|
}
|
|
@@ -80936,10 +81946,10 @@ function parseInterval2(raw) {
|
|
|
80936
81946
|
|
|
80937
81947
|
// src/commands/migrate.ts
|
|
80938
81948
|
init_src2();
|
|
80939
|
-
import { join as
|
|
81949
|
+
import { join as join22 } from "path";
|
|
80940
81950
|
function registerMigrateCommand(program2, context4) {
|
|
80941
81951
|
program2.command("migrate").summary("apply CLI-owned schema migrations").option("--json", "Output machine-readable JSON").action(async (options) => {
|
|
80942
|
-
const migrations = await loadSqlMigrations(
|
|
81952
|
+
const migrations = await loadSqlMigrations(join22(context4.cwd, "drizzle")).catch(() => {
|
|
80943
81953
|
return;
|
|
80944
81954
|
});
|
|
80945
81955
|
const applied = await applyCliMigrations(await context4.getDb(), migrations);
|
|
@@ -80951,12 +81961,12 @@ function registerMigrateCommand(program2, context4) {
|
|
|
80951
81961
|
// src/commands/projects.ts
|
|
80952
81962
|
init_src3();
|
|
80953
81963
|
init_dist5();
|
|
80954
|
-
import { basename as basename4, resolve as
|
|
81964
|
+
import { basename as basename4, resolve as resolve8 } from "path";
|
|
80955
81965
|
function registerProjectsCommand(program2, context4) {
|
|
80956
81966
|
const projectsCmd = program2.command("projects").summary("manage the Spur multi-project registry");
|
|
80957
81967
|
projectsCmd.command("add").argument("<path>", "Project root directory path").option("--name <name>", "Display name for the project").option("--json", "Output JSON response").action(async (pathArg, options) => {
|
|
80958
81968
|
try {
|
|
80959
|
-
const absolutePath =
|
|
81969
|
+
const absolutePath = resolve8(context4.cwd, pathArg);
|
|
80960
81970
|
if (!await context4.fs.exists(absolutePath)) {
|
|
80961
81971
|
throw new Error(`Directory does not exist: ${absolutePath}`);
|
|
80962
81972
|
}
|
|
@@ -81355,7 +82365,7 @@ function formatTraceDetail(detail) {
|
|
|
81355
82365
|
|
|
81356
82366
|
// src/commands/serve.ts
|
|
81357
82367
|
init_src();
|
|
81358
|
-
import { join as
|
|
82368
|
+
import { join as join26 } from "path";
|
|
81359
82369
|
|
|
81360
82370
|
// ../server/src/index.ts
|
|
81361
82371
|
init_src();
|
|
@@ -81365,11 +82375,11 @@ init_src3();
|
|
|
81365
82375
|
init_src();
|
|
81366
82376
|
init_loader();
|
|
81367
82377
|
init_src2();
|
|
81368
|
-
import { basename as basename6, dirname as
|
|
82378
|
+
import { basename as basename6, dirname as dirname17, isAbsolute as isAbsolute4, join as join25 } from "path";
|
|
81369
82379
|
init_dist5();
|
|
81370
82380
|
|
|
81371
82381
|
// ../server/src/bootstrap.ts
|
|
81372
|
-
import { join as
|
|
82382
|
+
import { join as join23 } from "path";
|
|
81373
82383
|
|
|
81374
82384
|
// ../../node_modules/.bun/radash@12.1.1/node_modules/radash/dist/esm/async.mjs
|
|
81375
82385
|
var guard = (func, shouldGuard) => {
|
|
@@ -81642,8 +82652,8 @@ class EventPublisher {
|
|
|
81642
82652
|
if (bufferedEvents.length > 0) {
|
|
81643
82653
|
return { done: false, value: bufferedEvents.shift() };
|
|
81644
82654
|
}
|
|
81645
|
-
return new Promise((
|
|
81646
|
-
pullResolvers.push([
|
|
82655
|
+
return new Promise((resolve9, reject) => {
|
|
82656
|
+
pullResolvers.push([resolve9, reject]);
|
|
81647
82657
|
});
|
|
81648
82658
|
}, async () => {
|
|
81649
82659
|
unsubscribe();
|
|
@@ -90266,7 +91276,7 @@ function createApp(appRt, opts) {
|
|
|
90266
91276
|
app.use("*", async (c3, next) => {
|
|
90267
91277
|
const pathname = c3.req.path === "/" ? "/index.html" : c3.req.path;
|
|
90268
91278
|
try {
|
|
90269
|
-
const file2 = Bun.file(
|
|
91279
|
+
const file2 = Bun.file(join23(webDistPath, pathname));
|
|
90270
91280
|
if (await file2.exists()) {
|
|
90271
91281
|
const headers = new Headers({ "content-type": file2.type });
|
|
90272
91282
|
return new Response(file2.stream(), { headers });
|
|
@@ -90279,7 +91289,7 @@ function createApp(appRt, opts) {
|
|
|
90279
91289
|
return c3.json({ error: "Not Found" }, 404);
|
|
90280
91290
|
}
|
|
90281
91291
|
try {
|
|
90282
|
-
const indexFile = Bun.file(
|
|
91292
|
+
const indexFile = Bun.file(join23(webDistPath, "index.html"));
|
|
90283
91293
|
if (await indexFile.exists()) {
|
|
90284
91294
|
return new Response(indexFile.stream(), {
|
|
90285
91295
|
headers: { "content-type": "text/html; charset=utf-8" }
|
|
@@ -90300,7 +91310,7 @@ init_src3();
|
|
|
90300
91310
|
init_src();
|
|
90301
91311
|
init_src2();
|
|
90302
91312
|
init_dist5();
|
|
90303
|
-
import { dirname as
|
|
91313
|
+
import { dirname as dirname16, join as join24 } from "path";
|
|
90304
91314
|
var NOOP_OUTPUT = { write: (_s) => {}, error: (_s) => {} };
|
|
90305
91315
|
|
|
90306
91316
|
class LazyPlanningEventEmitter {
|
|
@@ -90335,7 +91345,7 @@ class NotConfiguredError extends Error {
|
|
|
90335
91345
|
function createServerContext(appRt, options) {
|
|
90336
91346
|
const cwd = options.cwd;
|
|
90337
91347
|
const fs3 = options.fs;
|
|
90338
|
-
const dbUrl = options.dbUrl ??
|
|
91348
|
+
const dbUrl = options.dbUrl ?? join24(cwd, DEFAULT_DATABASE_URL);
|
|
90339
91349
|
const eventsBus = options.eventsBus ?? appRt.events;
|
|
90340
91350
|
const jobQueueEnabled = options.jobQueueEnabled ?? false;
|
|
90341
91351
|
const folders = options.folders ?? DEFAULT_PLANNING_FOLDERS;
|
|
@@ -90370,7 +91380,7 @@ function createServerContext(appRt, options) {
|
|
|
90370
91380
|
if (!dbPromise) {
|
|
90371
91381
|
const created = (async () => {
|
|
90372
91382
|
if (dbUrl !== IN_MEMORY_DATABASE_URL) {
|
|
90373
|
-
await fs3.ensureDir(
|
|
91383
|
+
await fs3.ensureDir(dirname16(dbUrl));
|
|
90374
91384
|
}
|
|
90375
91385
|
return createMigratedDbViaRuntime({ url: dbUrl });
|
|
90376
91386
|
})();
|
|
@@ -90695,15 +91705,15 @@ async function handleFeatureActionJob(ctx, env, payload) {
|
|
|
90695
91705
|
await runFeatureActionJob(ctx, env, payload);
|
|
90696
91706
|
}
|
|
90697
91707
|
async function resolveWebDistPath(configuredPath) {
|
|
90698
|
-
const candidates = configuredPath && configuredPath.trim() !== "" ? [
|
|
90699
|
-
|
|
90700
|
-
|
|
90701
|
-
|
|
90702
|
-
|
|
90703
|
-
|
|
91708
|
+
const candidates = configuredPath && configuredPath.trim() !== "" ? [isAbsolute4(configuredPath) ? configuredPath : join25(process.cwd(), configuredPath)] : [
|
|
91709
|
+
join25(process.cwd(), "dist/web"),
|
|
91710
|
+
join25(import.meta.dir, "web"),
|
|
91711
|
+
join25(dirname17(process.execPath), "web"),
|
|
91712
|
+
join25(dirname17(process.execPath), "../web"),
|
|
91713
|
+
join25(import.meta.dir, "../../../dist/web")
|
|
90704
91714
|
];
|
|
90705
91715
|
for (const candidate of candidates) {
|
|
90706
|
-
if (await Bun.file(
|
|
91716
|
+
if (await Bun.file(join25(candidate, "index.html")).exists()) {
|
|
90707
91717
|
return candidate;
|
|
90708
91718
|
}
|
|
90709
91719
|
}
|
|
@@ -90719,7 +91729,7 @@ async function startServer(options, deps = defaultDeps) {
|
|
|
90719
91729
|
async start(appRt) {
|
|
90720
91730
|
const fs3 = deps.createNodeFileSystem(process.cwd());
|
|
90721
91731
|
if (options.dbUrl && options.dbUrl !== IN_MEMORY_DATABASE_URL) {
|
|
90722
|
-
await fs3.ensureDir(
|
|
91732
|
+
await fs3.ensureDir(dirname17(options.dbUrl));
|
|
90723
91733
|
}
|
|
90724
91734
|
let scheduler3;
|
|
90725
91735
|
if (bootConfig.scheduler.enabled) {
|
|
@@ -90862,7 +91872,7 @@ if (false) {}
|
|
|
90862
91872
|
|
|
90863
91873
|
// src/commands/serve.ts
|
|
90864
91874
|
function resolveServeDbUrl(cwd, env, configuredUrl) {
|
|
90865
|
-
return env.DATABASE_URL === undefined ?
|
|
91875
|
+
return env.DATABASE_URL === undefined ? join26(cwd, DEFAULT_DATABASE_URL) : configuredUrl;
|
|
90866
91876
|
}
|
|
90867
91877
|
function registerServeCommand(program2, context4) {
|
|
90868
91878
|
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) => {
|
|
@@ -90901,7 +91911,7 @@ function registerServeCommand(program2, context4) {
|
|
|
90901
91911
|
}
|
|
90902
91912
|
|
|
90903
91913
|
// src/commands/status.ts
|
|
90904
|
-
import { join as
|
|
91914
|
+
import { join as join27 } from "path";
|
|
90905
91915
|
|
|
90906
91916
|
// src/errors.ts
|
|
90907
91917
|
class CommandError extends Error {
|
|
@@ -90972,8 +91982,8 @@ function registerStatusCommand(program2, context4) {
|
|
|
90972
91982
|
}
|
|
90973
91983
|
async function runStatusCore(path9, options, context4) {
|
|
90974
91984
|
const [packageJsonExists, spurConfigExists, git, agentSpecs] = await Promise.all([
|
|
90975
|
-
context4.fs.exists(
|
|
90976
|
-
context4.fs.exists(
|
|
91985
|
+
context4.fs.exists(join27(context4.cwd, "package.json")),
|
|
91986
|
+
context4.fs.exists(join27(context4.cwd, ".spur", "config.yaml")),
|
|
90977
91987
|
gitContext(context4.cwd),
|
|
90978
91988
|
listAgentSpecIds(context4)
|
|
90979
91989
|
]);
|
|
@@ -91001,14 +92011,14 @@ async function runStatusCore(path9, options, context4) {
|
|
|
91001
92011
|
return status.ok ? 0 : 1;
|
|
91002
92012
|
}
|
|
91003
92013
|
async function listAgentSpecIds(context4) {
|
|
91004
|
-
const dir =
|
|
92014
|
+
const dir = join27(context4.cwd, ".spur", "agents");
|
|
91005
92015
|
if (!await context4.fs.exists(dir))
|
|
91006
92016
|
return [];
|
|
91007
92017
|
const entries = await context4.fs.readDir(dir);
|
|
91008
92018
|
return entries.filter((entry) => entry.endsWith(".yaml") || entry.endsWith(".yml")).map((entry) => entry.replace(/\.ya?ml$/, "")).sort();
|
|
91009
92019
|
}
|
|
91010
92020
|
async function readTargetStatus(context4, targetPath) {
|
|
91011
|
-
const resolved =
|
|
92021
|
+
const resolved = join27(context4.cwd, targetPath);
|
|
91012
92022
|
const stat = await context4.fs.stat(resolved);
|
|
91013
92023
|
if (stat === null)
|
|
91014
92024
|
throw new CommandError(`status failed: path does not exist at ${resolved}`);
|
|
@@ -91020,8 +92030,8 @@ init_src3();
|
|
|
91020
92030
|
init_loader();
|
|
91021
92031
|
init_src2();
|
|
91022
92032
|
init_dist5();
|
|
91023
|
-
import { existsSync as
|
|
91024
|
-
import { join as
|
|
92033
|
+
import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
|
|
92034
|
+
import { join as join28 } from "path";
|
|
91025
92035
|
// schemas/section-matrix.schema.json
|
|
91026
92036
|
var section_matrix_schema_default = {
|
|
91027
92037
|
$schema: "http://json-schema.org/draft-07/schema#",
|
|
@@ -91760,7 +92770,7 @@ ${result.content}`);
|
|
|
91760
92770
|
let forcedDoneVerdict;
|
|
91761
92771
|
if (status === "done") {
|
|
91762
92772
|
const current = await svc.show(wbs);
|
|
91763
|
-
const verdictDir = options.verdictDir ??
|
|
92773
|
+
const verdictDir = options.verdictDir ?? join28(context4.cwd, ".spur", "run");
|
|
91764
92774
|
const loaded = await readVerdictArtifact(context4.fs, verdictDir, wbs);
|
|
91765
92775
|
const guardOutcome = evaluateDoneTransition({
|
|
91766
92776
|
wbs,
|
|
@@ -92321,17 +93331,17 @@ function loadTemplateContent(projectRoot, variant) {
|
|
|
92321
93331
|
return templateContentCache.get(variant);
|
|
92322
93332
|
if (templateMissSet.has(variant))
|
|
92323
93333
|
return;
|
|
92324
|
-
const localPath =
|
|
92325
|
-
if (
|
|
92326
|
-
const content =
|
|
93334
|
+
const localPath = join28(projectRoot, ".spur", "tasks", "templates", `${variant}.md`);
|
|
93335
|
+
if (existsSync11(localPath)) {
|
|
93336
|
+
const content = readFileSync10(localPath, "utf8");
|
|
92327
93337
|
templateContentCache.set(variant, content);
|
|
92328
93338
|
return content;
|
|
92329
93339
|
}
|
|
92330
93340
|
const root = bundledConfigRoot();
|
|
92331
93341
|
if (root !== null) {
|
|
92332
|
-
const templatePath =
|
|
92333
|
-
if (
|
|
92334
|
-
const content =
|
|
93342
|
+
const templatePath = join28(root, "templates", "task", `${variant}.md`);
|
|
93343
|
+
if (existsSync11(templatePath)) {
|
|
93344
|
+
const content = readFileSync10(templatePath, "utf8");
|
|
92335
93345
|
templateContentCache.set(variant, content);
|
|
92336
93346
|
return content;
|
|
92337
93347
|
}
|
|
@@ -92345,15 +93355,15 @@ function loadTemplateBodies(projectRoot, variant) {
|
|
|
92345
93355
|
if (cached2 !== undefined)
|
|
92346
93356
|
return cached2;
|
|
92347
93357
|
let bodies = {};
|
|
92348
|
-
const localPath =
|
|
92349
|
-
if (
|
|
92350
|
-
bodies = extractTemplateBodies(
|
|
93358
|
+
const localPath = join28(projectRoot, ".spur", "tasks", "templates", `${variant}.md`);
|
|
93359
|
+
if (existsSync11(localPath)) {
|
|
93360
|
+
bodies = extractTemplateBodies(readFileSync10(localPath, "utf8"));
|
|
92351
93361
|
} else {
|
|
92352
93362
|
const root = bundledConfigRoot();
|
|
92353
93363
|
if (root !== null) {
|
|
92354
|
-
const templatePath =
|
|
92355
|
-
if (
|
|
92356
|
-
bodies = extractTemplateBodies(
|
|
93364
|
+
const templatePath = join28(root, "templates", "task", `${variant}.md`);
|
|
93365
|
+
if (existsSync11(templatePath)) {
|
|
93366
|
+
bodies = extractTemplateBodies(readFileSync10(templatePath, "utf8"));
|
|
92357
93367
|
}
|
|
92358
93368
|
}
|
|
92359
93369
|
}
|
|
@@ -92404,7 +93414,7 @@ async function loadSectionMatrixUncached(projectRoot) {
|
|
|
92404
93414
|
}
|
|
92405
93415
|
const root = bundledConfigRoot();
|
|
92406
93416
|
if (root !== null) {
|
|
92407
|
-
const matrixPath =
|
|
93417
|
+
const matrixPath = join28(root, "tasks", "section-matrix.yaml");
|
|
92408
93418
|
if (await fs3.exists(matrixPath)) {
|
|
92409
93419
|
const data = await loadStructuredSpurConfig(matrixPath, {
|
|
92410
93420
|
validateJsonSchema: true,
|
|
@@ -92689,7 +93699,7 @@ init_dist7();
|
|
|
92689
93699
|
init_dist6();
|
|
92690
93700
|
init_dist5();
|
|
92691
93701
|
import { closeSync as closeSync5, fstatSync as fstatSync3, openSync as openSync5, readSync as readSync3 } from "fs";
|
|
92692
|
-
import { join as
|
|
93702
|
+
import { join as join29, resolve as resolve9 } from "path";
|
|
92693
93703
|
import { createInterface } from "readline";
|
|
92694
93704
|
import { setTimeout as sleep3 } from "timers/promises";
|
|
92695
93705
|
function shQuote2(value2) {
|
|
@@ -92857,13 +93867,13 @@ Monitor with: spur workflow trace ${runId2} --follow`);
|
|
|
92857
93867
|
let planPreview;
|
|
92858
93868
|
if (options.plan !== false) {
|
|
92859
93869
|
try {
|
|
92860
|
-
const def = await loadWorkflowDef(
|
|
93870
|
+
const def = await loadWorkflowDef(resolve9(context4.cwd, file2), { validateSchema: false });
|
|
92861
93871
|
planPreview = renderRunPlan(def);
|
|
92862
93872
|
} catch {}
|
|
92863
93873
|
}
|
|
92864
93874
|
const runLog = options.log === false ? undefined : new WorkflowRunLogSink({
|
|
92865
93875
|
bus,
|
|
92866
|
-
dir:
|
|
93876
|
+
dir: join29(context4.cwd, ".spur", "run"),
|
|
92867
93877
|
runId,
|
|
92868
93878
|
...planPreview !== undefined ? { planPreview } : {},
|
|
92869
93879
|
...await resolveOutputLogConfig(context4.cwd)
|
|
@@ -93274,7 +94284,7 @@ function readRunLogChunk(logPath, offset) {
|
|
|
93274
94284
|
}
|
|
93275
94285
|
}
|
|
93276
94286
|
async function followRunLog(service, runId, dir, pollMs, write, wait = (ms) => sleep3(ms)) {
|
|
93277
|
-
const logPath =
|
|
94287
|
+
const logPath = join29(dir, ".spur", "run", `${runId}.log`);
|
|
93278
94288
|
let offset = 0;
|
|
93279
94289
|
let everRead = false;
|
|
93280
94290
|
while (true) {
|
|
@@ -93321,7 +94331,7 @@ init_src3();
|
|
|
93321
94331
|
init_src();
|
|
93322
94332
|
init_src2();
|
|
93323
94333
|
init_dist5();
|
|
93324
|
-
import { dirname as
|
|
94334
|
+
import { dirname as dirname18, join as join30, resolve as resolve10 } from "path";
|
|
93325
94335
|
import { isatty as isatty4 } from "tty";
|
|
93326
94336
|
|
|
93327
94337
|
// ../../node_modules/.bun/@clack+core@1.4.1/node_modules/@clack/core/dist/index.mjs
|
|
@@ -94704,7 +95714,7 @@ class DefaultHitlResponder {
|
|
|
94704
95714
|
|
|
94705
95715
|
// src/context.ts
|
|
94706
95716
|
function createCliContext(options) {
|
|
94707
|
-
const cwd =
|
|
95717
|
+
const cwd = resolve10(options.cwd ?? process.cwd());
|
|
94708
95718
|
const env = options.env ?? process.env;
|
|
94709
95719
|
const fs3 = createNodeFileSystem3(cwd);
|
|
94710
95720
|
let dbPromise;
|
|
@@ -94743,10 +95753,10 @@ function createCliContext(options) {
|
|
|
94743
95753
|
function noopSetExitCode(_code) {}
|
|
94744
95754
|
async function createMigratedDbAdapter(cwd = process.cwd(), env = process.env, dbUrl) {
|
|
94745
95755
|
const config4 = buildConfigFromEnv(env);
|
|
94746
|
-
const configuredUrl = env.DATABASE_URL === undefined ?
|
|
95756
|
+
const configuredUrl = env.DATABASE_URL === undefined ? join30(cwd, DEFAULT_DATABASE_URL) : config4.database.url;
|
|
94747
95757
|
const url2 = dbUrl ?? configuredUrl;
|
|
94748
95758
|
if (url2 !== IN_MEMORY_DATABASE_URL) {
|
|
94749
|
-
await createNodeFileSystem3().ensureDir(
|
|
95759
|
+
await createNodeFileSystem3().ensureDir(dirname18(url2));
|
|
94750
95760
|
}
|
|
94751
95761
|
return createMigratedDb({ url: url2 });
|
|
94752
95762
|
}
|