@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
package/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# @arvoretech/pi-kiro-provider
|
|
2
|
+
|
|
3
|
+
A [pi](https://github.com/earendil-works/pi-coding-agent) provider extension that connects pi to the **Kiro API** (AWS CodeWhisperer/Q), exposing kiro-cli-verified models through one provider surface.
|
|
4
|
+
|
|
5
|
+
## Why this exists
|
|
6
|
+
|
|
7
|
+
Kiro gives you a strong free model menu, but pi needs a provider that speaks Kiro's auth, model catalog, and streaming protocol cleanly. `@arvoretech/pi-kiro-provider` handles that bridge, including:
|
|
8
|
+
|
|
9
|
+
- AWS Builder ID, IAM Identity Center, Google, and GitHub login flows
|
|
10
|
+
- shared credentials from an existing `kiro-cli` session when available
|
|
11
|
+
- reasoning-aware streaming
|
|
12
|
+
- region-aware model filtering so pi only shows models your Kiro region can actually use
|
|
13
|
+
|
|
14
|
+
## Quick start
|
|
15
|
+
|
|
16
|
+
Add to `.pi/settings.json`:
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"packages": ["npm:@arvoretech/pi-kiro-provider"]
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or reference the local dist path for project-local development:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"extensions": ["./arvore-pi-extensions/packages/kiro-provider/dist/index.js"]
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Then log in from pi:
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
/login kiro
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The login flow supports:
|
|
39
|
+
- **AWS Builder ID** — native device-code flow, works well over SSH/remotes
|
|
40
|
+
- **Your organization** — IAM Identity Center start URL
|
|
41
|
+
- **Google** — social login via `kiro-cli`
|
|
42
|
+
- **GitHub** — social login via `kiro-cli`
|
|
43
|
+
|
|
44
|
+
If you already use [kiro-cli](https://kiro.dev), the provider can reuse those credentials instead of forcing a second login.
|
|
45
|
+
|
|
46
|
+
## Models
|
|
47
|
+
|
|
48
|
+
| Family | Models | Context | Reasoning |
|
|
49
|
+
|--------|--------|---------|-----------|
|
|
50
|
+
| Claude Opus | `claude-opus-4-7`, `claude-opus-4-6` | 1M | ✓ |
|
|
51
|
+
| Claude Sonnet 5 | `claude-sonnet-5` | 1M | ✓ |
|
|
52
|
+
| Claude Sonnet 4.6 | `claude-sonnet-4-6` | 1M | ✓ |
|
|
53
|
+
| Claude Sonnet 4.5 | `claude-sonnet-4-5` | 200K | ✓ |
|
|
54
|
+
| Claude Sonnet 4 | `claude-sonnet-4` | 200K | ✓ |
|
|
55
|
+
| Claude Haiku 4.5 | `claude-haiku-4-5` | 200K | ✗ |
|
|
56
|
+
| Claude Fable 5 | `claude-fable-5` | 1M | ✓ |
|
|
57
|
+
| DeepSeek 3.2 | `deepseek-3-2` | 164K | ✓ |
|
|
58
|
+
| MiniMax | `minimax-m2-1`, `minimax-m2-5` | 196K | ✗ |
|
|
59
|
+
| GLM 5 | `glm-5` | 200K | ✓ |
|
|
60
|
+
| Qwen3 Coder | `qwen3-coder-next` | 256K | ✓ |
|
|
61
|
+
| Auto | `auto` | 1M | ✓ |
|
|
62
|
+
|
|
63
|
+
All listed models are free to use through Kiro.
|
|
64
|
+
|
|
65
|
+
## Usage
|
|
66
|
+
|
|
67
|
+
Once logged in, select any Kiro model in pi:
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
/model claude-sonnet-4-6
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Or let Kiro pick automatically:
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
/model auto
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Reasoning is automatically enabled for supported models. Use `/reasoning` to adjust the thinking budget.
|
|
80
|
+
|
|
81
|
+
## Retry Behavior
|
|
82
|
+
|
|
83
|
+
Generic transient retries such as HTTP `429` and `5xx` are handled by `pi-coding-agent` at the session layer.
|
|
84
|
+
|
|
85
|
+
This provider only keeps local recovery for Kiro-specific cases:
|
|
86
|
+
- `403` auth races, where it can refresh credentials from `kiro-cli`
|
|
87
|
+
- first-token / stalled-stream recovery
|
|
88
|
+
- empty-stream retries
|
|
89
|
+
- non-retryable Kiro body markers like `MONTHLY_REQUEST_COUNT` and `INSUFFICIENT_MODEL_CAPACITY`
|
|
90
|
+
|
|
91
|
+
## Development
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pnpm build # Compile TypeScript
|
|
95
|
+
pnpm check # Type check (no emit)
|
|
96
|
+
pnpm test # Run the Vitest suite
|
|
97
|
+
pnpm test:watch # Watch mode
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Architecture
|
|
101
|
+
|
|
102
|
+
The extension is organized as one feature per file:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
src/
|
|
106
|
+
├── index.ts # Extension registration
|
|
107
|
+
├── models.ts # 12 model definitions + ID resolution
|
|
108
|
+
├── oauth.ts # Multi-provider auth (Builder ID / Google / GitHub)
|
|
109
|
+
├── kiro-cli.ts # kiro-cli credential sharing
|
|
110
|
+
├── transform.ts # Message format conversion
|
|
111
|
+
├── history.ts # Conversation history management
|
|
112
|
+
├── thinking-parser.ts # Streaming <thinking> tag parser
|
|
113
|
+
├── event-parser.ts # Kiro stream event parser
|
|
114
|
+
└── stream.ts # Main streaming orchestrator
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
See [src/](src/) — each file owns one feature (extension registration, model catalog, OAuth, kiro-cli credential sharing, message transform, history management, thinking-tag parsing, event parsing, and the streaming orchestrator).
|
|
118
|
+
|
|
119
|
+
## License
|
|
120
|
+
|
|
121
|
+
MIT
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function findJsonEnd(text: string, start: number): number;
|
|
2
|
+
export interface BracketToolCall {
|
|
3
|
+
toolUseId: string;
|
|
4
|
+
name: string;
|
|
5
|
+
arguments: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
export interface BracketParseResult {
|
|
8
|
+
toolCalls: BracketToolCall[];
|
|
9
|
+
cleanedText: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function parseBracketToolCalls(text: string): BracketParseResult;
|
|
12
|
+
//# sourceMappingURL=bracket-tool-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bracket-tool-parser.d.ts","sourceRoot":"","sources":["../src/bracket-tool-parser.ts"],"names":[],"mappings":"AAGA,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CA2B/D;AAED,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,kBAAkB;IAClC,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CA8CtE"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// ABOUTME: Extracts bracket-style tool calls from content text as a fallback.
|
|
2
|
+
// ABOUTME: Parses [Called func_name with args: {...}] patterns from model output.
|
|
3
|
+
export function findJsonEnd(text, start) {
|
|
4
|
+
let braceCount = 0;
|
|
5
|
+
let inString = false;
|
|
6
|
+
let escapeNext = false;
|
|
7
|
+
for (let i = start; i < text.length; i++) {
|
|
8
|
+
const char = text[i];
|
|
9
|
+
if (escapeNext) {
|
|
10
|
+
escapeNext = false;
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
if (char === "\\") {
|
|
14
|
+
escapeNext = true;
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (char === '"') {
|
|
18
|
+
inString = !inString;
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (!inString) {
|
|
22
|
+
if (char === "{")
|
|
23
|
+
braceCount++;
|
|
24
|
+
else if (char === "}") {
|
|
25
|
+
braceCount--;
|
|
26
|
+
if (braceCount === 0)
|
|
27
|
+
return i;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return -1;
|
|
32
|
+
}
|
|
33
|
+
const BRACKET_PATTERN = /\[Called\s+([\w-]+)\s+with\s+args:\s*/g;
|
|
34
|
+
export function parseBracketToolCalls(text) {
|
|
35
|
+
const toolCalls = [];
|
|
36
|
+
const removals = [];
|
|
37
|
+
// Reset the regex lastIndex to ensure consistent behavior
|
|
38
|
+
BRACKET_PATTERN.lastIndex = 0;
|
|
39
|
+
let match = BRACKET_PATTERN.exec(text);
|
|
40
|
+
while (match !== null) {
|
|
41
|
+
const name = match[1];
|
|
42
|
+
const jsonStart = match.index + match[0].length;
|
|
43
|
+
const braceIdx = text.indexOf("{", jsonStart);
|
|
44
|
+
if (braceIdx >= 0 && braceIdx === jsonStart) {
|
|
45
|
+
const jsonEndIdx = findJsonEnd(text, braceIdx);
|
|
46
|
+
if (jsonEndIdx >= 0) {
|
|
47
|
+
const afterJson = text.indexOf("]", jsonEndIdx + 1);
|
|
48
|
+
if (afterJson >= 0) {
|
|
49
|
+
const between = text.substring(jsonEndIdx + 1, afterJson).trim();
|
|
50
|
+
if (between.length === 0) {
|
|
51
|
+
const jsonStr = text.substring(braceIdx, jsonEndIdx + 1);
|
|
52
|
+
try {
|
|
53
|
+
const args = JSON.parse(jsonStr);
|
|
54
|
+
toolCalls.push({
|
|
55
|
+
toolUseId: crypto.randomUUID(),
|
|
56
|
+
name,
|
|
57
|
+
arguments: args,
|
|
58
|
+
});
|
|
59
|
+
removals.push({ start: match.index, end: afterJson + 1 });
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// Malformed JSON — skip this match
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
match = BRACKET_PATTERN.exec(text);
|
|
69
|
+
}
|
|
70
|
+
// Build cleaned text by removing matched bracket patterns (reverse order to preserve indices)
|
|
71
|
+
let cleanedText = text;
|
|
72
|
+
for (let i = removals.length - 1; i >= 0; i--) {
|
|
73
|
+
const { start, end } = removals[i];
|
|
74
|
+
cleanedText = cleanedText.substring(0, start) + cleanedText.substring(end);
|
|
75
|
+
}
|
|
76
|
+
return { toolCalls, cleanedText };
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=bracket-tool-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bracket-tool-parser.js","sourceRoot":"","sources":["../src/bracket-tool-parser.ts"],"names":[],"mappings":"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"}
|
package/dist/debug.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAcA,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAkB9D"}
|
package/dist/debug.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// ABOUTME: Debug logging — dumps requests, responses, stream events, and errors
|
|
2
|
+
// ABOUTME: to a log file when KIRO_DEBUG=1. Custom path via KIRO_DEBUG_LOG.
|
|
3
|
+
import { appendFileSync, mkdirSync } from "node:fs";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
|
+
const ENABLED = !!process.env.KIRO_DEBUG && process.env.KIRO_DEBUG !== "0";
|
|
7
|
+
const LOG_FILE = process.env.KIRO_DEBUG_LOG ||
|
|
8
|
+
join(homedir(), ".pi", "logs", "kiro-debug.log");
|
|
9
|
+
let dirReady = false;
|
|
10
|
+
export function debugEnabled() {
|
|
11
|
+
return ENABLED;
|
|
12
|
+
}
|
|
13
|
+
export function debugLog(section, data) {
|
|
14
|
+
if (!ENABLED)
|
|
15
|
+
return;
|
|
16
|
+
try {
|
|
17
|
+
if (!dirReady) {
|
|
18
|
+
mkdirSync(dirname(LOG_FILE), { recursive: true });
|
|
19
|
+
dirReady = true;
|
|
20
|
+
}
|
|
21
|
+
const ts = new Date().toISOString();
|
|
22
|
+
const body = data === undefined
|
|
23
|
+
? ""
|
|
24
|
+
: typeof data === "string"
|
|
25
|
+
? ` ${data}`
|
|
26
|
+
: ` ${JSON.stringify(data, redact, 2)}`;
|
|
27
|
+
appendFileSync(LOG_FILE, `${ts} [${section}]${body}\n`);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// best-effort; never break the provider
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** Redact auth tokens in JSON output. */
|
|
34
|
+
function redact(key, value) {
|
|
35
|
+
if (typeof value !== "string")
|
|
36
|
+
return value;
|
|
37
|
+
const k = key.toLowerCase();
|
|
38
|
+
if (k === "authorization" ||
|
|
39
|
+
k === "access" ||
|
|
40
|
+
k === "refresh" ||
|
|
41
|
+
k.includes("token") ||
|
|
42
|
+
k.includes("secret")) {
|
|
43
|
+
return value.length > 8
|
|
44
|
+
? `${value.slice(0, 4)}…${value.slice(-4)}(${value.length})`
|
|
45
|
+
: "<redacted>";
|
|
46
|
+
}
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=debug.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.js","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,4EAA4E;AAE5E,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,GAAG,CAAC;AAC3E,MAAM,QAAQ,GACb,OAAO,CAAC,GAAG,CAAC,cAAc;IAC1B,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAElD,IAAI,QAAQ,GAAG,KAAK,CAAC;AAErB,MAAM,UAAU,YAAY;IAC3B,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,IAAc;IACvD,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,IAAI,CAAC;QACJ,IAAI,CAAC,QAAQ,EAAE,CAAC;YACf,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAClD,QAAQ,GAAG,IAAI,CAAC;QACjB,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,IAAI,GACT,IAAI,KAAK,SAAS;YACjB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ;gBACzB,CAAC,CAAC,IAAI,IAAI,EAAE;gBACZ,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC;QAC3C,cAAc,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,OAAO,IAAI,IAAI,IAAI,CAAC,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACR,wCAAwC;IACzC,CAAC;AACF,CAAC;AAED,yCAAyC;AACzC,SAAS,MAAM,CAAC,GAAW,EAAE,KAAc;IAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAC5B,IACC,CAAC,KAAK,eAAe;QACrB,CAAC,KAAK,QAAQ;QACd,CAAC,KAAK,SAAS;QACf,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;QACnB,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EACnB,CAAC;QACF,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC;YACtB,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG;YAC5D,CAAC,CAAC,YAAY,CAAC;IACjB,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export type KiroStreamEvent = {
|
|
2
|
+
type: "content";
|
|
3
|
+
data: string;
|
|
4
|
+
} | {
|
|
5
|
+
type: "toolUse";
|
|
6
|
+
data: {
|
|
7
|
+
name: string;
|
|
8
|
+
toolUseId: string;
|
|
9
|
+
input: string;
|
|
10
|
+
stop?: boolean;
|
|
11
|
+
};
|
|
12
|
+
} | {
|
|
13
|
+
type: "toolUseInput";
|
|
14
|
+
data: {
|
|
15
|
+
input: string;
|
|
16
|
+
};
|
|
17
|
+
} | {
|
|
18
|
+
type: "toolUseStop";
|
|
19
|
+
data: {
|
|
20
|
+
stop: boolean;
|
|
21
|
+
};
|
|
22
|
+
} | {
|
|
23
|
+
type: "contextUsage";
|
|
24
|
+
data: {
|
|
25
|
+
contextUsagePercentage: number;
|
|
26
|
+
};
|
|
27
|
+
} | {
|
|
28
|
+
type: "followupPrompt";
|
|
29
|
+
data: string;
|
|
30
|
+
} | {
|
|
31
|
+
type: "usage";
|
|
32
|
+
data: {
|
|
33
|
+
inputTokens?: number;
|
|
34
|
+
outputTokens?: number;
|
|
35
|
+
};
|
|
36
|
+
} | {
|
|
37
|
+
type: "error";
|
|
38
|
+
data: {
|
|
39
|
+
error: string;
|
|
40
|
+
message?: string;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
export declare function parseKiroEvent(parsed: Record<string, unknown>): KiroStreamEvent | null;
|
|
44
|
+
//# sourceMappingURL=event-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-parser.d.ts","sourceRoot":"","sources":["../src/event-parser.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,eAAe,GACxB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjC;IACA,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CACxE,GACD;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE;QAAE,sBAAsB,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAClE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACxE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAEhE,wBAAgB,cAAc,CAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,eAAe,GAAG,IAAI,CAkExB"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// ABOUTME: Kiro stream event type definitions and JSON-to-typed-event mapping.
|
|
2
|
+
// ABOUTME: Binary framing is handled by @smithy/core EventStreamMarshaller in stream.ts.
|
|
3
|
+
export function parseKiroEvent(parsed) {
|
|
4
|
+
if (parsed.content !== undefined)
|
|
5
|
+
return { type: "content", data: parsed.content };
|
|
6
|
+
if (parsed.name && parsed.toolUseId) {
|
|
7
|
+
const input = typeof parsed.input === "string"
|
|
8
|
+
? parsed.input
|
|
9
|
+
: parsed.input &&
|
|
10
|
+
typeof parsed.input === "object" &&
|
|
11
|
+
Object.keys(parsed.input).length > 0
|
|
12
|
+
? JSON.stringify(parsed.input)
|
|
13
|
+
: "";
|
|
14
|
+
return {
|
|
15
|
+
type: "toolUse",
|
|
16
|
+
data: {
|
|
17
|
+
name: parsed.name,
|
|
18
|
+
toolUseId: parsed.toolUseId,
|
|
19
|
+
input,
|
|
20
|
+
stop: parsed.stop,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (parsed.input !== undefined && !parsed.name) {
|
|
25
|
+
return {
|
|
26
|
+
type: "toolUseInput",
|
|
27
|
+
data: {
|
|
28
|
+
input: typeof parsed.input === "string"
|
|
29
|
+
? parsed.input
|
|
30
|
+
: JSON.stringify(parsed.input),
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
if (parsed.stop !== undefined && parsed.contextUsagePercentage === undefined)
|
|
35
|
+
return { type: "toolUseStop", data: { stop: parsed.stop } };
|
|
36
|
+
if (parsed.contextUsagePercentage !== undefined)
|
|
37
|
+
return {
|
|
38
|
+
type: "contextUsage",
|
|
39
|
+
data: { contextUsagePercentage: parsed.contextUsagePercentage },
|
|
40
|
+
};
|
|
41
|
+
if (parsed.followupPrompt !== undefined)
|
|
42
|
+
return { type: "followupPrompt", data: parsed.followupPrompt };
|
|
43
|
+
if (parsed.error !== undefined || parsed.Error !== undefined) {
|
|
44
|
+
const error = (parsed.error || parsed.Error || "unknown");
|
|
45
|
+
const message = (parsed.message || parsed.Message || parsed.reason);
|
|
46
|
+
return {
|
|
47
|
+
type: "error",
|
|
48
|
+
data: {
|
|
49
|
+
error: typeof error === "string" ? error : JSON.stringify(error),
|
|
50
|
+
message,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (parsed.usage !== undefined) {
|
|
55
|
+
const u = parsed.usage;
|
|
56
|
+
return {
|
|
57
|
+
type: "usage",
|
|
58
|
+
data: {
|
|
59
|
+
inputTokens: u.inputTokens,
|
|
60
|
+
outputTokens: u.outputTokens,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=event-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-parser.js","sourceRoot":"","sources":["../src/event-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { KiroHistoryEntry, KiroToolSpec } from "./transform.js";
|
|
2
|
+
export declare const HISTORY_LIMIT = 850000;
|
|
3
|
+
/** The context window size (in tokens) that HISTORY_LIMIT was calibrated for. */
|
|
4
|
+
export declare const HISTORY_LIMIT_CONTEXT_WINDOW = 200000;
|
|
5
|
+
/** Remove images from history entries — they've already been processed by the
|
|
6
|
+
* model in previous turns and re-sending them wastes context / causes 413s. */
|
|
7
|
+
export declare function stripHistoryImages(history: KiroHistoryEntry[]): KiroHistoryEntry[];
|
|
8
|
+
export declare function sanitizeHistory(history: KiroHistoryEntry[]): KiroHistoryEntry[];
|
|
9
|
+
export declare function injectSyntheticToolCalls(history: KiroHistoryEntry[]): KiroHistoryEntry[];
|
|
10
|
+
export declare function truncateHistory(history: KiroHistoryEntry[], limit: number): KiroHistoryEntry[];
|
|
11
|
+
export declare function extractToolNamesFromHistory(history: KiroHistoryEntry[]): Set<string>;
|
|
12
|
+
export declare function addPlaceholderTools(tools: KiroToolSpec[], history: KiroHistoryEntry[]): KiroToolSpec[];
|
|
13
|
+
//# sourceMappingURL=history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAErE,eAAO,MAAM,aAAa,SAAS,CAAC;AACpC,iFAAiF;AACjF,eAAO,MAAM,4BAA4B,SAAS,CAAC;AAEnD;gFACgF;AAChF,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,gBAAgB,EAAE,GACzB,gBAAgB,EAAE,CAMpB;AAED,wBAAgB,eAAe,CAC9B,OAAO,EAAE,gBAAgB,EAAE,GACzB,gBAAgB,EAAE,CAgCpB;AAED,wBAAgB,wBAAwB,CACvC,OAAO,EAAE,gBAAgB,EAAE,GACzB,gBAAgB,EAAE,CA8BpB;AAED,wBAAgB,eAAe,CAC9B,OAAO,EAAE,gBAAgB,EAAE,EAC3B,KAAK,EAAE,MAAM,GACX,gBAAgB,EAAE,CAWpB;AAED,wBAAgB,2BAA2B,CAC1C,OAAO,EAAE,gBAAgB,EAAE,GACzB,GAAG,CAAC,MAAM,CAAC,CAQb;AAED,wBAAgB,mBAAmB,CAClC,KAAK,EAAE,YAAY,EAAE,EACrB,OAAO,EAAE,gBAAgB,EAAE,GACzB,YAAY,EAAE,CAkBhB"}
|
package/dist/history.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// Feature 6: History Management
|
|
2
|
+
export const HISTORY_LIMIT = 850000;
|
|
3
|
+
/** The context window size (in tokens) that HISTORY_LIMIT was calibrated for. */
|
|
4
|
+
export const HISTORY_LIMIT_CONTEXT_WINDOW = 200000;
|
|
5
|
+
/** Remove images from history entries — they've already been processed by the
|
|
6
|
+
* model in previous turns and re-sending them wastes context / causes 413s. */
|
|
7
|
+
export function stripHistoryImages(history) {
|
|
8
|
+
return history.map((entry) => {
|
|
9
|
+
if (!entry.userInputMessage?.images)
|
|
10
|
+
return entry;
|
|
11
|
+
const { images, ...rest } = entry.userInputMessage;
|
|
12
|
+
return { ...entry, userInputMessage: { ...rest } };
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export function sanitizeHistory(history) {
|
|
16
|
+
// Strip leading entries that would make the history invalid
|
|
17
|
+
while (history.length > 0 &&
|
|
18
|
+
(!history[0]?.userInputMessage ||
|
|
19
|
+
history[0].userInputMessage.userInputMessageContext?.toolResults))
|
|
20
|
+
history = history.slice(1);
|
|
21
|
+
const result = [];
|
|
22
|
+
for (let i = 0; i < history.length; i++) {
|
|
23
|
+
const m = history[i];
|
|
24
|
+
if (!m)
|
|
25
|
+
continue;
|
|
26
|
+
// Skip assistant messages with no content and no tool uses (e.g. from API errors)
|
|
27
|
+
if (m.assistantResponseMessage &&
|
|
28
|
+
!m.assistantResponseMessage.toolUses &&
|
|
29
|
+
!m.assistantResponseMessage.content)
|
|
30
|
+
continue;
|
|
31
|
+
if (m.assistantResponseMessage?.toolUses) {
|
|
32
|
+
const next = history[i + 1];
|
|
33
|
+
if (next?.userInputMessage?.userInputMessageContext?.toolResults)
|
|
34
|
+
result.push(m);
|
|
35
|
+
}
|
|
36
|
+
else if (m.userInputMessage?.userInputMessageContext?.toolResults) {
|
|
37
|
+
const prev = result[result.length - 1];
|
|
38
|
+
if (prev?.assistantResponseMessage?.toolUses)
|
|
39
|
+
result.push(m);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
result.push(m);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Leading invalid entries already stripped above
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
export function injectSyntheticToolCalls(history) {
|
|
49
|
+
const validIds = new Set();
|
|
50
|
+
for (const entry of history) {
|
|
51
|
+
for (const tu of entry.assistantResponseMessage?.toolUses ?? []) {
|
|
52
|
+
if (tu.toolUseId)
|
|
53
|
+
validIds.add(tu.toolUseId);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const result = [];
|
|
57
|
+
for (const entry of history) {
|
|
58
|
+
const toolResults = entry.userInputMessage?.userInputMessageContext?.toolResults;
|
|
59
|
+
if (toolResults) {
|
|
60
|
+
const orphaned = toolResults.filter((tr) => !validIds.has(tr.toolUseId));
|
|
61
|
+
if (orphaned.length > 0) {
|
|
62
|
+
result.push({
|
|
63
|
+
assistantResponseMessage: {
|
|
64
|
+
content: "Tool calls were made.",
|
|
65
|
+
toolUses: orphaned.map((tr) => ({
|
|
66
|
+
name: "unknown_tool",
|
|
67
|
+
toolUseId: tr.toolUseId,
|
|
68
|
+
input: {},
|
|
69
|
+
})),
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
for (const tr of orphaned)
|
|
73
|
+
validIds.add(tr.toolUseId);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
result.push(entry);
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
export function truncateHistory(history, limit) {
|
|
81
|
+
let sanitized = sanitizeHistory(stripHistoryImages(history));
|
|
82
|
+
let historySize = JSON.stringify(sanitized).length;
|
|
83
|
+
while (historySize > limit && sanitized.length > 2) {
|
|
84
|
+
sanitized.shift();
|
|
85
|
+
while (sanitized.length > 0 && !sanitized[0]?.userInputMessage)
|
|
86
|
+
sanitized.shift();
|
|
87
|
+
sanitized = sanitizeHistory(sanitized);
|
|
88
|
+
historySize = JSON.stringify(sanitized).length;
|
|
89
|
+
}
|
|
90
|
+
return injectSyntheticToolCalls(sanitized);
|
|
91
|
+
}
|
|
92
|
+
export function extractToolNamesFromHistory(history) {
|
|
93
|
+
const names = new Set();
|
|
94
|
+
for (const entry of history) {
|
|
95
|
+
for (const tu of entry.assistantResponseMessage?.toolUses ?? []) {
|
|
96
|
+
if (tu.name)
|
|
97
|
+
names.add(tu.name);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return names;
|
|
101
|
+
}
|
|
102
|
+
export function addPlaceholderTools(tools, history) {
|
|
103
|
+
const historyNames = extractToolNamesFromHistory(history);
|
|
104
|
+
if (historyNames.size === 0)
|
|
105
|
+
return tools;
|
|
106
|
+
const existing = new Set(tools.map((t) => t.toolSpecification?.name).filter(Boolean));
|
|
107
|
+
const missing = Array.from(historyNames).filter((n) => !existing.has(n));
|
|
108
|
+
if (missing.length === 0)
|
|
109
|
+
return tools;
|
|
110
|
+
return [
|
|
111
|
+
...tools,
|
|
112
|
+
...missing.map((name) => ({
|
|
113
|
+
toolSpecification: {
|
|
114
|
+
name,
|
|
115
|
+
description: "Tool",
|
|
116
|
+
inputSchema: { json: { type: "object", properties: {} } },
|
|
117
|
+
},
|
|
118
|
+
})),
|
|
119
|
+
];
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.js","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
export type { KiroStreamEvent } from "./event-parser.js";
|
|
3
|
+
export { KIRO_MODEL_IDS, kiroModels, resolveApiRegion, resolveKiroModel, } from "./models.js";
|
|
4
|
+
export { streamKiro } from "./stream.js";
|
|
5
|
+
export default function (pi: ExtensionAPI): void;
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AASpE,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EACN,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,gBAAgB,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,CAAC,OAAO,WAAW,EAAE,EAAE,YAAY,QAgCxC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Feature 1: Extension Registration
|
|
2
|
+
//
|
|
3
|
+
// Entry point that wires all features together via pi.registerProvider().
|
|
4
|
+
import { getKiroCliCredentials } from "./kiro-cli.js";
|
|
5
|
+
import { setExtensionContext } from "./login-ui.js";
|
|
6
|
+
import { getCachedModels, kiroModels, resolveApiRegion } from "./models.js";
|
|
7
|
+
import { loginKiro, refreshKiroToken } from "./oauth.js";
|
|
8
|
+
import { streamKiro } from "./stream.js";
|
|
9
|
+
import { fetchKiroUsage } from "./usage.js";
|
|
10
|
+
export { KIRO_MODEL_IDS, kiroModels, resolveApiRegion, resolveKiroModel, } from "./models.js";
|
|
11
|
+
export { streamKiro } from "./stream.js";
|
|
12
|
+
export default function (pi) {
|
|
13
|
+
// Capture ctx for the custom TUI login component
|
|
14
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
15
|
+
setExtensionContext(ctx);
|
|
16
|
+
});
|
|
17
|
+
pi.registerProvider("kiro", {
|
|
18
|
+
baseUrl: "https://q.us-east-1.amazonaws.com/generateAssistantResponse",
|
|
19
|
+
api: "kiro-api",
|
|
20
|
+
models: kiroModels,
|
|
21
|
+
oauth: {
|
|
22
|
+
// Name reflects all supported auth methods: AWS Builder ID, Google, GitHub
|
|
23
|
+
name: "Kiro (Builder ID / Google / GitHub)",
|
|
24
|
+
login: loginKiro,
|
|
25
|
+
refreshToken: refreshKiroToken,
|
|
26
|
+
getApiKey: (cred) => cred.access,
|
|
27
|
+
getCliCredentials: getKiroCliCredentials,
|
|
28
|
+
modifyModels: (models, cred) => {
|
|
29
|
+
const apiRegion = resolveApiRegion(cred.region);
|
|
30
|
+
const cachedKiro = getCachedModels(apiRegion);
|
|
31
|
+
const nonKiro = models.filter((m) => m.provider !== "kiro");
|
|
32
|
+
const modifiedKiro = cachedKiro.map((m) => ({
|
|
33
|
+
...m,
|
|
34
|
+
baseUrl: `https://q.${apiRegion}.amazonaws.com/generateAssistantResponse`,
|
|
35
|
+
}));
|
|
36
|
+
return [...nonKiro, ...modifiedKiro];
|
|
37
|
+
},
|
|
38
|
+
fetchUsage: fetchKiroUsage,
|
|
39
|
+
// biome-ignore lint/suspicious/noExplicitAny: ProviderConfig.oauth doesn't include getCliCredentials but OAuthProviderInterface does
|
|
40
|
+
},
|
|
41
|
+
streamSimple: streamKiro,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,EAAE;AACF,0EAA0E;AAI1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG5C,OAAO,EACN,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,gBAAgB,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,CAAC,OAAO,WAAW,EAAgB;IACxC,iDAAiD;IACjD,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;QAC5C,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,gBAAgB,CAAC,MAAM,EAAE;QAC3B,OAAO,EAAE,6DAA6D;QACtE,GAAG,EAAE,UAAU;QACf,MAAM,EAAE,UAAU;QAClB,KAAK,EAAE;YACN,2EAA2E;YAC3E,IAAI,EAAE,qCAAqC;YAC3C,KAAK,EAAE,SAAS;YAChB,YAAY,EAAE,gBAAgB;YAC9B,SAAS,EAAE,CAAC,IAAsB,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM;YAClD,iBAAiB,EAAE,qBAAqB;YACxC,YAAY,EAAE,CAAC,MAAoB,EAAE,IAAsB,EAAE,EAAE;gBAC9D,MAAM,SAAS,GAAG,gBAAgB,CAAE,IAAwB,CAAC,MAAM,CAAC,CAAC;gBACrE,MAAM,UAAU,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;gBAC9C,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAa,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC;gBACxE,MAAM,YAAY,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAa,EAAE,EAAE,CAAC,CAAC;oBACvD,GAAG,CAAC;oBACJ,OAAO,EAAE,aAAa,SAAS,0CAA0C;iBACzE,CAAC,CAAC,CAAC;gBAEJ,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,YAAY,CAAC,CAAC;YACtC,CAAC;YACD,UAAU,EAAE,cAAc;YAC1B,qIAAqI;SAC9H;QACR,YAAY,EAAE,UAAU;KACxB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { KiroAuthMethod, KiroCredentials } from "./oauth.js";
|
|
2
|
+
export declare function getKiroCliDbPath(): string | undefined;
|
|
3
|
+
export declare function getKiroCliCredentials(): KiroCredentials | undefined;
|
|
4
|
+
/**
|
|
5
|
+
* Like getKiroCliCredentials but returns credentials even when the access token
|
|
6
|
+
* is expired, as long as a refresh token exists. Used to attempt a token refresh
|
|
7
|
+
* before falling back to the full device code login flow.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getKiroCliCredentialsAllowExpired(): KiroCredentials | undefined;
|
|
10
|
+
declare function tryKiroCliToken(dbPath: string, tokenKey: string, authMethod: KiroAuthMethod, allowExpired?: boolean): KiroCredentials | undefined;
|
|
11
|
+
export { tryKiroCliToken };
|
|
12
|
+
/**
|
|
13
|
+
* Get the social token (Google/GitHub) from kiro-cli if available.
|
|
14
|
+
* Returns undefined if no valid social token exists.
|
|
15
|
+
* This is used to prefer social login when the user has logged in that way.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getKiroCliSocialToken(): KiroCredentials | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Like getKiroCliSocialToken but returns credentials even when the access token
|
|
20
|
+
* is expired, as long as a refresh token exists.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getKiroCliSocialTokenAllowExpired(): KiroCredentials | undefined;
|
|
23
|
+
export declare function saveKiroCliCredentials(creds: KiroCredentials): void;
|
|
24
|
+
/**
|
|
25
|
+
* Ask kiro-cli to refresh its own tokens via `kiro-cli debug refresh-auth-token`,
|
|
26
|
+
* then re-read the SQLite DB for fresh credentials.
|
|
27
|
+
*
|
|
28
|
+
* Returns refreshed credentials on success, or undefined if kiro-cli is not
|
|
29
|
+
* installed, the command fails, or the DB still has no valid tokens afterward.
|
|
30
|
+
*/
|
|
31
|
+
export declare function refreshViaKiroCli(): KiroCredentials | undefined;
|
|
32
|
+
//# sourceMappingURL=kiro-cli.d.ts.map
|