@code-insights/cli 3.6.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +40 -4
  3. package/dashboard-dist/assets/index-D1JDyyu5.js +660 -0
  4. package/dashboard-dist/assets/index-kwbCW1n2.css +1 -0
  5. package/dashboard-dist/index.html +2 -2
  6. package/dist/commands/reflect.d.ts +3 -0
  7. package/dist/commands/reflect.d.ts.map +1 -0
  8. package/dist/commands/reflect.js +457 -0
  9. package/dist/commands/reflect.js.map +1 -0
  10. package/dist/commands/reset.d.ts.map +1 -1
  11. package/dist/commands/reset.js +3 -1
  12. package/dist/commands/reset.js.map +1 -1
  13. package/dist/commands/stats/actions/patterns.d.ts +3 -0
  14. package/dist/commands/stats/actions/patterns.d.ts.map +1 -0
  15. package/dist/commands/stats/actions/patterns.js +140 -0
  16. package/dist/commands/stats/actions/patterns.js.map +1 -0
  17. package/dist/commands/stats/data/aggregation-helpers.d.ts +23 -0
  18. package/dist/commands/stats/data/aggregation-helpers.d.ts.map +1 -0
  19. package/dist/commands/stats/data/aggregation-helpers.js +128 -0
  20. package/dist/commands/stats/data/aggregation-helpers.js.map +1 -0
  21. package/dist/commands/stats/data/aggregation.d.ts +3 -35
  22. package/dist/commands/stats/data/aggregation.d.ts.map +1 -1
  23. package/dist/commands/stats/data/aggregation.js +8 -290
  24. package/dist/commands/stats/data/aggregation.js.map +1 -1
  25. package/dist/commands/stats/data/time-series.d.ts +24 -0
  26. package/dist/commands/stats/data/time-series.d.ts.map +1 -0
  27. package/dist/commands/stats/data/time-series.js +162 -0
  28. package/dist/commands/stats/data/time-series.js.map +1 -0
  29. package/dist/commands/stats/index.d.ts.map +1 -1
  30. package/dist/commands/stats/index.js +7 -1
  31. package/dist/commands/stats/index.js.map +1 -1
  32. package/dist/commands/sync.d.ts +19 -0
  33. package/dist/commands/sync.d.ts.map +1 -1
  34. package/dist/commands/sync.js +67 -1
  35. package/dist/commands/sync.js.map +1 -1
  36. package/dist/constants/llm-providers.js +1 -1
  37. package/dist/constants/llm-providers.js.map +1 -1
  38. package/dist/db/client.d.ts +7 -0
  39. package/dist/db/client.d.ts.map +1 -1
  40. package/dist/db/client.js +11 -1
  41. package/dist/db/client.js.map +1 -1
  42. package/dist/db/migrate.d.ts +10 -1
  43. package/dist/db/migrate.d.ts.map +1 -1
  44. package/dist/db/migrate.js +96 -0
  45. package/dist/db/migrate.js.map +1 -1
  46. package/dist/db/read.d.ts +5 -0
  47. package/dist/db/read.d.ts.map +1 -1
  48. package/dist/db/read.js +20 -3
  49. package/dist/db/read.js.map +1 -1
  50. package/dist/db/schema.d.ts +1 -1
  51. package/dist/db/schema.js +2 -2
  52. package/dist/db/schema.js.map +1 -1
  53. package/dist/db/write.d.ts.map +1 -1
  54. package/dist/db/write.js +8 -2
  55. package/dist/db/write.js.map +1 -1
  56. package/dist/index.js +39 -3
  57. package/dist/index.js.map +1 -1
  58. package/dist/parser/jsonl.d.ts +19 -1
  59. package/dist/parser/jsonl.d.ts.map +1 -1
  60. package/dist/parser/jsonl.js +109 -3
  61. package/dist/parser/jsonl.js.map +1 -1
  62. package/dist/providers/codex.js +4 -1
  63. package/dist/providers/codex.js.map +1 -1
  64. package/dist/providers/copilot-cli.js +3 -0
  65. package/dist/providers/copilot-cli.js.map +1 -1
  66. package/dist/providers/copilot.js +3 -0
  67. package/dist/providers/copilot.js.map +1 -1
  68. package/dist/providers/cursor.js +3 -0
  69. package/dist/providers/cursor.js.map +1 -1
  70. package/dist/types.d.ts +109 -0
  71. package/dist/types.d.ts.map +1 -1
  72. package/dist/utils/date-utils.d.ts +6 -0
  73. package/dist/utils/date-utils.d.ts.map +1 -0
  74. package/dist/utils/date-utils.js +26 -0
  75. package/dist/utils/date-utils.js.map +1 -0
  76. package/dist/utils/telemetry.d.ts +1 -1
  77. package/dist/utils/telemetry.d.ts.map +1 -1
  78. package/dist/utils/telemetry.js.map +1 -1
  79. package/package.json +2 -1
  80. package/server-dist/export/agent-rules.d.ts.map +1 -1
  81. package/server-dist/export/agent-rules.js +15 -4
  82. package/server-dist/export/agent-rules.js.map +1 -1
  83. package/server-dist/export/knowledge-base.d.ts.map +1 -1
  84. package/server-dist/export/knowledge-base.js +30 -4
  85. package/server-dist/export/knowledge-base.js.map +1 -1
  86. package/server-dist/index.d.ts.map +1 -1
  87. package/server-dist/index.js +4 -0
  88. package/server-dist/index.js.map +1 -1
  89. package/server-dist/llm/analysis-db.d.ts +51 -0
  90. package/server-dist/llm/analysis-db.d.ts.map +1 -0
  91. package/server-dist/llm/analysis-db.js +208 -0
  92. package/server-dist/llm/analysis-db.js.map +1 -0
  93. package/server-dist/llm/analysis-internal.d.ts +36 -0
  94. package/server-dist/llm/analysis-internal.d.ts.map +1 -0
  95. package/server-dist/llm/analysis-internal.js +23 -0
  96. package/server-dist/llm/analysis-internal.js.map +1 -0
  97. package/server-dist/llm/analysis-pricing.d.ts +25 -0
  98. package/server-dist/llm/analysis-pricing.d.ts.map +1 -0
  99. package/server-dist/llm/analysis-pricing.js +74 -0
  100. package/server-dist/llm/analysis-pricing.js.map +1 -0
  101. package/server-dist/llm/analysis-usage-db.d.ts +45 -0
  102. package/server-dist/llm/analysis-usage-db.d.ts.map +1 -0
  103. package/server-dist/llm/analysis-usage-db.js +35 -0
  104. package/server-dist/llm/analysis-usage-db.js.map +1 -0
  105. package/server-dist/llm/analysis.d.ts +9 -79
  106. package/server-dist/llm/analysis.d.ts.map +1 -1
  107. package/server-dist/llm/analysis.js +119 -375
  108. package/server-dist/llm/analysis.js.map +1 -1
  109. package/server-dist/llm/facet-extraction.d.ts +14 -0
  110. package/server-dist/llm/facet-extraction.d.ts.map +1 -0
  111. package/server-dist/llm/facet-extraction.js +91 -0
  112. package/server-dist/llm/facet-extraction.js.map +1 -0
  113. package/server-dist/llm/friction-normalize.d.ts +16 -0
  114. package/server-dist/llm/friction-normalize.d.ts.map +1 -0
  115. package/server-dist/llm/friction-normalize.js +54 -0
  116. package/server-dist/llm/friction-normalize.js.map +1 -0
  117. package/server-dist/llm/index.d.ts +3 -2
  118. package/server-dist/llm/index.d.ts.map +1 -1
  119. package/server-dist/llm/index.js +1 -1
  120. package/server-dist/llm/index.js.map +1 -1
  121. package/server-dist/llm/message-format.d.ts +32 -0
  122. package/server-dist/llm/message-format.d.ts.map +1 -0
  123. package/server-dist/llm/message-format.js +129 -0
  124. package/server-dist/llm/message-format.js.map +1 -0
  125. package/server-dist/llm/normalize-utils.d.ts +22 -0
  126. package/server-dist/llm/normalize-utils.d.ts.map +1 -0
  127. package/server-dist/llm/normalize-utils.js +71 -0
  128. package/server-dist/llm/normalize-utils.js.map +1 -0
  129. package/server-dist/llm/pattern-normalize.d.ts +19 -0
  130. package/server-dist/llm/pattern-normalize.d.ts.map +1 -0
  131. package/server-dist/llm/pattern-normalize.js +90 -0
  132. package/server-dist/llm/pattern-normalize.js.map +1 -0
  133. package/server-dist/llm/prompt-constants.d.ts +9 -0
  134. package/server-dist/llm/prompt-constants.d.ts.map +1 -0
  135. package/server-dist/llm/prompt-constants.js +169 -0
  136. package/server-dist/llm/prompt-constants.js.map +1 -0
  137. package/server-dist/llm/prompt-quality-analysis.d.ts +8 -0
  138. package/server-dist/llm/prompt-quality-analysis.d.ts.map +1 -0
  139. package/server-dist/llm/prompt-quality-analysis.js +133 -0
  140. package/server-dist/llm/prompt-quality-analysis.js.map +1 -0
  141. package/server-dist/llm/prompt-quality-normalize.d.ts +26 -0
  142. package/server-dist/llm/prompt-quality-normalize.d.ts.map +1 -0
  143. package/server-dist/llm/prompt-quality-normalize.js +116 -0
  144. package/server-dist/llm/prompt-quality-normalize.js.map +1 -0
  145. package/server-dist/llm/prompt-types.d.ts +124 -0
  146. package/server-dist/llm/prompt-types.d.ts.map +1 -0
  147. package/server-dist/llm/prompt-types.js +4 -0
  148. package/server-dist/llm/prompt-types.js.map +1 -0
  149. package/server-dist/llm/prompts.d.ts +57 -100
  150. package/server-dist/llm/prompts.d.ts.map +1 -1
  151. package/server-dist/llm/prompts.js +606 -232
  152. package/server-dist/llm/prompts.js.map +1 -1
  153. package/server-dist/llm/providers/anthropic.d.ts.map +1 -1
  154. package/server-dist/llm/providers/anthropic.js +12 -0
  155. package/server-dist/llm/providers/anthropic.js.map +1 -1
  156. package/server-dist/llm/providers/gemini.d.ts.map +1 -1
  157. package/server-dist/llm/providers/gemini.js +10 -2
  158. package/server-dist/llm/providers/gemini.js.map +1 -1
  159. package/server-dist/llm/providers/ollama.d.ts.map +1 -1
  160. package/server-dist/llm/providers/ollama.js +3 -1
  161. package/server-dist/llm/providers/ollama.js.map +1 -1
  162. package/server-dist/llm/providers/openai.d.ts.map +1 -1
  163. package/server-dist/llm/providers/openai.js +4 -1
  164. package/server-dist/llm/providers/openai.js.map +1 -1
  165. package/server-dist/llm/recurring-insights.d.ts +26 -0
  166. package/server-dist/llm/recurring-insights.d.ts.map +1 -0
  167. package/server-dist/llm/recurring-insights.js +119 -0
  168. package/server-dist/llm/recurring-insights.js.map +1 -0
  169. package/server-dist/llm/reflect-prompts.d.ts +55 -0
  170. package/server-dist/llm/reflect-prompts.d.ts.map +1 -0
  171. package/server-dist/llm/reflect-prompts.js +151 -0
  172. package/server-dist/llm/reflect-prompts.js.map +1 -0
  173. package/server-dist/llm/response-parsers.d.ts +8 -0
  174. package/server-dist/llm/response-parsers.d.ts.map +1 -0
  175. package/server-dist/llm/response-parsers.js +151 -0
  176. package/server-dist/llm/response-parsers.js.map +1 -0
  177. package/server-dist/llm/types.d.ts +23 -1
  178. package/server-dist/llm/types.d.ts.map +1 -1
  179. package/server-dist/llm/types.js +10 -1
  180. package/server-dist/llm/types.js.map +1 -1
  181. package/server-dist/routes/analysis.d.ts.map +1 -1
  182. package/server-dist/routes/analysis.js +107 -282
  183. package/server-dist/routes/analysis.js.map +1 -1
  184. package/server-dist/routes/analytics.d.ts.map +1 -1
  185. package/server-dist/routes/analytics.js +3 -1
  186. package/server-dist/routes/analytics.js.map +1 -1
  187. package/server-dist/routes/export.d.ts.map +1 -1
  188. package/server-dist/routes/export.js +19 -27
  189. package/server-dist/routes/export.js.map +1 -1
  190. package/server-dist/routes/facets.d.ts +4 -0
  191. package/server-dist/routes/facets.d.ts.map +1 -0
  192. package/server-dist/routes/facets.js +208 -0
  193. package/server-dist/routes/facets.js.map +1 -0
  194. package/server-dist/routes/insights.d.ts.map +1 -1
  195. package/server-dist/routes/insights.js +12 -11
  196. package/server-dist/routes/insights.js.map +1 -1
  197. package/server-dist/routes/reflect.d.ts +4 -0
  198. package/server-dist/routes/reflect.d.ts.map +1 -0
  199. package/server-dist/routes/reflect.js +332 -0
  200. package/server-dist/routes/reflect.js.map +1 -0
  201. package/server-dist/routes/route-helpers.d.ts +124 -0
  202. package/server-dist/routes/route-helpers.d.ts.map +1 -0
  203. package/server-dist/routes/route-helpers.js +242 -0
  204. package/server-dist/routes/route-helpers.js.map +1 -0
  205. package/server-dist/routes/sessions.d.ts.map +1 -1
  206. package/server-dist/routes/sessions.js +29 -5
  207. package/server-dist/routes/sessions.js.map +1 -1
  208. package/server-dist/routes/shared-aggregation.d.ts +82 -0
  209. package/server-dist/routes/shared-aggregation.d.ts.map +1 -0
  210. package/server-dist/routes/shared-aggregation.js +384 -0
  211. package/server-dist/routes/shared-aggregation.js.map +1 -0
  212. package/dashboard-dist/assets/index-C1mDRV7y.js +0 -607
  213. package/dashboard-dist/assets/index-_SWpRg6C.css +0 -1
