@rejacky/opencode-insights 0.1.13 → 0.2.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.
package/README.md CHANGED
@@ -239,24 +239,30 @@ If SQLite is unavailable in the plugin runtime, the fallback path is:
239
239
  ~/.opencode-insights/insights.sqlite.jsonl
240
240
  ```
241
241
 
242
- The database keeps one day of captures by default and auto-cleans older rows on startup and after new captures. Set `retentionDays` to another number of days, or `0` to disable auto-cleaning.
242
+ The database keeps one day of captures by default and auto-cleans older rows on
243
+ startup and after new captures; `retentionDays` sets how many days to keep (`0`
244
+ disables auto-cleaning).
243
245
 
244
- You can override storage and retention in `opencode.json` or `opencode.jsonc`:
246
+ Storage settings live in the config file `~/.opencode-insights/config.jsonc` (JSONC
247
+ comments allowed). The plugin creates it on first run with `dbPath` commented out
248
+ (uncomment to relocate the database) and `retentionDays` defaulting to 1:
245
249
 
246
- ```json
250
+ ```jsonc
247
251
  {
248
- "plugin": [
249
- [
250
- "@rejacky/opencode-insights",
251
- {
252
- "dbPath": "/absolute/path/to/insights.sqlite",
253
- "retentionDays": 1
254
- }
255
- ]
256
- ]
252
+ // Database file. Default: ~/.opencode-insights/insights.sqlite
253
+ // "dbPath": "/absolute/path/to/insights.sqlite",
254
+ "retentionDays": 1,
255
+ "promptRightMetrics": ["tps", "avg", "used", "cache"],
256
+ "goUsage": { "enabled": false, "cookie": "", "workspaceID": "", "refreshMs": 300000 }
257
257
  }
258
258
  ```
259
259
 
260
+ A legacy `config.json` is still honored when `config.jsonc` does not exist. Plugin
261
+ params such as `{ "dbPath": … }` in `opencode.json` are ignored after the upgrade —
262
+ if you previously set `dbPath` or `retentionDays` there, copy those values into
263
+ `~/.opencode-insights/config.jsonc`. CLI commands read the configured database path
264
+ from this file; the former `--db`/`--data-dir`/`--retention-days` flags are removed.
265
+
260
266
  ## Privacy Model
261
267
 
262
268
  This plugin intentionally does not redact anything. It stores data locally exactly as OpenCode exposes it to plugin hooks and events.
