codedeck 0.6.0 → 0.7.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/README.md +50 -35
- package/dist/cli/commands/claims.js +3 -2
- package/dist/cli/commands/claims.js.map +1 -1
- package/dist/cli/commands/doctor.js +8 -40
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/logs.js +2 -2
- package/dist/cli/commands/logs.js.map +1 -1
- package/dist/cli/commands/open.js +102 -11
- package/dist/cli/commands/open.js.map +1 -1
- package/dist/cli/commands/ps.js +6 -6
- package/dist/cli/commands/ps.js.map +1 -1
- package/dist/cli/commands/review.js +36 -58
- package/dist/cli/commands/review.js.map +1 -1
- package/dist/cli/commands/run.js +27 -27
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/setup.js +96 -314
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/show.js +2 -1
- package/dist/cli/commands/show.js.map +1 -1
- package/dist/cli/commands/ui.js +61 -0
- package/dist/cli/commands/ui.js.map +1 -0
- package/dist/cli/commands/usage-backfill.js +149 -0
- package/dist/cli/commands/usage-backfill.js.map +1 -0
- package/dist/cli/commands/usage.js +113 -45
- package/dist/cli/commands/usage.js.map +1 -1
- package/dist/cli/commands/wait.js +3 -2
- package/dist/cli/commands/wait.js.map +1 -1
- package/dist/cli/index.js +55 -39
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/web-launch.js +126 -0
- package/dist/cli/web-launch.js.map +1 -0
- package/dist/config/config.js +0 -70
- package/dist/config/config.js.map +1 -1
- package/dist/config/paths.js +1 -0
- package/dist/config/paths.js.map +1 -1
- package/dist/config/setup.js +248 -0
- package/dist/config/setup.js.map +1 -0
- package/dist/config/web-host.js +31 -0
- package/dist/config/web-host.js.map +1 -0
- package/dist/config/web-port.js +24 -0
- package/dist/config/web-port.js.map +1 -0
- package/dist/core/claude-transcript.js +226 -0
- package/dist/core/claude-transcript.js.map +1 -0
- package/dist/core/errors.js +17 -0
- package/dist/core/errors.js.map +1 -1
- package/dist/core/models.js +4 -1
- package/dist/core/models.js.map +1 -1
- package/dist/core/pricing.js +87 -55
- package/dist/core/pricing.js.map +1 -1
- package/dist/core/roles.js +6 -5
- package/dist/core/roles.js.map +1 -1
- package/dist/core/run-skills.js +114 -0
- package/dist/core/run-skills.js.map +1 -0
- package/dist/core/run-usage.js +56 -10
- package/dist/core/run-usage.js.map +1 -1
- package/dist/core/session.js +6 -16
- package/dist/core/session.js.map +1 -1
- package/dist/core/usage-query.js +41 -0
- package/dist/core/usage-query.js.map +1 -0
- package/dist/core/usage-source.js +17 -0
- package/dist/core/usage-source.js.map +1 -0
- package/dist/daemon/build-id.js +30 -0
- package/dist/daemon/build-id.js.map +1 -0
- package/dist/daemon/daemon.js +1257 -700
- package/dist/daemon/daemon.js.map +1 -1
- package/dist/daemon/instance-lock.js +48 -0
- package/dist/daemon/instance-lock.js.map +1 -0
- package/dist/daemon/ipc.js +4 -3
- package/dist/daemon/ipc.js.map +1 -1
- package/dist/daemon/web-supervisor.js +251 -0
- package/dist/daemon/web-supervisor.js.map +1 -0
- package/dist/drivers/claude/driver.js +1 -0
- package/dist/drivers/claude/driver.js.map +1 -1
- package/dist/drivers/codex/driver.js +14 -3
- package/dist/drivers/codex/driver.js.map +1 -1
- package/dist/drivers/codex/host-skills.js +57 -0
- package/dist/drivers/codex/host-skills.js.map +1 -0
- package/dist/drivers/opencode/driver.js +6 -2
- package/dist/drivers/opencode/driver.js.map +1 -1
- package/dist/drivers/session-driver.js +7 -1
- package/dist/drivers/session-driver.js.map +1 -1
- package/dist/drivers/session-runtime.js +2 -0
- package/dist/drivers/session-runtime.js.map +1 -1
- package/dist/drivers/terminal.js +15 -0
- package/dist/drivers/terminal.js.map +1 -1
- package/dist/git/diff.js +29 -4
- package/dist/git/diff.js.map +1 -1
- package/dist/open/contract.js.map +1 -1
- package/dist/open/launchers/claude.js +78 -2
- package/dist/open/launchers/claude.js.map +1 -1
- package/dist/open/link-watcher.js +44 -0
- package/dist/open/link-watcher.js.map +1 -0
- package/dist/open/pty.js +330 -5
- package/dist/open/pty.js.map +1 -1
- package/dist/open/runtime.js +15 -12
- package/dist/open/runtime.js.map +1 -1
- package/dist/plugin/agents/general.md +33 -6
- package/dist/plugin/hooks/pane-ticker.ts +102 -0
- package/dist/plugin/hooks/register.tsx +39 -18
- package/dist/plugin/hooks/session-id.sh +1 -1
- package/dist/plugin/mods/agents/pane.ts +285 -156
- package/dist/plugin/mods/agents/types.ts +23 -3
- package/dist/plugin/statusline.sh +57 -32
- package/dist/store/database.js +49 -1
- package/dist/store/database.js.map +1 -1
- package/dist/store/native-links.js +80 -0
- package/dist/store/native-links.js.map +1 -0
- package/dist/store/sessions.js +166 -51
- package/dist/store/sessions.js.map +1 -1
- package/dist/store/usage-ledger.js +153 -0
- package/dist/store/usage-ledger.js.map +1 -0
- package/dist/utils/process.js +2 -16
- package/dist/utils/process.js.map +1 -1
- package/dist/web/brand.js +59 -0
- package/dist/web/brand.js.map +1 -0
- package/dist/web/child.js +67 -0
- package/dist/web/child.js.map +1 -0
- package/dist/web/home-page.js +48 -0
- package/dist/web/home-page.js.map +1 -0
- package/dist/web/review-page.js +12 -5
- package/dist/web/review-page.js.map +1 -1
- package/dist/web/security.js +170 -0
- package/dist/web/security.js.map +1 -0
- package/dist/web/server.js +198 -0
- package/dist/web/server.js.map +1 -0
- package/dist/web/setup-icons.js +37 -0
- package/dist/web/setup-icons.js.map +1 -0
- package/dist/web/setup-page.js +1795 -0
- package/dist/web/setup-page.js.map +1 -0
- package/dist/web/setup-routes.js +475 -0
- package/dist/web/setup-routes.js.map +1 -0
- package/dist/web/usage-page.js +609 -0
- package/dist/web/usage-page.js.map +1 -0
- package/dist/web/usage-routes.js +88 -0
- package/dist/web/usage-routes.js.map +1 -0
- package/dist/web/web-token.js +56 -0
- package/dist/web/web-token.js.map +1 -0
- package/package.json +1 -1
- package/dist/plugin/prompts/_partials/commit.md +0 -145
- package/dist/plugin/prompts/_partials/pr-writer.md +0 -186
|
@@ -65,26 +65,6 @@ const role =
|
|
|
65
65
|
tail(payload.agent?.name) ??
|
|
66
66
|
tail(payload.session_name);
|
|
67
67
|
|
|
68
|
-
const taskName = (() => {
|
|
69
|
-
const sessionFile = text(process.env.CODEDECK_SESSION_FILE);
|
|
70
|
-
const sessionId = payload.session_id;
|
|
71
|
-
if (
|
|
72
|
-
!sessionFile ||
|
|
73
|
-
typeof sessionId !== "string" ||
|
|
74
|
-
!/^[0-9a-fA-F-]{8,}$/.test(sessionId)
|
|
75
|
-
) return undefined;
|
|
76
|
-
|
|
77
|
-
try {
|
|
78
|
-
const value = readFileSync(`${sessionFile}.${sessionId}.name`, "utf8")
|
|
79
|
-
.replace(/\s+/g, " ")
|
|
80
|
-
.trim()
|
|
81
|
-
.slice(0, 30);
|
|
82
|
-
return value || undefined;
|
|
83
|
-
} catch {
|
|
84
|
-
return undefined;
|
|
85
|
-
}
|
|
86
|
-
})();
|
|
87
|
-
|
|
88
68
|
const cwd = firstText(payload.workspace?.current_dir, payload.cwd) ?? process.cwd();
|
|
89
69
|
const project = text(basename(cwd)) ?? (cwd === "/" ? "/" : undefined);
|
|
90
70
|
|
|
@@ -132,9 +112,8 @@ const compactTokens = (value) => {
|
|
|
132
112
|
|
|
133
113
|
/**
|
|
134
114
|
* Since Claude Code 2.1.132, these fields describe the latest context window,
|
|
135
|
-
* not cumulative session totals.
|
|
136
|
-
*
|
|
137
|
-
* Degraded mode may show this current local snapshot when it is available.
|
|
115
|
+
* not cumulative session totals. Use the local snapshot only without an active
|
|
116
|
+
* run summary, which already combines worker and orchestrator token totals.
|
|
138
117
|
*/
|
|
139
118
|
const localTokens = () => {
|
|
140
119
|
const context = payload.context_window;
|
|
@@ -177,12 +156,23 @@ const localCost = () => {
|
|
|
177
156
|
return typeof total === "number" && Number.isFinite(total) ? total : undefined;
|
|
178
157
|
};
|
|
179
158
|
|
|
159
|
+
const runId = text(process.env.CODEDECK_RUN_ID);
|
|
160
|
+
|
|
180
161
|
const getRunUsage = () => {
|
|
181
|
-
const runId = text(process.env.CODEDECK_RUN_ID);
|
|
182
162
|
if (!runId) return undefined;
|
|
183
163
|
|
|
164
|
+
const args = ["usage", runId, "--json"];
|
|
165
|
+
const sessionId = payload.session_id;
|
|
166
|
+
const validSessionId =
|
|
167
|
+
typeof sessionId === "string" && /^[0-9a-fA-F-]{8,}$/.test(sessionId);
|
|
168
|
+
const observeCost = nonNegativeNumber(payload.cost?.total_cost_usd);
|
|
169
|
+
if (validSessionId && observeCost !== undefined) args.push("--observe", `${sessionId}=${observeCost}`);
|
|
170
|
+
if (validSessionId && typeof payload.transcript_path === "string" && payload.transcript_path.length > 0) {
|
|
171
|
+
args.push("--transcript", `${sessionId}=${payload.transcript_path}`);
|
|
172
|
+
}
|
|
173
|
+
|
|
184
174
|
try {
|
|
185
|
-
const output = execFileSync("codedeck",
|
|
175
|
+
const output = execFileSync("codedeck", args, {
|
|
186
176
|
encoding: "utf8",
|
|
187
177
|
stdio: ["ignore", "pipe", "ignore"],
|
|
188
178
|
timeout: 1000,
|
|
@@ -215,20 +205,52 @@ const getRunUsage = () => {
|
|
|
215
205
|
}
|
|
216
206
|
};
|
|
217
207
|
|
|
208
|
+
const isObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
209
|
+
|
|
210
|
+
const getOrchestratorUsage = (usage) => {
|
|
211
|
+
const value = usage.orchestrator;
|
|
212
|
+
if (
|
|
213
|
+
!isObject(value) ||
|
|
214
|
+
nonNegativeNumber(value.costUsd) === undefined ||
|
|
215
|
+
typeof value.costComplete !== "boolean" ||
|
|
216
|
+
nonNegativeNumber(value.inputTokens) === undefined ||
|
|
217
|
+
nonNegativeNumber(value.outputTokens) === undefined ||
|
|
218
|
+
nonNegativeNumber(value.cachedTokens) === undefined ||
|
|
219
|
+
!Array.isArray(value.sources)
|
|
220
|
+
) return undefined;
|
|
221
|
+
if (!value.sources.every((source) =>
|
|
222
|
+
isObject(source) &&
|
|
223
|
+
typeof source.nativeId === "string" &&
|
|
224
|
+
nonNegativeNumber(source.costUsd) !== undefined
|
|
225
|
+
)) return undefined;
|
|
226
|
+
return value;
|
|
227
|
+
};
|
|
228
|
+
|
|
218
229
|
const local = localCost();
|
|
219
230
|
const runUsage = getRunUsage();
|
|
220
|
-
const
|
|
221
|
-
|
|
231
|
+
const orchestratorUsage = runUsage ? getOrchestratorUsage(runUsage) : undefined;
|
|
232
|
+
const workerTokens = runUsage ? nonNegativeNumber(runUsage.totalTokens) : undefined;
|
|
233
|
+
const orchestratorTokens = runUsage && isObject(runUsage.orchestrator)
|
|
234
|
+
? nonNegativeNumber(runUsage.orchestrator.totalTokens)
|
|
235
|
+
: undefined;
|
|
236
|
+
const runTokens = workerTokens !== undefined && orchestratorTokens !== undefined
|
|
237
|
+
? nonNegativeNumber(workerTokens + orchestratorTokens)
|
|
222
238
|
: undefined;
|
|
223
239
|
const tokenField = () => {
|
|
224
|
-
const total =
|
|
240
|
+
const total = runId ? runTokens : localTokens();
|
|
225
241
|
return total === undefined ? undefined : paint(MUTED, compactTokens(total) + " tok");
|
|
226
242
|
};
|
|
227
243
|
|
|
228
244
|
const runField = () => {
|
|
229
245
|
if (!runUsage) return undefined;
|
|
230
|
-
const
|
|
231
|
-
|
|
246
|
+
const sourceCost = orchestratorUsage
|
|
247
|
+
? orchestratorUsage.sources.reduce(
|
|
248
|
+
(sum, source) => source.nativeId === payload.session_id ? sum : sum + source.costUsd,
|
|
249
|
+
0,
|
|
250
|
+
)
|
|
251
|
+
: 0;
|
|
252
|
+
const total = (local ?? 0) + runUsage.costUsd + sourceCost;
|
|
253
|
+
const incomplete = !runUsage.costComplete || Boolean(orchestratorUsage && !orchestratorUsage.costComplete);
|
|
232
254
|
if (!incomplete && total < COST_DISPLAY_THRESHOLD) return undefined;
|
|
233
255
|
return paint(MUTED, "run ") + costAmount(total, incomplete);
|
|
234
256
|
};
|
|
@@ -238,8 +260,12 @@ const localField = () => {
|
|
|
238
260
|
return costAmount(local);
|
|
239
261
|
};
|
|
240
262
|
|
|
263
|
+
const collapsedProjectBranch = project && branch &&
|
|
264
|
+
(branch === project || branch === `worktree-${project}`);
|
|
241
265
|
const projectBranch = project && branch
|
|
242
|
-
?
|
|
266
|
+
? collapsedProjectBranch
|
|
267
|
+
? paint(BLOOD, clean(branch))
|
|
268
|
+
: paint(TEXT, clean(project)) + paint(MUTED, "/") + paint(BLOOD, clean(branch))
|
|
243
269
|
: project
|
|
244
270
|
? paint(TEXT, clean(project))
|
|
245
271
|
: branch
|
|
@@ -247,7 +273,6 @@ const projectBranch = project && branch
|
|
|
247
273
|
: undefined;
|
|
248
274
|
|
|
249
275
|
const fields = [
|
|
250
|
-
taskName && paint(EMBER, clean(taskName)),
|
|
251
276
|
role && paint(EMBER, clean(role)),
|
|
252
277
|
projectBranch,
|
|
253
278
|
contextField(),
|
package/dist/store/database.js
CHANGED
|
@@ -65,7 +65,9 @@ export class Database {
|
|
|
65
65
|
fast INTEGER NOT NULL DEFAULT 0,
|
|
66
66
|
sandbox TEXT,
|
|
67
67
|
dangerously_bypass_approvals_and_sandbox INTEGER,
|
|
68
|
-
origin TEXT
|
|
68
|
+
origin TEXT,
|
|
69
|
+
parent_id TEXT,
|
|
70
|
+
role TEXT
|
|
69
71
|
);
|
|
70
72
|
|
|
71
73
|
CREATE TABLE IF NOT EXISTS events (
|
|
@@ -89,9 +91,53 @@ export class Database {
|
|
|
89
91
|
active INTEGER NOT NULL DEFAULT 1
|
|
90
92
|
);
|
|
91
93
|
|
|
94
|
+
CREATE TABLE IF NOT EXISTS usage_sources (
|
|
95
|
+
source_key TEXT PRIMARY KEY,
|
|
96
|
+
cost REAL,
|
|
97
|
+
input_tokens INTEGER,
|
|
98
|
+
output_tokens INTEGER,
|
|
99
|
+
cached_tokens INTEGER,
|
|
100
|
+
updated_at TEXT NOT NULL
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
CREATE TABLE IF NOT EXISTS usage_attributions (
|
|
104
|
+
session_id TEXT NOT NULL,
|
|
105
|
+
source_key TEXT NOT NULL,
|
|
106
|
+
cost REAL,
|
|
107
|
+
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
108
|
+
output_tokens INTEGER NOT NULL DEFAULT 0,
|
|
109
|
+
cached_tokens INTEGER NOT NULL DEFAULT 0,
|
|
110
|
+
PRIMARY KEY (session_id, source_key),
|
|
111
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE,
|
|
112
|
+
FOREIGN KEY (source_key) REFERENCES usage_sources(source_key) ON DELETE CASCADE
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
CREATE TABLE IF NOT EXISTS session_native_links (
|
|
116
|
+
session_id TEXT NOT NULL,
|
|
117
|
+
native_id TEXT NOT NULL,
|
|
118
|
+
linked_at TEXT NOT NULL,
|
|
119
|
+
reconciled_at TEXT,
|
|
120
|
+
state TEXT,
|
|
121
|
+
PRIMARY KEY (session_id, native_id),
|
|
122
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
CREATE TABLE IF NOT EXISTS usage_legacy (
|
|
126
|
+
native_id TEXT PRIMARY KEY,
|
|
127
|
+
ended_at TEXT NOT NULL,
|
|
128
|
+
cwd TEXT,
|
|
129
|
+
repository TEXT,
|
|
130
|
+
model TEXT,
|
|
131
|
+
cost REAL,
|
|
132
|
+
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
133
|
+
output_tokens INTEGER NOT NULL DEFAULT 0,
|
|
134
|
+
cached_tokens INTEGER NOT NULL DEFAULT 0
|
|
135
|
+
);
|
|
136
|
+
|
|
92
137
|
CREATE INDEX IF NOT EXISTS idx_events_session_seq ON events(session_id, sequence);
|
|
93
138
|
CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);
|
|
94
139
|
CREATE INDEX IF NOT EXISTS idx_sessions_created ON sessions(created_at DESC);
|
|
140
|
+
CREATE INDEX IF NOT EXISTS idx_usage_attributions_source_key ON usage_attributions(source_key);
|
|
95
141
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_claims_active_session_path
|
|
96
142
|
ON claims(session_id, path_glob) WHERE active = 1;
|
|
97
143
|
`);
|
|
@@ -115,6 +161,8 @@ export class Database {
|
|
|
115
161
|
["origin", "TEXT"],
|
|
116
162
|
["pending_message", "TEXT"],
|
|
117
163
|
["pending_at", "TEXT"],
|
|
164
|
+
["parent_id", "TEXT"],
|
|
165
|
+
["role", "TEXT"],
|
|
118
166
|
];
|
|
119
167
|
for (const [name, type] of additions) {
|
|
120
168
|
if (!existing.has(name))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/store/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAM1D,MAAM,OAAO,QAAQ;IACX,EAAE,CAAe;IACjB,MAAM,CAAS;IACf,QAAQ,CAAU;IAE1B,YAAY,MAAe,EAAE,OAAyB;QACpD,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,KAAK,CAAC;QAC3C,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,UAAU,EAAE,CAAC;YACb,2BAA2B;YAC3B,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,CAAC,EAAE,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC;gBACH,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;YAC9C,CAAC;YAAC,MAAM,CAAC;gBACP,gCAAgC;YAClC,CAAC;QACH,CAAC;IACH,CAAC;IAEO,OAAO;QACb,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/store/database.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { SessionStore } from "./sessions.js";
|
|
2
|
+
function toNativeLink(row) {
|
|
3
|
+
return {
|
|
4
|
+
sessionId: row.session_id,
|
|
5
|
+
nativeId: row.native_id,
|
|
6
|
+
linkedAt: row.linked_at,
|
|
7
|
+
reconciledAt: row.reconciled_at,
|
|
8
|
+
state: row.state,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export class NativeLinkStore {
|
|
12
|
+
db;
|
|
13
|
+
constructor(db) {
|
|
14
|
+
this.db = db;
|
|
15
|
+
}
|
|
16
|
+
link(sessionId, nativeId) {
|
|
17
|
+
const previous = this.db.prepare(`
|
|
18
|
+
SELECT native_id FROM session_native_links
|
|
19
|
+
WHERE session_id = ? AND native_id <> ? AND reconciled_at IS NULL
|
|
20
|
+
ORDER BY linked_at, native_id
|
|
21
|
+
`).all(sessionId, nativeId).map((row) => row.native_id);
|
|
22
|
+
const result = this.db.prepare(`
|
|
23
|
+
INSERT INTO session_native_links (session_id, native_id, linked_at)
|
|
24
|
+
VALUES (?, ?, ?)
|
|
25
|
+
ON CONFLICT(session_id, native_id) DO NOTHING
|
|
26
|
+
`).run(sessionId, nativeId, new Date().toISOString());
|
|
27
|
+
return { created: Number(result.changes) > 0, previous };
|
|
28
|
+
}
|
|
29
|
+
unreconciled(sessionId) {
|
|
30
|
+
const rows = this.db.prepare(`
|
|
31
|
+
SELECT session_id, native_id, linked_at, reconciled_at, state
|
|
32
|
+
FROM session_native_links
|
|
33
|
+
WHERE session_id = ? AND reconciled_at IS NULL
|
|
34
|
+
ORDER BY linked_at, native_id
|
|
35
|
+
`).all(sessionId);
|
|
36
|
+
return rows.map(toNativeLink);
|
|
37
|
+
}
|
|
38
|
+
linksFor(sessionIds) {
|
|
39
|
+
if (sessionIds.length === 0)
|
|
40
|
+
return [];
|
|
41
|
+
const placeholders = sessionIds.map(() => "?").join(", ");
|
|
42
|
+
const rows = this.db.prepare(`
|
|
43
|
+
SELECT session_id, native_id, linked_at, reconciled_at, state
|
|
44
|
+
FROM session_native_links
|
|
45
|
+
WHERE session_id IN (${placeholders})
|
|
46
|
+
ORDER BY session_id, linked_at, native_id
|
|
47
|
+
`).all(...sessionIds);
|
|
48
|
+
return rows.map(toNativeLink);
|
|
49
|
+
}
|
|
50
|
+
markReconciled(sessionId, nativeId, state) {
|
|
51
|
+
this.db.prepare(`
|
|
52
|
+
UPDATE session_native_links SET reconciled_at = ?, state = ?
|
|
53
|
+
WHERE session_id = ? AND native_id = ?
|
|
54
|
+
`).run(new Date().toISOString(), state, sessionId, nativeId);
|
|
55
|
+
}
|
|
56
|
+
staleOpenRows(isDead) {
|
|
57
|
+
const candidates = this.db.prepare(`
|
|
58
|
+
SELECT DISTINCT sessions.id, sessions.status
|
|
59
|
+
FROM sessions
|
|
60
|
+
INNER JOIN session_native_links
|
|
61
|
+
ON session_native_links.session_id = sessions.id
|
|
62
|
+
WHERE sessions.origin = 'open'
|
|
63
|
+
AND session_native_links.reconciled_at IS NULL
|
|
64
|
+
AND sessions.status IN ('interrupted', 'working')
|
|
65
|
+
ORDER BY sessions.created_at, sessions.id
|
|
66
|
+
`).all();
|
|
67
|
+
const sessions = new SessionStore(this.db);
|
|
68
|
+
const stale = [];
|
|
69
|
+
for (const candidate of candidates) {
|
|
70
|
+
const session = sessions.get(candidate.id);
|
|
71
|
+
if (!session)
|
|
72
|
+
continue;
|
|
73
|
+
if (candidate.status === "interrupted" || (candidate.status === "working" && isDead(session))) {
|
|
74
|
+
stale.push(session);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return stale;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=native-links.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-links.js","sourceRoot":"","sources":["../../src/store/native-links.ts"],"names":[],"mappings":"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"}
|