@@ -0,0 +1,242 @@
1
+ // Shared helpers for route files — eliminates duplicated SQL queries and LLM guard blocks.
2
+ // Centralising these here ensures the session/messages query columns stay in sync across
3
+ // analysis.ts, facets.ts, export.ts, and reflect.ts. If a new column is added to the
4
+ // sessions or messages tables it only needs updating in one place.
5
+ import { streamSSE } from 'hono/streaming';
6
+ import { getDb } from '@code-insights/cli/db/client';
7
+ import { trackEvent, captureError } from '@code-insights/cli/utils/telemetry';
8
+ import { isLLMConfigured, loadLLMConfig } from '../llm/client.js';
9
+ import { calculateAnalysisCost } from '../llm/analysis-pricing.js';
10
+ /**
11
+ * Load a session row for LLM analysis. Returns undefined if the session doesn't exist
12
+ * or has been soft-deleted. The selected columns match exactly what the analysis engine
13
+ * expects via the SessionData interface.
14
+ */
15
+ export function loadSessionForAnalysis(db, sessionId) {
16
+ return db.prepare(`
17
+ SELECT id, project_id, project_name, project_path, summary, ended_at,
18
+ compact_count, auto_compact_count, slash_commands
19
+ FROM sessions WHERE id = ? AND deleted_at IS NULL
20
+ `).get(sessionId);
21
+ }
22
+ /**
23
+ * Load all messages for a session, ordered by timestamp ascending.
24
+ * The selected columns match the SQLiteMessageRow interface consumed by the analysis engine.
25
+ */
26
+ export function loadSessionMessages(db, sessionId) {
27
+ return db.prepare(`
28
+ SELECT id, session_id, type, content, thinking, tool_calls, tool_results, usage, timestamp, parent_id
29
+ FROM messages WHERE session_id = ? ORDER BY timestamp ASC
30
+ `).all(sessionId);
31
+ }
32
+ /**
33
+ * Hono middleware factory that short-circuits with a 400 if no LLM provider is configured.
34
+ * Apply per-route: app.post('/route', requireLLM(), async (c) => { ... })
35
+ * The error shape { success: false, error: '...' } matches the analysis endpoint convention.
36
+ */
37
+ export function requireLLM() {
38
+ return async (c, next) => {
39
+ if (!isLLMConfigured()) {
40
+ return c.json({
41
+ success: false,
42
+ error: 'LLM not configured. Run `code-insights config llm` to configure a provider.',
43
+ }, 400);
44
+ }
45
+ await next();
46
+ };
47
+ }
48
+ /**
49
+ * Emit the 'analysis_run' telemetry event (and captureError on failure) for a
50
+ * completed analysis call. Encapsulates the boilerplate shared across the session,
51
+ * prompt-quality, and recurring handlers in analysis.ts.
52
+ *
53
+ * Usage:
54
+ * trackAnalysisResult('session', result, startTime, {
55
+ * onSuccess: () => trackEvent('insight_generated', { type: 'session', count: result.insights.length }),
56
+ * });
57
+ */
58
+ export function trackAnalysisResult(analysisType, result, startTime, options) {
59
+ const llmConfig = loadLLMConfig();
60
+ const baseProperties = {
61
+ type: analysisType,
62
+ llm_provider: llmConfig?.provider,
63
+ llm_model: llmConfig?.model,
64
+ duration_ms: Date.now() - startTime,
65
+ success: result.success,
66
+ };
67
+ if (!result.success) {
68
+ const errorProperties = {
69
+ ...baseProperties,
70
+ error_type: result.error_type,
71
+ error_message: result.error,
72
+ response_preview: result.response_preview,
73
+ };
74
+ trackEvent('analysis_run', errorProperties);
75
+ captureError(new Error(result.error ?? `${analysisType} analysis failed`), errorProperties);
76
+ }
77
+ else {
78
+ trackEvent('analysis_run', baseProperties);
79
+ options?.onSuccess?.();
80
+ }
81
+ }
82
+ /**
83
+ * Shared SSE lifecycle for single-session analysis stream endpoints.
84
+ * Handles the streamSSE wrapper, abort signal, progress events, result telemetry,
85
+ * and complete/error SSE events. The two analysis stream handlers (session and
86
+ * prompt-quality) differed only in their progress message and analysis function —
87
+ * those are injected via options.
88
+ *
89
+ * Preserves the exact SSE event names and complete/error payload shapes the
90
+ * dashboard expects: progress → { phase, message, ...progress }, complete →
91
+ * { success, insightCount, tokenUsage }, error → { error }.
92
+ */
93
+ export function streamSessionAnalysis(c, session, messages, opts) {
94
+ const llmConfig = loadLLMConfig();
95
+ return streamSSE(c, async (stream) => {
96
+ const streamStart = Date.now();
97
+ try {
98
+ const abortSignal = c.req.raw.signal;
99
+ await stream.writeSSE({
100
+ event: 'progress',
101
+ data: JSON.stringify({ phase: 'loading_messages', message: 'Loading messages...' }),
102
+ });
103
+ const result = await opts.analysisFn(session, messages, {
104
+ signal: abortSignal,
105
+ onProgress: (progress) => {
106
+ const message = opts.progressMessage(progress);
107
+ void stream.writeSSE({
108
+ event: 'progress',
109
+ data: JSON.stringify({ ...progress, message }),
110
+ }).catch(() => { });
111
+ },
112
+ });
113
+ const baseProperties = {
114
+ type: opts.analysisType,
115
+ llm_provider: llmConfig?.provider,
116
+ llm_model: llmConfig?.model,
117
+ duration_ms: Date.now() - streamStart,
118
+ success: result.success,
119
+ };
120
+ if (!result.success) {
121
+ const errorProperties = {
122
+ ...baseProperties,
123
+ error_type: result.error_type,
124
+ error_message: result.error,
125
+ response_preview: result.response_preview,
126
+ };
127
+ trackEvent('analysis_run', errorProperties);
128
+ captureError(new Error(result.error ?? `${opts.analysisType} stream failed`), errorProperties);
129
+ await stream.writeSSE({
130
+ event: 'error',
131
+ data: JSON.stringify({ error: result.error ?? `${opts.analysisType} analysis failed` }),
132
+ });
133
+ }
134
+ else {
135
+ trackEvent('analysis_run', baseProperties);
136
+ opts.onSuccess?.(result);
137
+ // Compute cost from token usage for the SSE complete event.
138
+ // The actual cost was already persisted to analysis_usage by the analysis function.
139
+ // This includes it in the SSE payload so the dashboard can display it immediately
140
+ // without an extra round-trip to GET /api/analysis/usage.
141
+ const costUsd = result.usage && llmConfig
142
+ ? calculateAnalysisCost(llmConfig.provider, llmConfig.model, {
143
+ inputTokens: result.usage.inputTokens,
144
+ outputTokens: result.usage.outputTokens,
145
+ cacheCreationTokens: result.usage.cacheCreationTokens,
146
+ cacheReadTokens: result.usage.cacheReadTokens,
147
+ })
148
+ : 0;
149
+ await stream.writeSSE({
150
+ event: 'complete',
151
+ data: JSON.stringify({
152
+ success: true,
153
+ insightCount: result.insights.length,
154
+ tokenUsage: result.usage,
155
+ costUsd,
156
+ provider: llmConfig?.provider,
157
+ model: llmConfig?.model,
158
+ }),
159
+ });
160
+ }
161
+ }
162
+ catch (err) {
163
+ const message = err instanceof Error ? err.message : 'Unknown error';
164
+ // Normalize hyphens to underscores so 'prompt-quality_stream' becomes
165
+ // 'prompt_quality_stream' — matching the original per-handler telemetry strings.
166
+ const telemetryType = opts.analysisType.replace(/-/g, '_');
167
+ captureError(err, {
168
+ type: `${telemetryType}_stream`,
169
+ llm_provider: llmConfig?.provider,
170
+ llm_model: llmConfig?.model,
171
+ });
172
+ await stream.writeSSE({
173
+ event: 'error',
174
+ data: JSON.stringify({ error: message }),
175
+ }).catch(() => { });
176
+ }
177
+ });
178
+ }
179
+ /**
180
+ * Shared SSE lifecycle for batch backfill endpoints (facets backfill and PQ backfill).
181
+ * Iterates sessionIds one-by-one, streaming per-session progress events and a final
182
+ * complete event. Preserves the exact SSE payload shapes the dashboard expects:
183
+ * progress → { completed, failed, total, currentSessionId, error? }
184
+ * complete → { completed, failed, total }
185
+ *
186
+ * The caller is responsible for request body validation (sessionIds array present,
187
+ * length ≤ MAX_BACKFILL_SESSIONS) before calling this helper.
188
+ */
189
+ export function streamBatchBackfill(c, sessionIds, force, opts) {
190
+ const db = getDb();
191
+ return streamSSE(c, async (stream) => {
192
+ const abortSignal = c.req.raw.signal;
193
+ let completed = 0;
194
+ let failed = 0;
195
+ const total = sessionIds.length;
196
+ for (const sessionId of sessionIds) {
197
+ if (abortSignal.aborted)
198
+ break;
199
+ const session = loadSessionForAnalysis(db, sessionId);
200
+ if (!session) {
201
+ failed++;
202
+ await stream.writeSSE({
203
+ event: 'progress',
204
+ data: JSON.stringify({ completed, failed, total, currentSessionId: sessionId }),
205
+ });
206
+ continue;
207
+ }
208
+ // Skip sessions that already have work done unless force=true.
209
+ if (!force && opts.shouldSkip(sessionId)) {
210
+ completed++;
211
+ await stream.writeSSE({
212
+ event: 'progress',
213
+ data: JSON.stringify({ completed, failed, total, currentSessionId: sessionId }),
214
+ });
215
+ continue;
216
+ }
217
+ const messages = loadSessionMessages(db, sessionId);
218
+ const result = await opts.analysisFn(session, messages, { signal: abortSignal });
219
+ if (result.success) {
220
+ completed++;
221
+ }
222
+ else {
223
+ failed++;
224
+ }
225
+ await stream.writeSSE({
226
+ event: 'progress',
227
+ data: JSON.stringify({
228
+ completed,
229
+ failed,
230
+ total,
231
+ currentSessionId: sessionId,
232
+ ...(result.success ? {} : { error: result.error }),
233
+ }),
234
+ });
235
+ }
236
+ await stream.writeSSE({
237
+ event: 'complete',
238
+ data: JSON.stringify({ completed, failed, total }),
239
+ });
240
+ });
241
+ }
242
+ //# sourceMappingURL=route-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-helpers.js","sourceRoot":"","sources":["../../src/routes/route-helpers.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/routes/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,QAAA,MAAM,GAAG,4EAAa,CAAC;AAqEvB,eAAe,GAAG,CAAC"}
1
+ {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/routes/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,QAAA,MAAM,GAAG,4EAAa,CAAC;AAkGvB,eAAe,GAAG,CAAC"}
@@ -15,7 +15,8 @@ app.get('/', (c) => {
15
15
  conditions.push('source_tool = ?');
16
16
  params.push(sourceTool);
17
17
  }
18
- const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
18
+ conditions.push('deleted_at IS NULL');
19
+ const where = `WHERE ${conditions.join(' AND ')}`;
19
20
  const sessions = db.prepare(`
20
21
  SELECT id, project_id, project_name, project_path, git_remote_url,
21
22
  summary, custom_title, generated_title, title_source, session_character,
@@ -24,7 +25,8 @@ app.get('/', (c) => {
24
25
  claude_version, source_tool, device_id, device_hostname,
25
26
  device_platform, synced_at, total_input_tokens, total_output_tokens,
26
27
  cache_creation_tokens, cache_read_tokens, estimated_cost_usd,
27
- models_used, primary_model, usage_source
28
+ models_used, primary_model, usage_source,
29
+ compact_count, auto_compact_count, slash_commands
28
30
  FROM sessions
29
31
  ${where}
30
32
  ORDER BY started_at DESC
@@ -32,6 +34,20 @@ app.get('/', (c) => {
32
34
  `).all(...params, parseIntParam(limit, 50), parseIntParam(offset, 0));
33
35
  return c.json({ sessions });
34
36
  });
