@mtayfur/opencode-cache-view 0.0.4 → 1.0.2

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 (3) hide show
  1. package/README.md +6 -4
  2. package/dist/index.js +17 -18
  3. package/package.json +7 -6
package/README.md CHANGED
@@ -28,7 +28,7 @@ customize-opencode 3.1K tok
28
28
 
29
29
  - **Cache:** `Hit` is `cache.read / (input + cache.read + cache.write)` for the latest regular LLM step. `Session Hit` is the aggregate OpenCode session ratio, including compaction calls. `Miss` combines uncached input and cache writes.
30
30
  - **Estimated Tokens:** Uses one character-based estimator for the visible system, user, tool, reasoning, and output content from the latest completed compaction summary, its preserved tail, and subsequent messages loaded in the TUI. Provider system prompts, tool schemas, and media tokens are not included.
31
- - **Speed:** During streaming, `TPS` shows a `~`-prefixed estimate from visible text and reasoning deltas over the latest five seconds. Hidden reasoning with no deltas uses the current turn's cumulative rate when available, otherwise the previous completed turn, or remains `… tok/s` when neither exists. Completed model steps accumulate `(output + reasoning)` tokens and full step duration across tool calls, excluding tool execution time. The cumulative rate remains `~`-prefixed while the turn is incomplete; the final non-tool-call step replaces it with the exact weighted turn throughput. `TTFT` retains the estimated delay to the first visible reasoning or text block, and `Trend` shows the latest eight completed-turn TPS values.
31
+ - **Speed:** During streaming, `TPS` shows a `~`-prefixed estimate from visible text and reasoning deltas over the latest five seconds. Hidden reasoning with no deltas uses the previous completed turn or remains `… tok/s` when none exists. Completed tool-call steps and tool execution time are excluded. The rate remains `~`-prefixed while the turn is incomplete; the final non-tool-call assistant step replaces it with exact `(output + reasoning) / duration` throughput. `TTFT` retains the estimated delay to the first visible reasoning or text block, and `Trend` shows the latest eight completed-turn TPS values.
32
32
  - **Loaded Skills:** Shows active, non-compacted skill outputs and their estimated token counts. When a skill is loaded more than once, the latest load is shown.
33
33
 
34
34
  Rows and the cache-hit bar adapt to the available sidebar width. The arrow next to the hit rate compares the latest two LLM steps. Sections can be expanded or collapsed with the mouse.
@@ -88,9 +88,11 @@ Metric calculations are isolated from the TUI rendering layer. `read.ts` snapsho
88
88
 
89
89
  ## Development
90
90
 
91
+ From the repository root:
92
+
91
93
  ```sh
92
94
  bun install --frozen-lockfile
93
- bun run typecheck
94
- bun run build
95
- npm pack --dry-run
95
+ bun run --filter @mtayfur/opencode-cache-view typecheck
96
+ bun run --filter @mtayfur/opencode-cache-view build
97
+ npm pack ./packages/cache-view --dry-run
96
98
  ```
