@bogyie/opencode-kiro-plugin 0.3.10 → 0.3.12
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 +5 -5
- package/dist/plugin.js +21 -62
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -38,9 +38,9 @@ The plugin resolves credentials in this order:
|
|
|
38
38
|
3. Local Kiro CLI session token from the Kiro CLI SQLite store
|
|
39
39
|
4. `kiro-cli whoami` diagnostics for CLI session visibility
|
|
40
40
|
|
|
41
|
-
OpenCode startup does not start Kiro login or model discovery. The plugin injects
|
|
41
|
+
OpenCode startup does not start Kiro login or model discovery. The plugin injects `provider.kiro` with an `auto` placeholder model so Kiro appears in OpenCode's provider connector. Model discovery runs only when you explicitly call the `kiro_refresh_models` plugin tool; if discovery succeeds, later model-list requests use the latest in-memory cache. If discovery fails, the previous cache remains in use.
|
|
42
42
|
|
|
43
|
-
You can open OpenCode's provider connector, choose Kiro, and select `Kiro device login`.
|
|
43
|
+
You can open OpenCode's provider connector, choose Kiro, and select `Kiro device login`. The connector runs `kiro-cli login --use-device-flow`, waits for the local Kiro CLI session to become authenticated, then stores a local transport marker in OpenCode auth. If `login.identityProvider`, `login.region`, `login.license`, or `login.extraArgs` are configured, those options are passed to `kiro-cli login` along with `--use-device-flow`. After login succeeds, the plugin also tries to refresh the runtime model cache. If no OpenCode connector marker or API key is configured, direct fetch still reads the active Kiro CLI session token and calls Kiro's REST/EventStream endpoint directly. If an API/model call fails with an auth error, the selected transport starts the same configured Kiro CLI login flow and retries the request once. `cli-chat` mode uses the official `kiro-cli chat --no-interactive` surface and depends on the local Kiro CLI login state. `acp` mode uses the official `kiro-cli acp` surface, but is still treated as an explicit backend while its real-world protocol behavior is validated across Kiro CLI versions.
|
|
44
44
|
|
|
45
45
|
For AWS IAM Identity Center login, configure the default device-flow Start URL separately from the API region:
|
|
46
46
|
|
|
@@ -62,7 +62,7 @@ For AWS IAM Identity Center login, configure the default device-flow Start URL s
|
|
|
62
62
|
}
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
For IAM Identity Center,
|
|
65
|
+
For IAM Identity Center, configure `login.identityProvider` and `login.region` in plugin options so they are passed to `kiro-cli login --use-device-flow`.
|
|
66
66
|
|
|
67
67
|
Use the `kiro_status` plugin tool to inspect provider id, backend, region, auth method, and discovered model count. Use `kiro_refresh_models` when you explicitly want to run the configured model discovery command and update the in-memory model cache. Secrets are redacted in diagnostics.
|
|
68
68
|
|
|
@@ -105,7 +105,7 @@ Supported values:
|
|
|
105
105
|
|
|
106
106
|
## Model Churn Handling
|
|
107
107
|
|
|
108
|
-
The resolver intentionally avoids a hard whitelist. Startup
|
|
108
|
+
The resolver intentionally avoids a hard whitelist. Startup adds a fallback `auto` model so the provider can be connected before discovery succeeds. When you run `kiro_refresh_models`, the plugin reads the current Kiro CLI model list with `kiro-cli chat --list-models --format json`. Runtime discovery is the source of truth for the model picker once it has succeeded; failed refreshes do not clear the last successful cache.
|
|
109
109
|
|
|
110
110
|
Useful options:
|
|
111
111
|
|
|
@@ -153,7 +153,7 @@ Resolution order:
|
|
|
153
153
|
|
|
154
154
|
This keeps new Kiro model ids usable before the package is updated without advertising unavailable models in OpenCode's picker after discovery has succeeded. Use `extraModels` only when you explicitly want a model to appear even though it is not listed by your installed Kiro CLI. Set `disableModelPassThrough: true` only when you need strict model governance.
|
|
155
155
|
|
|
156
|
-
The plugin injects
|
|
156
|
+
The plugin injects `provider.kiro` with the `auto` placeholder needed for OpenCode's provider connector. Define `provider.kiro.models` yourself only when you need explicit model-picker metadata such as a display name or context limit. Use plugin `modelAliases` for aliases that should resolve one requested model id to another.
|
|
157
157
|
|
|
158
158
|
`modelDiscoveryCommand` defaults to `["kiro-cli", "chat", "--list-models", "--format", "json"]`. Set `modelDiscovery` to `"off"` to disable `kiro_refresh_models`. Discovery is best-effort and never runs during OpenCode startup; authenticate manually through the connector or let an API/model request handle auth failure. Discovery stdout can be a JSON array, `{ "models": [...] }`, `{ "data": [...] }`, Kiro CLI list-models JSON, Kiro CLI plain list output, or one model id per line.
|
|
159
159
|
|
package/dist/plugin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { tool } from "@opencode-ai/plugin";
|
|
2
2
|
import { KiroAcpTransport } from "./acp-transport.js";
|
|
3
|
-
import {
|
|
3
|
+
import { credentialFromKiroDeviceAuthKey, detectAuth, isKiroDeviceAuthKey, readKiroCliSessionCredential, resolveApiKey, startKiroCliLoginOnce, runKiroLoginFlowOnce, } from "./auth.js";
|
|
4
4
|
import { KiroCliChatTransport } from "./cli-transport.js";
|
|
5
5
|
import { loadOptions } from "./config.js";
|
|
6
6
|
import { createKiroFetch } from "./fetch-adapter.js";
|
|
@@ -9,6 +9,8 @@ import { ModelCache } from "./model-cache.js";
|
|
|
9
9
|
import { refreshModelCacheFromCommand } from "./model-discovery.js";
|
|
10
10
|
import { ModelResolver, normalizeModelName } from "./model-resolver.js";
|
|
11
11
|
import { KiroRestTransport } from "./kiro-rest-transport.js";
|
|
12
|
+
const PLACEHOLDER_MODEL_ID = "auto";
|
|
13
|
+
const PLACEHOLDER_MODEL = { name: "Auto" };
|
|
12
14
|
function discoveredProviderModels(cache) {
|
|
13
15
|
return Object.fromEntries(cache.all().map((model) => [
|
|
14
16
|
model.id,
|
|
@@ -42,17 +44,15 @@ function visibleProviderModels(cache, configuredModels, hiddenModels, disabledMo
|
|
|
42
44
|
...(configuredModels[id] ?? {}),
|
|
43
45
|
},
|
|
44
46
|
]));
|
|
45
|
-
|
|
47
|
+
if (Object.keys(models).length > 0 || disabledModels.has(PLACEHOLDER_MODEL_ID))
|
|
48
|
+
return models;
|
|
49
|
+
return { [PLACEHOLDER_MODEL_ID]: PLACEHOLDER_MODEL };
|
|
46
50
|
}
|
|
47
51
|
function bearerToken(init) {
|
|
48
52
|
const header = new Headers(init?.headers).get("authorization");
|
|
49
53
|
const match = header?.match(/^Bearer\s+(.+)$/i);
|
|
50
54
|
return match?.[1] || undefined;
|
|
51
55
|
}
|
|
52
|
-
function inputString(inputs, key) {
|
|
53
|
-
const value = inputs?.[key];
|
|
54
|
-
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
55
|
-
}
|
|
56
56
|
export function effectiveBackend(options, accessToken) {
|
|
57
57
|
const apiKey = accessToken || process.env.KIRO_API_KEY;
|
|
58
58
|
if (options.backend === "acp")
|
|
@@ -160,36 +160,26 @@ export function createKiroPlugin() {
|
|
|
160
160
|
localServer = await startLocalKiroServer(localFetch);
|
|
161
161
|
return localServer;
|
|
162
162
|
};
|
|
163
|
-
const
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
const authorization = await authorizeKiroDevice({
|
|
168
|
-
region: idcRegion,
|
|
169
|
-
...(startUrl ? { identityProvider: startUrl } : {}),
|
|
163
|
+
const authorizeCliDeviceLogin = async () => {
|
|
164
|
+
const session = startKiroCliLoginOnce({
|
|
165
|
+
...options.login,
|
|
166
|
+
useDeviceFlow: true,
|
|
170
167
|
});
|
|
171
|
-
|
|
168
|
+
await session.waitForPrompt(options.requestTimeoutMs);
|
|
172
169
|
return {
|
|
173
|
-
url,
|
|
174
|
-
instructions:
|
|
170
|
+
url: session.url,
|
|
171
|
+
instructions: session.instructions,
|
|
175
172
|
method: "auto",
|
|
176
173
|
callback: async () => {
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
const key = encodeKiroDeviceAuthKey(credential);
|
|
174
|
+
const authenticated = await session.waitForAuth();
|
|
175
|
+
if (!authenticated)
|
|
176
|
+
return { type: "failed" };
|
|
177
|
+
await refreshModels(true).catch(() => []);
|
|
182
178
|
return {
|
|
183
179
|
type: "success",
|
|
184
|
-
key,
|
|
185
|
-
access: key,
|
|
186
|
-
refresh: credential.refreshToken,
|
|
187
|
-
expires: credential.expiresAt,
|
|
180
|
+
key: "kiro-plugin-local-transport",
|
|
188
181
|
metadata: {
|
|
189
|
-
source: "kiro-device-
|
|
190
|
-
region: credential.region,
|
|
191
|
-
oidcRegion: credential.oidcRegion,
|
|
192
|
-
...(credential.profileArn ? { profileArn: credential.profileArn } : {}),
|
|
182
|
+
source: "kiro-cli-device-flow",
|
|
193
183
|
},
|
|
194
184
|
};
|
|
195
185
|
},
|
|
@@ -221,39 +211,8 @@ export function createKiroPlugin() {
|
|
|
221
211
|
methods: [
|
|
222
212
|
{
|
|
223
213
|
type: "oauth",
|
|
224
|
-
label:
|
|
225
|
-
authorize: async () =>
|
|
226
|
-
},
|
|
227
|
-
{
|
|
228
|
-
type: "oauth",
|
|
229
|
-
label: "Kiro device login (custom)",
|
|
230
|
-
prompts: [
|
|
231
|
-
{
|
|
232
|
-
type: "text",
|
|
233
|
-
key: "startUrl",
|
|
234
|
-
message: options.login.identityProvider
|
|
235
|
-
? `IAM Identity Center Start URL (current: ${options.login.identityProvider}, leave blank to keep)`
|
|
236
|
-
: "IAM Identity Center Start URL (leave blank for AWS Builder ID)",
|
|
237
|
-
placeholder: "https://your-company.awsapps.com/start",
|
|
238
|
-
},
|
|
239
|
-
{
|
|
240
|
-
type: "text",
|
|
241
|
-
key: "idcRegion",
|
|
242
|
-
message: options.login.region && options.login.region !== "us-east-1"
|
|
243
|
-
? `IAM Identity Center region (current: ${options.login.region}, leave blank to keep)`
|
|
244
|
-
: "IAM Identity Center region (leave blank for us-east-1)",
|
|
245
|
-
placeholder: "us-east-1",
|
|
246
|
-
},
|
|
247
|
-
{
|
|
248
|
-
type: "text",
|
|
249
|
-
key: "profileArn",
|
|
250
|
-
message: options.profileArn
|
|
251
|
-
? `Profile ARN (current: ${options.profileArn}, leave blank to keep)`
|
|
252
|
-
: "Profile ARN (optional, improves region/profile routing for IAM Identity Center)",
|
|
253
|
-
placeholder: "arn:aws:codewhisperer:us-east-1:123456789012:profile/XXXXXXXXXX",
|
|
254
|
-
},
|
|
255
|
-
],
|
|
256
|
-
authorize: async (inputs) => authorizeDeviceLogin(inputs),
|
|
214
|
+
label: "Kiro device login",
|
|
215
|
+
authorize: async () => authorizeCliDeviceLogin(),
|
|
257
216
|
},
|
|
258
217
|
{
|
|
259
218
|
type: "api",
|