@zhafron/opencode-kiro-auth 1.3.0 → 1.3.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.
@@ -91,18 +91,29 @@ export class AccountManager {
91
91
  }
92
92
  return !(a.rateLimitResetTime && now < a.rateLimitResetTime);
93
93
  });
94
- if (available.length === 0)
95
- return null;
96
94
  let selected;
97
- if (this.strategy === 'sticky') {
98
- selected = available.find((_, i) => i === this.cursor) || available[0];
99
- }
100
- else if (this.strategy === 'round-robin') {
101
- selected = available[this.cursor % available.length];
102
- this.cursor = (this.cursor + 1) % available.length;
95
+ if (available.length > 0) {
96
+ if (this.strategy === 'sticky') {
97
+ selected = available.find((_, i) => i === this.cursor) || available[0];
98
+ }
99
+ else if (this.strategy === 'round-robin') {
100
+ selected = available[this.cursor % available.length];
101
+ this.cursor = (this.cursor + 1) % available.length;
102
+ }
103
+ else if (this.strategy === 'lowest-usage') {
104
+ selected = [...available].sort((a, b) => (a.usedCount || 0) - (b.usedCount || 0) || (a.lastUsed || 0) - (b.lastUsed || 0))[0];
105
+ }
103
106
  }
104
- else if (this.strategy === 'lowest-usage') {
105
- selected = [...available].sort((a, b) => (a.usedCount || 0) - (b.usedCount || 0) || (a.lastUsed || 0) - (b.lastUsed || 0))[0];
107
+ if (!selected) {
108
+ const fallback = this.accounts
109
+ .filter((a) => !a.isHealthy)
110
+ .sort((a, b) => (a.usedCount || 0) - (b.usedCount || 0) || (a.lastUsed || 0) - (b.lastUsed || 0))[0];
111
+ if (fallback) {
112
+ fallback.isHealthy = true;
113
+ delete fallback.unhealthyReason;
114
+ delete fallback.recoveryTime;
115
+ selected = fallback;
116
+ }
106
117
  }
107
118
  if (selected) {
108
119
  selected.lastUsed = now;
@@ -175,7 +186,7 @@ export class AccountManager {
175
186
  if (acc) {
176
187
  acc.isHealthy = false;
177
188
  acc.unhealthyReason = reason;
178
- acc.recoveryTime = recovery;
189
+ acc.recoveryTime = recovery || Date.now() + 3600000;
179
190
  kiroDb.upsertAccount(acc);
180
191
  }
181
192
  }
@@ -9,8 +9,6 @@ export declare class KiroDatabase {
9
9
  deleteAccount(id: string): void;
10
10
  getUsage(): Record<string, UsageMetadata>;
11
11
  upsertUsage(id: string, meta: UsageMetadata): void;
12
- getSetting(key: string): string | null;
13
- setSetting(key: string, value: string): void;
14
12
  close(): void;
15
13
  }
16
14
  export declare const kiroDb: KiroDatabase;
@@ -37,7 +37,6 @@ export class KiroDatabase {
37
37
  FOREIGN KEY(account_id) REFERENCES accounts(id) ON DELETE CASCADE
38
38
  )
39
39
  `);
40
- this.db.run('CREATE TABLE IF NOT EXISTS settings (key TEXT PRIMARY KEY, value TEXT)');
41
40
  }
42
41
  getAccounts() {
43
42
  return this.db.prepare('SELECT * FROM accounts').all();
@@ -88,15 +87,6 @@ export class KiroDatabase {
88
87
  `)
89
88
  .run(id, meta.usedCount, meta.limitCount, meta.realEmail || null, meta.lastSync);
90
89
  }
91
- getSetting(key) {
92
- const row = this.db.prepare('SELECT value FROM settings WHERE key = ?').get(key);
93
- return row ? row.value : null;
94
- }
95
- setSetting(key, value) {
96
- this.db
97
- .prepare('INSERT INTO settings (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value=excluded.value')
98
- .run(key, value);
99
- }
100
90
  close() {
101
91
  this.db.close();
102
92
  }
@@ -47,7 +47,7 @@ export async function syncFromKiroCli() {
47
47
  const id = createDeterministicAccountId(email, authMethod, clientId, data.profile_arn);
48
48
  const existing = kiroDb.getAccounts().find((a) => a.id === id);
49
49
  const cliExpiresAt = data.expires_at ? new Date(data.expires_at).getTime() : 0;
50
- if (existing && existing.expires_at >= cliExpiresAt)
50
+ if (existing && existing.is_healthy === 1 && existing.expires_at >= cliExpiresAt)
51
51
  continue;
52
52
  kiroDb.upsertAccount({
53
53
  id,
@@ -77,7 +77,7 @@ export async function writeToKiroCli(acc) {
77
77
  return;
78
78
  try {
79
79
  const cliDb = new Database(dbPath);
80
- cliDb.exec('PRAGMA busy_timeout = 5000');
80
+ cliDb.run('PRAGMA busy_timeout = 5000');
81
81
  const rows = cliDb.prepare('SELECT key, value FROM auth_kv').all();
82
82
  const targetKey = acc.authMethod === 'idc' ? 'kirocli:odic:token' : 'kirocli:social:token';
83
83
  const row = rows.find((r) => r.key === targetKey || r.key.endsWith(targetKey));
package/dist/plugin.js CHANGED
@@ -87,6 +87,14 @@ export const createKiroPlugin = (id) => async ({ client, directory }) => {
87
87
  }
88
88
  throw new Error('All accounts are unhealthy or rate-limited');
89
89
  }
90
+ if (count > 1 && am.shouldShowToast())
91
+ showToast(`Using ${acc.realEmail || acc.email} (${am.getAccounts().indexOf(acc) + 1}/${count})`, 'info');
92
+ if (am.shouldShowUsageToast() &&
93
+ acc.usedCount !== undefined &&
94
+ acc.limitCount !== undefined) {
95
+ const p = acc.limitCount > 0 ? (acc.usedCount / acc.limitCount) * 100 : 0;
96
+ showToast(formatUsageMessage(acc.usedCount, acc.limitCount, acc.realEmail || acc.email), p >= 80 ? 'warning' : 'info');
97
+ }
90
98
  const auth = am.toAuthDetails(acc);
91
99
  if (accessTokenExpired(auth, config.token_expiry_buffer_ms)) {
92
100
  try {
@@ -294,10 +302,9 @@ export const createKiroPlugin = (id) => async ({ client, directory }) => {
294
302
  const accounts = [];
295
303
  let startFresh = true;
296
304
  const existingAm = await AccountManager.loadFromDisk(config.account_selection_strategy);
297
- const allAccounts = existingAm.getAccounts();
298
- const idcAccounts = allAccounts.filter((a) => a.authMethod === 'idc');
299
- if (idcAccounts.length > 0) {
300
- const existingAccounts = idcAccounts.map((acc, idx) => ({
305
+ const idcAccs = existingAm.getAccounts().filter((a) => a.authMethod === 'idc');
306
+ if (idcAccs.length > 0) {
307
+ const existingAccounts = idcAccs.map((acc, idx) => ({
301
308
  email: acc.realEmail || acc.email,
302
309
  index: idx
303
310
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhafron/opencode-kiro-auth",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "OpenCode plugin for AWS Kiro (CodeWhisperer) providing access to Claude models",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",