@leo000001/opencode-quota-sidebar 3.0.6 → 3.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -178,6 +178,7 @@ export async function QuotaSidebarPlugin(input) {
178
178
  getQuotaSnapshots,
179
179
  summarizeSessionUsageForDisplay,
180
180
  scheduleParentRefreshIfSafe,
181
+ isSessionActive,
181
182
  restoreConcurrency: RESTORE_TITLE_CONCURRENCY,
182
183
  });
183
184
  const titleRefresh = createTitleRefreshScheduler({
@@ -189,30 +190,7 @@ export async function QuotaSidebarPlugin(input) {
189
190
  onError: swallow('titleRefresh'),
190
191
  });
191
192
  scheduleTitleRefresh = titleRefresh.schedule;
192
- const restoreAllVisibleTitles = titleApplicator.restoreAllVisibleTitles;
193
- const refreshAllTouchedTitles = titleApplicator.refreshAllTouchedTitles;
194
- const refreshAllVisibleTitles = titleApplicator.refreshAllVisibleTitles;
195
- let startupTitleWork = Promise.resolve();
196
- const runStartupRestore = async (attempt = 0) => {
197
- const result = await restoreAllVisibleTitles({
198
- abortIfEnabled: config.sidebar.enabled,
199
- });
200
- if (result.restored === result.attempted)
201
- return;
202
- debug(`startup restore incomplete: restored ${result.restored}/${result.attempted} touched titles while display mode remains OFF`);
203
- if (state.titleEnabled || config.sidebar.enabled === false)
204
- return;
205
- if (attempt >= 2)
206
- return;
207
- await new Promise((resolve) => setTimeout(resolve, 1_000));
208
- await runStartupRestore(attempt + 1);
209
- };
210
- if (!state.titleEnabled || !config.sidebar.enabled) {
211
- startupTitleWork = runStartupRestore().catch(swallow('startup:restoreAllVisibleTitles'));
212
- }
213
- else {
214
- startupTitleWork = Promise.resolve();
215
- }
193
+ const startupTitleWork = Promise.resolve();
216
194
  const shutdown = async () => {
217
195
  await Promise.race([
218
196
  startupTitleWork,
@@ -379,11 +357,17 @@ export async function QuotaSidebarPlugin(input) {
379
357
  scheduleParentRefreshIfSafe(info.sessionID, state.sessions[info.sessionID]?.parentID);
380
358
  },
381
359
  onAssistantMessageUpdated: async (message) => {
382
- markSessionActive(message.sessionID);
360
+ const now = Date.now();
383
361
  const completed = message.time.completed;
384
362
  if (typeof completed !== 'number' || !Number.isFinite(completed)) {
363
+ markSessionActive(message.sessionID, now);
364
+ return;
365
+ }
366
+ const wasActive = isSessionActive(message.sessionID, now);
367
+ if (!wasActive) {
385
368
  return;
386
369
  }
370
+ markSessionActive(message.sessionID, now);
387
371
  usageService.markSessionDirty(message.sessionID);
388
372
  scheduleActiveTitleRefresh(message.sessionID);
389
373
  void maybeShowExpiryToast(message.sessionID);
@@ -406,14 +390,13 @@ export async function QuotaSidebarPlugin(input) {
406
390
  scheduleSave,
407
391
  flushSave,
408
392
  waitForStartupTitleWork: () => startupTitleWork,
393
+ markSessionActive,
409
394
  refreshSessionTitle: (sessionID, delay) => scheduleActiveTitleRefresh(sessionID, delay ?? 250),
410
395
  cancelAllTitleRefreshes: () => titleRefresh.cancelAll(),
411
396
  flushScheduledTitleRefreshes: () => titleRefresh.flushScheduled(),
412
397
  waitForTitleRefreshIdle: () => titleRefresh.waitForIdle(),
413
398
  waitForTitleRefreshQuiescence: () => titleRefresh.waitForQuiescence(),
414
- restoreAllVisibleTitles,
415
- refreshAllTouchedTitles,
416
- refreshAllVisibleTitles,
399
+ restoreSessionTitle: (sessionID) => titleApplicator.restoreSessionTitle(sessionID),
417
400
  showToast,
418
401
  summarizeForTool,
419
402
  getQuotaSnapshots,
@@ -17,6 +17,7 @@ export declare function createTitleApplicator(deps: {
17
17
  }) => Promise<QuotaSnapshot[]>;
18
18
  summarizeSessionUsageForDisplay: (sessionID: string, includeChildren: boolean) => Promise<UsageSummary>;
19
19
  scheduleParentRefreshIfSafe: (sessionID: string, parentID?: string) => void;
20
+ isSessionActive?: (sessionID: string) => boolean;
20
21
  restoreConcurrency: number;
21
22
  }): {
22
23
  applyTitle: (sessionID: string) => Promise<boolean>;
@@ -28,6 +28,10 @@ export function createTitleApplicator(deps) {
28
28
  const applyTitle = async (sessionID) => {
29
29
  if (!deps.config.sidebar.enabled)
30
30
  return false;
31
+ if (deps.isSessionActive && !deps.isSessionActive(sessionID)) {
32
+ debug(`applyTitle skipped inactive session ${sessionID}`);
33
+ return false;
34
+ }
31
35
  let stateMutated = false;
32
36
  const session = await deps.client.session
33
37
  .get({
package/dist/tools.d.ts CHANGED
@@ -10,26 +10,13 @@ export declare function createQuotaSidebarTools(deps: {
10
10
  scheduleSave: () => void;
11
11
  flushSave: () => Promise<void>;
12
12
  waitForStartupTitleWork: () => Promise<void>;
13
+ markSessionActive?: (sessionID: string) => void;
13
14
  refreshSessionTitle: (sessionID: string, delay?: number) => void;
14
15
  cancelAllTitleRefreshes: () => void;
15
16
  flushScheduledTitleRefreshes: () => Promise<void>;
16
17
  waitForTitleRefreshIdle: () => Promise<void>;
17
18
  waitForTitleRefreshQuiescence: () => Promise<void>;
18
- restoreAllVisibleTitles: () => Promise<{
19
- attempted: number;
20
- restored: number;
21
- listFailed: boolean;
22
- }>;
23
- refreshAllTouchedTitles: () => Promise<{
24
- attempted: number;
25
- refreshed: number;
26
- listFailed: boolean;
27
- }>;
28
- refreshAllVisibleTitles: () => Promise<{
29
- attempted: number;
30
- refreshed: number;
31
- listFailed: boolean;
32
- }>;
19
+ restoreSessionTitle?: (sessionID: string) => Promise<boolean>;
33
20
  showToast: (period: 'session' | 'day' | 'week' | 'month' | 'toggle', message: string) => Promise<void>;
34
21
  summarizeForTool: (period: 'session' | 'day' | 'week' | 'month', sessionID: string, includeChildren: boolean) => Promise<UsageSummary>;
35
22
  getQuotaSnapshots: (providerIDs: string[], options?: {
package/dist/tools.js CHANGED
@@ -63,11 +63,13 @@ export function createQuotaSidebarTools(deps) {
63
63
  deps.setTitleEnabled(true);
64
64
  deps.scheduleSave();
65
65
  await deps.flushSave();
66
+ deps.markSessionActive?.(context.sessionID);
66
67
  deps.refreshSessionTitle(context.sessionID, 0);
67
68
  if (startupTimedOut) {
68
69
  void deps.waitForStartupTitleWork().then(() => {
69
70
  if (!deps.getTitleEnabled())
70
71
  return;
72
+ deps.markSessionActive?.(context.sessionID);
71
73
  deps.refreshSessionTitle(context.sessionID, 0);
72
74
  });
73
75
  }
@@ -79,14 +81,17 @@ export function createQuotaSidebarTools(deps) {
79
81
  await deps.flushSave();
80
82
  deps.cancelAllTitleRefreshes();
81
83
  await deps.waitForTitleRefreshQuiescence();
82
- const restore = await deps.restoreAllVisibleTitles();
83
- if (restore.restored === restore.attempted) {
84
+ const restoredCurrent = await (deps.restoreSessionTitle
85
+ ? deps.restoreSessionTitle(context.sessionID)
86
+ : Promise.resolve(false));
87
+ if (restoredCurrent) {
84
88
  await deps.showToast('toggle', 'Sidebar usage display: OFF');
85
- return 'Sidebar usage display is now OFF. Touched session titles were restored to base titles.';
89
+ return 'Sidebar usage display is now OFF. The current session title was restored to its base title.';
86
90
  }
87
91
  deps.setTitleEnabled(true);
88
92
  deps.scheduleSave();
89
93
  await deps.flushSave();
94
+ deps.markSessionActive?.(context.sessionID);
90
95
  deps.refreshSessionTitle(context.sessionID, 0);
91
96
  await deps.showToast('toggle', 'Sidebar usage display: OFF failed');
92
97
  return 'Sidebar usage display remains ON because some touched session titles could not be restored. Try again after the session service recovers.';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leo000001/opencode-quota-sidebar",
3
- "version": "3.0.6",
3
+ "version": "3.0.9",
4
4
  "description": "OpenCode plugin that shows quota and token usage in TUI sidebar panels and compact session titles",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",