@straiffi/archon 1.8.13 → 1.8.15
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/assets/{ActivityView-DD1Fom-k.js → ActivityView-DpY9GZez.js} +1 -1
- package/dist/client/assets/{GitHubActionsDialog-aDf_6y6m.js → GitHubActionsDialog-BCr-hjvp.js} +1 -1
- package/dist/client/assets/{RepositoryGraphDialog-B4Ij2xmA.js → RepositoryGraphDialog-_hm-x1Dx.js} +1 -1
- package/dist/client/assets/{VerificationDialog-BBCRKTdr.js → VerificationDialog-CsjDzpE1.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-DW3kiEe6.js → architectureDiagram-3BPJPVTR-Dx7MJofM.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-BVWrspTj.js → blockDiagram-GPEHLZMM-CSSJR8F_.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-CDqXjYR1.js → c4Diagram-AAUBKEIU-C4F9969r.js} +1 -1
- package/dist/client/assets/channel-DVkhJzgx.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-Db4bg8nj.js → chunk-2J33WTMH-23HW6i-y.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-DqziKs5m.js → chunk-3OPIFGDE-C3ZmRDMb.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-wdN7gQNo.js → chunk-5ZQYHXKU-B_-UQvCg.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-Dj3aKc06.js → chunk-727SXJPM-5Dua6u1B.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-CAlE_C_J.js → chunk-AQP2D5EJ-DcpcaFRO.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-KstW8JRv.js → chunk-CSCIHK7Q-CLCpOw52.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-DrY-9bi9.js → chunk-KSCS5N6A-uOZFe2JI.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-C6fw_Dab.js → chunk-L5ZTLDWV-DNnzSNoX.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA-DaZP5hZq.js → chunk-LZXEDZCA-CSA3Xnoh.js} +2 -2
- package/dist/client/assets/{chunk-ND2GUHAM-ChYXM7G3.js → chunk-ND2GUHAM-BQR5rD7w.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-JajrDJgw.js → chunk-NZK2D7GU-DyIwcQYQ.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-C4HoCf_q.js → chunk-O5CBEL6O-DfW60w5V.js} +1 -1
- package/dist/client/assets/{chunk-WU5MYG2G-BdjAiDOI.js → chunk-WU5MYG2G-CzMMPYdi.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-6oZ93s5p.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-DYO_YnkU.js +1 -0
- package/dist/client/assets/{dagre-BM42HDAG-CpXupRCy.js → dagre-BM42HDAG-Ba7Pz-ZI.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-DyopuXBv.js → diagram-2AECGRRQ-BxYfgpZ6.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-C8lS8Vro.js → diagram-5GNKFQAL-Bc4-O-UJ.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-CsyC_xgK.js → diagram-KO2AKTUF-Ds1Lmrzm.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-DWsQdA71.js → diagram-LMA3HP47-VFQabxKS.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-YkNa_Tt6.js → diagram-OG6HWLK6-Baff59Zc.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-VmMz5G_L.js → erDiagram-TEJ5UH35-Da5zHjOK.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-DZAu6IJl.js → flowDiagram-I6XJVG4X-pdGMAuog.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-CHJRz_2M.js → ganttDiagram-6RSMTGT7-DjJGX0nm.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-BfA1qYTR.js → gitGraphDiagram-PVQCEYII-kErlwtcT.js} +1 -1
- package/dist/client/assets/index-CS4TzG41.css +2 -0
- package/dist/client/assets/{index-B4x8ZZ8N.js → index-D5TEfELZ.js} +107 -107
- package/dist/client/assets/{infoDiagram-5YYISTIA-CyqqEYvx.js → infoDiagram-5YYISTIA-Bx78HhDi.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-DnXMvxPm.js → ishikawaDiagram-YF4QCWOH-BP0YQCMl.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-DBumlehf.js → journeyDiagram-JHISSGLW-DUgrCOuD.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-D-QvfQhh.js → kanban-definition-UN3LZRKU-K0Zc5_M8.js} +1 -1
- package/dist/client/assets/{line-BgwSCyaP.js → line-Dtg-krjk.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-qDA1puIK.js → mermaid-parser.core-Dw5BI77W.js} +1 -1
- package/dist/client/assets/{mermaid.core-CFM-fuJi.js → mermaid.core-BE-qlWNj.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-B93RAITk.js → mindmap-definition-RKZ34NQL-1Piz4H9I.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-C9arDpCE.js → pieDiagram-4H26LBE5-zlWdJ7lL.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-Tma_RsUu.js → quadrantDiagram-W4KKPZXB-DRQY8Adp.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-C6GCxpqT.js → requirementDiagram-4Y6WPE33-B8_GJFxl.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-CY8ukFyG.js → sankeyDiagram-5OEKKPKP-BaI0Njo8.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-B6MbhJm7.js → sequenceDiagram-3UESZ5HK-DjqAXbRF.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-Bjy1dBVk.js → stateDiagram-AJRCARHV-Ovr_3LeO.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-9pmeAorV.js +1 -0
- package/dist/client/assets/{timeline-definition-PNZ67QCA-KrbaHcGf.js → timeline-definition-PNZ67QCA-DkczYKeZ.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-DQ-5gbga.js → vennDiagram-CIIHVFJN-BZyo4ESi.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-Cwpu-hvf.js → wardleyDiagram-YWT4CUSO-BEISrECX.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-DoP4HxQE.js → xychartDiagram-2RQKCTM6-CyNzGK7f.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server/db.js +2 -0
- package/dist/server/db.js.map +1 -1
- package/dist/server/index.js +37 -47
- package/dist/server/index.js.map +1 -1
- package/dist/server/lib/agent.js +231 -181
- package/dist/server/lib/agent.js.map +1 -1
- package/dist/server/lib/agentProvider.js +74 -0
- package/dist/server/lib/agentProvider.js.map +1 -0
- package/dist/server/lib/agentRuns.js +21 -9
- package/dist/server/lib/agentRuns.js.map +1 -1
- package/dist/server/lib/automationProgression.js +6 -2
- package/dist/server/lib/automationProgression.js.map +1 -1
- package/dist/server/lib/automationResumeDecision.js +4 -3
- package/dist/server/lib/automationResumeDecision.js.map +1 -1
- package/dist/server/lib/chatOperations.js +30 -1
- package/dist/server/lib/chatOperations.js.map +1 -1
- package/dist/server/lib/claudeAgentProvider.js +48 -0
- package/dist/server/lib/claudeAgentProvider.js.map +1 -0
- package/dist/server/lib/executionEnvironment.js +20 -0
- package/dist/server/lib/executionEnvironment.js.map +1 -0
- package/dist/server/lib/git.js +32 -1
- package/dist/server/lib/git.js.map +1 -1
- package/dist/server/lib/hostExecutionEnvironment.js +77 -0
- package/dist/server/lib/hostExecutionEnvironment.js.map +1 -0
- package/dist/server/lib/lightweightPrompt.js +18 -18
- package/dist/server/lib/lightweightPrompt.js.map +1 -1
- package/dist/server/lib/opencodeAgentProvider.js +139 -0
- package/dist/server/lib/opencodeAgentProvider.js.map +1 -0
- package/dist/server/lib/opencodeExecutionReliability.js +52 -0
- package/dist/server/lib/opencodeExecutionReliability.js.map +1 -0
- package/dist/server/lib/opencodeSessionOperations.js +358 -0
- package/dist/server/lib/opencodeSessionOperations.js.map +1 -0
- package/dist/server/lib/opencodeTaskSessions.js +13 -225
- package/dist/server/lib/opencodeTaskSessions.js.map +1 -1
- package/dist/server/lib/projectAutoConfig.js +23 -19
- package/dist/server/lib/projectAutoConfig.js.map +1 -1
- package/dist/server/lib/reviewFindings.js +15 -0
- package/dist/server/lib/reviewFindings.js.map +1 -1
- package/dist/server/lib/specArtifact.js +19 -0
- package/dist/server/lib/specArtifact.js.map +1 -1
- package/dist/server/lib/specBundleGroups.js +151 -0
- package/dist/server/lib/specBundleGroups.js.map +1 -0
- package/dist/server/lib/specExport.js +1 -0
- package/dist/server/lib/specExport.js.map +1 -1
- package/dist/server/lib/specFormatting.js +13 -0
- package/dist/server/lib/specFormatting.js.map +1 -1
- package/dist/server/lib/specReviewValidation.js +22 -1
- package/dist/server/lib/specReviewValidation.js.map +1 -1
- package/dist/server/lib/specReviews.js +1 -1
- package/dist/server/lib/specSections.js +8 -1
- package/dist/server/lib/specSections.js.map +1 -1
- package/dist/server/lib/specTicketMaterialization.js +119 -0
- package/dist/server/lib/specTicketMaterialization.js.map +1 -0
- package/dist/server/lib/specs.js +27 -5
- package/dist/server/lib/specs.js.map +1 -1
- package/dist/server/lib/types.js.map +1 -1
- package/dist/server/workers/followUp.js +35 -10
- package/dist/server/workers/followUp.js.map +1 -1
- package/dist/server/workers/plan.js +28 -23
- package/dist/server/workers/plan.js.map +1 -1
- package/dist/server/workers/review.js +62 -24
- package/dist/server/workers/review.js.map +1 -1
- package/dist/server/workers/specReview.js +7 -1
- package/dist/server/workers/specReview.js.map +1 -1
- package/dist/server/workers/specSession.js +68 -36
- package/dist/server/workers/specSession.js.map +1 -1
- package/package.json +1 -1
- package/dist/client/assets/channel-C14KP1Bm.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-CR20Gg9e.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-B-N-i15d.js +0 -1
- package/dist/client/assets/index-CCQwWUKF.css +0 -2
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-asf2fsPC.js +0 -1
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import { resolveOpencodeDbPath } from './runtimePaths.js';
|
|
3
|
+
export const EMPTY_OPENCODE_USAGE_SNAPSHOT = {
|
|
4
|
+
usage_snapshot_context_window: null,
|
|
5
|
+
usage_snapshot_max_output_tokens: null,
|
|
6
|
+
usage_snapshot_total_tokens: null,
|
|
7
|
+
usage_snapshot_input_tokens: null,
|
|
8
|
+
usage_snapshot_output_tokens: null,
|
|
9
|
+
usage_snapshot_cache_read_tokens: null,
|
|
10
|
+
usage_snapshot_reasoning_tokens: null,
|
|
11
|
+
usage_snapshot_cost: null,
|
|
12
|
+
};
|
|
13
|
+
const PLACEHOLDER_TITLE_PATTERN = /^New session\b/i;
|
|
14
|
+
const TASK_TOOL_NAMES = new Set(['task', 'subagent', 'agent']);
|
|
15
|
+
const getColumns = (database, table) => new Set(database.prepare(`PRAGMA table_info(${table})`).all()
|
|
16
|
+
.map(row => row.name)
|
|
17
|
+
.filter((name) => Boolean(name)));
|
|
18
|
+
const hasColumns = (columns, required) => required.every(column => columns.has(column));
|
|
19
|
+
const getString = (value) => typeof value === 'string' && value.trim() ? value.trim() : null;
|
|
20
|
+
const parseJsonObject = (value) => {
|
|
21
|
+
if (!value) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const parsed = JSON.parse(value);
|
|
26
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
27
|
+
? parsed
|
|
28
|
+
: null;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const getNestedString = (value, paths) => {
|
|
35
|
+
for (const path of paths) {
|
|
36
|
+
let current = value;
|
|
37
|
+
for (const segment of path) {
|
|
38
|
+
if (!current || typeof current !== 'object' || !(segment in current)) {
|
|
39
|
+
current = null;
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
current = current[segment];
|
|
43
|
+
}
|
|
44
|
+
const resolved = getString(current);
|
|
45
|
+
if (resolved) {
|
|
46
|
+
return resolved;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
};
|
|
51
|
+
const toFiniteNumber = (value) => typeof value === 'number' && Number.isFinite(value) ? value : null;
|
|
52
|
+
const getValueAtPath = (value, path) => {
|
|
53
|
+
let current = value;
|
|
54
|
+
for (const segment of path) {
|
|
55
|
+
if (!current || typeof current !== 'object' || !(segment in current)) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
current = current[segment];
|
|
59
|
+
}
|
|
60
|
+
return current;
|
|
61
|
+
};
|
|
62
|
+
const getNumberAtPaths = (value, paths) => {
|
|
63
|
+
for (const path of paths) {
|
|
64
|
+
const candidate = toFiniteNumber(getValueAtPath(value, path));
|
|
65
|
+
if (candidate !== null) {
|
|
66
|
+
return candidate;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
};
|
|
71
|
+
export const extractOpencodeUsageSnapshot = (value) => {
|
|
72
|
+
if (!value || typeof value !== 'object') {
|
|
73
|
+
return {};
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
usage_snapshot_context_window: getNumberAtPaths(value, [
|
|
77
|
+
['contextWindow'], ['context_window'], ['result', 'contextWindow'], ['result', 'context_window'],
|
|
78
|
+
['limit', 'context'], ['limits', 'context'],
|
|
79
|
+
]),
|
|
80
|
+
usage_snapshot_max_output_tokens: getNumberAtPaths(value, [
|
|
81
|
+
['maxOutputTokens'], ['max_output_tokens'], ['result', 'maxOutputTokens'], ['result', 'max_output_tokens'],
|
|
82
|
+
['limit', 'output'], ['limits', 'output'],
|
|
83
|
+
]),
|
|
84
|
+
usage_snapshot_total_tokens: getNumberAtPaths(value, [
|
|
85
|
+
['tokens', 'total'], ['usage', 'tokens', 'total'], ['usage', 'total'], ['usage', 'totalTokens'],
|
|
86
|
+
['result', 'tokens', 'total'], ['result', 'usage', 'tokens', 'total'], ['result', 'usage', 'total'],
|
|
87
|
+
['result', 'usage', 'totalTokens'],
|
|
88
|
+
]),
|
|
89
|
+
usage_snapshot_input_tokens: getNumberAtPaths(value, [
|
|
90
|
+
['message', 'usage', 'input_tokens'], ['usage', 'input_tokens'], ['tokens', 'input'],
|
|
91
|
+
['usage', 'tokens', 'input'], ['usage', 'input'], ['usage', 'inputTokens'], ['result', 'tokens', 'input'],
|
|
92
|
+
['result', 'usage', 'tokens', 'input'], ['result', 'usage', 'input'], ['result', 'usage', 'inputTokens'],
|
|
93
|
+
]),
|
|
94
|
+
usage_snapshot_output_tokens: getNumberAtPaths(value, [
|
|
95
|
+
['message', 'usage', 'output_tokens'], ['usage', 'output_tokens'], ['tokens', 'output'],
|
|
96
|
+
['usage', 'tokens', 'output'], ['usage', 'output'], ['usage', 'outputTokens'], ['result', 'tokens', 'output'],
|
|
97
|
+
['result', 'usage', 'tokens', 'output'], ['result', 'usage', 'output'], ['result', 'usage', 'outputTokens'],
|
|
98
|
+
]),
|
|
99
|
+
usage_snapshot_cache_read_tokens: getNumberAtPaths(value, [
|
|
100
|
+
['message', 'usage', 'cache_read_input_tokens'], ['usage', 'cache_read_input_tokens'],
|
|
101
|
+
['tokens', 'cache', 'read'], ['usage', 'tokens', 'cacheRead'], ['usage', 'cacheRead'],
|
|
102
|
+
['usage', 'cacheReadTokens'], ['result', 'tokens', 'cache', 'read'],
|
|
103
|
+
['result', 'usage', 'tokens', 'cacheRead'], ['result', 'usage', 'cacheRead'],
|
|
104
|
+
['result', 'usage', 'cacheReadTokens'],
|
|
105
|
+
]),
|
|
106
|
+
usage_snapshot_reasoning_tokens: getNumberAtPaths(value, [
|
|
107
|
+
['tokens', 'reasoning'], ['usage', 'tokens', 'reasoning'], ['usage', 'reasoning'],
|
|
108
|
+
['usage', 'reasoningTokens'], ['result', 'tokens', 'reasoning'],
|
|
109
|
+
['result', 'usage', 'tokens', 'reasoning'], ['result', 'usage', 'reasoning'],
|
|
110
|
+
['result', 'usage', 'reasoningTokens'],
|
|
111
|
+
]),
|
|
112
|
+
usage_snapshot_cost: getNumberAtPaths(value, [['total_cost_usd'], ['cost'], ['result', 'cost']]),
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
const mergeUsage = (current, next) => ({
|
|
116
|
+
usage_snapshot_context_window: next.usage_snapshot_context_window ?? current.usage_snapshot_context_window,
|
|
117
|
+
usage_snapshot_max_output_tokens: next.usage_snapshot_max_output_tokens ?? current.usage_snapshot_max_output_tokens,
|
|
118
|
+
usage_snapshot_total_tokens: next.usage_snapshot_total_tokens ?? current.usage_snapshot_total_tokens,
|
|
119
|
+
usage_snapshot_input_tokens: next.usage_snapshot_input_tokens ?? current.usage_snapshot_input_tokens,
|
|
120
|
+
usage_snapshot_output_tokens: next.usage_snapshot_output_tokens ?? current.usage_snapshot_output_tokens,
|
|
121
|
+
usage_snapshot_cache_read_tokens: next.usage_snapshot_cache_read_tokens ?? current.usage_snapshot_cache_read_tokens,
|
|
122
|
+
usage_snapshot_reasoning_tokens: next.usage_snapshot_reasoning_tokens ?? current.usage_snapshot_reasoning_tokens,
|
|
123
|
+
usage_snapshot_cost: next.usage_snapshot_cost ?? current.usage_snapshot_cost,
|
|
124
|
+
});
|
|
125
|
+
const hasUsage = (value) => Object.values(value).some(candidate => candidate !== null && candidate !== undefined);
|
|
126
|
+
const normalizeSession = (row) => {
|
|
127
|
+
const id = getString(row?.id);
|
|
128
|
+
if (!id) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
const normalizedTitle = getString(row?.title);
|
|
132
|
+
return {
|
|
133
|
+
id,
|
|
134
|
+
title: normalizedTitle && !PLACEHOLDER_TITLE_PATTERN.test(normalizedTitle) ? normalizedTitle : null,
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
const normalizeToolName = (value) => typeof value === 'string'
|
|
138
|
+
? value.toLowerCase().replace(/[^a-z0-9]/g, '')
|
|
139
|
+
: '';
|
|
140
|
+
const getTaskLabel = (part) => {
|
|
141
|
+
const description = getNestedString(part, [
|
|
142
|
+
['state', 'input', 'description'], ['state', 'input', 'title'], ['state', 'input', 'task'],
|
|
143
|
+
['state', 'input', 'subagent_type'], ['state', 'input', 'prompt'],
|
|
144
|
+
]) ?? 'Subagent';
|
|
145
|
+
const firstLine = description.split('\n')[0] ?? description;
|
|
146
|
+
const clipped = firstLine.length > 120 ? `${firstLine.slice(0, 117)}...` : firstLine;
|
|
147
|
+
return clipped.startsWith('Subagent:') ? clipped : `Subagent: ${clipped}`;
|
|
148
|
+
};
|
|
149
|
+
const mapTaskStatus = (value) => {
|
|
150
|
+
const normalized = value?.toLowerCase();
|
|
151
|
+
if (normalized === 'error' || normalized === 'failed') {
|
|
152
|
+
return 'error';
|
|
153
|
+
}
|
|
154
|
+
if (normalized === 'completed' || normalized === 'complete' || normalized === 'done') {
|
|
155
|
+
return 'done';
|
|
156
|
+
}
|
|
157
|
+
return 'running';
|
|
158
|
+
};
|
|
159
|
+
export const parseOpencodeTaskEnvelope = (value) => {
|
|
160
|
+
if (!value) {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
const taskStart = value.match(/<task\b([^>]*)>/i);
|
|
164
|
+
if (!taskStart) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
const attributes = taskStart[1] ?? '';
|
|
168
|
+
const childSessionId = attributes.match(/\bid=["']([^"']+)["']/i)?.[1]?.trim() || null;
|
|
169
|
+
const state = attributes.match(/\bstate=["']([^"']+)["']/i)?.[1]?.trim() || null;
|
|
170
|
+
const taskContent = value.slice((taskStart.index ?? 0) + taskStart[0].length);
|
|
171
|
+
const resultStart = taskContent.match(/<task_result>/i);
|
|
172
|
+
if (!resultStart) {
|
|
173
|
+
return { childSessionId, state, result: null };
|
|
174
|
+
}
|
|
175
|
+
const resultContent = taskContent.slice((resultStart.index ?? 0) + resultStart[0].length);
|
|
176
|
+
const resultEndIndex = resultContent.search(/<\/task_result>|<\/task>/i);
|
|
177
|
+
const result = (resultEndIndex >= 0 ? resultContent.slice(0, resultEndIndex) : resultContent).trim() || null;
|
|
178
|
+
return { childSessionId, state, result };
|
|
179
|
+
};
|
|
180
|
+
export const createHostOpencodeSessionOperations = (options = {}) => {
|
|
181
|
+
const openDatabase = options.openDatabase ?? (() => new Database(resolveOpencodeDbPath(), { readonly: true }));
|
|
182
|
+
const closeDatabase = options.closeDatabase ?? true;
|
|
183
|
+
const columnsByTable = new Map();
|
|
184
|
+
const getCachedColumns = (database, table) => {
|
|
185
|
+
const cached = columnsByTable.get(table);
|
|
186
|
+
if (cached) {
|
|
187
|
+
return cached;
|
|
188
|
+
}
|
|
189
|
+
const columns = getColumns(database, table);
|
|
190
|
+
columnsByTable.set(table, columns);
|
|
191
|
+
return columns;
|
|
192
|
+
};
|
|
193
|
+
const withDatabase = (fallback, read) => {
|
|
194
|
+
let database = null;
|
|
195
|
+
try {
|
|
196
|
+
database = openDatabase();
|
|
197
|
+
return read(database);
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
return fallback;
|
|
201
|
+
}
|
|
202
|
+
finally {
|
|
203
|
+
if (closeDatabase) {
|
|
204
|
+
database?.close();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
const readFromDatabase = (read) => {
|
|
209
|
+
let database = null;
|
|
210
|
+
try {
|
|
211
|
+
database = openDatabase();
|
|
212
|
+
return read(database);
|
|
213
|
+
}
|
|
214
|
+
finally {
|
|
215
|
+
if (closeDatabase) {
|
|
216
|
+
database?.close();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
const findSession = (query, value) => withDatabase(null, database => {
|
|
221
|
+
const columns = getCachedColumns(database, 'session');
|
|
222
|
+
if (!hasColumns(columns, ['id']) || (typeof value === 'number' && !columns.has('time_created'))) {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
const title = columns.has('title') ? 'title' : 'NULL AS title';
|
|
226
|
+
return normalizeSession(database.prepare(query.replace('{title}', title)).get(value));
|
|
227
|
+
});
|
|
228
|
+
return {
|
|
229
|
+
supportsTaskSessions: () => withDatabase(false, database => {
|
|
230
|
+
const columns = getCachedColumns(database, 'part');
|
|
231
|
+
return hasColumns(columns, ['id', 'session_id', 'time_created', 'data']);
|
|
232
|
+
}),
|
|
233
|
+
findSessionById: sessionId => findSession('SELECT id, {title} FROM session WHERE id = ? LIMIT 1', sessionId),
|
|
234
|
+
// Compatibility limitation: concurrent runs can still make this select another run's newest session.
|
|
235
|
+
findLatestSessionAfter: createdAfter => findSession('SELECT id, {title} FROM session WHERE time_created > ? ORDER BY time_created DESC LIMIT 1', createdAfter),
|
|
236
|
+
findParentSessionSince: createdSince => withDatabase(null, database => {
|
|
237
|
+
const columns = getCachedColumns(database, 'session');
|
|
238
|
+
if (!hasColumns(columns, ['id', 'time_created'])) {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
const title = columns.has('title') ? 'title' : 'NULL AS title';
|
|
242
|
+
const parentFilter = columns.has('parent_id') ? 'AND parent_id IS NULL' : '';
|
|
243
|
+
const row = database.prepare(`SELECT id, ${title}, time_created FROM session WHERE time_created >= ? ${parentFilter} ORDER BY time_created ASC LIMIT 1`).get(createdSince);
|
|
244
|
+
return getString(row?.id);
|
|
245
|
+
}),
|
|
246
|
+
hasCompletedAssistantSince: (sessionId, createdSince) => withDatabase(false, database => {
|
|
247
|
+
const columns = getCachedColumns(database, 'message');
|
|
248
|
+
if (!hasColumns(columns, ['session_id', 'time_created', 'data'])) {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
const row = database.prepare("SELECT 1 FROM message WHERE session_id = ? AND time_created >= ? AND json_extract(data, '$.role') = 'assistant' AND json_extract(data, '$.time.completed') IS NOT NULL ORDER BY time_created DESC LIMIT 1").get(sessionId, createdSince);
|
|
252
|
+
return Boolean(row);
|
|
253
|
+
}),
|
|
254
|
+
readUsageSnapshot: (sessionId, createdSince = null) => readFromDatabase(database => {
|
|
255
|
+
const sessionColumns = getCachedColumns(database, 'session');
|
|
256
|
+
const messageColumns = getCachedColumns(database, 'message');
|
|
257
|
+
const partColumns = getCachedColumns(database, 'part');
|
|
258
|
+
const costRow = hasColumns(sessionColumns, ['id', 'cost'])
|
|
259
|
+
? database.prepare('SELECT cost FROM session WHERE id = ?').get(sessionId)
|
|
260
|
+
: undefined;
|
|
261
|
+
const cost = typeof costRow?.cost === 'number' ? { usage_snapshot_cost: costRow.cost } : {};
|
|
262
|
+
let parsedUsage = {};
|
|
263
|
+
if (hasColumns(messageColumns, ['session_id', 'time_created', 'data'])) {
|
|
264
|
+
const query = createdSince === null
|
|
265
|
+
? "SELECT data FROM message WHERE session_id = ? AND json_extract(data, '$.role') = 'assistant' AND json_extract(data, '$.time.completed') IS NOT NULL ORDER BY time_created DESC LIMIT 1"
|
|
266
|
+
: "SELECT data FROM message WHERE session_id = ? AND time_created >= ? AND json_extract(data, '$.role') = 'assistant' AND json_extract(data, '$.time.completed') IS NOT NULL ORDER BY time_created DESC LIMIT 1";
|
|
267
|
+
const row = (createdSince === null
|
|
268
|
+
? database.prepare(query).get(sessionId)
|
|
269
|
+
: database.prepare(query).get(sessionId, createdSince));
|
|
270
|
+
const data = parseJsonObject(row?.data);
|
|
271
|
+
parsedUsage = extractOpencodeUsageSnapshot(data);
|
|
272
|
+
}
|
|
273
|
+
if (!hasUsage(parsedUsage) && hasColumns(partColumns, ['session_id', 'time_created', 'data'])) {
|
|
274
|
+
const query = createdSince === null
|
|
275
|
+
? "SELECT data FROM part WHERE session_id = ? AND json_extract(data, '$.type') = 'step-finish' ORDER BY time_created DESC LIMIT 1"
|
|
276
|
+
: "SELECT data FROM part WHERE session_id = ? AND time_created >= ? AND json_extract(data, '$.type') = 'step-finish' ORDER BY time_created DESC LIMIT 1";
|
|
277
|
+
const row = (createdSince === null
|
|
278
|
+
? database.prepare(query).get(sessionId)
|
|
279
|
+
: database.prepare(query).get(sessionId, createdSince));
|
|
280
|
+
parsedUsage = extractOpencodeUsageSnapshot(parseJsonObject(row?.data));
|
|
281
|
+
}
|
|
282
|
+
return mergeUsage(mergeUsage(EMPTY_OPENCODE_USAGE_SNAPSHOT, parsedUsage), cost);
|
|
283
|
+
}),
|
|
284
|
+
listTaskInvocations: (parentSessionId, createdSince) => withDatabase([], database => {
|
|
285
|
+
const columns = getCachedColumns(database, 'part');
|
|
286
|
+
if (!hasColumns(columns, ['id', 'session_id', 'time_created', 'data'])) {
|
|
287
|
+
return [];
|
|
288
|
+
}
|
|
289
|
+
const rows = database.prepare('SELECT id, data, time_created FROM part WHERE session_id = ? AND time_created >= ? ORDER BY time_created ASC, id ASC').all(parentSessionId, createdSince);
|
|
290
|
+
return rows.flatMap(row => {
|
|
291
|
+
const part = parseJsonObject(row.data);
|
|
292
|
+
if (!part || part.type !== 'tool' || !TASK_TOOL_NAMES.has(normalizeToolName(part.tool))) {
|
|
293
|
+
return [];
|
|
294
|
+
}
|
|
295
|
+
const callId = getNestedString(part, [['callID'], ['callId'], ['id']]);
|
|
296
|
+
if (!callId) {
|
|
297
|
+
return [];
|
|
298
|
+
}
|
|
299
|
+
const rawOutput = getNestedString(part, [['state', 'output']]);
|
|
300
|
+
const envelope = parseOpencodeTaskEnvelope(rawOutput);
|
|
301
|
+
const childSessionId = getNestedString(part, [
|
|
302
|
+
['state', 'metadata', 'sessionID'], ['state', 'metadata', 'sessionId'],
|
|
303
|
+
['state', 'metadata', 'session_id'],
|
|
304
|
+
]) ?? envelope?.childSessionId ?? null;
|
|
305
|
+
const rawStatus = getNestedString(part, [['state', 'status']]) ?? envelope?.state ?? null;
|
|
306
|
+
return [{
|
|
307
|
+
callId,
|
|
308
|
+
label: getTaskLabel(part),
|
|
309
|
+
status: mapTaskStatus(rawStatus),
|
|
310
|
+
output: envelope ? envelope.result : rawOutput,
|
|
311
|
+
childSessionId,
|
|
312
|
+
timeCreated: Number(row.time_created ?? 0),
|
|
313
|
+
}];
|
|
314
|
+
});
|
|
315
|
+
}),
|
|
316
|
+
listChildSessions: (parentSessionId, createdSince) => withDatabase([], database => {
|
|
317
|
+
const columns = getCachedColumns(database, 'session');
|
|
318
|
+
if (!hasColumns(columns, ['id', 'parent_id', 'time_created'])) {
|
|
319
|
+
return [];
|
|
320
|
+
}
|
|
321
|
+
const title = columns.has('title') ? 'title' : 'NULL AS title';
|
|
322
|
+
const rows = database.prepare(`SELECT id, ${title}, time_created FROM session WHERE parent_id = ? AND time_created >= ? ORDER BY time_created ASC, id ASC`).all(parentSessionId, createdSince);
|
|
323
|
+
return rows.flatMap(row => {
|
|
324
|
+
const id = getString(row.id);
|
|
325
|
+
return id ? [{ id, title: getString(row.title), timeCreated: Number(row.time_created ?? 0) }] : [];
|
|
326
|
+
});
|
|
327
|
+
}),
|
|
328
|
+
listSessionParts: (sessionId, createdSince) => withDatabase([], database => {
|
|
329
|
+
const messageColumns = getCachedColumns(database, 'message');
|
|
330
|
+
const partColumns = getCachedColumns(database, 'part');
|
|
331
|
+
if (!hasColumns(messageColumns, ['id', 'session_id', 'data'])
|
|
332
|
+
|| !hasColumns(partColumns, ['id', 'session_id', 'message_id', 'time_created', 'data'])) {
|
|
333
|
+
return [];
|
|
334
|
+
}
|
|
335
|
+
const query = createdSince === undefined
|
|
336
|
+
? 'SELECT p.id, p.data, p.time_created, m.data AS message_data FROM part p INNER JOIN message m ON m.id = p.message_id WHERE p.session_id = ? ORDER BY p.time_created ASC, p.id ASC'
|
|
337
|
+
: 'SELECT p.id, p.data, p.time_created, m.data AS message_data FROM part p INNER JOIN message m ON m.id = p.message_id WHERE p.session_id = ? AND p.time_created >= ? ORDER BY p.time_created ASC, p.id ASC';
|
|
338
|
+
const rows = (createdSince === undefined
|
|
339
|
+
? database.prepare(query).all(sessionId)
|
|
340
|
+
: database.prepare(query).all(sessionId, createdSince));
|
|
341
|
+
return rows.flatMap(row => {
|
|
342
|
+
const part = parseJsonObject(row.data);
|
|
343
|
+
if (!part) {
|
|
344
|
+
return [];
|
|
345
|
+
}
|
|
346
|
+
const message = parseJsonObject(row.message_data);
|
|
347
|
+
return [{
|
|
348
|
+
id: getString(row.id) ?? `${row.time_created ?? 0}`,
|
|
349
|
+
role: getString(message?.role),
|
|
350
|
+
timeCreated: Number(row.time_created ?? 0),
|
|
351
|
+
data: part,
|
|
352
|
+
}];
|
|
353
|
+
});
|
|
354
|
+
}),
|
|
355
|
+
};
|
|
356
|
+
};
|
|
357
|
+
export const hostOpencodeSessionOperations = createHostOpencodeSessionOperations();
|
|
358
|
+
//# sourceMappingURL=opencodeSessionOperations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencodeSessionOperations.js","sourceRoot":"","sources":["../../../server/lib/opencodeSessionOperations.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,227 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
try {
|
|
15
|
-
const parsed = JSON.parse(value);
|
|
16
|
-
return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
17
|
-
? parsed
|
|
18
|
-
: null;
|
|
19
|
-
}
|
|
20
|
-
catch {
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
const getString = (value) => {
|
|
25
|
-
return typeof value === 'string' && value.trim() ? value.trim() : null;
|
|
26
|
-
};
|
|
27
|
-
const getNestedString = (value, paths) => {
|
|
28
|
-
for (const path of paths) {
|
|
29
|
-
let current = value;
|
|
30
|
-
for (const segment of path) {
|
|
31
|
-
if (!current || typeof current !== 'object' || !(segment in current)) {
|
|
32
|
-
current = null;
|
|
33
|
-
break;
|
|
34
|
-
}
|
|
35
|
-
current = current[segment];
|
|
36
|
-
}
|
|
37
|
-
const resolved = getString(current);
|
|
38
|
-
if (resolved) {
|
|
39
|
-
return resolved;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return null;
|
|
43
|
-
};
|
|
44
|
-
const getTaskLabel = (part) => {
|
|
45
|
-
const description = getNestedString(part, [
|
|
46
|
-
['state', 'input', 'description'],
|
|
47
|
-
['state', 'input', 'title'],
|
|
48
|
-
['state', 'input', 'task'],
|
|
49
|
-
['state', 'input', 'subagent_type'],
|
|
50
|
-
['state', 'input', 'prompt'],
|
|
51
|
-
]) ?? 'Subagent';
|
|
52
|
-
const firstLine = description.split('\n')[0] ?? description;
|
|
53
|
-
const clipped = firstLine.length > 120 ? `${firstLine.slice(0, 117)}...` : firstLine;
|
|
54
|
-
return clipped.startsWith('Subagent:') ? clipped : `Subagent: ${clipped}`;
|
|
55
|
-
};
|
|
56
|
-
export const parseOpencodeTaskEnvelope = (value) => {
|
|
57
|
-
if (!value) {
|
|
58
|
-
return null;
|
|
59
|
-
}
|
|
60
|
-
const taskStart = value.match(/<task\b([^>]*)>/i);
|
|
61
|
-
if (!taskStart) {
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
const attributes = taskStart[1] ?? '';
|
|
65
|
-
const childSessionId = attributes.match(/\bid=["']([^"']+)["']/i)?.[1]?.trim() || null;
|
|
66
|
-
const state = attributes.match(/\bstate=["']([^"']+)["']/i)?.[1]?.trim() || null;
|
|
67
|
-
const taskContent = value.slice((taskStart.index ?? 0) + taskStart[0].length);
|
|
68
|
-
const resultStart = taskContent.match(/<task_result>/i);
|
|
69
|
-
if (!resultStart) {
|
|
70
|
-
return { childSessionId, state, result: null };
|
|
71
|
-
}
|
|
72
|
-
const resultContent = taskContent.slice((resultStart.index ?? 0) + resultStart[0].length);
|
|
73
|
-
const resultEndIndex = resultContent.search(/<\/task_result>|<\/task>/i);
|
|
74
|
-
const result = (resultEndIndex >= 0 ? resultContent.slice(0, resultEndIndex) : resultContent).trim() || null;
|
|
75
|
-
return { childSessionId, state, result };
|
|
76
|
-
};
|
|
77
|
-
const mapTaskStatus = (value) => {
|
|
78
|
-
const normalized = value?.toLowerCase();
|
|
79
|
-
if (normalized === 'error' || normalized === 'failed') {
|
|
80
|
-
return 'error';
|
|
81
|
-
}
|
|
82
|
-
if (normalized === 'completed' || normalized === 'complete' || normalized === 'done') {
|
|
83
|
-
return 'done';
|
|
84
|
-
}
|
|
85
|
-
return 'running';
|
|
86
|
-
};
|
|
87
|
-
const getColumns = (database, table) => {
|
|
88
|
-
return new Set(database.prepare(`PRAGMA table_info(${table})`).all()
|
|
89
|
-
.map(row => row.name)
|
|
90
|
-
.filter((name) => Boolean(name)));
|
|
91
|
-
};
|
|
92
|
-
export const createOpencodeTaskSessionReader = () => {
|
|
93
|
-
let database = null;
|
|
94
|
-
try {
|
|
95
|
-
database = new Database(resolveOpencodeDbPath(), { readonly: true });
|
|
96
|
-
const sessionColumns = getColumns(database, 'session');
|
|
97
|
-
const messageColumns = getColumns(database, 'message');
|
|
98
|
-
const partColumns = getColumns(database, 'part');
|
|
99
|
-
const canReadTasks = ['id', 'session_id', 'time_created', 'data'].every(column => partColumns.has(column));
|
|
100
|
-
const canFindChildren = ['id', 'parent_id', 'time_created'].every(column => sessionColumns.has(column));
|
|
101
|
-
const canReadTranscript = canReadTasks
|
|
102
|
-
&& ['id', 'session_id', 'data'].every(column => messageColumns.has(column))
|
|
103
|
-
&& partColumns.has('message_id');
|
|
104
|
-
if (!canReadTasks) {
|
|
105
|
-
database.close();
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
const listTaskInvocations = (parentSessionId, since) => {
|
|
109
|
-
if (!database) {
|
|
110
|
-
return [];
|
|
111
|
-
}
|
|
112
|
-
const rows = database.prepare(`
|
|
113
|
-
SELECT id, data, time_created
|
|
114
|
-
FROM part
|
|
115
|
-
WHERE session_id = ? AND time_created >= ?
|
|
116
|
-
ORDER BY time_created ASC, id ASC
|
|
117
|
-
`).all(parentSessionId, since);
|
|
118
|
-
return rows.flatMap(row => {
|
|
119
|
-
const part = parseJsonObject(row.data);
|
|
120
|
-
if (!part || part.type !== 'tool' || !isTaskTool(part.tool)) {
|
|
121
|
-
return [];
|
|
122
|
-
}
|
|
123
|
-
const callId = getNestedString(part, [['callID'], ['callId'], ['id']]);
|
|
124
|
-
if (!callId) {
|
|
125
|
-
return [];
|
|
126
|
-
}
|
|
127
|
-
const rawOutput = getNestedString(part, [['state', 'output']]);
|
|
128
|
-
const envelope = parseOpencodeTaskEnvelope(rawOutput);
|
|
129
|
-
const childSessionId = getNestedString(part, [
|
|
130
|
-
['state', 'metadata', 'sessionID'],
|
|
131
|
-
['state', 'metadata', 'sessionId'],
|
|
132
|
-
['state', 'metadata', 'session_id'],
|
|
133
|
-
]) ?? envelope?.childSessionId ?? null;
|
|
134
|
-
const rawStatus = getNestedString(part, [['state', 'status']]) ?? envelope?.state ?? null;
|
|
135
|
-
return [{
|
|
136
|
-
callId,
|
|
137
|
-
label: getTaskLabel(part),
|
|
138
|
-
status: mapTaskStatus(rawStatus),
|
|
139
|
-
output: envelope ? envelope.result : rawOutput,
|
|
140
|
-
childSessionId,
|
|
141
|
-
timeCreated: Number(row.time_created ?? 0),
|
|
142
|
-
}];
|
|
143
|
-
});
|
|
144
|
-
};
|
|
145
|
-
const findParentSessionSince = (since) => {
|
|
146
|
-
if (!database) {
|
|
147
|
-
return null;
|
|
148
|
-
}
|
|
149
|
-
const parentFilter = canFindChildren ? 'AND parent_id IS NULL' : '';
|
|
150
|
-
const row = database.prepare(`
|
|
151
|
-
SELECT id, title, time_created
|
|
152
|
-
FROM session
|
|
153
|
-
WHERE time_created >= ? ${parentFilter}
|
|
154
|
-
ORDER BY time_created ASC
|
|
155
|
-
LIMIT 1
|
|
156
|
-
`).get(since);
|
|
157
|
-
return getString(row?.id);
|
|
158
|
-
};
|
|
159
|
-
const listChildSessions = (parentSessionId, since) => {
|
|
160
|
-
if (!database || !canFindChildren) {
|
|
161
|
-
return [];
|
|
162
|
-
}
|
|
163
|
-
const titleColumn = sessionColumns.has('title') ? 'title' : 'NULL AS title';
|
|
164
|
-
const rows = database.prepare(`
|
|
165
|
-
SELECT id, ${titleColumn}, time_created
|
|
166
|
-
FROM session
|
|
167
|
-
WHERE parent_id = ? AND time_created >= ?
|
|
168
|
-
ORDER BY time_created ASC, id ASC
|
|
169
|
-
`).all(parentSessionId, since);
|
|
170
|
-
return rows.flatMap(row => {
|
|
171
|
-
const id = getString(row.id);
|
|
172
|
-
return id ? [{ id, title: getString(row.title), timeCreated: Number(row.time_created ?? 0) }] : [];
|
|
173
|
-
});
|
|
174
|
-
};
|
|
175
|
-
const listSessionParts = (sessionId, since) => {
|
|
176
|
-
if (!database || !canReadTranscript) {
|
|
177
|
-
return [];
|
|
178
|
-
}
|
|
179
|
-
const query = since === undefined
|
|
180
|
-
? `
|
|
181
|
-
SELECT p.id, p.data, p.time_created, m.data AS message_data
|
|
182
|
-
FROM part p
|
|
183
|
-
INNER JOIN message m ON m.id = p.message_id
|
|
184
|
-
WHERE p.session_id = ?
|
|
185
|
-
ORDER BY p.time_created ASC, p.id ASC
|
|
186
|
-
`
|
|
187
|
-
: `
|
|
188
|
-
SELECT p.id, p.data, p.time_created, m.data AS message_data
|
|
189
|
-
FROM part p
|
|
190
|
-
INNER JOIN message m ON m.id = p.message_id
|
|
191
|
-
WHERE p.session_id = ? AND p.time_created >= ?
|
|
192
|
-
ORDER BY p.time_created ASC, p.id ASC
|
|
193
|
-
`;
|
|
194
|
-
const rows = (since === undefined
|
|
195
|
-
? database.prepare(query).all(sessionId)
|
|
196
|
-
: database.prepare(query).all(sessionId, since));
|
|
197
|
-
return rows.flatMap(row => {
|
|
198
|
-
const part = parseJsonObject(row.data);
|
|
199
|
-
const message = parseJsonObject(row.message_data);
|
|
200
|
-
if (!part) {
|
|
201
|
-
return [];
|
|
202
|
-
}
|
|
203
|
-
return [{
|
|
204
|
-
id: getString(row.id) ?? `${row.time_created ?? 0}`,
|
|
205
|
-
role: getString(message?.role),
|
|
206
|
-
timeCreated: Number(row.time_created ?? 0),
|
|
207
|
-
data: part,
|
|
208
|
-
}];
|
|
209
|
-
});
|
|
210
|
-
};
|
|
211
|
-
return {
|
|
212
|
-
findParentSessionSince,
|
|
213
|
-
listTaskInvocations,
|
|
214
|
-
listChildSessions,
|
|
215
|
-
listSessionParts,
|
|
216
|
-
close: () => {
|
|
217
|
-
database?.close();
|
|
218
|
-
database = null;
|
|
219
|
-
},
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
catch {
|
|
223
|
-
database?.close();
|
|
224
|
-
return null;
|
|
225
|
-
}
|
|
1
|
+
import { hostOpencodeSessionOperations } from './opencodeSessionOperations.js';
|
|
2
|
+
export { parseOpencodeTaskEnvelope } from './opencodeSessionOperations.js';
|
|
3
|
+
export const createOpencodeTaskSessionReader = (operations = hostOpencodeSessionOperations) => {
|
|
4
|
+
if (!operations.supportsTaskSessions()) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
return {
|
|
8
|
+
findParentSessionSince: operations.findParentSessionSince,
|
|
9
|
+
listTaskInvocations: operations.listTaskInvocations,
|
|
10
|
+
listChildSessions: operations.listChildSessions,
|
|
11
|
+
listSessionParts: operations.listSessionParts,
|
|
12
|
+
close: () => { },
|
|
13
|
+
};
|
|
226
14
|
};
|
|
227
15
|
//# sourceMappingURL=opencodeTaskSessions.js.map
|