chatroom-cli 1.98.7 → 1.99.0
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/dist/client/build/assets/index-DKoewUK4.css +1 -0
- package/dist/client/build/assets/{index-6IhLktfo.js → index-LbWoI4E4.js} +23 -23
- package/dist/client/build/index.html +2 -2
- package/dist/index.js +647 -436
- package/dist/index.js.map +40 -33
- package/package.json +1 -1
- package/dist/client/build/assets/index-TiUlJQMc.css +0 -1
package/dist/index.js
CHANGED
|
@@ -83515,6 +83515,321 @@ function harnessCapabilitiesFingerprint(harnesses, versions) {
|
|
|
83515
83515
|
return `${h}::${v3}`;
|
|
83516
83516
|
}
|
|
83517
83517
|
|
|
83518
|
+
// src/daemon/infrastructure/outbox/lib/durable-fifo-queue-schema.ts
|
|
83519
|
+
var DURABLE_FIFO_QUEUE_MIGRATIONS;
|
|
83520
|
+
var init_durable_fifo_queue_schema = __esm(() => {
|
|
83521
|
+
DURABLE_FIFO_QUEUE_MIGRATIONS = [
|
|
83522
|
+
`CREATE TABLE IF NOT EXISTS schema_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)`,
|
|
83523
|
+
`CREATE TABLE IF NOT EXISTS fifo_outbox_entries (id INTEGER PRIMARY KEY AUTOINCREMENT, delivery_key TEXT NOT NULL, payload_json TEXT NOT NULL, status TEXT NOT NULL DEFAULT 'pending', attempts INTEGER NOT NULL DEFAULT 0, last_error TEXT, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)`,
|
|
83524
|
+
`CREATE INDEX IF NOT EXISTS idx_fifo_outbox_pending ON fifo_outbox_entries(delivery_key, status, id)`
|
|
83525
|
+
];
|
|
83526
|
+
});
|
|
83527
|
+
|
|
83528
|
+
// src/daemon/infrastructure/outbox/lib/durable-fifo-queue-store.ts
|
|
83529
|
+
import { DatabaseSync } from "node:sqlite";
|
|
83530
|
+
import { mkdirSync as mkdirSync4 } from "node:fs";
|
|
83531
|
+
import { dirname as dirname9 } from "node:path";
|
|
83532
|
+
function openDurableFifoQueueStore(dbPath) {
|
|
83533
|
+
mkdirSync4(dirname9(dbPath), { recursive: true });
|
|
83534
|
+
const db = new DatabaseSync(dbPath);
|
|
83535
|
+
for (const sql of DURABLE_FIFO_QUEUE_MIGRATIONS)
|
|
83536
|
+
db.exec(sql);
|
|
83537
|
+
db.prepare("UPDATE fifo_outbox_entries SET status='pending', updated_at=? WHERE status='in_flight'").run(Date.now());
|
|
83538
|
+
return {
|
|
83539
|
+
enqueue: (key, payloadJson) => {
|
|
83540
|
+
const now = Date.now();
|
|
83541
|
+
return Number(db.prepare("INSERT INTO fifo_outbox_entries(delivery_key,payload_json,created_at,updated_at) VALUES(?,?,?,?) RETURNING id").get(key, payloadJson, now, now).id);
|
|
83542
|
+
},
|
|
83543
|
+
claimNextBatch: (key, limit) => db.prepare("UPDATE fifo_outbox_entries SET status='in_flight', attempts=attempts+1, updated_at=? WHERE id IN (SELECT id FROM fifo_outbox_entries WHERE delivery_key=? AND status='pending' ORDER BY id LIMIT ?) RETURNING id, delivery_key as deliveryKey, payload_json as payloadJson, attempts").all(Date.now(), key, limit),
|
|
83544
|
+
markDone: (id3) => {
|
|
83545
|
+
db.prepare("DELETE FROM fifo_outbox_entries WHERE id=?").run(id3);
|
|
83546
|
+
},
|
|
83547
|
+
markPending: (id3) => {
|
|
83548
|
+
db.prepare("UPDATE fifo_outbox_entries SET status='pending', last_error=NULL, updated_at=? WHERE id=?").run(Date.now(), id3);
|
|
83549
|
+
},
|
|
83550
|
+
updatePayload: (id3, payloadJson) => {
|
|
83551
|
+
db.prepare("UPDATE fifo_outbox_entries SET payload_json=?, updated_at=? WHERE id=?").run(payloadJson, Date.now(), id3);
|
|
83552
|
+
},
|
|
83553
|
+
markPendingRetry: (id3, error) => {
|
|
83554
|
+
db.prepare("UPDATE fifo_outbox_entries SET status='pending', last_error=?, updated_at=? WHERE id=?").run(String(error), Date.now(), id3);
|
|
83555
|
+
},
|
|
83556
|
+
listPendingForRecovery: (key) => db.prepare("SELECT id, delivery_key as deliveryKey, payload_json as payloadJson, attempts FROM fifo_outbox_entries WHERE delivery_key=? AND status IN ('pending','in_flight') ORDER BY id").all(key),
|
|
83557
|
+
close: () => db.close()
|
|
83558
|
+
};
|
|
83559
|
+
}
|
|
83560
|
+
var init_durable_fifo_queue_store = __esm(() => {
|
|
83561
|
+
init_durable_fifo_queue_schema();
|
|
83562
|
+
});
|
|
83563
|
+
|
|
83564
|
+
// src/daemon/infrastructure/outbox/lib/outbox-retry-backoff.ts
|
|
83565
|
+
function computeExponentialRetryDelayMs(attempt, retryDelayMs, maxRetryDelayMs) {
|
|
83566
|
+
const exponent = Math.min(Math.max(0, attempt), MAX_RETRY_EXPONENT);
|
|
83567
|
+
return Math.min(retryDelayMs * 2 ** exponent, maxRetryDelayMs);
|
|
83568
|
+
}
|
|
83569
|
+
var MAX_RETRY_EXPONENT = 20;
|
|
83570
|
+
|
|
83571
|
+
// src/daemon/infrastructure/outbox/lib/fifo-batched-outbox.ts
|
|
83572
|
+
function createFifoBatchedOutbox(o) {
|
|
83573
|
+
const waiters = new Map;
|
|
83574
|
+
let running3;
|
|
83575
|
+
let stopped = false;
|
|
83576
|
+
let retryTimer;
|
|
83577
|
+
let retryAttempt = 0;
|
|
83578
|
+
const retryDelay = () => computeExponentialRetryDelayMs(retryAttempt++, o.retryDelayMs ?? 500, o.maxRetryDelayMs ?? 5000);
|
|
83579
|
+
const scheduleRetry = () => {
|
|
83580
|
+
if (!stopped && !retryTimer) {
|
|
83581
|
+
retryTimer = setTimeout(() => {
|
|
83582
|
+
retryTimer = undefined;
|
|
83583
|
+
drain().catch(() => {
|
|
83584
|
+
return;
|
|
83585
|
+
});
|
|
83586
|
+
}, retryDelay());
|
|
83587
|
+
retryTimer.unref?.();
|
|
83588
|
+
}
|
|
83589
|
+
};
|
|
83590
|
+
const drain = async () => {
|
|
83591
|
+
if (running3)
|
|
83592
|
+
return running3;
|
|
83593
|
+
running3 = (async () => {
|
|
83594
|
+
while (true) {
|
|
83595
|
+
const rows = o.store.claimNextBatch(o.deliveryKey, o.batchSize);
|
|
83596
|
+
if (!rows.length)
|
|
83597
|
+
break;
|
|
83598
|
+
try {
|
|
83599
|
+
const results = await o.send(rows.map((r) => o.deserialize(r.payloadJson)));
|
|
83600
|
+
let hasRetry = false;
|
|
83601
|
+
for (let i2 = 0;i2 < results.length; i2++) {
|
|
83602
|
+
const item = o.deserialize(rows[i2].payloadJson);
|
|
83603
|
+
const outcome = o.classifyOutcome?.(results[i2], item) ?? { kind: "success" };
|
|
83604
|
+
if (outcome.kind === "retry") {
|
|
83605
|
+
o.store.updatePayload(rows[i2].id, o.serialize(outcome.item));
|
|
83606
|
+
o.store.markPending(rows[i2].id);
|
|
83607
|
+
hasRetry = true;
|
|
83608
|
+
continue;
|
|
83609
|
+
}
|
|
83610
|
+
o.store.markDone(rows[i2].id);
|
|
83611
|
+
waiters.get(rows[i2].id)?.resolve(results[i2]);
|
|
83612
|
+
waiters.delete(rows[i2].id);
|
|
83613
|
+
}
|
|
83614
|
+
for (let i2 = results.length;i2 < rows.length; i2++)
|
|
83615
|
+
o.store.markPending(rows[i2].id);
|
|
83616
|
+
if (hasRetry) {
|
|
83617
|
+
scheduleRetry();
|
|
83618
|
+
break;
|
|
83619
|
+
}
|
|
83620
|
+
retryAttempt = 0;
|
|
83621
|
+
} catch (e) {
|
|
83622
|
+
o.onError?.(e);
|
|
83623
|
+
for (const r of rows)
|
|
83624
|
+
o.store.markPendingRetry(r.id, e);
|
|
83625
|
+
scheduleRetry();
|
|
83626
|
+
break;
|
|
83627
|
+
}
|
|
83628
|
+
}
|
|
83629
|
+
})().finally(() => {
|
|
83630
|
+
running3 = undefined;
|
|
83631
|
+
});
|
|
83632
|
+
return running3;
|
|
83633
|
+
};
|
|
83634
|
+
const enqueue = (item) => {
|
|
83635
|
+
if (stopped)
|
|
83636
|
+
return Promise.reject(new Error("Outbox is stopped"));
|
|
83637
|
+
const id3 = o.store.enqueue(o.deliveryKey, o.serialize(item));
|
|
83638
|
+
const p = new Promise((resolve4, reject) => waiters.set(id3, { resolve: resolve4, reject }));
|
|
83639
|
+
drain().catch(() => {
|
|
83640
|
+
return;
|
|
83641
|
+
});
|
|
83642
|
+
return p;
|
|
83643
|
+
};
|
|
83644
|
+
const flushNow = async () => {
|
|
83645
|
+
while (o.store.listPendingForRecovery(o.deliveryKey).length) {
|
|
83646
|
+
await drain();
|
|
83647
|
+
}
|
|
83648
|
+
};
|
|
83649
|
+
const stop4 = async () => {
|
|
83650
|
+
if (stopped)
|
|
83651
|
+
return;
|
|
83652
|
+
if (retryTimer)
|
|
83653
|
+
clearTimeout(retryTimer);
|
|
83654
|
+
retryTimer = undefined;
|
|
83655
|
+
await flushNow();
|
|
83656
|
+
stopped = true;
|
|
83657
|
+
};
|
|
83658
|
+
return { enqueue, flushNow, stop: stop4 };
|
|
83659
|
+
}
|
|
83660
|
+
var init_fifo_batched_outbox = () => {};
|
|
83661
|
+
|
|
83662
|
+
// src/daemon/infrastructure/outbox/lib/keyed-fifo-batched-outbox-registry.ts
|
|
83663
|
+
function createKeyedFifoBatchedOutboxRegistry(o) {
|
|
83664
|
+
const boxes = new Map;
|
|
83665
|
+
const get13 = (key) => {
|
|
83666
|
+
let b = boxes.get(key);
|
|
83667
|
+
if (!b) {
|
|
83668
|
+
b = createFifoBatchedOutbox({
|
|
83669
|
+
batchSize: o.batchSize,
|
|
83670
|
+
send: o.createSend(key),
|
|
83671
|
+
store: o.store,
|
|
83672
|
+
deliveryKey: key,
|
|
83673
|
+
serialize: o.serialize,
|
|
83674
|
+
deserialize: o.deserialize,
|
|
83675
|
+
retryDelayMs: o.retryDelayMs,
|
|
83676
|
+
maxRetryDelayMs: o.maxRetryDelayMs,
|
|
83677
|
+
onError: (e) => o.onError?.(key, e),
|
|
83678
|
+
classifyOutcome: o.classifyOutcome
|
|
83679
|
+
});
|
|
83680
|
+
boxes.set(key, b);
|
|
83681
|
+
}
|
|
83682
|
+
return b;
|
|
83683
|
+
};
|
|
83684
|
+
const stop4 = async (k) => {
|
|
83685
|
+
const b = boxes.get(k);
|
|
83686
|
+
if (b) {
|
|
83687
|
+
await b.stop();
|
|
83688
|
+
boxes.delete(k);
|
|
83689
|
+
}
|
|
83690
|
+
};
|
|
83691
|
+
return {
|
|
83692
|
+
enqueue: (k, i2) => get13(k).enqueue(i2),
|
|
83693
|
+
flushNow: async (k) => {
|
|
83694
|
+
if (k)
|
|
83695
|
+
await get13(k).flushNow();
|
|
83696
|
+
else
|
|
83697
|
+
for (const b of boxes.values())
|
|
83698
|
+
await b.flushNow();
|
|
83699
|
+
},
|
|
83700
|
+
stop: stop4,
|
|
83701
|
+
stopAll: async () => {
|
|
83702
|
+
for (const k of [...boxes.keys()])
|
|
83703
|
+
await stop4(k);
|
|
83704
|
+
o.store.close();
|
|
83705
|
+
}
|
|
83706
|
+
};
|
|
83707
|
+
}
|
|
83708
|
+
var init_keyed_fifo_batched_outbox_registry = __esm(() => {
|
|
83709
|
+
init_fifo_batched_outbox();
|
|
83710
|
+
});
|
|
83711
|
+
|
|
83712
|
+
// src/daemon/infrastructure/outbox/outbox-db-path.ts
|
|
83713
|
+
import { homedir as homedir5 } from "node:os";
|
|
83714
|
+
import { join as join17 } from "node:path";
|
|
83715
|
+
function resolveOutboxDbPath(machineId, kind) {
|
|
83716
|
+
return join17(homedir5(), ".chatroom", "daemon", machineId, `outbox-${kind}.sqlite`);
|
|
83717
|
+
}
|
|
83718
|
+
var init_outbox_db_path = () => {};
|
|
83719
|
+
|
|
83720
|
+
// src/daemon/domain/entities/agent-lifecycle-fact.ts
|
|
83721
|
+
function buildExitedLifecycleFact(auditArgs, emittedAt) {
|
|
83722
|
+
const { sessionId: _sessionId, machineId: _machineId, ...fields } = auditArgs;
|
|
83723
|
+
return {
|
|
83724
|
+
kind: "exited",
|
|
83725
|
+
...fields,
|
|
83726
|
+
revisionKey: buildAgentLifecycleRevisionKey("exited", {
|
|
83727
|
+
chatroomId: auditArgs.chatroomId,
|
|
83728
|
+
role: auditArgs.role,
|
|
83729
|
+
pid: auditArgs.pid,
|
|
83730
|
+
emittedAt
|
|
83731
|
+
}),
|
|
83732
|
+
emittedAt
|
|
83733
|
+
};
|
|
83734
|
+
}
|
|
83735
|
+
function normalizeAgentLifecycleFact(raw) {
|
|
83736
|
+
if (!raw || typeof raw !== "object") {
|
|
83737
|
+
throw new Error("Invalid agent lifecycle fact");
|
|
83738
|
+
}
|
|
83739
|
+
const value = raw;
|
|
83740
|
+
const { sessionId: _sessionId, machineId: _machineId, ...rest } = value;
|
|
83741
|
+
const kind = rest.kind;
|
|
83742
|
+
if (kind === "cleared_all_pids") {
|
|
83743
|
+
return {
|
|
83744
|
+
kind: "cleared_all_pids",
|
|
83745
|
+
revisionKey: String(rest.revisionKey),
|
|
83746
|
+
emittedAt: Number(rest.emittedAt)
|
|
83747
|
+
};
|
|
83748
|
+
}
|
|
83749
|
+
if (kind === "spawned" || kind === "exited") {
|
|
83750
|
+
return rest;
|
|
83751
|
+
}
|
|
83752
|
+
throw new Error(`Unknown agent lifecycle fact kind: ${String(kind)}`);
|
|
83753
|
+
}
|
|
83754
|
+
function agentLifecycleDeliveryKey(machineId, fact) {
|
|
83755
|
+
if (fact.kind === "cleared_all_pids")
|
|
83756
|
+
return `${machineId}:__machine__`;
|
|
83757
|
+
return `${machineId}:${fact.chatroomId}:${fact.role.toLowerCase()}`;
|
|
83758
|
+
}
|
|
83759
|
+
function buildAgentLifecycleRevisionKey(prefix, parts2) {
|
|
83760
|
+
return `${prefix}:${Object.entries(parts2).filter(([, v3]) => v3 !== undefined).map(([k, v3]) => `${k}=${v3}`).join(":")}`;
|
|
83761
|
+
}
|
|
83762
|
+
|
|
83763
|
+
// src/daemon/infrastructure/outbox/agent-lifecycle-outbox.ts
|
|
83764
|
+
function createAgentLifecycleOutboxRegistry(machineId, createSend, options) {
|
|
83765
|
+
const store = openDurableFifoQueueStore(resolveOutboxDbPath(machineId, "agent-lifecycle"));
|
|
83766
|
+
return createKeyedFifoBatchedOutboxRegistry({
|
|
83767
|
+
store,
|
|
83768
|
+
batchSize: AGENT_LIFECYCLE_OUTBOX_BATCH_SIZE,
|
|
83769
|
+
createSend: (key) => async (facts) => {
|
|
83770
|
+
const results = [];
|
|
83771
|
+
for (const fact of facts)
|
|
83772
|
+
results.push(await createSend(key)(fact));
|
|
83773
|
+
return results;
|
|
83774
|
+
},
|
|
83775
|
+
serialize: JSON.stringify,
|
|
83776
|
+
deserialize: (serialized) => normalizeAgentLifecycleFact(JSON.parse(serialized)),
|
|
83777
|
+
retryDelayMs: 500,
|
|
83778
|
+
maxRetryDelayMs: 5 * 60000,
|
|
83779
|
+
onError: options?.onError,
|
|
83780
|
+
classifyOutcome: () => ({ kind: "success" })
|
|
83781
|
+
});
|
|
83782
|
+
}
|
|
83783
|
+
function agentLifecycleKey(machineId, fact) {
|
|
83784
|
+
return agentLifecycleDeliveryKey(machineId, fact);
|
|
83785
|
+
}
|
|
83786
|
+
var AGENT_LIFECYCLE_OUTBOX_BATCH_SIZE = 1;
|
|
83787
|
+
var init_agent_lifecycle_outbox = __esm(() => {
|
|
83788
|
+
init_durable_fifo_queue_store();
|
|
83789
|
+
init_keyed_fifo_batched_outbox_registry();
|
|
83790
|
+
init_outbox_db_path();
|
|
83791
|
+
});
|
|
83792
|
+
|
|
83793
|
+
// src/daemon/infrastructure/outbox/agent-lifecycle-send.ts
|
|
83794
|
+
function toConvexLifecycleFact(fact) {
|
|
83795
|
+
const normalized = normalizeAgentLifecycleFact(fact);
|
|
83796
|
+
if (normalized.kind === "cleared_all_pids")
|
|
83797
|
+
return normalized;
|
|
83798
|
+
return {
|
|
83799
|
+
...normalized,
|
|
83800
|
+
chatroomId: normalized.chatroomId
|
|
83801
|
+
};
|
|
83802
|
+
}
|
|
83803
|
+
function createAgentLifecycleSend(session2) {
|
|
83804
|
+
return async (fact) => {
|
|
83805
|
+
const args2 = {
|
|
83806
|
+
sessionId: session2.sessionId,
|
|
83807
|
+
machineId: session2.machineId,
|
|
83808
|
+
fact: toConvexLifecycleFact(fact)
|
|
83809
|
+
};
|
|
83810
|
+
return await session2.backend.mutation(api.machines.projectAgentLifecycleFact, args2);
|
|
83811
|
+
};
|
|
83812
|
+
}
|
|
83813
|
+
var init_agent_lifecycle_send = __esm(() => {
|
|
83814
|
+
init_api3();
|
|
83815
|
+
});
|
|
83816
|
+
|
|
83817
|
+
// src/daemon/entry/agent-lifecycle-outbox-runtime.ts
|
|
83818
|
+
function createAgentLifecycleOutboxForSession(args2) {
|
|
83819
|
+
return createAgentLifecycleOutboxRegistry(args2.machineId, () => createAgentLifecycleSend({
|
|
83820
|
+
sessionId: args2.sessionId,
|
|
83821
|
+
machineId: args2.machineId,
|
|
83822
|
+
backend: args2.backend
|
|
83823
|
+
}));
|
|
83824
|
+
}
|
|
83825
|
+
function enqueueAgentLifecycleFact(registry2, machineId, fact) {
|
|
83826
|
+
return registry2.enqueue(agentLifecycleKey(machineId, fact), fact);
|
|
83827
|
+
}
|
|
83828
|
+
var init_agent_lifecycle_outbox_runtime = __esm(() => {
|
|
83829
|
+
init_agent_lifecycle_outbox();
|
|
83830
|
+
init_agent_lifecycle_send();
|
|
83831
|
+
});
|
|
83832
|
+
|
|
83518
83833
|
// src/daemon/entry/daemon-services.ts
|
|
83519
83834
|
function DaemonMutableStateServiceLive(init2) {
|
|
83520
83835
|
return exports_Layer.effect(DaemonMutableStateService, exports_Effect.gen(function* () {
|
|
@@ -83526,7 +83841,10 @@ function DaemonMutableStateServiceLive(init2) {
|
|
|
83526
83841
|
};
|
|
83527
83842
|
}));
|
|
83528
83843
|
}
|
|
83529
|
-
var
|
|
83844
|
+
var AgentLifecycleOutboxService, AgentLifecycleOutboxServiceLive = (registry2, machineId) => exports_Layer.succeed(AgentLifecycleOutboxService, {
|
|
83845
|
+
enqueue: (fact) => exports_Effect.promise(() => enqueueAgentLifecycleFact(registry2, machineId, fact)),
|
|
83846
|
+
stopAll: () => exports_Effect.promise(() => registry2.stopAll())
|
|
83847
|
+
}), DaemonMachineService, DaemonMachineServiceLive = (ops) => exports_Layer.succeed(DaemonMachineService, {
|
|
83530
83848
|
clearAgentPid: (machineId, chatroomId, role) => exports_Effect.promise(() => ops.clearAgentPid(machineId, chatroomId, role)),
|
|
83531
83849
|
persistAgentPid: (machineId, chatroomId, role, pid, harness) => exports_Effect.promise(() => ops.persistAgentPid(machineId, chatroomId, role, pid, harness)),
|
|
83532
83850
|
listAgentEntries: (machineId) => exports_Effect.promise(() => ops.listAgentEntries(machineId)),
|
|
@@ -83550,6 +83868,9 @@ var DaemonMachineService, DaemonMachineServiceLive = (ops) => exports_Layer.succ
|
|
|
83550
83868
|
}), DaemonSessionService, DaemonMutableStateService;
|
|
83551
83869
|
var init_daemon_services = __esm(() => {
|
|
83552
83870
|
init_esm();
|
|
83871
|
+
init_agent_lifecycle_outbox_runtime();
|
|
83872
|
+
AgentLifecycleOutboxService = class AgentLifecycleOutboxService extends exports_Context.Tag("AgentLifecycleOutboxService")() {
|
|
83873
|
+
};
|
|
83553
83874
|
DaemonMachineService = class DaemonMachineService extends exports_Context.Tag("DaemonMachineService")() {
|
|
83554
83875
|
};
|
|
83555
83876
|
DaemonSpawningService = class DaemonSpawningService extends exports_Context.Tag("DaemonSpawningService")() {
|
|
@@ -83572,7 +83893,7 @@ function daemonSessionToLayers(init2) {
|
|
|
83572
83893
|
return exports_Layer.mergeAll(BackendServiceLive({
|
|
83573
83894
|
mutation: (e, a) => init2.backend.mutation(e, a),
|
|
83574
83895
|
query: (e, a) => init2.backend.query(e, a)
|
|
83575
|
-
}), ProcessServiceLive, ClockServiceLive, FsServiceLive, DaemonMachineServiceLive(init2.machine), DaemonSpawningServiceLive(init2.spawning), DaemonAgentProcessManagerServiceLive(init2.agentProcessManager), DaemonMutableStateServiceLive({
|
|
83896
|
+
}), ProcessServiceLive, ClockServiceLive, FsServiceLive, DaemonMachineServiceLive(init2.machine), AgentLifecycleOutboxServiceLive(init2.agentLifecycleOutbox, init2.machineId), DaemonSpawningServiceLive(init2.spawning), DaemonAgentProcessManagerServiceLive(init2.agentProcessManager), DaemonMutableStateServiceLive({
|
|
83576
83897
|
lastPushedGitState: init2.lastPushedGitState,
|
|
83577
83898
|
lastPushedModels: init2.lastPushedModels,
|
|
83578
83899
|
lastPushedHarnessFingerprint: init2.lastPushedHarnessFingerprint,
|
|
@@ -83696,10 +84017,18 @@ var init_register_listeners = __esm(() => {
|
|
|
83696
84017
|
|
|
83697
84018
|
// src/daemon/entry/handlers/daemon-restart-cleanup.ts
|
|
83698
84019
|
var clearStaleSpawnedPidsEffect = () => exports_Effect.gen(function* () {
|
|
83699
|
-
const
|
|
84020
|
+
const outbox = yield* AgentLifecycleOutboxService;
|
|
83700
84021
|
const session2 = yield* DaemonSessionService;
|
|
83701
|
-
const
|
|
83702
|
-
|
|
84022
|
+
const emittedAt = Date.now();
|
|
84023
|
+
const result = yield* outbox.enqueue({
|
|
84024
|
+
kind: "cleared_all_pids",
|
|
84025
|
+
revisionKey: buildAgentLifecycleRevisionKey("cleared_all", {
|
|
84026
|
+
machineId: session2.machineId,
|
|
84027
|
+
emittedAt
|
|
84028
|
+
}),
|
|
84029
|
+
emittedAt
|
|
84030
|
+
});
|
|
84031
|
+
return result.clearedCount ?? 0;
|
|
83703
84032
|
}), reapOrphanCommandRunsEffect = () => exports_Effect.gen(function* () {
|
|
83704
84033
|
const backend2 = yield* BackendService;
|
|
83705
84034
|
const session2 = yield* DaemonSessionService;
|
|
@@ -83737,26 +84066,26 @@ import { createHash as createHash2 } from "node:crypto";
|
|
|
83737
84066
|
import {
|
|
83738
84067
|
appendFileSync,
|
|
83739
84068
|
existsSync as existsSync6,
|
|
83740
|
-
mkdirSync as
|
|
84069
|
+
mkdirSync as mkdirSync5,
|
|
83741
84070
|
readFileSync as readFileSync8,
|
|
83742
84071
|
renameSync,
|
|
83743
84072
|
unlinkSync,
|
|
83744
84073
|
writeFileSync as writeFileSync3
|
|
83745
84074
|
} from "node:fs";
|
|
83746
|
-
import { homedir as
|
|
83747
|
-
import { join as
|
|
84075
|
+
import { homedir as homedir6 } from "node:os";
|
|
84076
|
+
import { join as join18 } from "node:path";
|
|
83748
84077
|
function getUrlHash() {
|
|
83749
84078
|
const url2 = getConvexUrl();
|
|
83750
84079
|
return createHash2("sha256").update(url2).digest("hex").substring(0, 8);
|
|
83751
84080
|
}
|
|
83752
84081
|
function getChildPidsFilePath() {
|
|
83753
|
-
const dir =
|
|
83754
|
-
return
|
|
84082
|
+
const dir = join18(homedir6(), ".chatroom");
|
|
84083
|
+
return join18(dir, `daemon-children-${getUrlHash()}.pids`);
|
|
83755
84084
|
}
|
|
83756
84085
|
function ensureChatroomDir2() {
|
|
83757
|
-
const dir =
|
|
84086
|
+
const dir = join18(homedir6(), ".chatroom");
|
|
83758
84087
|
if (!existsSync6(dir)) {
|
|
83759
|
-
|
|
84088
|
+
mkdirSync5(dir, { recursive: true, mode: 448 });
|
|
83760
84089
|
}
|
|
83761
84090
|
}
|
|
83762
84091
|
function readPids() {
|
|
@@ -83869,7 +84198,7 @@ var init_orphan_tracker = __esm(() => {
|
|
|
83869
84198
|
// src/daemon/entry/handlers/process/output-store.ts
|
|
83870
84199
|
import { appendFile as appendFile2, mkdir as mkdir8, readFile as readFile6, rm as rm2 } from "node:fs/promises";
|
|
83871
84200
|
import { tmpdir } from "node:os";
|
|
83872
|
-
import { join as
|
|
84201
|
+
import { join as join19 } from "node:path";
|
|
83873
84202
|
|
|
83874
84203
|
class TempFileOutputStore {
|
|
83875
84204
|
state;
|
|
@@ -83932,7 +84261,7 @@ function createOutputStore(runId) {
|
|
|
83932
84261
|
if (!RUN_ID_RE.test(runId)) {
|
|
83933
84262
|
throw new Error(`Invalid runId: ${runId}`);
|
|
83934
84263
|
}
|
|
83935
|
-
const filePath =
|
|
84264
|
+
const filePath = join19(TEMP_DIR, `${runId}.log`);
|
|
83936
84265
|
return new TempFileOutputStore(filePath);
|
|
83937
84266
|
}
|
|
83938
84267
|
async function ensureTempDir() {
|
|
@@ -83946,7 +84275,7 @@ async function cleanOrphanTempFiles() {
|
|
|
83946
84275
|
var TAIL_WINDOW_BYTES, TEMP_DIR, RUN_ID_RE, MAX_TAIL_LINES_V2 = 50;
|
|
83947
84276
|
var init_output_store = __esm(() => {
|
|
83948
84277
|
TAIL_WINDOW_BYTES = 32 * 1024;
|
|
83949
|
-
TEMP_DIR =
|
|
84278
|
+
TEMP_DIR = join19(tmpdir(), "chatroom-cli", "runs");
|
|
83950
84279
|
RUN_ID_RE = /^[a-z0-9]+$/i;
|
|
83951
84280
|
});
|
|
83952
84281
|
|
|
@@ -84014,74 +84343,6 @@ async function logDaemonAuditEvent(logEvent, event) {
|
|
|
84014
84343
|
});
|
|
84015
84344
|
}
|
|
84016
84345
|
|
|
84017
|
-
// src/daemon/infrastructure/inbox/task-snapshot-state.ts
|
|
84018
|
-
function snapshotKey(taskId, role) {
|
|
84019
|
-
return `${taskId}:${role.toLowerCase()}`;
|
|
84020
|
-
}
|
|
84021
|
-
|
|
84022
|
-
class MachineTaskSnapshotState {
|
|
84023
|
-
snapshots = new Map;
|
|
84024
|
-
replace(snapshots) {
|
|
84025
|
-
this.snapshots.clear();
|
|
84026
|
-
this.upsert(snapshots);
|
|
84027
|
-
}
|
|
84028
|
-
applySignalPage(signals, snapshots) {
|
|
84029
|
-
const snapshotsByKey = new Map(snapshots.map((snapshot) => [
|
|
84030
|
-
snapshotKey(snapshot.taskId, snapshot.agentConfig.role),
|
|
84031
|
-
snapshot
|
|
84032
|
-
]));
|
|
84033
|
-
for (const signal of signals) {
|
|
84034
|
-
const key = snapshotKey(signal.taskId, signal.targetRole);
|
|
84035
|
-
const snapshot = snapshotsByKey.get(key);
|
|
84036
|
-
if (snapshot) {
|
|
84037
|
-
this.snapshots.set(key, snapshot);
|
|
84038
|
-
} else {
|
|
84039
|
-
this.snapshots.delete(key);
|
|
84040
|
-
}
|
|
84041
|
-
}
|
|
84042
|
-
}
|
|
84043
|
-
listForRole(chatroomId, role) {
|
|
84044
|
-
const roleLower = role.toLowerCase();
|
|
84045
|
-
return [...this.snapshots.values()].filter((snapshot) => snapshot.chatroomId === chatroomId && snapshot.agentConfig.role.toLowerCase() === roleLower);
|
|
84046
|
-
}
|
|
84047
|
-
listAll() {
|
|
84048
|
-
return [...this.snapshots.values()];
|
|
84049
|
-
}
|
|
84050
|
-
setDesiredState(chatroomId, role, desiredState) {
|
|
84051
|
-
const roleLower = role.toLowerCase();
|
|
84052
|
-
for (const [key, snapshot] of this.snapshots) {
|
|
84053
|
-
if (snapshot.chatroomId !== chatroomId || snapshot.agentConfig.role.toLowerCase() !== roleLower) {
|
|
84054
|
-
continue;
|
|
84055
|
-
}
|
|
84056
|
-
this.snapshots.set(key, {
|
|
84057
|
-
...snapshot,
|
|
84058
|
-
agentConfig: { ...snapshot.agentConfig, desiredState }
|
|
84059
|
-
});
|
|
84060
|
-
}
|
|
84061
|
-
}
|
|
84062
|
-
upsert(snapshots) {
|
|
84063
|
-
for (const snapshot of snapshots) {
|
|
84064
|
-
this.snapshots.set(snapshotKey(snapshot.taskId, snapshot.agentConfig.role), snapshot);
|
|
84065
|
-
}
|
|
84066
|
-
}
|
|
84067
|
-
}
|
|
84068
|
-
|
|
84069
|
-
// src/daemon/entry/native-delivery/native-delivery-session-registry.ts
|
|
84070
|
-
function registerNativeDeliverySession(ctx) {
|
|
84071
|
-
registered = {
|
|
84072
|
-
...ctx,
|
|
84073
|
-
taskSnapshotState: ctx.taskSnapshotState ?? new MachineTaskSnapshotState
|
|
84074
|
-
};
|
|
84075
|
-
}
|
|
84076
|
-
function unregisterNativeDeliverySession() {
|
|
84077
|
-
registered = null;
|
|
84078
|
-
}
|
|
84079
|
-
function getNativeDeliverySession() {
|
|
84080
|
-
return registered;
|
|
84081
|
-
}
|
|
84082
|
-
var registered = null;
|
|
84083
|
-
var init_native_delivery_session_registry = () => {};
|
|
84084
|
-
|
|
84085
84346
|
// ../../services/backend/config/reliability.ts
|
|
84086
84347
|
var HARNESS_SESSION_READY_TIMEOUT_MS = 5000, DAEMON_HEARTBEAT_INTERVAL_MS, DAEMON_HEARTBEAT_TTL_MS, AGENT_REQUEST_DEADLINE_MS = 120000, OBSERVED_FULL_PUSH_INTERVAL_MS, OBSERVED_SYNC_RECONCILE_MS, WORKSPACE_RECENCY_WINDOW_MS, WORKSPACE_LIST_RECONCILE_MS, CONNECTION_CLOSE_REQUEST_TTL_MS, ENHANCER_TERMINAL_JOB_RETENTION_MS;
|
|
84087
84348
|
var init_reliability = __esm(() => {
|
|
@@ -98811,8 +99072,6 @@ var init_assigned_task_snapshot_contract = __esm(() => {
|
|
|
98811
99072
|
assignedTo: exports_external.string().optional(),
|
|
98812
99073
|
lastSeenAction: exports_external.string().nullable().optional(),
|
|
98813
99074
|
lastStatus: exports_external.string().nullable().optional(),
|
|
98814
|
-
spawnedAgentPid: exports_external.number().optional(),
|
|
98815
|
-
desiredState: agentDesiredStateSchema.optional(),
|
|
98816
99075
|
sessionAugmentation: sessionAugmentationSchema.optional()
|
|
98817
99076
|
};
|
|
98818
99077
|
assignedTaskSignalSchema = exports_external.object(assignedTaskSignalBootstrapFields);
|
|
@@ -98889,13 +99148,99 @@ function getNativeDeliveryLedger() {
|
|
|
98889
99148
|
}
|
|
98890
99149
|
var sharedLedger;
|
|
98891
99150
|
|
|
99151
|
+
// src/daemon/infrastructure/agent-operational/agent-operational-read-model.ts
|
|
99152
|
+
function isOperationalDesiredRunning(row) {
|
|
99153
|
+
return row?.operationalState === "running" || row?.operationalState === "starting";
|
|
99154
|
+
}
|
|
99155
|
+
|
|
99156
|
+
class AgentOperationalReadModel {
|
|
99157
|
+
rows = new Map;
|
|
99158
|
+
replace(rows) {
|
|
99159
|
+
const changed = [];
|
|
99160
|
+
const nextKeys = new Set;
|
|
99161
|
+
for (const row of rows) {
|
|
99162
|
+
const key = roleKey(row.chatroomId, row.role);
|
|
99163
|
+
nextKeys.add(key);
|
|
99164
|
+
const prev = this.rows.get(key);
|
|
99165
|
+
if (!prev || prev.revisionKey !== row.revisionKey)
|
|
99166
|
+
changed.push({ chatroomId: row.chatroomId, role: row.role });
|
|
99167
|
+
this.rows.set(key, row);
|
|
99168
|
+
}
|
|
99169
|
+
for (const [key, prev] of this.rows) {
|
|
99170
|
+
if (!nextKeys.has(key)) {
|
|
99171
|
+
changed.push({ chatroomId: prev.chatroomId, role: prev.role });
|
|
99172
|
+
this.rows.delete(key);
|
|
99173
|
+
}
|
|
99174
|
+
}
|
|
99175
|
+
return changed;
|
|
99176
|
+
}
|
|
99177
|
+
get(chatroomId, role) {
|
|
99178
|
+
return this.rows.get(roleKey(chatroomId, role));
|
|
99179
|
+
}
|
|
99180
|
+
}
|
|
99181
|
+
var roleKey = (chatroomId, role) => `${chatroomId}:${role.toLowerCase()}`;
|
|
99182
|
+
|
|
99183
|
+
// src/daemon/infrastructure/inbox/task-snapshot-state.ts
|
|
99184
|
+
function snapshotKey(taskId, role) {
|
|
99185
|
+
return `${taskId}:${role.toLowerCase()}`;
|
|
99186
|
+
}
|
|
99187
|
+
|
|
99188
|
+
class MachineTaskSnapshotState {
|
|
99189
|
+
snapshots = new Map;
|
|
99190
|
+
replace(snapshots) {
|
|
99191
|
+
this.snapshots.clear();
|
|
99192
|
+
this.upsert(snapshots);
|
|
99193
|
+
}
|
|
99194
|
+
applySignalPage(signals, snapshots) {
|
|
99195
|
+
const snapshotsByKey = new Map(snapshots.map((snapshot) => [
|
|
99196
|
+
snapshotKey(snapshot.taskId, snapshot.agentConfig.role),
|
|
99197
|
+
snapshot
|
|
99198
|
+
]));
|
|
99199
|
+
for (const signal of signals) {
|
|
99200
|
+
const key = snapshotKey(signal.taskId, signal.targetRole);
|
|
99201
|
+
const snapshot = snapshotsByKey.get(key);
|
|
99202
|
+
if (snapshot) {
|
|
99203
|
+
this.snapshots.set(key, snapshot);
|
|
99204
|
+
} else {
|
|
99205
|
+
this.snapshots.delete(key);
|
|
99206
|
+
}
|
|
99207
|
+
}
|
|
99208
|
+
}
|
|
99209
|
+
listForRole(chatroomId, role) {
|
|
99210
|
+
const roleLower = role.toLowerCase();
|
|
99211
|
+
return [...this.snapshots.values()].filter((snapshot) => snapshot.chatroomId === chatroomId && snapshot.agentConfig.role.toLowerCase() === roleLower);
|
|
99212
|
+
}
|
|
99213
|
+
listAll() {
|
|
99214
|
+
return [...this.snapshots.values()];
|
|
99215
|
+
}
|
|
99216
|
+
upsert(snapshots) {
|
|
99217
|
+
for (const snapshot of snapshots) {
|
|
99218
|
+
this.snapshots.set(snapshotKey(snapshot.taskId, snapshot.agentConfig.role), snapshot);
|
|
99219
|
+
}
|
|
99220
|
+
}
|
|
99221
|
+
}
|
|
99222
|
+
|
|
99223
|
+
// src/daemon/entry/native-delivery/native-delivery-session-registry.ts
|
|
99224
|
+
function registerNativeDeliverySession(ctx) {
|
|
99225
|
+
registered = {
|
|
99226
|
+
...ctx,
|
|
99227
|
+
taskSnapshotState: ctx.taskSnapshotState ?? new MachineTaskSnapshotState,
|
|
99228
|
+
agentOperationalReadModel: ctx.agentOperationalReadModel ?? new AgentOperationalReadModel
|
|
99229
|
+
};
|
|
99230
|
+
}
|
|
99231
|
+
function unregisterNativeDeliverySession() {
|
|
99232
|
+
registered = null;
|
|
99233
|
+
}
|
|
99234
|
+
function getNativeDeliverySession() {
|
|
99235
|
+
return registered;
|
|
99236
|
+
}
|
|
99237
|
+
var registered = null;
|
|
99238
|
+
var init_native_delivery_session_registry = () => {};
|
|
99239
|
+
|
|
98892
99240
|
// src/daemon/domain/entities/assigned-task.ts
|
|
98893
99241
|
function isDeliverableTaskStatus(status3) {
|
|
98894
99242
|
return status3 === "pending" || status3 === "acknowledged";
|
|
98895
99243
|
}
|
|
98896
|
-
function isAgentDesiredRunning(desiredState) {
|
|
98897
|
-
return desiredState === "running";
|
|
98898
|
-
}
|
|
98899
99244
|
var init_assigned_task = () => {};
|
|
98900
99245
|
|
|
98901
99246
|
// src/daemon/domain/usecase/check-agent-slot.ts
|
|
@@ -98925,8 +99270,9 @@ function explainAgentReadyForNativeDeliveryBlock(task, slot) {
|
|
|
98925
99270
|
if (!isNativeHarness(agentConfig.agentHarness)) {
|
|
98926
99271
|
return `not_native_harness (harness=${agentConfig.agentHarness})`;
|
|
98927
99272
|
}
|
|
98928
|
-
|
|
98929
|
-
|
|
99273
|
+
const operational = getNativeDeliverySession()?.agentOperationalReadModel?.get(task.chatroomId, agentConfig.role);
|
|
99274
|
+
if (!isOperationalDesiredRunning(operational)) {
|
|
99275
|
+
return `operational_state_not_running (state=${operational?.operationalState ?? "missing"})`;
|
|
98930
99276
|
}
|
|
98931
99277
|
if (!slot) {
|
|
98932
99278
|
return agentConfig.spawnedAgentPid == null ? "spawned_pid_missing" : `slot_missing (expectedPid=${agentConfig.spawnedAgentPid})`;
|
|
@@ -98954,6 +99300,7 @@ function isDeliverableNativeTaskStatus(status3) {
|
|
|
98954
99300
|
}
|
|
98955
99301
|
var init_native_ready_invariant = __esm(() => {
|
|
98956
99302
|
init_types();
|
|
99303
|
+
init_native_delivery_session_registry();
|
|
98957
99304
|
init_assigned_task();
|
|
98958
99305
|
init_check_agent_slot();
|
|
98959
99306
|
});
|
|
@@ -99466,20 +99813,20 @@ function mapAssignedTaskSnapshotList(rows) {
|
|
|
99466
99813
|
}
|
|
99467
99814
|
|
|
99468
99815
|
// src/daemon/entry/restart-orchestrator-in-flight.ts
|
|
99469
|
-
function
|
|
99816
|
+
function roleKey2(chatroomId, role) {
|
|
99470
99817
|
return `${chatroomId}:${role.toLowerCase()}`;
|
|
99471
99818
|
}
|
|
99472
99819
|
function markRestartOrchestratorInFlight(chatroomId, role, correlationId) {
|
|
99473
|
-
inFlight.set(
|
|
99820
|
+
inFlight.set(roleKey2(chatroomId, role), correlationId);
|
|
99474
99821
|
}
|
|
99475
99822
|
function clearRestartOrchestratorInFlight(chatroomId, role, correlationId) {
|
|
99476
|
-
const key =
|
|
99823
|
+
const key = roleKey2(chatroomId, role);
|
|
99477
99824
|
if (correlationId !== undefined && inFlight.get(key) !== correlationId)
|
|
99478
99825
|
return;
|
|
99479
99826
|
inFlight.delete(key);
|
|
99480
99827
|
}
|
|
99481
99828
|
function isRestartOrchestratorInFlight(chatroomId, role) {
|
|
99482
|
-
return inFlight.has(
|
|
99829
|
+
return inFlight.has(roleKey2(chatroomId, role));
|
|
99483
99830
|
}
|
|
99484
99831
|
function filterSnapshotsExcludingRestartInFlight(snapshots) {
|
|
99485
99832
|
return snapshots.filter((row) => !isRestartOrchestratorInFlight(row.chatroomId, row.agentConfig.role));
|
|
@@ -99490,7 +99837,7 @@ var init_restart_orchestrator_in_flight = __esm(() => {
|
|
|
99490
99837
|
});
|
|
99491
99838
|
|
|
99492
99839
|
// src/daemon/entry/role-delivery-state.ts
|
|
99493
|
-
function
|
|
99840
|
+
function roleKey3(chatroomId, role) {
|
|
99494
99841
|
return `${chatroomId}:${role.toLowerCase()}`;
|
|
99495
99842
|
}
|
|
99496
99843
|
|
|
@@ -99499,10 +99846,10 @@ class RoleDeliveryState {
|
|
|
99499
99846
|
inFlight = new Set;
|
|
99500
99847
|
nativeNudgeFailures = new Map;
|
|
99501
99848
|
getGeneration(chatroomId, role) {
|
|
99502
|
-
return this.generation.get(
|
|
99849
|
+
return this.generation.get(roleKey3(chatroomId, role)) ?? 0;
|
|
99503
99850
|
}
|
|
99504
99851
|
resetDeliveryState(chatroomId, role) {
|
|
99505
|
-
const key =
|
|
99852
|
+
const key = roleKey3(chatroomId, role);
|
|
99506
99853
|
const next4 = (this.generation.get(key) ?? 0) + 1;
|
|
99507
99854
|
this.generation.set(key, next4);
|
|
99508
99855
|
this.inFlight.delete(key);
|
|
@@ -99510,26 +99857,26 @@ class RoleDeliveryState {
|
|
|
99510
99857
|
return next4;
|
|
99511
99858
|
}
|
|
99512
99859
|
tryAcquireDelivery(chatroomId, role) {
|
|
99513
|
-
const key =
|
|
99860
|
+
const key = roleKey3(chatroomId, role);
|
|
99514
99861
|
if (this.inFlight.has(key))
|
|
99515
99862
|
return false;
|
|
99516
99863
|
this.inFlight.add(key);
|
|
99517
99864
|
return true;
|
|
99518
99865
|
}
|
|
99519
99866
|
releaseDelivery(chatroomId, role) {
|
|
99520
|
-
this.inFlight.delete(
|
|
99867
|
+
this.inFlight.delete(roleKey3(chatroomId, role));
|
|
99521
99868
|
}
|
|
99522
99869
|
recordNativeNudgeFailure(chatroomId, role) {
|
|
99523
|
-
const key =
|
|
99870
|
+
const key = roleKey3(chatroomId, role);
|
|
99524
99871
|
const count3 = (this.nativeNudgeFailures.get(key) ?? 0) + 1;
|
|
99525
99872
|
this.nativeNudgeFailures.set(key, count3);
|
|
99526
99873
|
return count3;
|
|
99527
99874
|
}
|
|
99528
99875
|
clearNativeNudgeFailures(chatroomId, role) {
|
|
99529
|
-
this.nativeNudgeFailures.delete(
|
|
99876
|
+
this.nativeNudgeFailures.delete(roleKey3(chatroomId, role));
|
|
99530
99877
|
}
|
|
99531
99878
|
getNativeNudgeFailures(chatroomId, role) {
|
|
99532
|
-
return this.nativeNudgeFailures.get(
|
|
99879
|
+
return this.nativeNudgeFailures.get(roleKey3(chatroomId, role)) ?? 0;
|
|
99533
99880
|
}
|
|
99534
99881
|
}
|
|
99535
99882
|
function getRoleDeliveryState() {
|
|
@@ -99916,8 +100263,6 @@ function createStartAgentDeps(agentMgr, session2) {
|
|
|
99916
100263
|
return {
|
|
99917
100264
|
agentProcessManager: {
|
|
99918
100265
|
ensureRunning: async (args2) => {
|
|
99919
|
-
const taskSnapshotState = getNativeDeliverySession()?.taskSnapshotState;
|
|
99920
|
-
taskSnapshotState?.setDesiredState(args2.chatroomId, args2.role, "running");
|
|
99921
100266
|
const result = await exports_Effect.runPromise(agentMgr.ensureRunning({
|
|
99922
100267
|
chatroomId: args2.chatroomId,
|
|
99923
100268
|
role: args2.role,
|
|
@@ -99927,9 +100272,7 @@ function createStartAgentDeps(agentMgr, session2) {
|
|
|
99927
100272
|
reason: args2.reason,
|
|
99928
100273
|
wantResume: args2.wantResume
|
|
99929
100274
|
}));
|
|
99930
|
-
if (!result.success) {
|
|
99931
|
-
taskSnapshotState?.setDesiredState(args2.chatroomId, args2.role, "stopped");
|
|
99932
|
-
}
|
|
100275
|
+
if (!result.success) {}
|
|
99933
100276
|
return result;
|
|
99934
100277
|
}
|
|
99935
100278
|
},
|
|
@@ -100052,7 +100395,6 @@ function createRecoverAgentStateDeps(agentMgr, session2) {
|
|
|
100052
100395
|
var init_agent_control_bridge = __esm(() => {
|
|
100053
100396
|
init_esm();
|
|
100054
100397
|
init_api3();
|
|
100055
|
-
init_native_delivery_session_registry();
|
|
100056
100398
|
init_restart_orchestrator();
|
|
100057
100399
|
});
|
|
100058
100400
|
|
|
@@ -100188,9 +100530,9 @@ var init_daemon_process_scan = __esm(() => {
|
|
|
100188
100530
|
|
|
100189
100531
|
// src/commands/machine/pid.ts
|
|
100190
100532
|
import { createHash as createHash3 } from "node:crypto";
|
|
100191
|
-
import { existsSync as existsSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync4, unlinkSync as unlinkSync2, mkdirSync as
|
|
100192
|
-
import { homedir as
|
|
100193
|
-
import { join as
|
|
100533
|
+
import { existsSync as existsSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync4, unlinkSync as unlinkSync2, mkdirSync as mkdirSync6 } from "node:fs";
|
|
100534
|
+
import { homedir as homedir7 } from "node:os";
|
|
100535
|
+
import { join as join20 } from "node:path";
|
|
100194
100536
|
function getUrlHash2() {
|
|
100195
100537
|
const url3 = getConvexUrl();
|
|
100196
100538
|
return createHash3("sha256").update(url3).digest("hex").substring(0, 8);
|
|
@@ -100200,11 +100542,11 @@ function getPidFileName() {
|
|
|
100200
100542
|
}
|
|
100201
100543
|
function ensureChatroomDir3() {
|
|
100202
100544
|
if (!existsSync8(CHATROOM_DIR4)) {
|
|
100203
|
-
|
|
100545
|
+
mkdirSync6(CHATROOM_DIR4, { recursive: true, mode: 448 });
|
|
100204
100546
|
}
|
|
100205
100547
|
}
|
|
100206
100548
|
function getPidFilePath() {
|
|
100207
|
-
return
|
|
100549
|
+
return join20(CHATROOM_DIR4, getPidFileName());
|
|
100208
100550
|
}
|
|
100209
100551
|
function isProcessRunning(pid) {
|
|
100210
100552
|
try {
|
|
@@ -100350,7 +100692,7 @@ var CHATROOM_DIR4, LOCK_RETRY_INTERVAL_MS = 500, LOCK_RETRY_MAX_WAIT_MS = 15000,
|
|
|
100350
100692
|
var init_pid = __esm(() => {
|
|
100351
100693
|
init_daemon_process_scan();
|
|
100352
100694
|
init_client2();
|
|
100353
|
-
CHATROOM_DIR4 =
|
|
100695
|
+
CHATROOM_DIR4 = join20(homedir7(), ".chatroom");
|
|
100354
100696
|
});
|
|
100355
100697
|
|
|
100356
100698
|
// src/infrastructure/machine/crash-loop-tracker.ts
|
|
@@ -102096,9 +102438,8 @@ class AgentProcessManager {
|
|
|
102096
102438
|
console.log(` ⚠️ ${failureLog}: ${err.message}`);
|
|
102097
102439
|
this.queueExitRetry({ role, args: exitArgs });
|
|
102098
102440
|
});
|
|
102099
|
-
this.deps.
|
|
102100
|
-
|
|
102101
|
-
});
|
|
102441
|
+
const emittedAt = this.deps.clock.now();
|
|
102442
|
+
this.deps.lifecycleOutbox.enqueue(buildExitedLifecycleFact(exitArgs, emittedAt)).catch((err) => console.log(` ⚠️ Failed to enqueue agent exited lifecycle fact: ${err.message}`));
|
|
102102
102443
|
}
|
|
102103
102444
|
async clearAgentPidQuietly(chatroomId, role) {
|
|
102104
102445
|
try {
|
|
@@ -102502,28 +102843,23 @@ class AgentProcessManager {
|
|
|
102502
102843
|
}).catch((err) => {
|
|
102503
102844
|
console.log(` ⚠️ Failed to record agent.started event: ${err.message}`);
|
|
102504
102845
|
});
|
|
102505
|
-
this.deps.
|
|
102506
|
-
|
|
102507
|
-
|
|
102846
|
+
const emittedAt = this.deps.clock.now();
|
|
102847
|
+
this.deps.lifecycleOutbox.enqueue({
|
|
102848
|
+
kind: "spawned",
|
|
102508
102849
|
chatroomId: opts.chatroomId,
|
|
102509
102850
|
role: opts.role,
|
|
102510
102851
|
pid,
|
|
102511
102852
|
model: opts.model,
|
|
102512
102853
|
reason: opts.reason,
|
|
102513
|
-
...spawnResult.harnessSessionId ? { harnessSessionId: spawnResult.harnessSessionId } : {}
|
|
102514
|
-
|
|
102515
|
-
|
|
102516
|
-
|
|
102517
|
-
|
|
102518
|
-
|
|
102519
|
-
|
|
102520
|
-
|
|
102521
|
-
|
|
102522
|
-
pid,
|
|
102523
|
-
model: opts.model
|
|
102524
|
-
}).catch((err) => {
|
|
102525
|
-
console.log(` ⚠️ Failed to update PID in backend: ${err.message}`);
|
|
102526
|
-
});
|
|
102854
|
+
...spawnResult.harnessSessionId ? { harnessSessionId: spawnResult.harnessSessionId } : {},
|
|
102855
|
+
revisionKey: buildAgentLifecycleRevisionKey("spawned", {
|
|
102856
|
+
chatroomId: opts.chatroomId,
|
|
102857
|
+
role: opts.role,
|
|
102858
|
+
pid,
|
|
102859
|
+
emittedAt
|
|
102860
|
+
}),
|
|
102861
|
+
emittedAt
|
|
102862
|
+
}).catch((err) => console.log(` ⚠️ Failed to enqueue agent spawned lifecycle fact: ${err.message}`));
|
|
102527
102863
|
}
|
|
102528
102864
|
registerSpawnCallbacks(slot, opts, spawnResult, pid) {
|
|
102529
102865
|
if (spawnResult.onLogLine) {
|
|
@@ -102878,6 +103214,11 @@ function assembleDaemonSessionInit(args2) {
|
|
|
102878
103214
|
} = args2;
|
|
102879
103215
|
deps.backend.mutation = (endpoint, args3) => client4.mutation(endpoint, args3);
|
|
102880
103216
|
deps.backend.query = (endpoint, args3) => client4.query(endpoint, args3);
|
|
103217
|
+
const agentLifecycleOutbox = createAgentLifecycleOutboxForSession({
|
|
103218
|
+
sessionId: typedSessionId,
|
|
103219
|
+
machineId,
|
|
103220
|
+
backend: deps.backend
|
|
103221
|
+
});
|
|
102881
103222
|
deps.agentProcessManager = new AgentProcessManager({
|
|
102882
103223
|
logEvent: activeLogEvent ?? (async () => {
|
|
102883
103224
|
return;
|
|
@@ -102893,7 +103234,8 @@ function assembleDaemonSessionInit(args2) {
|
|
|
102893
103234
|
persistence: deps.machine,
|
|
102894
103235
|
spawning: deps.spawning,
|
|
102895
103236
|
crashLoop: new CrashLoopTracker,
|
|
102896
|
-
convexUrl
|
|
103237
|
+
convexUrl,
|
|
103238
|
+
lifecycleOutbox: { enqueue: (fact) => enqueueAgentLifecycleFact(agentLifecycleOutbox, machineId, fact) }
|
|
102897
103239
|
});
|
|
102898
103240
|
return {
|
|
102899
103241
|
client: client4,
|
|
@@ -102906,6 +103248,7 @@ function assembleDaemonSessionInit(args2) {
|
|
|
102906
103248
|
machine: deps.machine,
|
|
102907
103249
|
spawning: deps.spawning,
|
|
102908
103250
|
agentProcessManager: deps.agentProcessManager,
|
|
103251
|
+
agentLifecycleOutbox,
|
|
102909
103252
|
events: new DaemonEventBus,
|
|
102910
103253
|
agentServices,
|
|
102911
103254
|
lastPushedGitState: new Map,
|
|
@@ -103138,6 +103481,8 @@ var init_init_daemon = __esm(() => {
|
|
|
103138
103481
|
init_daemon_startup_log();
|
|
103139
103482
|
init_orphan_tracker();
|
|
103140
103483
|
init_output_store();
|
|
103484
|
+
init_agent_lifecycle_outbox_runtime();
|
|
103485
|
+
init_agent_lifecycle_outbox_runtime();
|
|
103141
103486
|
init_state_recovery();
|
|
103142
103487
|
init_pid();
|
|
103143
103488
|
init_storage();
|
|
@@ -105768,6 +106113,14 @@ var init_workspace_cache = __esm(() => {
|
|
|
105768
106113
|
|
|
105769
106114
|
// src/daemon/infrastructure/git/run-command.ts
|
|
105770
106115
|
import { spawn as spawn4 } from "node:child_process";
|
|
106116
|
+
function enqueueGit(cwd, task) {
|
|
106117
|
+
const tail = gitQueues.get(cwd) ?? Promise.resolve();
|
|
106118
|
+
const run3 = tail.then(task, task);
|
|
106119
|
+
gitQueues.set(cwd, run3.catch(() => {
|
|
106120
|
+
return;
|
|
106121
|
+
}));
|
|
106122
|
+
return run3;
|
|
106123
|
+
}
|
|
105771
106124
|
function runCommandSpawn(command, args2, cwd, options) {
|
|
105772
106125
|
const successExitCodes = options?.successExitCodes ?? [0];
|
|
105773
106126
|
return new Promise((resolve4) => {
|
|
@@ -105813,7 +106166,7 @@ function runCommandSpawn(command, args2, cwd, options) {
|
|
|
105813
106166
|
});
|
|
105814
106167
|
}
|
|
105815
106168
|
function runGit(args2, cwd, options) {
|
|
105816
|
-
return runCommandSpawn("git", args2, cwd, options);
|
|
106169
|
+
return enqueueGit(cwd, () => runCommandSpawn("git", options?.readOnly ? ["--no-optional-locks", ...args2] : args2, cwd, options));
|
|
105817
106170
|
}
|
|
105818
106171
|
function runGh(args2, cwd, options) {
|
|
105819
106172
|
return runCommandSpawn("gh", args2, cwd, {
|
|
@@ -105821,7 +106174,7 @@ function runGh(args2, cwd, options) {
|
|
|
105821
106174
|
env: { ...process.env, NO_COLOR: "1" }
|
|
105822
106175
|
});
|
|
105823
106176
|
}
|
|
105824
|
-
var DEFAULT_GIT_ENV;
|
|
106177
|
+
var DEFAULT_GIT_ENV, gitQueues;
|
|
105825
106178
|
var init_run_command = __esm(() => {
|
|
105826
106179
|
DEFAULT_GIT_ENV = {
|
|
105827
106180
|
...process.env,
|
|
@@ -105829,6 +106182,7 @@ var init_run_command = __esm(() => {
|
|
|
105829
106182
|
GIT_PAGER: "cat",
|
|
105830
106183
|
NO_COLOR: "1"
|
|
105831
106184
|
};
|
|
106185
|
+
gitQueues = new Map;
|
|
105832
106186
|
});
|
|
105833
106187
|
|
|
105834
106188
|
// src/daemon/infrastructure/git/types.ts
|
|
@@ -105838,6 +106192,9 @@ function makeGitStateKey(machineId, workingDir) {
|
|
|
105838
106192
|
var FULL_DIFF_MAX_BYTES = 500000, COMMITS_PER_PAGE = 20;
|
|
105839
106193
|
|
|
105840
106194
|
// src/daemon/infrastructure/git/git-reader.ts
|
|
106195
|
+
function runGit2(args2, cwd, options) {
|
|
106196
|
+
return runGit(cwd ? args2 : args2, cwd, { ...options, readOnly: true });
|
|
106197
|
+
}
|
|
105841
106198
|
function repoArgs(repoSlug) {
|
|
105842
106199
|
return repoSlug ? ["--repo", repoSlug] : [];
|
|
105843
106200
|
}
|
|
@@ -105854,14 +106211,14 @@ function isEmptyRepo(stderr) {
|
|
|
105854
106211
|
return stderr.includes("does not have any commits yet") || stderr.includes("no commits yet") || stderr.includes("ambiguous argument 'HEAD'") || stderr.includes("unknown revision or path");
|
|
105855
106212
|
}
|
|
105856
106213
|
async function listUntrackedFiles(workingDir) {
|
|
105857
|
-
const result = await
|
|
106214
|
+
const result = await runGit2(["ls-files", "--others", "--exclude-standard"], workingDir);
|
|
105858
106215
|
if ("error" in result)
|
|
105859
106216
|
return [];
|
|
105860
106217
|
return result.stdout.split(`
|
|
105861
106218
|
`).map((line) => line.trim()).filter(Boolean);
|
|
105862
106219
|
}
|
|
105863
106220
|
async function getUntrackedFileDiff(workingDir, filePath) {
|
|
105864
|
-
const result = await
|
|
106221
|
+
const result = await runGit2(["diff", "--no-index", "--", NULL_DEVICE, filePath], workingDir, {
|
|
105865
106222
|
successExitCodes: [0, 1]
|
|
105866
106223
|
});
|
|
105867
106224
|
if ("error" in result)
|
|
@@ -105922,7 +106279,7 @@ function truncateDiffContent(raw) {
|
|
|
105922
106279
|
return { status: "available", content: raw, truncated: false };
|
|
105923
106280
|
}
|
|
105924
106281
|
async function runTrackedHeadDiff(workingDir, args2, options) {
|
|
105925
|
-
const result = await
|
|
106282
|
+
const result = await runGit2(args2, workingDir, options);
|
|
105926
106283
|
if ("error" in result) {
|
|
105927
106284
|
const errMsg = result.error.message;
|
|
105928
106285
|
if (isEmptyRepo(errMsg))
|
|
@@ -105951,13 +106308,13 @@ function classifyError(errMessage) {
|
|
|
105951
106308
|
return { status: "error", message: errMessage.trim() };
|
|
105952
106309
|
}
|
|
105953
106310
|
async function isGitRepo(workingDir) {
|
|
105954
|
-
const result = await
|
|
106311
|
+
const result = await runGit2(["rev-parse", "--git-dir"], workingDir);
|
|
105955
106312
|
if ("error" in result)
|
|
105956
106313
|
return false;
|
|
105957
106314
|
return result.stdout.trim().length > 0;
|
|
105958
106315
|
}
|
|
105959
106316
|
async function getBranch(workingDir) {
|
|
105960
|
-
const result = await
|
|
106317
|
+
const result = await runGit2(["rev-parse", "--abbrev-ref", "HEAD"], workingDir);
|
|
105961
106318
|
if ("error" in result) {
|
|
105962
106319
|
const errMsg = result.error.message;
|
|
105963
106320
|
if (errMsg.includes("unknown revision") || errMsg.includes("No such file or directory") || errMsg.includes("does not have any commits")) {
|
|
@@ -105972,7 +106329,7 @@ async function getBranch(workingDir) {
|
|
|
105972
106329
|
return { status: "available", branch };
|
|
105973
106330
|
}
|
|
105974
106331
|
async function isDirty(workingDir) {
|
|
105975
|
-
const result = await
|
|
106332
|
+
const result = await runGit2(["status", "--porcelain"], workingDir);
|
|
105976
106333
|
if ("error" in result)
|
|
105977
106334
|
return false;
|
|
105978
106335
|
return result.stdout.trim().length > 0;
|
|
@@ -106042,7 +106399,7 @@ async function getRecentCommits(workingDir, count3 = 20, skip = 0) {
|
|
|
106042
106399
|
if (skip > 0)
|
|
106043
106400
|
logArgs.push(`--skip=${skip}`);
|
|
106044
106401
|
logArgs.push(`--format=${format4}`);
|
|
106045
|
-
const result = await
|
|
106402
|
+
const result = await runGit2(logArgs, workingDir);
|
|
106046
106403
|
if ("error" in result) {
|
|
106047
106404
|
return [];
|
|
106048
106405
|
}
|
|
@@ -106064,7 +106421,7 @@ async function getRecentCommits(workingDir, count3 = 20, skip = 0) {
|
|
|
106064
106421
|
return commits;
|
|
106065
106422
|
}
|
|
106066
106423
|
async function getCommitDetail(workingDir, sha) {
|
|
106067
|
-
const result = await
|
|
106424
|
+
const result = await runGit2(["show", sha, "--format=", "--stat", "-p"], workingDir);
|
|
106068
106425
|
if ("error" in result) {
|
|
106069
106426
|
const errMsg = result.error.message;
|
|
106070
106427
|
const classified = classifyError(errMsg);
|
|
@@ -106085,7 +106442,7 @@ async function getCommitDetail(workingDir, sha) {
|
|
|
106085
106442
|
}
|
|
106086
106443
|
async function getCommitMetadata(workingDir, sha) {
|
|
106087
106444
|
const format4 = "%s%x1f%b%x1f%an%x1f%aI";
|
|
106088
|
-
const result = await
|
|
106445
|
+
const result = await runGit2(["log", "-1", `--format=${format4}`, sha], workingDir);
|
|
106089
106446
|
if ("error" in result)
|
|
106090
106447
|
return null;
|
|
106091
106448
|
const output = result.stdout.trim();
|
|
@@ -106111,7 +106468,7 @@ function parseRepoSlug(remoteUrl) {
|
|
|
106111
106468
|
return null;
|
|
106112
106469
|
}
|
|
106113
106470
|
async function getOriginRepoSlug(cwd) {
|
|
106114
|
-
const result = await
|
|
106471
|
+
const result = await runGit2(["remote", "get-url", "origin"], cwd);
|
|
106115
106472
|
if ("error" in result)
|
|
106116
106473
|
return null;
|
|
106117
106474
|
const url3 = result.stdout.trim();
|
|
@@ -106248,7 +106605,7 @@ async function getPRCommits(cwd, prNumber) {
|
|
|
106248
106605
|
}
|
|
106249
106606
|
}
|
|
106250
106607
|
async function getRemotes(cwd) {
|
|
106251
|
-
const result = await
|
|
106608
|
+
const result = await runGit2(["remote", "-v"], cwd);
|
|
106252
106609
|
if ("error" in result)
|
|
106253
106610
|
return [];
|
|
106254
106611
|
if (!result.stdout.trim())
|
|
@@ -106272,14 +106629,14 @@ async function getRemotes(cwd) {
|
|
|
106272
106629
|
return remotes;
|
|
106273
106630
|
}
|
|
106274
106631
|
async function getCommitsAhead(workingDir) {
|
|
106275
|
-
const result = await
|
|
106632
|
+
const result = await runGit2(["rev-list", "--count", "@{upstream}..HEAD"], workingDir);
|
|
106276
106633
|
if ("error" in result)
|
|
106277
106634
|
return 0;
|
|
106278
106635
|
const count3 = parseInt(result.stdout.trim(), 10);
|
|
106279
106636
|
return Number.isNaN(count3) ? 0 : count3;
|
|
106280
106637
|
}
|
|
106281
106638
|
async function getCommitsBehind(workingDir) {
|
|
106282
|
-
const result = await
|
|
106639
|
+
const result = await runGit2(["rev-list", "--count", "HEAD..@{upstream}"], workingDir);
|
|
106283
106640
|
if ("error" in result)
|
|
106284
106641
|
return 0;
|
|
106285
106642
|
const count3 = parseInt(result.stdout.trim(), 10);
|
|
@@ -106373,16 +106730,12 @@ class GitStatePipeline {
|
|
|
106373
106730
|
const results = new Map(preCollected);
|
|
106374
106731
|
if (this.fields.length === 0)
|
|
106375
106732
|
return results;
|
|
106376
|
-
const
|
|
106733
|
+
for (const field of this.fields.filter((f) => !results.has(f.key))) {
|
|
106377
106734
|
try {
|
|
106378
|
-
|
|
106379
|
-
return { key: field.key, raw };
|
|
106735
|
+
results.set(field.key, await field.collect(workingDir));
|
|
106380
106736
|
} catch {
|
|
106381
|
-
|
|
106737
|
+
results.set(field.key, field.defaultValue);
|
|
106382
106738
|
}
|
|
106383
|
-
}));
|
|
106384
|
-
for (const { key, raw } of entries2) {
|
|
106385
|
-
results.set(key, raw);
|
|
106386
106739
|
}
|
|
106387
106740
|
return results;
|
|
106388
106741
|
}
|
|
@@ -107547,16 +107900,16 @@ var init_jsonc = __esm(() => {
|
|
|
107547
107900
|
|
|
107548
107901
|
// src/infrastructure/services/workspace/workspace-resolver.ts
|
|
107549
107902
|
import { readFile as readFile7, readdir, stat as stat3 } from "node:fs/promises";
|
|
107550
|
-
import { join as
|
|
107903
|
+
import { join as join21, basename, resolve as resolve4 } from "node:path";
|
|
107551
107904
|
async function resolveGlobPatternStar(rootDir, cleaned) {
|
|
107552
|
-
const parentDir =
|
|
107905
|
+
const parentDir = join21(rootDir, cleaned.slice(0, -2));
|
|
107553
107906
|
try {
|
|
107554
107907
|
const entries2 = await readdir(parentDir, { withFileTypes: true });
|
|
107555
107908
|
const dirs = [];
|
|
107556
107909
|
for (const entry of entries2) {
|
|
107557
107910
|
if (!entry.isDirectory())
|
|
107558
107911
|
continue;
|
|
107559
|
-
const dirPath =
|
|
107912
|
+
const dirPath = join21(parentDir, entry.name);
|
|
107560
107913
|
if (resolve4(dirPath).startsWith(resolve4(rootDir))) {
|
|
107561
107914
|
dirs.push(dirPath);
|
|
107562
107915
|
}
|
|
@@ -107567,7 +107920,7 @@ async function resolveGlobPatternStar(rootDir, cleaned) {
|
|
|
107567
107920
|
}
|
|
107568
107921
|
}
|
|
107569
107922
|
async function resolveLiteralPath(rootDir, cleaned) {
|
|
107570
|
-
const dir =
|
|
107923
|
+
const dir = join21(rootDir, cleaned);
|
|
107571
107924
|
try {
|
|
107572
107925
|
if (!resolve4(dir).startsWith(resolve4(rootDir)))
|
|
107573
107926
|
return [];
|
|
@@ -107587,7 +107940,7 @@ async function resolveGlobPattern(rootDir, pattern) {
|
|
|
107587
107940
|
}
|
|
107588
107941
|
async function readPackageJson(dir) {
|
|
107589
107942
|
try {
|
|
107590
|
-
const content = await readFile7(
|
|
107943
|
+
const content = await readFile7(join21(dir, "package.json"), "utf-8");
|
|
107591
107944
|
const pkg = JSON.parse(content);
|
|
107592
107945
|
return {
|
|
107593
107946
|
name: pkg.name || basename(dir),
|
|
@@ -107599,7 +107952,7 @@ async function readPackageJson(dir) {
|
|
|
107599
107952
|
}
|
|
107600
107953
|
async function readPnpmWorkspacePatterns(rootDir) {
|
|
107601
107954
|
try {
|
|
107602
|
-
const content = await readFile7(
|
|
107955
|
+
const content = await readFile7(join21(rootDir, "pnpm-workspace.yaml"), "utf-8");
|
|
107603
107956
|
const patterns = [];
|
|
107604
107957
|
let inPackages = false;
|
|
107605
107958
|
for (const line of content.split(`
|
|
@@ -107626,7 +107979,7 @@ async function readPnpmWorkspacePatterns(rootDir) {
|
|
|
107626
107979
|
}
|
|
107627
107980
|
async function readPackageJsonWorkspacePatterns(rootDir) {
|
|
107628
107981
|
try {
|
|
107629
|
-
const content = await readFile7(
|
|
107982
|
+
const content = await readFile7(join21(rootDir, "package.json"), "utf-8");
|
|
107630
107983
|
const pkg = JSON.parse(content);
|
|
107631
107984
|
if (!pkg.workspaces)
|
|
107632
107985
|
return [];
|
|
@@ -107707,11 +108060,11 @@ var MAX_NAME_LENGTH = 256;
|
|
|
107707
108060
|
|
|
107708
108061
|
// src/infrastructure/services/workspace/command-discovery.ts
|
|
107709
108062
|
import { access as access2, readFile as readFile8 } from "node:fs/promises";
|
|
107710
|
-
import { join as
|
|
108063
|
+
import { join as join22, relative, basename as basename2 } from "node:path";
|
|
107711
108064
|
async function detectPackageManager(workingDir) {
|
|
107712
108065
|
for (const { file: file2, manager } of LOCKFILE_MAP) {
|
|
107713
108066
|
try {
|
|
107714
|
-
await access2(
|
|
108067
|
+
await access2(join22(workingDir, file2));
|
|
107715
108068
|
return manager;
|
|
107716
108069
|
} catch {}
|
|
107717
108070
|
}
|
|
@@ -107780,7 +108133,7 @@ function collectRootScriptCommands(scripts, pm, scriptPrefix, rootSw) {
|
|
|
107780
108133
|
}
|
|
107781
108134
|
async function readRootPackageJson(workingDir, pm, scriptPrefix) {
|
|
107782
108135
|
let rootPackageName = basename2(workingDir);
|
|
107783
|
-
const pkg = await readJsonFile(
|
|
108136
|
+
const pkg = await readJsonFile(join22(workingDir, "package.json"), "root package.json");
|
|
107784
108137
|
if (!pkg)
|
|
107785
108138
|
return { commands: [], rootPackageName };
|
|
107786
108139
|
if (pkg.name)
|
|
@@ -107796,7 +108149,7 @@ async function readRootPackageJson(workingDir, pm, scriptPrefix) {
|
|
|
107796
108149
|
}
|
|
107797
108150
|
async function readTurboJson(workingDir, _turboPrefix, _rootSubWorkspace) {
|
|
107798
108151
|
const turboTaskNames = [];
|
|
107799
|
-
const turbo = await readJsonFile(
|
|
108152
|
+
const turbo = await readJsonFile(join22(workingDir, "turbo.json"), "turbo.json");
|
|
107800
108153
|
if (!turbo?.tasks || typeof turbo.tasks !== "object")
|
|
107801
108154
|
return turboTaskNames;
|
|
107802
108155
|
for (const taskName of Object.keys(turbo.tasks)) {
|
|
@@ -107809,7 +108162,7 @@ async function readTurboJson(workingDir, _turboPrefix, _rootSubWorkspace) {
|
|
|
107809
108162
|
async function readDenoJson(workingDir) {
|
|
107810
108163
|
const commands = [];
|
|
107811
108164
|
for (const fileName of ["deno.json", "deno.jsonc"]) {
|
|
107812
|
-
const deno = await readJsonFile(
|
|
108165
|
+
const deno = await readJsonFile(join22(workingDir, fileName), fileName);
|
|
107813
108166
|
if (!deno?.tasks || typeof deno.tasks !== "object")
|
|
107814
108167
|
continue;
|
|
107815
108168
|
const pkgName = deno.name ?? basename2(workingDir);
|
|
@@ -107832,7 +108185,7 @@ async function readMakefile(workingDir) {
|
|
|
107832
108185
|
const commands = [];
|
|
107833
108186
|
for (const fileName of ["Makefile", "makefile"]) {
|
|
107834
108187
|
try {
|
|
107835
|
-
const content = await readFile8(
|
|
108188
|
+
const content = await readFile8(join22(workingDir, fileName), "utf-8");
|
|
107836
108189
|
const targets = parseMakefileTargets(content);
|
|
107837
108190
|
if (targets.length === 0)
|
|
107838
108191
|
continue;
|
|
@@ -110038,7 +110391,7 @@ var init_assert_registered_working_dir = __esm(() => {
|
|
|
110038
110391
|
|
|
110039
110392
|
// src/infrastructure/services/workspace/workspace-path-security.ts
|
|
110040
110393
|
import { realpath } from "node:fs/promises";
|
|
110041
|
-
import { dirname as
|
|
110394
|
+
import { dirname as dirname10, isAbsolute, relative as relative2, resolve as resolve5, sep } from "node:path";
|
|
110042
110395
|
import { gunzipSync } from "node:zlib";
|
|
110043
110396
|
function validateRelativePathSegments(filePath) {
|
|
110044
110397
|
if (filePath.includes("\x00"))
|
|
@@ -110066,7 +110419,7 @@ function assertContained(workspaceRoot, targetPath) {
|
|
|
110066
110419
|
return { ok: true };
|
|
110067
110420
|
}
|
|
110068
110421
|
async function resolveNonExistentTarget(workspaceRoot, candidate) {
|
|
110069
|
-
let current =
|
|
110422
|
+
let current = dirname10(candidate);
|
|
110070
110423
|
for (;; ) {
|
|
110071
110424
|
try {
|
|
110072
110425
|
const ancestorReal = await realpath(current);
|
|
@@ -110084,7 +110437,7 @@ async function resolveNonExistentTarget(workspaceRoot, candidate) {
|
|
|
110084
110437
|
if (code2 !== "ENOENT") {
|
|
110085
110438
|
return { ok: false, error: "Invalid file path" };
|
|
110086
110439
|
}
|
|
110087
|
-
const parent =
|
|
110440
|
+
const parent = dirname10(current);
|
|
110088
110441
|
if (parent === current) {
|
|
110089
110442
|
return { ok: false, error: "Path escapes workspace" };
|
|
110090
110443
|
}
|
|
@@ -110895,16 +111248,16 @@ var require_ignore = __commonJS((exports, module) => {
|
|
|
110895
111248
|
// src/infrastructure/services/workspace/workspace-ignore.ts
|
|
110896
111249
|
import { promises as fsPromises } from "node:fs";
|
|
110897
111250
|
import { readFile as readFile10 } from "node:fs/promises";
|
|
110898
|
-
import { homedir as
|
|
111251
|
+
import { homedir as homedir8 } from "node:os";
|
|
110899
111252
|
import path3 from "node:path";
|
|
110900
111253
|
function normalizeRelativePath(relativePath) {
|
|
110901
111254
|
return relativePath.replace(/\\/g, "/").replace(/^\.?\//, "").replace(/\/+$/, "");
|
|
110902
111255
|
}
|
|
110903
111256
|
function expandUserPath(filePath) {
|
|
110904
111257
|
if (filePath === "~")
|
|
110905
|
-
return
|
|
111258
|
+
return homedir8();
|
|
110906
111259
|
if (filePath.startsWith("~/"))
|
|
110907
|
-
return path3.join(
|
|
111260
|
+
return path3.join(homedir8(), filePath.slice(2));
|
|
110908
111261
|
return filePath;
|
|
110909
111262
|
}
|
|
110910
111263
|
function readExcludesFileFromGitconfig(content) {
|
|
@@ -110935,11 +111288,11 @@ async function readGitconfigExcludesFilePath(configPath) {
|
|
|
110935
111288
|
return path3.isAbsolute(raw) ? expandUserPath(raw) : path3.resolve(path3.dirname(configPath), raw);
|
|
110936
111289
|
}
|
|
110937
111290
|
async function resolveGitExtraExcludeFilePaths(rootDir) {
|
|
110938
|
-
const globalConfig2 = process.env.GIT_CONFIG_GLOBAL?.length ? process.env.GIT_CONFIG_GLOBAL : path3.join(
|
|
111291
|
+
const globalConfig2 = process.env.GIT_CONFIG_GLOBAL?.length ? process.env.GIT_CONFIG_GLOBAL : path3.join(homedir8(), ".gitconfig");
|
|
110939
111292
|
const localConfig = path3.join(rootDir, ".git", "config");
|
|
110940
111293
|
let excludesFile = await readGitconfigExcludesFilePath(localConfig) ?? await readGitconfigExcludesFilePath(globalConfig2);
|
|
110941
111294
|
if (!excludesFile) {
|
|
110942
|
-
excludesFile = path3.join(process.env.XDG_CONFIG_HOME?.length ? process.env.XDG_CONFIG_HOME : path3.join(
|
|
111295
|
+
excludesFile = path3.join(process.env.XDG_CONFIG_HOME?.length ? process.env.XDG_CONFIG_HOME : path3.join(homedir8(), ".config"), "git", "ignore");
|
|
110943
111296
|
}
|
|
110944
111297
|
const candidates = [excludesFile, path3.join(rootDir, ".git", "info", "exclude")];
|
|
110945
111298
|
const existing = [];
|
|
@@ -111391,7 +111744,8 @@ function porcelainUntrackedDeletedEvents(args2) {
|
|
|
111391
111744
|
}
|
|
111392
111745
|
async function readGitHead(workTree) {
|
|
111393
111746
|
const result = await runGit(["rev-parse", "HEAD"], workTree, {
|
|
111394
|
-
timeout: GIT_POLL_TIMEOUT_MS
|
|
111747
|
+
timeout: GIT_POLL_TIMEOUT_MS,
|
|
111748
|
+
readOnly: true
|
|
111395
111749
|
});
|
|
111396
111750
|
if ("error" in result) {
|
|
111397
111751
|
if (isEmptyRepoHeadError(result.error))
|
|
@@ -111415,7 +111769,10 @@ async function readGitPorcelainStatus(node) {
|
|
|
111415
111769
|
const args2 = ["status", "--porcelain=v1", "-z", "-uall", "--"];
|
|
111416
111770
|
if (node.pathspec.length > 0)
|
|
111417
111771
|
args2.push(...node.pathspec);
|
|
111418
|
-
const result = await runGit(args2, node.workTree, {
|
|
111772
|
+
const result = await runGit(args2, node.workTree, {
|
|
111773
|
+
timeout: GIT_POLL_TIMEOUT_MS,
|
|
111774
|
+
readOnly: true
|
|
111775
|
+
});
|
|
111419
111776
|
if ("error" in result) {
|
|
111420
111777
|
throw new GitWorkspaceCommandError({
|
|
111421
111778
|
operation: "readGitPorcelainStatus",
|
|
@@ -111553,35 +111910,31 @@ function createGitWorkspaceChangeSource(options) {
|
|
|
111553
111910
|
let needsReconcile = false;
|
|
111554
111911
|
let tickHadFailure = false;
|
|
111555
111912
|
let maxNodeFailures = 0;
|
|
111556
|
-
const
|
|
111557
|
-
|
|
111558
|
-
|
|
111559
|
-
|
|
111560
|
-
|
|
111561
|
-
|
|
111562
|
-
|
|
111563
|
-
|
|
111564
|
-
|
|
111565
|
-
|
|
111566
|
-
|
|
111567
|
-
|
|
111568
|
-
|
|
111569
|
-
needsReconcile
|
|
111570
|
-
|
|
111571
|
-
|
|
111572
|
-
|
|
111573
|
-
|
|
111574
|
-
|
|
111575
|
-
|
|
111576
|
-
|
|
111577
|
-
|
|
111578
|
-
|
|
111579
|
-
|
|
111580
|
-
|
|
111581
|
-
const prevFailures = nodeFailureCounts.get(node.workTree) ?? 0;
|
|
111582
|
-
const nextFailures = prevFailures + 1;
|
|
111583
|
-
nodeFailureCounts.set(node.workTree, nextFailures);
|
|
111584
|
-
maxNodeFailures = Math.max(maxNodeFailures, nextFailures);
|
|
111913
|
+
for (const node of nodes) {
|
|
111914
|
+
try {
|
|
111915
|
+
const prev = state.get(node.workTree) ?? {
|
|
111916
|
+
prevEntries: [],
|
|
111917
|
+
prevHead: { head: null },
|
|
111918
|
+
baselineEstablished: false
|
|
111919
|
+
};
|
|
111920
|
+
const result = await pollGitWorkspaceNode({
|
|
111921
|
+
options,
|
|
111922
|
+
node,
|
|
111923
|
+
prev
|
|
111924
|
+
});
|
|
111925
|
+
allEvents.push(...result.events);
|
|
111926
|
+
if (result.needsReconcile)
|
|
111927
|
+
needsReconcile = true;
|
|
111928
|
+
state.set(node.workTree, result.nextState);
|
|
111929
|
+
nodeFailureCounts.set(node.workTree, 0);
|
|
111930
|
+
} catch (reason) {
|
|
111931
|
+
tickHadFailure = true;
|
|
111932
|
+
options.onError?.(reason);
|
|
111933
|
+
const prevFailures = nodeFailureCounts.get(node.workTree) ?? 0;
|
|
111934
|
+
const nextFailures = prevFailures + 1;
|
|
111935
|
+
nodeFailureCounts.set(node.workTree, nextFailures);
|
|
111936
|
+
maxNodeFailures = Math.max(maxNodeFailures, nextFailures);
|
|
111937
|
+
}
|
|
111585
111938
|
}
|
|
111586
111939
|
if (tickHadFailure) {
|
|
111587
111940
|
consecutiveFailureTicks += 1;
|
|
@@ -111639,7 +111992,7 @@ function createGitWorkspaceChangeSource(options) {
|
|
|
111639
111992
|
}
|
|
111640
111993
|
};
|
|
111641
111994
|
}
|
|
111642
|
-
var DEFAULT_POLL_INTERVAL_MS =
|
|
111995
|
+
var DEFAULT_POLL_INTERVAL_MS = 3000, MAX_BACKOFF_MS = 30000, PERSISTENT_FAILURE_THRESHOLD = 3;
|
|
111643
111996
|
var init_git_workspace_change_source = __esm(() => {
|
|
111644
111997
|
init_git_workspace_porcelain();
|
|
111645
111998
|
});
|
|
@@ -112068,9 +112421,9 @@ class NodeFsHandler {
|
|
|
112068
112421
|
if (this.fsw.closed) {
|
|
112069
112422
|
return;
|
|
112070
112423
|
}
|
|
112071
|
-
const
|
|
112424
|
+
const dirname12 = sp.dirname(file2);
|
|
112072
112425
|
const basename4 = sp.basename(file2);
|
|
112073
|
-
const parent = this.fsw._getWatchedDir(
|
|
112426
|
+
const parent = this.fsw._getWatchedDir(dirname12);
|
|
112074
112427
|
let prevStats = stats;
|
|
112075
112428
|
if (parent.has(basename4))
|
|
112076
112429
|
return;
|
|
@@ -112097,7 +112450,7 @@ class NodeFsHandler {
|
|
|
112097
112450
|
prevStats = newStats2;
|
|
112098
112451
|
}
|
|
112099
112452
|
} catch (error51) {
|
|
112100
|
-
this.fsw._remove(
|
|
112453
|
+
this.fsw._remove(dirname12, basename4);
|
|
112101
112454
|
}
|
|
112102
112455
|
} else if (parent.has(basename4)) {
|
|
112103
112456
|
const at = newStats.atimeMs;
|
|
@@ -113486,8 +113839,8 @@ function diffPathIndexes(previous, next4) {
|
|
|
113486
113839
|
// src/infrastructure/services/workspace/workspace-sync-state.ts
|
|
113487
113840
|
import { createHash as createHash7, randomUUID as randomUUID9 } from "node:crypto";
|
|
113488
113841
|
import * as fs11 from "node:fs/promises";
|
|
113489
|
-
import { homedir as
|
|
113490
|
-
import { join as
|
|
113842
|
+
import { homedir as homedir9 } from "node:os";
|
|
113843
|
+
import { join as join25 } from "node:path";
|
|
113491
113844
|
function workspaceKeyFor(workingDir) {
|
|
113492
113845
|
const normalized = normalizeWorkingDirForLookup(workingDir);
|
|
113493
113846
|
return createHash7("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
@@ -113501,10 +113854,10 @@ function buildPathIndex(entries2) {
|
|
|
113501
113854
|
}
|
|
113502
113855
|
function manifestPath(machineId, workingDir) {
|
|
113503
113856
|
const key = workspaceKeyFor(workingDir);
|
|
113504
|
-
return
|
|
113857
|
+
return join25(SYNC_STATE_DIR, machineId, key, "manifest.json");
|
|
113505
113858
|
}
|
|
113506
113859
|
async function ensureDir(filePath) {
|
|
113507
|
-
await fs11.mkdir(
|
|
113860
|
+
await fs11.mkdir(join25(filePath, ".."), { recursive: true, mode: 448 });
|
|
113508
113861
|
}
|
|
113509
113862
|
async function loadWorkspaceSyncManifest(machineId, workingDir) {
|
|
113510
113863
|
try {
|
|
@@ -113564,7 +113917,7 @@ function entriesFromPathIndex(paths) {
|
|
|
113564
113917
|
}
|
|
113565
113918
|
var SYNC_STATE_VERSION = "2", SYNC_STATE_DIR;
|
|
113566
113919
|
var init_workspace_sync_state = __esm(() => {
|
|
113567
|
-
SYNC_STATE_DIR =
|
|
113920
|
+
SYNC_STATE_DIR = join25(homedir9(), ".chatroom", "sync-state");
|
|
113568
113921
|
});
|
|
113569
113922
|
|
|
113570
113923
|
// src/infrastructure/services/workspace/workspace-file-tree-coordinator.ts
|
|
@@ -113941,12 +114294,12 @@ var init_durable_coalescing_state_schema = __esm(() => {
|
|
|
113941
114294
|
});
|
|
113942
114295
|
|
|
113943
114296
|
// src/daemon/infrastructure/outbox/lib/durable-coalescing-state-store.ts
|
|
113944
|
-
import { mkdirSync as
|
|
113945
|
-
import { dirname as
|
|
113946
|
-
import { DatabaseSync } from "node:sqlite";
|
|
114297
|
+
import { mkdirSync as mkdirSync7 } from "node:fs";
|
|
114298
|
+
import { dirname as dirname13 } from "node:path";
|
|
114299
|
+
import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
113947
114300
|
function openDurableCoalescingStateStore(path8) {
|
|
113948
|
-
|
|
113949
|
-
const db = new
|
|
114301
|
+
mkdirSync7(dirname13(path8), { recursive: true });
|
|
114302
|
+
const db = new DatabaseSync2(path8);
|
|
113950
114303
|
for (const sql of DURABLE_COALESCING_STATE_MIGRATIONS)
|
|
113951
114304
|
db.exec(sql);
|
|
113952
114305
|
db.prepare("UPDATE coalescing_outbox_entries SET status='pending' WHERE status='in_flight'").run();
|
|
@@ -113963,13 +114316,6 @@ var init_durable_coalescing_state_store = __esm(() => {
|
|
|
113963
114316
|
init_durable_coalescing_state_schema();
|
|
113964
114317
|
});
|
|
113965
114318
|
|
|
113966
|
-
// src/daemon/infrastructure/outbox/lib/outbox-retry-backoff.ts
|
|
113967
|
-
function computeExponentialRetryDelayMs(attempt, retryDelayMs, maxRetryDelayMs) {
|
|
113968
|
-
const exponent = Math.min(Math.max(0, attempt), MAX_RETRY_EXPONENT);
|
|
113969
|
-
return Math.min(retryDelayMs * 2 ** exponent, maxRetryDelayMs);
|
|
113970
|
-
}
|
|
113971
|
-
var MAX_RETRY_EXPONENT = 20;
|
|
113972
|
-
|
|
113973
114319
|
// src/daemon/infrastructure/outbox/lib/coalescing-state-outbox.ts
|
|
113974
114320
|
function createCoalescingStateOutbox(options) {
|
|
113975
114321
|
const durable = [options.store, options.deliveryKey, options.serialize, options.deserialize];
|
|
@@ -114146,14 +114492,6 @@ var init_keyed_coalescing_state_outbox_registry = __esm(() => {
|
|
|
114146
114492
|
init_coalescing_state_outbox();
|
|
114147
114493
|
});
|
|
114148
114494
|
|
|
114149
|
-
// src/daemon/infrastructure/outbox/outbox-db-path.ts
|
|
114150
|
-
import { homedir as homedir9 } from "node:os";
|
|
114151
|
-
import { join as join25 } from "node:path";
|
|
114152
|
-
function resolveOutboxDbPath(machineId, kind) {
|
|
114153
|
-
return join25(homedir9(), ".chatroom", "daemon", machineId, `outbox-${kind}.sqlite`);
|
|
114154
|
-
}
|
|
114155
|
-
var init_outbox_db_path = () => {};
|
|
114156
|
-
|
|
114157
114495
|
// src/daemon/infrastructure/outbox/workspace-file-tree-checkpoint-outbox.ts
|
|
114158
114496
|
function createWorkspaceFileTreeCheckpointOutboxRegistry(machineId, createSend, options) {
|
|
114159
114497
|
return createKeyedCoalescingStateOutboxRegistry({
|
|
@@ -114175,193 +114513,6 @@ var init_workspace_file_tree_checkpoint_outbox = __esm(() => {
|
|
|
114175
114513
|
WORKSPACE_FILE_TREE_CHECKPOINT_OUTBOX_MAX_RETRY_DELAY_MS = 5 * 60000;
|
|
114176
114514
|
});
|
|
114177
114515
|
|
|
114178
|
-
// src/daemon/infrastructure/outbox/lib/durable-fifo-queue-schema.ts
|
|
114179
|
-
var DURABLE_FIFO_QUEUE_MIGRATIONS;
|
|
114180
|
-
var init_durable_fifo_queue_schema = __esm(() => {
|
|
114181
|
-
DURABLE_FIFO_QUEUE_MIGRATIONS = [
|
|
114182
|
-
`CREATE TABLE IF NOT EXISTS schema_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)`,
|
|
114183
|
-
`CREATE TABLE IF NOT EXISTS fifo_outbox_entries (id INTEGER PRIMARY KEY AUTOINCREMENT, delivery_key TEXT NOT NULL, payload_json TEXT NOT NULL, status TEXT NOT NULL DEFAULT 'pending', attempts INTEGER NOT NULL DEFAULT 0, last_error TEXT, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)`,
|
|
114184
|
-
`CREATE INDEX IF NOT EXISTS idx_fifo_outbox_pending ON fifo_outbox_entries(delivery_key, status, id)`
|
|
114185
|
-
];
|
|
114186
|
-
});
|
|
114187
|
-
|
|
114188
|
-
// src/daemon/infrastructure/outbox/lib/durable-fifo-queue-store.ts
|
|
114189
|
-
import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
114190
|
-
import { mkdirSync as mkdirSync7 } from "node:fs";
|
|
114191
|
-
import { dirname as dirname13 } from "node:path";
|
|
114192
|
-
function openDurableFifoQueueStore(dbPath) {
|
|
114193
|
-
mkdirSync7(dirname13(dbPath), { recursive: true });
|
|
114194
|
-
const db = new DatabaseSync2(dbPath);
|
|
114195
|
-
for (const sql of DURABLE_FIFO_QUEUE_MIGRATIONS)
|
|
114196
|
-
db.exec(sql);
|
|
114197
|
-
db.prepare("UPDATE fifo_outbox_entries SET status='pending', updated_at=? WHERE status='in_flight'").run(Date.now());
|
|
114198
|
-
return {
|
|
114199
|
-
enqueue: (key, payloadJson) => {
|
|
114200
|
-
const now = Date.now();
|
|
114201
|
-
return Number(db.prepare("INSERT INTO fifo_outbox_entries(delivery_key,payload_json,created_at,updated_at) VALUES(?,?,?,?) RETURNING id").get(key, payloadJson, now, now).id);
|
|
114202
|
-
},
|
|
114203
|
-
claimNextBatch: (key, limit) => db.prepare("UPDATE fifo_outbox_entries SET status='in_flight', attempts=attempts+1, updated_at=? WHERE id IN (SELECT id FROM fifo_outbox_entries WHERE delivery_key=? AND status='pending' ORDER BY id LIMIT ?) RETURNING id, delivery_key as deliveryKey, payload_json as payloadJson, attempts").all(Date.now(), key, limit),
|
|
114204
|
-
markDone: (id3) => {
|
|
114205
|
-
db.prepare("DELETE FROM fifo_outbox_entries WHERE id=?").run(id3);
|
|
114206
|
-
},
|
|
114207
|
-
markPending: (id3) => {
|
|
114208
|
-
db.prepare("UPDATE fifo_outbox_entries SET status='pending', last_error=NULL, updated_at=? WHERE id=?").run(Date.now(), id3);
|
|
114209
|
-
},
|
|
114210
|
-
updatePayload: (id3, payloadJson) => {
|
|
114211
|
-
db.prepare("UPDATE fifo_outbox_entries SET payload_json=?, updated_at=? WHERE id=?").run(payloadJson, Date.now(), id3);
|
|
114212
|
-
},
|
|
114213
|
-
markPendingRetry: (id3, error51) => {
|
|
114214
|
-
db.prepare("UPDATE fifo_outbox_entries SET status='pending', last_error=?, updated_at=? WHERE id=?").run(String(error51), Date.now(), id3);
|
|
114215
|
-
},
|
|
114216
|
-
listPendingForRecovery: (key) => db.prepare("SELECT id, delivery_key as deliveryKey, payload_json as payloadJson, attempts FROM fifo_outbox_entries WHERE delivery_key=? AND status IN ('pending','in_flight') ORDER BY id").all(key),
|
|
114217
|
-
close: () => db.close()
|
|
114218
|
-
};
|
|
114219
|
-
}
|
|
114220
|
-
var init_durable_fifo_queue_store = __esm(() => {
|
|
114221
|
-
init_durable_fifo_queue_schema();
|
|
114222
|
-
});
|
|
114223
|
-
|
|
114224
|
-
// src/daemon/infrastructure/outbox/lib/fifo-batched-outbox.ts
|
|
114225
|
-
function createFifoBatchedOutbox(o) {
|
|
114226
|
-
const waiters = new Map;
|
|
114227
|
-
let running3;
|
|
114228
|
-
let stopped = false;
|
|
114229
|
-
let retryTimer;
|
|
114230
|
-
let retryAttempt = 0;
|
|
114231
|
-
const retryDelay = () => computeExponentialRetryDelayMs(retryAttempt++, o.retryDelayMs ?? 500, o.maxRetryDelayMs ?? 5000);
|
|
114232
|
-
const scheduleRetry = () => {
|
|
114233
|
-
if (!stopped && !retryTimer) {
|
|
114234
|
-
retryTimer = setTimeout(() => {
|
|
114235
|
-
retryTimer = undefined;
|
|
114236
|
-
drain2().catch(() => {
|
|
114237
|
-
return;
|
|
114238
|
-
});
|
|
114239
|
-
}, retryDelay());
|
|
114240
|
-
retryTimer.unref?.();
|
|
114241
|
-
}
|
|
114242
|
-
};
|
|
114243
|
-
const drain2 = async () => {
|
|
114244
|
-
if (running3)
|
|
114245
|
-
return running3;
|
|
114246
|
-
running3 = (async () => {
|
|
114247
|
-
while (true) {
|
|
114248
|
-
const rows = o.store.claimNextBatch(o.deliveryKey, o.batchSize);
|
|
114249
|
-
if (!rows.length)
|
|
114250
|
-
break;
|
|
114251
|
-
try {
|
|
114252
|
-
const results = await o.send(rows.map((r) => o.deserialize(r.payloadJson)));
|
|
114253
|
-
let hasRetry = false;
|
|
114254
|
-
for (let i2 = 0;i2 < results.length; i2++) {
|
|
114255
|
-
const item = o.deserialize(rows[i2].payloadJson);
|
|
114256
|
-
const outcome = o.classifyOutcome?.(results[i2], item) ?? { kind: "success" };
|
|
114257
|
-
if (outcome.kind === "retry") {
|
|
114258
|
-
o.store.updatePayload(rows[i2].id, o.serialize(outcome.item));
|
|
114259
|
-
o.store.markPending(rows[i2].id);
|
|
114260
|
-
hasRetry = true;
|
|
114261
|
-
continue;
|
|
114262
|
-
}
|
|
114263
|
-
o.store.markDone(rows[i2].id);
|
|
114264
|
-
waiters.get(rows[i2].id)?.resolve(results[i2]);
|
|
114265
|
-
waiters.delete(rows[i2].id);
|
|
114266
|
-
}
|
|
114267
|
-
for (let i2 = results.length;i2 < rows.length; i2++)
|
|
114268
|
-
o.store.markPending(rows[i2].id);
|
|
114269
|
-
if (hasRetry) {
|
|
114270
|
-
scheduleRetry();
|
|
114271
|
-
break;
|
|
114272
|
-
}
|
|
114273
|
-
retryAttempt = 0;
|
|
114274
|
-
} catch (e) {
|
|
114275
|
-
o.onError?.(e);
|
|
114276
|
-
for (const r of rows)
|
|
114277
|
-
o.store.markPendingRetry(r.id, e);
|
|
114278
|
-
scheduleRetry();
|
|
114279
|
-
break;
|
|
114280
|
-
}
|
|
114281
|
-
}
|
|
114282
|
-
})().finally(() => {
|
|
114283
|
-
running3 = undefined;
|
|
114284
|
-
});
|
|
114285
|
-
return running3;
|
|
114286
|
-
};
|
|
114287
|
-
const enqueue = (item) => {
|
|
114288
|
-
if (stopped)
|
|
114289
|
-
return Promise.reject(new Error("Outbox is stopped"));
|
|
114290
|
-
const id3 = o.store.enqueue(o.deliveryKey, o.serialize(item));
|
|
114291
|
-
const p = new Promise((resolve8, reject) => waiters.set(id3, { resolve: resolve8, reject }));
|
|
114292
|
-
drain2().catch(() => {
|
|
114293
|
-
return;
|
|
114294
|
-
});
|
|
114295
|
-
return p;
|
|
114296
|
-
};
|
|
114297
|
-
const flushNow = async () => {
|
|
114298
|
-
while (o.store.listPendingForRecovery(o.deliveryKey).length) {
|
|
114299
|
-
await drain2();
|
|
114300
|
-
}
|
|
114301
|
-
};
|
|
114302
|
-
const stop4 = async () => {
|
|
114303
|
-
if (stopped)
|
|
114304
|
-
return;
|
|
114305
|
-
if (retryTimer)
|
|
114306
|
-
clearTimeout(retryTimer);
|
|
114307
|
-
retryTimer = undefined;
|
|
114308
|
-
await flushNow();
|
|
114309
|
-
stopped = true;
|
|
114310
|
-
};
|
|
114311
|
-
return { enqueue, flushNow, stop: stop4 };
|
|
114312
|
-
}
|
|
114313
|
-
var init_fifo_batched_outbox = () => {};
|
|
114314
|
-
|
|
114315
|
-
// src/daemon/infrastructure/outbox/lib/keyed-fifo-batched-outbox-registry.ts
|
|
114316
|
-
function createKeyedFifoBatchedOutboxRegistry(o) {
|
|
114317
|
-
const boxes = new Map;
|
|
114318
|
-
const get13 = (key) => {
|
|
114319
|
-
let b = boxes.get(key);
|
|
114320
|
-
if (!b) {
|
|
114321
|
-
b = createFifoBatchedOutbox({
|
|
114322
|
-
batchSize: o.batchSize,
|
|
114323
|
-
send: o.createSend(key),
|
|
114324
|
-
store: o.store,
|
|
114325
|
-
deliveryKey: key,
|
|
114326
|
-
serialize: o.serialize,
|
|
114327
|
-
deserialize: o.deserialize,
|
|
114328
|
-
retryDelayMs: o.retryDelayMs,
|
|
114329
|
-
maxRetryDelayMs: o.maxRetryDelayMs,
|
|
114330
|
-
onError: (e) => o.onError?.(key, e),
|
|
114331
|
-
classifyOutcome: o.classifyOutcome
|
|
114332
|
-
});
|
|
114333
|
-
boxes.set(key, b);
|
|
114334
|
-
}
|
|
114335
|
-
return b;
|
|
114336
|
-
};
|
|
114337
|
-
const stop4 = async (k) => {
|
|
114338
|
-
const b = boxes.get(k);
|
|
114339
|
-
if (b) {
|
|
114340
|
-
await b.stop();
|
|
114341
|
-
boxes.delete(k);
|
|
114342
|
-
}
|
|
114343
|
-
};
|
|
114344
|
-
return {
|
|
114345
|
-
enqueue: (k, i2) => get13(k).enqueue(i2),
|
|
114346
|
-
flushNow: async (k) => {
|
|
114347
|
-
if (k)
|
|
114348
|
-
await get13(k).flushNow();
|
|
114349
|
-
else
|
|
114350
|
-
for (const b of boxes.values())
|
|
114351
|
-
await b.flushNow();
|
|
114352
|
-
},
|
|
114353
|
-
stop: stop4,
|
|
114354
|
-
stopAll: async () => {
|
|
114355
|
-
for (const k of [...boxes.keys()])
|
|
114356
|
-
await stop4(k);
|
|
114357
|
-
o.store.close();
|
|
114358
|
-
}
|
|
114359
|
-
};
|
|
114360
|
-
}
|
|
114361
|
-
var init_keyed_fifo_batched_outbox_registry = __esm(() => {
|
|
114362
|
-
init_fifo_batched_outbox();
|
|
114363
|
-
});
|
|
114364
|
-
|
|
114365
114516
|
// src/daemon/infrastructure/outbox/workspace-file-tree-delta-outbox.ts
|
|
114366
114517
|
function createWorkspaceFileTreeDeltaOutboxRegistry(machineId, createSend, options) {
|
|
114367
114518
|
const store = openDurableFifoQueueStore(resolveOutboxDbPath(machineId, "file-tree-delta"));
|
|
@@ -114396,6 +114547,8 @@ var init_workspace_file_tree_delta_outbox = __esm(() => {
|
|
|
114396
114547
|
var init_outbox = __esm(() => {
|
|
114397
114548
|
init_workspace_file_tree_checkpoint_outbox();
|
|
114398
114549
|
init_workspace_file_tree_delta_outbox();
|
|
114550
|
+
init_agent_lifecycle_outbox();
|
|
114551
|
+
init_agent_lifecycle_send();
|
|
114399
114552
|
});
|
|
114400
114553
|
|
|
114401
114554
|
// ../../services/backend/src/domain/workspace-file-tree/types.ts
|
|
@@ -115804,7 +115957,8 @@ var init_command_run_subscription = __esm(() => {
|
|
|
115804
115957
|
// src/daemon/entry/task-delivery/task-delivery-logic.ts
|
|
115805
115958
|
function isPendingAliveRunningTask(task) {
|
|
115806
115959
|
const { agentConfig, status: status3 } = task;
|
|
115807
|
-
|
|
115960
|
+
const op = getNativeDeliverySession()?.agentOperationalReadModel?.get(task.chatroomId, agentConfig.role);
|
|
115961
|
+
return status3 === "pending" && (agentConfig.spawnedAgentPid != null || op?.isAlive === true) && isOperationalDesiredRunning(op);
|
|
115808
115962
|
}
|
|
115809
115963
|
function isSlotUnavailableForPid(slot, pid, isPidAlive, now = Date.now()) {
|
|
115810
115964
|
if (!slot) {
|
|
@@ -115847,7 +116001,8 @@ function isNativeAgentSlotDown(task, health, now = Date.now()) {
|
|
|
115847
116001
|
function isNativeActiveTaskAgentDown(task, health, now) {
|
|
115848
116002
|
if (!isNativeHarness(task.agentConfig.agentHarness))
|
|
115849
116003
|
return false;
|
|
115850
|
-
|
|
116004
|
+
const op = getNativeDeliverySession()?.agentOperationalReadModel?.get(task.chatroomId, task.agentConfig.role);
|
|
116005
|
+
if (!isOperationalDesiredRunning(op))
|
|
115851
116006
|
return false;
|
|
115852
116007
|
if (!isNativeRevivableTaskStatus(task))
|
|
115853
116008
|
return false;
|
|
@@ -115871,7 +116026,8 @@ function isNativePendingTaskNeedingWake(task) {
|
|
|
115871
116026
|
return false;
|
|
115872
116027
|
if (task.status !== "pending")
|
|
115873
116028
|
return false;
|
|
115874
|
-
|
|
116029
|
+
const op = getNativeDeliverySession()?.agentOperationalReadModel?.get(task.chatroomId, task.agentConfig.role);
|
|
116030
|
+
if (isOperationalDesiredRunning(op))
|
|
115875
116031
|
return false;
|
|
115876
116032
|
return Boolean(task.agentConfig.workingDir);
|
|
115877
116033
|
}
|
|
@@ -115947,10 +116103,10 @@ function listTasksReadyForNudge(tasks, now, cooldown, getSlot) {
|
|
|
115947
116103
|
}
|
|
115948
116104
|
var PENDING_IDLE_NUDGE_MS = 15000, NUDGE_COOLDOWN_MS = 60000;
|
|
115949
116105
|
var init_task_delivery_logic = __esm(() => {
|
|
115950
|
-
init_assigned_task();
|
|
115951
116106
|
init_check_agent_slot();
|
|
115952
116107
|
init_predicates();
|
|
115953
116108
|
init_agent_process_manager();
|
|
116109
|
+
init_native_delivery_session_registry();
|
|
115954
116110
|
init_native_ready_invariant();
|
|
115955
116111
|
init_native_task_injector_logic();
|
|
115956
116112
|
});
|
|
@@ -116050,7 +116206,7 @@ function runNativeWakeEffect(task, runtime4, effectContext2, agentMgr) {
|
|
|
116050
116206
|
if (!ctx)
|
|
116051
116207
|
return;
|
|
116052
116208
|
const { chatroomId, agentConfig, role, workingDir, wantResume } = ctx;
|
|
116053
|
-
console.log(`[TaskMonitor] native wake ${role}@${chatroomId} —
|
|
116209
|
+
console.log(`[TaskMonitor] native wake ${role}@${chatroomId} — operational_state=stopped with pending task ${task.taskId}`);
|
|
116054
116210
|
exports_Runtime.runFork(runtime4)(exports_Effect.gen(function* () {
|
|
116055
116211
|
yield* agentMgr.ensureRunning({
|
|
116056
116212
|
chatroomId,
|
|
@@ -116152,6 +116308,31 @@ var init_task_delivery_processor = __esm(() => {
|
|
|
116152
116308
|
init_task_delivery_logic();
|
|
116153
116309
|
});
|
|
116154
116310
|
|
|
116311
|
+
// src/daemon/infrastructure/agent-operational/enrich-snapshot-with-operational.ts
|
|
116312
|
+
function enrichSnapshotWithOperational(snapshot) {
|
|
116313
|
+
const op = getNativeDeliverySession()?.agentOperationalReadModel?.get(snapshot.chatroomId, snapshot.agentConfig.role);
|
|
116314
|
+
if (!op)
|
|
116315
|
+
return snapshot;
|
|
116316
|
+
return { ...snapshot, agentConfig: { ...snapshot.agentConfig, desiredState: isOperationalDesiredRunning(op) ? "running" : "stopped" } };
|
|
116317
|
+
}
|
|
116318
|
+
function enrichSnapshotsWithOperational(snapshots) {
|
|
116319
|
+
return snapshots.map(enrichSnapshotWithOperational);
|
|
116320
|
+
}
|
|
116321
|
+
var init_enrich_snapshot_with_operational = __esm(() => {
|
|
116322
|
+
init_native_delivery_session_registry();
|
|
116323
|
+
});
|
|
116324
|
+
|
|
116325
|
+
// src/daemon/infrastructure/agent-operational/subscribe-machine-agent-operational-status.ts
|
|
116326
|
+
function subscribeMachineAgentOperationalStatus(client4, options, onRows) {
|
|
116327
|
+
return client4.onUpdate(api.machines.subscribeMachineAgentOperationalStatus, { sessionId: options.sessionId, machineId: options.machineId }, (result) => {
|
|
116328
|
+
if (Array.isArray(result))
|
|
116329
|
+
onRows(result);
|
|
116330
|
+
});
|
|
116331
|
+
}
|
|
116332
|
+
var init_subscribe_machine_agent_operational_status = __esm(() => {
|
|
116333
|
+
init_api3();
|
|
116334
|
+
});
|
|
116335
|
+
|
|
116155
116336
|
// src/daemon/infrastructure/inbox/fetch-machine-assigned-task-snapshots.ts
|
|
116156
116337
|
async function fetchMachineAssignedTaskSnapshots(sessionDeps, machineId) {
|
|
116157
116338
|
const result = await sessionDeps.backend.query(api.machines.listMachineAssignedTaskSnapshots, {
|
|
@@ -116321,11 +116502,12 @@ async function handleTaskInboxUpdate(update6, deps) {
|
|
|
116321
116502
|
taskSnapshotState?.applySignalPage(update6.signals, update6.snapshots);
|
|
116322
116503
|
if (update6.snapshots.length === 0)
|
|
116323
116504
|
return;
|
|
116324
|
-
await processTasksUpdate(deps.runtime, deps.effectContext, deps.cooldown, deps.agentMgr, deps.sessionDeps, deps.machineId, "inbox-signal", { snapshots: update6.snapshots });
|
|
116505
|
+
await processTasksUpdate(deps.runtime, deps.effectContext, deps.cooldown, deps.agentMgr, deps.sessionDeps, deps.machineId, "inbox-signal", { snapshots: enrichSnapshotsWithOperational(update6.snapshots) });
|
|
116325
116506
|
}
|
|
116326
116507
|
var init_task_inbox_delivery = __esm(() => {
|
|
116327
116508
|
init_native_delivery_session_registry();
|
|
116328
116509
|
init_task_delivery_processor();
|
|
116510
|
+
init_enrich_snapshot_with_operational();
|
|
116329
116511
|
});
|
|
116330
116512
|
|
|
116331
116513
|
// src/daemon/infrastructure/inbox/task.ts
|
|
@@ -116435,6 +116617,10 @@ var init_task = __esm(() => {
|
|
|
116435
116617
|
|
|
116436
116618
|
// src/daemon/entry/task-inbox-runtime.ts
|
|
116437
116619
|
async function bootstrapMachineAssignedTaskSnapshots(deps) {
|
|
116620
|
+
await deps.sessionDeps.backend.mutation(api.machines.backfillAgentOperationalStatusForMachine, {
|
|
116621
|
+
sessionId: deps.sessionDeps.sessionId,
|
|
116622
|
+
machineId: deps.machineId
|
|
116623
|
+
});
|
|
116438
116624
|
await deps.sessionDeps.backend.mutation(api.machines.syncMachineAssignedTaskSnapshotsMutation, {
|
|
116439
116625
|
sessionId: deps.sessionDeps.sessionId,
|
|
116440
116626
|
machineId: deps.machineId
|
|
@@ -116443,7 +116629,7 @@ async function bootstrapMachineAssignedTaskSnapshots(deps) {
|
|
|
116443
116629
|
deps.taskSnapshotState?.replace(tasks);
|
|
116444
116630
|
if (!tasks.length)
|
|
116445
116631
|
return;
|
|
116446
|
-
await processTasksUpdate(deps.runtime, deps.effectContext, deps.cooldown, deps.agentMgr, deps.sessionDeps, deps.machineId, "bootstrap", { snapshots: tasks });
|
|
116632
|
+
await processTasksUpdate(deps.runtime, deps.effectContext, deps.cooldown, deps.agentMgr, deps.sessionDeps, deps.machineId, "bootstrap", { snapshots: enrichSnapshotsWithOperational(tasks) });
|
|
116447
116633
|
}
|
|
116448
116634
|
function isAbortError(error51) {
|
|
116449
116635
|
return error51 instanceof Error && error51.name === "AbortError";
|
|
@@ -116487,13 +116673,15 @@ var NATIVE_DELIVERY_RECONCILE_MS = 1e4, INBOX_RESTART_INITIAL_MS = 1000, INBOX_R
|
|
|
116487
116673
|
const abort = new AbortController;
|
|
116488
116674
|
let stopped = false;
|
|
116489
116675
|
const taskSnapshotState = new MachineTaskSnapshotState;
|
|
116676
|
+
const agentOperationalReadModel = new AgentOperationalReadModel;
|
|
116490
116677
|
registerNativeDeliverySession({
|
|
116491
116678
|
runtime: runtime4,
|
|
116492
116679
|
effectContext: effectContext2,
|
|
116493
116680
|
agentMgr,
|
|
116494
116681
|
sessionDeps,
|
|
116495
116682
|
machineId: session2.machineId,
|
|
116496
|
-
taskSnapshotState
|
|
116683
|
+
taskSnapshotState,
|
|
116684
|
+
agentOperationalReadModel
|
|
116497
116685
|
});
|
|
116498
116686
|
const cooldown = new RecoveryCooldown;
|
|
116499
116687
|
let inboxUpdateInFlight = false;
|
|
@@ -116535,11 +116723,24 @@ var NATIVE_DELIVERY_RECONCILE_MS = 1e4, INBOX_RESTART_INITIAL_MS = 1000, INBOX_R
|
|
|
116535
116723
|
console.warn("[TaskInbox] bootstrap failed:", error51);
|
|
116536
116724
|
return exports_Effect.void;
|
|
116537
116725
|
}));
|
|
116726
|
+
const unsubscribeOperational = subscribeMachineAgentOperationalStatus(wsClient2, {
|
|
116727
|
+
sessionId: session2.sessionId,
|
|
116728
|
+
machineId: session2.machineId,
|
|
116729
|
+
signal: abort.signal
|
|
116730
|
+
}, (rows) => {
|
|
116731
|
+
if (stopped)
|
|
116732
|
+
return;
|
|
116733
|
+
const changed = agentOperationalReadModel.replace(rows);
|
|
116734
|
+
const snapshots = changed.flatMap(({ chatroomId, role }) => taskSnapshotState.listForRole(chatroomId, role));
|
|
116735
|
+
if (snapshots.length === 0)
|
|
116736
|
+
return;
|
|
116737
|
+
processTasksUpdate(runtime4, effectContext2, cooldown, agentMgr, sessionDeps, session2.machineId, "operational-status", { snapshots: enrichSnapshotsWithOperational(snapshots) }).catch((error51) => console.warn("[TaskInbox] operational-status reconcile failed:", error51));
|
|
116738
|
+
}) ?? (() => {});
|
|
116538
116739
|
const reconcileTimer = setInterval(() => {
|
|
116539
116740
|
if (stopped || inboxUpdateInFlight || reconcileInFlight)
|
|
116540
116741
|
return;
|
|
116541
116742
|
reconcileInFlight = true;
|
|
116542
|
-
processTasksUpdate(runtime4, effectContext2, cooldown, agentMgr, sessionDeps, session2.machineId, "periodic-reconcile", { snapshots: taskSnapshotState.listAll() }).catch((error51) => {
|
|
116743
|
+
processTasksUpdate(runtime4, effectContext2, cooldown, agentMgr, sessionDeps, session2.machineId, "periodic-reconcile", { snapshots: enrichSnapshotsWithOperational(taskSnapshotState.listAll()) }).catch((error51) => {
|
|
116543
116744
|
console.warn("[TaskInbox] local delivery reconciliation failed:", error51);
|
|
116544
116745
|
}).finally(() => {
|
|
116545
116746
|
reconcileInFlight = false;
|
|
@@ -116549,6 +116750,7 @@ var NATIVE_DELIVERY_RECONCILE_MS = 1e4, INBOX_RESTART_INITIAL_MS = 1000, INBOX_R
|
|
|
116549
116750
|
return {
|
|
116550
116751
|
stop() {
|
|
116551
116752
|
stopped = true;
|
|
116753
|
+
unsubscribeOperational();
|
|
116552
116754
|
abort.abort();
|
|
116553
116755
|
clearInterval(reconcileTimer);
|
|
116554
116756
|
unregisterNativeDeliverySession();
|
|
@@ -116563,6 +116765,8 @@ var init_task_inbox_runtime = __esm(() => {
|
|
|
116563
116765
|
init_native_delivery_session_registry();
|
|
116564
116766
|
init_task_delivery_processor();
|
|
116565
116767
|
init_task_delivery_logic();
|
|
116768
|
+
init_enrich_snapshot_with_operational();
|
|
116769
|
+
init_subscribe_machine_agent_operational_status();
|
|
116566
116770
|
init_fetch_machine_assigned_task_snapshots();
|
|
116567
116771
|
init_inbox();
|
|
116568
116772
|
init_task_inbox_delivery();
|
|
@@ -117020,6 +117224,9 @@ function createDaemonRuntime(deps) {
|
|
|
117020
117224
|
shutdownWatchdog.unref?.();
|
|
117021
117225
|
if (heartbeatTimer)
|
|
117022
117226
|
clearInterval(heartbeatTimer);
|
|
117227
|
+
await deps.agentLifecycleOutbox?.stopAll().catch(() => {
|
|
117228
|
+
return;
|
|
117229
|
+
});
|
|
117023
117230
|
stopWorkers();
|
|
117024
117231
|
await withTimeout2(exports_Effect.runPromise(exports_Effect.gen(function* () {
|
|
117025
117232
|
const effectContext2 = yield* exports_Effect.context();
|
|
@@ -132841,7 +133048,11 @@ async function startDaemon() {
|
|
|
132841
133048
|
console.log(`[daemon] Local web UI: http://127.0.0.1:${localWeb.port}/`);
|
|
132842
133049
|
const layers = daemonSessionToLayers(init2);
|
|
132843
133050
|
startBackgroundMachineCapabilitiesDiscovery(createStartBackgroundCapabilitiesDiscoveryDeps(layers));
|
|
132844
|
-
const runtime4 = createDaemonRuntime({
|
|
133051
|
+
const runtime4 = createDaemonRuntime({
|
|
133052
|
+
wsClient: wsClient2,
|
|
133053
|
+
layers,
|
|
133054
|
+
agentLifecycleOutbox: init2.agentLifecycleOutbox
|
|
133055
|
+
});
|
|
132845
133056
|
try {
|
|
132846
133057
|
await runtime4.run();
|
|
132847
133058
|
} finally {
|
|
@@ -134086,4 +134297,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
|
134086
134297
|
});
|
|
134087
134298
|
program2.parse();
|
|
134088
134299
|
|
|
134089
|
-
//# debugId=
|
|
134300
|
+
//# debugId=D5DF842800E395EE64756E2164756E21
|