@arvoretech/pi-kiro-provider 0.8.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 +121 -0
- package/dist/bracket-tool-parser.d.ts +12 -0
- package/dist/bracket-tool-parser.d.ts.map +1 -0
- package/dist/bracket-tool-parser.js +78 -0
- package/dist/bracket-tool-parser.js.map +1 -0
- package/dist/debug.d.ts +3 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +49 -0
- package/dist/debug.js.map +1 -0
- package/dist/event-parser.d.ts +44 -0
- package/dist/event-parser.d.ts.map +1 -0
- package/dist/event-parser.js +66 -0
- package/dist/event-parser.js.map +1 -0
- package/dist/history.d.ts +13 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +121 -0
- package/dist/history.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/kiro-cli.d.ts +32 -0
- package/dist/kiro-cli.d.ts.map +1 -0
- package/dist/kiro-cli.js +271 -0
- package/dist/kiro-cli.js.map +1 -0
- package/dist/kiro-ide.d.ts +13 -0
- package/dist/kiro-ide.d.ts.map +1 -0
- package/dist/kiro-ide.js +74 -0
- package/dist/kiro-ide.js.map +1 -0
- package/dist/login-ui.d.ts +18 -0
- package/dist/login-ui.d.ts.map +1 -0
- package/dist/login-ui.js +124 -0
- package/dist/login-ui.js.map +1 -0
- package/dist/login.d.ts +16 -0
- package/dist/login.d.ts.map +1 -0
- package/dist/login.js +217 -0
- package/dist/login.js.map +1 -0
- package/dist/models.d.ts +72 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +461 -0
- package/dist/models.js.map +1 -0
- package/dist/oauth.d.ts +30 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +226 -0
- package/dist/oauth.js.map +1 -0
- package/dist/retry.d.ts +21 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +51 -0
- package/dist/retry.js.map +1 -0
- package/dist/stream.d.ts +5 -0
- package/dist/stream.d.ts.map +1 -0
- package/dist/stream.js +858 -0
- package/dist/stream.js.map +1 -0
- package/dist/thinking-parser.d.ts +24 -0
- package/dist/thinking-parser.d.ts.map +1 -0
- package/dist/thinking-parser.js +205 -0
- package/dist/thinking-parser.js.map +1 -0
- package/dist/tokenizer.d.ts +2 -0
- package/dist/tokenizer.d.ts.map +1 -0
- package/dist/tokenizer.js +16 -0
- package/dist/tokenizer.js.map +1 -0
- package/dist/transform.d.ts +63 -0
- package/dist/transform.d.ts.map +1 -0
- package/dist/transform.js +200 -0
- package/dist/transform.js.map +1 -0
- package/dist/truncation.d.ts +4 -0
- package/dist/truncation.d.ts.map +1 -0
- package/dist/truncation.js +13 -0
- package/dist/truncation.js.map +1 -0
- package/dist/usage.d.ts +90 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +169 -0
- package/dist/usage.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kiro-cli.d.ts","sourceRoot":"","sources":["../src/kiro-cli.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIlE,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAmBrD;AAoED,wBAAgB,qBAAqB,IAAI,eAAe,GAAG,SAAS,CAoBnE;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,IAC9C,eAAe,GACf,SAAS,CAmBX;AAED,iBAAS,eAAe,CACvB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,cAAc,EAC1B,YAAY,UAAQ,GAClB,eAAe,GAAG,SAAS,CAuD7B;AAGD,OAAO,EAAE,eAAe,EAAE,CAAC;AAE3B;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,GAAG,SAAS,CAQnE;AAED;;;GAGG;AACH,wBAAgB,iCAAiC,IAC9C,eAAe,GACf,SAAS,CAQX;AAOD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAgCnE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,eAAe,GAAG,SAAS,CAY/D"}
|
package/dist/kiro-cli.js
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
// ABOUTME: Reads and writes credentials from the kiro-cli SQLite database.
|
|
2
|
+
// ABOUTME: Provides fallback auth and write-back to keep kiro-cli in sync after refresh.
|
|
3
|
+
import { execFileSync, execSync } from "node:child_process";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import { createRequire } from "node:module";
|
|
6
|
+
import { homedir, platform } from "node:os";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
export function getKiroCliDbPath() {
|
|
10
|
+
const p = platform();
|
|
11
|
+
let dbPath;
|
|
12
|
+
if (p === "win32")
|
|
13
|
+
dbPath = join(process.env.APPDATA || join(homedir(), "AppData", "Roaming"), "kiro-cli", "data.sqlite3");
|
|
14
|
+
else if (p === "darwin")
|
|
15
|
+
dbPath = join(homedir(), "Library", "Application Support", "kiro-cli", "data.sqlite3");
|
|
16
|
+
else
|
|
17
|
+
dbPath = join(homedir(), ".local", "share", "kiro-cli", "data.sqlite3");
|
|
18
|
+
return existsSync(dbPath) ? dbPath : undefined;
|
|
19
|
+
}
|
|
20
|
+
function getNodeSqlite() {
|
|
21
|
+
try {
|
|
22
|
+
return require("node:sqlite");
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function queryKiroCliDb(dbPath, sql) {
|
|
29
|
+
const sqlite = getNodeSqlite();
|
|
30
|
+
if (sqlite) {
|
|
31
|
+
try {
|
|
32
|
+
const db = new sqlite.DatabaseSync(dbPath, { readOnly: true });
|
|
33
|
+
try {
|
|
34
|
+
const rows = db.prepare(sql).all();
|
|
35
|
+
const result = JSON.stringify(rows);
|
|
36
|
+
return result === "[]" ? undefined : result;
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
db.close();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Fall through to sqlite3 CLI fallback
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const result = execSync(`sqlite3 -json "${dbPath}" "${sql}"`, {
|
|
48
|
+
encoding: "utf-8",
|
|
49
|
+
timeout: 5000,
|
|
50
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
51
|
+
}).trim();
|
|
52
|
+
return result || undefined;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function execKiroCliDb(dbPath, sql) {
|
|
59
|
+
const sqlite = getNodeSqlite();
|
|
60
|
+
if (sqlite) {
|
|
61
|
+
try {
|
|
62
|
+
const db = new sqlite.DatabaseSync(dbPath);
|
|
63
|
+
try {
|
|
64
|
+
db.exec(sql);
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
db.close();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// Fall through to sqlite3 CLI fallback
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
execSync(`sqlite3 "${dbPath}"`, {
|
|
77
|
+
input: sql,
|
|
78
|
+
encoding: "utf-8",
|
|
79
|
+
timeout: 5000,
|
|
80
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
81
|
+
});
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export function getKiroCliCredentials() {
|
|
89
|
+
const dbPath = getKiroCliDbPath();
|
|
90
|
+
if (!dbPath)
|
|
91
|
+
return undefined;
|
|
92
|
+
try {
|
|
93
|
+
// Try IDC token first (preferred — has clientId/clientSecret for refresh)
|
|
94
|
+
const idcCreds = tryKiroCliToken(dbPath, "kirocli:odic:token", "idc");
|
|
95
|
+
if (idcCreds)
|
|
96
|
+
return idcCreds;
|
|
97
|
+
// Fall back to desktop/social token
|
|
98
|
+
const desktopCreds = tryKiroCliToken(dbPath, "kirocli:social:token", "desktop");
|
|
99
|
+
if (desktopCreds)
|
|
100
|
+
return desktopCreds;
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Like getKiroCliCredentials but returns credentials even when the access token
|
|
109
|
+
* is expired, as long as a refresh token exists. Used to attempt a token refresh
|
|
110
|
+
* before falling back to the full device code login flow.
|
|
111
|
+
*/
|
|
112
|
+
export function getKiroCliCredentialsAllowExpired() {
|
|
113
|
+
const dbPath = getKiroCliDbPath();
|
|
114
|
+
if (!dbPath)
|
|
115
|
+
return undefined;
|
|
116
|
+
try {
|
|
117
|
+
const idcCreds = tryKiroCliToken(dbPath, "kirocli:odic:token", "idc", true);
|
|
118
|
+
if (idcCreds)
|
|
119
|
+
return idcCreds;
|
|
120
|
+
const desktopCreds = tryKiroCliToken(dbPath, "kirocli:social:token", "desktop", true);
|
|
121
|
+
if (desktopCreds)
|
|
122
|
+
return desktopCreds;
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function tryKiroCliToken(dbPath, tokenKey, authMethod, allowExpired = false) {
|
|
130
|
+
const tokenResult = queryKiroCliDb(dbPath, `SELECT value FROM auth_kv WHERE key = '${tokenKey}'`);
|
|
131
|
+
if (!tokenResult)
|
|
132
|
+
return undefined;
|
|
133
|
+
const rows = JSON.parse(tokenResult);
|
|
134
|
+
if (!rows[0]?.value)
|
|
135
|
+
return undefined;
|
|
136
|
+
const tokenData = JSON.parse(rows[0].value);
|
|
137
|
+
if (!tokenData.access_token || !tokenData.refresh_token)
|
|
138
|
+
return undefined;
|
|
139
|
+
let expiresAt = Date.now() + 3600000;
|
|
140
|
+
if (tokenData.expires_at)
|
|
141
|
+
expiresAt = new Date(tokenData.expires_at).getTime();
|
|
142
|
+
if (!allowExpired && Date.now() >= expiresAt - 2 * 60 * 1000)
|
|
143
|
+
return undefined;
|
|
144
|
+
const region = tokenData.region || "us-east-1";
|
|
145
|
+
if (authMethod === "desktop") {
|
|
146
|
+
return {
|
|
147
|
+
refresh: `${tokenData.refresh_token}|desktop`,
|
|
148
|
+
access: tokenData.access_token,
|
|
149
|
+
expires: expiresAt,
|
|
150
|
+
clientId: "",
|
|
151
|
+
clientSecret: "",
|
|
152
|
+
region,
|
|
153
|
+
authMethod: "desktop",
|
|
154
|
+
profileArn: tokenData.profile_arn || tokenData.profileArn,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
// IDC — need device registration credentials for refresh
|
|
158
|
+
let clientId = "";
|
|
159
|
+
let clientSecret = "";
|
|
160
|
+
// Match the device-registration key to the same prefix as the token key
|
|
161
|
+
const keyPrefix = tokenKey.split(":")[0]; // "kirocli" or "codewhisperer"
|
|
162
|
+
const deviceResult = queryKiroCliDb(dbPath, `SELECT value FROM auth_kv WHERE key = '${keyPrefix}:odic:device-registration'`);
|
|
163
|
+
if (deviceResult) {
|
|
164
|
+
try {
|
|
165
|
+
const d = JSON.parse(JSON.parse(deviceResult)[0]?.value);
|
|
166
|
+
clientId = d.client_id || d.clientId || "";
|
|
167
|
+
clientSecret = d.client_secret || d.clientSecret || "";
|
|
168
|
+
}
|
|
169
|
+
catch { }
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
refresh: `${tokenData.refresh_token}|${clientId}|${clientSecret}|idc`,
|
|
173
|
+
access: tokenData.access_token,
|
|
174
|
+
expires: expiresAt,
|
|
175
|
+
clientId,
|
|
176
|
+
clientSecret,
|
|
177
|
+
region,
|
|
178
|
+
authMethod: "idc",
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
// Re-export the internal function for use by getKiroCliSocialToken
|
|
182
|
+
export { tryKiroCliToken };
|
|
183
|
+
/**
|
|
184
|
+
* Get the social token (Google/GitHub) from kiro-cli if available.
|
|
185
|
+
* Returns undefined if no valid social token exists.
|
|
186
|
+
* This is used to prefer social login when the user has logged in that way.
|
|
187
|
+
*/
|
|
188
|
+
export function getKiroCliSocialToken() {
|
|
189
|
+
const dbPath = getKiroCliDbPath();
|
|
190
|
+
if (!dbPath)
|
|
191
|
+
return undefined;
|
|
192
|
+
try {
|
|
193
|
+
return tryKiroCliToken(dbPath, "kirocli:social:token", "desktop");
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Like getKiroCliSocialToken but returns credentials even when the access token
|
|
201
|
+
* is expired, as long as a refresh token exists.
|
|
202
|
+
*/
|
|
203
|
+
export function getKiroCliSocialTokenAllowExpired() {
|
|
204
|
+
const dbPath = getKiroCliDbPath();
|
|
205
|
+
if (!dbPath)
|
|
206
|
+
return undefined;
|
|
207
|
+
try {
|
|
208
|
+
return tryKiroCliToken(dbPath, "kirocli:social:token", "desktop", true);
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
return undefined;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
const TOKEN_KEY_BY_AUTH_METHOD = {
|
|
215
|
+
idc: ["kirocli:odic:token", "codewhisperer:odic:token"],
|
|
216
|
+
desktop: ["kirocli:social:token"],
|
|
217
|
+
};
|
|
218
|
+
export function saveKiroCliCredentials(creds) {
|
|
219
|
+
const dbPath = getKiroCliDbPath();
|
|
220
|
+
if (!dbPath)
|
|
221
|
+
return;
|
|
222
|
+
const rawRefreshToken = creds.refresh.split("|")[0] ?? "";
|
|
223
|
+
// Our expires has a 5-min buffer subtracted; restore approximate actual expiry for kiro-cli
|
|
224
|
+
const expiresAt = new Date(creds.expires + 5 * 60 * 1000).toISOString();
|
|
225
|
+
const tokenKeys = TOKEN_KEY_BY_AUTH_METHOD[creds.authMethod] ?? [];
|
|
226
|
+
for (const key of tokenKeys) {
|
|
227
|
+
const existing = queryKiroCliDb(dbPath, `SELECT value FROM auth_kv WHERE key = '${key}'`);
|
|
228
|
+
if (!existing)
|
|
229
|
+
continue;
|
|
230
|
+
try {
|
|
231
|
+
const rows = JSON.parse(existing);
|
|
232
|
+
if (!rows[0]?.value)
|
|
233
|
+
continue;
|
|
234
|
+
const tokenData = JSON.parse(rows[0].value);
|
|
235
|
+
tokenData.access_token = creds.access;
|
|
236
|
+
tokenData.refresh_token = rawRefreshToken;
|
|
237
|
+
tokenData.expires_at = expiresAt;
|
|
238
|
+
if (creds.region)
|
|
239
|
+
tokenData.region = creds.region;
|
|
240
|
+
if (creds.profileArn)
|
|
241
|
+
tokenData.profile_arn = creds.profileArn;
|
|
242
|
+
const escaped = JSON.stringify(tokenData).replace(/'/g, "''");
|
|
243
|
+
const sql = `UPDATE auth_kv SET value = '${escaped}' WHERE key = '${key}';`;
|
|
244
|
+
if (execKiroCliDb(dbPath, sql))
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
catch { }
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Ask kiro-cli to refresh its own tokens via `kiro-cli debug refresh-auth-token`,
|
|
252
|
+
* then re-read the SQLite DB for fresh credentials.
|
|
253
|
+
*
|
|
254
|
+
* Returns refreshed credentials on success, or undefined if kiro-cli is not
|
|
255
|
+
* installed, the command fails, or the DB still has no valid tokens afterward.
|
|
256
|
+
*/
|
|
257
|
+
export function refreshViaKiroCli() {
|
|
258
|
+
try {
|
|
259
|
+
execFileSync("kiro-cli", ["debug", "refresh-auth-token"], {
|
|
260
|
+
timeout: 15000,
|
|
261
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
262
|
+
});
|
|
263
|
+
return getKiroCliCredentials();
|
|
264
|
+
}
|
|
265
|
+
catch (error) {
|
|
266
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
267
|
+
console.warn(`[pi-provider-kiro] kiro-cli refresh failed: ${msg}`);
|
|
268
|
+
return undefined;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=kiro-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kiro-cli.js","sourceRoot":"","sources":["../src/kiro-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { KiroCredentials } from "./oauth.js";
|
|
2
|
+
/**
|
|
3
|
+
* Returns valid (non-expired) Kiro IDE credentials read from
|
|
4
|
+
* ~/.aws/sso/cache/kiro-auth-token.json, or undefined if the IDE has not
|
|
5
|
+
* logged in or the token has already expired.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getKiroIdeCredentials(): KiroCredentials | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Like getKiroIdeCredentials but also returns expired tokens so the caller can
|
|
10
|
+
* attempt a silent OIDC refresh before falling back to the full login flow.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getKiroIdeCredentialsAllowExpired(): KiroCredentials | undefined;
|
|
13
|
+
//# sourceMappingURL=kiro-ide.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kiro-ide.d.ts","sourceRoot":"","sources":["../src/kiro-ide.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAyElD;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,GAAG,SAAS,CAEnE;AAED;;;GAGG;AACH,wBAAgB,iCAAiC,IAC9C,eAAe,GACf,SAAS,CAEX"}
|
package/dist/kiro-ide.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// ABOUTME: Reads credentials written by the Kiro IDE.
|
|
2
|
+
// ABOUTME: The IDE stores its auth token at ~/.aws/sso/cache/kiro-auth-token.json
|
|
3
|
+
// ABOUTME: on all platforms (Windows, macOS, Linux) after every successful login,
|
|
4
|
+
// ABOUTME: including IAM Identity Center (authMethod: "IdC") and Builder ID.
|
|
5
|
+
// ABOUTME: A companion file, ~/.aws/sso/cache/{clientIdHash}.json, holds the
|
|
6
|
+
// ABOUTME: OIDC clientId/clientSecret needed to silently refresh the access token
|
|
7
|
+
// ABOUTME: via the standard AWS OIDC /token endpoint — no extra login flow needed.
|
|
8
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
9
|
+
import { homedir } from "node:os";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
// ~/.aws/sso/cache is the standard AWS SSO cache directory on all platforms.
|
|
12
|
+
// Node's os.homedir() returns the correct home directory on Windows, macOS and Linux.
|
|
13
|
+
const SSO_CACHE_DIR = join(homedir(), ".aws", "sso", "cache");
|
|
14
|
+
const KIRO_IDE_TOKEN_PATH = join(SSO_CACHE_DIR, "kiro-auth-token.json");
|
|
15
|
+
function readKiroIdeToken(allowExpired) {
|
|
16
|
+
try {
|
|
17
|
+
if (!existsSync(KIRO_IDE_TOKEN_PATH))
|
|
18
|
+
return undefined;
|
|
19
|
+
const tokenData = JSON.parse(readFileSync(KIRO_IDE_TOKEN_PATH, "utf-8"));
|
|
20
|
+
if (!tokenData.accessToken || !tokenData.refreshToken)
|
|
21
|
+
return undefined;
|
|
22
|
+
const expiresAt = new Date(tokenData.expiresAt).getTime();
|
|
23
|
+
if (!allowExpired && Date.now() >= expiresAt - 2 * 60 * 1000)
|
|
24
|
+
return undefined;
|
|
25
|
+
const region = tokenData.region ?? "us-east-1";
|
|
26
|
+
// Load the OIDC client registration so refreshKiroTokenDirect can call the
|
|
27
|
+
// AWS OIDC /token endpoint with a refresh_token grant without prompting the user.
|
|
28
|
+
let clientId = "";
|
|
29
|
+
let clientSecret = "";
|
|
30
|
+
if (tokenData.clientIdHash) {
|
|
31
|
+
const regPath = join(SSO_CACHE_DIR, `${tokenData.clientIdHash}.json`);
|
|
32
|
+
if (existsSync(regPath)) {
|
|
33
|
+
try {
|
|
34
|
+
const reg = JSON.parse(readFileSync(regPath, "utf-8"));
|
|
35
|
+
clientId = reg.clientId ?? "";
|
|
36
|
+
clientSecret = reg.clientSecret ?? "";
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Ignore — we can still use the token without a refresh client
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
// Pack into the same pipe-delimited format used by the rest of the refresh chain
|
|
45
|
+
refresh: `${tokenData.refreshToken}|${clientId}|${clientSecret}|idc`,
|
|
46
|
+
access: tokenData.accessToken,
|
|
47
|
+
// Subtract 2-min buffer so we refresh before the actual AWS expiry
|
|
48
|
+
expires: expiresAt - 2 * 60 * 1000,
|
|
49
|
+
clientId,
|
|
50
|
+
clientSecret,
|
|
51
|
+
region,
|
|
52
|
+
authMethod: "idc",
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Returns valid (non-expired) Kiro IDE credentials read from
|
|
61
|
+
* ~/.aws/sso/cache/kiro-auth-token.json, or undefined if the IDE has not
|
|
62
|
+
* logged in or the token has already expired.
|
|
63
|
+
*/
|
|
64
|
+
export function getKiroIdeCredentials() {
|
|
65
|
+
return readKiroIdeToken(false);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Like getKiroIdeCredentials but also returns expired tokens so the caller can
|
|
69
|
+
* attempt a silent OIDC refresh before falling back to the full login flow.
|
|
70
|
+
*/
|
|
71
|
+
export function getKiroIdeCredentialsAllowExpired() {
|
|
72
|
+
return readKiroIdeToken(true);
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=kiro-ide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kiro-ide.js","sourceRoot":"","sources":["../src/kiro-ide.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,kFAAkF;AAClF,kFAAkF;AAClF,6EAA6E;AAC7E,6EAA6E;AAC7E,kFAAkF;AAClF,mFAAmF;AAEnF,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,6EAA6E;AAC7E,sFAAsF;AACtF,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAC9D,MAAM,mBAAmB,GAAG,IAAI,CAAC,aAAa,EAAE,sBAAsB,CAAC,CAAC;AAkBxE,SAAS,gBAAgB,CAAC,YAAqB;IAC9C,IAAI,CAAC;QACJ,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC;YAAE,OAAO,SAAS,CAAC;QAEvD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAC3B,YAAY,CAAC,mBAAmB,EAAE,OAAO,CAAC,CACtB,CAAC;QACtB,IAAI,CAAC,SAAS,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,YAAY;YAAE,OAAO,SAAS,CAAC;QAExE,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QAC1D,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,SAAS,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI;YAC3D,OAAO,SAAS,CAAC;QAElB,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,IAAI,WAAW,CAAC;QAE/C,2EAA2E;QAC3E,kFAAkF;QAClF,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,IAAI,YAAY,GAAG,EAAE,CAAC;QACtB,IAAI,SAAS,CAAC,YAAY,EAAE,CAAC;YAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,EAAE,GAAG,SAAS,CAAC,YAAY,OAAO,CAAC,CAAC;YACtE,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBACzB,IAAI,CAAC;oBACJ,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACrB,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CACT,CAAC;oBACvB,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC;oBAC9B,YAAY,GAAG,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;gBACvC,CAAC;gBAAC,MAAM,CAAC;oBACR,+DAA+D;gBAChE,CAAC;YACF,CAAC;QACF,CAAC;QAED,OAAO;YACN,iFAAiF;YACjF,OAAO,EAAE,GAAG,SAAS,CAAC,YAAY,IAAI,QAAQ,IAAI,YAAY,MAAM;YACpE,MAAM,EAAE,SAAS,CAAC,WAAW;YAC7B,mEAAmE;YACnE,OAAO,EAAE,SAAS,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI;YAClC,QAAQ;YACR,YAAY;YACZ,MAAM;YACN,UAAU,EAAE,KAAK;SACjB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB;IACpC,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iCAAiC;IAGhD,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
export type LoginChoice = {
|
|
3
|
+
method: "builder-id";
|
|
4
|
+
} | {
|
|
5
|
+
method: "idc";
|
|
6
|
+
startUrl: string;
|
|
7
|
+
} | {
|
|
8
|
+
method: "google";
|
|
9
|
+
} | {
|
|
10
|
+
method: "github";
|
|
11
|
+
} | null;
|
|
12
|
+
export declare function setExtensionContext(ctx: ExtensionContext): void;
|
|
13
|
+
/**
|
|
14
|
+
* Show the login method selection UI using pi's native TUI components.
|
|
15
|
+
* Returns the user's choice or null if cancelled.
|
|
16
|
+
*/
|
|
17
|
+
export declare function showLoginUI(): Promise<LoginChoice>;
|
|
18
|
+
//# sourceMappingURL=login-ui.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login-ui.d.ts","sourceRoot":"","sources":["../src/login-ui.ts"],"names":[],"mappings":"AAQA,OAAO,EAEN,KAAK,gBAAgB,EACrB,MAAM,iCAAiC,CAAC;AASzC,MAAM,MAAM,WAAW,GACpB;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,GACxB;IAAE,MAAM,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,GACpB;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,GACpB,IAAI,CAAC;AAIR,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,gBAAgB,QAExD;AAED;;;GAGG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,CA4HxD"}
|
package/dist/login-ui.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// Feature 10b: Custom TUI login component
|
|
2
|
+
//
|
|
3
|
+
// Replaces multiple onPrompt calls with a single ctx.ui.custom() overlay
|
|
4
|
+
// to work around pi's stacked-input bug (mirrored cursors on sequential prompts).
|
|
5
|
+
//
|
|
6
|
+
// Phase 1: SelectList — pick login method (Builder ID / IdC / Google / GitHub)
|
|
7
|
+
// Phase 2: Input — enter IAM Identity Center start URL (only for option 2)
|
|
8
|
+
import { DynamicBorder, } from "@earendil-works/pi-coding-agent";
|
|
9
|
+
import { Container, Input, SelectList, Text, } from "@earendil-works/pi-tui";
|
|
10
|
+
let _ctx;
|
|
11
|
+
export function setExtensionContext(ctx) {
|
|
12
|
+
_ctx = ctx;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Show the login method selection UI using pi's native TUI components.
|
|
16
|
+
* Returns the user's choice or null if cancelled.
|
|
17
|
+
*/
|
|
18
|
+
export async function showLoginUI() {
|
|
19
|
+
if (!_ctx)
|
|
20
|
+
return null;
|
|
21
|
+
const ctx = _ctx;
|
|
22
|
+
return ctx.ui.custom((tui, theme, _kb, done) => {
|
|
23
|
+
const items = [
|
|
24
|
+
{
|
|
25
|
+
value: "builder-id",
|
|
26
|
+
label: "Builder ID",
|
|
27
|
+
description: "AWS Builder ID (default)",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
value: "idc",
|
|
31
|
+
label: "Your organization",
|
|
32
|
+
description: "IAM Identity Center (SSO)",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
value: "google",
|
|
36
|
+
label: "Google",
|
|
37
|
+
description: "Social login via kiro-cli",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
value: "github",
|
|
41
|
+
label: "GitHub",
|
|
42
|
+
description: "Social login via kiro-cli",
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
let phase = "select";
|
|
46
|
+
const container = new Container();
|
|
47
|
+
const border = new DynamicBorder((s) => theme.fg("accent", s));
|
|
48
|
+
const title = new Text(theme.fg("accent", theme.bold("Kiro Login")), 1, 0);
|
|
49
|
+
const hint = new Text(theme.fg("dim", "↑↓ navigate • enter select • esc cancel"), 1, 0);
|
|
50
|
+
const borderBottom = new DynamicBorder((s) => theme.fg("accent", s));
|
|
51
|
+
// Phase 1: SelectList
|
|
52
|
+
const selectList = new SelectList(items, items.length, {
|
|
53
|
+
selectedPrefix: (t) => theme.fg("accent", t),
|
|
54
|
+
selectedText: (t) => theme.fg("accent", t),
|
|
55
|
+
description: (t) => theme.fg("muted", t),
|
|
56
|
+
scrollInfo: (t) => theme.fg("dim", t),
|
|
57
|
+
noMatch: (t) => theme.fg("warning", t),
|
|
58
|
+
});
|
|
59
|
+
selectList.onSelect = (item) => {
|
|
60
|
+
if (item.value === "idc") {
|
|
61
|
+
switchToUrlInput();
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
done({ method: item.value });
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
selectList.onCancel = () => done(null);
|
|
68
|
+
// Phase 2: URL Input
|
|
69
|
+
const urlLabel = new Text("Start URL (e.g. https://mycompany.awsapps.com/start)", 1, 0);
|
|
70
|
+
const urlInput = new Input();
|
|
71
|
+
const urlHint = new Text(theme.fg("dim", "enter submit • esc back"), 1, 0);
|
|
72
|
+
urlInput.onSubmit = (value) => {
|
|
73
|
+
const trimmed = value.trim();
|
|
74
|
+
if (trimmed?.startsWith("http")) {
|
|
75
|
+
done({ method: "idc", startUrl: trimmed });
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
urlInput.onEscape = () => {
|
|
79
|
+
switchToSelect();
|
|
80
|
+
};
|
|
81
|
+
function switchToUrlInput() {
|
|
82
|
+
phase = "url";
|
|
83
|
+
container.clear();
|
|
84
|
+
container.addChild(border);
|
|
85
|
+
container.addChild(new Text(theme.fg("accent", theme.bold("IAM Identity Center")), 1, 0));
|
|
86
|
+
container.addChild(urlLabel);
|
|
87
|
+
container.addChild(urlInput);
|
|
88
|
+
container.addChild(urlHint);
|
|
89
|
+
container.addChild(borderBottom);
|
|
90
|
+
tui.requestRender();
|
|
91
|
+
}
|
|
92
|
+
function switchToSelect() {
|
|
93
|
+
phase = "select";
|
|
94
|
+
urlInput.setValue("");
|
|
95
|
+
container.clear();
|
|
96
|
+
container.addChild(border);
|
|
97
|
+
container.addChild(title);
|
|
98
|
+
container.addChild(selectList);
|
|
99
|
+
container.addChild(hint);
|
|
100
|
+
container.addChild(borderBottom);
|
|
101
|
+
tui.requestRender();
|
|
102
|
+
}
|
|
103
|
+
// Initial state
|
|
104
|
+
switchToSelect();
|
|
105
|
+
return {
|
|
106
|
+
render(width) {
|
|
107
|
+
return container.render(width);
|
|
108
|
+
},
|
|
109
|
+
invalidate() {
|
|
110
|
+
container.invalidate();
|
|
111
|
+
},
|
|
112
|
+
handleInput(data) {
|
|
113
|
+
if (phase === "select") {
|
|
114
|
+
selectList.handleInput(data);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
urlInput.handleInput(data);
|
|
118
|
+
}
|
|
119
|
+
tui.requestRender();
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=login-ui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login-ui.js","sourceRoot":"","sources":["../src/login-ui.ts"],"names":[],"mappings":"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"}
|
package/dist/login.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { OAuthCredentials, OAuthLoginCallbacks } from "@earendil-works/pi-ai";
|
|
2
|
+
/**
|
|
3
|
+
* Interactive login fallback — shown when no existing credentials are available.
|
|
4
|
+
*
|
|
5
|
+
* Uses pi's native TUI components (SelectList + Input) via ctx.ui.custom()
|
|
6
|
+
* when available, falling back to a single onPrompt call otherwise.
|
|
7
|
+
* This avoids pi's stacked-input bug where sequential onPrompt calls
|
|
8
|
+
* render simultaneously with mirrored cursors.
|
|
9
|
+
*/
|
|
10
|
+
export declare function interactiveLogin(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials>;
|
|
11
|
+
/**
|
|
12
|
+
* Delegate Google/GitHub social login to kiro-cli.
|
|
13
|
+
* Requires kiro-cli to be installed and in PATH.
|
|
14
|
+
*/
|
|
15
|
+
export declare function loginViaKiroCli(callbacks: OAuthLoginCallbacks, provider: "google" | "github"): Promise<OAuthCredentials>;
|
|
16
|
+
//# sourceMappingURL=login.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../src/login.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EACX,gBAAgB,EAChB,mBAAmB,EACnB,MAAM,uBAAuB,CAAC;AAuD/B;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACrC,SAAS,EAAE,mBAAmB,GAC5B,OAAO,CAAC,gBAAgB,CAAC,CAoC3B;AA8KD;;;GAGG;AACH,wBAAsB,eAAe,CACpC,SAAS,EAAE,mBAAmB,EAC9B,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CA+B3B"}
|