package/dist/index.js CHANGED
@@ -410,7 +410,7 @@ function createSpeedTracker(api) {
410
410
  const starts = new Map;
411
411
  const latest = new Map;
412
412
  const trends = new Map;
413
- const turnTotals = new Map;
413
+ const pendingToolTurns = new Set;
414
414
  const streamParts = new Map;
415
415
  const streamSamples = new Map;
416
416
  const clearStream = (messageID) => {
@@ -446,28 +446,27 @@ function createSpeedTracker(api) {
446
446
  if (!start || start.sessionID !== event.properties.sessionID)
447
447
  return;
448
448
  clearStream(value.messageID);
449
- const duration = event.properties.time - start.time;
449
+ const duration = start.firstTokenTime === undefined ? 0 : event.properties.time - start.firstTokenTime;
450
450
  const tokens = value.tokens.output + value.tokens.reasoning;
451
- if (duration <= 0 || tokens <= 0)
452
- return;
453
- const previous = turnTotals.get(start.sessionID) ?? { tokens: 0, duration: 0 };
454
- const turn = {
455
- tokens: previous.tokens + tokens,
456
- duration: previous.duration + duration
457
- };
458
- const speed = turn.tokens / turn.duration * 1000;
459
- latest.set(start.sessionID, speed);
460
451
  if (value.reason === "tool-calls") {
461
- turnTotals.set(start.sessionID, turn);
452
+ pendingToolTurns.add(start.sessionID);
462
453
  return;
463
454
  }
464
- turnTotals.delete(start.sessionID);
455
+ pendingToolTurns.delete(start.sessionID);
456
+ if (duration <= 0 || tokens <= 0)
457
+ return;
458
+ const speed = tokens / duration * 1000;
459
+ latest.set(start.sessionID, speed);
465
460
  trends.set(start.sessionID, [...trends.get(start.sessionID) ?? [], speed].slice(-8));
466
461
  });
467
462
  const delta = api.event.on("message.part.delta", (event) => {
468
- if (event.properties.field !== "text" || !starts.has(event.properties.messageID))
463
+ if (event.properties.field !== "text")
464
+ return;
465
+ const start = starts.get(event.properties.messageID);
466
+ if (!start)
469
467
  return;
470
468
  const now = Date.now();
469
+ start.firstTokenTime ??= now;
471
470
  const previous = streamParts.get(event.properties.partID) ?? {
472
471
  messageID: event.properties.messageID,
473
472
  units: 0
@@ -489,7 +488,7 @@ function createSpeedTracker(api) {
489
488
  starts.delete(event.properties.info.id);
490
489
  clearStream(event.properties.info.id);
491
490
  if (event.properties.info.error !== undefined)
492
- turnTotals.delete(event.properties.sessionID);
491
+ pendingToolTurns.delete(event.properties.sessionID);
493
492
  });
494
493
  const messageRemoved = api.event.on("message.removed", (event) => {
495
494
  starts.delete(event.properties.messageID);
@@ -498,7 +497,7 @@ function createSpeedTracker(api) {
498
497
  const sessionDeleted = api.event.on("session.deleted", (event) => {
499
498
  latest.delete(event.properties.sessionID);
500
499
  trends.delete(event.properties.sessionID);
501
- turnTotals.delete(event.properties.sessionID);
500
+ pendingToolTurns.delete(event.properties.sessionID);
502
501
  for (const [messageID, start] of starts) {
503
502
  if (start.sessionID === event.properties.sessionID) {
504
503
  starts.delete(messageID);
@@ -519,7 +518,7 @@ function createSpeedTracker(api) {
519
518
  const active = activeMessageID !== undefined;
520
519
  const live = activeMessageID === undefined ? undefined : streamingSpeed(activeMessageID, Date.now());
521
520
  const fallback = latest.get(sessionID);
522
- const provisional = active || turnTotals.has(sessionID);
521
+ const provisional = active || pendingToolTurns.has(sessionID);
523
522
  return {
524
523
  active,
525
524
  value: active ? live ?? fallback : fallback,
@@ -536,7 +535,7 @@ function createSpeedTracker(api) {
536
535
  starts.clear();
537
536
  latest.clear();
538
537
  trends.clear();
539
- turnTotals.clear();
538
+ pendingToolTurns.clear();
540
539
  streamParts.clear();
541
540
  streamSamples.clear();
542
541
  }
package/package.json CHANGED
@@ -1,16 +1,17 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@mtayfur/opencode-cache-view",
4
- "version": "0.0.4",
4
+ "version": "1.0.2",
5
5
  "description": "Minimal OpenCode TUI sidebar for cache hit, estimated tokens, and generation speed.",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "git+https://github.com/mtayfur/opencode-cache-view.git"
8
+ "url": "git+https://github.com/mtayfur/opencode-plugins.git",
9
+ "directory": "packages/cache-view"
9
10
  },
10
11
  "bugs": {
11
- "url": "https://github.com/mtayfur/opencode-cache-view/issues"
12
+ "url": "https://github.com/mtayfur/opencode-plugins/issues"
12
13
  },
13
- "homepage": "https://github.com/mtayfur/opencode-cache-view#readme",
14
+ "homepage": "https://github.com/mtayfur/opencode-plugins/tree/main/packages/cache-view#readme",
14
15
  "files": [
15
16
  "dist"
16
17
  ],
@@ -38,8 +39,8 @@
38
39
  "@opentui/solid": ">=0.2.0"
39
40
  },
40
41
  "devDependencies": {
41
- "@opencode-ai/plugin": "^1.18.16",
42
- "@opencode-ai/sdk": "^1.18.16",
42
+ "@opencode-ai/plugin": "1.18.16",
43
+ "@opencode-ai/sdk": "1.18.16",
43
44
  "@opentui/core": "^0.5.1",
44
45
  "@opentui/solid": "^0.5.1",
45
46
  "jsonc-parser": "^3.3.1",