opencode-kiro 0.4.0 → 0.5.0-beta.1

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
@@ -1,22 +1,45 @@
1
1
  # opencode-kiro
2
2
 
3
- The ACP-compliant [Kiro](https://kiro.dev) auth plugin for [opencode](https://opencode.ai).
4
-
5
- opencode learns the `kiro` provider and its available models (US region) from the
6
- [models.dev](https://models.dev) catalog. This plugin supplies the following pieces:
7
-
8
- - **Auth** via the official `kiro-cli` login flow (`opencode auth login`, then "Kiro CLI Login")
9
- - **Provider options loader**: the `cwd`, `agent`, `trustAllTools`, `mcpTimeout` values
10
- opencode forwards into the SDK factory
11
- - **TUI credits display**: an opt-in Kiro credits box in the sidebar (appended below the
12
- native Context box) plus a matching footer credits chip
3
+ > ⚠️ **Experimental prerelease** — `0.5.0-beta.1` targets the **unreleased OpenCode v2**
4
+ > plugin contract at a pinned snapshot. It does **not** work with OpenCode v1.
5
+ > v1 users: stay on **`opencode-kiro@0.4.0`** (the `main` branch / npm `latest` line,
6
+ > which remains the supported stable release). See
7
+ > [RELEASE_NOTES_0.5.0-beta.1.md](./RELEASE_NOTES_0.5.0-beta.1.md) and
8
+ > [PINNED_VERSIONS.md](./PINNED_VERSIONS.md) for exact pins and the tested OpenCode SHA.
9
+ > No OpenCode v2 release date is known or claimed here.
10
+
11
+ The ACP-compliant [Kiro](https://kiro.dev) plugin for [opencode](https://opencode.ai).
12
+
13
+ The plugin supplies:
14
+
15
+ - **Auth** via the official `kiro-cli` login flow: it registers the `kiro` integration
16
+ with a **Kiro CLI Login** OAuth method (`opencode auth login`)
17
+ - **Model discovery**: after auth it captures Kiro's live model lineup and merges it
18
+ into OpenCode's catalog (exact ID intersection, reasoning-effort variants), with a
19
+ minimal self-registration fallback when the catalog lacks a `kiro` entry
20
+ - **Provider ownership**: an AISDK hook constructs the provider from
21
+ [`kiro-acp-ai-provider`](https://www.npmjs.com/package/kiro-acp-ai-provider) with the
22
+ right options (`cwd`, `agent`, `trustAllTools`, `mcpTimeout`, `contextWindows`)
23
+ - **TUI credits display**: a live Kiro credits box in the sidebar
24
+
25
+ `kiro-acp-ai-provider` talks to your locally installed `kiro-cli` over Kiro's
26
+ [Agent Client Protocol](https://agentclientprotocol.com) (ACP). This is the supported
27
+ integration path: requests go through kiro-cli exactly like Kiro's own IDE clients,
28
+ with no credential scraping and no reuse of Kiro credentials against other providers.
29
+
30
+ ## Compatibility
31
+
32
+ This prerelease is built and tested against **one pinned OpenCode v2 snapshot**:
33
+
34
+ | Item | Value |
35
+ |---|---|
36
+ | Tested OpenCode commit (`upstream/v2`) | `b47cfbee7c4fd24e5d73e5753b4755db62a92a63` |
37
+ | `@opencode-ai/plugin` | `0.0.0-next-16420` (exact) |
38
+ | Package version | `0.5.0-beta.1` |
13
39
 
14
- The `kiro` provider resolves to [`kiro-acp-ai-provider`](https://www.npmjs.com/package/kiro-acp-ai-provider),
15
- an AI-SDK provider that talks to your locally installed `kiro-cli` over Kiro's
16
- [Agent Client Protocol](https://agentclientprotocol.com) (ACP); opencode picks it up from
17
- the catalog's `npm` field. This is the supported integration path: requests go through
18
- kiro-cli exactly like Kiro's own IDE clients, with no credential scraping and no reuse of
19
- Kiro credentials against other providers.
40
+ Full pin table and verification evidence: [PINNED_VERSIONS.md](./PINNED_VERSIONS.md).
41
+ There is no `engines.opencode` constraint the v2 host has no stable semver yet; the
42
+ tested SHA above is the compatibility target. Other v2 snapshots may or may not work.
20
43
 
21
44
  ## Prerequisites
22
45
 
@@ -24,57 +47,68 @@ Kiro credentials against other providers.
24
47
  |---|---|
25
48
  | [kiro-cli](https://kiro.dev/docs/cli/) | Must be installed and on `PATH`; a Kiro subscription / AWS Builder ID account |
26
49
  | [Node.js](https://nodejs.org) `>= 20` | Enforced via `engines.node`. |
27
- | opencode `>= 1.16.0` | Enforced via `engines.opencode` on released builds. The shipped catalog must include the `kiro` provider (see [Troubleshooting](#troubleshooting)). |
28
-
29
- ## Install
30
-
31
- ```bash
32
- opencode plugin opencode-kiro
33
- ```
34
-
35
- (alias: `opencode plug opencode-kiro`; add `--global`/`-g` to install into your global config instead of the project)
36
-
37
- The installer reads this package's `exports` and detects both plugin entrypoints
38
- (`./server` and `./tui`), then patches **both** config files automatically:
50
+ | OpenCode v2 at the tested snapshot | See [Compatibility](#compatibility). This prerelease does not support OpenCode v1. |
39
51
 
40
- - `.opencode/opencode.json`: the server plugin (auth)
41
- - `.opencode/tui.json`: the TUI plugin (credits sidebar box + footer chip)
52
+ ## Install and configure
42
53
 
43
- (with `--global`: `~/.config/opencode/opencode.json` and `~/.config/opencode/tui.json`)
54
+ OpenCode v2 splits plugin configuration into **two separate files**, and both entries
55
+ are configured manually:
44
56
 
45
- You do **not** add a `provider.kiro` block; opencode loads the `kiro` provider and its
46
- models straight from the models.dev catalog. See
47
- [Credits in the sidebar](#credits-in-the-sidebar) for what the TUI plugin adds.
57
+ ### 1. Server plugin `plugins` in your OpenCode config
48
58
 
49
- ### Manual alternative
59
+ Add the package to the **`plugins`** array (plural) of your OpenCode config
60
+ (`opencode.json`, project or global). The object form pins the version and leaves room
61
+ for future options:
50
62
 
51
- Add the package name to the `plugin` array of **both** files yourself (in the
52
- project's `.opencode/` directory, at the project root, or in the global
53
- `~/.config/opencode/`, all are valid config locations):
63
+ ```json
64
+ {
65
+ "plugins": [
66
+ {
67
+ "package": "opencode-kiro@0.5.0-beta.1",
68
+ "options": {}
69
+ }
70
+ ]
71
+ }
72
+ ```
54
73
 
55
- `opencode.json`:
74
+ A plain package string is also accepted:
56
75
 
57
76
  ```json
58
77
  {
59
- "plugin": ["opencode-kiro"]
78
+ "plugins": ["opencode-kiro@0.5.0-beta.1"]
60
79
  }
61
80
  ```
62
81
 
63
- `tui.json`:
82
+ This loads the server entry (`./server` export): auth, model discovery, and provider
83
+ ownership.
84
+
85
+ ### 2. TUI plugin — `plugins` in your global `cli.json`
86
+
87
+ To enable the Kiro credits sidebar, add `"opencode-kiro"` to the **`plugins`** array in
88
+ your **global `cli.json`** (typically `~/.config/opencode/cli.json`) and restart
89
+ opencode:
64
90
 
65
91
  ```json
66
92
  {
67
- "plugin": ["opencode-kiro"]
93
+ "plugins": ["opencode-kiro"]
68
94
  }
69
95
  ```
70
96
 
71
- That single `plugin` entry is all the [credits sidebar](#credits-in-the-sidebar) box and
72
- footer chip need; there is no `plugin_enabled` step.
97
+ This loads the TUI entry (`./tui` export): the sidebar credits box. The connect flow
98
+ shows these same steps when you answer **Yes** to the
99
+ "Enable the Kiro credits sidebar?" prompt during `opencode auth login`.
100
+
101
+ ### Legacy `tui.json` (v1)
102
+
103
+ `tui.json` is **legacy v1 configuration** and, under v2, is **migration input only**:
104
+ the host may read it when migrating old setups, and this plugin **never modifies it**
105
+ (the v1 consent-driven update of that file was deleted in v2). Do not add new entries
106
+ to `tui.json`; use the global `cli.json` `plugins` array described above.
73
107
 
74
108
  ### Local development (path source)
75
109
 
76
- Run a local checkout without npm: build first, then reference the repo directory by
77
- absolute path in both `plugin` arrays:
110
+ Run a local checkout without npm build first, then reference the repo directory by
111
+ absolute path in both `plugins` arrays:
78
112
 
79
113
  ```bash
80
114
  git clone https://github.com/NachoFLizaur/opencode-kiro && cd opencode-kiro
@@ -82,25 +116,14 @@ npm install && npm run build
82
116
  ```
83
117
 
84
118
  ```json
85
- { "plugin": ["/absolute/path/to/opencode-kiro"] }
119
+ { "plugins": ["/absolute/path/to/opencode-kiro"] }
86
120
  ```
87
121
 
88
- opencode resolves the right entrypoint per file from the package `exports`. Note that
89
- path-sourced TUI plugins **must export an `id`** (opencode rejects them otherwise);
90
- this package ships `{ id: "opencode-kiro", tui }`, so the id is identical across path
91
- and npm installs.
92
-
93
- Because the provider now comes from the catalog rather than the plugin, a local checkout
94
- also needs a catalog that includes `kiro`. opencode reads its catalog from
95
- `OPENCODE_MODELS_PATH` when set; point it at an `api.json` that contains the `kiro`
96
- provider (for example one generated from a [models.dev](https://models.dev) checkout):
97
-
98
- ```bash
99
- OPENCODE_MODELS_PATH=/path/to/api.json opencode models | grep '^kiro/'
100
- ```
101
-
102
- Until the catalog opencode loads contains `kiro`, the provider will not appear regardless
103
- of this plugin being installed (the plugin only adds auth, not the provider definition).
122
+ OpenCode resolves the right entrypoint per file from the package `exports`
123
+ (`./server` for the server config, `./tui` for `cli.json`). Each entry module exports
124
+ its own `id`, which file-source TUI installs require: the server plugin's id is
125
+ `kiro` and the TUI plugin's id is `opencode-kiro`. Enable/disable directives and
126
+ host logs use `kiro` for the server plugin and `opencode-kiro` for the TUI plugin.
104
127
 
105
128
  ## Auth
106
129
 
@@ -108,24 +131,28 @@ of this plugin being installed (the plugin only adds auth, not the provider defi
108
131
  opencode auth login
109
132
  ```
110
133
 
111
- Select the **Kiro (plugin)** provider, then the **Kiro CLI Login** method:
134
+ Select the **Kiro** integration, then the **Kiro CLI Login** method:
112
135
 
113
136
  - **Already logged in to kiro-cli**: immediate success; the existing kiro-cli session is reused.
114
137
  - **Not logged in**: the plugin launches `kiro-cli login`, which opens a browser window.
115
- Complete the login there; the plugin polls for up to 120 seconds and stores the
116
- credential when kiro-cli reports success.
138
+ Complete the login there; the plugin polls for up to 120 seconds and stores a minimal
139
+ credential record when kiro-cli reports success.
117
140
 
118
141
  If the flow times out, authenticate directly with kiro-cli (`kiro-cli login`) and run
119
142
  `opencode auth login` again; the fast path then completes immediately.
120
143
 
121
- > **Note:** opencode will also surface `kiro` if the `KIRO_API_KEY` environment variable
122
- > is set, because the catalog entry declares `env: ["KIRO_API_KEY"]`. The intended auth
123
- > path for this plugin is still **Kiro CLI Login** above (it reuses your local kiro-cli
124
- > session); the env var is a secondary route opencode offers for any catalog provider.
144
+ kiro-cli owns credential storage and refresh OpenCode never stores real AWS tokens,
145
+ and the plugin implements no refresh callback.
125
146
 
126
147
  ## Models
127
148
 
128
- After authentication, the plugin exposes the exact, case-sensitive intersection of Kiro's runtime `modelId` values and the models.dev catalog's `model.api.id` values. The runtime `listModels()` result is authoritative: `runtimeEfforts` is always an array, an empty array leaves the matching catalog model unchanged, and nonempty arrays merge exact effort variants into the catalog. Existing variant metadata survives key collisions while the runtime effort sets `reasoningEffort`; an optional runtime `baselineEffort` sets the model's base effort. Successful discovery keeps every matching catalog key and all other metadata while omitting runtime-only and catalog-only IDs. A discovery exception or duplicate runtime ID preserves the exact original catalog unchanged.
149
+ After authentication, the plugin captures Kiro's runtime model list and transforms
150
+ OpenCode's catalog to the exact, case-sensitive intersection of runtime `modelId`
151
+ values and catalog model IDs. Runtime reasoning-effort levels are merged as model
152
+ variants (per model family, native levels only); an optional runtime baseline effort
153
+ sets the model's base effort. A discovery failure or duplicate runtime ID leaves the
154
+ catalog unchanged (fail-open). If the loaded catalog has no `kiro` provider at all, the
155
+ plugin self-registers a minimal fallback entry so discovered models remain usable.
129
156
 
130
157
  List the resulting models with:
131
158
 
@@ -134,95 +161,79 @@ opencode models
134
161
  opencode run -m kiro/<exact-model-id> "hello"
135
162
  ```
136
163
 
137
- Image input is capability-driven: paste an image path into the TUI prompt and
138
- image-capable models receive it as an attachment.
139
-
140
- ### Reasoning effort
164
+ Effort-capable models expose their variants through OpenCode's model-variant selection.
165
+ The chosen level reaches the SDK through the provider-settings path: OpenCode overlays
166
+ the selected variant's `settings` onto the model's `settings`, hands them to the
167
+ plugin's `aisdk` hook as `event.options`, and the plugin passes them verbatim to
168
+ `createKiroAcp({ effort })`. That is why the plugin emits the SDK's own `effort` key
169
+ (not `reasoningEffort`) — and why the SDK factory setting, not per-call provider
170
+ options, is the working carrier: OpenCode builds per-call `providerOptions` only for
171
+ the first-party `@ai-sdk/*` provider families, so `providerOptions.kiro.*` is never
172
+ populated for an `aisdk:` package provider like this one. Kiro cannot disable thinking,
173
+ so even the lowest level still produces a reasoning trail.
141
174
 
142
- Effort-capable models expose a reasoning-effort toggle: cycle it in opencode with the
143
- **Cycle model variants** action (default keybind `ctrl+t`). It is **per model**, showing
144
- each family's native levels.
145
-
146
- Models without effort control show no effort option. opencode's **Default** (unset) returns the model to its native
147
- default effort. No config is required: the plugin's `provider.models` hook supplies the
148
- variants automatically and the chosen level flows to the SDK as
149
- `providerOptions.kiro.reasoningEffort`. Kiro cannot disable thinking, so even the lowest
150
- level still produces a reasoning trail.
151
-
152
- ## Credits in the sidebar
175
+ ## Credits in the TUI
153
176
 
154
177
  Kiro is subscription-metered: requests consume **credits**, and the dollar cost
155
- opencode normally displays for Kiro turns is always $0.00. To surface credits the
156
- plugin **appends** a small Kiro credits box in the sidebar, rendered right below the
157
- native **Context** box. It does **not** replace or disable any builtin section: the
158
- native Context box stays and keeps showing the usual tokens, context percentage, and
159
- cost.
160
-
161
- The credits box renders only for Kiro sessions; for a non-Kiro session it shows nothing,
162
- so that session's sidebar is unchanged. The credits value and its unit come from the
163
- metadata the SDK attaches to each message part (kiro-cli reports the unit); nothing is
164
- hardcoded client-side.
165
-
166
- All you need in `tui.json` is the plugin entry:
167
-
168
- ```json
169
- {
170
- "plugin": ["opencode-kiro"]
171
- }
172
- ```
173
-
174
- There is no `plugin_enabled` step anymore.
175
-
176
- ### Migrating from 0.2.1 and earlier
177
-
178
- Older versions replaced the native Context box with a clone and disabled the builtin via:
179
-
180
- ```json
181
- {
182
- "plugin_enabled": { "internal:sidebar-context": false }
183
- }
184
- ```
185
-
186
- If you upgraded from 0.2.1 or earlier and still have that line in your `tui.json`,
187
- remove it yourself: the plugin no longer manages `plugin_enabled`. Once the line is
188
- gone the native Context box returns and shows the usual tokens / context % / cost, and
189
- the Kiro credits box appears in a separate box right below it.
190
-
191
- ## Known limitation
192
-
193
- **Credits render in the TUI only.** Two TUI surfaces show them: the sidebar credits
194
- box (above) and the input/prompt meta row chip (`session_prompt_right`), which sits
195
- above the host's `$` cost chip. Every other cost surface (ACP clients, the web app,
196
- desktop, web share pages, and CLI cost output) shows $0.00 for Kiro sessions. The
197
- models.dev catalog declares Kiro's per-token `cost` as 0 (it is a subscription-metered
198
- provider with no per-token pricing), so opencode core computes $0.00 everywhere it
199
- renders dollar cost. That is expected, not a defect. A cross-surface credits display
200
- would require opencode core changes and is intentionally out of scope for this plugin.
178
+ OpenCode normally displays for Kiro turns is always $0.00. To surface credits the TUI
179
+ plugin renders one surface:
180
+
181
+ - a Kiro credits box in the sidebar (`sidebar.content` slot), showing the session's
182
+ live credits total and unit
183
+
184
+ It renders only for sessions that carry Kiro credit data; other sessions are
185
+ unchanged. The credits value and unit come from the provider state the SDK attaches to
186
+ each message part (`part.state.credits` / `part.state.creditsUnit`); nothing is
187
+ hardcoded client-side. The only configuration needed is the `cli.json` `plugins` entry
188
+ from [Install](#2-tui-plugin--plugins-in-your-global-clijson).
189
+
190
+ While a turn is still streaming, credits for just-ended text are picked up live through
191
+ a transient store that works around a host reducer bug at the pinned snapshot (the
192
+ text-ended event's provider state is dropped by the host); once durable message state
193
+ arrives, it is authoritative and nothing is double-counted. See the release notes for
194
+ details.
195
+
196
+ ## Known limitations (prerelease)
197
+
198
+ - **No slot ordering.** OpenCode v2 slots have no order parameter, so the sidebar
199
+ credits box renders where the host places `sidebar.content` contributions (after the
200
+ built-in sidebar sections), not at a plugin-chosen position.
201
+ - **Default styling.** The pinned snapshot has no supported theme-token API for plugin
202
+ views, so the credits box uses default/inherited terminal styling instead of
203
+ matching the active theme.
204
+ - **Reduced toast feedback.** Auth-flow feedback is delivered as connect-flow text
205
+ (method instructions and the sidebar setup steps) rather than toasts. A toast API
206
+ exists at the pinned snapshot, but this plugin's core deliberately does not depend on
207
+ it — the TUI context surface is churning and toast availability is not guaranteed
208
+ across snapshots.
209
+ - **Live text credits use a workaround.** See [Credits in the TUI](#credits-in-the-tui)
210
+ and the release notes.
211
+ - **Credits render in the TUI only.** Every other cost surface (ACP clients, web,
212
+ desktop, share pages, CLI cost output) shows $0.00 for Kiro sessions because the
213
+ catalog declares Kiro's per-token `cost` as 0 (subscription-metered, no per-token
214
+ pricing). That is expected, not a defect.
201
215
 
202
216
  ## How it works
203
217
 
204
- - **Provider metadata and runtime models**: opencode loads the `kiro` provider and model
205
- metadata from models.dev. After auth, this plugin keeps only exact catalog/runtime ID
206
- matches, preserves catalog metadata, and projects the runtime-authoritative effort
207
- options; a discovery exception or duplicate runtime ID keeps the input catalog unchanged.
208
- - **SDK resolution (resolveSDK)**: opencode reads the catalog's `npm` field
209
- (`kiro-acp-ai-provider`), installs that package into its package cache on first model
210
- use, and imports it. This plugin's `auth` loader supplies the provider options
211
- (`cwd`, `agent`, `trustAllTools`, `mcpTimeout`, `contextWindows`) that opencode forwards
212
- into `createKiroAcp(...)`. The loader relays each model's `limit.context` (from
213
- models.dev, via opencode's resolved catalog) into the SDK's `contextWindows` map keyed
214
- by `api.id`, so the SDK keeps no hardcoded per-model data and falls back to 1,000,000
215
- for any model absent from the relay.
216
- - **Auth (this plugin)**: registers the "Kiro CLI Login" OAuth method (kiro-cli login
217
- flow) plus the options loader above. The same plugin also imports `verifyAuth` from
218
- `kiro-acp-ai-provider` to check kiro-cli installation/login state.
219
- - **Session affinity & reset (in-SDK)**: the SDK keys kiro-cli sessions off opencode's
220
- `x-session-affinity` header, isolates tool-less utility calls (title generation) on
221
- an ephemeral session, detects prompt-history divergence (`fork/undo`), and starts a
222
- fresh kiro session when needed. No host-side session plumbing.
223
- - **Credits metadata**: the SDK attaches `{ kiro: { credits, creditsUnit } }` to the
224
- `metadata` of the final message part of each turn; opencode persists it, and the TUI
225
- plugin sums it per assistant message (deduped across text/reasoning parts) for the sidebar.
218
+ - **Auth (Integration + Credential)**: the plugin upserts the `kiro` integration with a
219
+ "Kiro CLI Login" OAuth method. `verifyAuth` from `kiro-acp-ai-provider` is the auth
220
+ authority (it delegates to kiro-cli); success is stored as a minimal
221
+ `Credential.OAuth` presence record.
222
+ - **Model discovery (catalog transform)**: after login (and on later login events) the
223
+ plugin runs `listModels()` outside the transform, then applies the validated capture
224
+ via a catalog transform and reload exact ID matching, catalog metadata preserved,
225
+ effort variants projected, fail-open on any discovery error.
226
+ - **Provider ownership (AISDK hook)**: the plugin's SDK hook always constructs the
227
+ provider from `kiro-acp-ai-provider` with the plugin-supplied options and sets it as
228
+ the event's SDK, so the Kiro provider is always plugin-owned. The options relay each
229
+ model's context window into the SDK's `contextWindows` map keyed by model ID.
230
+ - **Session affinity & reset (in-SDK)**: the SDK keys kiro-cli sessions off OpenCode's
231
+ session affinity, isolates tool-less utility calls on an ephemeral session, detects
232
+ prompt-history divergence, and starts a fresh kiro session when needed.
233
+ - **Credits state**: the SDK reports `credits` / `creditsUnit` in each turn's provider
234
+ metadata; OpenCode persists them key-unwrapped on message part state
235
+ (`part.state.credits`, `part.state.creditsUnit`), and the TUI plugin sums them per
236
+ assistant message (deduped across parts).
226
237
 
227
238
  ## Troubleshooting
228
239
 
@@ -230,11 +241,21 @@ would require opencode core changes and is intentionally out of scope for this p
230
241
  |---|---|
231
242
  | `kiro-cli is not installed` during auth | Install kiro-cli from <https://kiro.dev/docs/cli/> and ensure it is on `PATH` for the opencode process. |
232
243
  | Auth times out after ~120s | Complete the browser login faster, or run `kiro-cli login` yourself, then re-run `opencode auth login` (fast path). |
233
- | No credits line / credits stay 0 | Credits appear after the first **completed** kiro turn; cancelled turns and turns without usage metadata contribute nothing. Check the TUI plugin is `active` in the Plugins dialog (and listed in `tui.json`). |
234
- | Credits box never appears (even with `tui.json` configured correctly) | The TUI credits box renders only when `opencode-kiro` is resolvable in opencode's package cache. If the package is missing from the cache the box silently does not appear. Fix: ensure `opencode-kiro` is installed so it resolves in the cache. Do **not** manually clear the package cache: clearing can trigger a flaky on-demand refetch that fails with an "unknown git error". |
235
- | `kiro` provider not showing in `opencode models` | The provider comes from the models.dev catalog, not this plugin. Ensure your opencode version ships a catalog that includes `kiro` (run `opencode models --refresh` to update the cache). For local development, point opencode at a kiro-inclusive catalog via `OPENCODE_MODELS_PATH=/path/to/api.json` (see [Local development](#local-development-path-source)). |
244
+ | No credits line / credits stay 0 | Credits appear after the first **completed** kiro turn; cancelled turns and turns without usage state contribute nothing. Check `"opencode-kiro"` is listed in your global `cli.json` `plugins` array. |
245
+ | Credits box never appears | The TUI entry loads from the global `cli.json` `plugins` array only a server-side `plugins` entry alone does not enable it. Add the `cli.json` entry and restart opencode. |
246
+ | `kiro` provider not showing in `opencode models` | Run `opencode auth login` first: models are discovered after auth. If the loaded catalog lacks a `kiro` entry, the plugin self-registers a minimal fallback during discovery. |
236
247
  | Path install rejected (`must export id`) | Run `npm run build` in your checkout first and reference the repo root (both entry modules export ids). |
237
- | Provider visible but runs fail | The provider is selectable (from the catalog) before any credential exists. Run `opencode auth login` first. |
248
+ | Provider visible but runs fail | The provider can be selectable before any credential exists. Run `opencode auth login` first. |
249
+ | Worked yesterday, broken today | This prerelease targets one pinned OpenCode snapshot (see [Compatibility](#compatibility)). If your OpenCode build moved past the tested SHA, the v2 plugin surface may have changed underneath it. |
250
+
251
+ ## Legacy: v1 / OpenCode v1 users (`0.4.0`)
252
+
253
+ `opencode-kiro@0.4.0` on the `main` branch is the supported stable line for OpenCode
254
+ v1 (`opencode >= 1.16.0`). It uses the v1 contract throughout: singular `plugin`
255
+ arrays in `opencode.json` and `tui.json`, the `opencode plugin opencode-kiro`
256
+ installer, and `part.metadata.kiro` credits. Its full documentation is the README at
257
+ the [`v0.4.0` tag](https://github.com/NachoFLizaur/opencode-kiro/tree/v0.4.0)
258
+ (equivalently, `main`). Do not install `0.5.0-beta.1` into an OpenCode v1 setup.
238
259
 
239
260
  ## Development
240
261
 
@@ -0,0 +1,40 @@
1
+ // src/tui/credits.ts
2
+ function isRecord(value) {
3
+ return typeof value === "object" && value !== null;
4
+ }
5
+ function readCreditState(state) {
6
+ if (!isRecord(state)) return void 0;
7
+ if (typeof state.credits !== "number" || !Number.isFinite(state.credits)) return void 0;
8
+ return {
9
+ credits: state.credits,
10
+ unit: typeof state.creditsUnit === "string" && state.creditsUnit.length > 0 ? state.creditsUnit : void 0
11
+ };
12
+ }
13
+ function readPartCredits(part) {
14
+ if (!isRecord(part)) return void 0;
15
+ if (part.type !== "text" && part.type !== "reasoning") return void 0;
16
+ return readCreditState(part.state);
17
+ }
18
+ function messageCredits(parts) {
19
+ const carriers = parts.map(readPartCredits).filter((value) => value !== void 0);
20
+ const last = carriers.at(-1);
21
+ if (!last) return void 0;
22
+ return {
23
+ credits: last.credits,
24
+ unit: last.unit ?? carriers.findLast((carrier) => carrier.unit !== void 0)?.unit
25
+ };
26
+ }
27
+ var creditsAmount = new Intl.NumberFormat("en-US", { maximumFractionDigits: 2 });
28
+ function formatCredits(value, unit) {
29
+ const amount = creditsAmount.format(Number.isFinite(value) ? value : 0);
30
+ if (!unit) return amount;
31
+ const label = value === 1 || unit.endsWith("s") ? unit : `${unit}s`;
32
+ return `${amount} ${label}`;
33
+ }
34
+ var money = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" });
35
+
36
+ export {
37
+ readCreditState,
38
+ messageCredits,
39
+ formatCredits
40
+ };
@@ -0,0 +1,35 @@
1
+ import {
2
+ formatCredits
3
+ } from "./chunk-M7OUVABX.js";
4
+
5
+ // src/tui/credits-box-view.ts
6
+ import { createElement, insert, insertNode } from "@opentui/solid";
7
+ import { createMemo } from "solid-js";
8
+ function createCreditsBoxView(credits) {
9
+ const current = createMemo(credits);
10
+ const root = createElement("box");
11
+ insertNode(
12
+ root,
13
+ headerLine(() => current().present ? "Kiro" : "")
14
+ );
15
+ insertNode(
16
+ root,
17
+ plainLine(() => current().present ? formatCredits(current().total, current().unit) : "")
18
+ );
19
+ return root;
20
+ }
21
+ function headerLine(content) {
22
+ const line = createElement("text");
23
+ const bold = createElement("b");
24
+ insert(bold, content);
25
+ insertNode(line, bold);
26
+ return line;
27
+ }
28
+ function plainLine(content) {
29
+ const line = createElement("text");
30
+ insert(line, content);
31
+ return line;
32
+ }
33
+ export {
34
+ createCreditsBoxView
35
+ };
package/dist/server.d.ts CHANGED
@@ -1,20 +1,7 @@
1
- import { Plugin, PluginInput, Hooks } from '@opencode-ai/plugin';
1
+ import { Plugin } from '@opencode-ai/plugin';
2
2
 
3
- declare function kiroTokenPath(): string;
4
- declare function readToken(tokenPath: string | undefined): Promise<{
5
- type: "success";
6
- refresh: string;
7
- access: string;
8
- expires: number;
9
- } | {
10
- type: "failed";
11
- }>;
12
- declare function notifyIfTokenExpired(client: PluginInput["client"] | undefined): Promise<void>;
13
- declare function enableSidebarConfig(path: string, input: PluginInput): Promise<void>;
14
- declare const KiroAuthPlugin: Plugin;
15
- declare const _default: {
16
- id: string;
17
- server: (input: PluginInput) => Promise<Hooks>;
18
- };
3
+ declare const plugin: Plugin.Plugin;
19
4
 
20
- export { KiroAuthPlugin, _default as default, enableSidebarConfig, kiroTokenPath, notifyIfTokenExpired, readToken };
5
+ declare const KiroAuthPlugin: Plugin.Plugin;
6
+
7
+ export { KiroAuthPlugin, plugin as default };