@gobing-ai/spur 0.3.9 → 0.3.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/rules/boundary/sp-runtime-path.yaml +4 -0
- package/package.json +1 -1
- package/spur.js +556 -99
- package/web/_astro/{BoardApp.DjpO2XHn.js → BoardApp.C6AZyK1W.js} +106 -105
- package/web/_astro/BoardApp.EXjc9f_0.js +1 -0
- package/web/_astro/{TaskDetail.DilpuD7R.js → TaskDetail.qCmrwQkG.js} +1 -1
- package/web/_astro/{arc.KcqIior8.js → arc.CbRppOdF.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.BTFU70BY.js → architectureDiagram-3BPJPVTR.9PfIcrsr.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.apx49Oy9.js → blockDiagram-GPEHLZMM.D8X1aH9F.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.BM-J4juX.js → c4Diagram-AAUBKEIU.BnAemEBs.js} +1 -1
- package/web/_astro/channel.DDlSVLNA.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.K6z7IYZU.js → chunk-2J33WTMH.DzOqcSmH.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.BDYhxKa0.js → chunk-4BX2VUAB.AqtW-DKu.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.BnNOxqnI.js → chunk-55IACEB6.BIRjE6jR.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.DNeg6N7v.js → chunk-727SXJPM.CgDzPlSk.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.BjILBkba.js → chunk-AQP2D5EJ.DjOW-ScW.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.DQ5UvvsV.js → chunk-FMBD7UC4.wdJmHym6.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.Yn1OvRJs.js → chunk-ND2GUHAM.C-Ho8u3p.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.UErqHgqw.js → chunk-QZHKN3VN.BF1HouUh.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.BmjVF7iZ.js → classDiagram-4FO5ZUOK.DAyOMMHn.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.BmjVF7iZ.js → classDiagram-v2-Q7XG4LA2.DAyOMMHn.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.iKBxnkbb.js → cose-bilkent-S5V4N54A.CNoutjqT.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.OwnCCrs6.js → dagre-BM42HDAG.yQbaJnir.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.DCdcffxE.js → diagram-2AECGRRQ.Y-0ZX0wP.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.Ai-LvmVW.js → diagram-5GNKFQAL.Co7hW1JF.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.B6e21QDN.js → diagram-KO2AKTUF.BW6g9zEB.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.oPfqy1fq.js → diagram-LMA3HP47.5laYcnBs.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.Dh5QRDCE.js → diagram-OG6HWLK6.DOXfn0B3.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.DpBiOcO3.js → erDiagram-TEJ5UH35.B65zPLW1.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.NbMxFlVk.js → flowDiagram-I6XJVG4X.EyV3nzyc.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.JgZ3fDME.js → ganttDiagram-6RSMTGT7.Dbg3JgqV.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.oMjFeZRt.js → gitGraphDiagram-PVQCEYII.C_h4o8Bn.js} +1 -1
- package/web/_astro/{index.CA3GTZM6.css → index.BSoQ0ZL0.css} +1 -1
- package/web/_astro/{infoDiagram-5YYISTIA.kaio3YzK.js → infoDiagram-5YYISTIA.DmMa9Qku.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.CXQfMyeF.js → ishikawaDiagram-YF4QCWOH.GWMrgoLC.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.AvNKMzx6.js → journeyDiagram-JHISSGLW.BWABlU6N.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.kv3cZGdE.js → kanban-definition-UN3LZRKU.MbfHFA2-.js} +1 -1
- package/web/_astro/{linear.CfLoHWjz.js → linear.BmIHCCO9.js} +1 -1
- package/web/_astro/{mermaid.core.BSV8pBn-.js → mermaid.core.CpHEEQAK.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.CbL_3b32.js → mindmap-definition-RKZ34NQL.DYK94Ave.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.5BXdOLRb.js → pieDiagram-4H26LBE5.CnEGAkqK.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.krXYbhlh.js → quadrantDiagram-W4KKPZXB.CsByTJjg.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.COO4LapZ.js → requirementDiagram-4Y6WPE33.AL6ZRSrQ.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.BvL0Jbdx.js → sankeyDiagram-5OEKKPKP.BLAeuWlE.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.Dk7Tu15E.js → sequenceDiagram-3UESZ5HK.BGpsvxUR.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.Cqh_KmEW.js → stateDiagram-AJRCARHV.BBk0gd25.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.WapPgDCy.js → stateDiagram-v2-BHNVJYJU.BrqvmSUS.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.CEVdiX0n.js → timeline-definition-PNZ67QCA.DkZf5CQT.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.Cd9A63eF.js → vennDiagram-CIIHVFJN.BZvWwMZF.js} +1 -1
- package/web/_astro/{wardley-L42UT6IY.DEiaHiIT.js → wardley-L42UT6IY.HfB08mt3.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.B7nGP61E.js → wardleyDiagram-YWT4CUSO.DgpZzmgA.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.Bq8CHmxC.js → xychartDiagram-2RQKCTM6.BlgrPsbQ.js} +1 -1
- package/web/index.html +2 -2
- package/web/_astro/BoardApp.Bcfvp2GH.js +0 -1
- package/web/_astro/channel.vSp82e1U.js +0 -1
package/spur.js
CHANGED
|
@@ -60765,6 +60765,41 @@ var init_system_event_tap = __esm(() => {
|
|
|
60765
60765
|
init_event_names();
|
|
60766
60766
|
});
|
|
60767
60767
|
|
|
60768
|
+
// ../../packages/app/src/services/system-event-emitter.ts
|
|
60769
|
+
class SystemEventEmitter {
|
|
60770
|
+
dao;
|
|
60771
|
+
logger;
|
|
60772
|
+
constructor(dao2, logger3) {
|
|
60773
|
+
this.dao = dao2;
|
|
60774
|
+
this.logger = logger3;
|
|
60775
|
+
}
|
|
60776
|
+
async emit(event2) {
|
|
60777
|
+
const entry = systemEventCatalogEntry(event2.event);
|
|
60778
|
+
if (!entry)
|
|
60779
|
+
return;
|
|
60780
|
+
try {
|
|
60781
|
+
await this.dao.insert({
|
|
60782
|
+
id: createId("sev"),
|
|
60783
|
+
event_name: entry.name,
|
|
60784
|
+
occurred_at: event2.at,
|
|
60785
|
+
actor: extractSystemEventActor(event2),
|
|
60786
|
+
payload_json: safeStringify(normalizeSystemEventPayload(entry, event2))
|
|
60787
|
+
});
|
|
60788
|
+
await this.dao.prune(SYSTEM_EVENTS_CAP);
|
|
60789
|
+
} catch (error51) {
|
|
60790
|
+
this.logger.warn("system_events emitter: persist failed", {
|
|
60791
|
+
event: event2.event,
|
|
60792
|
+
error: error51 instanceof Error ? `${error51.name}: ${error51.message}` : String(error51)
|
|
60793
|
+
});
|
|
60794
|
+
}
|
|
60795
|
+
}
|
|
60796
|
+
}
|
|
60797
|
+
var init_system_event_emitter = __esm(() => {
|
|
60798
|
+
init_src2();
|
|
60799
|
+
init_event_names();
|
|
60800
|
+
init_system_event_tap();
|
|
60801
|
+
});
|
|
60802
|
+
|
|
60768
60803
|
// ../../packages/app/src/services/task-check.ts
|
|
60769
60804
|
import { dirname as dirname9, join as join9 } from "path";
|
|
60770
60805
|
function isPlaceholderBody(body) {
|
|
@@ -62482,11 +62517,282 @@ var init_team_service = __esm(() => {
|
|
|
62482
62517
|
init_planning_folders();
|
|
62483
62518
|
});
|
|
62484
62519
|
|
|
62520
|
+
// ../../packages/app/src/services/token-ledger-service.ts
|
|
62521
|
+
import { closeSync as closeSync2, existsSync as existsSync5, fstatSync, openSync as openSync2, readSync } from "fs";
|
|
62522
|
+
import { join as join11 } from "path";
|
|
62523
|
+
function isSparseToolActivity(events2) {
|
|
62524
|
+
return events2.length === 0 || !events2.some((e) => TOOL_ACTIVITY_TYPES.has(e.type));
|
|
62525
|
+
}
|
|
62526
|
+
function clampToolUseLimit(raw) {
|
|
62527
|
+
if (raw === undefined || !Number.isFinite(raw) || raw <= 0) {
|
|
62528
|
+
return TOKEN_LEDGER_DEFAULT_LIMIT;
|
|
62529
|
+
}
|
|
62530
|
+
return Math.min(Math.floor(raw), TOKEN_LEDGER_MAX_LIMIT);
|
|
62531
|
+
}
|
|
62532
|
+
function parseLedgerLine(line) {
|
|
62533
|
+
const trimmed = line.trim();
|
|
62534
|
+
if (!trimmed)
|
|
62535
|
+
return null;
|
|
62536
|
+
try {
|
|
62537
|
+
const obj = JSON.parse(trimmed);
|
|
62538
|
+
if (typeof obj.ts !== "string" || typeof obj.session !== "string" || typeof obj.type !== "string") {
|
|
62539
|
+
return null;
|
|
62540
|
+
}
|
|
62541
|
+
const event2 = {
|
|
62542
|
+
ts: obj.ts,
|
|
62543
|
+
session: obj.session,
|
|
62544
|
+
type: obj.type
|
|
62545
|
+
};
|
|
62546
|
+
if (typeof obj.file === "string")
|
|
62547
|
+
event2.file = obj.file;
|
|
62548
|
+
if (typeof obj.summary === "string")
|
|
62549
|
+
event2.summary = obj.summary;
|
|
62550
|
+
if (typeof obj.tokens === "number" && Number.isFinite(obj.tokens) && obj.tokens >= 0) {
|
|
62551
|
+
event2.tokens = obj.tokens;
|
|
62552
|
+
}
|
|
62553
|
+
if (typeof obj.action === "string")
|
|
62554
|
+
event2.action = obj.action;
|
|
62555
|
+
if (typeof obj.sessionId === "string")
|
|
62556
|
+
event2.sessionId = obj.sessionId;
|
|
62557
|
+
if (typeof obj.agent === "string")
|
|
62558
|
+
event2.agent = obj.agent;
|
|
62559
|
+
if (typeof obj.model === "string")
|
|
62560
|
+
event2.model = obj.model;
|
|
62561
|
+
if (obj.totals !== null && typeof obj.totals === "object") {
|
|
62562
|
+
const t = obj.totals;
|
|
62563
|
+
if (typeof t.reads === "number" && typeof t.writes === "number" && typeof t.tokens === "number") {
|
|
62564
|
+
event2.totals = { reads: t.reads, writes: t.writes, tokens: t.tokens };
|
|
62565
|
+
}
|
|
62566
|
+
}
|
|
62567
|
+
return event2;
|
|
62568
|
+
} catch {
|
|
62569
|
+
return null;
|
|
62570
|
+
}
|
|
62571
|
+
}
|
|
62572
|
+
function tailTokenLedgerFile(filePath, limit, chunkSize = DEFAULT_CHUNK, before) {
|
|
62573
|
+
if (!existsSync5(filePath)) {
|
|
62574
|
+
return { events: [], truncated: false };
|
|
62575
|
+
}
|
|
62576
|
+
const target = limit + 1;
|
|
62577
|
+
const fd = openSync2(filePath, "r");
|
|
62578
|
+
try {
|
|
62579
|
+
const { size } = fstatSync(fd);
|
|
62580
|
+
if (size === 0)
|
|
62581
|
+
return { events: [], truncated: false };
|
|
62582
|
+
let pos = size;
|
|
62583
|
+
let carry = "";
|
|
62584
|
+
const events2 = [];
|
|
62585
|
+
while (pos > 0 && events2.length < target) {
|
|
62586
|
+
const n2 = Math.min(chunkSize, pos);
|
|
62587
|
+
pos -= n2;
|
|
62588
|
+
const buf = Buffer.alloc(n2);
|
|
62589
|
+
readSync(fd, buf, 0, n2, pos);
|
|
62590
|
+
const text4 = buf.toString("utf8") + carry;
|
|
62591
|
+
const parts = text4.split(`
|
|
62592
|
+
`);
|
|
62593
|
+
if (pos > 0) {
|
|
62594
|
+
carry = parts.shift() ?? "";
|
|
62595
|
+
} else {
|
|
62596
|
+
carry = "";
|
|
62597
|
+
}
|
|
62598
|
+
for (let i2 = parts.length - 1;i2 >= 0; i2--) {
|
|
62599
|
+
const evt = parseLedgerLine(parts[i2] ?? "");
|
|
62600
|
+
if (!evt)
|
|
62601
|
+
continue;
|
|
62602
|
+
if (before !== undefined && evt.ts >= before)
|
|
62603
|
+
continue;
|
|
62604
|
+
events2.push(evt);
|
|
62605
|
+
if (events2.length >= target)
|
|
62606
|
+
break;
|
|
62607
|
+
}
|
|
62608
|
+
}
|
|
62609
|
+
const truncated = events2.length > limit;
|
|
62610
|
+
return {
|
|
62611
|
+
events: events2.slice(0, limit),
|
|
62612
|
+
truncated
|
|
62613
|
+
};
|
|
62614
|
+
} finally {
|
|
62615
|
+
closeSync2(fd);
|
|
62616
|
+
}
|
|
62617
|
+
}
|
|
62618
|
+
|
|
62619
|
+
class TokenLedgerService {
|
|
62620
|
+
ledgerPath;
|
|
62621
|
+
chunkSize;
|
|
62622
|
+
constructor(options) {
|
|
62623
|
+
this.ledgerPath = options.ledgerPath ?? join11(options.cwd, TOKEN_LEDGER_RELATIVE_PATH);
|
|
62624
|
+
this.chunkSize = options.chunkSize ?? DEFAULT_CHUNK;
|
|
62625
|
+
}
|
|
62626
|
+
get path() {
|
|
62627
|
+
return this.ledgerPath;
|
|
62628
|
+
}
|
|
62629
|
+
snapshot(limitRawOrOpts, maybeBefore) {
|
|
62630
|
+
let limitRaw;
|
|
62631
|
+
let before;
|
|
62632
|
+
if (typeof limitRawOrOpts === "object" && limitRawOrOpts !== null) {
|
|
62633
|
+
limitRaw = limitRawOrOpts.limit;
|
|
62634
|
+
before = limitRawOrOpts.before;
|
|
62635
|
+
} else {
|
|
62636
|
+
limitRaw = limitRawOrOpts;
|
|
62637
|
+
before = maybeBefore;
|
|
62638
|
+
}
|
|
62639
|
+
if (before !== undefined && (typeof before !== "string" || before.length === 0)) {
|
|
62640
|
+
before = undefined;
|
|
62641
|
+
}
|
|
62642
|
+
const limit = clampToolUseLimit(limitRaw);
|
|
62643
|
+
const capturedAt = new Date().toISOString();
|
|
62644
|
+
const { events: raw, truncated } = tailTokenLedgerFile(this.ledgerPath, limit, this.chunkSize, before);
|
|
62645
|
+
const events2 = raw.map((e, seq) => ({ ...e, seq }));
|
|
62646
|
+
const sparseToolActivity = isSparseToolActivity(events2);
|
|
62647
|
+
const oldest = events2.length > 0 ? events2[events2.length - 1] : undefined;
|
|
62648
|
+
const nextBefore = truncated && oldest ? oldest.ts : null;
|
|
62649
|
+
return {
|
|
62650
|
+
events: events2,
|
|
62651
|
+
count: events2.length,
|
|
62652
|
+
limit,
|
|
62653
|
+
truncated,
|
|
62654
|
+
path: this.ledgerPath,
|
|
62655
|
+
capturedAt,
|
|
62656
|
+
sparseToolActivity,
|
|
62657
|
+
nextBefore
|
|
62658
|
+
};
|
|
62659
|
+
}
|
|
62660
|
+
}
|
|
62661
|
+
var TOOL_ACTIVITY_TYPES, TOKEN_LEDGER_DEFAULT_LIMIT = 200, TOKEN_LEDGER_MAX_LIMIT = 1000, TOKEN_LEDGER_RELATIVE_PATH, DEFAULT_CHUNK;
|
|
62662
|
+
var init_token_ledger_service = __esm(() => {
|
|
62663
|
+
TOOL_ACTIVITY_TYPES = new Set(["read", "write", "bash", "grep", "glob"]);
|
|
62664
|
+
TOKEN_LEDGER_RELATIVE_PATH = join11(".spur", "context", "token-ledger.jsonl");
|
|
62665
|
+
DEFAULT_CHUNK = 64 * 1024;
|
|
62666
|
+
});
|
|
62667
|
+
|
|
62668
|
+
// ../../packages/app/src/services/token-ledger-watcher.ts
|
|
62669
|
+
import { closeSync as closeSync3, existsSync as existsSync6, fstatSync as fstatSync2, openSync as openSync3, readSync as readSync2, watch } from "fs";
|
|
62670
|
+
|
|
62671
|
+
class TokenLedgerWatcher {
|
|
62672
|
+
ledgerPath;
|
|
62673
|
+
debounceMs;
|
|
62674
|
+
listeners = new Set;
|
|
62675
|
+
watcher;
|
|
62676
|
+
offset = 0;
|
|
62677
|
+
debounceTimer;
|
|
62678
|
+
started = false;
|
|
62679
|
+
carry = "";
|
|
62680
|
+
constructor(options) {
|
|
62681
|
+
this.ledgerPath = options.ledgerPath;
|
|
62682
|
+
this.debounceMs = options.debounceMs ?? 50;
|
|
62683
|
+
}
|
|
62684
|
+
start() {
|
|
62685
|
+
if (this.started)
|
|
62686
|
+
return;
|
|
62687
|
+
this.started = true;
|
|
62688
|
+
this.offset = this.currentSize();
|
|
62689
|
+
try {
|
|
62690
|
+
const target = existsSync6(this.ledgerPath) ? this.ledgerPath : this.parentDir();
|
|
62691
|
+
this.watcher = watch(target, () => this.schedulePoll());
|
|
62692
|
+
} catch {
|
|
62693
|
+
this.watcher = undefined;
|
|
62694
|
+
}
|
|
62695
|
+
}
|
|
62696
|
+
stop() {
|
|
62697
|
+
this.started = false;
|
|
62698
|
+
if (this.debounceTimer)
|
|
62699
|
+
clearTimeout(this.debounceTimer);
|
|
62700
|
+
this.debounceTimer = undefined;
|
|
62701
|
+
try {
|
|
62702
|
+
this.watcher?.close();
|
|
62703
|
+
} catch {}
|
|
62704
|
+
this.watcher = undefined;
|
|
62705
|
+
this.listeners.clear();
|
|
62706
|
+
}
|
|
62707
|
+
subscribe(listener) {
|
|
62708
|
+
this.listeners.add(listener);
|
|
62709
|
+
if (!this.started)
|
|
62710
|
+
this.start();
|
|
62711
|
+
return () => {
|
|
62712
|
+
this.listeners.delete(listener);
|
|
62713
|
+
if (this.listeners.size === 0)
|
|
62714
|
+
this.stop();
|
|
62715
|
+
};
|
|
62716
|
+
}
|
|
62717
|
+
get subscriberCount() {
|
|
62718
|
+
return this.listeners.size;
|
|
62719
|
+
}
|
|
62720
|
+
parentDir() {
|
|
62721
|
+
const idx = Math.max(this.ledgerPath.lastIndexOf("/"), this.ledgerPath.lastIndexOf("\\"));
|
|
62722
|
+
return idx > 0 ? this.ledgerPath.slice(0, idx) : ".";
|
|
62723
|
+
}
|
|
62724
|
+
currentSize() {
|
|
62725
|
+
if (!existsSync6(this.ledgerPath))
|
|
62726
|
+
return 0;
|
|
62727
|
+
try {
|
|
62728
|
+
const fd = openSync3(this.ledgerPath, "r");
|
|
62729
|
+
try {
|
|
62730
|
+
return fstatSync2(fd).size;
|
|
62731
|
+
} finally {
|
|
62732
|
+
closeSync3(fd);
|
|
62733
|
+
}
|
|
62734
|
+
} catch {
|
|
62735
|
+
return 0;
|
|
62736
|
+
}
|
|
62737
|
+
}
|
|
62738
|
+
schedulePoll() {
|
|
62739
|
+
if (this.debounceTimer)
|
|
62740
|
+
clearTimeout(this.debounceTimer);
|
|
62741
|
+
this.debounceTimer = setTimeout(() => {
|
|
62742
|
+
this.debounceTimer = undefined;
|
|
62743
|
+
this.pollNewBytes();
|
|
62744
|
+
}, this.debounceMs);
|
|
62745
|
+
}
|
|
62746
|
+
pollNewBytes() {
|
|
62747
|
+
if (!existsSync6(this.ledgerPath)) {
|
|
62748
|
+
this.offset = 0;
|
|
62749
|
+
this.carry = "";
|
|
62750
|
+
return;
|
|
62751
|
+
}
|
|
62752
|
+
let size;
|
|
62753
|
+
try {
|
|
62754
|
+
const fd = openSync3(this.ledgerPath, "r");
|
|
62755
|
+
try {
|
|
62756
|
+
size = fstatSync2(fd).size;
|
|
62757
|
+
if (size < this.offset) {
|
|
62758
|
+
this.offset = 0;
|
|
62759
|
+
this.carry = "";
|
|
62760
|
+
}
|
|
62761
|
+
if (size === this.offset)
|
|
62762
|
+
return;
|
|
62763
|
+
const len = size - this.offset;
|
|
62764
|
+
const buf = Buffer.alloc(len);
|
|
62765
|
+
readSync2(fd, buf, 0, len, this.offset);
|
|
62766
|
+
this.offset = size;
|
|
62767
|
+
const text4 = this.carry + buf.toString("utf8");
|
|
62768
|
+
const parts = text4.split(`
|
|
62769
|
+
`);
|
|
62770
|
+
this.carry = parts.pop() ?? "";
|
|
62771
|
+
for (const line of parts) {
|
|
62772
|
+
const evt = parseLedgerLine(line);
|
|
62773
|
+
if (!evt)
|
|
62774
|
+
continue;
|
|
62775
|
+
for (const listener of this.listeners) {
|
|
62776
|
+
try {
|
|
62777
|
+
listener(evt);
|
|
62778
|
+
} catch {}
|
|
62779
|
+
}
|
|
62780
|
+
}
|
|
62781
|
+
} finally {
|
|
62782
|
+
closeSync3(fd);
|
|
62783
|
+
}
|
|
62784
|
+
} catch {}
|
|
62785
|
+
}
|
|
62786
|
+
}
|
|
62787
|
+
var init_token_ledger_watcher = __esm(() => {
|
|
62788
|
+
init_token_ledger_service();
|
|
62789
|
+
});
|
|
62790
|
+
|
|
62485
62791
|
// ../../packages/app/src/workflow/actions/agent-run.ts
|
|
62486
62792
|
import { execFile } from "child_process";
|
|
62487
|
-
import { existsSync as
|
|
62793
|
+
import { existsSync as existsSync7 } from "fs";
|
|
62488
62794
|
import { mkdir, writeFile } from "fs/promises";
|
|
62489
|
-
import { dirname as dirname10, isAbsolute as isAbsolute2, join as
|
|
62795
|
+
import { dirname as dirname10, isAbsolute as isAbsolute2, join as join12 } from "path";
|
|
62490
62796
|
import { promisify as promisify3 } from "util";
|
|
62491
62797
|
|
|
62492
62798
|
class AgentRunActionRunner {
|
|
@@ -62540,13 +62846,13 @@ class AgentRunActionRunner {
|
|
|
62540
62846
|
const { exitCode: exitCode2, answer } = captured;
|
|
62541
62847
|
const ok2 = exitCode2 === 0;
|
|
62542
62848
|
if (answerFile !== undefined) {
|
|
62543
|
-
const target = isAbsolute2(answerFile) ? answerFile :
|
|
62849
|
+
const target = isAbsolute2(answerFile) ? answerFile : join12(cwd, answerFile);
|
|
62544
62850
|
await mkdir(dirname10(target), { recursive: true });
|
|
62545
62851
|
await writeFile(target, answer, "utf8");
|
|
62546
62852
|
}
|
|
62547
62853
|
if (ok2 && expectFile !== undefined) {
|
|
62548
|
-
const target = isAbsolute2(expectFile) ? expectFile :
|
|
62549
|
-
if (!
|
|
62854
|
+
const target = isAbsolute2(expectFile) ? expectFile : join12(cwd, expectFile);
|
|
62855
|
+
if (!existsSync7(target)) {
|
|
62550
62856
|
return {
|
|
62551
62857
|
ok: false,
|
|
62552
62858
|
data: { exitCode: exitCode2, agent: agentLabel, answer },
|
|
@@ -62567,8 +62873,8 @@ class AgentRunActionRunner {
|
|
|
62567
62873
|
const exitCode = await this.agentService.run(input, flags);
|
|
62568
62874
|
const ok = exitCode === 0;
|
|
62569
62875
|
if (ok && expectFile !== undefined) {
|
|
62570
|
-
const target = isAbsolute2(expectFile) ? expectFile :
|
|
62571
|
-
if (!
|
|
62876
|
+
const target = isAbsolute2(expectFile) ? expectFile : join12(cwd, expectFile);
|
|
62877
|
+
if (!existsSync7(target)) {
|
|
62572
62878
|
return {
|
|
62573
62879
|
ok: false,
|
|
62574
62880
|
data: { exitCode, agent: agentLabel },
|
|
@@ -62645,7 +62951,7 @@ async function writePartialWorkArtifact(context4, agentLabel, model, captured, c
|
|
|
62645
62951
|
""
|
|
62646
62952
|
].join(`
|
|
62647
62953
|
`);
|
|
62648
|
-
const target =
|
|
62954
|
+
const target = join12(cwd, ".spur", "run", `${context4.runId}-${context4.stateOrNodeId}-partial.md`);
|
|
62649
62955
|
await mkdir(dirname10(target), { recursive: true });
|
|
62650
62956
|
await writeFile(target, body, "utf8");
|
|
62651
62957
|
} catch {}
|
|
@@ -63309,7 +63615,7 @@ var now = () => new Date().toISOString();
|
|
|
63309
63615
|
// ../../packages/app/src/services/workflow-service.ts
|
|
63310
63616
|
import { access as access2, lstat, readdir as readdir3, readFile as readFile2, realpath } from "fs/promises";
|
|
63311
63617
|
import { homedir as homedir3 } from "os";
|
|
63312
|
-
import { join as
|
|
63618
|
+
import { join as join13, resolve as resolve3 } from "path";
|
|
63313
63619
|
function signalSubprocess(pid) {
|
|
63314
63620
|
try {
|
|
63315
63621
|
process.kill(-pid, "SIGTERM");
|
|
@@ -63513,7 +63819,7 @@ class WorkflowAppService {
|
|
|
63513
63819
|
}
|
|
63514
63820
|
async list(workflowPaths = [".spur/workflows/"]) {
|
|
63515
63821
|
const projectRoot = this.ctx.cwd;
|
|
63516
|
-
const globalRoot =
|
|
63822
|
+
const globalRoot = join13(homedir3(), ".config", "spur");
|
|
63517
63823
|
const layers = [];
|
|
63518
63824
|
const entries = [];
|
|
63519
63825
|
const scannedPaths = new Set;
|
|
@@ -63849,6 +64155,7 @@ var isActionStarted = (e) => ("kind" in e) && ("node" in e), isActionFinished =
|
|
|
63849
64155
|
// ../../packages/app/src/index.ts
|
|
63850
64156
|
var exports_src2 = {};
|
|
63851
64157
|
__export(exports_src2, {
|
|
64158
|
+
tailTokenLedgerFile: () => tailTokenLedgerFile,
|
|
63852
64159
|
systemEventCatalogEntry: () => systemEventCatalogEntry,
|
|
63853
64160
|
resolvePlanningFolders: () => resolvePlanningFolders,
|
|
63854
64161
|
renderTesting: () => renderTesting,
|
|
@@ -63861,6 +64168,7 @@ __export(exports_src2, {
|
|
|
63861
64168
|
readVerdict: () => readVerdict,
|
|
63862
64169
|
parseVerdict: () => parseVerdict,
|
|
63863
64170
|
parsePsOutput: () => parsePsOutput,
|
|
64171
|
+
parseLedgerLine: () => parseLedgerLine,
|
|
63864
64172
|
parseEtimeToSeconds: () => parseEtimeToSeconds,
|
|
63865
64173
|
normalizeSystemEventPayload: () => normalizeSystemEventPayload,
|
|
63866
64174
|
hitlConfirmDefault: () => hitlConfirmDefault,
|
|
@@ -63868,14 +64176,21 @@ __export(exports_src2, {
|
|
|
63868
64176
|
extractSystemEventActor: () => extractSystemEventActor,
|
|
63869
64177
|
deriveVerdict: () => deriveVerdict,
|
|
63870
64178
|
createPsProcessInspector: () => createPsProcessInspector,
|
|
64179
|
+
clampToolUseLimit: () => clampToolUseLimit,
|
|
63871
64180
|
bridgeEventBus: () => bridgeEventBus,
|
|
63872
64181
|
WorkflowAppService: () => WorkflowAppService,
|
|
63873
64182
|
UnsupportedProcessPlatformError: () => UnsupportedProcessPlatformError,
|
|
64183
|
+
TokenLedgerWatcher: () => TokenLedgerWatcher,
|
|
64184
|
+
TokenLedgerService: () => TokenLedgerService,
|
|
63874
64185
|
TeamService: () => TeamService,
|
|
63875
64186
|
TaskService: () => TaskService,
|
|
63876
64187
|
TaskCheckService: () => TaskCheckService,
|
|
64188
|
+
TOKEN_LEDGER_RELATIVE_PATH: () => TOKEN_LEDGER_RELATIVE_PATH,
|
|
64189
|
+
TOKEN_LEDGER_MAX_LIMIT: () => TOKEN_LEDGER_MAX_LIMIT,
|
|
64190
|
+
TOKEN_LEDGER_DEFAULT_LIMIT: () => TOKEN_LEDGER_DEFAULT_LIMIT,
|
|
63877
64191
|
TASK_LIFECYCLE_PROFILE: () => TASK_LIFECYCLE_PROFILE,
|
|
63878
64192
|
TASK_ACTION_COMMANDS: () => TASK_ACTION_COMMANDS,
|
|
64193
|
+
SystemEventEmitter: () => SystemEventEmitter,
|
|
63879
64194
|
SupervisorService: () => SupervisorService,
|
|
63880
64195
|
SYSTEM_EVENT_STREAMED_NAMES: () => SYSTEM_EVENT_STREAMED_NAMES,
|
|
63881
64196
|
SYSTEM_EVENT_PREFIXES: () => SYSTEM_EVENT_PREFIXES,
|
|
@@ -63927,11 +64242,14 @@ var init_src3 = __esm(() => {
|
|
|
63927
64242
|
init_process_inspector();
|
|
63928
64243
|
init_process_inventory_service();
|
|
63929
64244
|
init_rule_service();
|
|
64245
|
+
init_system_event_emitter();
|
|
63930
64246
|
init_system_event_tap();
|
|
63931
64247
|
init_task_check();
|
|
63932
64248
|
init_task_record();
|
|
63933
64249
|
init_task_service();
|
|
63934
64250
|
init_team_service();
|
|
64251
|
+
init_token_ledger_service();
|
|
64252
|
+
init_token_ledger_watcher();
|
|
63935
64253
|
init_workflow_service();
|
|
63936
64254
|
init_agent_run();
|
|
63937
64255
|
init_file_exists();
|
|
@@ -71378,13 +71696,38 @@ ${prompt}`;
|
|
|
71378
71696
|
// src/commands/feature.ts
|
|
71379
71697
|
init_src3();
|
|
71380
71698
|
|
|
71699
|
+
// src/planning-emitter.ts
|
|
71700
|
+
init_src3();
|
|
71701
|
+
init_src2();
|
|
71702
|
+
function makeWarnLogger(context4) {
|
|
71703
|
+
return {
|
|
71704
|
+
warn: (msg, data) => {
|
|
71705
|
+
context4.output.error(`${msg}${data ? ` ${JSON.stringify(data)}` : ""}`);
|
|
71706
|
+
}
|
|
71707
|
+
};
|
|
71708
|
+
}
|
|
71709
|
+
function makePlanningEmitter(context4) {
|
|
71710
|
+
let cached2;
|
|
71711
|
+
const logger3 = makeWarnLogger(context4);
|
|
71712
|
+
return {
|
|
71713
|
+
async emit(event2) {
|
|
71714
|
+
try {
|
|
71715
|
+
cached2 ??= new SystemEventEmitter(new SystemEventDao(await context4.getDb()), logger3);
|
|
71716
|
+
await cached2.emit(event2);
|
|
71717
|
+
} catch (error51) {
|
|
71718
|
+
context4.output.error(`system_events emitter: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
71719
|
+
}
|
|
71720
|
+
}
|
|
71721
|
+
};
|
|
71722
|
+
}
|
|
71723
|
+
|
|
71381
71724
|
// src/workflow/make-lifecycle-adapter.ts
|
|
71382
71725
|
init_src3();
|
|
71383
71726
|
init_loader();
|
|
71384
71727
|
init_src2();
|
|
71385
|
-
import { existsSync as
|
|
71728
|
+
import { existsSync as existsSync8 } from "fs";
|
|
71386
71729
|
import { homedir as homedir4 } from "os";
|
|
71387
|
-
import { join as
|
|
71730
|
+
import { join as join14, resolve as resolve4 } from "path";
|
|
71388
71731
|
|
|
71389
71732
|
// src/workflow/resolve-spur-bin.ts
|
|
71390
71733
|
import { basename as basename2 } from "path";
|
|
@@ -71402,23 +71745,23 @@ function resolveSpurBin() {
|
|
|
71402
71745
|
}
|
|
71403
71746
|
|
|
71404
71747
|
// src/workflow/make-lifecycle-adapter.ts
|
|
71405
|
-
var GLOBAL_CONFIG_DIR =
|
|
71748
|
+
var GLOBAL_CONFIG_DIR = join14(".config", "spur");
|
|
71406
71749
|
function globalConfigRoot(context4) {
|
|
71407
71750
|
const override = context4.env.SPUR_GLOBAL_RULES_DIR;
|
|
71408
|
-
return override !== undefined && override.length > 0 ? resolve4(context4.cwd, override) :
|
|
71751
|
+
return override !== undefined && override.length > 0 ? resolve4(context4.cwd, override) : join14(homedir4(), GLOBAL_CONFIG_DIR);
|
|
71409
71752
|
}
|
|
71410
71753
|
function resolveWorkflowPath(context4, profile) {
|
|
71411
71754
|
const bundledRoot = bundledConfigRoot();
|
|
71412
71755
|
if (bundledRoot !== null) {
|
|
71413
|
-
const bundledPath =
|
|
71414
|
-
if (
|
|
71756
|
+
const bundledPath = join14(bundledRoot, "workflows", `${profile.workflowName}.yaml`);
|
|
71757
|
+
if (existsSync8(bundledPath))
|
|
71415
71758
|
return bundledPath;
|
|
71416
71759
|
}
|
|
71417
|
-
const projectPath =
|
|
71418
|
-
if (
|
|
71760
|
+
const projectPath = join14(context4.cwd, ".spur", "workflows", `${profile.workflowName}.yaml`);
|
|
71761
|
+
if (existsSync8(projectPath))
|
|
71419
71762
|
return projectPath;
|
|
71420
|
-
const globalPath =
|
|
71421
|
-
if (
|
|
71763
|
+
const globalPath = join14(globalConfigRoot(context4), "workflows", `${profile.workflowName}.yaml`);
|
|
71764
|
+
if (existsSync8(globalPath))
|
|
71422
71765
|
return globalPath;
|
|
71423
71766
|
return null;
|
|
71424
71767
|
}
|
|
@@ -71701,7 +72044,8 @@ async function makeService(context4, folderOverride) {
|
|
|
71701
72044
|
const lifecycle = makeLifecycleAdapter(context4, FEATURE_LIFECYCLE_PROFILE);
|
|
71702
72045
|
const writeService = new PlanningWriteService({
|
|
71703
72046
|
fs: context4.fs,
|
|
71704
|
-
...lifecycle ? { lifecycle } : {}
|
|
72047
|
+
...lifecycle ? { lifecycle } : {},
|
|
72048
|
+
emitter: makePlanningEmitter(context4)
|
|
71705
72049
|
});
|
|
71706
72050
|
return new FeatureService({ fs: context4.fs, writeService, featuresDir, tasksDir });
|
|
71707
72051
|
}
|
|
@@ -71771,13 +72115,13 @@ init_loader();
|
|
|
71771
72115
|
init_src2();
|
|
71772
72116
|
init_dist10();
|
|
71773
72117
|
import { homedir as homedir5 } from "os";
|
|
71774
|
-
import { join as
|
|
72118
|
+
import { join as join15, resolve as resolve5 } from "path";
|
|
71775
72119
|
|
|
71776
72120
|
// src/config.ts
|
|
71777
72121
|
var CLI_CONFIG = {
|
|
71778
72122
|
binaryName: "spur",
|
|
71779
72123
|
binaryLabel: "spur",
|
|
71780
|
-
binaryVersion: "0.3.
|
|
72124
|
+
binaryVersion: "0.3.10",
|
|
71781
72125
|
configDir: ".spur",
|
|
71782
72126
|
configFile: ".spur/config.yaml",
|
|
71783
72127
|
databaseFile: ".spur/spur.db"
|
|
@@ -71828,8 +72172,8 @@ var SCAFFOLD_MANIFEST = [
|
|
|
71828
72172
|
];
|
|
71829
72173
|
|
|
71830
72174
|
// src/commands/init.ts
|
|
71831
|
-
var GLOBAL_CONFIG_DIR2 =
|
|
71832
|
-
var GLOBAL_RULES_DIR2 =
|
|
72175
|
+
var GLOBAL_CONFIG_DIR2 = join15(".config", "spur");
|
|
72176
|
+
var GLOBAL_RULES_DIR2 = join15(GLOBAL_CONFIG_DIR2, "rules");
|
|
71833
72177
|
var GLOBAL_CONFIG_EXAMPLE = "config.example.yaml";
|
|
71834
72178
|
var GLOBAL_CONFIG_FILE2 = "config.yaml";
|
|
71835
72179
|
var INDEXED_CONTEXT_MARKER = "## Indexed context";
|
|
@@ -71856,7 +72200,7 @@ If \`.spur/context/\` is absent, proceed normally. Never block work on its absen
|
|
|
71856
72200
|
`;
|
|
71857
72201
|
function globalRulesRoot(context4) {
|
|
71858
72202
|
const override = context4.env.SPUR_GLOBAL_RULES_DIR;
|
|
71859
|
-
return override !== undefined && override.length > 0 ? resolve5(context4.cwd, override) :
|
|
72203
|
+
return override !== undefined && override.length > 0 ? resolve5(context4.cwd, override) : join15(homedir5(), GLOBAL_RULES_DIR2);
|
|
71860
72204
|
}
|
|
71861
72205
|
async function writeIfNew(context4, path9, content, force, result) {
|
|
71862
72206
|
if (!force && await context4.fs.exists(path9)) {
|
|
@@ -71873,11 +72217,11 @@ async function seedGlobalRules(context4) {
|
|
|
71873
72217
|
const target = globalRulesRoot(context4);
|
|
71874
72218
|
let written = 0;
|
|
71875
72219
|
for (const relPath of await listBundledRuleFiles()) {
|
|
71876
|
-
const destination =
|
|
72220
|
+
const destination = join15(target, relPath);
|
|
71877
72221
|
if (await context4.fs.exists(destination))
|
|
71878
72222
|
continue;
|
|
71879
|
-
await context4.fs.ensureDir(
|
|
71880
|
-
await context4.fs.writeFile(destination, await context4.fs.readFile(
|
|
72223
|
+
await context4.fs.ensureDir(join15(target, ...relPath.split("/").slice(0, -1)));
|
|
72224
|
+
await context4.fs.writeFile(destination, await context4.fs.readFile(join15(source, relPath)));
|
|
71881
72225
|
written += 1;
|
|
71882
72226
|
}
|
|
71883
72227
|
return written;
|
|
@@ -71887,20 +72231,20 @@ async function seedGlobalConfig(context4) {
|
|
|
71887
72231
|
if (source === null)
|
|
71888
72232
|
return 0;
|
|
71889
72233
|
const globalOverride = context4.env.SPUR_GLOBAL_RULES_DIR;
|
|
71890
|
-
const target = globalOverride !== undefined && globalOverride.length > 0 ? resolve5(context4.cwd, globalOverride) :
|
|
72234
|
+
const target = globalOverride !== undefined && globalOverride.length > 0 ? resolve5(context4.cwd, globalOverride) : join15(homedir5(), GLOBAL_CONFIG_DIR2);
|
|
71891
72235
|
let written = 0;
|
|
71892
72236
|
for (const relPath of listBundledConfigFiles()) {
|
|
71893
72237
|
if (relPath === GLOBAL_CONFIG_EXAMPLE)
|
|
71894
72238
|
continue;
|
|
71895
|
-
const destination =
|
|
72239
|
+
const destination = join15(target, relPath);
|
|
71896
72240
|
if (await context4.fs.exists(destination))
|
|
71897
72241
|
continue;
|
|
71898
|
-
await context4.fs.ensureDir(
|
|
71899
|
-
await context4.fs.writeFile(destination, await context4.fs.readFile(
|
|
72242
|
+
await context4.fs.ensureDir(join15(target, ...relPath.split("/").slice(0, -1)));
|
|
72243
|
+
await context4.fs.writeFile(destination, await context4.fs.readFile(join15(source, relPath)));
|
|
71900
72244
|
written += 1;
|
|
71901
72245
|
}
|
|
71902
|
-
const examplePath =
|
|
71903
|
-
const globalConfigPath =
|
|
72246
|
+
const examplePath = join15(source, GLOBAL_CONFIG_EXAMPLE);
|
|
72247
|
+
const globalConfigPath = join15(target, GLOBAL_CONFIG_FILE2);
|
|
71904
72248
|
if (await context4.fs.exists(examplePath) && !await context4.fs.exists(globalConfigPath)) {
|
|
71905
72249
|
await context4.fs.ensureDir(target);
|
|
71906
72250
|
await context4.fs.writeFile(globalConfigPath, await context4.fs.readFile(examplePath));
|
|
@@ -71914,7 +72258,7 @@ function registerInitCommand(program2, context4) {
|
|
|
71914
72258
|
const force = options.force === true;
|
|
71915
72259
|
const minimal = options.minimal === true;
|
|
71916
72260
|
const projectName = options.name ?? "default";
|
|
71917
|
-
const configPath =
|
|
72261
|
+
const configPath = join15(context4.cwd, CLI_CONFIG.configFile);
|
|
71918
72262
|
if (!force && await context4.fs.exists(configPath)) {
|
|
71919
72263
|
const message = `Already initialized: ${CLI_CONFIG.configFile}. Use --force to overwrite.`;
|
|
71920
72264
|
context4.output.write(json3 ? toJson2({ ok: false, reason: "already-initialized", config: CLI_CONFIG.configFile }) : message);
|
|
@@ -71949,13 +72293,13 @@ function registerInitCommand(program2, context4) {
|
|
|
71949
72293
|
].join(`
|
|
71950
72294
|
`)}
|
|
71951
72295
|
`;
|
|
71952
|
-
await context4.fs.ensureDir(
|
|
72296
|
+
await context4.fs.ensureDir(join15(context4.cwd, CLI_CONFIG.configDir));
|
|
71953
72297
|
await context4.fs.writeFile(configPath, configYaml);
|
|
71954
72298
|
result.created.push(configPath);
|
|
71955
|
-
const agentsDir =
|
|
72299
|
+
const agentsDir = join15(context4.cwd, CLI_CONFIG.configDir, "agents");
|
|
71956
72300
|
await context4.fs.ensureDir(agentsDir);
|
|
71957
|
-
await writeIfNew(context4,
|
|
71958
|
-
const gitignorePath =
|
|
72301
|
+
await writeIfNew(context4, join15(agentsDir, ".gitkeep"), "", force, result);
|
|
72302
|
+
const gitignorePath = join15(context4.cwd, ".gitignore");
|
|
71959
72303
|
const contextEntry = ".spur/context/";
|
|
71960
72304
|
if (await context4.fs.exists(gitignorePath)) {
|
|
71961
72305
|
const existing = await context4.fs.readFile(gitignorePath);
|
|
@@ -71975,20 +72319,20 @@ ${contextEntry}
|
|
|
71975
72319
|
const configRoot = bundledConfigRoot();
|
|
71976
72320
|
if (configRoot !== null) {
|
|
71977
72321
|
for (const relPath of listBundledProjectSeedFiles()) {
|
|
71978
|
-
const sourcePath =
|
|
72322
|
+
const sourcePath = join15(configRoot, relPath);
|
|
71979
72323
|
if (!await context4.fs.exists(sourcePath))
|
|
71980
72324
|
continue;
|
|
71981
|
-
const targetPath =
|
|
71982
|
-
await context4.fs.ensureDir(
|
|
72325
|
+
const targetPath = join15(context4.cwd, CLI_CONFIG.configDir, relPath);
|
|
72326
|
+
await context4.fs.ensureDir(join15(targetPath, ".."));
|
|
71983
72327
|
await writeIfNew(context4, targetPath, await context4.fs.readFile(sourcePath), force, result);
|
|
71984
72328
|
}
|
|
71985
72329
|
for (const entry of SCAFFOLD_MANIFEST) {
|
|
71986
|
-
const sourcePath =
|
|
72330
|
+
const sourcePath = join15(configRoot, entry.source);
|
|
71987
72331
|
if (!await context4.fs.exists(sourcePath))
|
|
71988
72332
|
continue;
|
|
71989
|
-
const baseDir = entry.root === true ? context4.cwd :
|
|
71990
|
-
const targetPath =
|
|
71991
|
-
await context4.fs.ensureDir(
|
|
72333
|
+
const baseDir = entry.root === true ? context4.cwd : join15(context4.cwd, CLI_CONFIG.configDir);
|
|
72334
|
+
const targetPath = join15(baseDir, entry.target);
|
|
72335
|
+
await context4.fs.ensureDir(join15(targetPath, ".."));
|
|
71992
72336
|
const entryForce = entry.preserve === true ? false : force;
|
|
71993
72337
|
let body = await context4.fs.readFile(sourcePath);
|
|
71994
72338
|
if (entry.target === "AGENTS.md") {
|
|
@@ -71998,7 +72342,7 @@ ${contextEntry}
|
|
|
71998
72342
|
}
|
|
71999
72343
|
}
|
|
72000
72344
|
}
|
|
72001
|
-
const agentsMdPath =
|
|
72345
|
+
const agentsMdPath = join15(context4.cwd, "AGENTS.md");
|
|
72002
72346
|
if (await context4.fs.exists(agentsMdPath)) {
|
|
72003
72347
|
const existing = await context4.fs.readFile(agentsMdPath);
|
|
72004
72348
|
if (!existing.includes(INDEXED_CONTEXT_MARKER)) {
|
|
@@ -72176,10 +72520,10 @@ function parseInterval2(raw) {
|
|
|
72176
72520
|
|
|
72177
72521
|
// src/commands/migrate.ts
|
|
72178
72522
|
init_src2();
|
|
72179
|
-
import { join as
|
|
72523
|
+
import { join as join16 } from "path";
|
|
72180
72524
|
function registerMigrateCommand(program2, context4) {
|
|
72181
72525
|
program2.command("migrate").summary("apply CLI-owned schema migrations").option("--json", "Output machine-readable JSON").action(async (options) => {
|
|
72182
|
-
const migrations = await loadSqlMigrations(
|
|
72526
|
+
const migrations = await loadSqlMigrations(join16(context4.cwd, "drizzle")).catch(() => {
|
|
72183
72527
|
return;
|
|
72184
72528
|
});
|
|
72185
72529
|
const applied = await applyCliMigrations(await context4.getDb(), migrations);
|
|
@@ -72431,7 +72775,7 @@ function formatTraceDetail(detail) {
|
|
|
72431
72775
|
|
|
72432
72776
|
// src/commands/serve.ts
|
|
72433
72777
|
init_src();
|
|
72434
|
-
import { join as
|
|
72778
|
+
import { join as join20 } from "path";
|
|
72435
72779
|
|
|
72436
72780
|
// ../server/src/index.ts
|
|
72437
72781
|
init_src();
|
|
@@ -72441,11 +72785,11 @@ init_src3();
|
|
|
72441
72785
|
init_src();
|
|
72442
72786
|
init_loader();
|
|
72443
72787
|
init_src2();
|
|
72444
|
-
import { dirname as dirname12, isAbsolute as isAbsolute3, join as
|
|
72788
|
+
import { dirname as dirname12, isAbsolute as isAbsolute3, join as join19 } from "path";
|
|
72445
72789
|
init_dist5();
|
|
72446
72790
|
|
|
72447
72791
|
// ../server/src/bootstrap.ts
|
|
72448
|
-
import { join as
|
|
72792
|
+
import { join as join17 } from "path";
|
|
72449
72793
|
|
|
72450
72794
|
// ../../node_modules/.bun/radash@12.1.1/node_modules/radash/dist/esm/async.mjs
|
|
72451
72795
|
var guard = (func, shouldGuard) => {
|
|
@@ -78549,23 +78893,128 @@ function parseLimit(raw2, fallback) {
|
|
|
78549
78893
|
|
|
78550
78894
|
// ../server/src/modules/observability/index.ts
|
|
78551
78895
|
init_src3();
|
|
78896
|
+
var ledgerWatcher;
|
|
78897
|
+
var watcherPath;
|
|
78898
|
+
function getLedgerWatcher(path9) {
|
|
78899
|
+
if (!ledgerWatcher || watcherPath !== path9) {
|
|
78900
|
+
ledgerWatcher?.stop();
|
|
78901
|
+
ledgerWatcher = new TokenLedgerWatcher({ ledgerPath: path9 });
|
|
78902
|
+
watcherPath = path9;
|
|
78903
|
+
ledgerWatcher.start();
|
|
78904
|
+
}
|
|
78905
|
+
return ledgerWatcher;
|
|
78906
|
+
}
|
|
78907
|
+
function toolUseSsePayload(event2) {
|
|
78908
|
+
return {
|
|
78909
|
+
type: "tool-use",
|
|
78910
|
+
occurredAt: event2.ts,
|
|
78911
|
+
event: event2
|
|
78912
|
+
};
|
|
78913
|
+
}
|
|
78914
|
+
function handleProcesses(ctx) {
|
|
78915
|
+
return async (c3) => {
|
|
78916
|
+
try {
|
|
78917
|
+
const snapshot = await ctx.processInventory().snapshot();
|
|
78918
|
+
return c3.json(snapshot);
|
|
78919
|
+
} catch (err) {
|
|
78920
|
+
if (err instanceof UnsupportedProcessPlatformError) {
|
|
78921
|
+
return c3.json({ error: err.message, code: err.code }, 501);
|
|
78922
|
+
}
|
|
78923
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
78924
|
+
return c3.json({ error: message }, 500);
|
|
78925
|
+
}
|
|
78926
|
+
};
|
|
78927
|
+
}
|
|
78928
|
+
function handleToolUseGet(ctx) {
|
|
78929
|
+
return (c3) => {
|
|
78930
|
+
try {
|
|
78931
|
+
const limitParam = c3.req.query("limit");
|
|
78932
|
+
let limitRaw;
|
|
78933
|
+
if (limitParam !== undefined) {
|
|
78934
|
+
const parsed = Number.parseInt(limitParam, 10);
|
|
78935
|
+
if (!Number.isNaN(parsed))
|
|
78936
|
+
limitRaw = parsed;
|
|
78937
|
+
}
|
|
78938
|
+
const before = c3.req.query("before") ?? undefined;
|
|
78939
|
+
const limit = clampToolUseLimit(limitRaw);
|
|
78940
|
+
const snapshot = ctx.tokenLedger().snapshot({ limit, before });
|
|
78941
|
+
return c3.json(snapshot);
|
|
78942
|
+
} catch (err) {
|
|
78943
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
78944
|
+
return c3.json({ error: message }, 500);
|
|
78945
|
+
}
|
|
78946
|
+
};
|
|
78947
|
+
}
|
|
78948
|
+
function handleToolUseStream(ctx) {
|
|
78949
|
+
return (c3) => {
|
|
78950
|
+
const closed = { current: false };
|
|
78951
|
+
let heartbeatInterval;
|
|
78952
|
+
let unsubscribe;
|
|
78953
|
+
const signal = c3.req.raw.signal;
|
|
78954
|
+
let closeController = () => {};
|
|
78955
|
+
const teardown = () => {
|
|
78956
|
+
if (closed.current)
|
|
78957
|
+
return;
|
|
78958
|
+
closed.current = true;
|
|
78959
|
+
if (heartbeatInterval)
|
|
78960
|
+
clearInterval(heartbeatInterval);
|
|
78961
|
+
try {
|
|
78962
|
+
unsubscribe?.();
|
|
78963
|
+
} catch {}
|
|
78964
|
+
signal.removeEventListener("abort", teardown);
|
|
78965
|
+
closeController();
|
|
78966
|
+
};
|
|
78967
|
+
const stream = new ReadableStream({
|
|
78968
|
+
start(controller) {
|
|
78969
|
+
const encoder = new TextEncoder;
|
|
78970
|
+
closeController = () => {
|
|
78971
|
+
try {
|
|
78972
|
+
controller.close();
|
|
78973
|
+
} catch {}
|
|
78974
|
+
};
|
|
78975
|
+
if (signal.aborted) {
|
|
78976
|
+
teardown();
|
|
78977
|
+
return;
|
|
78978
|
+
}
|
|
78979
|
+
signal.addEventListener("abort", teardown);
|
|
78980
|
+
heartbeatInterval = setInterval(sendSseKeepalive, 15000, closed, controller, encoder);
|
|
78981
|
+
enqueueSseFrame(closed, controller, encoder, {
|
|
78982
|
+
type: "connected",
|
|
78983
|
+
occurredAt: new Date().toISOString()
|
|
78984
|
+
});
|
|
78985
|
+
try {
|
|
78986
|
+
const path9 = ctx.tokenLedger().path;
|
|
78987
|
+
const watcher = getLedgerWatcher(path9);
|
|
78988
|
+
unsubscribe = watcher.subscribe((event2) => {
|
|
78989
|
+
if (!enqueueSseFrame(closed, controller, encoder, toolUseSsePayload(event2)))
|
|
78990
|
+
teardown();
|
|
78991
|
+
});
|
|
78992
|
+
} catch {
|
|
78993
|
+
enqueueSseFrame(closed, controller, encoder, {
|
|
78994
|
+
type: "error",
|
|
78995
|
+
error: "ledger watch unavailable",
|
|
78996
|
+
occurredAt: new Date().toISOString()
|
|
78997
|
+
});
|
|
78998
|
+
}
|
|
78999
|
+
},
|
|
79000
|
+
cancel() {
|
|
79001
|
+
teardown();
|
|
79002
|
+
}
|
|
79003
|
+
});
|
|
79004
|
+
return c3.newResponse(stream, 200, {
|
|
79005
|
+
"Content-Type": "text/event-stream",
|
|
79006
|
+
"Cache-Control": "no-cache"
|
|
79007
|
+
});
|
|
79008
|
+
};
|
|
79009
|
+
}
|
|
78552
79010
|
var observabilityModule = {
|
|
78553
79011
|
name: "observability",
|
|
78554
79012
|
mount(app, ctx) {
|
|
78555
79013
|
if (!ctx)
|
|
78556
79014
|
return;
|
|
78557
|
-
app.get("/api/observability/processes",
|
|
78558
|
-
|
|
78559
|
-
|
|
78560
|
-
return c3.json(snapshot);
|
|
78561
|
-
} catch (err) {
|
|
78562
|
-
if (err instanceof UnsupportedProcessPlatformError) {
|
|
78563
|
-
return c3.json({ error: err.message, code: err.code }, 501);
|
|
78564
|
-
}
|
|
78565
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
78566
|
-
return c3.json({ error: message }, 500);
|
|
78567
|
-
}
|
|
78568
|
-
});
|
|
79015
|
+
app.get("/api/observability/processes", handleProcesses(ctx));
|
|
79016
|
+
app.get("/api/observability/tool-use", handleToolUseGet(ctx));
|
|
79017
|
+
app.get("/api/observability/tool-use/stream", handleToolUseStream(ctx));
|
|
78569
79018
|
}
|
|
78570
79019
|
};
|
|
78571
79020
|
|
|
@@ -80803,7 +81252,7 @@ function createApp(appRt, opts) {
|
|
|
80803
81252
|
app.use("*", async (c3, next) => {
|
|
80804
81253
|
const pathname = c3.req.path === "/" ? "/index.html" : c3.req.path;
|
|
80805
81254
|
try {
|
|
80806
|
-
const file2 = Bun.file(
|
|
81255
|
+
const file2 = Bun.file(join17(webDistPath, pathname));
|
|
80807
81256
|
if (await file2.exists()) {
|
|
80808
81257
|
const headers = new Headers({ "content-type": file2.type });
|
|
80809
81258
|
return new Response(file2.stream(), { headers });
|
|
@@ -80816,7 +81265,7 @@ function createApp(appRt, opts) {
|
|
|
80816
81265
|
return c3.json({ error: "Not Found" }, 404);
|
|
80817
81266
|
}
|
|
80818
81267
|
try {
|
|
80819
|
-
const indexFile = Bun.file(
|
|
81268
|
+
const indexFile = Bun.file(join17(webDistPath, "index.html"));
|
|
80820
81269
|
if (await indexFile.exists()) {
|
|
80821
81270
|
return new Response(indexFile.stream(), {
|
|
80822
81271
|
headers: { "content-type": "text/html; charset=utf-8" }
|
|
@@ -80837,7 +81286,7 @@ init_src3();
|
|
|
80837
81286
|
init_src();
|
|
80838
81287
|
init_src2();
|
|
80839
81288
|
init_dist5();
|
|
80840
|
-
import { dirname as dirname11, join as
|
|
81289
|
+
import { dirname as dirname11, join as join18 } from "path";
|
|
80841
81290
|
var NOOP_OUTPUT = { write: (_s) => {}, error: (_s) => {} };
|
|
80842
81291
|
|
|
80843
81292
|
class LazyPlanningEventEmitter {
|
|
@@ -80872,7 +81321,7 @@ class NotConfiguredError extends Error {
|
|
|
80872
81321
|
function createServerContext(appRt, options) {
|
|
80873
81322
|
const cwd = options.cwd;
|
|
80874
81323
|
const fs3 = options.fs;
|
|
80875
|
-
const dbUrl = options.dbUrl ??
|
|
81324
|
+
const dbUrl = options.dbUrl ?? join18(cwd, DEFAULT_DATABASE_URL);
|
|
80876
81325
|
const eventsBus = options.eventsBus ?? appRt.events;
|
|
80877
81326
|
const jobQueueEnabled = options.jobQueueEnabled ?? false;
|
|
80878
81327
|
const folders = options.folders ?? DEFAULT_PLANNING_FOLDERS;
|
|
@@ -80890,6 +81339,7 @@ function createServerContext(appRt, options) {
|
|
|
80890
81339
|
let teamSvc;
|
|
80891
81340
|
let supervisorSvc;
|
|
80892
81341
|
let processInventorySvc;
|
|
81342
|
+
let tokenLedgerSvc;
|
|
80893
81343
|
let agentSvc;
|
|
80894
81344
|
let ruleSvc;
|
|
80895
81345
|
let workflowSvc;
|
|
@@ -80980,6 +81430,12 @@ function createServerContext(appRt, options) {
|
|
|
80980
81430
|
}
|
|
80981
81431
|
return processInventorySvc;
|
|
80982
81432
|
},
|
|
81433
|
+
tokenLedger() {
|
|
81434
|
+
if (!tokenLedgerSvc) {
|
|
81435
|
+
tokenLedgerSvc = new TokenLedgerService({ cwd });
|
|
81436
|
+
}
|
|
81437
|
+
return tokenLedgerSvc;
|
|
81438
|
+
},
|
|
80983
81439
|
agentService() {
|
|
80984
81440
|
agentSvc ??= new AgentService({
|
|
80985
81441
|
cwd,
|
|
@@ -81159,15 +81615,15 @@ async function runTaskActionJob(ctx, env, payload, createAgentService = createTa
|
|
|
81159
81615
|
}
|
|
81160
81616
|
}
|
|
81161
81617
|
async function resolveWebDistPath(configuredPath) {
|
|
81162
|
-
const candidates = configuredPath && configuredPath.trim() !== "" ? [isAbsolute3(configuredPath) ? configuredPath :
|
|
81163
|
-
|
|
81164
|
-
|
|
81165
|
-
|
|
81166
|
-
|
|
81167
|
-
|
|
81618
|
+
const candidates = configuredPath && configuredPath.trim() !== "" ? [isAbsolute3(configuredPath) ? configuredPath : join19(process.cwd(), configuredPath)] : [
|
|
81619
|
+
join19(process.cwd(), "dist/web"),
|
|
81620
|
+
join19(import.meta.dir, "web"),
|
|
81621
|
+
join19(dirname12(process.execPath), "web"),
|
|
81622
|
+
join19(dirname12(process.execPath), "../web"),
|
|
81623
|
+
join19(import.meta.dir, "../../../dist/web")
|
|
81168
81624
|
];
|
|
81169
81625
|
for (const candidate of candidates) {
|
|
81170
|
-
if (await Bun.file(
|
|
81626
|
+
if (await Bun.file(join19(candidate, "index.html")).exists()) {
|
|
81171
81627
|
return candidate;
|
|
81172
81628
|
}
|
|
81173
81629
|
}
|
|
@@ -81295,7 +81751,7 @@ if (false) {}
|
|
|
81295
81751
|
|
|
81296
81752
|
// src/commands/serve.ts
|
|
81297
81753
|
function resolveServeDbUrl(cwd, env, configuredUrl) {
|
|
81298
|
-
return env.DATABASE_URL === undefined ?
|
|
81754
|
+
return env.DATABASE_URL === undefined ? join20(cwd, DEFAULT_DATABASE_URL) : configuredUrl;
|
|
81299
81755
|
}
|
|
81300
81756
|
function registerServeCommand(program2, context4) {
|
|
81301
81757
|
program2.command("serve").summary("start the Spur web server (local fallback)").option("--port <n>", "Server port (env: PORT, default: 3000)", parseInt).option("--host <addr>", "Bind address (env: HOST, default: localhost)").option("--no-open", "Skip opening the browser").option("--cwd <path>", "Working directory", context4.cwd).option("--json", "Output { port, url, pid } and exit").action(async (options) => {
|
|
@@ -81334,7 +81790,7 @@ function registerServeCommand(program2, context4) {
|
|
|
81334
81790
|
}
|
|
81335
81791
|
|
|
81336
81792
|
// src/commands/status.ts
|
|
81337
|
-
import { join as
|
|
81793
|
+
import { join as join21 } from "path";
|
|
81338
81794
|
|
|
81339
81795
|
// src/errors.ts
|
|
81340
81796
|
class CommandError extends Error {
|
|
@@ -81405,8 +81861,8 @@ function registerStatusCommand(program2, context4) {
|
|
|
81405
81861
|
}
|
|
81406
81862
|
async function runStatusCore(path9, options, context4) {
|
|
81407
81863
|
const [packageJsonExists, spurConfigExists, git, agentSpecs] = await Promise.all([
|
|
81408
|
-
context4.fs.exists(
|
|
81409
|
-
context4.fs.exists(
|
|
81864
|
+
context4.fs.exists(join21(context4.cwd, "package.json")),
|
|
81865
|
+
context4.fs.exists(join21(context4.cwd, ".spur", "config.yaml")),
|
|
81410
81866
|
gitContext(context4.cwd),
|
|
81411
81867
|
listAgentSpecIds(context4)
|
|
81412
81868
|
]);
|
|
@@ -81434,14 +81890,14 @@ async function runStatusCore(path9, options, context4) {
|
|
|
81434
81890
|
return status.ok ? 0 : 1;
|
|
81435
81891
|
}
|
|
81436
81892
|
async function listAgentSpecIds(context4) {
|
|
81437
|
-
const dir =
|
|
81893
|
+
const dir = join21(context4.cwd, ".spur", "agents");
|
|
81438
81894
|
if (!await context4.fs.exists(dir))
|
|
81439
81895
|
return [];
|
|
81440
81896
|
const entries = await context4.fs.readDir(dir);
|
|
81441
81897
|
return entries.filter((entry) => entry.endsWith(".yaml") || entry.endsWith(".yml")).map((entry) => entry.replace(/\.ya?ml$/, "")).sort();
|
|
81442
81898
|
}
|
|
81443
81899
|
async function readTargetStatus(context4, targetPath) {
|
|
81444
|
-
const resolved =
|
|
81900
|
+
const resolved = join21(context4.cwd, targetPath);
|
|
81445
81901
|
const stat2 = await context4.fs.stat(resolved);
|
|
81446
81902
|
if (stat2 === null)
|
|
81447
81903
|
throw new CommandError(`status failed: path does not exist at ${resolved}`);
|
|
@@ -81452,8 +81908,8 @@ async function readTargetStatus(context4, targetPath) {
|
|
|
81452
81908
|
init_src3();
|
|
81453
81909
|
init_loader();
|
|
81454
81910
|
init_src2();
|
|
81455
|
-
import { existsSync as
|
|
81456
|
-
import { join as
|
|
81911
|
+
import { existsSync as existsSync9, readFileSync as readFileSync8 } from "fs";
|
|
81912
|
+
import { join as join22 } from "path";
|
|
81457
81913
|
// schemas/section-matrix.schema.json
|
|
81458
81914
|
var section_matrix_schema_default = {
|
|
81459
81915
|
$schema: "http://json-schema.org/draft-07/schema#",
|
|
@@ -82308,7 +82764,8 @@ async function makeService2(context4, folderOverride, noLifecycle = false) {
|
|
|
82308
82764
|
const lifecycle = noLifecycle ? undefined : makeLifecycleAdapter(context4, TASK_LIFECYCLE_PROFILE);
|
|
82309
82765
|
const writeService = new PlanningWriteService({
|
|
82310
82766
|
fs: context4.fs,
|
|
82311
|
-
...lifecycle ? { lifecycle } : {}
|
|
82767
|
+
...lifecycle ? { lifecycle } : {},
|
|
82768
|
+
emitter: makePlanningEmitter(context4)
|
|
82312
82769
|
});
|
|
82313
82770
|
return new TaskService({
|
|
82314
82771
|
fs: context4.fs,
|
|
@@ -82327,16 +82784,16 @@ function loadTemplateContent(projectRoot, variant) {
|
|
|
82327
82784
|
return templateContentCache.get(variant);
|
|
82328
82785
|
if (templateMissSet.has(variant))
|
|
82329
82786
|
return;
|
|
82330
|
-
const localPath =
|
|
82331
|
-
if (
|
|
82787
|
+
const localPath = join22(projectRoot, ".spur", "tasks", "templates", `${variant}.md`);
|
|
82788
|
+
if (existsSync9(localPath)) {
|
|
82332
82789
|
const content = readFileSync8(localPath, "utf8");
|
|
82333
82790
|
templateContentCache.set(variant, content);
|
|
82334
82791
|
return content;
|
|
82335
82792
|
}
|
|
82336
82793
|
const root = bundledConfigRoot();
|
|
82337
82794
|
if (root !== null) {
|
|
82338
|
-
const templatePath =
|
|
82339
|
-
if (
|
|
82795
|
+
const templatePath = join22(root, "templates", "task", `${variant}.md`);
|
|
82796
|
+
if (existsSync9(templatePath)) {
|
|
82340
82797
|
const content = readFileSync8(templatePath, "utf8");
|
|
82341
82798
|
templateContentCache.set(variant, content);
|
|
82342
82799
|
return content;
|
|
@@ -82351,14 +82808,14 @@ function loadTemplateBodies(projectRoot, variant) {
|
|
|
82351
82808
|
if (cached2 !== undefined)
|
|
82352
82809
|
return cached2;
|
|
82353
82810
|
let bodies = {};
|
|
82354
|
-
const localPath =
|
|
82355
|
-
if (
|
|
82811
|
+
const localPath = join22(projectRoot, ".spur", "tasks", "templates", `${variant}.md`);
|
|
82812
|
+
if (existsSync9(localPath)) {
|
|
82356
82813
|
bodies = extractTemplateBodies(readFileSync8(localPath, "utf8"));
|
|
82357
82814
|
} else {
|
|
82358
82815
|
const root = bundledConfigRoot();
|
|
82359
82816
|
if (root !== null) {
|
|
82360
|
-
const templatePath =
|
|
82361
|
-
if (
|
|
82817
|
+
const templatePath = join22(root, "templates", "task", `${variant}.md`);
|
|
82818
|
+
if (existsSync9(templatePath)) {
|
|
82362
82819
|
bodies = extractTemplateBodies(readFileSync8(templatePath, "utf8"));
|
|
82363
82820
|
}
|
|
82364
82821
|
}
|
|
@@ -82392,8 +82849,8 @@ async function loadSectionMatrix(projectRoot) {
|
|
|
82392
82849
|
return promise2;
|
|
82393
82850
|
}
|
|
82394
82851
|
async function loadSectionMatrixUncached(projectRoot) {
|
|
82395
|
-
const localPath =
|
|
82396
|
-
if (
|
|
82852
|
+
const localPath = join22(projectRoot, ".spur", "tasks", "section-matrix.yaml");
|
|
82853
|
+
if (existsSync9(localPath)) {
|
|
82397
82854
|
const data = await loadStructuredSpurConfig(localPath, {
|
|
82398
82855
|
validateJsonSchema: true,
|
|
82399
82856
|
embeddedSchemas: EMBEDDED_SPUR_SCHEMAS
|
|
@@ -82402,8 +82859,8 @@ async function loadSectionMatrixUncached(projectRoot) {
|
|
|
82402
82859
|
}
|
|
82403
82860
|
const root = bundledConfigRoot();
|
|
82404
82861
|
if (root !== null) {
|
|
82405
|
-
const matrixPath =
|
|
82406
|
-
if (
|
|
82862
|
+
const matrixPath = join22(root, "tasks", "section-matrix.yaml");
|
|
82863
|
+
if (existsSync9(matrixPath)) {
|
|
82407
82864
|
const data = await loadStructuredSpurConfig(matrixPath, {
|
|
82408
82865
|
validateJsonSchema: true,
|
|
82409
82866
|
embeddedSchemas: EMBEDDED_SPUR_SCHEMAS
|
|
@@ -82848,7 +83305,7 @@ init_src3();
|
|
|
82848
83305
|
init_src();
|
|
82849
83306
|
init_src2();
|
|
82850
83307
|
init_dist5();
|
|
82851
|
-
import { dirname as dirname13, join as
|
|
83308
|
+
import { dirname as dirname13, join as join23, resolve as resolve7 } from "path";
|
|
82852
83309
|
import { isatty as isatty4 } from "tty";
|
|
82853
83310
|
|
|
82854
83311
|
// ../../node_modules/.bun/@clack+core@1.4.1/node_modules/@clack/core/dist/index.mjs
|
|
@@ -84262,7 +84719,7 @@ function createCliContext(options) {
|
|
|
84262
84719
|
function noopSetExitCode(_code) {}
|
|
84263
84720
|
async function createMigratedDbAdapter(cwd = process.cwd(), env = process.env, dbUrl) {
|
|
84264
84721
|
const config4 = buildConfigFromEnv(env);
|
|
84265
|
-
const configuredUrl = env.DATABASE_URL === undefined ?
|
|
84722
|
+
const configuredUrl = env.DATABASE_URL === undefined ? join23(cwd, DEFAULT_DATABASE_URL) : config4.database.url;
|
|
84266
84723
|
const url2 = dbUrl ?? configuredUrl;
|
|
84267
84724
|
if (url2 !== IN_MEMORY_DATABASE_URL) {
|
|
84268
84725
|
await createNodeFileSystem3().ensureDir(dirname13(url2));
|