@magpie-community/opencode-kiro-auth 0.1.13 → 0.1.14

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.
Files changed (3) hide show
  1. package/README.md +11 -4
  2. package/index.mjs +23 -5
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -17,14 +17,21 @@ Power) and makes its requests, in OpenCode and in magpie. Provider id:
17
17
  - Builder ID and Identity Center come back with an AWS sign-in URL and
18
18
  region. The plugin registers a client with AWS's OIDC service, sends
19
19
  the browser to AWS, and trades the code AWS returns.
20
- - The account is named by the email Kiro has for it (`Get-Usage-Limits`),
21
- and its plan is read from the same call.
20
+ - The account is named by the email Kiro has for it (`Get-Usage-Limits`)
21
+ and the way it was signed in to: `email (Google)`, `email (GitHub)`,
22
+ `email (Builder ID)`, `email (IAM Identity Center)`, `email
23
+ (Internal)`. Its plan is read from the same call, and its usage names
24
+ it the same way.
22
25
  - Kiro keeps a Google, a GitHub, a Builder ID and an Identity Center
23
26
  sign-in of one email as different accounts. The sign-in carries a `uid`
24
27
  (`google`, `github`, `builderid`, `enterprise`), so magpie keeps each one
25
28
  beside the others, and a sign-in again the same way replaces only its
26
- own account. An account signed in before 0.1.13 is given its `uid` on
27
- its first request, model listing, usage read or renewal.
29
+ own account. An account signed in before 0.1.13 is given its `uid`,
30
+ and one named by its bare email before 0.1.14 its name, on its first
31
+ request, model listing, usage read or renewal. Until then, a sign-in
32
+ again the same way goes beside it rather than replacing it: magpie
33
+ matches a sign-in by its name, and the plugin can't see the other
34
+ accounts to match it by `uid`.
28
35
  - A company's own identity provider (`external_idp`) is not supported
29
36
  here. Sign in with `kiro-cli login` and use the next method instead.
30
37
  - **Kiro CLI's or Kiro IDE's sign-in**: uses the account kiro-cli is signed
package/index.mjs CHANGED
@@ -56,6 +56,15 @@ const isBuilderID = (provider) => String(provider ?? "").toLowerCase() === "buil
56
56
  // keeps a sign-in of an email already signed in as that account unless
57
57
  // both have a uid and the two differ (#309). "" when it isn't known.
58
58
  const uidOf = (loginProvider) => String(loginProvider ?? "").trim().toLowerCase()
59
+ // nameOf is what an account is called: its email and the way it was signed
60
+ // in to, as Kiro's sign-in page names it, so two accounts of one email read
61
+ // apart (#309; magpie names a plugin's account by its accountId). A way not
62
+ // known, kiro-cli's or the Kiro IDE's sign-in among them, leaves the email
63
+ // as it is, and magpie tells two such apart by their slot.
64
+ const WAYS = { google: "Google", github: "GitHub", builderid: "Builder ID", enterprise: "IAM Identity Center", internal: "Internal" }
65
+ const nameOf = (email, loginProvider) => (WAYS[uidOf(loginProvider)] ? `${email} (${WAYS[uidOf(loginProvider)]})` : email)
66
+ // a bare email: what an account was called before nameOf
67
+ const bareEmail = (id) => typeof id === "string" && /^[^\s()]+@[^\s()]+$/.test(id)
59
68
 
60
69
  const env = (k) => process.env[k] ?? ""
61
70
  const home = () => env("HOME") || homedir()
@@ -448,11 +457,17 @@ function account(client) {
448
457
  // sign-in with another way to the same email no longer replaces it
449
458
  const uidSaved = new Set()
450
459
  const uidField = (auth) => (!auth?.uid && uidOf(auth?.loginProvider) ? { uid: uidOf(auth.loginProvider) } : {})
460
+ // and one called by its bare email is given its name, the way it was
461
+ // signed in to with it
462
+ const nameField = (auth) =>
463
+ bareEmail(auth?.accountId) && nameOf(auth.accountId, auth.loginProvider) !== auth.accountId
464
+ ? { accountId: nameOf(auth.accountId, auth.loginProvider) } : {}
465
+ const idFields = (auth) => ({ ...uidField(auth), ...nameField(auth) })
451
466
  const save = async (auth, c) => {
452
467
  if (!c.own || !client?.auth?.set) return
453
468
  const { type: _t, ...rest } = auth
454
469
  await client.auth.set({ path: { id: ID }, body: { ...rest, type: "oauth", access: c.access, refresh: c.refresh, expires: c.expires,
455
- profileArn: c.profile, region: c.region, ...uidField(auth) } }).catch(() => {})
470
+ profileArn: c.profile, region: c.region, ...idFields(auth) } }).catch(() => {})
456
471
  }
457
472
  const creds = (auth, stale = false) =>
458
473
  locked(async () => {
@@ -490,7 +505,7 @@ function account(client) {
490
505
  }
491
506
  }
492
507
  // once per token: a save that didn't take isn't tried on every request
493
- if (!saved && c.own && uidField(auth).uid && !uidSaved.has(c.access)) {
508
+ if (!saved && c.own && Object.keys(idFields(auth)).length && !uidSaved.has(c.access)) {
494
509
  uidSaved.add(c.access)
495
510
  await save(auth, c)
496
511
  }
@@ -513,7 +528,7 @@ function account(client) {
513
528
  const out = { access: c.access, expires: c.expires }
514
529
  if (c.refresh !== auth.refresh) out.refresh = c.refresh
515
530
  if (c.profile && c.profile !== auth.profileArn) out.profileArn = c.profile
516
- return { ...out, ...uidField(auth) }
531
+ return { ...out, ...idFields(auth) }
517
532
  })
518
533
  return creds
519
534
  }
@@ -1423,7 +1438,7 @@ async function browserSignIn() {
1423
1438
  return fail(e.message)
1424
1439
  }
1425
1440
  const who = await whoIs(c)
1426
- const user = who.email || "Kiro account"
1441
+ const user = who.email ? nameOf(who.email, c.loginProvider) : "Kiro account"
1427
1442
  finish({ type: "success", provider: ID, refresh: c.refresh, access: c.access, expires: c.expires, accountId: user,
1428
1443
  ...(uidOf(c.loginProvider) ? { uid: uidOf(c.loginProvider) } : {}),
1429
1444
  method: c.method, loginProvider: c.loginProvider, region: c.region, profileArn: who.profile,
@@ -1515,7 +1530,10 @@ export async function KiroAuthPlugin({ client } = {}) {
1515
1530
  const auth = await getAuth()
1516
1531
  if (!(auth?.type === "api" && auth.key) && auth?.type !== "oauth") return { error: "not signed in", signIn: "kept" }
1517
1532
  try {
1518
- return { ...usageOf(await usageLimits(await creds(auth), true)), signIn: "kept" }
1533
+ const u = usageOf(await usageLimits(await creds(auth), true))
1534
+ // named as the account is
1535
+ if (u.user && auth.type === "oauth" && !auth.source) u.user = nameOf(u.user, auth.loginProvider)
1536
+ return { ...u, signIn: "kept" }
1519
1537
  } catch (e) {
1520
1538
  return { error: e.message, signIn: "kept" }
1521
1539
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magpie-community/opencode-kiro-auth",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
4
4
  "description": "Kiro subscriptions (Free, Pro, Pro+, Power) in OpenCode and magpie",
5
5
  "type": "module",
6
6
  "main": "./index.mjs",