repoburg 1.3.188 → 1.3.196
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/agent-pane/.prettierignore +5 -0
- package/agent-pane/.prettierrc +8 -0
- package/agent-pane/backend/coverage/base.css +224 -0
- package/agent-pane/backend/coverage/block-navigation.js +87 -0
- package/agent-pane/backend/coverage/clover.xml +887 -0
- package/agent-pane/backend/coverage/coverage-final.json +10 -0
- package/agent-pane/backend/coverage/favicon.png +0 -0
- package/agent-pane/backend/coverage/index.html +176 -0
- package/agent-pane/backend/coverage/prettify.css +1 -0
- package/agent-pane/backend/coverage/prettify.js +2 -0
- package/agent-pane/backend/coverage/sort-arrow-sprite.png +0 -0
- package/agent-pane/backend/coverage/sorter.js +210 -0
- package/agent-pane/backend/coverage/src/codex/codex-provider.ts.html +1402 -0
- package/agent-pane/backend/coverage/src/codex/index.html +131 -0
- package/agent-pane/backend/coverage/src/codex/item-mapper.ts.html +331 -0
- package/agent-pane/backend/coverage/src/db/index.html +131 -0
- package/agent-pane/backend/coverage/src/db/index.ts.html +436 -0
- package/agent-pane/backend/coverage/src/db/schema.ts.html +175 -0
- package/agent-pane/backend/coverage/src/index.html +116 -0
- package/agent-pane/backend/coverage/src/index.ts.html +262 -0
- package/agent-pane/backend/coverage/src/routes/index.html +146 -0
- package/agent-pane/backend/coverage/src/routes/sessions.ts.html +991 -0
- package/agent-pane/backend/coverage/src/routes/turns.ts.html +256 -0
- package/agent-pane/backend/coverage/src/routes/workspaces.ts.html +406 -0
- package/agent-pane/backend/coverage/src/ws/index.html +116 -0
- package/agent-pane/backend/coverage/src/ws/index.ts.html +238 -0
- package/agent-pane/backend/data.db +0 -0
- package/agent-pane/backend/data.db-shm +0 -0
- package/agent-pane/backend/data.db-wal +0 -0
- package/agent-pane/backend/dist/index.js +70869 -0
- package/agent-pane/backend/package-lock.json +4529 -1013
- package/agent-pane/backend/package.json +10 -6
- package/agent-pane/backend/src/claude/claude-message-mapper.test.ts +163 -0
- package/agent-pane/backend/src/claude/claude-message-mapper.ts +154 -0
- package/agent-pane/backend/src/claude/claude-provider.test.ts +65 -0
- package/agent-pane/backend/src/claude/claude-provider.ts +482 -0
- package/agent-pane/backend/src/claude/claude-types.ts +33 -0
- package/agent-pane/backend/src/codex/app-server-client.test.ts +183 -0
- package/agent-pane/backend/src/codex/app-server-client.ts +225 -0
- package/agent-pane/backend/src/codex/app-server-types.ts +259 -0
- package/agent-pane/backend/src/codex/codex-provider-runtime-config.test.ts +56 -0
- package/agent-pane/backend/src/codex/codex-provider.test.ts +60 -0
- package/agent-pane/backend/src/codex/codex-provider.ts +521 -265
- package/agent-pane/backend/src/codex/item-mapper.test.ts +221 -0
- package/agent-pane/backend/src/codex/item-mapper.ts +35 -8
- package/agent-pane/backend/src/codex/shared-app-server.ts +25 -0
- package/agent-pane/backend/src/db/index.test.ts +125 -0
- package/agent-pane/backend/src/db/index.ts +39 -8
- package/agent-pane/backend/src/db/schema.ts +28 -74
- package/agent-pane/backend/src/index.ts +29 -2
- package/agent-pane/backend/src/integration/__fixtures__/cancel-turn.json +29 -0
- package/agent-pane/backend/src/integration/__fixtures__/delta-streaming.json +40 -0
- package/agent-pane/backend/src/integration/__fixtures__/failed-turn.json +16 -0
- package/agent-pane/backend/src/integration/__fixtures__/mcp-tool-call.json +60 -0
- package/agent-pane/backend/src/integration/__fixtures__/missing-item-started.json +34 -0
- package/agent-pane/backend/src/integration/__fixtures__/multi-item-turn.json +85 -0
- package/agent-pane/backend/src/integration/__fixtures__/multi-turn.json +48 -0
- package/agent-pane/backend/src/integration/__fixtures__/simple-turn.json +35 -0
- package/agent-pane/backend/src/integration/delta-streaming.test.ts +130 -0
- package/agent-pane/backend/src/integration/helpers/app-server-mock.ts +272 -0
- package/agent-pane/backend/src/integration/helpers/test-app.ts +108 -0
- package/agent-pane/backend/src/integration/helpers/ws-capture.ts +64 -0
- package/agent-pane/backend/src/integration/item-lifecycle.test.ts +133 -0
- package/agent-pane/backend/src/integration/mcp-tool-call.test.ts +102 -0
- package/agent-pane/backend/src/integration/missing-item-started.test.ts +91 -0
- package/agent-pane/backend/src/integration/multi-turn.test.ts +121 -0
- package/agent-pane/backend/src/integration/session-operations.test.ts +168 -0
- package/agent-pane/backend/src/integration/title-generation.test.ts +109 -0
- package/agent-pane/backend/src/integration/turn-cancel.test.ts +111 -0
- package/agent-pane/backend/src/integration/turn-failure.test.ts +97 -0
- package/agent-pane/backend/src/integration/turn-lifecycle.test.ts +141 -0
- package/agent-pane/backend/src/providers/index.ts +14 -0
- package/agent-pane/backend/src/providers/registry.test.ts +92 -0
- package/agent-pane/backend/src/providers/registry.ts +43 -0
- package/agent-pane/backend/src/providers/runtime-provider.ts +25 -0
- package/agent-pane/backend/src/routes/files.ts +31 -0
- package/agent-pane/backend/src/routes/mcp.ts +33 -0
- package/agent-pane/backend/src/routes/models.test.ts +92 -0
- package/agent-pane/backend/src/routes/models.ts +16 -0
- package/agent-pane/backend/src/routes/plugins.ts +40 -0
- package/agent-pane/backend/src/routes/providers.test.ts +69 -0
- package/agent-pane/backend/src/routes/providers.ts +57 -0
- package/agent-pane/backend/src/routes/sessions.test.ts +424 -0
- package/agent-pane/backend/src/routes/sessions.ts +295 -42
- package/agent-pane/backend/src/routes/skills.test.ts +114 -0
- package/agent-pane/backend/src/routes/skills.ts +70 -0
- package/agent-pane/backend/src/routes/turns.test.ts +152 -0
- package/agent-pane/backend/src/routes/turns.ts +36 -16
- package/agent-pane/backend/src/routes/workspaces.test.ts +197 -0
- package/agent-pane/backend/src/routes/workspaces.ts +73 -55
- package/agent-pane/backend/src/ws/index.test.ts +107 -0
- package/agent-pane/backend/src/ws/index.ts +19 -11
- package/agent-pane/backend/tsconfig.json +4 -2
- package/agent-pane/backend/vitest.config.ts +20 -0
- package/agent-pane/eslint.config.js +33 -0
- package/agent-pane/frontend/coverage/base.css +224 -0
- package/agent-pane/frontend/coverage/block-navigation.js +87 -0
- package/agent-pane/frontend/coverage/clover.xml +2962 -0
- package/agent-pane/frontend/coverage/coverage-final.json +37 -0
- package/agent-pane/frontend/coverage/favicon.png +0 -0
- package/agent-pane/frontend/coverage/index.html +251 -0
- package/agent-pane/frontend/coverage/prettify.css +1 -0
- package/agent-pane/frontend/coverage/prettify.js +2 -0
- package/agent-pane/frontend/coverage/sort-arrow-sprite.png +0 -0
- package/agent-pane/frontend/coverage/sorter.js +210 -0
- package/agent-pane/frontend/coverage/src/App.tsx.html +217 -0
- package/agent-pane/frontend/coverage/src/AppInitializer.tsx.html +223 -0
- package/agent-pane/frontend/coverage/src/api/client.ts.html +187 -0
- package/agent-pane/frontend/coverage/src/api/index.html +161 -0
- package/agent-pane/frontend/coverage/src/api/sessions.ts.html +316 -0
- package/agent-pane/frontend/coverage/src/api/websocket.ts.html +544 -0
- package/agent-pane/frontend/coverage/src/api/workspaces.ts.html +199 -0
- package/agent-pane/frontend/coverage/src/components/CollapsibleToolCalls.tsx.html +226 -0
- package/agent-pane/frontend/coverage/src/components/CommandInputBar.tsx.html +382 -0
- package/agent-pane/frontend/coverage/src/components/CommandPalette.tsx.html +715 -0
- package/agent-pane/frontend/coverage/src/components/IdeWorkspace.tsx.html +160 -0
- package/agent-pane/frontend/coverage/src/components/ModelSelector.tsx.html +478 -0
- package/agent-pane/frontend/coverage/src/components/NewSessionDialog.tsx.html +472 -0
- package/agent-pane/frontend/coverage/src/components/RenderArea.tsx.html +574 -0
- package/agent-pane/frontend/coverage/src/components/RightPanel.tsx.html +205 -0
- package/agent-pane/frontend/coverage/src/components/RuntimeIcon.tsx.html +133 -0
- package/agent-pane/frontend/coverage/src/components/SessionTabs.tsx.html +217 -0
- package/agent-pane/frontend/coverage/src/components/StatusBar.tsx.html +271 -0
- package/agent-pane/frontend/coverage/src/components/StatusDot.tsx.html +109 -0
- package/agent-pane/frontend/coverage/src/components/Toast.tsx.html +313 -0
- package/agent-pane/frontend/coverage/src/components/TurnContent.tsx.html +1216 -0
- package/agent-pane/frontend/coverage/src/components/WorkspaceSidebar.tsx.html +1138 -0
- package/agent-pane/frontend/coverage/src/components/index.html +326 -0
- package/agent-pane/frontend/coverage/src/components/panels/ChangesPanel.tsx.html +247 -0
- package/agent-pane/frontend/coverage/src/components/panels/LogsPanel.tsx.html +160 -0
- package/agent-pane/frontend/coverage/src/components/panels/MetricsPanel.tsx.html +427 -0
- package/agent-pane/frontend/coverage/src/components/panels/TurnsPanel.tsx.html +397 -0
- package/agent-pane/frontend/coverage/src/components/panels/index.html +161 -0
- package/agent-pane/frontend/coverage/src/constants/index.html +116 -0
- package/agent-pane/frontend/coverage/src/constants/models.ts.html +406 -0
- package/agent-pane/frontend/coverage/src/hooks/index.html +146 -0
- package/agent-pane/frontend/coverage/src/hooks/useEscapeKey.ts.html +124 -0
- package/agent-pane/frontend/coverage/src/hooks/useOutsideClick.ts.html +142 -0
- package/agent-pane/frontend/coverage/src/hooks/useSessionStatus.ts.html +187 -0
- package/agent-pane/frontend/coverage/src/index.html +146 -0
- package/agent-pane/frontend/coverage/src/main.tsx.html +115 -0
- package/agent-pane/frontend/coverage/src/store/index.html +116 -0
- package/agent-pane/frontend/coverage/src/store/store.ts.html +2404 -0
- package/agent-pane/frontend/coverage/src/test/component-helpers.ts.html +190 -0
- package/agent-pane/frontend/coverage/src/test/fixtures.ts.html +367 -0
- package/agent-pane/frontend/coverage/src/test/index.html +131 -0
- package/agent-pane/frontend/coverage/src/types/index.html +116 -0
- package/agent-pane/frontend/coverage/src/types/index.ts.html +466 -0
- package/agent-pane/frontend/coverage/src/utils/changes.ts.html +202 -0
- package/agent-pane/frontend/coverage/src/utils/duration.ts.html +127 -0
- package/agent-pane/frontend/coverage/src/utils/index.html +131 -0
- package/agent-pane/frontend/dist/assets/index-Bg0PF2aV.css +1 -0
- package/agent-pane/frontend/dist/assets/index-BlybeX5e.js +281 -0
- package/agent-pane/frontend/dist/index.html +19 -0
- package/agent-pane/frontend/package-lock.json +2434 -213
- package/agent-pane/frontend/package.json +10 -3
- package/agent-pane/frontend/src/App.test.tsx +74 -0
- package/agent-pane/frontend/src/App.tsx +1 -1
- package/agent-pane/frontend/src/AppInitializer.test.tsx +142 -0
- package/agent-pane/frontend/src/AppInitializer.tsx +1 -1
- package/agent-pane/frontend/src/api/client.test.ts +126 -0
- package/agent-pane/frontend/src/api/client.ts +22 -29
- package/agent-pane/frontend/src/api/models.ts +7 -0
- package/agent-pane/frontend/src/api/providers.ts +12 -0
- package/agent-pane/frontend/src/api/sessions.test.ts +241 -0
- package/agent-pane/frontend/src/api/sessions.ts +43 -1
- package/agent-pane/frontend/src/api/skills.ts +12 -0
- package/agent-pane/frontend/src/api/websocket.test.ts +288 -0
- package/agent-pane/frontend/src/api/websocket.ts +27 -2
- package/agent-pane/frontend/src/api/workspaces.test.ts +112 -0
- package/agent-pane/frontend/src/api/workspaces.ts +17 -3
- package/agent-pane/frontend/src/components/CollapsibleToolCalls.test.tsx +49 -0
- package/agent-pane/frontend/src/components/CollapsibleToolCalls.tsx +2 -5
- package/agent-pane/frontend/src/components/CommandInputBar.test.tsx +133 -0
- package/agent-pane/frontend/src/components/CommandInputBar.tsx +296 -17
- package/agent-pane/frontend/src/components/CommandPalette.test.tsx +230 -0
- package/agent-pane/frontend/src/components/CommandPalette.tsx +26 -23
- package/agent-pane/frontend/src/components/IdeWorkspace.tsx +1 -1
- package/agent-pane/frontend/src/components/ModelSelector.test.tsx +129 -0
- package/agent-pane/frontend/src/components/ModelSelector.tsx +191 -0
- package/agent-pane/frontend/src/components/NewSessionDialog.test.tsx +95 -0
- package/agent-pane/frontend/src/components/NewSessionDialog.tsx +58 -13
- package/agent-pane/frontend/src/components/RenderArea.test.tsx +160 -0
- package/agent-pane/frontend/src/components/RenderArea.tsx +18 -25
- package/agent-pane/frontend/src/components/RightPanel.test.tsx +43 -0
- package/agent-pane/frontend/src/components/RightPanel.tsx +1 -1
- package/agent-pane/frontend/src/components/RuntimeIcon.test.tsx +32 -0
- package/agent-pane/frontend/src/components/RuntimeIcon.tsx +1 -1
- package/agent-pane/frontend/src/components/SessionTabs.test.tsx +72 -0
- package/agent-pane/frontend/src/components/SessionTabs.tsx +12 -12
- package/agent-pane/frontend/src/components/StatusBar.test.tsx +56 -0
- package/agent-pane/frontend/src/components/StatusBar.tsx +25 -31
- package/agent-pane/frontend/src/components/StatusDot.test.tsx +25 -0
- package/agent-pane/frontend/src/components/StatusDot.tsx +2 -7
- package/agent-pane/frontend/src/components/Toast.test.tsx +79 -0
- package/agent-pane/frontend/src/components/Toast.tsx +2 -6
- package/agent-pane/frontend/src/components/TurnContent.test.tsx +287 -0
- package/agent-pane/frontend/src/components/TurnContent.tsx +107 -24
- package/agent-pane/frontend/src/components/WorkspaceSidebar.test.tsx +297 -0
- package/agent-pane/frontend/src/components/WorkspaceSidebar.tsx +33 -32
- package/agent-pane/frontend/src/components/input/OptionSubPopup.tsx +32 -0
- package/agent-pane/frontend/src/components/input/SkillMentionPopup.test.tsx +63 -0
- package/agent-pane/frontend/src/components/input/SkillMentionPopup.tsx +78 -0
- package/agent-pane/frontend/src/components/input/SlashPopup.test.tsx +96 -0
- package/agent-pane/frontend/src/components/input/SlashPopup.tsx +63 -0
- package/agent-pane/frontend/src/components/panels/ChangesPanel.test.tsx +61 -0
- package/agent-pane/frontend/src/components/panels/ChangesPanel.tsx +12 -39
- package/agent-pane/frontend/src/components/panels/LogsPanel.test.tsx +58 -0
- package/agent-pane/frontend/src/components/panels/LogsPanel.tsx +1 -1
- package/agent-pane/frontend/src/components/panels/MetricsPanel.test.tsx +71 -0
- package/agent-pane/frontend/src/components/panels/MetricsPanel.tsx +63 -31
- package/agent-pane/frontend/src/components/panels/TurnsPanel.test.tsx +83 -0
- package/agent-pane/frontend/src/components/panels/TurnsPanel.tsx +66 -7
- package/agent-pane/frontend/src/constants/models.test.ts +97 -0
- package/agent-pane/frontend/src/constants/models.ts +129 -0
- package/agent-pane/frontend/src/hooks/useEscapeKey.test.ts +42 -0
- package/agent-pane/frontend/src/hooks/useEscapeKey.ts +13 -0
- package/agent-pane/frontend/src/hooks/useOutsideClick.test.ts +92 -0
- package/agent-pane/frontend/src/hooks/useOutsideClick.ts +19 -0
- package/agent-pane/frontend/src/hooks/useProvider.ts +44 -0
- package/agent-pane/frontend/src/hooks/useSessionStatus.test.ts +114 -0
- package/agent-pane/frontend/src/hooks/useSessionStatus.ts +34 -0
- package/agent-pane/frontend/src/main.test.tsx +37 -0
- package/agent-pane/frontend/src/main.tsx +1 -1
- package/agent-pane/frontend/src/store/sessionSlice.ts +417 -0
- package/agent-pane/frontend/src/store/store.test.ts +1284 -0
- package/agent-pane/frontend/src/store/store.ts +16 -617
- package/agent-pane/frontend/src/store/uiSlice.ts +83 -0
- package/agent-pane/frontend/src/store/workspaceSlice.ts +77 -0
- package/agent-pane/frontend/src/store/wsSlice.ts +292 -0
- package/agent-pane/frontend/src/styles/app.css +113 -7
- package/agent-pane/frontend/src/test/component-helpers.ts +36 -0
- package/agent-pane/frontend/src/test/fixtures.ts +96 -0
- package/agent-pane/frontend/src/test-setup.ts +5 -0
- package/agent-pane/frontend/src/types/index.test.ts +128 -0
- package/agent-pane/frontend/src/types/index.ts +80 -104
- package/agent-pane/frontend/src/utils/changes.test.ts +81 -0
- package/agent-pane/frontend/src/utils/changes.ts +39 -0
- package/agent-pane/frontend/src/utils/duration.test.ts +71 -0
- package/agent-pane/frontend/src/utils/duration.ts +14 -0
- package/agent-pane/frontend/tsconfig.json +4 -1
- package/agent-pane/frontend/vite.config.ts +6 -0
- package/agent-pane/frontend/vitest.config.ts +29 -0
- package/agent-pane/package-lock.json +1527 -0
- package/agent-pane/package.json +19 -0
- package/agent-pane/shared/provider-types.ts +53 -0
- package/agent-pane/shared/types.ts +107 -0
- package/agentpane-branch-session.png +0 -0
- package/agentpane-expanded-all.png +0 -0
- package/agentpane-fixed-rendering.png +0 -0
- package/agentpane-focus-check.png +0 -0
- package/agentpane-initial.png +0 -0
- package/agentpane-mcp-detail.png +0 -0
- package/agentpane-no-focus-ring.png +0 -0
- package/agentpane-soft-focus.png +0 -0
- package/backend/dist/src/llm-provider/ollama-llm.provider.js +1 -0
- package/backend/dist/src/llm-provider/ollama-llm.provider.js.map +1 -1
- package/backend/dist/tsconfig.build.tsbuildinfo +1 -1
- package/data.db +0 -0
- package/empty-state.png +0 -0
- package/frontend-home.png +0 -0
- package/model-selector-open.png +0 -0
- package/package.json +1 -1
- package/slash-popup-working.png +0 -0
- package/agent-pane/frontend/src/components/DiffViewer.tsx +0 -27
|
@@ -0,0 +1,991 @@
|
|
|
1
|
+
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<title>Code coverage report for src/routes/sessions.ts</title>
|
|
7
|
+
<meta charset="utf-8" />
|
|
8
|
+
<link rel="stylesheet" href="../../prettify.css" />
|
|
9
|
+
<link rel="stylesheet" href="../../base.css" />
|
|
10
|
+
<link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
|
|
11
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
12
|
+
<style type='text/css'>
|
|
13
|
+
.coverage-summary .sorter {
|
|
14
|
+
background-image: url(../../sort-arrow-sprite.png);
|
|
15
|
+
}
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<div class='wrapper'>
|
|
21
|
+
<div class='pad1'>
|
|
22
|
+
<h1><a href="../../index.html">All files</a> / <a href="index.html">src/routes</a> sessions.ts</h1>
|
|
23
|
+
<div class='clearfix'>
|
|
24
|
+
|
|
25
|
+
<div class='fl pad1y space-right2'>
|
|
26
|
+
<span class="strong">98.19% </span>
|
|
27
|
+
<span class="quiet">Statements</span>
|
|
28
|
+
<span class='fraction'>217/221</span>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<div class='fl pad1y space-right2'>
|
|
33
|
+
<span class="strong">81.25% </span>
|
|
34
|
+
<span class="quiet">Branches</span>
|
|
35
|
+
<span class='fraction'>39/48</span>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<div class='fl pad1y space-right2'>
|
|
40
|
+
<span class="strong">100% </span>
|
|
41
|
+
<span class="quiet">Functions</span>
|
|
42
|
+
<span class='fraction'>1/1</span>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<div class='fl pad1y space-right2'>
|
|
47
|
+
<span class="strong">98.19% </span>
|
|
48
|
+
<span class="quiet">Lines</span>
|
|
49
|
+
<span class='fraction'>217/221</span>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
<p class="quiet">
|
|
55
|
+
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
56
|
+
</p>
|
|
57
|
+
<template id="filterTemplate">
|
|
58
|
+
<div class="quiet">
|
|
59
|
+
Filter:
|
|
60
|
+
<input type="search" id="fileSearch">
|
|
61
|
+
</div>
|
|
62
|
+
</template>
|
|
63
|
+
</div>
|
|
64
|
+
<div class='status-line high'></div>
|
|
65
|
+
<pre><table class="coverage">
|
|
66
|
+
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
|
|
67
|
+
<a name='L2'></a><a href='#L2'>2</a>
|
|
68
|
+
<a name='L3'></a><a href='#L3'>3</a>
|
|
69
|
+
<a name='L4'></a><a href='#L4'>4</a>
|
|
70
|
+
<a name='L5'></a><a href='#L5'>5</a>
|
|
71
|
+
<a name='L6'></a><a href='#L6'>6</a>
|
|
72
|
+
<a name='L7'></a><a href='#L7'>7</a>
|
|
73
|
+
<a name='L8'></a><a href='#L8'>8</a>
|
|
74
|
+
<a name='L9'></a><a href='#L9'>9</a>
|
|
75
|
+
<a name='L10'></a><a href='#L10'>10</a>
|
|
76
|
+
<a name='L11'></a><a href='#L11'>11</a>
|
|
77
|
+
<a name='L12'></a><a href='#L12'>12</a>
|
|
78
|
+
<a name='L13'></a><a href='#L13'>13</a>
|
|
79
|
+
<a name='L14'></a><a href='#L14'>14</a>
|
|
80
|
+
<a name='L15'></a><a href='#L15'>15</a>
|
|
81
|
+
<a name='L16'></a><a href='#L16'>16</a>
|
|
82
|
+
<a name='L17'></a><a href='#L17'>17</a>
|
|
83
|
+
<a name='L18'></a><a href='#L18'>18</a>
|
|
84
|
+
<a name='L19'></a><a href='#L19'>19</a>
|
|
85
|
+
<a name='L20'></a><a href='#L20'>20</a>
|
|
86
|
+
<a name='L21'></a><a href='#L21'>21</a>
|
|
87
|
+
<a name='L22'></a><a href='#L22'>22</a>
|
|
88
|
+
<a name='L23'></a><a href='#L23'>23</a>
|
|
89
|
+
<a name='L24'></a><a href='#L24'>24</a>
|
|
90
|
+
<a name='L25'></a><a href='#L25'>25</a>
|
|
91
|
+
<a name='L26'></a><a href='#L26'>26</a>
|
|
92
|
+
<a name='L27'></a><a href='#L27'>27</a>
|
|
93
|
+
<a name='L28'></a><a href='#L28'>28</a>
|
|
94
|
+
<a name='L29'></a><a href='#L29'>29</a>
|
|
95
|
+
<a name='L30'></a><a href='#L30'>30</a>
|
|
96
|
+
<a name='L31'></a><a href='#L31'>31</a>
|
|
97
|
+
<a name='L32'></a><a href='#L32'>32</a>
|
|
98
|
+
<a name='L33'></a><a href='#L33'>33</a>
|
|
99
|
+
<a name='L34'></a><a href='#L34'>34</a>
|
|
100
|
+
<a name='L35'></a><a href='#L35'>35</a>
|
|
101
|
+
<a name='L36'></a><a href='#L36'>36</a>
|
|
102
|
+
<a name='L37'></a><a href='#L37'>37</a>
|
|
103
|
+
<a name='L38'></a><a href='#L38'>38</a>
|
|
104
|
+
<a name='L39'></a><a href='#L39'>39</a>
|
|
105
|
+
<a name='L40'></a><a href='#L40'>40</a>
|
|
106
|
+
<a name='L41'></a><a href='#L41'>41</a>
|
|
107
|
+
<a name='L42'></a><a href='#L42'>42</a>
|
|
108
|
+
<a name='L43'></a><a href='#L43'>43</a>
|
|
109
|
+
<a name='L44'></a><a href='#L44'>44</a>
|
|
110
|
+
<a name='L45'></a><a href='#L45'>45</a>
|
|
111
|
+
<a name='L46'></a><a href='#L46'>46</a>
|
|
112
|
+
<a name='L47'></a><a href='#L47'>47</a>
|
|
113
|
+
<a name='L48'></a><a href='#L48'>48</a>
|
|
114
|
+
<a name='L49'></a><a href='#L49'>49</a>
|
|
115
|
+
<a name='L50'></a><a href='#L50'>50</a>
|
|
116
|
+
<a name='L51'></a><a href='#L51'>51</a>
|
|
117
|
+
<a name='L52'></a><a href='#L52'>52</a>
|
|
118
|
+
<a name='L53'></a><a href='#L53'>53</a>
|
|
119
|
+
<a name='L54'></a><a href='#L54'>54</a>
|
|
120
|
+
<a name='L55'></a><a href='#L55'>55</a>
|
|
121
|
+
<a name='L56'></a><a href='#L56'>56</a>
|
|
122
|
+
<a name='L57'></a><a href='#L57'>57</a>
|
|
123
|
+
<a name='L58'></a><a href='#L58'>58</a>
|
|
124
|
+
<a name='L59'></a><a href='#L59'>59</a>
|
|
125
|
+
<a name='L60'></a><a href='#L60'>60</a>
|
|
126
|
+
<a name='L61'></a><a href='#L61'>61</a>
|
|
127
|
+
<a name='L62'></a><a href='#L62'>62</a>
|
|
128
|
+
<a name='L63'></a><a href='#L63'>63</a>
|
|
129
|
+
<a name='L64'></a><a href='#L64'>64</a>
|
|
130
|
+
<a name='L65'></a><a href='#L65'>65</a>
|
|
131
|
+
<a name='L66'></a><a href='#L66'>66</a>
|
|
132
|
+
<a name='L67'></a><a href='#L67'>67</a>
|
|
133
|
+
<a name='L68'></a><a href='#L68'>68</a>
|
|
134
|
+
<a name='L69'></a><a href='#L69'>69</a>
|
|
135
|
+
<a name='L70'></a><a href='#L70'>70</a>
|
|
136
|
+
<a name='L71'></a><a href='#L71'>71</a>
|
|
137
|
+
<a name='L72'></a><a href='#L72'>72</a>
|
|
138
|
+
<a name='L73'></a><a href='#L73'>73</a>
|
|
139
|
+
<a name='L74'></a><a href='#L74'>74</a>
|
|
140
|
+
<a name='L75'></a><a href='#L75'>75</a>
|
|
141
|
+
<a name='L76'></a><a href='#L76'>76</a>
|
|
142
|
+
<a name='L77'></a><a href='#L77'>77</a>
|
|
143
|
+
<a name='L78'></a><a href='#L78'>78</a>
|
|
144
|
+
<a name='L79'></a><a href='#L79'>79</a>
|
|
145
|
+
<a name='L80'></a><a href='#L80'>80</a>
|
|
146
|
+
<a name='L81'></a><a href='#L81'>81</a>
|
|
147
|
+
<a name='L82'></a><a href='#L82'>82</a>
|
|
148
|
+
<a name='L83'></a><a href='#L83'>83</a>
|
|
149
|
+
<a name='L84'></a><a href='#L84'>84</a>
|
|
150
|
+
<a name='L85'></a><a href='#L85'>85</a>
|
|
151
|
+
<a name='L86'></a><a href='#L86'>86</a>
|
|
152
|
+
<a name='L87'></a><a href='#L87'>87</a>
|
|
153
|
+
<a name='L88'></a><a href='#L88'>88</a>
|
|
154
|
+
<a name='L89'></a><a href='#L89'>89</a>
|
|
155
|
+
<a name='L90'></a><a href='#L90'>90</a>
|
|
156
|
+
<a name='L91'></a><a href='#L91'>91</a>
|
|
157
|
+
<a name='L92'></a><a href='#L92'>92</a>
|
|
158
|
+
<a name='L93'></a><a href='#L93'>93</a>
|
|
159
|
+
<a name='L94'></a><a href='#L94'>94</a>
|
|
160
|
+
<a name='L95'></a><a href='#L95'>95</a>
|
|
161
|
+
<a name='L96'></a><a href='#L96'>96</a>
|
|
162
|
+
<a name='L97'></a><a href='#L97'>97</a>
|
|
163
|
+
<a name='L98'></a><a href='#L98'>98</a>
|
|
164
|
+
<a name='L99'></a><a href='#L99'>99</a>
|
|
165
|
+
<a name='L100'></a><a href='#L100'>100</a>
|
|
166
|
+
<a name='L101'></a><a href='#L101'>101</a>
|
|
167
|
+
<a name='L102'></a><a href='#L102'>102</a>
|
|
168
|
+
<a name='L103'></a><a href='#L103'>103</a>
|
|
169
|
+
<a name='L104'></a><a href='#L104'>104</a>
|
|
170
|
+
<a name='L105'></a><a href='#L105'>105</a>
|
|
171
|
+
<a name='L106'></a><a href='#L106'>106</a>
|
|
172
|
+
<a name='L107'></a><a href='#L107'>107</a>
|
|
173
|
+
<a name='L108'></a><a href='#L108'>108</a>
|
|
174
|
+
<a name='L109'></a><a href='#L109'>109</a>
|
|
175
|
+
<a name='L110'></a><a href='#L110'>110</a>
|
|
176
|
+
<a name='L111'></a><a href='#L111'>111</a>
|
|
177
|
+
<a name='L112'></a><a href='#L112'>112</a>
|
|
178
|
+
<a name='L113'></a><a href='#L113'>113</a>
|
|
179
|
+
<a name='L114'></a><a href='#L114'>114</a>
|
|
180
|
+
<a name='L115'></a><a href='#L115'>115</a>
|
|
181
|
+
<a name='L116'></a><a href='#L116'>116</a>
|
|
182
|
+
<a name='L117'></a><a href='#L117'>117</a>
|
|
183
|
+
<a name='L118'></a><a href='#L118'>118</a>
|
|
184
|
+
<a name='L119'></a><a href='#L119'>119</a>
|
|
185
|
+
<a name='L120'></a><a href='#L120'>120</a>
|
|
186
|
+
<a name='L121'></a><a href='#L121'>121</a>
|
|
187
|
+
<a name='L122'></a><a href='#L122'>122</a>
|
|
188
|
+
<a name='L123'></a><a href='#L123'>123</a>
|
|
189
|
+
<a name='L124'></a><a href='#L124'>124</a>
|
|
190
|
+
<a name='L125'></a><a href='#L125'>125</a>
|
|
191
|
+
<a name='L126'></a><a href='#L126'>126</a>
|
|
192
|
+
<a name='L127'></a><a href='#L127'>127</a>
|
|
193
|
+
<a name='L128'></a><a href='#L128'>128</a>
|
|
194
|
+
<a name='L129'></a><a href='#L129'>129</a>
|
|
195
|
+
<a name='L130'></a><a href='#L130'>130</a>
|
|
196
|
+
<a name='L131'></a><a href='#L131'>131</a>
|
|
197
|
+
<a name='L132'></a><a href='#L132'>132</a>
|
|
198
|
+
<a name='L133'></a><a href='#L133'>133</a>
|
|
199
|
+
<a name='L134'></a><a href='#L134'>134</a>
|
|
200
|
+
<a name='L135'></a><a href='#L135'>135</a>
|
|
201
|
+
<a name='L136'></a><a href='#L136'>136</a>
|
|
202
|
+
<a name='L137'></a><a href='#L137'>137</a>
|
|
203
|
+
<a name='L138'></a><a href='#L138'>138</a>
|
|
204
|
+
<a name='L139'></a><a href='#L139'>139</a>
|
|
205
|
+
<a name='L140'></a><a href='#L140'>140</a>
|
|
206
|
+
<a name='L141'></a><a href='#L141'>141</a>
|
|
207
|
+
<a name='L142'></a><a href='#L142'>142</a>
|
|
208
|
+
<a name='L143'></a><a href='#L143'>143</a>
|
|
209
|
+
<a name='L144'></a><a href='#L144'>144</a>
|
|
210
|
+
<a name='L145'></a><a href='#L145'>145</a>
|
|
211
|
+
<a name='L146'></a><a href='#L146'>146</a>
|
|
212
|
+
<a name='L147'></a><a href='#L147'>147</a>
|
|
213
|
+
<a name='L148'></a><a href='#L148'>148</a>
|
|
214
|
+
<a name='L149'></a><a href='#L149'>149</a>
|
|
215
|
+
<a name='L150'></a><a href='#L150'>150</a>
|
|
216
|
+
<a name='L151'></a><a href='#L151'>151</a>
|
|
217
|
+
<a name='L152'></a><a href='#L152'>152</a>
|
|
218
|
+
<a name='L153'></a><a href='#L153'>153</a>
|
|
219
|
+
<a name='L154'></a><a href='#L154'>154</a>
|
|
220
|
+
<a name='L155'></a><a href='#L155'>155</a>
|
|
221
|
+
<a name='L156'></a><a href='#L156'>156</a>
|
|
222
|
+
<a name='L157'></a><a href='#L157'>157</a>
|
|
223
|
+
<a name='L158'></a><a href='#L158'>158</a>
|
|
224
|
+
<a name='L159'></a><a href='#L159'>159</a>
|
|
225
|
+
<a name='L160'></a><a href='#L160'>160</a>
|
|
226
|
+
<a name='L161'></a><a href='#L161'>161</a>
|
|
227
|
+
<a name='L162'></a><a href='#L162'>162</a>
|
|
228
|
+
<a name='L163'></a><a href='#L163'>163</a>
|
|
229
|
+
<a name='L164'></a><a href='#L164'>164</a>
|
|
230
|
+
<a name='L165'></a><a href='#L165'>165</a>
|
|
231
|
+
<a name='L166'></a><a href='#L166'>166</a>
|
|
232
|
+
<a name='L167'></a><a href='#L167'>167</a>
|
|
233
|
+
<a name='L168'></a><a href='#L168'>168</a>
|
|
234
|
+
<a name='L169'></a><a href='#L169'>169</a>
|
|
235
|
+
<a name='L170'></a><a href='#L170'>170</a>
|
|
236
|
+
<a name='L171'></a><a href='#L171'>171</a>
|
|
237
|
+
<a name='L172'></a><a href='#L172'>172</a>
|
|
238
|
+
<a name='L173'></a><a href='#L173'>173</a>
|
|
239
|
+
<a name='L174'></a><a href='#L174'>174</a>
|
|
240
|
+
<a name='L175'></a><a href='#L175'>175</a>
|
|
241
|
+
<a name='L176'></a><a href='#L176'>176</a>
|
|
242
|
+
<a name='L177'></a><a href='#L177'>177</a>
|
|
243
|
+
<a name='L178'></a><a href='#L178'>178</a>
|
|
244
|
+
<a name='L179'></a><a href='#L179'>179</a>
|
|
245
|
+
<a name='L180'></a><a href='#L180'>180</a>
|
|
246
|
+
<a name='L181'></a><a href='#L181'>181</a>
|
|
247
|
+
<a name='L182'></a><a href='#L182'>182</a>
|
|
248
|
+
<a name='L183'></a><a href='#L183'>183</a>
|
|
249
|
+
<a name='L184'></a><a href='#L184'>184</a>
|
|
250
|
+
<a name='L185'></a><a href='#L185'>185</a>
|
|
251
|
+
<a name='L186'></a><a href='#L186'>186</a>
|
|
252
|
+
<a name='L187'></a><a href='#L187'>187</a>
|
|
253
|
+
<a name='L188'></a><a href='#L188'>188</a>
|
|
254
|
+
<a name='L189'></a><a href='#L189'>189</a>
|
|
255
|
+
<a name='L190'></a><a href='#L190'>190</a>
|
|
256
|
+
<a name='L191'></a><a href='#L191'>191</a>
|
|
257
|
+
<a name='L192'></a><a href='#L192'>192</a>
|
|
258
|
+
<a name='L193'></a><a href='#L193'>193</a>
|
|
259
|
+
<a name='L194'></a><a href='#L194'>194</a>
|
|
260
|
+
<a name='L195'></a><a href='#L195'>195</a>
|
|
261
|
+
<a name='L196'></a><a href='#L196'>196</a>
|
|
262
|
+
<a name='L197'></a><a href='#L197'>197</a>
|
|
263
|
+
<a name='L198'></a><a href='#L198'>198</a>
|
|
264
|
+
<a name='L199'></a><a href='#L199'>199</a>
|
|
265
|
+
<a name='L200'></a><a href='#L200'>200</a>
|
|
266
|
+
<a name='L201'></a><a href='#L201'>201</a>
|
|
267
|
+
<a name='L202'></a><a href='#L202'>202</a>
|
|
268
|
+
<a name='L203'></a><a href='#L203'>203</a>
|
|
269
|
+
<a name='L204'></a><a href='#L204'>204</a>
|
|
270
|
+
<a name='L205'></a><a href='#L205'>205</a>
|
|
271
|
+
<a name='L206'></a><a href='#L206'>206</a>
|
|
272
|
+
<a name='L207'></a><a href='#L207'>207</a>
|
|
273
|
+
<a name='L208'></a><a href='#L208'>208</a>
|
|
274
|
+
<a name='L209'></a><a href='#L209'>209</a>
|
|
275
|
+
<a name='L210'></a><a href='#L210'>210</a>
|
|
276
|
+
<a name='L211'></a><a href='#L211'>211</a>
|
|
277
|
+
<a name='L212'></a><a href='#L212'>212</a>
|
|
278
|
+
<a name='L213'></a><a href='#L213'>213</a>
|
|
279
|
+
<a name='L214'></a><a href='#L214'>214</a>
|
|
280
|
+
<a name='L215'></a><a href='#L215'>215</a>
|
|
281
|
+
<a name='L216'></a><a href='#L216'>216</a>
|
|
282
|
+
<a name='L217'></a><a href='#L217'>217</a>
|
|
283
|
+
<a name='L218'></a><a href='#L218'>218</a>
|
|
284
|
+
<a name='L219'></a><a href='#L219'>219</a>
|
|
285
|
+
<a name='L220'></a><a href='#L220'>220</a>
|
|
286
|
+
<a name='L221'></a><a href='#L221'>221</a>
|
|
287
|
+
<a name='L222'></a><a href='#L222'>222</a>
|
|
288
|
+
<a name='L223'></a><a href='#L223'>223</a>
|
|
289
|
+
<a name='L224'></a><a href='#L224'>224</a>
|
|
290
|
+
<a name='L225'></a><a href='#L225'>225</a>
|
|
291
|
+
<a name='L226'></a><a href='#L226'>226</a>
|
|
292
|
+
<a name='L227'></a><a href='#L227'>227</a>
|
|
293
|
+
<a name='L228'></a><a href='#L228'>228</a>
|
|
294
|
+
<a name='L229'></a><a href='#L229'>229</a>
|
|
295
|
+
<a name='L230'></a><a href='#L230'>230</a>
|
|
296
|
+
<a name='L231'></a><a href='#L231'>231</a>
|
|
297
|
+
<a name='L232'></a><a href='#L232'>232</a>
|
|
298
|
+
<a name='L233'></a><a href='#L233'>233</a>
|
|
299
|
+
<a name='L234'></a><a href='#L234'>234</a>
|
|
300
|
+
<a name='L235'></a><a href='#L235'>235</a>
|
|
301
|
+
<a name='L236'></a><a href='#L236'>236</a>
|
|
302
|
+
<a name='L237'></a><a href='#L237'>237</a>
|
|
303
|
+
<a name='L238'></a><a href='#L238'>238</a>
|
|
304
|
+
<a name='L239'></a><a href='#L239'>239</a>
|
|
305
|
+
<a name='L240'></a><a href='#L240'>240</a>
|
|
306
|
+
<a name='L241'></a><a href='#L241'>241</a>
|
|
307
|
+
<a name='L242'></a><a href='#L242'>242</a>
|
|
308
|
+
<a name='L243'></a><a href='#L243'>243</a>
|
|
309
|
+
<a name='L244'></a><a href='#L244'>244</a>
|
|
310
|
+
<a name='L245'></a><a href='#L245'>245</a>
|
|
311
|
+
<a name='L246'></a><a href='#L246'>246</a>
|
|
312
|
+
<a name='L247'></a><a href='#L247'>247</a>
|
|
313
|
+
<a name='L248'></a><a href='#L248'>248</a>
|
|
314
|
+
<a name='L249'></a><a href='#L249'>249</a>
|
|
315
|
+
<a name='L250'></a><a href='#L250'>250</a>
|
|
316
|
+
<a name='L251'></a><a href='#L251'>251</a>
|
|
317
|
+
<a name='L252'></a><a href='#L252'>252</a>
|
|
318
|
+
<a name='L253'></a><a href='#L253'>253</a>
|
|
319
|
+
<a name='L254'></a><a href='#L254'>254</a>
|
|
320
|
+
<a name='L255'></a><a href='#L255'>255</a>
|
|
321
|
+
<a name='L256'></a><a href='#L256'>256</a>
|
|
322
|
+
<a name='L257'></a><a href='#L257'>257</a>
|
|
323
|
+
<a name='L258'></a><a href='#L258'>258</a>
|
|
324
|
+
<a name='L259'></a><a href='#L259'>259</a>
|
|
325
|
+
<a name='L260'></a><a href='#L260'>260</a>
|
|
326
|
+
<a name='L261'></a><a href='#L261'>261</a>
|
|
327
|
+
<a name='L262'></a><a href='#L262'>262</a>
|
|
328
|
+
<a name='L263'></a><a href='#L263'>263</a>
|
|
329
|
+
<a name='L264'></a><a href='#L264'>264</a>
|
|
330
|
+
<a name='L265'></a><a href='#L265'>265</a>
|
|
331
|
+
<a name='L266'></a><a href='#L266'>266</a>
|
|
332
|
+
<a name='L267'></a><a href='#L267'>267</a>
|
|
333
|
+
<a name='L268'></a><a href='#L268'>268</a>
|
|
334
|
+
<a name='L269'></a><a href='#L269'>269</a>
|
|
335
|
+
<a name='L270'></a><a href='#L270'>270</a>
|
|
336
|
+
<a name='L271'></a><a href='#L271'>271</a>
|
|
337
|
+
<a name='L272'></a><a href='#L272'>272</a>
|
|
338
|
+
<a name='L273'></a><a href='#L273'>273</a>
|
|
339
|
+
<a name='L274'></a><a href='#L274'>274</a>
|
|
340
|
+
<a name='L275'></a><a href='#L275'>275</a>
|
|
341
|
+
<a name='L276'></a><a href='#L276'>276</a>
|
|
342
|
+
<a name='L277'></a><a href='#L277'>277</a>
|
|
343
|
+
<a name='L278'></a><a href='#L278'>278</a>
|
|
344
|
+
<a name='L279'></a><a href='#L279'>279</a>
|
|
345
|
+
<a name='L280'></a><a href='#L280'>280</a>
|
|
346
|
+
<a name='L281'></a><a href='#L281'>281</a>
|
|
347
|
+
<a name='L282'></a><a href='#L282'>282</a>
|
|
348
|
+
<a name='L283'></a><a href='#L283'>283</a>
|
|
349
|
+
<a name='L284'></a><a href='#L284'>284</a>
|
|
350
|
+
<a name='L285'></a><a href='#L285'>285</a>
|
|
351
|
+
<a name='L286'></a><a href='#L286'>286</a>
|
|
352
|
+
<a name='L287'></a><a href='#L287'>287</a>
|
|
353
|
+
<a name='L288'></a><a href='#L288'>288</a>
|
|
354
|
+
<a name='L289'></a><a href='#L289'>289</a>
|
|
355
|
+
<a name='L290'></a><a href='#L290'>290</a>
|
|
356
|
+
<a name='L291'></a><a href='#L291'>291</a>
|
|
357
|
+
<a name='L292'></a><a href='#L292'>292</a>
|
|
358
|
+
<a name='L293'></a><a href='#L293'>293</a>
|
|
359
|
+
<a name='L294'></a><a href='#L294'>294</a>
|
|
360
|
+
<a name='L295'></a><a href='#L295'>295</a>
|
|
361
|
+
<a name='L296'></a><a href='#L296'>296</a>
|
|
362
|
+
<a name='L297'></a><a href='#L297'>297</a>
|
|
363
|
+
<a name='L298'></a><a href='#L298'>298</a>
|
|
364
|
+
<a name='L299'></a><a href='#L299'>299</a>
|
|
365
|
+
<a name='L300'></a><a href='#L300'>300</a>
|
|
366
|
+
<a name='L301'></a><a href='#L301'>301</a>
|
|
367
|
+
<a name='L302'></a><a href='#L302'>302</a>
|
|
368
|
+
<a name='L303'></a><a href='#L303'>303</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
369
|
+
<span class="cline-any cline-yes">1x</span>
|
|
370
|
+
<span class="cline-any cline-yes">1x</span>
|
|
371
|
+
<span class="cline-any cline-yes">1x</span>
|
|
372
|
+
<span class="cline-any cline-neutral"> </span>
|
|
373
|
+
<span class="cline-any cline-neutral"> </span>
|
|
374
|
+
<span class="cline-any cline-neutral"> </span>
|
|
375
|
+
<span class="cline-any cline-neutral"> </span>
|
|
376
|
+
<span class="cline-any cline-neutral"> </span>
|
|
377
|
+
<span class="cline-any cline-neutral"> </span>
|
|
378
|
+
<span class="cline-any cline-neutral"> </span>
|
|
379
|
+
<span class="cline-any cline-neutral"> </span>
|
|
380
|
+
<span class="cline-any cline-neutral"> </span>
|
|
381
|
+
<span class="cline-any cline-neutral"> </span>
|
|
382
|
+
<span class="cline-any cline-neutral"> </span>
|
|
383
|
+
<span class="cline-any cline-neutral"> </span>
|
|
384
|
+
<span class="cline-any cline-yes">23x</span>
|
|
385
|
+
<span class="cline-any cline-neutral"> </span>
|
|
386
|
+
<span class="cline-any cline-yes">23x</span>
|
|
387
|
+
<span class="cline-any cline-yes">2x</span>
|
|
388
|
+
<span class="cline-any cline-yes">2x</span>
|
|
389
|
+
<span class="cline-any cline-yes">23x</span>
|
|
390
|
+
<span class="cline-any cline-neutral"> </span>
|
|
391
|
+
<span class="cline-any cline-neutral"> </span>
|
|
392
|
+
<span class="cline-any cline-yes">23x</span>
|
|
393
|
+
<span class="cline-any cline-yes">2x</span>
|
|
394
|
+
<span class="cline-any cline-yes">2x</span>
|
|
395
|
+
<span class="cline-any cline-neutral"> </span>
|
|
396
|
+
<span class="cline-any cline-yes">2x</span>
|
|
397
|
+
<span class="cline-any cline-yes">2x</span>
|
|
398
|
+
<span class="cline-any cline-yes">1x</span>
|
|
399
|
+
<span class="cline-any cline-yes">1x</span>
|
|
400
|
+
<span class="cline-any cline-neutral"> </span>
|
|
401
|
+
<span class="cline-any cline-yes">1x</span>
|
|
402
|
+
<span class="cline-any cline-yes">1x</span>
|
|
403
|
+
<span class="cline-any cline-yes">1x</span>
|
|
404
|
+
<span class="cline-any cline-yes">1x</span>
|
|
405
|
+
<span class="cline-any cline-yes">1x</span>
|
|
406
|
+
<span class="cline-any cline-yes">1x</span>
|
|
407
|
+
<span class="cline-any cline-yes">1x</span>
|
|
408
|
+
<span class="cline-any cline-yes">1x</span>
|
|
409
|
+
<span class="cline-any cline-neutral"> </span>
|
|
410
|
+
<span class="cline-any cline-neutral"> </span>
|
|
411
|
+
<span class="cline-any cline-yes">1x</span>
|
|
412
|
+
<span class="cline-any cline-yes">1x</span>
|
|
413
|
+
<span class="cline-any cline-yes">1x</span>
|
|
414
|
+
<span class="cline-any cline-yes">1x</span>
|
|
415
|
+
<span class="cline-any cline-yes">1x</span>
|
|
416
|
+
<span class="cline-any cline-yes">1x</span>
|
|
417
|
+
<span class="cline-any cline-yes">1x</span>
|
|
418
|
+
<span class="cline-any cline-yes">1x</span>
|
|
419
|
+
<span class="cline-any cline-yes">1x</span>
|
|
420
|
+
<span class="cline-any cline-yes">1x</span>
|
|
421
|
+
<span class="cline-any cline-neutral"> </span>
|
|
422
|
+
<span class="cline-any cline-yes">1x</span>
|
|
423
|
+
<span class="cline-any cline-yes">1x</span>
|
|
424
|
+
<span class="cline-any cline-yes">1x</span>
|
|
425
|
+
<span class="cline-any cline-yes">1x</span>
|
|
426
|
+
<span class="cline-any cline-yes">1x</span>
|
|
427
|
+
<span class="cline-any cline-yes">1x</span>
|
|
428
|
+
<span class="cline-any cline-yes">1x</span>
|
|
429
|
+
<span class="cline-any cline-yes">1x</span>
|
|
430
|
+
<span class="cline-any cline-neutral"> </span>
|
|
431
|
+
<span class="cline-any cline-yes">1x</span>
|
|
432
|
+
<span class="cline-any cline-yes">23x</span>
|
|
433
|
+
<span class="cline-any cline-neutral"> </span>
|
|
434
|
+
<span class="cline-any cline-neutral"> </span>
|
|
435
|
+
<span class="cline-any cline-yes">23x</span>
|
|
436
|
+
<span class="cline-any cline-neutral"> </span>
|
|
437
|
+
<span class="cline-any cline-yes">23x</span>
|
|
438
|
+
<span class="cline-any cline-yes">2x</span>
|
|
439
|
+
<span class="cline-any cline-yes">2x</span>
|
|
440
|
+
<span class="cline-any cline-yes">2x</span>
|
|
441
|
+
<span class="cline-any cline-yes">2x</span>
|
|
442
|
+
<span class="cline-any cline-yes">2x</span>
|
|
443
|
+
<span class="cline-any cline-yes">2x</span>
|
|
444
|
+
<span class="cline-any cline-yes">2x</span>
|
|
445
|
+
<span class="cline-any cline-yes">2x</span>
|
|
446
|
+
<span class="cline-any cline-yes">2x</span>
|
|
447
|
+
<span class="cline-any cline-neutral"> </span>
|
|
448
|
+
<span class="cline-any cline-yes">2x</span>
|
|
449
|
+
<span class="cline-any cline-yes">2x</span>
|
|
450
|
+
<span class="cline-any cline-yes">2x</span>
|
|
451
|
+
<span class="cline-any cline-neutral"> </span>
|
|
452
|
+
<span class="cline-any cline-yes">2x</span>
|
|
453
|
+
<span class="cline-any cline-yes">2x</span>
|
|
454
|
+
<span class="cline-any cline-neutral"> </span>
|
|
455
|
+
<span class="cline-any cline-yes">2x</span>
|
|
456
|
+
<span class="cline-any cline-yes">2x</span>
|
|
457
|
+
<span class="cline-any cline-yes">23x</span>
|
|
458
|
+
<span class="cline-any cline-neutral"> </span>
|
|
459
|
+
<span class="cline-any cline-neutral"> </span>
|
|
460
|
+
<span class="cline-any cline-yes">23x</span>
|
|
461
|
+
<span class="cline-any cline-yes">2x</span>
|
|
462
|
+
<span class="cline-any cline-yes">2x</span>
|
|
463
|
+
<span class="cline-any cline-neutral"> </span>
|
|
464
|
+
<span class="cline-any cline-yes">2x</span>
|
|
465
|
+
<span class="cline-any cline-yes">2x</span>
|
|
466
|
+
<span class="cline-any cline-yes">1x</span>
|
|
467
|
+
<span class="cline-any cline-yes">1x</span>
|
|
468
|
+
<span class="cline-any cline-neutral"> </span>
|
|
469
|
+
<span class="cline-any cline-neutral"> </span>
|
|
470
|
+
<span class="cline-any cline-yes">1x</span>
|
|
471
|
+
<span class="cline-any cline-yes">1x</span>
|
|
472
|
+
<span class="cline-any cline-yes">1x</span>
|
|
473
|
+
<span class="cline-any cline-neutral"> </span>
|
|
474
|
+
<span class="cline-any cline-yes">1x</span>
|
|
475
|
+
<span class="cline-any cline-yes">23x</span>
|
|
476
|
+
<span class="cline-any cline-neutral"> </span>
|
|
477
|
+
<span class="cline-any cline-neutral"> </span>
|
|
478
|
+
<span class="cline-any cline-yes">23x</span>
|
|
479
|
+
<span class="cline-any cline-neutral"> </span>
|
|
480
|
+
<span class="cline-any cline-neutral"> </span>
|
|
481
|
+
<span class="cline-any cline-neutral"> </span>
|
|
482
|
+
<span class="cline-any cline-neutral"> </span>
|
|
483
|
+
<span class="cline-any cline-neutral"> </span>
|
|
484
|
+
<span class="cline-any cline-neutral"> </span>
|
|
485
|
+
<span class="cline-any cline-neutral"> </span>
|
|
486
|
+
<span class="cline-any cline-neutral"> </span>
|
|
487
|
+
<span class="cline-any cline-yes">23x</span>
|
|
488
|
+
<span class="cline-any cline-yes">6x</span>
|
|
489
|
+
<span class="cline-any cline-yes">6x</span>
|
|
490
|
+
<span class="cline-any cline-yes">6x</span>
|
|
491
|
+
<span class="cline-any cline-neutral"> </span>
|
|
492
|
+
<span class="cline-any cline-yes">6x</span>
|
|
493
|
+
<span class="cline-any cline-yes">6x</span>
|
|
494
|
+
<span class="cline-any cline-yes">1x</span>
|
|
495
|
+
<span class="cline-any cline-yes">1x</span>
|
|
496
|
+
<span class="cline-any cline-neutral"> </span>
|
|
497
|
+
<span class="cline-any cline-yes">5x</span>
|
|
498
|
+
<span class="cline-any cline-yes">5x</span>
|
|
499
|
+
<span class="cline-any cline-yes">5x</span>
|
|
500
|
+
<span class="cline-any cline-neutral"> </span>
|
|
501
|
+
<span class="cline-any cline-yes">5x</span>
|
|
502
|
+
<span class="cline-any cline-neutral"> </span>
|
|
503
|
+
<span class="cline-any cline-yes">6x</span>
|
|
504
|
+
<span class="cline-any cline-yes">1x</span>
|
|
505
|
+
<span class="cline-any cline-yes">1x</span>
|
|
506
|
+
<span class="cline-any cline-yes">1x</span>
|
|
507
|
+
<span class="cline-any cline-yes">6x</span>
|
|
508
|
+
<span class="cline-any cline-yes">1x</span>
|
|
509
|
+
<span class="cline-any cline-yes">1x</span>
|
|
510
|
+
<span class="cline-any cline-yes">1x</span>
|
|
511
|
+
<span class="cline-any cline-yes">6x</span>
|
|
512
|
+
<span class="cline-any cline-yes">1x</span>
|
|
513
|
+
<span class="cline-any cline-yes">1x</span>
|
|
514
|
+
<span class="cline-any cline-yes">1x</span>
|
|
515
|
+
<span class="cline-any cline-yes">6x</span>
|
|
516
|
+
<span class="cline-any cline-yes">2x</span>
|
|
517
|
+
<span class="cline-any cline-yes">2x</span>
|
|
518
|
+
<span class="cline-any cline-yes">2x</span>
|
|
519
|
+
<span class="cline-any cline-yes">2x</span>
|
|
520
|
+
<span class="cline-any cline-yes">6x</span>
|
|
521
|
+
<span class="cline-any cline-no"> </span>
|
|
522
|
+
<span class="cline-any cline-no"> </span>
|
|
523
|
+
<span class="cline-any cline-no"> </span>
|
|
524
|
+
<span class="cline-any cline-no"> </span>
|
|
525
|
+
<span class="cline-any cline-neutral"> </span>
|
|
526
|
+
<span class="cline-any cline-yes">5x</span>
|
|
527
|
+
<span class="cline-any cline-neutral"> </span>
|
|
528
|
+
<span class="cline-any cline-neutral"> </span>
|
|
529
|
+
<span class="cline-any cline-yes">6x</span>
|
|
530
|
+
<span class="cline-any cline-yes">1x</span>
|
|
531
|
+
<span class="cline-any cline-yes">1x</span>
|
|
532
|
+
<span class="cline-any cline-yes">1x</span>
|
|
533
|
+
<span class="cline-any cline-neutral"> </span>
|
|
534
|
+
<span class="cline-any cline-yes">5x</span>
|
|
535
|
+
<span class="cline-any cline-yes">5x</span>
|
|
536
|
+
<span class="cline-any cline-yes">23x</span>
|
|
537
|
+
<span class="cline-any cline-neutral"> </span>
|
|
538
|
+
<span class="cline-any cline-neutral"> </span>
|
|
539
|
+
<span class="cline-any cline-yes">23x</span>
|
|
540
|
+
<span class="cline-any cline-yes">23x</span>
|
|
541
|
+
<span class="cline-any cline-yes">23x</span>
|
|
542
|
+
<span class="cline-any cline-yes">5x</span>
|
|
543
|
+
<span class="cline-any cline-yes">5x</span>
|
|
544
|
+
<span class="cline-any cline-yes">5x</span>
|
|
545
|
+
<span class="cline-any cline-yes">1x</span>
|
|
546
|
+
<span class="cline-any cline-yes">1x</span>
|
|
547
|
+
<span class="cline-any cline-neutral"> </span>
|
|
548
|
+
<span class="cline-any cline-yes">4x</span>
|
|
549
|
+
<span class="cline-any cline-yes">4x</span>
|
|
550
|
+
<span class="cline-any cline-yes">5x</span>
|
|
551
|
+
<span class="cline-any cline-yes">1x</span>
|
|
552
|
+
<span class="cline-any cline-yes">1x</span>
|
|
553
|
+
<span class="cline-any cline-yes">5x</span>
|
|
554
|
+
<span class="cline-any cline-yes">1x</span>
|
|
555
|
+
<span class="cline-any cline-yes">1x</span>
|
|
556
|
+
<span class="cline-any cline-neutral"> </span>
|
|
557
|
+
<span class="cline-any cline-yes">2x</span>
|
|
558
|
+
<span class="cline-any cline-neutral"> </span>
|
|
559
|
+
<span class="cline-any cline-yes">5x</span>
|
|
560
|
+
<span class="cline-any cline-yes">1x</span>
|
|
561
|
+
<span class="cline-any cline-yes">1x</span>
|
|
562
|
+
<span class="cline-any cline-neutral"> </span>
|
|
563
|
+
<span class="cline-any cline-neutral"> </span>
|
|
564
|
+
<span class="cline-any cline-yes">1x</span>
|
|
565
|
+
<span class="cline-any cline-neutral"> </span>
|
|
566
|
+
<span class="cline-any cline-neutral"> </span>
|
|
567
|
+
<span class="cline-any cline-yes">1x</span>
|
|
568
|
+
<span class="cline-any cline-yes">1x</span>
|
|
569
|
+
<span class="cline-any cline-neutral"> </span>
|
|
570
|
+
<span class="cline-any cline-neutral"> </span>
|
|
571
|
+
<span class="cline-any cline-yes">1x</span>
|
|
572
|
+
<span class="cline-any cline-neutral"> </span>
|
|
573
|
+
<span class="cline-any cline-yes">1x</span>
|
|
574
|
+
<span class="cline-any cline-yes">1x</span>
|
|
575
|
+
<span class="cline-any cline-yes">5x</span>
|
|
576
|
+
<span class="cline-any cline-yes">23x</span>
|
|
577
|
+
<span class="cline-any cline-neutral"> </span>
|
|
578
|
+
<span class="cline-any cline-neutral"> </span>
|
|
579
|
+
<span class="cline-any cline-yes">23x</span>
|
|
580
|
+
<span class="cline-any cline-yes">23x</span>
|
|
581
|
+
<span class="cline-any cline-yes">23x</span>
|
|
582
|
+
<span class="cline-any cline-yes">4x</span>
|
|
583
|
+
<span class="cline-any cline-yes">4x</span>
|
|
584
|
+
<span class="cline-any cline-yes">4x</span>
|
|
585
|
+
<span class="cline-any cline-yes">1x</span>
|
|
586
|
+
<span class="cline-any cline-yes">1x</span>
|
|
587
|
+
<span class="cline-any cline-neutral"> </span>
|
|
588
|
+
<span class="cline-any cline-yes">3x</span>
|
|
589
|
+
<span class="cline-any cline-yes">3x</span>
|
|
590
|
+
<span class="cline-any cline-yes">4x</span>
|
|
591
|
+
<span class="cline-any cline-yes">1x</span>
|
|
592
|
+
<span class="cline-any cline-yes">1x</span>
|
|
593
|
+
<span class="cline-any cline-neutral"> </span>
|
|
594
|
+
<span class="cline-any cline-yes">2x</span>
|
|
595
|
+
<span class="cline-any cline-neutral"> </span>
|
|
596
|
+
<span class="cline-any cline-yes">4x</span>
|
|
597
|
+
<span class="cline-any cline-yes">1x</span>
|
|
598
|
+
<span class="cline-any cline-yes">1x</span>
|
|
599
|
+
<span class="cline-any cline-neutral"> </span>
|
|
600
|
+
<span class="cline-any cline-neutral"> </span>
|
|
601
|
+
<span class="cline-any cline-yes">1x</span>
|
|
602
|
+
<span class="cline-any cline-yes">1x</span>
|
|
603
|
+
<span class="cline-any cline-yes">1x</span>
|
|
604
|
+
<span class="cline-any cline-neutral"> </span>
|
|
605
|
+
<span class="cline-any cline-yes">4x</span>
|
|
606
|
+
<span class="cline-any cline-yes">4x</span>
|
|
607
|
+
<span class="cline-any cline-neutral"> </span>
|
|
608
|
+
<span class="cline-any cline-yes">4x</span>
|
|
609
|
+
<span class="cline-any cline-yes">4x</span>
|
|
610
|
+
<span class="cline-any cline-yes">4x</span>
|
|
611
|
+
<span class="cline-any cline-yes">4x</span>
|
|
612
|
+
<span class="cline-any cline-yes">4x</span>
|
|
613
|
+
<span class="cline-any cline-yes">4x</span>
|
|
614
|
+
<span class="cline-any cline-yes">4x</span>
|
|
615
|
+
<span class="cline-any cline-yes">4x</span>
|
|
616
|
+
<span class="cline-any cline-yes">4x</span>
|
|
617
|
+
<span class="cline-any cline-yes">4x</span>
|
|
618
|
+
<span class="cline-any cline-neutral"> </span>
|
|
619
|
+
<span class="cline-any cline-neutral"> </span>
|
|
620
|
+
<span class="cline-any cline-yes">4x</span>
|
|
621
|
+
<span class="cline-any cline-yes">4x</span>
|
|
622
|
+
<span class="cline-any cline-yes">4x</span>
|
|
623
|
+
<span class="cline-any cline-neutral"> </span>
|
|
624
|
+
<span class="cline-any cline-yes">4x</span>
|
|
625
|
+
<span class="cline-any cline-yes">1x</span>
|
|
626
|
+
<span class="cline-any cline-yes">1x</span>
|
|
627
|
+
<span class="cline-any cline-yes">1x</span>
|
|
628
|
+
<span class="cline-any cline-neutral"> </span>
|
|
629
|
+
<span class="cline-any cline-yes">1x</span>
|
|
630
|
+
<span class="cline-any cline-yes">1x</span>
|
|
631
|
+
<span class="cline-any cline-yes">1x</span>
|
|
632
|
+
<span class="cline-any cline-yes">1x</span>
|
|
633
|
+
<span class="cline-any cline-yes">1x</span>
|
|
634
|
+
<span class="cline-any cline-yes">1x</span>
|
|
635
|
+
<span class="cline-any cline-yes">1x</span>
|
|
636
|
+
<span class="cline-any cline-yes">1x</span>
|
|
637
|
+
<span class="cline-any cline-yes">1x</span>
|
|
638
|
+
<span class="cline-any cline-yes">1x</span>
|
|
639
|
+
<span class="cline-any cline-yes">1x</span>
|
|
640
|
+
<span class="cline-any cline-yes">1x</span>
|
|
641
|
+
<span class="cline-any cline-yes">1x</span>
|
|
642
|
+
<span class="cline-any cline-neutral"> </span>
|
|
643
|
+
<span class="cline-any cline-neutral"> </span>
|
|
644
|
+
<span class="cline-any cline-yes">1x</span>
|
|
645
|
+
<span class="cline-any cline-yes">1x</span>
|
|
646
|
+
<span class="cline-any cline-yes">1x</span>
|
|
647
|
+
<span class="cline-any cline-yes">1x</span>
|
|
648
|
+
<span class="cline-any cline-yes">1x</span>
|
|
649
|
+
<span class="cline-any cline-yes">1x</span>
|
|
650
|
+
<span class="cline-any cline-yes">1x</span>
|
|
651
|
+
<span class="cline-any cline-neutral"> </span>
|
|
652
|
+
<span class="cline-any cline-yes">1x</span>
|
|
653
|
+
<span class="cline-any cline-yes">1x</span>
|
|
654
|
+
<span class="cline-any cline-yes">1x</span>
|
|
655
|
+
<span class="cline-any cline-yes">1x</span>
|
|
656
|
+
<span class="cline-any cline-yes">1x</span>
|
|
657
|
+
<span class="cline-any cline-yes">1x</span>
|
|
658
|
+
<span class="cline-any cline-yes">1x</span>
|
|
659
|
+
<span class="cline-any cline-yes">1x</span>
|
|
660
|
+
<span class="cline-any cline-yes">1x</span>
|
|
661
|
+
<span class="cline-any cline-yes">1x</span>
|
|
662
|
+
<span class="cline-any cline-yes">1x</span>
|
|
663
|
+
<span class="cline-any cline-yes">1x</span>
|
|
664
|
+
<span class="cline-any cline-neutral"> </span>
|
|
665
|
+
<span class="cline-any cline-yes">1x</span>
|
|
666
|
+
<span class="cline-any cline-yes">1x</span>
|
|
667
|
+
<span class="cline-any cline-yes">4x</span>
|
|
668
|
+
<span class="cline-any cline-yes">23x</span>
|
|
669
|
+
<span class="cline-any cline-yes">23x</span>
|
|
670
|
+
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import type { FastifyInstance } from 'fastify';
|
|
671
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
672
|
+
import { getDb } from '../db/index.ts';
|
|
673
|
+
import { clearThread } from '../codex/codex-provider.ts';
|
|
674
|
+
import type { Session, SessionDetail, Turn, Item } from '../db/schema.ts';
|
|
675
|
+
|
|
676
|
+
/** Raw DB row for turns — token_usage is a JSON string, not parsed; no items field. */
|
|
677
|
+
interface TurnRow extends Omit<Turn, 'token_usage' | 'items'> {
|
|
678
|
+
token_usage: string | null;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/** Raw DB row for items — data is a JSON string, not parsed. */
|
|
682
|
+
interface ItemRow extends Omit<Item, 'data'> {
|
|
683
|
+
data: string | null;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
export async function registerSessionRoutes(fastify: FastifyInstance): Promise<void> {
|
|
687
|
+
// GET /api/sessions — list all sessions
|
|
688
|
+
fastify.get('/api/sessions', async () => {
|
|
689
|
+
const rows = getDb().prepare('SELECT * FROM sessions ORDER BY created_at DESC').all() as Session[];
|
|
690
|
+
return rows;
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
// GET /api/sessions/:id — session with turns + items
|
|
694
|
+
fastify.get<{ Params: { id: string } }>('/api/sessions/:id', async (request, reply) => {
|
|
695
|
+
const { id } = request.params;
|
|
696
|
+
const db = getDb();
|
|
697
|
+
|
|
698
|
+
const session = db.prepare('SELECT * FROM sessions WHERE id = ?').get(id) as Session | undefined;
|
|
699
|
+
if (!session) {
|
|
700
|
+
return reply.code(404).send({ error: 'Session not found' });
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
const turnRows = db
|
|
704
|
+
.prepare('SELECT * FROM turns WHERE session_id = ? ORDER BY created_at ASC')
|
|
705
|
+
.all(id) as TurnRow[];
|
|
706
|
+
const itemRows = db
|
|
707
|
+
.prepare(
|
|
708
|
+
'SELECT * FROM items WHERE turn_id IN (SELECT id FROM turns WHERE session_id = ?) ORDER BY created_at ASC',
|
|
709
|
+
)
|
|
710
|
+
.all(id) as ItemRow[];
|
|
711
|
+
|
|
712
|
+
// Parse item data from JSON string and group by turn_id
|
|
713
|
+
const itemsByTurn = new Map<string, Item[]>();
|
|
714
|
+
for (const row of itemRows) {
|
|
715
|
+
const item: Item = {
|
|
716
|
+
...row,
|
|
717
|
+
data: row.data ? JSON.parse(row.data<span class="branch-0 cbranch-no" title="branch not covered" >) : null,</span>
|
|
718
|
+
};
|
|
719
|
+
const list = itemsByTurn.get(item.turn_id) ?? [];
|
|
720
|
+
list.push(item);
|
|
721
|
+
itemsByTurn.set(item.turn_id, list);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
const detail: SessionDetail = {
|
|
725
|
+
...session,
|
|
726
|
+
turns: turnRows.map((row) => ({
|
|
727
|
+
...row,
|
|
728
|
+
token_usage: row.<span class="branch-0 cbranch-no" title="branch not covered" >token_usage ? JSON.parse(row.token_usage) : n</span>ull,
|
|
729
|
+
items: itemsByTurn.get(row.id<span class="branch-0 cbranch-no" title="branch not covered" >) ?? [],</span>
|
|
730
|
+
})),
|
|
731
|
+
};
|
|
732
|
+
|
|
733
|
+
return detail;
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
// POST /api/sessions — create session
|
|
737
|
+
fastify.post<{
|
|
738
|
+
Body: { title?: string; runtime_type?: string; model?: string; model_reasoning_effort?: string; cwd?: string };
|
|
739
|
+
}>('/api/sessions', async (request) => {
|
|
740
|
+
const {
|
|
741
|
+
title = null,
|
|
742
|
+
runtime_type = 'codex',
|
|
743
|
+
model = null,
|
|
744
|
+
model_reasoning_effort = null,
|
|
745
|
+
cwd = null,
|
|
746
|
+
} = request.<span class="branch-0 cbranch-no" title="branch not covered" >body || {};</span>
|
|
747
|
+
const id = uuidv4();
|
|
748
|
+
const now = new Date().toISOString();
|
|
749
|
+
|
|
750
|
+
getDb()
|
|
751
|
+
.prepare(
|
|
752
|
+
`INSERT INTO sessions (id, title, runtime_type, model, model_reasoning_effort, cwd, external_thread_id, status, is_running, created_at, updated_at)
|
|
753
|
+
VALUES (?, ?, ?, ?, ?, ?, NULL, 'active', 0, ?, ?)`,
|
|
754
|
+
)
|
|
755
|
+
.run(id, title, runtime_type, model, model_reasoning_effort, cwd, now, now);
|
|
756
|
+
|
|
757
|
+
const session = getDb().prepare('SELECT * FROM sessions WHERE id = ?').get(id) as Session;
|
|
758
|
+
return session;
|
|
759
|
+
});
|
|
760
|
+
|
|
761
|
+
// DELETE /api/sessions/:id — delete session (cascade)
|
|
762
|
+
fastify.delete<{ Params: { id: string } }>('/api/sessions/:id', async (request, reply) => {
|
|
763
|
+
const { id } = request.params;
|
|
764
|
+
const db = getDb();
|
|
765
|
+
|
|
766
|
+
const existing = db.prepare('SELECT id FROM sessions WHERE id = ?').get(id);
|
|
767
|
+
if (!existing) {
|
|
768
|
+
return reply.code(404).send({ error: 'Session not found' });
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
// Delete items first (turns cascade via FK, but better-sqlite3 needs explicit cascade if pragma is set)
|
|
772
|
+
db.prepare('DELETE FROM items WHERE turn_id IN (SELECT id FROM turns WHERE session_id = ?)').run(id);
|
|
773
|
+
db.prepare('DELETE FROM turns WHERE session_id = ?').run(id);
|
|
774
|
+
db.prepare('DELETE FROM sessions WHERE id = ?').run(id);
|
|
775
|
+
|
|
776
|
+
return { success: true };
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
// PATCH /api/sessions/:id — update session (title, lifecycle, has_unreviewed, model, model_reasoning_effort)
|
|
780
|
+
fastify.patch<{
|
|
781
|
+
Params: { id: string };
|
|
782
|
+
Body: {
|
|
783
|
+
title?: string;
|
|
784
|
+
lifecycle?: string;
|
|
785
|
+
has_unreviewed?: number;
|
|
786
|
+
model?: string | null;
|
|
787
|
+
model_reasoning_effort?: string | null;
|
|
788
|
+
};
|
|
789
|
+
}>('/api/sessions/:id', async (request, reply) => {
|
|
790
|
+
const { id } = request.params;
|
|
791
|
+
const { title, lifecycle, has_unreviewed, model, model_reasoning_effort } = request.<span class="branch-0 cbranch-no" title="branch not covered" >body || {};</span>
|
|
792
|
+
const db = getDb();
|
|
793
|
+
|
|
794
|
+
const existing = db.prepare('SELECT * FROM sessions WHERE id = ?').get(id) as Session | undefined;
|
|
795
|
+
if (!existing) {
|
|
796
|
+
return reply.code(404).send({ error: 'Session not found' });
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
const now = new Date().toISOString();
|
|
800
|
+
const updates: string[] = ['updated_at = ?'];
|
|
801
|
+
const params: (string | number | null)[] = [now];
|
|
802
|
+
|
|
803
|
+
let modelChanged = false;
|
|
804
|
+
|
|
805
|
+
if (title !== undefined) {
|
|
806
|
+
updates.push('title = ?');
|
|
807
|
+
params.push(title);
|
|
808
|
+
}
|
|
809
|
+
if (lifecycle !== undefined) {
|
|
810
|
+
updates.push('lifecycle = ?');
|
|
811
|
+
params.push(lifecycle);
|
|
812
|
+
}
|
|
813
|
+
if (has_unreviewed !== undefined) {
|
|
814
|
+
updates.push('has_unreviewed = ?');
|
|
815
|
+
params.push(has_unreviewed);
|
|
816
|
+
}
|
|
817
|
+
if (model !== undefined) {
|
|
818
|
+
updates.push('model = ?');
|
|
819
|
+
params.push(model);
|
|
820
|
+
if (model !== existing.model) modelChanged = true;
|
|
821
|
+
}
|
|
822
|
+
if (model_reasoning_effort !== undefined) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
823
|
+
<span class="cstat-no" title="statement not covered" > updates.push('model_reasoning_effort = ?');</span>
|
|
824
|
+
<span class="cstat-no" title="statement not covered" > params.push(model_reasoning_effort);</span>
|
|
825
|
+
<span class="cstat-no" title="statement not covered" > if (model_reasoning_effort !== existing.model_reasoning_effort) modelChanged = true;</span>
|
|
826
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
827
|
+
|
|
828
|
+
db.prepare(`UPDATE sessions SET ${updates.join(', ')} WHERE id = ?`).run(...params, id);
|
|
829
|
+
|
|
830
|
+
// If model or reasoning effort changed, clear the cached thread so next turn uses new settings
|
|
831
|
+
if (modelChanged && existing.external_thread_id) {
|
|
832
|
+
db.prepare('UPDATE sessions SET external_thread_id = NULL, updated_at = ? WHERE id = ?').run(now, id);
|
|
833
|
+
clearThread(id);
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
const session = db.prepare('SELECT * FROM sessions WHERE id = ?').get(id) as Session;
|
|
837
|
+
return session;
|
|
838
|
+
});
|
|
839
|
+
|
|
840
|
+
// POST /api/sessions/:id/rewind — delete turns after target turn, reset Codex thread
|
|
841
|
+
fastify.post<{ Params: { id: string }; Body: { turn_id: string } }>(
|
|
842
|
+
'/api/sessions/:id/rewind',
|
|
843
|
+
async (request, reply) => {
|
|
844
|
+
const { id } = request.params;
|
|
845
|
+
const { turn_id } = request.<span class="branch-0 cbranch-no" title="branch not covered" >body || {};</span>
|
|
846
|
+
if (!turn_id) {
|
|
847
|
+
return reply.code(400).send({ error: 'turn_id is required' });
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
const db = getDb();
|
|
851
|
+
const session = db.prepare('SELECT * FROM sessions WHERE id = ?').get(id) as Session | undefined;
|
|
852
|
+
if (!session) {
|
|
853
|
+
return reply.code(404).send({ error: 'Session not found' });
|
|
854
|
+
}
|
|
855
|
+
if (session.is_running) {
|
|
856
|
+
return reply.code(409).send({ error: 'Cannot rewind while a turn is running' });
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
const targetTurn = db.prepare('SELECT created_at FROM turns WHERE id = ? AND session_id = ?').get(turn_id, id) as
|
|
860
|
+
{ created_at: string } | undefined;
|
|
861
|
+
if (!targetTurn) {
|
|
862
|
+
return reply.code(404).send({ error: 'Turn not found' });
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
// Delete turns after the target (cascade deletes items via FK)
|
|
866
|
+
db.prepare('DELETE FROM turns WHERE session_id = ? AND created_at > ?').run(id, targetTurn.created_at);
|
|
867
|
+
|
|
868
|
+
// Null out external_thread_id — next turn creates a fresh Codex thread
|
|
869
|
+
const now = new Date().toISOString();
|
|
870
|
+
db.prepare('UPDATE sessions SET external_thread_id = NULL, updated_at = ? WHERE id = ?').run(now, id);
|
|
871
|
+
|
|
872
|
+
// Clear in-memory thread entry
|
|
873
|
+
clearThread(id);
|
|
874
|
+
|
|
875
|
+
const updated = db.prepare('SELECT * FROM sessions WHERE id = ?').get(id) as Session;
|
|
876
|
+
return updated;
|
|
877
|
+
},
|
|
878
|
+
);
|
|
879
|
+
|
|
880
|
+
// POST /api/sessions/:id/branch — create new session with turns up to and including target turn
|
|
881
|
+
fastify.post<{ Params: { id: string }; Body: { turn_id: string; title?: string } }>(
|
|
882
|
+
'/api/sessions/:id/branch',
|
|
883
|
+
async (request, reply) => {
|
|
884
|
+
const { id } = request.params;
|
|
885
|
+
const { turn_id, title } = request.<span class="branch-0 cbranch-no" title="branch not covered" >body || {};</span>
|
|
886
|
+
if (!turn_id) {
|
|
887
|
+
return reply.code(400).send({ error: 'turn_id is required' });
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
const db = getDb();
|
|
891
|
+
const session = db.prepare('SELECT * FROM sessions WHERE id = ?').get(id) as Session | undefined;
|
|
892
|
+
if (!session) {
|
|
893
|
+
return reply.code(404).send({ error: 'Session not found' });
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
const targetTurn = db.prepare('SELECT created_at FROM turns WHERE id = ? AND session_id = ?').get(turn_id, id) as
|
|
897
|
+
{ created_at: string } | undefined;
|
|
898
|
+
if (!targetTurn) {
|
|
899
|
+
return reply.code(404).send({ error: 'Turn not found' });
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
// Create new session
|
|
903
|
+
const newSessionId = uuidv4();
|
|
904
|
+
const now = new Date().toISOString();
|
|
905
|
+
const newTitle = title || `Branch of ${session.<span class="branch-0 cbranch-no" title="branch not covered" >title || session.id.slice(0, 8)}</span>`;
|
|
906
|
+
|
|
907
|
+
db.prepare(
|
|
908
|
+
`INSERT INTO sessions (id, title, runtime_type, model, model_reasoning_effort, cwd, external_thread_id, status, is_running, lifecycle, has_unreviewed, created_at, updated_at)
|
|
909
|
+
VALUES (?, ?, ?, ?, ?, ?, NULL, 'active', 0, 'working', 0, ?, ?)`,
|
|
910
|
+
).run(
|
|
911
|
+
newSessionId,
|
|
912
|
+
newTitle,
|
|
913
|
+
session.runtime_type,
|
|
914
|
+
session.model,
|
|
915
|
+
session.model_reasoning_effort,
|
|
916
|
+
session.cwd,
|
|
917
|
+
now,
|
|
918
|
+
now,
|
|
919
|
+
);
|
|
920
|
+
|
|
921
|
+
// Copy turns up to and including the target turn
|
|
922
|
+
const turnRows = db
|
|
923
|
+
.prepare('SELECT * FROM turns WHERE session_id = ? AND created_at <= ? ORDER BY created_at ASC')
|
|
924
|
+
.all(id, targetTurn.created_at) as TurnRow[];
|
|
925
|
+
|
|
926
|
+
for (const turn of turnRows) {
|
|
927
|
+
const newTurnId = uuidv4();
|
|
928
|
+
db.prepare(
|
|
929
|
+
`INSERT INTO turns (id, session_id, user_prompt, agent_response, thoughts, token_usage, external_turn_id, status, error, created_at, updated_at)
|
|
930
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
931
|
+
).run(
|
|
932
|
+
newTurnId,
|
|
933
|
+
newSessionId,
|
|
934
|
+
turn.user_prompt,
|
|
935
|
+
turn.agent_response,
|
|
936
|
+
turn.thoughts,
|
|
937
|
+
turn.token_usage,
|
|
938
|
+
turn.external_turn_id,
|
|
939
|
+
turn.status,
|
|
940
|
+
turn.error,
|
|
941
|
+
turn.created_at,
|
|
942
|
+
turn.updated_at,
|
|
943
|
+
);
|
|
944
|
+
|
|
945
|
+
// Copy items for this turn
|
|
946
|
+
const itemRows = db
|
|
947
|
+
.prepare('SELECT * FROM items WHERE turn_id = ? ORDER BY created_at ASC')
|
|
948
|
+
.all(turn.id) as ItemRow[];
|
|
949
|
+
for (const item of itemRows) {
|
|
950
|
+
const newItemId = uuidv4();
|
|
951
|
+
db.prepare(
|
|
952
|
+
`INSERT INTO items (id, turn_id, external_item_id, type, data, status, created_at, updated_at)
|
|
953
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
954
|
+
).run(
|
|
955
|
+
newItemId,
|
|
956
|
+
newTurnId,
|
|
957
|
+
item.external_item_id,
|
|
958
|
+
item.type,
|
|
959
|
+
item.data,
|
|
960
|
+
item.status,
|
|
961
|
+
item.created_at,
|
|
962
|
+
item.updated_at,
|
|
963
|
+
);
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
const newSession = db.prepare('SELECT * FROM sessions WHERE id = ?').get(newSessionId) as Session;
|
|
968
|
+
return newSession;
|
|
969
|
+
},
|
|
970
|
+
);
|
|
971
|
+
}
|
|
972
|
+
</pre></td></tr></table></pre>
|
|
973
|
+
|
|
974
|
+
<div class='push'></div><!-- for sticky footer -->
|
|
975
|
+
</div><!-- /wrapper -->
|
|
976
|
+
<div class='footer quiet pad2 space-top1 center small'>
|
|
977
|
+
Code coverage generated by
|
|
978
|
+
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
979
|
+
at 2026-08-15T06:50:35.719Z
|
|
980
|
+
</div>
|
|
981
|
+
<script src="../../prettify.js"></script>
|
|
982
|
+
<script>
|
|
983
|
+
window.onload = function () {
|
|
984
|
+
prettyPrint();
|
|
985
|
+
};
|
|
986
|
+
</script>
|
|
987
|
+
<script src="../../sorter.js"></script>
|
|
988
|
+
<script src="../../block-navigation.js"></script>
|
|
989
|
+
</body>
|
|
990
|
+
</html>
|
|
991
|
+
|