@sunerpy/opencode-kiro-auth 0.5.2 → 0.6.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/dist/plugin/accounts.d.ts +12 -2
- package/dist/plugin/accounts.js +26 -9
- package/dist/plugin/config/loader.js +2 -0
- package/dist/plugin/config/schema.d.ts +17 -0
- package/dist/plugin/config/schema.js +15 -0
- package/dist/plugin/sync/kiro-cli-parser.d.ts +1 -0
- package/dist/plugin/sync/kiro-cli-parser.js +6 -0
- package/dist/plugin/sync/kiro-cli.js +48 -43
- package/dist/plugin.js +4 -1
- package/package.json +1 -1
|
@@ -6,8 +6,18 @@ export declare class AccountManager {
|
|
|
6
6
|
private strategy;
|
|
7
7
|
private lastToastTime;
|
|
8
8
|
private lastUsageToastTime;
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
private rrCursor;
|
|
10
|
+
private stickyId?;
|
|
11
|
+
private quotaAvoidanceEnabled;
|
|
12
|
+
private quotaReserveThreshold;
|
|
13
|
+
constructor(accounts: ManagedAccount[], strategy?: AccountSelectionStrategy, opts?: {
|
|
14
|
+
quotaAvoidanceEnabled?: boolean;
|
|
15
|
+
quotaReserveThreshold?: number;
|
|
16
|
+
});
|
|
17
|
+
static loadFromDisk(strategy?: AccountSelectionStrategy, opts?: {
|
|
18
|
+
quotaAvoidanceEnabled?: boolean;
|
|
19
|
+
quotaReserveThreshold?: number;
|
|
20
|
+
}): Promise<AccountManager>;
|
|
11
21
|
getAccountCount(): number;
|
|
12
22
|
getAccounts(): ManagedAccount[];
|
|
13
23
|
shouldShowToast(debounce?: number): boolean;
|
package/dist/plugin/accounts.js
CHANGED
|
@@ -15,12 +15,18 @@ export class AccountManager {
|
|
|
15
15
|
strategy;
|
|
16
16
|
lastToastTime = 0;
|
|
17
17
|
lastUsageToastTime = 0;
|
|
18
|
-
|
|
18
|
+
rrCursor = 0;
|
|
19
|
+
stickyId;
|
|
20
|
+
quotaAvoidanceEnabled;
|
|
21
|
+
quotaReserveThreshold;
|
|
22
|
+
constructor(accounts, strategy = 'sticky', opts) {
|
|
19
23
|
this.accounts = accounts;
|
|
20
24
|
this.cursor = 0;
|
|
21
25
|
this.strategy = strategy;
|
|
26
|
+
this.quotaAvoidanceEnabled = opts?.quotaAvoidanceEnabled ?? true;
|
|
27
|
+
this.quotaReserveThreshold = opts?.quotaReserveThreshold ?? 0.95;
|
|
22
28
|
}
|
|
23
|
-
static async loadFromDisk(strategy) {
|
|
29
|
+
static async loadFromDisk(strategy, opts) {
|
|
24
30
|
const rows = kiroDb.getAccounts();
|
|
25
31
|
const accounts = rows.map((r) => ({
|
|
26
32
|
id: r.id,
|
|
@@ -44,7 +50,7 @@ export class AccountManager {
|
|
|
44
50
|
usedCount: r.used_count,
|
|
45
51
|
limitCount: r.limit_count
|
|
46
52
|
}));
|
|
47
|
-
return new AccountManager(accounts, strategy || 'sticky');
|
|
53
|
+
return new AccountManager(accounts, strategy || 'sticky', opts);
|
|
48
54
|
}
|
|
49
55
|
getAccountCount() {
|
|
50
56
|
return this.accounts.length;
|
|
@@ -86,17 +92,29 @@ export class AccountManager {
|
|
|
86
92
|
}
|
|
87
93
|
return !(a.rateLimitResetTime && now < a.rateLimitResetTime);
|
|
88
94
|
});
|
|
95
|
+
let candidatePool = available;
|
|
96
|
+
if (this.accounts.length > 1 && this.quotaAvoidanceEnabled) {
|
|
97
|
+
const ratio = (a) => a.limitCount && a.limitCount > 0 ? (a.usedCount || 0) / a.limitCount : 0;
|
|
98
|
+
const ample = available.filter((a) => ratio(a) < this.quotaReserveThreshold);
|
|
99
|
+
// used>=limit stays in nearFull (soft/drainable, NOT hard-excluded): the
|
|
100
|
+
// real 402 is the authoritative exhaustion signal and already
|
|
101
|
+
// hard-switches accounts in error-handler.
|
|
102
|
+
const nearFull = available.filter((a) => ratio(a) >= this.quotaReserveThreshold);
|
|
103
|
+
candidatePool = ample.length > 0 ? ample : nearFull;
|
|
104
|
+
}
|
|
89
105
|
let selected;
|
|
90
|
-
if (
|
|
106
|
+
if (candidatePool.length > 0) {
|
|
91
107
|
if (this.strategy === 'sticky') {
|
|
92
|
-
selected =
|
|
108
|
+
selected = candidatePool.find((a) => a.id === this.stickyId) || candidatePool[0];
|
|
109
|
+
if (selected)
|
|
110
|
+
this.stickyId = selected.id;
|
|
93
111
|
}
|
|
94
112
|
else if (this.strategy === 'round-robin') {
|
|
95
|
-
selected =
|
|
96
|
-
this.
|
|
113
|
+
selected = candidatePool[this.rrCursor % candidatePool.length];
|
|
114
|
+
this.rrCursor++;
|
|
97
115
|
}
|
|
98
116
|
else if (this.strategy === 'lowest-usage') {
|
|
99
|
-
selected = [...
|
|
117
|
+
selected = [...candidatePool].sort((a, b) => (a.usedCount || 0) - (b.usedCount || 0) || (a.lastUsed || 0) - (b.lastUsed || 0))[0];
|
|
100
118
|
}
|
|
101
119
|
}
|
|
102
120
|
if (!selected) {
|
|
@@ -113,7 +131,6 @@ export class AccountManager {
|
|
|
113
131
|
if (selected) {
|
|
114
132
|
selected.lastUsed = now;
|
|
115
133
|
selected.usedCount = (selected.usedCount || 0) + 1;
|
|
116
|
-
this.cursor = this.accounts.indexOf(selected);
|
|
117
134
|
return selected;
|
|
118
135
|
}
|
|
119
136
|
return null;
|
|
@@ -90,6 +90,8 @@ function applyEnvOverrides(config) {
|
|
|
90
90
|
account_selection_strategy: env.KIRO_ACCOUNT_SELECTION_STRATEGY
|
|
91
91
|
? AccountSelectionStrategySchema.catch('lowest-usage').parse(env.KIRO_ACCOUNT_SELECTION_STRATEGY)
|
|
92
92
|
: config.account_selection_strategy,
|
|
93
|
+
quota_avoidance_enabled: parseBooleanEnv(env.KIRO_QUOTA_AVOIDANCE_ENABLED, config.quota_avoidance_enabled),
|
|
94
|
+
quota_reserve_threshold: parseNumberEnv(env.KIRO_QUOTA_RESERVE_THRESHOLD, config.quota_reserve_threshold),
|
|
93
95
|
default_region: env.KIRO_DEFAULT_REGION
|
|
94
96
|
? RegionSchema.catch('us-east-1').parse(env.KIRO_DEFAULT_REGION)
|
|
95
97
|
: config.default_region,
|
|
@@ -19,6 +19,19 @@ export declare const KiroConfigSchema: z.ZodObject<{
|
|
|
19
19
|
idc_region: z.ZodOptional<z.ZodEnum<["us-east-1", "us-east-2", "us-west-1", "us-west-2", "af-south-1", "ap-east-1", "ap-south-2", "ap-southeast-3", "ap-southeast-5", "ap-southeast-4", "ap-south-1", "ap-southeast-6", "ap-northeast-3", "ap-northeast-2", "ap-southeast-1", "ap-southeast-2", "ap-east-2", "ap-southeast-7", "ap-northeast-1", "ca-central-1", "ca-west-1", "eu-central-1", "eu-west-1", "eu-west-2", "eu-south-1", "eu-west-3", "eu-south-2", "eu-north-1", "eu-central-2", "il-central-1", "mx-central-1", "me-south-1", "me-central-1", "sa-east-1"]>>;
|
|
20
20
|
idc_profile_arn: z.ZodOptional<z.ZodString>;
|
|
21
21
|
account_selection_strategy: z.ZodDefault<z.ZodEnum<["sticky", "round-robin", "lowest-usage"]>>;
|
|
22
|
+
/**
|
|
23
|
+
* Softly avoid accounts whose usage ratio is at/above
|
|
24
|
+
* `quota_reserve_threshold` when other accounts still have room. When ALL
|
|
25
|
+
* healthy accounts are near-full they are drained anyway (the real 402 in
|
|
26
|
+
* error-handler is the authoritative hard-switch). Only affects
|
|
27
|
+
* multi-account selection; single-account behavior is unchanged.
|
|
28
|
+
*/
|
|
29
|
+
quota_avoidance_enabled: z.ZodDefault<z.ZodBoolean>;
|
|
30
|
+
/**
|
|
31
|
+
* Usage ratio (used/limit) at/above which an account is considered
|
|
32
|
+
* near-full and softly avoided. Default 0.95 (95%).
|
|
33
|
+
*/
|
|
34
|
+
quota_reserve_threshold: z.ZodDefault<z.ZodNumber>;
|
|
22
35
|
default_region: z.ZodDefault<z.ZodEnum<["us-east-1", "us-east-2", "us-west-1", "us-west-2", "af-south-1", "ap-east-1", "ap-south-2", "ap-southeast-3", "ap-southeast-5", "ap-southeast-4", "ap-south-1", "ap-southeast-6", "ap-northeast-3", "ap-northeast-2", "ap-southeast-1", "ap-southeast-2", "ap-east-2", "ap-southeast-7", "ap-northeast-1", "ca-central-1", "ca-west-1", "eu-central-1", "eu-west-1", "eu-west-2", "eu-south-1", "eu-west-3", "eu-south-2", "eu-north-1", "eu-central-2", "il-central-1", "mx-central-1", "me-south-1", "me-central-1", "sa-east-1"]>>;
|
|
23
36
|
rate_limit_retry_delay_ms: z.ZodDefault<z.ZodNumber>;
|
|
24
37
|
rate_limit_max_retries: z.ZodDefault<z.ZodNumber>;
|
|
@@ -52,6 +65,8 @@ export declare const KiroConfigSchema: z.ZodObject<{
|
|
|
52
65
|
auto_effort_mapping: z.ZodDefault<z.ZodBoolean>;
|
|
53
66
|
}, "strip", z.ZodTypeAny, {
|
|
54
67
|
account_selection_strategy: "sticky" | "round-robin" | "lowest-usage";
|
|
68
|
+
quota_avoidance_enabled: boolean;
|
|
69
|
+
quota_reserve_threshold: number;
|
|
55
70
|
default_region: "us-east-1" | "us-east-2" | "us-west-1" | "us-west-2" | "af-south-1" | "ap-east-1" | "ap-south-2" | "ap-southeast-3" | "ap-southeast-5" | "ap-southeast-4" | "ap-south-1" | "ap-southeast-6" | "ap-northeast-3" | "ap-northeast-2" | "ap-southeast-1" | "ap-southeast-2" | "ap-east-2" | "ap-southeast-7" | "ap-northeast-1" | "ca-central-1" | "ca-west-1" | "eu-central-1" | "eu-west-1" | "eu-west-2" | "eu-south-1" | "eu-west-3" | "eu-south-2" | "eu-north-1" | "eu-central-2" | "il-central-1" | "mx-central-1" | "me-south-1" | "me-central-1" | "sa-east-1";
|
|
56
71
|
rate_limit_retry_delay_ms: number;
|
|
57
72
|
rate_limit_max_retries: number;
|
|
@@ -77,6 +92,8 @@ export declare const KiroConfigSchema: z.ZodObject<{
|
|
|
77
92
|
idc_region?: "us-east-1" | "us-east-2" | "us-west-1" | "us-west-2" | "af-south-1" | "ap-east-1" | "ap-south-2" | "ap-southeast-3" | "ap-southeast-5" | "ap-southeast-4" | "ap-south-1" | "ap-southeast-6" | "ap-northeast-3" | "ap-northeast-2" | "ap-southeast-1" | "ap-southeast-2" | "ap-east-2" | "ap-southeast-7" | "ap-northeast-1" | "ca-central-1" | "ca-west-1" | "eu-central-1" | "eu-west-1" | "eu-west-2" | "eu-south-1" | "eu-west-3" | "eu-south-2" | "eu-north-1" | "eu-central-2" | "il-central-1" | "mx-central-1" | "me-south-1" | "me-central-1" | "sa-east-1" | undefined;
|
|
78
93
|
idc_profile_arn?: string | undefined;
|
|
79
94
|
account_selection_strategy?: "sticky" | "round-robin" | "lowest-usage" | undefined;
|
|
95
|
+
quota_avoidance_enabled?: boolean | undefined;
|
|
96
|
+
quota_reserve_threshold?: number | undefined;
|
|
80
97
|
default_region?: "us-east-1" | "us-east-2" | "us-west-1" | "us-west-2" | "af-south-1" | "ap-east-1" | "ap-south-2" | "ap-southeast-3" | "ap-southeast-5" | "ap-southeast-4" | "ap-south-1" | "ap-southeast-6" | "ap-northeast-3" | "ap-northeast-2" | "ap-southeast-1" | "ap-southeast-2" | "ap-east-2" | "ap-southeast-7" | "ap-northeast-1" | "ca-central-1" | "ca-west-1" | "eu-central-1" | "eu-west-1" | "eu-west-2" | "eu-south-1" | "eu-west-3" | "eu-south-2" | "eu-north-1" | "eu-central-2" | "il-central-1" | "mx-central-1" | "me-south-1" | "me-central-1" | "sa-east-1" | undefined;
|
|
81
98
|
rate_limit_retry_delay_ms?: number | undefined;
|
|
82
99
|
rate_limit_max_retries?: number | undefined;
|
|
@@ -51,6 +51,19 @@ export const KiroConfigSchema = z.object({
|
|
|
51
51
|
idc_region: RegionSchema.optional(),
|
|
52
52
|
idc_profile_arn: z.string().optional(),
|
|
53
53
|
account_selection_strategy: AccountSelectionStrategySchema.default('lowest-usage'),
|
|
54
|
+
/**
|
|
55
|
+
* Softly avoid accounts whose usage ratio is at/above
|
|
56
|
+
* `quota_reserve_threshold` when other accounts still have room. When ALL
|
|
57
|
+
* healthy accounts are near-full they are drained anyway (the real 402 in
|
|
58
|
+
* error-handler is the authoritative hard-switch). Only affects
|
|
59
|
+
* multi-account selection; single-account behavior is unchanged.
|
|
60
|
+
*/
|
|
61
|
+
quota_avoidance_enabled: z.boolean().default(true),
|
|
62
|
+
/**
|
|
63
|
+
* Usage ratio (used/limit) at/above which an account is considered
|
|
64
|
+
* near-full and softly avoided. Default 0.95 (95%).
|
|
65
|
+
*/
|
|
66
|
+
quota_reserve_threshold: z.number().min(0).max(1).default(0.95),
|
|
54
67
|
default_region: RegionSchema.default('us-east-1'),
|
|
55
68
|
rate_limit_retry_delay_ms: z.number().min(1000).max(60000).default(5000),
|
|
56
69
|
rate_limit_max_retries: z.number().min(0).max(10).default(3),
|
|
@@ -85,6 +98,8 @@ export const KiroConfigSchema = z.object({
|
|
|
85
98
|
});
|
|
86
99
|
export const DEFAULT_CONFIG = {
|
|
87
100
|
account_selection_strategy: 'lowest-usage',
|
|
101
|
+
quota_avoidance_enabled: true,
|
|
102
|
+
quota_reserve_threshold: 0.95,
|
|
88
103
|
default_region: 'us-east-1',
|
|
89
104
|
rate_limit_retry_delay_ms: 5000,
|
|
90
105
|
rate_limit_max_retries: 3,
|
|
@@ -6,3 +6,4 @@ export declare function findClientCredsRecursive(input: unknown): {
|
|
|
6
6
|
clientSecret?: string;
|
|
7
7
|
};
|
|
8
8
|
export declare function makePlaceholderEmail(authMethod: string, region: string, clientId?: string, profileArn?: string): string;
|
|
9
|
+
export declare function isPlaceholderEmail(email: unknown): boolean;
|
|
@@ -70,3 +70,9 @@ export function makePlaceholderEmail(authMethod, region, clientId, profileArn) {
|
|
|
70
70
|
const h = createHash('sha256').update(seed).digest('hex').slice(0, 16);
|
|
71
71
|
return `${authMethod}-placeholder+${h}@awsapps.local`;
|
|
72
72
|
}
|
|
73
|
+
// Loose pre-filter ONLY. NOT authoritative: before deleting, callers must also
|
|
74
|
+
// require row.email === exact makePlaceholderEmail(...) AND row.id === recomputed
|
|
75
|
+
// placeholderId for the SAME identity, so a real account is never deleted.
|
|
76
|
+
export function isPlaceholderEmail(email) {
|
|
77
|
+
return (typeof email === 'string' && email.includes('-placeholder+') && email.endsWith('@awsapps.local'));
|
|
78
|
+
}
|
|
@@ -5,7 +5,7 @@ import { createDeterministicAccountId } from '../accounts.js';
|
|
|
5
5
|
import * as logger from '../logger.js';
|
|
6
6
|
import { kiroDb } from '../storage/sqlite.js';
|
|
7
7
|
import { fetchUsageLimits } from '../usage.js';
|
|
8
|
-
import { findClientCredsRecursive, getCliDbPath, makePlaceholderEmail, normalizeExpiresAt, safeJsonParse } from './kiro-cli-parser.js';
|
|
8
|
+
import { findClientCredsRecursive, getCliDbPath, isPlaceholderEmail, makePlaceholderEmail, normalizeExpiresAt, safeJsonParse } from './kiro-cli-parser.js';
|
|
9
9
|
import { readActiveProfileArnFromKiroCli } from './kiro-cli-profile.js';
|
|
10
10
|
import { getStaleKiroCliAccountIds, STALE_CLI_ACCOUNT_REASON } from './stale-accounts.js';
|
|
11
11
|
export async function syncFromKiroCli() {
|
|
@@ -96,61 +96,66 @@ export async function syncFromKiroCli() {
|
|
|
96
96
|
}
|
|
97
97
|
const all = kiroDb.getAccounts();
|
|
98
98
|
if (!email) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
99
|
+
const sameIdentity = all.filter((a) => {
|
|
100
|
+
if (profileArn && a.auth_method === authMethod && a.profile_arn === profileArn)
|
|
101
|
+
return true;
|
|
102
|
+
if (authMethod === 'idc' &&
|
|
103
|
+
clientId &&
|
|
104
|
+
a.auth_method === 'idc' &&
|
|
105
|
+
a.client_id === clientId)
|
|
106
|
+
return true;
|
|
107
|
+
return false;
|
|
108
|
+
});
|
|
109
|
+
const realAccount = sameIdentity.find((a) => typeof a.email === 'string' && a.email && !isPlaceholderEmail(a.email));
|
|
110
|
+
if (realAccount) {
|
|
111
|
+
email = realAccount.email;
|
|
108
112
|
}
|
|
109
113
|
else {
|
|
114
|
+
const placeholderId = createDeterministicAccountId(makePlaceholderEmail(authMethod, serviceRegion, clientId, profileArn), authMethod, clientId, profileArn);
|
|
115
|
+
if (await kiroDb.isAccountRemoved(placeholderId)) {
|
|
116
|
+
await kiroDb.clearRemovedAccount(placeholderId);
|
|
117
|
+
}
|
|
110
118
|
email = makePlaceholderEmail(authMethod, serviceRegion, clientId, profileArn);
|
|
111
119
|
}
|
|
112
120
|
}
|
|
113
121
|
const resolvedEmail = email || makePlaceholderEmail(authMethod, serviceRegion, clientId, profileArn);
|
|
122
|
+
const hasRealEmail = !!resolvedEmail && !isPlaceholderEmail(resolvedEmail);
|
|
114
123
|
const id = createDeterministicAccountId(resolvedEmail, authMethod, clientId, profileArn);
|
|
124
|
+
// Cleanup runs BEFORE the fresh-enough early-continue: a lingering
|
|
125
|
+
// same-identity placeholder must be removed even when the real account
|
|
126
|
+
// is already up to date and would otherwise skip the rest of the round.
|
|
127
|
+
if (hasRealEmail) {
|
|
128
|
+
for (const row of all) {
|
|
129
|
+
if (row.id === id)
|
|
130
|
+
continue;
|
|
131
|
+
const sameIdentity = (!!profileArn && row.auth_method === authMethod && row.profile_arn === profileArn) ||
|
|
132
|
+
(authMethod === 'idc' &&
|
|
133
|
+
!!clientId &&
|
|
134
|
+
row.auth_method === 'idc' &&
|
|
135
|
+
row.client_id === clientId);
|
|
136
|
+
if (!sameIdentity)
|
|
137
|
+
continue;
|
|
138
|
+
if (!isPlaceholderEmail(row.email))
|
|
139
|
+
continue;
|
|
140
|
+
// Prove the row is a genuine placeholder by self-consistency against
|
|
141
|
+
// its OWN fields (clientId rotates across device re-registration, so
|
|
142
|
+
// recomputing with the current token's clientId would miss it). A
|
|
143
|
+
// real email can never equal its own makePlaceholderEmail recompute,
|
|
144
|
+
// so this never deletes a real account.
|
|
145
|
+
const rowPlaceholderEmail = makePlaceholderEmail(row.auth_method, row.region, row.client_id, row.profile_arn);
|
|
146
|
+
const rowPlaceholderId = createDeterministicAccountId(rowPlaceholderEmail, row.auth_method, row.client_id, row.profile_arn);
|
|
147
|
+
if (row.email === rowPlaceholderEmail && row.id === rowPlaceholderId) {
|
|
148
|
+
await kiroDb.deleteAccount(row.id);
|
|
149
|
+
await kiroDb.addRemovedAccount(row.id);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
115
153
|
const existingById = all.find((a) => a.id === id);
|
|
116
154
|
if (existingById &&
|
|
117
155
|
existingById.is_healthy === 1 &&
|
|
118
156
|
existingById.expires_at >= cliExpiresAt &&
|
|
119
157
|
existingById.expires_at > Date.now())
|
|
120
158
|
continue;
|
|
121
|
-
if (usageOk) {
|
|
122
|
-
const placeholderEmail = makePlaceholderEmail(authMethod, serviceRegion, clientId, profileArn);
|
|
123
|
-
const placeholderId = createDeterministicAccountId(placeholderEmail, authMethod, clientId, profileArn);
|
|
124
|
-
if (placeholderId !== id) {
|
|
125
|
-
const placeholderRow = all.find((a) => a.id === placeholderId);
|
|
126
|
-
if (placeholderRow && (await kiroDb.isAccountRemoved(placeholderId))) {
|
|
127
|
-
skippedRemoved++;
|
|
128
|
-
}
|
|
129
|
-
else if (placeholderRow) {
|
|
130
|
-
await kiroDb.upsertAccount({
|
|
131
|
-
id: placeholderId,
|
|
132
|
-
email: placeholderRow.email,
|
|
133
|
-
authMethod,
|
|
134
|
-
region: placeholderRow.region || serviceRegion,
|
|
135
|
-
oidcRegion: placeholderRow.oidc_region || oidcRegion,
|
|
136
|
-
clientId,
|
|
137
|
-
clientSecret,
|
|
138
|
-
profileArn,
|
|
139
|
-
refreshToken: placeholderRow.refresh_token || refreshToken,
|
|
140
|
-
accessToken: placeholderRow.access_token || accessToken,
|
|
141
|
-
expiresAt: placeholderRow.expires_at || cliExpiresAt,
|
|
142
|
-
rateLimitResetTime: 0,
|
|
143
|
-
isHealthy: false,
|
|
144
|
-
failCount: 10,
|
|
145
|
-
unhealthyReason: 'Replaced by real email',
|
|
146
|
-
recoveryTime: Date.now() + 31536000000,
|
|
147
|
-
usedCount: placeholderRow.used_count || 0,
|
|
148
|
-
limitCount: placeholderRow.limit_count || 0,
|
|
149
|
-
lastSync: Date.now()
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
159
|
if (await kiroDb.isAccountRemoved(id)) {
|
|
155
160
|
skippedRemoved++;
|
|
156
161
|
continue;
|
package/dist/plugin.js
CHANGED
|
@@ -15,7 +15,10 @@ export const createKiroPlugin = (id) => async ({ client, directory }) => {
|
|
|
15
15
|
const cache = new AccountCache(60000);
|
|
16
16
|
const repository = new AccountRepository(cache);
|
|
17
17
|
const authHandler = new AuthHandler(config, repository);
|
|
18
|
-
const accountManager = await AccountManager.loadFromDisk(config.account_selection_strategy
|
|
18
|
+
const accountManager = await AccountManager.loadFromDisk(config.account_selection_strategy, {
|
|
19
|
+
quotaAvoidanceEnabled: config.quota_avoidance_enabled,
|
|
20
|
+
quotaReserveThreshold: config.quota_reserve_threshold
|
|
21
|
+
});
|
|
19
22
|
authHandler.setAccountManager(accountManager);
|
|
20
23
|
const requestHandler = new RequestHandler(accountManager, config, repository, client);
|
|
21
24
|
// Compute the base URL once so both the config hook and auth loader use the same value
|