opencode-kiro 0.3.1 → 0.3.3
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/server.js +32 -35
- package/dist/tui.d.ts +6 -11
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
// src/server.ts
|
|
2
|
+
import { readFileSync } from "fs";
|
|
2
3
|
import { homedir } from "os";
|
|
3
4
|
import { dirname, join } from "path";
|
|
4
5
|
var KIRO_PLUGIN_NAME = "opencode-kiro";
|
|
5
6
|
var server = async (input) => {
|
|
6
|
-
|
|
7
|
-
const tuiPath = tuiConfigPath();
|
|
8
|
-
const alreadyConfigured = isSidebarConfigured(await readTuiConfig(tuiPath));
|
|
9
|
-
const prompts = alreadyConfigured ? [] : [
|
|
7
|
+
const prompts = [
|
|
10
8
|
{
|
|
11
9
|
type: "select",
|
|
12
10
|
key: "sidebar",
|
|
@@ -20,18 +18,19 @@ var server = async (input) => {
|
|
|
20
18
|
return {
|
|
21
19
|
auth: {
|
|
22
20
|
provider: "kiro",
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
21
|
+
// options forwarded into createKiroAcp(). maps each model's limit.context into contextWindows by api.id; zero/missing skipped (SDK falls back to 1M).
|
|
22
|
+
loader: async (_getAuth, provider) => {
|
|
23
|
+
void notifyIfTokenExpired(input.client);
|
|
24
|
+
return {
|
|
25
|
+
cwd: input.directory ?? input.worktree,
|
|
26
|
+
agent: "opencode",
|
|
27
|
+
trustAllTools: true,
|
|
28
|
+
mcpTimeout: 45,
|
|
29
|
+
contextWindows: Object.fromEntries(
|
|
30
|
+
Object.values(provider?.models ?? {}).filter((m) => m.api?.id && (m.limit?.context ?? 0) > 0).map((m) => [m.api.id, m.limit.context])
|
|
31
|
+
)
|
|
32
|
+
};
|
|
33
|
+
},
|
|
35
34
|
methods: [
|
|
36
35
|
{
|
|
37
36
|
type: "oauth",
|
|
@@ -44,9 +43,8 @@ var server = async (input) => {
|
|
|
44
43
|
throw new Error(
|
|
45
44
|
"kiro-cli is not installed. Install it from https://kiro.dev/docs/cli/"
|
|
46
45
|
);
|
|
47
|
-
const enableSidebar = !alreadyConfigured && inputs?.sidebar === "yes";
|
|
48
46
|
const onSuccess = async () => {
|
|
49
|
-
if (
|
|
47
|
+
if (inputs?.sidebar === "yes") await enableSidebarConfig(tuiConfigPath(), input);
|
|
50
48
|
};
|
|
51
49
|
if (status.authenticated) {
|
|
52
50
|
return {
|
|
@@ -91,18 +89,18 @@ var server = async (input) => {
|
|
|
91
89
|
}
|
|
92
90
|
]
|
|
93
91
|
},
|
|
94
|
-
//
|
|
95
|
-
//
|
|
96
|
-
// auth init). Mutates in place; the ??= keeps it idempotent and never
|
|
97
|
-
// clobbers a real models.dev kiro entry when one is present.
|
|
92
|
+
// crash guard: core derefs an undefined kiro provider during auth init when a cred exists but the catalog lacks kiro.
|
|
93
|
+
// only inject when authed; ??= is idempotent and won't clobber a real catalog entry.
|
|
98
94
|
config: async (input2) => {
|
|
95
|
+
if (!hasStoredKiroCredential()) return;
|
|
99
96
|
input2.provider ??= {};
|
|
100
97
|
input2.provider.kiro ??= {};
|
|
101
98
|
},
|
|
102
99
|
provider: {
|
|
103
100
|
id: "kiro",
|
|
104
|
-
//
|
|
105
|
-
async models(provider,
|
|
101
|
+
// inject per-model reasoning-effort variants (consumed as providerOptions.kiro.reasoningEffort)
|
|
102
|
+
async models(provider, ctx) {
|
|
103
|
+
if (!ctx.auth) return provider.models;
|
|
106
104
|
const { reasoningEffortsFor } = await import("kiro-acp-ai-provider");
|
|
107
105
|
for (const model of Object.values(provider.models)) {
|
|
108
106
|
const apiId = model.api?.id;
|
|
@@ -142,8 +140,7 @@ async function readToken(tokenPath) {
|
|
|
142
140
|
// real refresh when present, else ""
|
|
143
141
|
access: access || "authenticated",
|
|
144
142
|
// cosmetic; opencode-core only needs presence
|
|
145
|
-
//
|
|
146
|
-
// opencode-core does not flag a logged-in user as expired. NOT the file value.
|
|
143
|
+
// future expiry, refreshed each startup (server() re-runs per session) so core doesn't flag a logged-in user as expired. not the file value.
|
|
147
144
|
expires: Date.now() + 8 * 60 * 60 * 1e3
|
|
148
145
|
};
|
|
149
146
|
}
|
|
@@ -158,19 +155,19 @@ async function notifyIfTokenExpired(client) {
|
|
|
158
155
|
} catch {
|
|
159
156
|
}
|
|
160
157
|
}
|
|
161
|
-
function
|
|
162
|
-
const base = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
|
|
163
|
-
return join(base, "opencode", "tui.json");
|
|
164
|
-
}
|
|
165
|
-
async function readTuiConfig(path) {
|
|
158
|
+
function hasStoredKiroCredential() {
|
|
166
159
|
try {
|
|
167
|
-
const
|
|
168
|
-
const parsed = JSON.parse(
|
|
169
|
-
return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)
|
|
160
|
+
const path = process.env.XDG_DATA_HOME ? join(process.env.XDG_DATA_HOME, "opencode", "auth.json") : process.platform === "win32" ? join(homedir(), ".opencode", "auth.json") : join(homedir(), ".local", "share", "opencode", "auth.json");
|
|
161
|
+
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
162
|
+
return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) && "kiro" in parsed;
|
|
170
163
|
} catch {
|
|
171
|
-
return
|
|
164
|
+
return false;
|
|
172
165
|
}
|
|
173
166
|
}
|
|
167
|
+
function tuiConfigPath() {
|
|
168
|
+
const base = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
|
|
169
|
+
return join(base, "opencode", "tui.json");
|
|
170
|
+
}
|
|
174
171
|
function isSidebarConfigured(config) {
|
|
175
172
|
if (!config) return false;
|
|
176
173
|
const plugin = config.plugin;
|
package/dist/tui.d.ts
CHANGED
|
@@ -17,10 +17,8 @@ interface SessionCredits {
|
|
|
17
17
|
total: number;
|
|
18
18
|
unit?: string;
|
|
19
19
|
/**
|
|
20
|
-
* True once any assistant message carried kiro credit metadata. Lets the
|
|
21
|
-
*
|
|
22
|
-
* since a credits total of 0 (a real kiro turn) is indistinguishable from
|
|
23
|
-
* "no kiro metadata at all" by `total` alone.
|
|
20
|
+
* True once any assistant message carried kiro credit metadata. Lets the view pick credits over the
|
|
21
|
+
* "$X spent" fallback, since a 0-credit kiro turn is indistinguishable from no metadata by `total` alone.
|
|
24
22
|
*/
|
|
25
23
|
present: boolean;
|
|
26
24
|
}
|
|
@@ -35,14 +33,11 @@ declare function sumSessionCredits(messages: ReadonlyArray<CreditMessage>, parts
|
|
|
35
33
|
/** Render credits with the unit, e.g. "12.5 credits", "1 credit". Unit is naively pluralized unless it ends in "s"; with no unit, only the number renders. */
|
|
36
34
|
declare function formatCredits(value: number, unit?: string): string;
|
|
37
35
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* -
|
|
41
|
-
* ["$X.XX spent", "N credits"]
|
|
42
|
-
* - credits only (credits present, dollar cost 0): ["N credits"] (Kiro-only)
|
|
36
|
+
* Muted cost lines as an array (one per rendered row). Three states:
|
|
37
|
+
* - both (credits present + non-zero cost): ["$X.XX spent", "N credits"]
|
|
38
|
+
* - credits only (cost 0): ["N credits"]
|
|
43
39
|
* - dollars only (no credits): ["$X.XX spent"] (also ["$0.00 spent"] when empty)
|
|
44
|
-
*
|
|
45
|
-
* and `cost > 0`, never off `credits.total` alone.
|
|
40
|
+
* Keys off `credits.present` and `cost > 0`, never `credits.total` alone (a 0-credit kiro turn is present).
|
|
46
41
|
*/
|
|
47
42
|
declare function spendLines(input: {
|
|
48
43
|
cost: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-kiro",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "The ACP-compliant Kiro plugin for opencode: auth via the official kiro-cli login, the live Kiro model lineup through the Agent Client Protocol, and TUI credits display",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Nacho F. Lizaur (https://github.com/NachoFLizaur)",
|