37
+ // GET /api/sessions/deleted/count — count of soft-deleted sessions for a project
38
+ // IMPORTANT: registered before /:id so "deleted" isn't matched as a session ID
39
+ app.get('/deleted/count', (c) => {
40
+ const db = getDb();
41
+ const { projectId } = c.req.query();
42
+ let row;
43
+ if (projectId) {
44
+ row = db.prepare(`SELECT COUNT(*) AS count FROM sessions WHERE deleted_at IS NOT NULL AND project_id = ?`).get(projectId);
45
+ }
46
+ else {
47
+ row = db.prepare(`SELECT COUNT(*) AS count FROM sessions WHERE deleted_at IS NOT NULL`).get();
48
+ }
49
+ return c.json({ count: row.count });
50
+ });
35
51
  app.get('/:id', (c) => {
36
52
  const db = getDb();
37
53
  const session = db.prepare(`
@@ -42,8 +58,9 @@ app.get('/:id', (c) => {
42
58
  claude_version, source_tool, device_id, device_hostname,
43
59
  device_platform, synced_at, total_input_tokens, total_output_tokens,
44
60
  cache_creation_tokens, cache_read_tokens, estimated_cost_usd,
45
- models_used, primary_model, usage_source
46
- FROM sessions WHERE id = ?
61
+ models_used, primary_model, usage_source,
62
+ compact_count, auto_compact_count, slash_commands
63
+ FROM sessions WHERE id = ? AND deleted_at IS NULL
47
64
  `).get(c.req.param('id'));
48
65
  if (!session)
49
66
  return c.json({ error: 'Not found' }, 404);
@@ -56,7 +73,14 @@ app.patch('/:id', async (c) => {
56
73
  if (customTitle === undefined) {
57
74
  return c.json({ error: 'customTitle is required' }, 400);
58
75
  }
59
- const result = db.prepare('UPDATE sessions SET custom_title = ? WHERE id = ?').run(customTitle || null, c.req.param('id'));
76
+ const result = db.prepare('UPDATE sessions SET custom_title = ? WHERE id = ? AND deleted_at IS NULL').run(customTitle || null, c.req.param('id'));
77
+ if (result.changes === 0)
78
+ return c.json({ error: 'Not found' }, 404);
79
+ return c.json({ ok: true });
80
+ });
81
+ app.delete('/:id', (c) => {
82
+ const db = getDb();
83
+ const result = db.prepare(`UPDATE sessions SET deleted_at = datetime('now') WHERE id = ? AND deleted_at IS NULL`).run(c.req.param('id'));
60
84
  if (result.changes === 0)
61
85
  return c.json({ error: 'Not found' }, 404);
62
86
  return c.json({ ok: true });
@@ -1 +1 @@
1
- {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/routes/sessions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/routes/sessions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ import { getDb } from '@code-insights/cli/db/client';
2
+ /**
3
+ * Parse an ISO week string (YYYY-WNN) into UTC Monday/Sunday boundaries.
4
+ * Returns { start: Monday 00:00 UTC, end: next Monday 00:00 UTC } (exclusive end).
5
+ *
6
+ * ISO 8601 week rules: week 1 contains the first Thursday of the year,
7
+ * weeks start on Monday. We use the "Thursday trick": Jan 4 is always
8
+ * in week 1, so we find that Monday, then step to the target week.
9
+ */
10
+ export declare function parseIsoWeek(weekStr: string): {
11
+ start: Date;
12
+ end: Date;
13
+ } | null;
14
+ /**
15
+ * Format a Date (representing a Monday) as an ISO week string (YYYY-WNN).
16
+ * Used when generating week inventory from a list of Mondays.
17
+ */
18
+ export declare function formatIsoWeek(monday: Date): string;
19
+ export declare function buildPeriodFilter(period: string): string | null;
20
+ export declare function buildWhereClause(period: string, project?: string, source?: string): {
21
+ where: string;
22
+ params: (string | number)[];
23
+ };
24
+ export interface AggregatedFrictionCategory {
25
+ category: string;
26
+ count: number;
27
+ avg_severity: number;
28
+ examples: string[];
29
+ }
30
+ export interface AggregatedEffectivePattern {
31
+ category: string;
32
+ label: string;
33
+ frequency: number;
34
+ avg_confidence: number;
35
+ descriptions: string[];
36
+ drivers: Record<string, number>;
37
+ }
38
+ export interface AggregatedPQCategory {
39
+ category: string;
40
+ label: string;
41
+ count: number;
42
+ }
43
+ export interface RateLimitInfo {
44
+ count: number;
45
+ sessionsAffected: number;
46
+ examples: string[];
47
+ }
48
+ export interface AggregatedData {
49
+ frictionCategories: AggregatedFrictionCategory[];
50
+ effectivePatterns: AggregatedEffectivePattern[];
51
+ outcomeDistribution: Record<string, number>;
52
+ workflowDistribution: Record<string, number>;
53
+ characterDistribution: Record<string, number>;
54
+ totalSessions: number;
55
+ frictionTotal: number;
56
+ totalAllSessions: number;
57
+ rateLimitInfo: RateLimitInfo | null;
58
+ streak: number;
59
+ sourceToolCount: number;
60
+ pqDeficits: AggregatedPQCategory[];
61
+ pqStrengths: AggregatedPQCategory[];
62
+ }
63
+ /**
64
+ * Run all aggregation queries needed for facet analysis and synthesis.
65
+ * Aggregation is done in code (SQL), not by LLMs — LLMs synthesize, they don't count.
66
+ *
67
+ * project and source are passed separately so streak can build its own
68
+ * period-free where clause (streak measures continuity across all time).
69
+ */
70
+ export declare function getAggregatedData(db: ReturnType<typeof getDb>, where: string, params: (string | number)[], project?: string, source?: string): AggregatedData;
71
+ /**
72
+ * Aggregate prompt quality findings from the insights table for the given scope.
73
+ * Returns deficits and strengths as separate arrays, pre-filtered to count >= 2.
74
+ * Count is session-level (unique session IDs), not finding-level — more honest signal.
75
+ *
76
+ * Uses the same where/params scope as getAggregatedData so period/project/source filters apply.
77
+ */
78
+ export declare function aggregatePQFindings(db: ReturnType<typeof getDb>, where: string, params: (string | number)[]): {
79
+ pqDeficits: AggregatedPQCategory[];
80
+ pqStrengths: AggregatedPQCategory[];
81
+ };
82
+ //# sourceMappingURL=shared-aggregation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-aggregation.d.ts","sourceRoot":"","sources":["../../src/routes/shared-aggregation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AASrD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,IAAI,CAAA;CAAE,GAAG,IAAI,CAoB/E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,IAAI,GAAG,MAAM,CAclD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM/D;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GACd;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;CAAE,CAiChD;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,kBAAkB,EAAE,0BAA0B,EAAE,CAAC;IACjD,iBAAiB,EAAE,0BAA0B,EAAE,CAAC;IAChD,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,oBAAoB,EAAE,CAAC;IACnC,WAAW,EAAE,oBAAoB,EAAE,CAAC;CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,UAAU,CAAC,OAAO,KAAK,CAAC,EAC5B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAC3B,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GACd,cAAc,CAgQhB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,UAAU,CAAC,OAAO,KAAK,CAAC,EAC5B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAC1B;IAAE,UAAU,EAAE,oBAAoB,EAAE,CAAC;IAAC,WAAW,EAAE,oBAAoB,EAAE,CAAA;CAAE,CAyC7E"}