@goondocks/myco 0.19.6 → 0.20.1
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/{agent-run-WK5NKBYA.js → agent-run-PQXC246Y.js} +8 -8
- package/dist/{agent-tasks-2E73GG3A.js → agent-tasks-323BZEBX.js} +8 -8
- package/dist/{chunk-VLGBWOBY.js → chunk-22JALAXN.js} +6 -6
- package/dist/chunk-22JALAXN.js.map +1 -0
- package/dist/{chunk-DURKJTVO.js → chunk-3WOS4TAR.js} +9 -1
- package/dist/chunk-3WOS4TAR.js.map +1 -0
- package/dist/{chunk-QH5HS54N.js → chunk-3WWJOTYG.js} +3 -3
- package/dist/{chunk-Q4QD6LJT.js → chunk-4M7EWPIA.js} +3 -3
- package/dist/{chunk-FGKCE5AE.js → chunk-4YFKBL3F.js} +2 -2
- package/dist/{chunk-KYH4V4ML.js → chunk-57O67XVF.js} +3 -3
- package/dist/{chunk-7ONVLO43.js → chunk-5XIVBO25.js} +2 -2
- package/dist/{chunk-W3JUH5S3.js → chunk-63ZGP4Q2.js} +4 -4
- package/dist/{chunk-ST2D3SGM.js → chunk-AIYFHQRX.js} +2 -2
- package/dist/{chunk-6ZDJXSEO.js → chunk-BPRIYNLE.js} +3 -3
- package/dist/chunk-CUDIZJY7.js +36 -0
- package/dist/chunk-CUDIZJY7.js.map +1 -0
- package/dist/{chunk-WKNAKQKA.js → chunk-DCSGJ7W4.js} +13 -19
- package/dist/chunk-DCSGJ7W4.js.map +1 -0
- package/dist/{chunk-Q6OEZM3S.js → chunk-EVDQKYCG.js} +237 -10
- package/dist/chunk-EVDQKYCG.js.map +1 -0
- package/dist/{chunk-P5VNHGVZ.js → chunk-FGY7J6EZ.js} +67 -16
- package/dist/chunk-FGY7J6EZ.js.map +1 -0
- package/dist/{chunk-I54KLC6H.js → chunk-FLLBJLHM.js} +3 -1
- package/dist/{chunk-I54KLC6H.js.map → chunk-FLLBJLHM.js.map} +1 -1
- package/dist/{chunk-PMT2LSTQ.js → chunk-FMRZ26U5.js} +2 -2
- package/dist/{chunk-3J6TUJSV.js → chunk-KHT24OWC.js} +3 -3
- package/dist/{chunk-TMNFCUAD.js → chunk-LZP4IJB3.js} +51 -23
- package/dist/chunk-LZP4IJB3.js.map +1 -0
- package/dist/{chunk-6DDRJQ4X.js → chunk-MYOZLMB2.js} +2 -2
- package/dist/{chunk-UVKQ62II.js → chunk-NGROSFOH.js} +24 -2
- package/dist/chunk-NGROSFOH.js.map +1 -0
- package/dist/{chunk-FKBPXCH3.js → chunk-QS5TWZBL.js} +4 -4
- package/dist/{chunk-NKQZ73LL.js → chunk-SRXTSI25.js} +109 -3
- package/dist/chunk-SRXTSI25.js.map +1 -0
- package/dist/{chunk-NCBLB2C6.js → chunk-UEWMSIL3.js} +7 -4
- package/dist/chunk-UEWMSIL3.js.map +1 -0
- package/dist/{chunk-GFR542SM.js → chunk-US4LNCAT.js} +5 -11
- package/dist/chunk-US4LNCAT.js.map +1 -0
- package/dist/{chunk-44PZCAYS.js → chunk-XL75KZGI.js} +23 -13
- package/dist/chunk-XL75KZGI.js.map +1 -0
- package/dist/chunk-ZXZPJJN3.js +54 -0
- package/dist/chunk-ZXZPJJN3.js.map +1 -0
- package/dist/{cli-LCTXK7N6.js → cli-UWBAOHLL.js} +43 -43
- package/dist/{client-S47ENM76.js → client-SLDDMSKN.js} +4 -4
- package/dist/{config-IO5WALOD.js → config-XPV5GDE4.js} +8 -16
- package/dist/config-XPV5GDE4.js.map +1 -0
- package/dist/{detect-BEOIHGBC.js → detect-PXNM6TA7.js} +2 -2
- package/dist/{detect-providers-2EY55EHK.js → detect-providers-5KOPZ7J2.js} +4 -4
- package/dist/{doctor-EE6GAC54.js → doctor-UUUOVDZS.js} +14 -14
- package/dist/doctor-UUUOVDZS.js.map +1 -0
- package/dist/{executor-NXNSUEMQ.js → executor-J4IBXSBY.js} +21 -22
- package/dist/executor-J4IBXSBY.js.map +1 -0
- package/dist/{init-IPL3XV6F.js → init-UDH3ZBDD.js} +17 -21
- package/dist/init-UDH3ZBDD.js.map +1 -0
- package/dist/{installer-WMTB4NCX.js → installer-I6KRGJOO.js} +4 -4
- package/dist/{llm-SWDDQQWY.js → llm-TH4NLIRM.js} +4 -4
- package/dist/{loader-V774GZU4.js → loader-H7OFASVC.js} +15 -3
- package/dist/{loader-AAZ6VUIA.js → loader-TSB5M7FD.js} +3 -3
- package/dist/{logs-KNKPQE5A.js → logs-7YVGGBIS.js} +2 -2
- package/dist/{main-RPJSS7PT.js → main-E7HU4QYR.js} +842 -249
- package/dist/main-E7HU4QYR.js.map +1 -0
- package/dist/{open-OYBKVBYX.js → open-4UGDPBKN.js} +8 -8
- package/dist/{post-compact-E2OVMNGQ.js → post-compact-BFU3WZSV.js} +9 -8
- package/dist/{post-compact-E2OVMNGQ.js.map → post-compact-BFU3WZSV.js.map} +1 -1
- package/dist/{post-tool-use-FGQE26GJ.js → post-tool-use-RYHXLCTC.js} +8 -7
- package/dist/{post-tool-use-FGQE26GJ.js.map → post-tool-use-RYHXLCTC.js.map} +1 -1
- package/dist/{post-tool-use-failure-3CITJYQK.js → post-tool-use-failure-DCVHK2P3.js} +9 -8
- package/dist/{post-tool-use-failure-3CITJYQK.js.map → post-tool-use-failure-DCVHK2P3.js.map} +1 -1
- package/dist/{pre-compact-GYMHCXII.js → pre-compact-EZZCJ6AG.js} +9 -8
- package/dist/{pre-compact-GYMHCXII.js.map → pre-compact-EZZCJ6AG.js.map} +1 -1
- package/dist/{provider-check-WCM3SDTM.js → provider-check-43LAMSMH.js} +4 -4
- package/dist/{registry-OCM4WAPJ.js → registry-MGJSJBAS.js} +4 -4
- package/dist/{remove-72ER3TG5.js → remove-GBBQG3SJ.js} +10 -10
- package/dist/{restart-EQHEJCGT.js → restart-RMIGKMA6.js} +9 -9
- package/dist/{search-JOBYIW43.js → search-2A5AJVNG.js} +9 -9
- package/dist/{server-PZCWYWZL.js → server-TSYZMFFK.js} +40 -27
- package/dist/{server-PZCWYWZL.js.map → server-TSYZMFFK.js.map} +1 -1
- package/dist/{session-APO4A2C7.js → session-NKREOTEO.js} +9 -10
- package/dist/{session-APO4A2C7.js.map → session-NKREOTEO.js.map} +1 -1
- package/dist/{session-end-4V4VHAOQ.js → session-end-DQELLTGJ.js} +8 -7
- package/dist/{session-end-4V4VHAOQ.js.map → session-end-DQELLTGJ.js.map} +1 -1
- package/dist/{session-start-K6ESRZU7.js → session-start-5SUTR5GP.js} +17 -17
- package/dist/session-start-5SUTR5GP.js.map +1 -0
- package/dist/{setup-llm-QUWOSB7A.js → setup-llm-SLX5764H.js} +10 -9
- package/dist/{setup-llm-QUWOSB7A.js.map → setup-llm-SLX5764H.js.map} +1 -1
- package/dist/src/cli.js +1 -1
- package/dist/src/daemon/main.js +1 -1
- package/dist/src/hooks/post-tool-use.js +1 -1
- package/dist/src/hooks/session-end.js +1 -1
- package/dist/src/hooks/session-start.js +1 -1
- package/dist/src/hooks/stop.js +1 -1
- package/dist/src/hooks/user-prompt-submit.js +1 -1
- package/dist/src/mcp/server.js +1 -1
- package/dist/src/symbionts/manifests/codex.yaml +28 -0
- package/dist/{stats-TYOZAOP2.js → stats-ARBLNEE3.js} +9 -9
- package/dist/{stop-2COOWEYG.js → stop-5AJXBKEE.js} +8 -7
- package/dist/{stop-2COOWEYG.js.map → stop-5AJXBKEE.js.map} +1 -1
- package/dist/{stop-failure-UQ33GZLE.js → stop-failure-XGKTZPLR.js} +9 -8
- package/dist/{stop-failure-UQ33GZLE.js.map → stop-failure-XGKTZPLR.js.map} +1 -1
- package/dist/{subagent-start-YENEY6VF.js → subagent-start-2JLIPGJN.js} +9 -8
- package/dist/{subagent-start-YENEY6VF.js.map → subagent-start-2JLIPGJN.js.map} +1 -1
- package/dist/{subagent-stop-W2757YDB.js → subagent-stop-FV4EOKWZ.js} +9 -8
- package/dist/{subagent-stop-W2757YDB.js.map → subagent-stop-FV4EOKWZ.js.map} +1 -1
- package/dist/{task-completed-KU6GWMWV.js → task-completed-XJKT366I.js} +9 -8
- package/dist/{task-completed-KU6GWMWV.js.map → task-completed-XJKT366I.js.map} +1 -1
- package/dist/{team-SNLC6FZM.js → team-3JKF7VAD.js} +5 -5
- package/dist/ui/assets/index-C2JuNtRB.css +1 -0
- package/dist/ui/assets/index-JLVaQKV2.js +832 -0
- package/dist/ui/favicon-dusk.svg +11 -0
- package/dist/ui/favicon-moss.svg +11 -0
- package/dist/ui/favicon-plum.svg +11 -0
- package/dist/ui/favicon-sage.svg +11 -0
- package/dist/ui/favicon-slate.svg +11 -0
- package/dist/ui/favicon-terracotta.svg +11 -0
- package/dist/ui/index.html +3 -3
- package/dist/{update-5VYNQZJ4.js → update-XVSAMN4O.js} +10 -10
- package/dist/{user-prompt-submit-KATLHAKA.js → user-prompt-submit-TTBTHBBH.js} +9 -8
- package/dist/{user-prompt-submit-KATLHAKA.js.map → user-prompt-submit-TTBTHBBH.js.map} +1 -1
- package/dist/{verify-BGJVB3K2.js → verify-LMHNEYIP.js} +7 -7
- package/dist/verify-LMHNEYIP.js.map +1 -0
- package/dist/{version-MKNN5GYM.js → version-HRVSEMUR.js} +2 -2
- package/package.json +1 -1
- package/skills/myco/SKILL.md +78 -43
- package/skills/myco/references/vault-status.md +1 -1
- package/dist/chunk-44PZCAYS.js.map +0 -1
- package/dist/chunk-5ZT2Q6P5.js +0 -25
- package/dist/chunk-5ZT2Q6P5.js.map +0 -1
- package/dist/chunk-AULBWINA.js +0 -227
- package/dist/chunk-AULBWINA.js.map +0 -1
- package/dist/chunk-DURKJTVO.js.map +0 -1
- package/dist/chunk-GFR542SM.js.map +0 -1
- package/dist/chunk-NCBLB2C6.js.map +0 -1
- package/dist/chunk-NKQZ73LL.js.map +0 -1
- package/dist/chunk-P5VNHGVZ.js.map +0 -1
- package/dist/chunk-Q6OEZM3S.js.map +0 -1
- package/dist/chunk-TMNFCUAD.js.map +0 -1
- package/dist/chunk-UVKQ62II.js.map +0 -1
- package/dist/chunk-VLGBWOBY.js.map +0 -1
- package/dist/chunk-VQF5E4ZX.js +0 -91
- package/dist/chunk-VQF5E4ZX.js.map +0 -1
- package/dist/chunk-WKNAKQKA.js.map +0 -1
- package/dist/config-IO5WALOD.js.map +0 -1
- package/dist/doctor-EE6GAC54.js.map +0 -1
- package/dist/executor-NXNSUEMQ.js.map +0 -1
- package/dist/init-IPL3XV6F.js.map +0 -1
- package/dist/main-RPJSS7PT.js.map +0 -1
- package/dist/resolution-events-PYLSI6QT.js +0 -15
- package/dist/session-start-K6ESRZU7.js.map +0 -1
- package/dist/ui/assets/index-816yFmz_.js +0 -842
- package/dist/ui/assets/index-Dj6vQpFd.css +0 -1
- package/dist/verify-BGJVB3K2.js.map +0 -1
- package/dist/version-MKNN5GYM.js.map +0 -1
- /package/dist/{agent-run-WK5NKBYA.js.map → agent-run-PQXC246Y.js.map} +0 -0
- /package/dist/{agent-tasks-2E73GG3A.js.map → agent-tasks-323BZEBX.js.map} +0 -0
- /package/dist/{chunk-QH5HS54N.js.map → chunk-3WWJOTYG.js.map} +0 -0
- /package/dist/{chunk-Q4QD6LJT.js.map → chunk-4M7EWPIA.js.map} +0 -0
- /package/dist/{chunk-FGKCE5AE.js.map → chunk-4YFKBL3F.js.map} +0 -0
- /package/dist/{chunk-KYH4V4ML.js.map → chunk-57O67XVF.js.map} +0 -0
- /package/dist/{chunk-7ONVLO43.js.map → chunk-5XIVBO25.js.map} +0 -0
- /package/dist/{chunk-W3JUH5S3.js.map → chunk-63ZGP4Q2.js.map} +0 -0
- /package/dist/{chunk-ST2D3SGM.js.map → chunk-AIYFHQRX.js.map} +0 -0
- /package/dist/{chunk-6ZDJXSEO.js.map → chunk-BPRIYNLE.js.map} +0 -0
- /package/dist/{chunk-PMT2LSTQ.js.map → chunk-FMRZ26U5.js.map} +0 -0
- /package/dist/{chunk-3J6TUJSV.js.map → chunk-KHT24OWC.js.map} +0 -0
- /package/dist/{chunk-6DDRJQ4X.js.map → chunk-MYOZLMB2.js.map} +0 -0
- /package/dist/{chunk-FKBPXCH3.js.map → chunk-QS5TWZBL.js.map} +0 -0
- /package/dist/{cli-LCTXK7N6.js.map → cli-UWBAOHLL.js.map} +0 -0
- /package/dist/{client-S47ENM76.js.map → client-SLDDMSKN.js.map} +0 -0
- /package/dist/{detect-BEOIHGBC.js.map → detect-PXNM6TA7.js.map} +0 -0
- /package/dist/{detect-providers-2EY55EHK.js.map → detect-providers-5KOPZ7J2.js.map} +0 -0
- /package/dist/{installer-WMTB4NCX.js.map → installer-I6KRGJOO.js.map} +0 -0
- /package/dist/{llm-SWDDQQWY.js.map → llm-TH4NLIRM.js.map} +0 -0
- /package/dist/{loader-AAZ6VUIA.js.map → loader-H7OFASVC.js.map} +0 -0
- /package/dist/{loader-V774GZU4.js.map → loader-TSB5M7FD.js.map} +0 -0
- /package/dist/{logs-KNKPQE5A.js.map → logs-7YVGGBIS.js.map} +0 -0
- /package/dist/{open-OYBKVBYX.js.map → open-4UGDPBKN.js.map} +0 -0
- /package/dist/{provider-check-WCM3SDTM.js.map → provider-check-43LAMSMH.js.map} +0 -0
- /package/dist/{registry-OCM4WAPJ.js.map → registry-MGJSJBAS.js.map} +0 -0
- /package/dist/{remove-72ER3TG5.js.map → remove-GBBQG3SJ.js.map} +0 -0
- /package/dist/{restart-EQHEJCGT.js.map → restart-RMIGKMA6.js.map} +0 -0
- /package/dist/{search-JOBYIW43.js.map → search-2A5AJVNG.js.map} +0 -0
- /package/dist/{stats-TYOZAOP2.js.map → stats-ARBLNEE3.js.map} +0 -0
- /package/dist/{resolution-events-PYLSI6QT.js.map → team-3JKF7VAD.js.map} +0 -0
- /package/dist/{update-5VYNQZJ4.js.map → update-XVSAMN4O.js.map} +0 -0
- /package/dist/{team-SNLC6FZM.js.map → version-HRVSEMUR.js.map} +0 -0
|
@@ -1,11 +1,212 @@
|
|
|
1
1
|
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
getTeamMachineId,
|
|
4
|
-
syncRow
|
|
5
|
-
} from "./chunk-AULBWINA.js";
|
|
6
2
|
import {
|
|
7
3
|
getDatabase
|
|
8
4
|
} from "./chunk-MYX5NCRH.js";
|
|
5
|
+
import {
|
|
6
|
+
DEFAULT_MACHINE_ID
|
|
7
|
+
} from "./chunk-FLLBJLHM.js";
|
|
8
|
+
|
|
9
|
+
// src/daemon/team-context.ts
|
|
10
|
+
var teamSyncEnabled = false;
|
|
11
|
+
var teamMachineId = DEFAULT_MACHINE_ID;
|
|
12
|
+
function initTeamContext(enabled, machineId) {
|
|
13
|
+
teamSyncEnabled = enabled;
|
|
14
|
+
teamMachineId = machineId;
|
|
15
|
+
}
|
|
16
|
+
function isTeamSyncEnabled() {
|
|
17
|
+
return teamSyncEnabled;
|
|
18
|
+
}
|
|
19
|
+
function getTeamMachineId() {
|
|
20
|
+
return teamMachineId;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/db/queries/team-outbox.ts
|
|
24
|
+
var BURST_BATCH_SIZE = 200;
|
|
25
|
+
var SENT_PRUNE_AGE_SECONDS = 86400;
|
|
26
|
+
var MAX_OUTBOX_RETRIES = 10;
|
|
27
|
+
var MS_PER_SECOND = 1e3;
|
|
28
|
+
var OUTBOX_COLUMNS = [
|
|
29
|
+
"id",
|
|
30
|
+
"table_name",
|
|
31
|
+
"row_id",
|
|
32
|
+
"operation",
|
|
33
|
+
"payload",
|
|
34
|
+
"machine_id",
|
|
35
|
+
"created_at",
|
|
36
|
+
"sent_at",
|
|
37
|
+
"retry_count",
|
|
38
|
+
"last_attempt_at"
|
|
39
|
+
];
|
|
40
|
+
var SELECT_COLUMNS = OUTBOX_COLUMNS.join(", ");
|
|
41
|
+
function toOutboxRow(row) {
|
|
42
|
+
return {
|
|
43
|
+
id: row.id,
|
|
44
|
+
table_name: row.table_name,
|
|
45
|
+
row_id: row.row_id,
|
|
46
|
+
operation: row.operation,
|
|
47
|
+
payload: row.payload,
|
|
48
|
+
machine_id: row.machine_id,
|
|
49
|
+
created_at: row.created_at,
|
|
50
|
+
sent_at: row.sent_at ?? null,
|
|
51
|
+
retry_count: row.retry_count ?? 0,
|
|
52
|
+
last_attempt_at: row.last_attempt_at ?? null
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function syncRow(tableName, row) {
|
|
56
|
+
if (!isTeamSyncEnabled()) return;
|
|
57
|
+
enqueueOutbox({
|
|
58
|
+
table_name: tableName,
|
|
59
|
+
row_id: String(row.id),
|
|
60
|
+
payload: JSON.stringify(row),
|
|
61
|
+
machine_id: getTeamMachineId(),
|
|
62
|
+
created_at: row.created_at ?? Math.floor(Date.now() / 1e3)
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function enqueueOutbox(data) {
|
|
66
|
+
const db = getDatabase();
|
|
67
|
+
const info = db.prepare(
|
|
68
|
+
`INSERT INTO team_outbox (
|
|
69
|
+
table_name, row_id, operation, payload, machine_id, created_at
|
|
70
|
+
) VALUES (?, ?, ?, ?, ?, ?)`
|
|
71
|
+
).run(
|
|
72
|
+
data.table_name,
|
|
73
|
+
data.row_id,
|
|
74
|
+
data.operation ?? "upsert",
|
|
75
|
+
data.payload,
|
|
76
|
+
data.machine_id,
|
|
77
|
+
data.created_at
|
|
78
|
+
);
|
|
79
|
+
const id = Number(info.lastInsertRowid);
|
|
80
|
+
return toOutboxRow(
|
|
81
|
+
db.prepare(`SELECT ${SELECT_COLUMNS} FROM team_outbox WHERE id = ?`).get(id)
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
function listPending(limit) {
|
|
85
|
+
const db = getDatabase();
|
|
86
|
+
const rows = db.prepare(
|
|
87
|
+
`SELECT ${SELECT_COLUMNS}
|
|
88
|
+
FROM team_outbox
|
|
89
|
+
WHERE sent_at IS NULL AND retry_count < ?
|
|
90
|
+
ORDER BY created_at ASC
|
|
91
|
+
LIMIT ?`
|
|
92
|
+
).all(MAX_OUTBOX_RETRIES, limit ?? BURST_BATCH_SIZE);
|
|
93
|
+
return rows.map(toOutboxRow);
|
|
94
|
+
}
|
|
95
|
+
function markSent(ids, sentAt) {
|
|
96
|
+
if (ids.length === 0) return;
|
|
97
|
+
const db = getDatabase();
|
|
98
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
99
|
+
db.prepare(
|
|
100
|
+
`UPDATE team_outbox
|
|
101
|
+
SET sent_at = ?
|
|
102
|
+
WHERE id IN (${placeholders})`
|
|
103
|
+
).run(sentAt, ...ids);
|
|
104
|
+
}
|
|
105
|
+
function incrementRetryCount(ids, attemptAt) {
|
|
106
|
+
if (ids.length === 0) return [];
|
|
107
|
+
const db = getDatabase();
|
|
108
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
109
|
+
db.prepare(
|
|
110
|
+
`UPDATE team_outbox
|
|
111
|
+
SET retry_count = retry_count + 1, last_attempt_at = ?
|
|
112
|
+
WHERE id IN (${placeholders})`
|
|
113
|
+
).run(attemptAt, ...ids);
|
|
114
|
+
const deadLettered = db.prepare(
|
|
115
|
+
`SELECT id FROM team_outbox
|
|
116
|
+
WHERE id IN (${placeholders}) AND retry_count >= ?`
|
|
117
|
+
).all(...ids, MAX_OUTBOX_RETRIES);
|
|
118
|
+
return deadLettered.map((r) => r.id);
|
|
119
|
+
}
|
|
120
|
+
function retryDeadLettered() {
|
|
121
|
+
const db = getDatabase();
|
|
122
|
+
const info = db.prepare(
|
|
123
|
+
`UPDATE team_outbox
|
|
124
|
+
SET retry_count = 0, last_attempt_at = NULL
|
|
125
|
+
WHERE sent_at IS NULL AND retry_count >= ?`
|
|
126
|
+
).run(MAX_OUTBOX_RETRIES);
|
|
127
|
+
return info.changes;
|
|
128
|
+
}
|
|
129
|
+
function countDeadLettered() {
|
|
130
|
+
const db = getDatabase();
|
|
131
|
+
const row = db.prepare(
|
|
132
|
+
`SELECT COUNT(*) as count FROM team_outbox WHERE sent_at IS NULL AND retry_count >= ?`
|
|
133
|
+
).get(MAX_OUTBOX_RETRIES);
|
|
134
|
+
return row.count;
|
|
135
|
+
}
|
|
136
|
+
function pruneOld() {
|
|
137
|
+
const db = getDatabase();
|
|
138
|
+
const cutoff = Math.floor(Date.now() / MS_PER_SECOND) - SENT_PRUNE_AGE_SECONDS;
|
|
139
|
+
const info = db.prepare(
|
|
140
|
+
`DELETE FROM team_outbox
|
|
141
|
+
WHERE sent_at IS NOT NULL AND sent_at < ?`
|
|
142
|
+
).run(cutoff);
|
|
143
|
+
return info.changes;
|
|
144
|
+
}
|
|
145
|
+
function countPending() {
|
|
146
|
+
const db = getDatabase();
|
|
147
|
+
const row = db.prepare(
|
|
148
|
+
`SELECT COUNT(*) as count FROM team_outbox WHERE sent_at IS NULL AND retry_count < ?`
|
|
149
|
+
).get(MAX_OUTBOX_RETRIES);
|
|
150
|
+
return row.count;
|
|
151
|
+
}
|
|
152
|
+
var BACKFILL_TABLES = [
|
|
153
|
+
"sessions",
|
|
154
|
+
"prompt_batches",
|
|
155
|
+
"spores",
|
|
156
|
+
"entities",
|
|
157
|
+
"graph_edges",
|
|
158
|
+
"resolution_events",
|
|
159
|
+
"plans",
|
|
160
|
+
"artifacts",
|
|
161
|
+
"digest_extracts",
|
|
162
|
+
"skill_candidates",
|
|
163
|
+
"skill_records"
|
|
164
|
+
];
|
|
165
|
+
var BACKFILL_TABLE_SET = new Set(BACKFILL_TABLES);
|
|
166
|
+
function markSourceRowsSynced(records, syncedAt) {
|
|
167
|
+
const db = getDatabase();
|
|
168
|
+
const byTable = /* @__PURE__ */ new Map();
|
|
169
|
+
for (const rec of records) {
|
|
170
|
+
if (!BACKFILL_TABLE_SET.has(rec.table_name)) continue;
|
|
171
|
+
const ids = byTable.get(rec.table_name) ?? [];
|
|
172
|
+
ids.push(rec.row_id);
|
|
173
|
+
byTable.set(rec.table_name, ids);
|
|
174
|
+
}
|
|
175
|
+
for (const [table, ids] of byTable) {
|
|
176
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
177
|
+
db.prepare(
|
|
178
|
+
`UPDATE ${table} SET synced_at = ? WHERE id IN (${placeholders}) AND synced_at IS NULL`
|
|
179
|
+
).run(syncedAt, ...ids);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function backfillUnsynced(machineId) {
|
|
183
|
+
const db = getDatabase();
|
|
184
|
+
let total = 0;
|
|
185
|
+
const now = Math.floor(Date.now() / MS_PER_SECOND);
|
|
186
|
+
for (const table of BACKFILL_TABLES) {
|
|
187
|
+
const rows = db.prepare(
|
|
188
|
+
`SELECT * FROM ${table}
|
|
189
|
+
WHERE synced_at IS NULL
|
|
190
|
+
AND NOT EXISTS (
|
|
191
|
+
SELECT 1 FROM team_outbox
|
|
192
|
+
WHERE team_outbox.table_name = ? AND team_outbox.row_id = CAST(${table}.id AS TEXT)
|
|
193
|
+
)`
|
|
194
|
+
).all(table);
|
|
195
|
+
if (rows.length === 0) continue;
|
|
196
|
+
const insertBatch = db.transaction((batchRows) => {
|
|
197
|
+
const stmt = db.prepare(
|
|
198
|
+
`INSERT INTO team_outbox (table_name, row_id, operation, payload, machine_id, created_at)
|
|
199
|
+
VALUES (?, ?, 'upsert', ?, ?, ?)`
|
|
200
|
+
);
|
|
201
|
+
for (const row of batchRows) {
|
|
202
|
+
stmt.run(table, String(row.id), JSON.stringify(row), machineId, now);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
insertBatch(rows);
|
|
206
|
+
total += rows.length;
|
|
207
|
+
}
|
|
208
|
+
return total;
|
|
209
|
+
}
|
|
9
210
|
|
|
10
211
|
// src/db/queries/sessions.ts
|
|
11
212
|
var DEFAULT_LIST_LIMIT = 100;
|
|
@@ -37,7 +238,7 @@ var SESSION_COLUMNS = [
|
|
|
37
238
|
"machine_id",
|
|
38
239
|
"synced_at"
|
|
39
240
|
];
|
|
40
|
-
var
|
|
241
|
+
var SELECT_COLUMNS2 = SESSION_COLUMNS.join(", ");
|
|
41
242
|
function toSessionRow(row) {
|
|
42
243
|
return {
|
|
43
244
|
id: row.id,
|
|
@@ -120,7 +321,7 @@ function upsertSession(data) {
|
|
|
120
321
|
data.tool_count !== void 0 ? 1 : 0
|
|
121
322
|
);
|
|
122
323
|
const row = toSessionRow(
|
|
123
|
-
db.prepare(`SELECT ${
|
|
324
|
+
db.prepare(`SELECT ${SELECT_COLUMNS2} FROM sessions WHERE id = ?`).get(data.id)
|
|
124
325
|
);
|
|
125
326
|
syncRow("sessions", row);
|
|
126
327
|
return row;
|
|
@@ -128,7 +329,7 @@ function upsertSession(data) {
|
|
|
128
329
|
function getSession(id) {
|
|
129
330
|
const db = getDatabase();
|
|
130
331
|
const row = db.prepare(
|
|
131
|
-
`SELECT ${
|
|
332
|
+
`SELECT ${SELECT_COLUMNS2} FROM sessions WHERE id = ?`
|
|
132
333
|
).get(id);
|
|
133
334
|
if (!row) return null;
|
|
134
335
|
return toSessionRow(row);
|
|
@@ -144,6 +345,18 @@ function buildSessionsWhere(options) {
|
|
|
144
345
|
conditions.push(`agent = ?`);
|
|
145
346
|
params.push(options.agent);
|
|
146
347
|
}
|
|
348
|
+
if (options.branch !== void 0) {
|
|
349
|
+
conditions.push(`branch = ?`);
|
|
350
|
+
params.push(options.branch);
|
|
351
|
+
}
|
|
352
|
+
if (options.user !== void 0) {
|
|
353
|
+
conditions.push(`"user" = ?`);
|
|
354
|
+
params.push(options.user);
|
|
355
|
+
}
|
|
356
|
+
if (options.id !== void 0) {
|
|
357
|
+
conditions.push(`id = ?`);
|
|
358
|
+
params.push(options.id);
|
|
359
|
+
}
|
|
147
360
|
if (options.search !== void 0 && options.search.length > 0) {
|
|
148
361
|
conditions.push(`(title LIKE ? OR id LIKE ?)`);
|
|
149
362
|
const pattern = `%${options.search}%`;
|
|
@@ -167,7 +380,7 @@ function listSessions(options = {}) {
|
|
|
167
380
|
const limit = options.limit ?? DEFAULT_LIST_LIMIT;
|
|
168
381
|
const offset = options.offset ?? 0;
|
|
169
382
|
const rows = db.prepare(
|
|
170
|
-
`SELECT ${
|
|
383
|
+
`SELECT ${SELECT_COLUMNS2}
|
|
171
384
|
FROM sessions
|
|
172
385
|
${where}
|
|
173
386
|
ORDER BY created_at DESC
|
|
@@ -198,7 +411,7 @@ function reactivateSessionIfCompleted(id) {
|
|
|
198
411
|
).run(id);
|
|
199
412
|
if (info.changes === 0) return false;
|
|
200
413
|
const row = db.prepare(
|
|
201
|
-
`SELECT ${
|
|
414
|
+
`SELECT ${SELECT_COLUMNS2} FROM sessions WHERE id = ?`
|
|
202
415
|
).get(id);
|
|
203
416
|
if (row) syncRow("sessions", toSessionRow(row));
|
|
204
417
|
return true;
|
|
@@ -328,6 +541,20 @@ function deleteSessionCascade(sessionId) {
|
|
|
328
541
|
}
|
|
329
542
|
|
|
330
543
|
export {
|
|
544
|
+
initTeamContext,
|
|
545
|
+
isTeamSyncEnabled,
|
|
546
|
+
getTeamMachineId,
|
|
547
|
+
syncRow,
|
|
548
|
+
enqueueOutbox,
|
|
549
|
+
listPending,
|
|
550
|
+
markSent,
|
|
551
|
+
incrementRetryCount,
|
|
552
|
+
retryDeadLettered,
|
|
553
|
+
countDeadLettered,
|
|
554
|
+
pruneOld,
|
|
555
|
+
countPending,
|
|
556
|
+
markSourceRowsSynced,
|
|
557
|
+
backfillUnsynced,
|
|
331
558
|
upsertSession,
|
|
332
559
|
getSession,
|
|
333
560
|
listSessions,
|
|
@@ -340,4 +567,4 @@ export {
|
|
|
340
567
|
getSessionImpact,
|
|
341
568
|
deleteSessionCascade
|
|
342
569
|
};
|
|
343
|
-
//# sourceMappingURL=chunk-
|
|
570
|
+
//# sourceMappingURL=chunk-EVDQKYCG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/daemon/team-context.ts","../src/db/queries/team-outbox.ts","../src/db/queries/sessions.ts"],"sourcesContent":["/**\n * Module-level state for team sync.\n *\n * Initialized once by the daemon on startup. Query modules import\n * `isTeamSyncEnabled()` and `getTeamMachineId()` to decide whether\n * to enqueue outbox records on write.\n */\n\nimport { SYNC_PROTOCOL_VERSION, DEFAULT_MACHINE_ID } from '@myco/constants.js';\n\n// ---------------------------------------------------------------------------\n// Module state\n// ---------------------------------------------------------------------------\n\nlet teamSyncEnabled = false;\nlet teamMachineId = DEFAULT_MACHINE_ID;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Initialize team context. Called once on daemon startup.\n */\nexport function initTeamContext(enabled: boolean, machineId: string): void {\n teamSyncEnabled = enabled;\n teamMachineId = machineId;\n}\n\n/**\n * Whether team sync is currently enabled.\n *\n * Query modules check this before enqueuing outbox records.\n */\nexport function isTeamSyncEnabled(): boolean {\n return teamSyncEnabled;\n}\n\n/**\n * The machine ID for this instance.\n */\nexport function getTeamMachineId(): string {\n return teamMachineId;\n}\n\n/**\n * The sync protocol version in use.\n */\nexport function getTeamSyncProtocolVersion(): number {\n return SYNC_PROTOCOL_VERSION;\n}\n\n/**\n * Reset team context (for testing).\n */\nexport function resetTeamContext(): void {\n teamSyncEnabled = false;\n teamMachineId = DEFAULT_MACHINE_ID;\n}\n","/**\n * Team outbox CRUD query helpers.\n *\n * The outbox pattern: write paths enqueue records here when team sync is enabled.\n * The sync client flushes pending records in batches to the Cloudflare Worker.\n *\n * All functions obtain the SQLite instance internally via `getDatabase()`.\n * Queries use positional `?` placeholders throughout (better-sqlite3).\n */\n\nimport { getDatabase } from '@myco/db/client.js';\nimport { isTeamSyncEnabled, getTeamMachineId } from '@myco/daemon/team-context.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Max records returned per listPending call. */\nconst BURST_BATCH_SIZE = 200;\n\n/** Age in seconds after which sent records are pruned (24 hours). */\nconst SENT_PRUNE_AGE_SECONDS = 86_400;\n\n/** Max retry attempts before a record is dead-lettered. */\nexport const MAX_OUTBOX_RETRIES = 10;\n\n/** Milliseconds-per-second multiplier for epoch math. */\nconst MS_PER_SECOND = 1000;\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Fields required when enqueuing an outbox record. */\nexport interface OutboxInsert {\n table_name: string;\n row_id: string;\n operation?: string;\n payload: string;\n machine_id: string;\n created_at: number;\n}\n\n/** Row shape returned from outbox queries. */\nexport interface OutboxRow {\n id: number;\n table_name: string;\n row_id: string;\n operation: string;\n payload: string;\n machine_id: string;\n created_at: number;\n sent_at: number | null;\n retry_count: number;\n last_attempt_at: number | null;\n}\n\n// ---------------------------------------------------------------------------\n// Column list\n// ---------------------------------------------------------------------------\n\nconst OUTBOX_COLUMNS = [\n 'id',\n 'table_name',\n 'row_id',\n 'operation',\n 'payload',\n 'machine_id',\n 'created_at',\n 'sent_at',\n 'retry_count',\n 'last_attempt_at',\n] as const;\n\nconst SELECT_COLUMNS = OUTBOX_COLUMNS.join(', ');\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Normalize a SQLite result row into a typed OutboxRow. */\nfunction toOutboxRow(row: Record<string, unknown>): OutboxRow {\n return {\n id: row.id as number,\n table_name: row.table_name as string,\n row_id: row.row_id as string,\n operation: row.operation as string,\n payload: row.payload as string,\n machine_id: row.machine_id as string,\n created_at: row.created_at as number,\n sent_at: (row.sent_at as number) ?? null,\n retry_count: (row.retry_count as number) ?? 0,\n last_attempt_at: (row.last_attempt_at as number) ?? null,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Convenience helper — used by query modules\n// ---------------------------------------------------------------------------\n\n/**\n * Enqueue a row for team sync if sync is enabled.\n *\n * Centralizes the if-enabled / enqueue / serialize pattern that every\n * write-path query module previously duplicated inline.\n */\nexport function syncRow(tableName: string, row: { id: string | number; created_at?: number }): void {\n if (!isTeamSyncEnabled()) return;\n enqueueOutbox({\n table_name: tableName,\n row_id: String(row.id),\n payload: JSON.stringify(row),\n machine_id: getTeamMachineId(),\n created_at: row.created_at ?? Math.floor(Date.now() / 1000),\n });\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Enqueue a record into the team outbox for later sync.\n *\n * Inserted with `sent_at = NULL` (pending).\n */\nexport function enqueueOutbox(data: OutboxInsert): OutboxRow {\n const db = getDatabase();\n\n const info = db.prepare(\n `INSERT INTO team_outbox (\n table_name, row_id, operation, payload, machine_id, created_at\n ) VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(\n data.table_name,\n data.row_id,\n data.operation ?? 'upsert',\n data.payload,\n data.machine_id,\n data.created_at,\n );\n\n const id = Number(info.lastInsertRowid);\n\n return toOutboxRow(\n db.prepare(`SELECT ${SELECT_COLUMNS} FROM team_outbox WHERE id = ?`).get(id) as Record<string, unknown>,\n );\n}\n\n/**\n * List pending outbox records (oldest-first).\n *\n * Uses burst sizing: fetches BURST_BATCH_SIZE rows and returns them all.\n * If fewer than BURST_THRESHOLD rows come back, callers get a normal-size\n * batch; if more, the full burst. This avoids a separate COUNT query.\n */\nexport function listPending(limit?: number): OutboxRow[] {\n const db = getDatabase();\n\n const rows = db.prepare(\n `SELECT ${SELECT_COLUMNS}\n FROM team_outbox\n WHERE sent_at IS NULL AND retry_count < ?\n ORDER BY created_at ASC\n LIMIT ?`,\n ).all(MAX_OUTBOX_RETRIES, limit ?? BURST_BATCH_SIZE) as Record<string, unknown>[];\n\n return rows.map(toOutboxRow);\n}\n\n/**\n * Mark outbox records as sent by setting sent_at.\n */\nexport function markSent(ids: number[], sentAt: number): void {\n if (ids.length === 0) return;\n\n const db = getDatabase();\n const placeholders = ids.map(() => '?').join(', ');\n\n db.prepare(\n `UPDATE team_outbox\n SET sent_at = ?\n WHERE id IN (${placeholders})`,\n ).run(sentAt, ...ids);\n}\n\n/**\n * Reset sent_at to NULL for records that need to be retried.\n *\n * This allows the sync client to re-enqueue specific records for retry.\n */\nexport function markForRetry(ids: number[]): void {\n if (ids.length === 0) return;\n\n const db = getDatabase();\n const placeholders = ids.map(() => '?').join(', ');\n\n db.prepare(\n `UPDATE team_outbox\n SET sent_at = NULL\n WHERE id IN (${placeholders})`,\n ).run(...ids);\n}\n\n/**\n * Increment retry_count and set last_attempt_at for failed outbox records.\n *\n * @returns IDs of records that have now reached MAX_OUTBOX_RETRIES (newly dead-lettered).\n */\nexport function incrementRetryCount(ids: number[], attemptAt: number): number[] {\n if (ids.length === 0) return [];\n\n const db = getDatabase();\n const placeholders = ids.map(() => '?').join(', ');\n\n db.prepare(\n `UPDATE team_outbox\n SET retry_count = retry_count + 1, last_attempt_at = ?\n WHERE id IN (${placeholders})`,\n ).run(attemptAt, ...ids);\n\n // Return IDs that just hit the threshold\n const deadLettered = db.prepare(\n `SELECT id FROM team_outbox\n WHERE id IN (${placeholders}) AND retry_count >= ?`,\n ).all(...ids, MAX_OUTBOX_RETRIES) as Array<{ id: number }>;\n\n return deadLettered.map((r) => r.id);\n}\n\n/**\n * Reset all dead-lettered records back to pending for retry.\n *\n * @returns the number of records reset.\n */\nexport function retryDeadLettered(): number {\n const db = getDatabase();\n\n const info = db.prepare(\n `UPDATE team_outbox\n SET retry_count = 0, last_attempt_at = NULL\n WHERE sent_at IS NULL AND retry_count >= ?`,\n ).run(MAX_OUTBOX_RETRIES);\n\n return info.changes;\n}\n\n/**\n * Count dead-lettered outbox records (exceeded max retries, never sent).\n */\nexport function countDeadLettered(): number {\n const db = getDatabase();\n\n const row = db.prepare(\n `SELECT COUNT(*) as count FROM team_outbox WHERE sent_at IS NULL AND retry_count >= ?`,\n ).get(MAX_OUTBOX_RETRIES) as { count: number };\n\n return row.count;\n}\n\n/**\n * Prune old outbox records.\n *\n * Removes sent records older than 24 hours.\n *\n * @returns the number of records deleted.\n */\nexport function pruneOld(): number {\n const db = getDatabase();\n const cutoff = Math.floor(Date.now() / MS_PER_SECOND) - SENT_PRUNE_AGE_SECONDS;\n\n const info = db.prepare(\n `DELETE FROM team_outbox\n WHERE sent_at IS NOT NULL AND sent_at < ?`,\n ).run(cutoff);\n\n return info.changes;\n}\n\n/**\n * Count pending (unsent) outbox records.\n */\nexport function countPending(): number {\n const db = getDatabase();\n\n const row = db.prepare(\n `SELECT COUNT(*) as count FROM team_outbox WHERE sent_at IS NULL AND retry_count < ?`,\n ).get(MAX_OUTBOX_RETRIES) as { count: number };\n\n return row.count;\n}\n\n// ---------------------------------------------------------------------------\n// Source-row sync bookkeeping\n// ---------------------------------------------------------------------------\n\n/** Tables eligible for backfill/sync (must have id, machine_id, synced_at columns). */\nconst BACKFILL_TABLES = [\n 'sessions',\n 'prompt_batches',\n 'spores',\n 'entities',\n 'graph_edges',\n 'resolution_events',\n 'plans',\n 'artifacts',\n 'digest_extracts',\n 'skill_candidates',\n 'skill_records',\n] as const;\n// entity_mentions excluded — no `id` column (composite key entity_id+note_id+note_type)\n// skill_usage excluded — no `synced_at` column (syncs via syncRow on insert)\n\nconst BACKFILL_TABLE_SET = new Set<string>(BACKFILL_TABLES);\n\n/**\n * Mark source rows as synced after successful outbox flush.\n *\n * Groups outbox records by table_name, then sets `synced_at` on the\n * corresponding source rows. This closes the re-enqueue loop: once\n * synced_at is non-NULL, `backfillUnsynced` skips the row even after\n * the outbox entry is pruned.\n */\nexport function markSourceRowsSynced(records: OutboxRow[], syncedAt: number): void {\n const db = getDatabase();\n\n // Group row_ids by table\n const byTable = new Map<string, string[]>();\n for (const rec of records) {\n if (!BACKFILL_TABLE_SET.has(rec.table_name)) continue;\n const ids = byTable.get(rec.table_name) ?? [];\n ids.push(rec.row_id);\n byTable.set(rec.table_name, ids);\n }\n\n for (const [table, ids] of byTable) {\n const placeholders = ids.map(() => '?').join(', ');\n db.prepare(\n `UPDATE ${table} SET synced_at = ? WHERE id IN (${placeholders}) AND synced_at IS NULL`,\n ).run(syncedAt, ...ids);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Backfill\n// ---------------------------------------------------------------------------\n\n/**\n * Enqueue all unsynced records across all synced tables into the outbox.\n *\n * Scans each table for rows where `synced_at IS NULL`, serializes the full\n * row as JSON, and inserts into the outbox. Idempotent — re-running only\n * picks up rows not yet in the outbox (checked via existing outbox entries).\n *\n * @returns the total number of records enqueued.\n */\nexport function backfillUnsynced(machineId: string): number {\n const db = getDatabase();\n let total = 0;\n\n const now = Math.floor(Date.now() / MS_PER_SECOND);\n\n // Process one table at a time in separate transactions to avoid long locks\n for (const table of BACKFILL_TABLES) {\n const rows = db.prepare(\n `SELECT * FROM ${table}\n WHERE synced_at IS NULL\n AND NOT EXISTS (\n SELECT 1 FROM team_outbox\n WHERE team_outbox.table_name = ? AND team_outbox.row_id = CAST(${table}.id AS TEXT)\n )`,\n ).all(table) as Record<string, unknown>[];\n\n if (rows.length === 0) continue;\n\n const insertBatch = db.transaction((batchRows: Record<string, unknown>[]) => {\n const stmt = db.prepare(\n `INSERT INTO team_outbox (table_name, row_id, operation, payload, machine_id, created_at)\n VALUES (?, ?, 'upsert', ?, ?, ?)`,\n );\n for (const row of batchRows) {\n stmt.run(table, String(row.id), JSON.stringify(row), machineId, now);\n }\n });\n\n insertBatch(rows);\n total += rows.length;\n }\n\n return total;\n}\n\n","/**\n * Session CRUD query helpers.\n *\n * All functions obtain the SQLite instance internally via `getDatabase()`.\n * Queries use positional `?` placeholders throughout (better-sqlite3).\n */\n\nimport { getDatabase } from '@myco/db/client.js';\nimport { getTeamMachineId } from '@myco/daemon/team-context.js';\nimport { syncRow } from '@myco/db/queries/team-outbox.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Default number of sessions returned by listSessions when no limit given. */\nconst DEFAULT_LIST_LIMIT = 100;\n\n/** Session status value when a session is closed normally. */\nconst STATUS_COMPLETED = 'completed';\n\n/** Default session status for new sessions. */\nconst DEFAULT_STATUS = 'active';\n\n/** Default prompt count for new sessions. */\nconst DEFAULT_PROMPT_COUNT = 0;\n\n/** Default tool count for new sessions. */\nconst DEFAULT_TOOL_COUNT = 0;\n\n/** Default processed flag for new sessions. */\nconst DEFAULT_PROCESSED = 0;\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Fields required (or optional) when inserting/upserting a session. */\nexport interface SessionInsert {\n id: string;\n agent: string;\n started_at: number;\n created_at: number;\n user?: string | null;\n project_root?: string | null;\n branch?: string | null;\n ended_at?: number | null;\n status?: string;\n prompt_count?: number;\n tool_count?: number;\n title?: string | null;\n summary?: string | null;\n transcript_path?: string | null;\n parent_session_id?: string | null;\n parent_session_reason?: string | null;\n processed?: number;\n content_hash?: string | null;\n machine_id?: string;\n}\n\n/** Row shape returned from session queries (all columns). */\nexport interface SessionRow {\n id: string;\n agent: string;\n user: string | null;\n project_root: string | null;\n branch: string | null;\n started_at: number;\n ended_at: number | null;\n status: string;\n prompt_count: number;\n tool_count: number;\n title: string | null;\n summary: string | null;\n transcript_path: string | null;\n parent_session_id: string | null;\n parent_session_reason: string | null;\n processed: number;\n content_hash: string | null;\n embedded: number;\n created_at: number;\n machine_id: string;\n synced_at: number | null;\n}\n\n/** Updatable fields for `updateSession`. */\nexport interface SessionUpdate {\n agent?: string;\n user?: string | null;\n project_root?: string | null;\n branch?: string | null;\n ended_at?: number | null;\n status?: string;\n prompt_count?: number;\n tool_count?: number;\n title?: string | null;\n summary?: string | null;\n transcript_path?: string | null;\n parent_session_id?: string | null;\n parent_session_reason?: string | null;\n processed?: number;\n content_hash?: string | null;\n}\n\n/** Filter options for `listSessions`. */\nexport interface ListSessionsOptions {\n limit?: number;\n offset?: number;\n status?: string;\n agent?: string;\n search?: string;\n /** Filter to sessions that ran on this git branch. */\n branch?: string;\n /** Filter to sessions authored by this user. */\n user?: string;\n /** Filter to this exact session id (used for plan→session resolution). */\n id?: string;\n /** Only return sessions created after this epoch-seconds timestamp. */\n since?: number;\n /**\n * When explicitly `false` and no `status` filter is set, exclude sessions\n * still in `status = 'active'` — intelligence-task reads opt in to this.\n * Defaults permissive so UI listings keep showing in-flight sessions.\n */\n includeActive?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Column list\n// ---------------------------------------------------------------------------\n\nconst SESSION_COLUMNS = [\n 'id',\n 'agent',\n '\"user\"',\n 'project_root',\n 'branch',\n 'started_at',\n 'ended_at',\n 'status',\n 'prompt_count',\n 'tool_count',\n 'title',\n 'summary',\n 'transcript_path',\n 'parent_session_id',\n 'parent_session_reason',\n 'processed',\n 'content_hash',\n 'embedded',\n 'created_at',\n 'machine_id',\n 'synced_at',\n] as const;\n\nconst SELECT_COLUMNS = SESSION_COLUMNS.join(', ');\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Normalize a SQLite result row into a typed SessionRow.\n *\n * The quoted \"user\" column comes back as `user` in the result object.\n */\nfunction toSessionRow(row: Record<string, unknown>): SessionRow {\n return {\n id: row.id as string,\n agent: row.agent as string,\n user: (row.user as string) ?? null,\n project_root: (row.project_root as string) ?? null,\n branch: (row.branch as string) ?? null,\n started_at: row.started_at as number,\n ended_at: (row.ended_at as number) ?? null,\n status: row.status as string,\n prompt_count: row.prompt_count as number,\n tool_count: row.tool_count as number,\n title: (row.title as string) ?? null,\n summary: (row.summary as string) ?? null,\n transcript_path: (row.transcript_path as string) ?? null,\n parent_session_id: (row.parent_session_id as string) ?? null,\n parent_session_reason: (row.parent_session_reason as string) ?? null,\n processed: row.processed as number,\n content_hash: (row.content_hash as string) ?? null,\n embedded: (row.embedded as number) ?? 0,\n created_at: row.created_at as number,\n machine_id: (row.machine_id as string) ?? 'local',\n synced_at: (row.synced_at as number) ?? null,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Insert a session or update it if the id already exists.\n *\n * On conflict the row is updated with the values from `data`, preserving\n * any columns not supplied via COALESCE with EXCLUDED values.\n */\nexport function upsertSession(data: SessionInsert): SessionRow {\n const db = getDatabase();\n\n db.prepare(\n `INSERT INTO sessions (\n id, agent, \"user\", project_root, branch,\n started_at, ended_at, status, prompt_count, tool_count,\n title, summary, transcript_path,\n parent_session_id, parent_session_reason,\n processed, content_hash, created_at, machine_id\n ) VALUES (\n ?, ?, ?, ?, ?,\n ?, ?, ?, ?, ?,\n ?, ?, ?,\n ?, ?,\n ?, ?, ?, ?\n )\n ON CONFLICT (id) DO UPDATE SET\n agent = EXCLUDED.agent,\n \"user\" = EXCLUDED.\"user\",\n project_root = EXCLUDED.project_root,\n branch = EXCLUDED.branch,\n started_at = EXCLUDED.started_at,\n ended_at = COALESCE(EXCLUDED.ended_at, sessions.ended_at),\n status = COALESCE(EXCLUDED.status, sessions.status),\n prompt_count = CASE WHEN ? THEN EXCLUDED.prompt_count ELSE sessions.prompt_count END,\n tool_count = CASE WHEN ? THEN EXCLUDED.tool_count ELSE sessions.tool_count END,\n title = COALESCE(EXCLUDED.title, sessions.title),\n summary = COALESCE(EXCLUDED.summary, sessions.summary),\n transcript_path = COALESCE(EXCLUDED.transcript_path, sessions.transcript_path),\n parent_session_id = EXCLUDED.parent_session_id,\n parent_session_reason = EXCLUDED.parent_session_reason,\n processed = COALESCE(EXCLUDED.processed, sessions.processed),\n content_hash = EXCLUDED.content_hash`,\n ).run(\n data.id,\n data.agent,\n data.user ?? null,\n data.project_root ?? null,\n data.branch ?? null,\n data.started_at,\n data.ended_at ?? null,\n data.status ?? DEFAULT_STATUS,\n data.prompt_count ?? DEFAULT_PROMPT_COUNT,\n data.tool_count ?? DEFAULT_TOOL_COUNT,\n data.title ?? null,\n data.summary ?? null,\n data.transcript_path ?? null,\n data.parent_session_id ?? null,\n data.parent_session_reason ?? null,\n data.processed ?? DEFAULT_PROCESSED,\n data.content_hash ?? null,\n data.created_at,\n data.machine_id ?? getTeamMachineId(),\n data.prompt_count !== undefined ? 1 : 0,\n data.tool_count !== undefined ? 1 : 0,\n );\n\n const row = toSessionRow(\n db.prepare(`SELECT ${SELECT_COLUMNS} FROM sessions WHERE id = ?`).get(data.id) as Record<string, unknown>,\n );\n\n syncRow('sessions', row);\n\n return row;\n}\n\n/**\n * Retrieve a single session by id.\n *\n * @returns the session row, or null if not found.\n */\nexport function getSession(id: string): SessionRow | null {\n const db = getDatabase();\n\n const row = db.prepare(\n `SELECT ${SELECT_COLUMNS} FROM sessions WHERE id = ?`,\n ).get(id) as Record<string, unknown> | undefined;\n\n if (!row) return null;\n return toSessionRow(row);\n}\n\n/** Build WHERE clause and bound params from session filter options. */\nfunction buildSessionsWhere(\n options: Omit<ListSessionsOptions, 'limit' | 'offset'>,\n): { where: string; params: unknown[] } {\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (options.status !== undefined) {\n conditions.push(`status = ?`);\n params.push(options.status);\n }\n\n if (options.agent !== undefined) {\n conditions.push(`agent = ?`);\n params.push(options.agent);\n }\n\n if (options.branch !== undefined) {\n conditions.push(`branch = ?`);\n params.push(options.branch);\n }\n\n if (options.user !== undefined) {\n conditions.push(`\"user\" = ?`);\n params.push(options.user);\n }\n\n if (options.id !== undefined) {\n conditions.push(`id = ?`);\n params.push(options.id);\n }\n\n if (options.search !== undefined && options.search.length > 0) {\n conditions.push(`(title LIKE ? OR id LIKE ?)`);\n const pattern = `%${options.search}%`;\n params.push(pattern, pattern);\n }\n if (options.since !== undefined) {\n conditions.push('created_at > ?');\n params.push(options.since);\n }\n\n // Exclude active sessions only when the caller explicitly opts in and\n // hasn't already constrained `status`. Intelligence-task reads set this\n // to avoid picking up in-flight work; UI/CLI leave it unset.\n if (options.includeActive === false && options.status === undefined) {\n conditions.push(`status != 'active'`);\n }\n\n return {\n where: conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '',\n params,\n };\n}\n\n/**\n * List sessions with optional filters, ordered by created_at DESC.\n */\nexport function listSessions(\n options: ListSessionsOptions = {},\n): SessionRow[] {\n const db = getDatabase();\n const { where, params } = buildSessionsWhere(options);\n const limit = options.limit ?? DEFAULT_LIST_LIMIT;\n const offset = options.offset ?? 0;\n\n const rows = db.prepare(\n `SELECT ${SELECT_COLUMNS}\n FROM sessions\n ${where}\n ORDER BY created_at DESC\n LIMIT ?\n OFFSET ?`,\n ).all(...params, limit, offset) as Record<string, unknown>[];\n\n return rows.map(toSessionRow);\n}\n\n/**\n * Count sessions matching optional filters (for pagination totals).\n */\nexport function countSessions(\n options: Omit<ListSessionsOptions, 'limit' | 'offset'> = {},\n): number {\n const db = getDatabase();\n const { where, params } = buildSessionsWhere(options);\n\n const row = db.prepare(\n `SELECT COUNT(*) as count FROM sessions ${where}`,\n ).get(...params) as { count: number };\n\n return row.count;\n}\n\n/**\n * Return the set of session IDs currently in `status = 'active'`.\n *\n * Used by the semantic-search path, which can't apply a SQL join against\n * session status (the vector store is a separate concern), so it filters\n * results in-memory against this set instead. Bounded by the number of\n * concurrent in-flight sessions — typically small.\n */\nexport function getActiveSessionIds(): Set<string> {\n const db = getDatabase();\n const rows = db.prepare(\n `SELECT id FROM sessions WHERE status = 'active'`,\n ).all() as Array<{ id: string }>;\n return new Set(rows.map((r) => r.id));\n}\n\n/**\n * Flip a session back to `status = 'active'` if it's currently `'completed'`.\n *\n * Called on live user activity (`user_prompt` events) so a session that was\n * auto-completed by the stale sweep or manually completed via the API snaps\n * back to active transparently when the user resumes. No-op for sessions\n * that are already active or don't exist.\n *\n * The `ended_at` column is intentionally preserved — it records the most\n * recent completion time, and the next completion will overwrite it.\n *\n * @returns true if a row was updated (session was completed and is now active)\n */\nexport function reactivateSessionIfCompleted(id: string): boolean {\n const db = getDatabase();\n const info = db.prepare(\n `UPDATE sessions SET status = 'active' WHERE id = ? AND status = 'completed'`,\n ).run(id);\n if (info.changes === 0) return false;\n\n const row = db.prepare(\n `SELECT ${SELECT_COLUMNS} FROM sessions WHERE id = ?`,\n ).get(id) as Record<string, unknown> | undefined;\n if (row) syncRow('sessions', toSessionRow(row));\n\n return true;\n}\n\n/**\n * Update specific fields on an existing session.\n *\n * @returns the updated row, or null if the session does not exist.\n */\nexport function updateSession(\n id: string,\n updates: SessionUpdate,\n): SessionRow | null {\n const db = getDatabase();\n\n const setClauses: string[] = [];\n const params: unknown[] = [];\n\n const fieldMap: Record<string, string> = {\n agent: 'agent',\n user: '\"user\"',\n project_root: 'project_root',\n branch: 'branch',\n ended_at: 'ended_at',\n status: 'status',\n prompt_count: 'prompt_count',\n tool_count: 'tool_count',\n title: 'title',\n summary: 'summary',\n transcript_path: 'transcript_path',\n parent_session_id: 'parent_session_id',\n parent_session_reason: 'parent_session_reason',\n processed: 'processed',\n content_hash: 'content_hash',\n };\n\n for (const [key, column] of Object.entries(fieldMap)) {\n if (key in updates) {\n setClauses.push(`${column} = ?`);\n params.push((updates as Record<string, unknown>)[key] ?? null);\n }\n }\n\n if (setClauses.length === 0) return getSession(id);\n\n params.push(id);\n\n db.prepare(\n `UPDATE sessions\n SET ${setClauses.join(', ')}\n WHERE id = ?`,\n ).run(...params);\n\n const updated = getSession(id);\n\n if (updated) syncRow('sessions', updated);\n\n return updated;\n}\n\n/**\n * Atomically increment tool_count for a session.\n *\n * Uses SQL `tool_count + 1` to avoid read-modify-write races.\n */\nexport function incrementSessionToolCount(id: string): void {\n const db = getDatabase();\n db.prepare(\n `UPDATE sessions SET tool_count = COALESCE(tool_count, 0) + 1 WHERE id = ?`,\n ).run(id);\n}\n\n/**\n * Close a session — set status to 'completed' and record the end time.\n *\n * @returns the updated row, or null if the session does not exist.\n */\nexport function closeSession(\n id: string,\n endedAt: number,\n): SessionRow | null {\n const db = getDatabase();\n\n db.prepare(\n `UPDATE sessions\n SET status = ?, ended_at = ?\n WHERE id = ?`,\n ).run(STATUS_COMPLETED, endedAt, id);\n\n const closed = getSession(id);\n\n if (closed) syncRow('sessions', closed);\n\n return closed;\n}\n\n/**\n * Delete a session and all its child rows (batches, activities, attachments).\n *\n * No ON DELETE CASCADE in the schema, so we delete children first.\n * Returns true if the session existed and was deleted.\n */\nexport function deleteSession(id: string): boolean {\n const db = getDatabase();\n\n db.prepare(`DELETE FROM activities WHERE session_id = ?`).run(id);\n db.prepare(`DELETE FROM attachments WHERE session_id = ?`).run(id);\n db.prepare(`DELETE FROM prompt_batches WHERE session_id = ?`).run(id);\n const info = db.prepare(`DELETE FROM sessions WHERE id = ?`).run(id);\n\n return info.changes > 0;\n}\n\n// ---------------------------------------------------------------------------\n// Cascade delete + impact query\n// ---------------------------------------------------------------------------\n\n/** Counts of related data that would be affected by a session delete. */\nexport interface SessionImpact {\n promptCount: number;\n sporeCount: number;\n attachmentCount: number;\n graphEdgeCount: number;\n}\n\n/** Result of a cascade delete operation. */\nexport interface DeleteCascadeResult {\n deleted: boolean;\n counts: {\n prompts: number;\n spores: number;\n attachments: number;\n graphEdges: number;\n resolutionEvents: number;\n };\n /** Spore IDs that were deleted (needed for vault file + vector cleanup). */\n deletedSporeIds: string[];\n /** Attachment file paths that were deleted from DB (needed for disk cleanup). */\n deletedAttachmentPaths: string[];\n}\n\n/**\n * Get counts of all data related to a session, for pre-delete impact display.\n */\nexport function getSessionImpact(sessionId: string): SessionImpact {\n const db = getDatabase();\n\n const row = db.prepare(\n `SELECT\n (SELECT COUNT(*) FROM prompt_batches WHERE session_id = ?) AS promptCount,\n (SELECT COUNT(*) FROM spores WHERE session_id = ?) AS sporeCount,\n (SELECT COUNT(*) FROM attachments WHERE session_id = ?) AS attachmentCount,\n (SELECT COUNT(*) FROM graph_edges WHERE session_id = ?) AS graphEdgeCount`,\n ).get(sessionId, sessionId, sessionId, sessionId) as SessionImpact;\n\n return row;\n}\n\n/**\n * Delete a session and ALL related data in a single transaction.\n *\n * Returns counts of deleted rows and IDs needed for post-transaction\n * cleanup (vault files, embedding vectors).\n */\nexport function deleteSessionCascade(sessionId: string): DeleteCascadeResult {\n const db = getDatabase();\n\n const zeroCounts: DeleteCascadeResult = {\n deleted: false,\n counts: { prompts: 0, spores: 0, attachments: 0, graphEdges: 0, resolutionEvents: 0 },\n deletedSporeIds: [],\n deletedAttachmentPaths: [],\n };\n\n // Check session exists first\n const exists = db.prepare(`SELECT id FROM sessions WHERE id = ?`).get(sessionId);\n if (!exists) return zeroCounts;\n\n // Collect IDs/paths needed for post-transaction cleanup before deleting.\n // Spores can reference prompt_batches from a different session (cross-session\n // spore linkage), so we must also collect spores linked via prompt_batch_id.\n const sporeIds = (db.prepare(\n `SELECT id FROM spores\n WHERE session_id = ?\n OR prompt_batch_id IN (SELECT id FROM prompt_batches WHERE session_id = ?)`,\n ).all(sessionId, sessionId) as { id: string }[]).map((r) => r.id);\n\n const attachmentPaths = (db.prepare(\n `SELECT file_path FROM attachments WHERE session_id = ?`,\n ).all(sessionId) as { file_path: string }[]).map((r) => r.file_path);\n\n // Run all deletes in a single transaction.\n //\n // Order matters — foreign_keys = ON is set in client.ts, so every DELETE\n // is checked immediately. Child rows must be removed before their parents:\n // - spores.prompt_batch_id → prompt_batches(id) [spores BEFORE prompt_batches]\n // - plans.prompt_batch_id → prompt_batches(id) [plans BEFORE prompt_batches]\n // - resolution_events.spore_id → spores(id) [resolution_events BEFORE spores]\n // - skill_usage.session_id → sessions(id) NOT NULL\n // - plans.session_id → sessions(id)\n // resolution_events can reference spores across sessions (e.g. a later\n // session supersedes an earlier session's spore), so we match by either\n // session_id OR spore_id-in-this-session to catch cross-session references.\n //\n // Spores can also reference prompt_batches from a different session\n // (cross-session prompt_batch_id linkage). We must delete those spores\n // BEFORE deleting prompt_batches to avoid FK violations.\n const result = db.transaction(() => {\n db.prepare(`DELETE FROM activities WHERE session_id = ?`).run(sessionId);\n const attachments = db.prepare(`DELETE FROM attachments WHERE session_id = ?`).run(sessionId);\n db.prepare(`DELETE FROM plans WHERE session_id = ?`).run(sessionId);\n db.prepare(`DELETE FROM skill_usage WHERE session_id = ?`).run(sessionId);\n const resEvents = db.prepare(\n `DELETE FROM resolution_events\n WHERE session_id = ?\n OR spore_id IN (\n SELECT id FROM spores\n WHERE session_id = ?\n OR prompt_batch_id IN (SELECT id FROM prompt_batches WHERE session_id = ?)\n )`,\n ).run(sessionId, sessionId, sessionId);\n const edges = db.prepare(`DELETE FROM graph_edges WHERE session_id = ?`).run(sessionId);\n const spores = db.prepare(\n `DELETE FROM spores\n WHERE session_id = ?\n OR prompt_batch_id IN (SELECT id FROM prompt_batches WHERE session_id = ?)`,\n ).run(sessionId, sessionId);\n const prompts = db.prepare(`DELETE FROM prompt_batches WHERE session_id = ?`).run(sessionId);\n const session = db.prepare(`DELETE FROM sessions WHERE id = ?`).run(sessionId);\n\n return {\n deleted: session.changes > 0,\n counts: {\n prompts: prompts.changes,\n spores: spores.changes,\n attachments: attachments.changes,\n graphEdges: edges.changes,\n resolutionEvents: resEvents.changes,\n },\n };\n })();\n\n return {\n ...result,\n deletedSporeIds: sporeIds,\n deletedAttachmentPaths: attachmentPaths,\n };\n}\n"],"mappings":"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","names":["SELECT_COLUMNS"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
loadAllTasks
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-57O67XVF.js";
|
|
5
5
|
import {
|
|
6
6
|
getAgent,
|
|
7
7
|
getDefaultTask,
|
|
@@ -9,23 +9,21 @@ import {
|
|
|
9
9
|
loadAgentDefinition,
|
|
10
10
|
resolveDefinitionsDir,
|
|
11
11
|
resolveEffectiveConfig
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-4M7EWPIA.js";
|
|
13
13
|
import {
|
|
14
14
|
getSpore,
|
|
15
15
|
listSporeIdsSince,
|
|
16
16
|
listSpores
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-4YFKBL3F.js";
|
|
18
18
|
import {
|
|
19
19
|
getSession,
|
|
20
|
-
listSessions
|
|
21
|
-
} from "./chunk-Q6OEZM3S.js";
|
|
22
|
-
import {
|
|
23
20
|
getTeamMachineId,
|
|
21
|
+
listSessions,
|
|
24
22
|
syncRow
|
|
25
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-EVDQKYCG.js";
|
|
26
24
|
import {
|
|
27
|
-
|
|
28
|
-
} from "./chunk-
|
|
25
|
+
loadMergedConfig
|
|
26
|
+
} from "./chunk-SRXTSI25.js";
|
|
29
27
|
import {
|
|
30
28
|
getDatabase
|
|
31
29
|
} from "./chunk-MYX5NCRH.js";
|
|
@@ -39,7 +37,7 @@ import {
|
|
|
39
37
|
GRAPH_EDGE_DEFAULT_CONFIDENCE,
|
|
40
38
|
QUERY_DEFAULT_LIST_LIMIT,
|
|
41
39
|
epochSeconds
|
|
42
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-FLLBJLHM.js";
|
|
43
41
|
import {
|
|
44
42
|
require_dist
|
|
45
43
|
} from "./chunk-6LQIMRTC.js";
|
|
@@ -140,7 +138,7 @@ function getType(typeId) {
|
|
|
140
138
|
function notify(vaultDir, payload, config) {
|
|
141
139
|
if (!vaultDir) return null;
|
|
142
140
|
try {
|
|
143
|
-
const cfg = config ??
|
|
141
|
+
const cfg = config ?? loadMergedConfig(vaultDir);
|
|
144
142
|
if (!cfg.notifications.enabled) return null;
|
|
145
143
|
const domainConfig = cfg.notifications.domains[payload.domain];
|
|
146
144
|
if (domainConfig && !domainConfig.enabled) return null;
|
|
@@ -404,7 +402,7 @@ function resolveRunConfig(agentId, requestedTask, vaultDir) {
|
|
|
404
402
|
let phaseProviderOverrides = {};
|
|
405
403
|
let taskParams;
|
|
406
404
|
try {
|
|
407
|
-
const mycoConfig =
|
|
405
|
+
const mycoConfig = loadMergedConfig(vaultDir);
|
|
408
406
|
const taskConfig = taskName ? mycoConfig.agent.tasks?.[taskName] : void 0;
|
|
409
407
|
const globalProvider = mycoConfig.agent.provider;
|
|
410
408
|
if (taskConfig?.provider) {
|
|
@@ -2091,6 +2089,58 @@ function createBatchLineage(agentId, sessionId, batchId, createdAt) {
|
|
|
2091
2089
|
});
|
|
2092
2090
|
}
|
|
2093
2091
|
|
|
2092
|
+
// src/db/queries/resolution-events.ts
|
|
2093
|
+
var EVENT_COLUMNS = [
|
|
2094
|
+
"id",
|
|
2095
|
+
"agent_id",
|
|
2096
|
+
"spore_id",
|
|
2097
|
+
"action",
|
|
2098
|
+
"new_spore_id",
|
|
2099
|
+
"reason",
|
|
2100
|
+
"session_id",
|
|
2101
|
+
"created_at",
|
|
2102
|
+
"machine_id",
|
|
2103
|
+
"synced_at"
|
|
2104
|
+
];
|
|
2105
|
+
var SELECT_COLUMNS10 = EVENT_COLUMNS.join(", ");
|
|
2106
|
+
function toResolutionEventRow(row) {
|
|
2107
|
+
return {
|
|
2108
|
+
id: row.id,
|
|
2109
|
+
agent_id: row.agent_id,
|
|
2110
|
+
spore_id: row.spore_id,
|
|
2111
|
+
action: row.action,
|
|
2112
|
+
new_spore_id: row.new_spore_id ?? null,
|
|
2113
|
+
reason: row.reason ?? null,
|
|
2114
|
+
session_id: row.session_id ?? null,
|
|
2115
|
+
created_at: row.created_at,
|
|
2116
|
+
machine_id: row.machine_id ?? "local",
|
|
2117
|
+
synced_at: row.synced_at ?? null
|
|
2118
|
+
};
|
|
2119
|
+
}
|
|
2120
|
+
function insertResolutionEvent(data) {
|
|
2121
|
+
const db = getDatabase();
|
|
2122
|
+
db.prepare(
|
|
2123
|
+
`INSERT INTO resolution_events (
|
|
2124
|
+
id, agent_id, spore_id, action, new_spore_id, reason, session_id, created_at, machine_id
|
|
2125
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
2126
|
+
).run(
|
|
2127
|
+
data.id,
|
|
2128
|
+
data.agent_id,
|
|
2129
|
+
data.spore_id,
|
|
2130
|
+
data.action,
|
|
2131
|
+
data.new_spore_id ?? null,
|
|
2132
|
+
data.reason ?? null,
|
|
2133
|
+
data.session_id ?? null,
|
|
2134
|
+
data.created_at,
|
|
2135
|
+
data.machine_id ?? getTeamMachineId()
|
|
2136
|
+
);
|
|
2137
|
+
const row = toResolutionEventRow(
|
|
2138
|
+
db.prepare(`SELECT ${SELECT_COLUMNS10} FROM resolution_events WHERE id = ?`).get(data.id)
|
|
2139
|
+
);
|
|
2140
|
+
syncRow("resolution_events", row);
|
|
2141
|
+
return row;
|
|
2142
|
+
}
|
|
2143
|
+
|
|
2094
2144
|
// src/db/queries/reports.ts
|
|
2095
2145
|
var REPORT_COLUMNS = [
|
|
2096
2146
|
"id",
|
|
@@ -2101,7 +2151,7 @@ var REPORT_COLUMNS = [
|
|
|
2101
2151
|
"details",
|
|
2102
2152
|
"created_at"
|
|
2103
2153
|
];
|
|
2104
|
-
var
|
|
2154
|
+
var SELECT_COLUMNS11 = REPORT_COLUMNS.join(", ");
|
|
2105
2155
|
function toReportRow(row) {
|
|
2106
2156
|
return {
|
|
2107
2157
|
id: row.id,
|
|
@@ -2131,13 +2181,13 @@ function insertReport(data) {
|
|
|
2131
2181
|
);
|
|
2132
2182
|
const reportId = Number(info.lastInsertRowid);
|
|
2133
2183
|
return toReportRow(
|
|
2134
|
-
db.prepare(`SELECT ${
|
|
2184
|
+
db.prepare(`SELECT ${SELECT_COLUMNS11} FROM agent_reports WHERE id = ?`).get(reportId)
|
|
2135
2185
|
);
|
|
2136
2186
|
}
|
|
2137
2187
|
function listReports(runId) {
|
|
2138
2188
|
const db = getDatabase();
|
|
2139
2189
|
const rows = db.prepare(
|
|
2140
|
-
`SELECT ${
|
|
2190
|
+
`SELECT ${SELECT_COLUMNS11}
|
|
2141
2191
|
FROM agent_reports
|
|
2142
2192
|
WHERE run_id = ?
|
|
2143
2193
|
ORDER BY created_at ASC`
|
|
@@ -2205,6 +2255,7 @@ export {
|
|
|
2205
2255
|
listEntities,
|
|
2206
2256
|
createSporeLineage,
|
|
2207
2257
|
createBatchLineage,
|
|
2258
|
+
insertResolutionEvent,
|
|
2208
2259
|
upsertDigestExtract,
|
|
2209
2260
|
getDigestExtract,
|
|
2210
2261
|
listDigestExtracts,
|
|
@@ -2222,4 +2273,4 @@ export {
|
|
|
2222
2273
|
buildTaskInstruction,
|
|
2223
2274
|
isInstructionRequiredTask
|
|
2224
2275
|
};
|
|
2225
|
-
//# sourceMappingURL=chunk-
|
|
2276
|
+
//# sourceMappingURL=chunk-FGY7J6EZ.js.map
|