@@ -110,11 +110,15 @@ type GoUsageConfig = {
110
110
  type InsightsConfig = {
111
111
  promptRightMetrics: PromptRightMetric[];
112
112
  goUsage: GoUsageConfig;
113
+ dbPath?: string | undefined;
114
+ retentionDays?: number | undefined;
113
115
  };
114
116
  declare function defaultDataDir(): string;
115
117
  declare function resolveCapturePath(options?: InsightsOptions): string;
116
118
  declare function resolveInsightsConfigPath(options?: InsightsOptions): string;
119
+ declare function resolveLegacyInsightsConfigPath(options?: InsightsOptions): string;
117
120
  declare function readInsightsConfig(options?: InsightsOptions): Promise<InsightsConfig>;
121
+ declare function insightsOptionsFromConfig(config: InsightsConfig, dataDir?: string): InsightsOptions;
118
122
  declare function normalizeChatMessageCapture(input: unknown, output: unknown, timestamp?: number): CaptureRecord;
119
123
  declare function normalizeChatParamsCapture(input: unknown, output: unknown, timestamp?: number): CaptureRecord;
120
124
  declare function normalizeChatHeadersCapture(input: unknown, output: unknown, timestamp?: number): CaptureRecord;
@@ -152,4 +156,4 @@ declare class SqliteCaptureStore implements CaptureStore {
152
156
  declare function createCaptureStore(options?: InsightsOptions): CaptureStore;
153
157
  declare function resolveRetentionDays(value: unknown): number;
154
158
 
155
- export { type AssistantResponseUsage as A, renderMetricsText as B, type CaptureRecord as C, DEFAULT_PROMPT_RIGHT_METRICS as D, renderPromptRightMetricsText as E, renderResponseMetricsText as F, type GoUsageConfig as G, renderSessionTokenUsage as H, type InsightsConfig as I, JsonlCaptureStore as J, resolveCapturePath as K, resolveInsightsConfigPath as L, type MessageTiming as M, resolveRetentionDays as N, type PromptRightMetric as P, type SessionAverage as S, type CaptureKind as a, type CaptureStore as b, type InsightsOptions as c, type MetricsState as d, type SessionTokenUsage as e, SqliteCaptureStore as f, type SqliteDb as g, type StreamSample as h, createCaptureStore as i, createMetricsState as j, defaultDataDir as k, estimateStreamTokens as l, extractEventType as m, getSessionTokenUsage as n, normalizeChatHeadersCapture as o, normalizeChatMessageCapture as p, normalizeChatParamsCapture as q, normalizeEventCapture as r, normalizeExperimentalChatMessagesTransformCapture as s, normalizeExperimentalChatSystemTransformCapture as t, normalizeToolCapture as u, openDatabase as v, readInsightsConfig as w, recordAssistantDelta as x, recordAssistantMessage as y, recordToolActivity as z };
159
+ export { type AssistantResponseUsage as A, recordToolActivity as B, type CaptureRecord as C, DEFAULT_PROMPT_RIGHT_METRICS as D, renderMetricsText as E, renderPromptRightMetricsText as F, type GoUsageConfig as G, renderResponseMetricsText as H, type InsightsConfig as I, JsonlCaptureStore as J, renderSessionTokenUsage as K, resolveCapturePath as L, type MessageTiming as M, resolveInsightsConfigPath as N, resolveLegacyInsightsConfigPath as O, type PromptRightMetric as P, resolveRetentionDays as Q, type SessionAverage as S, type CaptureKind as a, type CaptureStore as b, type InsightsOptions as c, type MetricsState as d, type SessionTokenUsage as e, SqliteCaptureStore as f, type SqliteDb as g, type StreamSample as h, createCaptureStore as i, createMetricsState as j, defaultDataDir as k, estimateStreamTokens as l, extractEventType as m, getSessionTokenUsage as n, insightsOptionsFromConfig as o, normalizeChatHeadersCapture as p, normalizeChatMessageCapture as q, normalizeChatParamsCapture as r, normalizeEventCapture as s, normalizeExperimentalChatMessagesTransformCapture as t, normalizeExperimentalChatSystemTransformCapture as u, normalizeToolCapture as v, openDatabase as w, readInsightsConfig as x, recordAssistantDelta as y, recordAssistantMessage as z };
@@ -266,6 +266,7 @@ import { mkdir, appendFile, readFile, writeFile } from "fs/promises";
266
266
  import { existsSync, readFileSync } from "fs";
267
267
  import { dirname, join } from "path";
268
268
  import { homedir } from "os";
269
+ import { parse } from "jsonc-parser";
269
270
  var DEFAULT_RETENTION_DAYS = 1;
270
271
  var DAY_MS = 24 * 60 * 60 * 1e3;
271
272
  var DEFAULT_GO_USAGE_REFRESH_MS = 3e5;
@@ -328,25 +329,55 @@ function resolveCapturePath(options = {}) {
328
329
  return join(dataDir, "insights.sqlite");
329
330
  }
330
331
  function resolveInsightsConfigPath(options = {}) {
331
- return join(dirname(resolveCapturePath(options)), "config.json");
332
+ return join(resolveConfigDataDir(options), "config.jsonc");
333
+ }
334
+ function resolveLegacyInsightsConfigPath(options = {}) {
335
+ return join(resolveConfigDataDir(options), "config.json");
336
+ }
337
+ function resolveConfigDataDir(options = {}) {
338
+ return typeof options.dataDir === "string" && options.dataDir.length > 0 ? options.dataDir : defaultDataDir();
332
339
  }
333
340
  async function readInsightsConfig(options = {}) {
334
- const path = resolveInsightsConfigPath(options);
335
- if (!existsSync(path)) {
336
- try {
337
- await mkdir(dirname(path), { recursive: true });
338
- await writeFile(path, `${JSON.stringify(defaultInsightsConfig(), null, 2)}
339
- `, "utf8");
340
- } catch {
341
- return defaultInsightsConfig();
342
- }
341
+ const jsoncPath = resolveInsightsConfigPath(options);
342
+ if (existsSync(jsoncPath)) {
343
+ return parseInsightsConfigFile(jsoncPath);
344
+ }
345
+ const legacyPath = resolveLegacyInsightsConfigPath(options);
346
+ if (existsSync(legacyPath)) {
347
+ return parseInsightsConfigFile(legacyPath);
343
348
  }
344
349
  try {
345
- return insightsConfigFrom(JSON.parse(await readFile(path, "utf8")));
350
+ await mkdir(dirname(jsoncPath), { recursive: true });
351
+ await writeFile(jsoncPath, defaultInsightsConfigJsonc(), "utf8");
352
+ } catch {
353
+ }
354
+ return defaultInsightsConfig();
355
+ }
356
+ async function parseInsightsConfigFile(path) {
357
+ try {
358
+ const parseErrors = [];
359
+ const parsed = parse(await readFile(path, "utf8"), parseErrors, { allowTrailingComma: true });
360
+ if (parseErrors.length > 0) return defaultInsightsConfig();
361
+ return insightsConfigFrom(parsed);
346
362
  } catch {
347
363
  return defaultInsightsConfig();
348
364
  }
349
365
  }
366
+ function defaultInsightsConfigJsonc() {
367
+ return [
368
+ "{",
369
+ " // Database file. Default: ~/.opencode-insights/insights.sqlite",
370
+ ' // "dbPath": "/absolute/path/to/insights.sqlite",',
371
+ ` "retentionDays": ${DEFAULT_RETENTION_DAYS},`,
372
+ ` "promptRightMetrics": ${JSON.stringify(DEFAULT_PROMPT_RIGHT_METRICS)},`,
373
+ ` "goUsage": ${JSON.stringify(defaultGoUsageConfig())}`,
374
+ "}",
375
+ ""
376
+ ].join("\n");
377
+ }
378
+ function insightsOptionsFromConfig(config, dataDir) {
379
+ return compactUndefined({ dataDir, dbPath: config.dbPath, retentionDays: config.retentionDays });
380
+ }
350
381
  function defaultInsightsConfig() {
351
382
  return { promptRightMetrics: [...DEFAULT_PROMPT_RIGHT_METRICS], goUsage: defaultGoUsageConfig() };
352
383
  }
@@ -356,9 +387,14 @@ function defaultGoUsageConfig() {
356
387
  function insightsConfigFrom(value) {
357
388
  const record = isRecord(value) ? value : {};
358
389
  const metrics = Array.isArray(record.promptRightMetrics) ? record.promptRightMetrics.filter(isPromptRightMetric) : [];
390
+ const dbPath = typeof record.dbPath === "string" && record.dbPath.trim().length > 0 ? record.dbPath.trim() : void 0;
391
+ const rawRetention = record.retentionDays;
392
+ const retentionDays = rawRetention === void 0 || rawRetention === null || rawRetention === "" ? void 0 : resolveRetentionDays(rawRetention);
359
393
  return {
360
394
  promptRightMetrics: metrics.length ? metrics : [...DEFAULT_PROMPT_RIGHT_METRICS],
361
- goUsage: goUsageConfigFrom(record.goUsage)
395
+ goUsage: goUsageConfigFrom(record.goUsage),
396
+ dbPath,
397
+ retentionDays
362
398
  };
363
399
  }
364
400
  function goUsageConfigFrom(value) {
@@ -708,7 +744,9 @@ export {
708
744
  defaultDataDir,
709
745
  resolveCapturePath,
710
746
  resolveInsightsConfigPath,
747
+ resolveLegacyInsightsConfigPath,
711
748
  readInsightsConfig,
749
+ insightsOptionsFromConfig,
712
750
  normalizeChatMessageCapture,
713
751
  normalizeChatParamsCapture,
714
752
  normalizeChatHeadersCapture,
package/dist/cli.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { C as CaptureRecord } from './capture-BpktoFGh.js';
2
+ import { C as CaptureRecord } from './capture-CwesXqmX.js';
3
3
 
4
4
  type HistoryMessage = {
5
5
  id: string;
@@ -72,10 +72,10 @@ type CliOptions = {
72
72
  port?: number | undefined;
73
73
  output?: string | undefined;
74
74
  configDir?: string | undefined;
75
- retentionDays?: number | undefined;
76
75
  dryRun: boolean;
77
76
  keepData: boolean;
78
77
  };
78
+ declare function unsupportedFlagWarning(arg: string): string | undefined;
79
79
  declare function parseOptions(args: string[]): CliOptions;
80
80
  declare function summarizeSessions(sessions: ReturnType<typeof buildRequestHistory>["sessions"]): {
81
81
  id: string;
@@ -95,4 +95,4 @@ declare function addUniquePlugin(config: JsonObject, plugin: string): boolean;
95
95
  declare function removePlugin(config: JsonObject, plugin: string): boolean;
96
96
  declare function uninstallOpenCode(options: CliOptions): Promise<string>;
97
97
 
98
- export { addUniquePlugin, configureOpenCodeDebug, defaultOpenCodeConfigDir, formatSessionSummary, parseOptions, removePlugin, resolveOpenCodeConfigPath, stripJsonCommentsAndTrailingCommas, summarizeSessions, uninstallOpenCode };
98
+ export { addUniquePlugin, configureOpenCodeDebug, defaultOpenCodeConfigDir, formatSessionSummary, parseOptions, removePlugin, resolveOpenCodeConfigPath, stripJsonCommentsAndTrailingCommas, summarizeSessions, uninstallOpenCode, unsupportedFlagWarning };
package/dist/cli.js CHANGED
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  openDatabase,
4
- resolveCapturePath
5
- } from "./chunk-RWPY5QOE.js";
4
+ readInsightsConfig,
5
+ resolveCapturePath,
6
+ resolveInsightsConfigPath
7
+ } from "./chunk-RZGCLQ2M.js";
6
8
 
7
9
  // src/cli.ts
8
10
  import { execFile as execFile2 } from "child_process";
@@ -1446,10 +1448,25 @@ var DEFAULT_HISTORY_LIMIT = 5e3;
1446
1448
  var SERVER_PLUGIN_SPEC = "@rejacky/opencode-insights";
1447
1449
  var TUI_PLUGIN_SPEC = SERVER_PLUGIN_SPEC;
1448
1450
  var SUBPATH_TUI_PLUGIN_SPEC = "@rejacky/opencode-insights/tui";
1451
+ function unsupportedFlagWarning(arg) {
1452
+ if (arg === "--data-dir") {
1453
+ return "warning: --data-dir is no longer supported; the CLI reads the configured database path from ~/.opencode-insights/config.jsonc";
1454
+ }
1455
+ const setting = arg === "--db" ? "dbPath" : arg === "--retention-days" ? "retentionDays" : void 0;
1456
+ if (!setting) return void 0;
1457
+ return `warning: ${arg} is no longer supported; set ${setting} in ~/.opencode-insights/config.jsonc`;
1458
+ }
1449
1459
  async function main(argv) {
1450
1460
  const command = argv[2] ?? "recent";
1461
+ for (const arg of argv.slice(3)) {
1462
+ const warning = unsupportedFlagWarning(arg);
1463
+ if (warning) process.stderr.write(`${warning}
1464
+ `);
1465
+ }
1451
1466
  const options = parseOptions(argv.slice(3));
1452
1467
  const positionals = parsePositionals(argv.slice(3));
1468
+ const config = await readInsightsConfig();
1469
+ options.dbPath = config.dbPath;
1453
1470
  if (command === "help" || command === "--help" || command === "-h") {
1454
1471
  process.stdout.write(`${usage()}
1455
1472
  `);
@@ -1553,14 +1570,6 @@ function parseOptions(args) {
1553
1570
  options.dryRun = true;
1554
1571
  } else if (arg === "--keep-data") {
1555
1572
  options.keepData = true;
1556
- } else if (arg === "--db") {
1557
- const value = args[index + 1];
1558
- if (value) options.dbPath = value;
1559
- index += 1;
1560
- } else if (arg === "--data-dir") {
1561
- const value = args[index + 1];
1562
- if (value) options.dataDir = value;
1563
- index += 1;
1564
1573
  } else if (arg === "--limit") {
1565
1574
  options.limit = Number.parseInt(args[index + 1] ?? "20", 10);
1566
1575
  options.limitProvided = true;
@@ -1580,16 +1589,10 @@ function parseOptions(args) {
1580
1589
  const value = args[index + 1];
1581
1590
  if (value) options.configDir = value;
1582
1591
  index += 1;
1583
- } else if (arg === "--retention-days") {
1584
- options.retentionDays = Number.parseFloat(args[index + 1] ?? "");
1585
- index += 1;
1586
1592
  }
1587
1593
  }
1588
1594
  if (!Number.isFinite(options.limit) || options.limit < 1) options.limit = DEFAULT_RECENT_LIMIT;
1589
1595
  if (options.port !== void 0 && (!Number.isFinite(options.port) || options.port < 1)) options.port = 8765;
1590
- if (options.retentionDays !== void 0 && (!Number.isFinite(options.retentionDays) || options.retentionDays < 0)) {
1591
- options.retentionDays = void 0;
1592
- }
1593
1596
  return options;
1594
1597
  }
1595
1598
  function parsePositionals(args) {
@@ -1732,7 +1735,7 @@ async function configureOpenCodeDebug(options) {
1732
1735
  const tuiSource = await readJsonConfigSource(tuiPath);
1733
1736
  const opencodeConfig = await readJsonConfig(opencodePath, { plugin: [] }, opencodeSource);
1734
1737
  const tuiConfig = await readJsonConfig(tuiPath, { plugin: [] }, tuiSource);
1735
- setSinglePluginSpec(opencodeConfig, SERVER_PLUGIN_SPEC, [localServerEntry, debugServerOptions(options)], localServerEntry);
1738
+ setSinglePluginSpec(opencodeConfig, SERVER_PLUGIN_SPEC, localServerEntry);
1736
1739
  setSinglePluginSpec(tuiConfig, TUI_PLUGIN_SPEC, localTuiEntry);
1737
1740
  removePlugin(tuiConfig, SUBPATH_TUI_PLUGIN_SPEC);
1738
1741
  const lines = [
@@ -1740,6 +1743,7 @@ async function configureOpenCodeDebug(options) {
1740
1743
  `TUI config: ${tuiPath}`,
1741
1744
  `Local server plugin: ${localServerEntry}`,
1742
1745
  `Local TUI plugin: ${localTuiEntry}`,
1746
+ `Insights config: ${resolveInsightsConfigPath({ dataDir: options.dataDir })}`,
1743
1747
  `Server plugin: set local build output`,
1744
1748
  `TUI plugin: set local build output`
1745
1749
  ];
@@ -1747,6 +1751,7 @@ async function configureOpenCodeDebug(options) {
1747
1751
  lines.push("Dry run: no files written.");
1748
1752
  return lines.join("\n");
1749
1753
  }
1754
+ await readInsightsConfig({ dataDir: options.dataDir });
1750
1755
  await mkdir(configDir, { recursive: true });
1751
1756
  await writeJsonConfig(opencodePath, opencodeConfig, opencodeSource);
1752
1757
  await writeJsonConfig(tuiPath, tuiConfig, tuiSource);
@@ -1826,11 +1831,6 @@ function stripJsonCommentsAndTrailingCommas(input) {
1826
1831
  function isJsonObject(value) {
1827
1832
  return !!value && typeof value === "object" && !Array.isArray(value);
1828
1833
  }
1829
- function debugServerOptions(options) {
1830
- const serverOptions = {};
1831
- if (options.retentionDays !== void 0) serverOptions.retentionDays = options.retentionDays;
1832
- return serverOptions;
1833
- }
1834
1834
  function addUniquePlugin(config, plugin) {
1835
1835
  const current = Array.isArray(config.plugin) ? config.plugin : [];
1836
1836
  if (current.includes(plugin)) {
@@ -1928,17 +1928,17 @@ async function writeJsonConfig(path, config, source) {
1928
1928
  function usage() {
1929
1929
  return [
1930
1930
  "Usage:",
1931
- " opencode-insights debug [--config-dir DIR] [--retention-days DAYS] [--dry-run]",
1932
- " opencode-insights uninstall [--config-dir DIR] [--db PATH] [--data-dir DIR] [--keep-data] [--dry-run]",
1933
- " opencode-insights recent [--db PATH] [--data-dir DIR] [--limit N] [--json]",
1934
- " opencode-insights sessions [--db PATH] [--data-dir DIR] [--limit N] [--json]",
1935
- " opencode-insights history [--db PATH] [--data-dir DIR] [--limit N]",
1936
- " opencode-insights show <session-id> [--db PATH] [--data-dir DIR] [--limit N]",
1937
- " opencode-insights export <session-id> [--output PATH] [--db PATH] [--data-dir DIR] [--limit N]",
1938
- " opencode-insights serve [--db PATH] [--data-dir DIR] [--limit N] [--host HOST] [--port PORT]",
1939
- " opencode-insights open [--db PATH] [--data-dir DIR] [--limit N] [--host HOST] [--port PORT]",
1940
- " opencode-insights doctor [--db PATH] [--data-dir DIR]",
1941
- " opencode-insights vacuum [--db PATH] [--data-dir DIR]"
1931
+ " opencode-insights debug [--config-dir DIR] [--dry-run]",
1932
+ " opencode-insights uninstall [--config-dir DIR] [--keep-data] [--dry-run]",
1933
+ " opencode-insights recent [--limit N] [--json]",
1934
+ " opencode-insights sessions [--limit N] [--json]",
1935
+ " opencode-insights history [--limit N]",
1936
+ " opencode-insights show <session-id> [--limit N]",
1937
+ " opencode-insights export <session-id> [--output PATH] [--limit N]",
1938
+ " opencode-insights serve [--limit N] [--host HOST] [--port PORT]",
1939
+ " opencode-insights open [--limit N] [--host HOST] [--port PORT]",
1940
+ " opencode-insights doctor",
1941
+ " opencode-insights vacuum"
1942
1942
  ].join("\n");
1943
1943
  }
1944
1944
  function isDirectRun() {
@@ -1967,5 +1967,6 @@ export {
1967
1967
  resolveOpenCodeConfigPath,
1968
1968
  stripJsonCommentsAndTrailingCommas,
1969
1969
  summarizeSessions,
1970
- uninstallOpenCode
1970
+ uninstallOpenCode,
1971
+ unsupportedFlagWarning
1971
1972
  };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Plugin } from '@opencode-ai/plugin';
2
2
  import { TuiPlugin } from '@opencode-ai/plugin/tui';
3
- export { A as AssistantResponseUsage, a as CaptureKind, C as CaptureRecord, b as CaptureStore, D as DEFAULT_PROMPT_RIGHT_METRICS, G as GoUsageConfig, I as InsightsConfig, c as InsightsOptions, J as JsonlCaptureStore, M as MessageTiming, d as MetricsState, P as PromptRightMetric, S as SessionAverage, e as SessionTokenUsage, f as SqliteCaptureStore, g as SqliteDb, h as StreamSample, i as createCaptureStore, j as createMetricsState, k as defaultDataDir, l as estimateStreamTokens, m as extractEventType, n as getSessionTokenUsage, o as normalizeChatHeadersCapture, p as normalizeChatMessageCapture, q as normalizeChatParamsCapture, r as normalizeEventCapture, s as normalizeExperimentalChatMessagesTransformCapture, t as normalizeExperimentalChatSystemTransformCapture, u as normalizeToolCapture, v as openDatabase, w as readInsightsConfig, x as recordAssistantDelta, y as recordAssistantMessage, z as recordToolActivity, B as renderMetricsText, E as renderPromptRightMetricsText, F as renderResponseMetricsText, H as renderSessionTokenUsage, K as resolveCapturePath, L as resolveInsightsConfigPath, N as resolveRetentionDays } from './capture-BpktoFGh.js';
3
+ export { A as AssistantResponseUsage, a as CaptureKind, C as CaptureRecord, b as CaptureStore, D as DEFAULT_PROMPT_RIGHT_METRICS, G as GoUsageConfig, I as InsightsConfig, c as InsightsOptions, J as JsonlCaptureStore, M as MessageTiming, d as MetricsState, P as PromptRightMetric, S as SessionAverage, e as SessionTokenUsage, f as SqliteCaptureStore, g as SqliteDb, h as StreamSample, i as createCaptureStore, j as createMetricsState, k as defaultDataDir, l as estimateStreamTokens, m as extractEventType, n as getSessionTokenUsage, o as insightsOptionsFromConfig, p as normalizeChatHeadersCapture, q as normalizeChatMessageCapture, r as normalizeChatParamsCapture, s as normalizeEventCapture, t as normalizeExperimentalChatMessagesTransformCapture, u as normalizeExperimentalChatSystemTransformCapture, v as normalizeToolCapture, w as openDatabase, x as readInsightsConfig, y as recordAssistantDelta, z as recordAssistantMessage, B as recordToolActivity, E as renderMetricsText, F as renderPromptRightMetricsText, H as renderResponseMetricsText, K as renderSessionTokenUsage, L as resolveCapturePath, N as resolveInsightsConfigPath, O as resolveLegacyInsightsConfigPath, Q as resolveRetentionDays } from './capture-CwesXqmX.js';
4
4
 
5
5
  type SubagentStatus = "running" | "done" | "error";
6
6
  type SubagentInfo = {
package/dist/index.js CHANGED
@@ -19,6 +19,7 @@ import {
19
19
  estimateStreamTokens,
20
20
  extractEventType,
21
21
  getSessionTokenUsage,
22
+ insightsOptionsFromConfig,
22
23
  normalizeChatHeadersCapture,
23
24
  normalizeChatMessageCapture,
24
25
  normalizeChatParamsCapture,
@@ -37,8 +38,9 @@ import {
37
38
  renderSessionTokenUsage,
38
39
  resolveCapturePath,
39
40
  resolveInsightsConfigPath,
41
+ resolveLegacyInsightsConfigPath,
40
42
  resolveRetentionDays
41
- } from "./chunk-RWPY5QOE.js";
43
+ } from "./chunk-RZGCLQ2M.js";
42
44
 
43
45
  // src/cli-shim.ts
44
46
  import { existsSync } from "fs";
@@ -91,7 +93,8 @@ var OpenCodeInsights = async (_input, options) => {
91
93
  if (options?.cliShim !== false) {
92
94
  void ensureCliShim().catch(() => void 0);
93
95
  }
94
- const store = createCaptureStore(options);
96
+ const config = await readInsightsConfig(options);
97
+ const store = createCaptureStore(insightsOptionsFromConfig(config, options?.dataDir));
95
98
  try {
96
99
  await store.initialize?.();
97
100
  } catch {
@@ -157,6 +160,7 @@ export {
157
160
  getSubagentSidebarModel,
158
161
  getSubagentSidebarRowAtLine,
159
162
  id,
163
+ insightsOptionsFromConfig,
160
164
  normalizeChatHeadersCapture,
161
165
  normalizeChatMessageCapture,
162
166
  normalizeChatParamsCapture,
@@ -179,6 +183,7 @@ export {
179
183
  renderSubagentStatus,
180
184
  resolveCapturePath,
181
185
  resolveInsightsConfigPath,
186
+ resolveLegacyInsightsConfigPath,
182
187
  resolveRetentionDays,
183
188
  server,
184
189
  rootTui as tui
package/dist/tui.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  recordToolActivity,
13
13
  renderPromptRightMetricsText,
14
14
  renderSessionTokenUsage
15
- } from "./chunk-RWPY5QOE.js";
15
+ } from "./chunk-RZGCLQ2M.js";
16
16
 
17
17
  // src/tui.tsx
18
18
  import { createTextAttributes, StyledText } from "@opentui/core";
@@ -85,9 +85,19 @@ function formatReset(seconds) {
85
85
  if (hours > 0) return minutes > 0 ? `${hours}h ${minutes}m` : `${hours}h`;
86
86
  return `${minutes}m`;
87
87
  }
88
+ var BLOCK_PARTIALS = ["", "\u258F", "\u258E", "\u258D", "\u258C", "\u258B", "\u258A", "\u2589"];
89
+ function formatUsageBar(usagePercent, width = 10) {
90
+ const percent = Math.max(0, Math.min(100, usagePercent));
91
+ const steps = width * 8;
92
+ const filled = Math.min(steps, Math.max(0, Math.round(percent / 100 * steps)));
93
+ const full = Math.floor(filled / 8);
94
+ const remainder = filled % 8;
95
+ const partial = BLOCK_PARTIALS[remainder] ?? "";
96
+ const empty = Math.max(0, width - full - (partial.length > 0 ? 1 : 0));
97
+ return "\u2588".repeat(full) + partial + "\u2591".repeat(empty);
98
+ }
88
99
  function formatGoUsageRow(row) {
89
- const fill = Math.min(4, Math.ceil(row.usagePercent / 25));
90
- const bar = "\u2588".repeat(fill) + "\u2591".repeat(4 - fill);
100
+ const bar = formatUsageBar(row.usagePercent);
91
101
  return `${row.label.padEnd(9)}${`${row.usagePercent}%`.padEnd(3)} ${bar} ${row.reset}`;
92
102
  }
93
103
  function goUsageSectionVisible(config, usesGoProvider) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@rejacky/opencode-insights",
4
- "version": "0.1.13",
4
+ "version": "0.2.0",
5
5
  "description": "OpenCode plugin for local request capture, TPS metrics, and subagent status visibility.",
6
6
  "type": "module",
7
7
  "author": "opencode-insights contributors",