opencode-navigator 0.21.4 → 0.21.6

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/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## [0.21.6] - 2026-10-09
6
+
7
+ - Refine Limits with a continuous muted guide, full-width thin-line quota scales, and reset-left/remaining-right details. Keep long reset text from overlapping the remaining value and preserve Text fallback, resize clipping, and existing controls.
8
+
9
+ ## [0.21.5] - 2026-10-07
10
+
11
+ - Make automatic Limits refresh configurable in scoped Behavior settings and portable configuration, with a five-minute default and one-minute minimum. Keep manual Refresh and supported model/account switches immediate.
12
+ - Avoid extra quota polling from unrelated preference changes and unchanged provider-account metadata observations.
13
+
5
14
  ## [0.21.4] - 2026-10-07
6
15
 
7
16
  - Add `c` to Navigator shortcuts for a manual update check and `u` to check then confirm a Navigator update. Report available, current, or unavailable results, preserve the installation method and scope, and require a restart after updating.
@@ -95,6 +104,8 @@
95
104
 
96
105
  Earlier release notes are available on [GitHub Releases](https://github.com/St1ggy/opencode-navigator/releases).
97
106
 
107
+ [0.21.6]: https://github.com/St1ggy/opencode-navigator/compare/v0.21.5...v0.21.6
108
+ [0.21.5]: https://github.com/St1ggy/opencode-navigator/compare/v0.21.4...v0.21.5
98
109
  [0.21.4]: https://github.com/St1ggy/opencode-navigator/compare/v0.21.3...v0.21.4
99
110
  [0.21.3]: https://github.com/St1ggy/opencode-navigator/compare/v0.21.2...v0.21.3
100
111
  [0.21.2]: https://github.com/St1ggy/opencode-navigator/compare/v0.21.1...v0.21.2
package/README.md CHANGED
@@ -145,7 +145,7 @@ the uninstalled-font result remains visible rather than being documented only in
145
145
 
146
146
  ![Nerd Font without Navigator corner font](https://raw.githubusercontent.com/St1ggy/opencode-navigator/main/screenshots/35-no-corner-font-layout-preview.png)
147
147
 
148
- The [complete 38-state screenshot gallery](screenshots/README.md) shows every
148
+ The [complete 47-state screenshot gallery](screenshots/README.md) shows every
149
149
  Todo and Subagent filter, sidebar section, Search and Settings tab, preset menu
150
150
  and preview, confirmation, keyboard-help, setup, and icon-fallback state.
151
151
 
@@ -370,6 +370,11 @@ across models. The protocol can return `normalModelSlug: null` for this ordinary
370
370
  bucket; that field is display metadata for quota aliases, not a prerequisite for
371
371
  account usage. Separate model-specific buckets require explicit model association.
372
372
  Switching provider, model, session, or account invalidates stale reads and credit actions.
373
+ In OpenCode 2.x, Limits follows the prompt's selected model immediately, before a
374
+ message is sent, through the public reactive `ui.model.current()` API. OpenCode
375
+ 1.x through 1.18.35 exposes only the saved session model: a newly selected prompt
376
+ model becomes visible to Navigator when the host saves it, normally on submission.
377
+ An immediate pre-submission switch in 1.x needs a new public host accessor or event.
373
378
  CodexBar is useful for discovering providers, but its cookie, credential-file,
374
379
  and undocumented endpoint integrations are not Navigator data sources.
375
380
 
@@ -427,20 +432,29 @@ Codex account** and **Unlink Codex account** for the outdated manual association
427
432
  bindings are reused; conflicting bindings remain isolated until a deliberate relink.
428
433
 
429
434
  Limits starts with **[Provider name] Model name · variant**. Activate the model or
430
- variant with the mouse or keyboard to open OpenCode's native selector. Each quota
431
- window uses two compact rows: remaining headroom with an adaptive muted thin-line
432
- scale spanning the available sidebar content width, then a muted reset time.
435
+ variant with the mouse or keyboard to open OpenCode's native selector. A muted
436
+ vertical guide joins the quota windows, with one guide-only row between them
437
+ (`|` in Text fallback). Each window uses two compact rows: a full-width adaptive
438
+ thin-line scale, then muted reset time on the left and remaining headroom aligned
439
+ to the right. The remaining value keeps its own space; long reset text is clipped.
433
440
  Both rows stay within the sidebar's padding when it resizes. Healthy views omit
434
441
  account IDs, technical scope/window-duration suffixes, source explanations, and update timestamps. Account scope and native window durations remain in the data model;
435
442
  durations describe provider quota windows, not time remaining until reset. Balances retain their native
436
443
  currency or point unit; a missing total does not become a full progress scale.
437
444
 
438
445
  The header has no section counter. Its compact **Refresh** control requests a
439
- read immediately; background reads continue every five seconds, including while
440
- hidden. Failed reads retain cached windows with stale guidance and the same header
446
+ read immediately. Automatic refresh defaults to **five minutes**, including while
447
+ hidden. Change **Settings → Behavior → Limits refresh interval** in Global or
448
+ Current worktree scope; enter a whole number of minutes, with a minimum of one.
449
+ Changing the effective interval reschedules the timer without an extra quota read.
450
+ Model/account switches and manual Refresh remain immediate; unrelated settings
451
+ updates and provider-response observations do not trigger extra quota polling.
452
+ Failed reads retain cached windows with stale guidance and the same header
441
453
  control for retrying. Unsupported mappings, authentication, and setup states have
442
454
  separate muted guidance.
443
455
 
456
+ ![Scoped Limits refresh interval setting](screenshots/47-limits-refresh-settings.png)
457
+
444
458
  ### Review and manually use a banked reset
445
459
 
446
460
  The header's **Banked Resets** button appears when credits or an unresolved attempt
@@ -492,6 +506,7 @@ Navigator plugin tuple:
492
506
  "focusKey": "ctrl+shift+f",
493
507
  "searchKey": "ctrl+shift+k",
494
508
  "persistMcp": true,
509
+ "limitsRefreshMinutes": 5,
495
510
  "startInChat": false,
496
511
  "showSessionTitle": true,
497
512
  "showSessionDate": true,
@@ -530,10 +545,10 @@ For example, the schema-valid `opencode.json` entry is:
530
545
  }
531
546
  ```
532
547
 
533
- Behavior keys control the optional start-in-chat flow, shortcuts, MCP persistence, `nerd`/`text` icon style, row
548
+ Behavior keys control the optional start-in-chat flow, shortcuts, MCP persistence, Limits refresh cadence, `nerd`/`text` icon style, row
534
549
  density, item limits, and Navigator's safe Quick Action allowlist. Unknown values,
535
550
  sections, actions, and MCP states are discarded. The previous snake_case tuple
536
- options (`toggle_key`, `focus_key`, `search_key`, `persist_mcp`, `start_in_chat`, `show_session_title`,
551
+ options (`toggle_key`, `focus_key`, `search_key`, `persist_mcp`, `limits_refresh_minutes`, `start_in_chat`, `show_session_title`,
537
552
  `show_session_date`, `corner_font`, `icon_style`,
538
553
  `lsp_icon_style`, `row_density`, `section_item_limits`, `quick_action_order`,
539
554
  `quick_action_visibility`, `sections`, and `section_order`) remain compatible;
@@ -3,5 +3,6 @@ var TOGGLE_COMMAND=`${PLUGIN_ID}.toggle`
3
3
  var FOCUS_COMMAND=`${PLUGIN_ID}.focus`
4
4
  var SEARCH_COMMAND=`${PLUGIN_ID}.search`;
5
5
  var QUICK_ACTION_IDS=["session.rename","session.timeline","session.copy","session.export","session.compact","session.list","session.new","session.fork","messages.copy","session.first","session.last","session.messages_last_user","session.message.next","session.message.previous","permission.mode"]
6
- var SECTION_DEFINITIONS=[{name:"limits",label:"Limits"},{name:"todo",label:"Todo"},{name:"subagents",label:"Subagents"},{name:"skills",label:"Skills"},{name:"quick_actions",label:"Quick actions"},{name:"lsp",label:"LSP"},{name:"mcp",label:"MCP"}]
6
+ var SECTION_DEFINITIONS=[{name:"limits",label:"Limits"},{name:"todo",label:"Todo"},{name:"subagents",label:"Subagents"},{name:"skills",label:"Skills"},{name:"quick_actions",label:"Quick actions"},{name:"lsp",label:"LSP"},{name:"mcp",label:"MCP"}];
7
+ var MAX_LIMITS_REFRESH_MINUTES=Math.floor(2147483647 / 60000)
7
8
  export{QUICK_ACTION_IDS,SECTION_DEFINITIONS,PLUGIN_ID}
@@ -1,5 +1,5 @@
1
1
  import {SECTION_DEFINITIONS,PLUGIN_ID
2
- } from "./chunk-cmmnfes2.js";
2
+ } from "./chunk-d1bws32s.js";
3
3
  import {createComponent as _$createComponent7} from "@opentui/solid"
4
4
  import {setProp as _$setProp5} from "@opentui/solid"
5
5
  import {effect as _$effect5} from "@opentui/solid"
@@ -1,5 +1,5 @@
1
1
  import {PLUGIN_ID
2
- } from "./chunk-cmmnfes2.js";
2
+ } from "./chunk-d1bws32s.js";
3
3
  import {createSignal} from "solid-js"
4
4
  function versionParts(value){const match=/^v?(\d+)\.(\d+)\.(\d+)(?:-([^+]+))?/.exec(value)
5
5
  return match?{numbers:match.slice(1,4).map(Number),prerelease:match[4]||undefined}:undefined
@@ -50,6 +50,9 @@ return Object.fromEntries(SIDEBAR_SECTIONS.flatMap((section)=>{const limit=input
50
50
  return typeof limit==="number"&&Number.isSafeInteger(limit)&&limit>=0?[[section,limit]]:[]
51
51
  }))
52
52
  }
53
+ var MAX_LIMITS_REFRESH_MINUTES=Math.floor(2147483647 / 60000)
54
+ function parseLimitsRefreshMinutes(value){return typeof value==="number"&&Number.isSafeInteger(value)&&value>=1&&value<=MAX_LIMITS_REFRESH_MINUTES?value:undefined
55
+ }
53
56
  var PLUGIN_ID="opencode-navigator"
54
57
  var TOGGLE_COMMAND=`${PLUGIN_ID}.toggle`
55
58
  var FOCUS_COMMAND=`${PLUGIN_ID}.focus`
@@ -61,7 +64,8 @@ return value
61
64
  function parsePluginSettings(value){const input=record(value)
62
65
  if(!input)
63
66
  return{}
64
- return{...typeof input.toggleKey==="string"&&input.toggleKey.trim()&&{toggleKey:input.toggleKey.trim()},...typeof input.focusKey==="string"&&input.focusKey.trim()&&{focusKey:input.focusKey.trim()},...typeof input.searchKey==="string"&&input.searchKey.trim()&&{searchKey:input.searchKey.trim()},...typeof input.persistMcp==="boolean"&&{persistMcp:input.persistMcp},...typeof input.startInChat==="boolean"&&{startInChat:input.startInChat},...typeof input.showSessionTitle==="boolean"&&{showSessionTitle:input.showSessionTitle},...typeof input.showSessionDate==="boolean"&&{showSessionDate:input.showSessionDate},...typeof input.cornerFont==="boolean"&&{cornerFont:input.cornerFont},...(input.lspIconStyle==="nerd"||input.lspIconStyle==="text")&&{lspIconStyle:input.lspIconStyle},...(input.rowDensity==="compact"||input.rowDensity==="comfortable")&&{rowDensity:input.rowDensity
67
+ return{...typeof input.toggleKey==="string"&&input.toggleKey.trim()&&{toggleKey:input.toggleKey.trim()},...typeof input.focusKey==="string"&&input.focusKey.trim()&&{focusKey:input.focusKey.trim()},...typeof input.searchKey==="string"&&input.searchKey.trim()&&{searchKey:input.searchKey.trim()},...typeof input.persistMcp==="boolean"&&{persistMcp:input.persistMcp},...parseLimitsRefreshMinutes(input.limitsRefreshMinutes)!==undefined&&{limitsRefreshMinutes:parseLimitsRefreshMinutes(input.limitsRefreshMinutes)
68
+ },...typeof input.startInChat==="boolean"&&{startInChat:input.startInChat},...typeof input.showSessionTitle==="boolean"&&{showSessionTitle:input.showSessionTitle},...typeof input.showSessionDate==="boolean"&&{showSessionDate:input.showSessionDate},...typeof input.cornerFont==="boolean"&&{cornerFont:input.cornerFont},...(input.lspIconStyle==="nerd"||input.lspIconStyle==="text")&&{lspIconStyle:input.lspIconStyle},...(input.rowDensity==="compact"||input.rowDensity==="comfortable")&&{rowDensity:input.rowDensity
65
69
  },...Object.keys(parseSectionItemLimits(input.sectionItemLimits)).length>0&&{sectionItemLimits:parseSectionItemLimits(input.sectionItemLimits)
66
70
  },...parseQuickActionOrder(input.quickActionOrder)&&{quickActionOrder:parseQuickActionOrder(input.quickActionOrder)
67
71
  },...Object.keys(parseQuickActionVisibility(input.quickActionVisibility)).length>0&&{quickActionVisibility:parseQuickActionVisibility(input.quickActionVisibility)