@serviceme/devtools-core 2.0.0 → 2.0.2
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/auth-Bzss8zOv.mjs +995 -0
- package/dist/auth-Bzss8zOv.mjs.map +1 -0
- package/dist/auth-DXam3c4S.js +1078 -0
- package/dist/auth-DXam3c4S.js.map +1 -0
- package/dist/auth.d.mts +2 -2
- package/dist/auth.d.ts +2 -2
- package/dist/auth.js +14 -1029
- package/dist/auth.mjs +2 -991
- package/dist/device-CDDcwDY6.mjs +758 -0
- package/dist/device-CDDcwDY6.mjs.map +1 -0
- package/dist/device-DuAYH8bk.js +839 -0
- package/dist/device-DuAYH8bk.js.map +1 -0
- package/dist/device.d.mts +2 -455
- package/dist/device.d.ts +2 -455
- package/dist/device.js +15 -728
- package/dist/device.mjs +2 -679
- package/dist/index-2rX86yMq.d.mts +331 -0
- package/dist/index-BI11AfMH.d.mts +377 -0
- package/dist/index-BI11AfMH.d.ts +377 -0
- package/dist/index-CoA6y0MP.d.mts +498 -0
- package/dist/index-CoA6y0MP.d.ts +498 -0
- package/dist/index-DaW7IYA-.d.mts +185 -0
- package/dist/index-DaW7IYA-.d.ts +185 -0
- package/dist/index-Dp6FwWKh.d.ts +331 -0
- package/dist/index.d.mts +2340 -2101
- package/dist/index.d.ts +2340 -2101
- package/dist/index.js +8117 -10538
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +7895 -10318
- package/dist/index.mjs.map +1 -1
- package/dist/rolldown-runtime-VH7oDXx4.js +28 -0
- package/dist/skill-linker.d.mts +82 -81
- package/dist/skill-linker.d.ts +82 -81
- package/dist/skill-linker.js +359 -402
- package/dist/skill-linker.js.map +1 -1
- package/dist/skill-linker.mjs +345 -357
- package/dist/skill-linker.mjs.map +1 -1
- package/dist/skill-store-Bym2yinU.mjs +388 -0
- package/dist/skill-store-Bym2yinU.mjs.map +1 -0
- package/dist/skill-store-CJdYyyxu.js +408 -0
- package/dist/skill-store-CJdYyyxu.js.map +1 -0
- package/dist/skill-store.d.mts +41 -42
- package/dist/skill-store.d.ts +41 -42
- package/dist/skill-store.js +5 -338
- package/dist/skill-store.mjs +2 -301
- package/dist/submit-Cg7wSa3x.mjs +84 -0
- package/dist/submit-Cg7wSa3x.mjs.map +1 -0
- package/dist/submit-CltE6YOZ.js +98 -0
- package/dist/submit-CltE6YOZ.js.map +1 -0
- package/dist/submit.d.mts +2 -3
- package/dist/submit.d.ts +2 -3
- package/dist/submit.js +4 -166
- package/dist/submit.mjs +2 -130
- package/dist/toolbox-CbfxpNg-.mjs +540 -0
- package/dist/toolbox-CbfxpNg-.mjs.map +1 -0
- package/dist/toolbox-CxnOr-FY.js +614 -0
- package/dist/toolbox-CxnOr-FY.js.map +1 -0
- package/dist/toolbox.d.mts +2 -244
- package/dist/toolbox.d.ts +2 -244
- package/dist/toolbox.js +14 -584
- package/dist/toolbox.mjs +2 -536
- package/dist/{types-B9gk3dXH.d.ts → types-BCV3IedE.d.mts} +25 -23
- package/dist/{types-B9gk3dXH.d.mts → types-BCV3IedE.d.ts} +25 -23
- package/dist/userHome-BquDeFVE.js +526 -0
- package/dist/userHome-BquDeFVE.js.map +1 -0
- package/dist/userHome-CcnAQPG1.mjs +212 -0
- package/dist/userHome-CcnAQPG1.mjs.map +1 -0
- package/package.json +10 -10
- package/dist/auth.js.map +0 -1
- package/dist/auth.mjs.map +0 -1
- package/dist/device.js.map +0 -1
- package/dist/device.mjs.map +0 -1
- package/dist/index-BMk4tqIT.d.mts +0 -328
- package/dist/index-CymN0x9Z.d.ts +0 -328
- package/dist/index-PD135hlB.d.mts +0 -626
- package/dist/index-PD135hlB.d.ts +0 -626
- package/dist/skill-store.js.map +0 -1
- package/dist/skill-store.mjs.map +0 -1
- package/dist/submit.js.map +0 -1
- package/dist/submit.mjs.map +0 -1
- package/dist/toolbox.js.map +0 -1
- package/dist/toolbox.mjs.map +0 -1
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
import { AuthAccountMeta, AuthLoginResult, AuthProvider, AuthStatus, AuthSwitchResult, AuthWhoamiResult } from "@serviceme/devtools-protocol";
|
|
2
|
+
//#region src/auth/AccessControl.d.ts
|
|
3
|
+
/** Core-local mirror of `GitHubOrgMembershipCheckResult` (defined in `@serviceme/devtools-shared`). */
|
|
4
|
+
interface CoreOrgMembershipResult {
|
|
5
|
+
status: "active" | "pending" | "not_member" | "unknown";
|
|
6
|
+
httpStatus?: number;
|
|
7
|
+
role?: string;
|
|
8
|
+
directMembership?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Upstream org-membership fetcher. CLI / Extension adapters wrap
|
|
12
|
+
* `getGitHubOrgMembership` (or the local extension copy) to match
|
|
13
|
+
* this signature.
|
|
14
|
+
*/
|
|
15
|
+
type OrgMembershipFetcher = (token: string, org: string) => Promise<CoreOrgMembershipResult>;
|
|
16
|
+
/** Pluggable key/value store. Extension injects `globalState`-backed impl; CLI injects a file-backed impl. */
|
|
17
|
+
interface KeyValueStore {
|
|
18
|
+
get<T>(key: string): T | undefined;
|
|
19
|
+
update<T>(key: string, value: T): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
interface AccessCheckResult {
|
|
22
|
+
allowed: boolean;
|
|
23
|
+
reason?: "not_authenticated" | "not_member";
|
|
24
|
+
username?: string;
|
|
25
|
+
}
|
|
26
|
+
interface AccessControlOptions {
|
|
27
|
+
org: string;
|
|
28
|
+
/** Domains that auto-qualify Microsoft users without a GitHub link. */
|
|
29
|
+
microsoftEmailDomains?: readonly string[];
|
|
30
|
+
/** TTL for in-memory membership cache (ms). */
|
|
31
|
+
cacheTtlMs?: number;
|
|
32
|
+
/** TTL for persisted membership cache (ms). */
|
|
33
|
+
persistentCacheTtlMs?: number;
|
|
34
|
+
/** Tokens whose bearer can be supplied to `OrgMembershipFetcher`. */
|
|
35
|
+
tokenFetcher: (provider: AuthProvider) => Promise<string | null>;
|
|
36
|
+
/** Upstream org-membership fetcher (typically `getGitHubOrgMembership` from `@serviceme/devtools-shared`). */
|
|
37
|
+
orgFetcher: OrgMembershipFetcher;
|
|
38
|
+
/** Clock seam for tests. */
|
|
39
|
+
now?: () => number;
|
|
40
|
+
}
|
|
41
|
+
declare class AccessControl {
|
|
42
|
+
private readonly kv;
|
|
43
|
+
private readonly memCache;
|
|
44
|
+
private readonly serverInOrgMem;
|
|
45
|
+
private readonly listeners;
|
|
46
|
+
private readonly opts;
|
|
47
|
+
constructor(kv: KeyValueStore, options: AccessControlOptions);
|
|
48
|
+
/** Subscribe to inOrg changes (used by extension to refresh access-gated UI). */
|
|
49
|
+
onDidChange(listener: () => void): () => void;
|
|
50
|
+
/** Full check: requires authentication + org membership / admin grant. */
|
|
51
|
+
checkAccess(user: AuthAccountMeta | null): Promise<AccessCheckResult>;
|
|
52
|
+
/** Admin: grant access to a GitHub username (bypasses org check). */
|
|
53
|
+
grantAccess(username: string): Promise<void>;
|
|
54
|
+
/** Admin: revoke a previously granted access. */
|
|
55
|
+
revokeAccess(username: string): Promise<void>;
|
|
56
|
+
/** Snapshot of all admin-granted usernames (lowercased). */
|
|
57
|
+
getGrantedUsers(): string[];
|
|
58
|
+
/** Cached membership lookup with both in-memory + persistent layers. */
|
|
59
|
+
checkOrgMembership(username: string): Promise<boolean>;
|
|
60
|
+
/** Server-confirmed inOrg status (set by device claim flow). */
|
|
61
|
+
setServerInOrg(username: string, inOrg: boolean): void;
|
|
62
|
+
/** Inspect server-confirmed inOrg for a username; returns undefined when unknown. */
|
|
63
|
+
getServerInOrg(username: string): boolean | undefined;
|
|
64
|
+
private resolveDecision;
|
|
65
|
+
private updateCache;
|
|
66
|
+
private notifyListeners;
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region src/logger.d.ts
|
|
70
|
+
interface ServiceMeLogger {
|
|
71
|
+
debug(message: string, ...args: unknown[]): void;
|
|
72
|
+
info(message: string, ...args: unknown[]): void;
|
|
73
|
+
warn(message: string, ...args: unknown[]): void;
|
|
74
|
+
error(message: string, ...args: unknown[]): void;
|
|
75
|
+
}
|
|
76
|
+
declare const noopLogger: ServiceMeLogger;
|
|
77
|
+
declare function createConsoleLogger(prefix?: string): ServiceMeLogger;
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region src/auth/AuthStateManager.d.ts
|
|
80
|
+
interface AuthStateManagerOptions {
|
|
81
|
+
/** EventEmitter listener cap; defaults to 32 (Node default) but raised for hot test paths. */
|
|
82
|
+
maxListeners?: number;
|
|
83
|
+
}
|
|
84
|
+
declare class AuthStateManager {
|
|
85
|
+
private readonly emitter;
|
|
86
|
+
private accounts;
|
|
87
|
+
private activeProvider;
|
|
88
|
+
private activeAccountId;
|
|
89
|
+
private lastError;
|
|
90
|
+
constructor(opts?: AuthStateManagerOptions);
|
|
91
|
+
/** Subscribe to state-change events. Returns a disposer. */
|
|
92
|
+
onDidChange(listener: () => void): () => void;
|
|
93
|
+
/** Snapshot of all known accounts (immutable copy). */
|
|
94
|
+
listAccounts(): AuthAccountMeta[];
|
|
95
|
+
/** Find an account by `(provider, accountId)` tuple; returns `null` when absent. */
|
|
96
|
+
findAccount(provider: AuthProvider, accountId: string): AuthAccountMeta | null;
|
|
97
|
+
/** First account for the requested provider — used for "switch to GitHub" UX. */
|
|
98
|
+
findFirstForProvider(provider: AuthProvider): AuthAccountMeta | null;
|
|
99
|
+
/** Insert or update an account entry. New accounts land at the head of the list. */
|
|
100
|
+
upsertAccount(meta: AuthAccountMeta): void;
|
|
101
|
+
/** Remove an account entry. Returns `true` when an entry was removed. */
|
|
102
|
+
removeAccount(provider: AuthProvider, accountId: string): boolean;
|
|
103
|
+
/** Set the active provider. When `accountId` is omitted, picks the first account for that provider. */
|
|
104
|
+
setActive(provider: AuthProvider, accountId?: string): boolean;
|
|
105
|
+
/** Currently active provider — `null` when no session is active. */
|
|
106
|
+
getActiveProvider(): AuthProvider | null;
|
|
107
|
+
/** Currently active account metadata — `null` when none. */
|
|
108
|
+
getActiveAccount(): AuthAccountMeta | null;
|
|
109
|
+
/** True when at least one provider has an account entry. */
|
|
110
|
+
hasAnySession(): boolean;
|
|
111
|
+
/** Snapshot of the state for `auth.status` and bridge serialization. */
|
|
112
|
+
getStatus(): AuthStatus;
|
|
113
|
+
/** Record a non-fatal error from the last login/refresh attempt. */
|
|
114
|
+
recordError(message: string): void;
|
|
115
|
+
/** Clear the recorded error (e.g. after a successful login). */
|
|
116
|
+
clearError(): void;
|
|
117
|
+
/** Drop every account — used by `auth.logout` with no provider. */
|
|
118
|
+
clearAll(): void;
|
|
119
|
+
private fire;
|
|
120
|
+
}
|
|
121
|
+
//#endregion
|
|
122
|
+
//#region src/auth/KeychainAuthTokenStore.d.ts
|
|
123
|
+
/**
|
|
124
|
+
* KeychainAuthTokenStore — abstract adapter for token byte persistence.
|
|
125
|
+
*
|
|
126
|
+
* Per ADL-004 the OAuth token bytes live in one of three places:
|
|
127
|
+
* (a) VSCode `SecretStorage` (Extension process)
|
|
128
|
+
* (b) `@napi-rs/keyring` Entry (CLI process)
|
|
129
|
+
* (c) HTTP request `Authorization` header
|
|
130
|
+
*
|
|
131
|
+
* `AuthCore` MUST NOT call any of these directly. Instead it receives
|
|
132
|
+
* a `KeychainAuthTokenStore` via DI; CLI provides a `@napi-rs/keyring`
|
|
133
|
+
* adapter, Extension provides a `SecretStorage` adapter. This keeps
|
|
134
|
+
* Core free of native-binding concerns and lets the same business
|
|
135
|
+
* logic power both runtimes.
|
|
136
|
+
*
|
|
137
|
+
* Implementations:
|
|
138
|
+
* - CLI: `apps/serviceme-cli/src/.../KeyringTokenStore.ts` (Phase 5.3)
|
|
139
|
+
* - Extension: `apps/extension/src/.../SecretStorageTokenStore.ts` (Phase 5.5)
|
|
140
|
+
*
|
|
141
|
+
* Failure semantics — `get()` returns `null` when no token is stored
|
|
142
|
+
* (cold-start), throws when the underlying keychain is unavailable
|
|
143
|
+
* (rare on Linux without libsecret). Callers should surface the throw
|
|
144
|
+
* as `AUTH_KEYRING_UNAVAILABLE` rather than silently falling back to
|
|
145
|
+
* in-memory storage (per ADL-004 §不变量).
|
|
146
|
+
*
|
|
147
|
+
* Refs:
|
|
148
|
+
* - ADL-004 — CLI 端 Auth Token 存储选型
|
|
149
|
+
* - 4.功能规划.md §2.1 — "Core MUST NOT directly depend on `@napi-rs/keyring`"
|
|
150
|
+
*/
|
|
151
|
+
/** Opaque account identifier (provider + upstream user id). */
|
|
152
|
+
interface KeychainAccountKey {
|
|
153
|
+
provider: string;
|
|
154
|
+
accountId: string;
|
|
155
|
+
}
|
|
156
|
+
/** Non-secret metadata returned alongside a `get()` so callers can audit. */
|
|
157
|
+
interface KeychainTokenMetadata {
|
|
158
|
+
provider: string;
|
|
159
|
+
accountId: string;
|
|
160
|
+
expiresAt?: number | null;
|
|
161
|
+
storedAt?: number;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Result envelope — callers receive the token bytes (for immediate use
|
|
165
|
+
* in an HTTP `Authorization` header) plus optional non-secret metadata.
|
|
166
|
+
*
|
|
167
|
+
* IMPORTANT: the `token` field is plain `string` here, not the
|
|
168
|
+
* `SecretToken` brand. The provider -> store -> HTTP-header pipeline
|
|
169
|
+
* runs inside a single trust boundary; crossing that boundary requires
|
|
170
|
+
* `KeychainTokenEnvelope<SecretToken>` and the `auth.tokenRead`
|
|
171
|
+
* capability gate (see ADL-004 §不变量).
|
|
172
|
+
*/
|
|
173
|
+
interface KeychainTokenEnvelope {
|
|
174
|
+
token: string;
|
|
175
|
+
metadata: KeychainTokenMetadata;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Abstract token-storage adapter. All methods are async because the
|
|
179
|
+
* keyring / SecretStorage backends are async-by-nature.
|
|
180
|
+
*
|
|
181
|
+
* Thread-safety: implementations MUST be safe for concurrent calls;
|
|
182
|
+
* `AuthCore` will multiplex over multiple providers on the same
|
|
183
|
+
* runtime.
|
|
184
|
+
*/
|
|
185
|
+
interface KeychainAuthTokenStore {
|
|
186
|
+
/** Persist token bytes for the given provider + account pair. */
|
|
187
|
+
set(key: KeychainAccountKey, token: string, opts?: {
|
|
188
|
+
expiresAt?: number | null;
|
|
189
|
+
}): Promise<void>;
|
|
190
|
+
/** Fetch the token bytes; returns `null` when none is stored. */
|
|
191
|
+
get(key: KeychainAccountKey): Promise<KeychainTokenEnvelope | null>;
|
|
192
|
+
/** Remove the token entry. Idempotent — removing a missing entry is not an error. */
|
|
193
|
+
delete(key: KeychainAccountKey): Promise<void>;
|
|
194
|
+
/**
|
|
195
|
+
* List all stored token keys (metadata only — never the token bytes).
|
|
196
|
+
* Useful for multi-account enumeration and bridge `auth.status`.
|
|
197
|
+
*/
|
|
198
|
+
list(): Promise<KeychainAccountKey[]>;
|
|
199
|
+
/**
|
|
200
|
+
* Health probe — returns `false` when the keychain is unreachable
|
|
201
|
+
* (e.g. Linux without libsecret). Callers SHOULD probe on first
|
|
202
|
+
* use and surface `AUTH_KEYRING_UNAVAILABLE` rather than degrade.
|
|
203
|
+
*/
|
|
204
|
+
isAvailable(): Promise<boolean>;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Sentinel error thrown by `KeychainAuthTokenStore.get()` / `.set()`
|
|
208
|
+
* when the underlying keychain is unavailable. Callers map this to
|
|
209
|
+
* `AUTH_KEYRING_UNAVAILABLE` (Phase 5.3 error code).
|
|
210
|
+
*/
|
|
211
|
+
declare class KeychainUnavailableError extends Error {
|
|
212
|
+
constructor(message: string, cause?: unknown);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* In-memory `KeychainAuthTokenStore` — test/dev fallback. NEVER use
|
|
216
|
+
* in production: tokens live in process memory and disappear on exit.
|
|
217
|
+
* Production wiring is `KeyringTokenStore` (CLI) / `SecretStorageTokenStore`
|
|
218
|
+
* (Extension).
|
|
219
|
+
*/
|
|
220
|
+
declare class InMemoryKeychainAuthTokenStore implements KeychainAuthTokenStore {
|
|
221
|
+
private readonly entries;
|
|
222
|
+
private compositeKey;
|
|
223
|
+
set(key: KeychainAccountKey, token: string, opts?: {
|
|
224
|
+
expiresAt?: number | null;
|
|
225
|
+
}): Promise<void>;
|
|
226
|
+
get(key: KeychainAccountKey): Promise<KeychainTokenEnvelope | null>;
|
|
227
|
+
delete(key: KeychainAccountKey): Promise<void>;
|
|
228
|
+
list(): Promise<KeychainAccountKey[]>;
|
|
229
|
+
isAvailable(): Promise<boolean>;
|
|
230
|
+
}
|
|
231
|
+
//#endregion
|
|
232
|
+
//#region src/auth/providers/IAuthProvider.d.ts
|
|
233
|
+
/** Public, non-secret user metadata fetched right after device-flow success. */
|
|
234
|
+
interface IAuthProviderUserInfo {
|
|
235
|
+
id: string;
|
|
236
|
+
login?: string;
|
|
237
|
+
name?: string;
|
|
238
|
+
email?: string | null;
|
|
239
|
+
avatarUrl?: string;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Outcome of `completeDeviceFlow()`. The token is returned ONLY so the
|
|
243
|
+
* caller can immediately persist it via `KeychainAuthTokenStore`; it
|
|
244
|
+
* must not be logged, JSON.stringify'd, or stored on disk by callers.
|
|
245
|
+
*/
|
|
246
|
+
interface IAuthProviderSession {
|
|
247
|
+
token: string;
|
|
248
|
+
refreshToken?: string;
|
|
249
|
+
expiresIn?: number;
|
|
250
|
+
user: IAuthProviderUserInfo;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Abstraction for any auth provider that supports OAuth Device Flow
|
|
254
|
+
* (ADL-002). The provider is responsible for:
|
|
255
|
+
* 1. Talking to the upstream `POST <deviceCodeUrl>` to obtain the
|
|
256
|
+
* user-visible code + verification URL.
|
|
257
|
+
* 2. Polling the upstream `POST <tokenUrl>` until the user grants
|
|
258
|
+
* access (or the device code expires).
|
|
259
|
+
* 3. Fetching user metadata so the account is recognizable on the
|
|
260
|
+
* bridge side.
|
|
261
|
+
*/
|
|
262
|
+
interface IAuthProvider {
|
|
263
|
+
readonly providerId: AuthProvider;
|
|
264
|
+
/**
|
|
265
|
+
* Step 1: ask the upstream for a fresh device-flow code.
|
|
266
|
+
* Returns the user-visible code, verification URL, and the
|
|
267
|
+
* caller-supplied callback for the polling loop.
|
|
268
|
+
*/
|
|
269
|
+
requestDeviceFlow(opts?: {
|
|
270
|
+
scope?: string;
|
|
271
|
+
}): Promise<AuthLoginResult>;
|
|
272
|
+
/**
|
|
273
|
+
* Step 2: poll until the user authorizes (or the code expires).
|
|
274
|
+
* Returns the session including the token bytes — callers MUST
|
|
275
|
+
* immediately hand the token to a `KeychainAuthTokenStore` and
|
|
276
|
+
* discard the returned reference.
|
|
277
|
+
*
|
|
278
|
+
* @param shouldContinue Aborts the poll loop when it returns false
|
|
279
|
+
* (used by callers to wire up Ctrl-C, QuickPick cancel, etc.).
|
|
280
|
+
* @param initialPollIntervalMs The `pollIntervalMs` from the matching
|
|
281
|
+
* `requestDeviceFlow()` result (per the Device Flow spec's `interval`
|
|
282
|
+
* field). Implementations should never poll faster than this — doing
|
|
283
|
+
* so can put the device code into a `slow_down` state that never
|
|
284
|
+
* clears even after the user authorizes.
|
|
285
|
+
*/
|
|
286
|
+
completeDeviceFlow(deviceCode: string, shouldContinue?: () => boolean, initialPollIntervalMs?: number): Promise<IAuthProviderSession>;
|
|
287
|
+
/**
|
|
288
|
+
* Refresh an expiring access token. Throws when the provider has no
|
|
289
|
+
* refresh-token grant (GitHub user-to-server tokens, for instance,
|
|
290
|
+
* cannot be refreshed and must be re-issued via device flow).
|
|
291
|
+
*/
|
|
292
|
+
refreshAccessToken(refreshToken: string): Promise<IAuthProviderSession>;
|
|
293
|
+
/** Validate a token by hitting the provider's `GET /user`-style endpoint. */
|
|
294
|
+
validateToken(token: string): Promise<boolean>;
|
|
295
|
+
/** Fetch non-secret user metadata (used by `auth.whoami` and `auth.switch`). */
|
|
296
|
+
fetchAccountMeta(token: string): Promise<AuthAccountMeta>;
|
|
297
|
+
}
|
|
298
|
+
//#endregion
|
|
299
|
+
//#region src/auth/ProviderRegistry.d.ts
|
|
300
|
+
declare class ProviderRegistry {
|
|
301
|
+
private readonly providers;
|
|
302
|
+
/** Register or replace a provider implementation. */
|
|
303
|
+
register(provider: IAuthProvider): void;
|
|
304
|
+
/** Look up a registered provider by id; throws when missing. */
|
|
305
|
+
get(providerId: AuthProvider): IAuthProvider;
|
|
306
|
+
/** Non-throwing lookup; returns `undefined` when the provider is unknown. */
|
|
307
|
+
tryGet(providerId: AuthProvider): IAuthProvider | undefined;
|
|
308
|
+
/** Return all registered provider ids — used by `auth.status` and bridge capability hints. */
|
|
309
|
+
list(): AuthProvider[];
|
|
310
|
+
/** True when a provider has been registered for this id. */
|
|
311
|
+
has(providerId: AuthProvider): boolean;
|
|
312
|
+
}
|
|
313
|
+
//#endregion
|
|
314
|
+
//#region src/auth/AuthCore.d.ts
|
|
315
|
+
interface AuthCoreOptions {
|
|
316
|
+
providers: IAuthProvider[];
|
|
317
|
+
tokenStore: KeychainAuthTokenStore;
|
|
318
|
+
accessControl?: AccessControl;
|
|
319
|
+
stateManager?: AuthStateManager;
|
|
320
|
+
/** Diagnostic logger for login/logout lifecycle events (never receives token bytes). */
|
|
321
|
+
logger?: ServiceMeLogger;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Callback invoked once the user finishes the device-flow handshake but
|
|
325
|
+
* BEFORE the token is written to the keychain. Lets the caller display
|
|
326
|
+
* the `userCode` + `verificationUrl` to the user (Phase 5.3 CLI prints to
|
|
327
|
+
* stdout; Phase 5.5 Extension pops a webview notification).
|
|
328
|
+
*/
|
|
329
|
+
type DeviceFlowUiCallback = (result: AuthLoginResult) => void | Promise<void>;
|
|
330
|
+
/**
|
|
331
|
+
* Optional cancellation handle — when `shouldContinue()` returns false,
|
|
332
|
+
* the polling loop exits with a clear error so callers can render
|
|
333
|
+
* "Login cancelled" UX.
|
|
334
|
+
*/
|
|
335
|
+
type CancellationCheck = () => boolean;
|
|
336
|
+
declare class AuthCore {
|
|
337
|
+
private readonly registry;
|
|
338
|
+
private readonly state;
|
|
339
|
+
private readonly tokenStore;
|
|
340
|
+
private readonly accessControl?;
|
|
341
|
+
private readonly logger;
|
|
342
|
+
constructor(opts: AuthCoreOptions);
|
|
343
|
+
/** Snapshot of every account, the active provider, and the last error. */
|
|
344
|
+
status(): AuthStatus;
|
|
345
|
+
/** List accounts (immutable copy). */
|
|
346
|
+
listAccounts(): AuthAccountMeta[];
|
|
347
|
+
/**
|
|
348
|
+
* Drive the device-flow login for `provider`.
|
|
349
|
+
*
|
|
350
|
+
* Sequence:
|
|
351
|
+
* 1. Ask the provider for the user code + verification URL.
|
|
352
|
+
* 2. Surface the code to the user (via `ui`).
|
|
353
|
+
* 3. Poll until the user authorizes (or `shouldContinue` aborts).
|
|
354
|
+
* 4. Persist the token via `KeychainAuthTokenStore.set()`.
|
|
355
|
+
* 5. Insert the resulting `AuthAccountMeta` into state and mark active.
|
|
356
|
+
*/
|
|
357
|
+
login(provider: AuthProvider, ui: DeviceFlowUiCallback, shouldContinue?: CancellationCheck): Promise<AuthLoginResult>;
|
|
358
|
+
/**
|
|
359
|
+
* Complete the device-flow handshake given a pre-fetched user code.
|
|
360
|
+
* Useful when the caller (Phase 5.3 CLI) wants to fetch the code,
|
|
361
|
+
* print the URL, and then poll on a subsequent invocation.
|
|
362
|
+
*/
|
|
363
|
+
completeLogin(provider: AuthProvider, deviceCode: string, shouldContinue?: CancellationCheck): Promise<AuthLoginResult>;
|
|
364
|
+
/** Resolve the provider + token for the active session; returns null when no session is active. */
|
|
365
|
+
resolveActiveToken(): Promise<{
|
|
366
|
+
provider: AuthProvider;
|
|
367
|
+
account: AuthAccountMeta;
|
|
368
|
+
token: string;
|
|
369
|
+
} | null>;
|
|
370
|
+
/**
|
|
371
|
+
* Logout: removes the token bytes from the keychain + drops the
|
|
372
|
+
* account entry from state. When `provider` is omitted, clears
|
|
373
|
+
* every account.
|
|
374
|
+
*/
|
|
375
|
+
logout(provider?: AuthProvider): Promise<{
|
|
376
|
+
provider: AuthProvider | null;
|
|
377
|
+
success: boolean;
|
|
378
|
+
}>;
|
|
379
|
+
/** Minimal identity for `auth.whoami`. */
|
|
380
|
+
whoami(): Promise<AuthWhoamiResult>;
|
|
381
|
+
/** Switch the active provider. Returns the resulting active account. */
|
|
382
|
+
switchProvider(provider: AuthProvider, accountId?: string): AuthSwitchResult;
|
|
383
|
+
/** Run the access-control check against the active account (optional, requires AccessControl). */
|
|
384
|
+
checkAccess(): Promise<AccessCheckResult | null>;
|
|
385
|
+
/** Expose the state manager for test inspection (not for mutation). */
|
|
386
|
+
getStateManager(): AuthStateManager;
|
|
387
|
+
/** Expose the provider registry for test inspection. */
|
|
388
|
+
getProviderRegistry(): ProviderRegistry;
|
|
389
|
+
/** Expose the access control (or undefined when not configured). */
|
|
390
|
+
getAccessControl(): AccessControl | undefined;
|
|
391
|
+
private persistSession;
|
|
392
|
+
}
|
|
393
|
+
//#endregion
|
|
394
|
+
//#region src/auth/providers/GitHubAuthProvider.d.ts
|
|
395
|
+
/** Tunable provider config — exposed for tests + forks. */
|
|
396
|
+
interface GitHubAuthProviderConfig {
|
|
397
|
+
clientId: string;
|
|
398
|
+
deviceCodeUrl?: string;
|
|
399
|
+
tokenUrl?: string;
|
|
400
|
+
userUrl?: string;
|
|
401
|
+
scope?: string;
|
|
402
|
+
/** Polling interval (ms) floor. The device-flow response's `interval` wins when larger. */
|
|
403
|
+
minPollIntervalMs?: number;
|
|
404
|
+
/**
|
|
405
|
+
* Maximum poll interval after back-off. Must stay generous — GitHub's
|
|
406
|
+
* `slow_down` response requires adding a fixed step to the interval each
|
|
407
|
+
* time it occurs (see `completeDeviceFlow`), and capping this too low
|
|
408
|
+
* prevents the interval from ever satisfying GitHub's actual requirement,
|
|
409
|
+
* causing a permanent `slow_down` loop that never clears even after the
|
|
410
|
+
* user authorizes.
|
|
411
|
+
*/
|
|
412
|
+
maxPollIntervalMs?: number;
|
|
413
|
+
/** Fetch override (for tests + DI). */
|
|
414
|
+
fetchImpl?: typeof fetch;
|
|
415
|
+
/** Poll-delay override (for tests + DI). Defaults to a real timer-based sleep. */
|
|
416
|
+
sleepImpl?: (ms: number) => Promise<void>;
|
|
417
|
+
/** Maximum wall-clock time to wait for the user before giving up (ms). Defaults to `expires_in * 1000`. */
|
|
418
|
+
maxWaitMs?: number;
|
|
419
|
+
/** Base delay (ms) before retrying the device-code request after a transient network error. */
|
|
420
|
+
deviceCodeRetryBaseDelayMs?: number;
|
|
421
|
+
/**
|
|
422
|
+
* Diagnostic logger — never receives token bytes or the raw `device_code`,
|
|
423
|
+
* only user-facing codes, HTTP statuses, and poll-loop timing so callers
|
|
424
|
+
* can troubleshoot a stuck / slow device-flow login.
|
|
425
|
+
*/
|
|
426
|
+
logger?: ServiceMeLogger;
|
|
427
|
+
}
|
|
428
|
+
declare class GitHubAuthProvider implements IAuthProvider {
|
|
429
|
+
readonly providerId: AuthProvider;
|
|
430
|
+
private readonly cfg;
|
|
431
|
+
private readonly logger;
|
|
432
|
+
private readonly sleepImpl;
|
|
433
|
+
constructor(config: GitHubAuthProviderConfig);
|
|
434
|
+
requestDeviceFlow(opts?: {
|
|
435
|
+
scope?: string;
|
|
436
|
+
}): Promise<AuthLoginResult>;
|
|
437
|
+
completeDeviceFlow(deviceCode: string, shouldContinue?: () => boolean, initialPollIntervalMs?: number): Promise<IAuthProviderSession>;
|
|
438
|
+
refreshAccessToken(refreshToken: string): Promise<IAuthProviderSession>;
|
|
439
|
+
validateToken(token: string): Promise<boolean>;
|
|
440
|
+
fetchAccountMeta(token: string): Promise<AuthAccountMeta>;
|
|
441
|
+
private fetchGitHubUser;
|
|
442
|
+
/**
|
|
443
|
+
* GitHub's `/user` endpoint returns `null` when the user kept their
|
|
444
|
+
* email private. The `/user/emails` endpoint reveals verified emails;
|
|
445
|
+
* we pick the primary one, falling back to the synthetic
|
|
446
|
+
* `<login>@github.local` form so the account is never email-less.
|
|
447
|
+
*/
|
|
448
|
+
private resolveEmail;
|
|
449
|
+
}
|
|
450
|
+
//#endregion
|
|
451
|
+
//#region src/auth/providers/MicrosoftAuthProvider.d.ts
|
|
452
|
+
/**
|
|
453
|
+
* Error thrown when callers invoke Microsoft auth from a non-Extension
|
|
454
|
+
* runtime (CLI / Bridge). The CLI maps this to `AUTH_PROVIDER_REQUIRES_HOST`
|
|
455
|
+
* so the user is prompted to retry inside VSCode.
|
|
456
|
+
*/
|
|
457
|
+
declare class MicrosoftProviderNotHostedError extends Error {
|
|
458
|
+
constructor(message?: string);
|
|
459
|
+
}
|
|
460
|
+
declare class MicrosoftAuthProvider implements IAuthProvider {
|
|
461
|
+
readonly providerId: AuthProvider;
|
|
462
|
+
requestDeviceFlow(): Promise<AuthLoginResult>;
|
|
463
|
+
completeDeviceFlow(_deviceCode: string, _shouldContinue?: () => boolean): Promise<IAuthProviderSession>;
|
|
464
|
+
refreshAccessToken(_refreshToken: string): Promise<IAuthProviderSession>;
|
|
465
|
+
validateToken(_token: string): Promise<boolean>;
|
|
466
|
+
fetchAccountMeta(_token: string): Promise<AuthAccountMeta>;
|
|
467
|
+
}
|
|
468
|
+
//#endregion
|
|
469
|
+
//#region src/auth/utils/githubUserEmail.d.ts
|
|
470
|
+
/**
|
|
471
|
+
* AuthCore — Pure local utilities for GitHub local email handling.
|
|
472
|
+
*
|
|
473
|
+
* Copied verbatim from `@serviceme/devtools-shared/src/github-user-email.ts` (15 LOC)
|
|
474
|
+
* because ADL-003 forbids Core from depending on `@serviceme/devtools-shared`. These
|
|
475
|
+
* helpers are pure functions with zero side effects, so the duplication is
|
|
476
|
+
* trivial to keep in sync.
|
|
477
|
+
*
|
|
478
|
+
* Refs:
|
|
479
|
+
* - 4.功能规划.md §2.1 — "utils/githubUserEmail.ts 纯函数,直接搬"
|
|
480
|
+
* - ADL-003 — `@serviceme/devtools-shared` boundary decision
|
|
481
|
+
*/
|
|
482
|
+
/**
|
|
483
|
+
* Returns true when the supplied address is a synthetic GitHub "local" email
|
|
484
|
+
* (suffixed with `@github.local`). Real GitHub OAuth clients often return
|
|
485
|
+
* `null` for `email` (user kept it private) and the application substitutes
|
|
486
|
+
* `<login>@github.local` to keep the field non-null.
|
|
487
|
+
*/
|
|
488
|
+
declare function isGitHubLocalEmail(email: string | null | undefined): boolean;
|
|
489
|
+
/** Build a synthetic `<login>@github.local` address. */
|
|
490
|
+
declare function buildGitHubLocalEmail(login: string): string;
|
|
491
|
+
/**
|
|
492
|
+
* Resolve the user's primary email address — falling back to the synthetic
|
|
493
|
+
* `<login>@github.local` form when the upstream email is missing or blank.
|
|
494
|
+
*/
|
|
495
|
+
declare function resolvePrimaryEmail(login: string, email: string | null | undefined): string;
|
|
496
|
+
//#endregion
|
|
497
|
+
export { KeyValueStore as A, AuthStateManagerOptions as C, AccessCheckResult as D, noopLogger as E, AccessControl as O, AuthStateManager as S, createConsoleLogger as T, KeychainAccountKey as _, MicrosoftProviderNotHostedError as a, KeychainTokenMetadata as b, AuthCore as c, DeviceFlowUiCallback as d, ProviderRegistry as f, InMemoryKeychainAuthTokenStore as g, IAuthProviderUserInfo as h, MicrosoftAuthProvider as i, OrgMembershipFetcher as j, AccessControlOptions as k, AuthCoreOptions as l, IAuthProviderSession as m, isGitHubLocalEmail as n, GitHubAuthProvider as o, IAuthProvider as p, resolvePrimaryEmail as r, GitHubAuthProviderConfig as s, buildGitHubLocalEmail as t, CancellationCheck as u, KeychainAuthTokenStore as v, ServiceMeLogger as w, KeychainUnavailableError as x, KeychainTokenEnvelope as y };
|
|
498
|
+
//# sourceMappingURL=index-CoA6y0MP.d.ts.map
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { ExternalTool, ToolboxList, ToolboxScope } from "@serviceme/devtools-protocol";
|
|
2
|
+
//#region src/toolbox/sort.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Sort by "recently used" — entries with newer `lastUsedAt` float to
|
|
5
|
+
* the top, entries with no `lastUsedAt` sort to the bottom (preserving
|
|
6
|
+
* their relative `order` index when both are absent).
|
|
7
|
+
*
|
|
8
|
+
* Ties (same `lastUsedAt` or both missing) are broken by `order`, then
|
|
9
|
+
* by `id` for determinism.
|
|
10
|
+
*/
|
|
11
|
+
declare function sortByRecentFirst(tools: readonly ExternalTool[]): ExternalTool[];
|
|
12
|
+
/**
|
|
13
|
+
* Sort by user-defined `order` field. Entries without `order` are
|
|
14
|
+
* appended in their input order (stable sort via `id` tiebreaker).
|
|
15
|
+
*/
|
|
16
|
+
declare function sortByUserOrder(tools: readonly ExternalTool[]): ExternalTool[];
|
|
17
|
+
/**
|
|
18
|
+
* Merge built-in defaults with user-stored tools. Defaults keep
|
|
19
|
+
* `isDefault: true` and their `order`; user tools are appended with
|
|
20
|
+
* their stored metadata. Output is sorted by user order.
|
|
21
|
+
*/
|
|
22
|
+
declare function mergeWithDefaults(defaults: readonly ExternalTool[], userTools: readonly ExternalTool[]): ExternalTool[];
|
|
23
|
+
/**
|
|
24
|
+
* Re-number `order` for a list of tool ids. Used by
|
|
25
|
+
* `toolbox.update` when the user drags-and-drops entries in the UI.
|
|
26
|
+
*/
|
|
27
|
+
declare function reindexOrder(tools: ExternalTool[], newOrderIds: readonly string[]): ExternalTool[];
|
|
28
|
+
/**
|
|
29
|
+
* Stamp `lastUsedAt` on the targeted tool (clones the array). Returns
|
|
30
|
+
* a new array; the input is left untouched.
|
|
31
|
+
*/
|
|
32
|
+
declare function touchLastUsedAt(tools: readonly ExternalTool[], id: string, when?: Date): ExternalTool[];
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/toolbox/types.d.ts
|
|
35
|
+
/** Schema version of the on-disk toolbox JSON files. Bumped on breaking changes. */
|
|
36
|
+
declare const TOOLBOX_JSON_SCHEMA_VERSION = 1;
|
|
37
|
+
interface PersistedToolbox {
|
|
38
|
+
version: number;
|
|
39
|
+
tools: ExternalTool[];
|
|
40
|
+
}
|
|
41
|
+
/** Patch payload accepted by `ToolboxCore.update` (mirrors `ExternalToolPatch`). */
|
|
42
|
+
type ToolboxPatch = Partial<Omit<ExternalTool, "id" | "isDefault">>;
|
|
43
|
+
/**
|
|
44
|
+
* Built-in (default) tool seeds. Mirrors the Extension's
|
|
45
|
+
* `apps/extension/src/config/external-tools.ts`. The Core stores these
|
|
46
|
+
* verbatim and never mutates them — the Extension's `ToolBoxService`
|
|
47
|
+
* runs the same merge on top of the Core's view.
|
|
48
|
+
*/
|
|
49
|
+
interface DefaultToolSeed {
|
|
50
|
+
id: string;
|
|
51
|
+
name: string;
|
|
52
|
+
description: string;
|
|
53
|
+
icon: string;
|
|
54
|
+
url: string;
|
|
55
|
+
}
|
|
56
|
+
/** Built-in tools rendered when the JSON file is missing or empty. */
|
|
57
|
+
declare const BUILTIN_DEFAULT_TOOLS: readonly DefaultToolSeed[];
|
|
58
|
+
/** Resolved toolbox shape returned by `ToolboxStore.read()`. */
|
|
59
|
+
interface ResolvedToolbox {
|
|
60
|
+
scope: ToolboxScope;
|
|
61
|
+
tools: ExternalTool[];
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/toolbox/ToolboxStore.d.ts
|
|
65
|
+
declare const WORKSPACE_TOOLBOX_RELATIVE_PATH: string;
|
|
66
|
+
interface ToolboxFileBackend {
|
|
67
|
+
read(filePath: string): Promise<PersistedToolbox | null>;
|
|
68
|
+
write(filePath: string, payload: PersistedToolbox): Promise<void>;
|
|
69
|
+
exists(filePath: string): Promise<boolean>;
|
|
70
|
+
/** Maximum number of `.corrupted.*.bak` snapshots to keep per toolbox file (default: 5). */
|
|
71
|
+
maxBackupCount?: number;
|
|
72
|
+
}
|
|
73
|
+
interface ToolboxStoreOptions {
|
|
74
|
+
/** Override the user-scope file path (default: `getToolboxJsonPath()`). */
|
|
75
|
+
userFilePath?: string;
|
|
76
|
+
/** Override the workspace-scope file path resolver (default: cwd-relative). */
|
|
77
|
+
resolveWorkspacePath?: () => string | null;
|
|
78
|
+
/** Injectable built-in tool seeds (default: `BUILTIN_DEFAULT_TOOLS`). */
|
|
79
|
+
defaultTools?: readonly DefaultToolSeed[];
|
|
80
|
+
hooks?: ToolboxStoreHooks;
|
|
81
|
+
backend?: ToolboxFileBackend;
|
|
82
|
+
lockTimeoutMs?: number;
|
|
83
|
+
lockRetryMs?: number;
|
|
84
|
+
}
|
|
85
|
+
interface ToolboxStoreHooks {
|
|
86
|
+
beforeWrite?: (scope: ToolboxScope, payload: PersistedToolbox) => void | Promise<void>;
|
|
87
|
+
afterWrite?: (scope: ToolboxScope, payload: PersistedToolbox) => void | Promise<void>;
|
|
88
|
+
}
|
|
89
|
+
declare class FsToolboxFileBackend implements ToolboxFileBackend {
|
|
90
|
+
maxBackupCount: number;
|
|
91
|
+
exists(filePath: string): Promise<boolean>;
|
|
92
|
+
read(filePath: string): Promise<PersistedToolbox | null>;
|
|
93
|
+
private backupCorruptedFile;
|
|
94
|
+
private purgeExcessBackups;
|
|
95
|
+
write(filePath: string, payload: PersistedToolbox): Promise<void>;
|
|
96
|
+
}
|
|
97
|
+
declare class ToolboxStore {
|
|
98
|
+
private readonly userFilePath;
|
|
99
|
+
private readonly resolveWorkspacePath;
|
|
100
|
+
private readonly defaults;
|
|
101
|
+
private readonly hooks;
|
|
102
|
+
private readonly backend;
|
|
103
|
+
private readonly lockTimeoutMs;
|
|
104
|
+
private readonly lockRetryMs;
|
|
105
|
+
constructor(opts?: ToolboxStoreOptions);
|
|
106
|
+
/** Read a scope; returns the resolved toolbox (with defaults merged when empty). */
|
|
107
|
+
read(scope: ToolboxScope): Promise<ResolvedToolbox>;
|
|
108
|
+
/**
|
|
109
|
+
* Atomic write under a file lock. Replaces the entire `tools` array
|
|
110
|
+
* with the provided snapshot.
|
|
111
|
+
*/
|
|
112
|
+
write(scope: ToolboxScope, tools: readonly ExternalTool[]): Promise<void>;
|
|
113
|
+
/**
|
|
114
|
+
* Read-modify-write under the file lock. The mutator receives the
|
|
115
|
+
* current user-only list (defaults not included) and returns the
|
|
116
|
+
* replacement list. Throwing inside the mutator aborts the write.
|
|
117
|
+
*/
|
|
118
|
+
mutate(scope: ToolboxScope, mutator: (current: ExternalTool[]) => Promise<ExternalTool[]>): Promise<ExternalTool[]>;
|
|
119
|
+
/** Wipe a scope entirely (used by `toolbox.remove --all` extensions). */
|
|
120
|
+
clear(scope: ToolboxScope): Promise<void>;
|
|
121
|
+
/** Test seam — resolve the user-scope file path. */
|
|
122
|
+
getUserFilePath(): string;
|
|
123
|
+
/** Test seam — resolve the workspace-scope file path (or null when disabled). */
|
|
124
|
+
getWorkspaceFilePath(): string | null;
|
|
125
|
+
private filePathFor;
|
|
126
|
+
}
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region src/toolbox/ToolboxCore.d.ts
|
|
129
|
+
/** Sentinel — caller tried to remove a built-in (immutable) tool. */
|
|
130
|
+
declare class DefaultToolImmutableError extends Error {
|
|
131
|
+
readonly toolId: string;
|
|
132
|
+
constructor(toolId: string);
|
|
133
|
+
}
|
|
134
|
+
interface ToolboxCoreOptions {
|
|
135
|
+
store?: ToolboxStore;
|
|
136
|
+
defaultTools?: readonly DefaultToolSeed[];
|
|
137
|
+
/** Sort applied to the merged list returned by `list()`. Default: `sortByUserOrder`. */
|
|
138
|
+
listSort?: (tools: readonly ExternalTool[]) => ExternalTool[];
|
|
139
|
+
}
|
|
140
|
+
declare class ToolboxCore {
|
|
141
|
+
private readonly store;
|
|
142
|
+
private readonly defaults;
|
|
143
|
+
private readonly listSort;
|
|
144
|
+
constructor(opts?: ToolboxCoreOptions);
|
|
145
|
+
/** List all tools in a scope. Built-in defaults are merged in. */
|
|
146
|
+
list(scope?: ToolboxScope): Promise<ToolboxList>;
|
|
147
|
+
/**
|
|
148
|
+
* Append a new tool to the requested scope. Default tools are
|
|
149
|
+
* rejected (they are seeds, not user entries).
|
|
150
|
+
*/
|
|
151
|
+
add(tool: ExternalTool, scope?: ToolboxScope): Promise<ToolboxList>;
|
|
152
|
+
/**
|
|
153
|
+
* Remove a tool by id. Returns `success: false` when the id is a
|
|
154
|
+
* built-in default (idempotent, never throws on missing entries).
|
|
155
|
+
*/
|
|
156
|
+
remove(id: string, scope?: ToolboxScope): Promise<{
|
|
157
|
+
scope: ToolboxScope;
|
|
158
|
+
toolId: string;
|
|
159
|
+
success: boolean;
|
|
160
|
+
}>;
|
|
161
|
+
/**
|
|
162
|
+
* Patch a tool by id. Default tools can only have their `order`
|
|
163
|
+
* updated; other patches are silently ignored for default entries
|
|
164
|
+
* (callers can compare before/after to detect the ignore).
|
|
165
|
+
*/
|
|
166
|
+
update(id: string, patch: ToolboxPatch, scope?: ToolboxScope): Promise<ToolboxList>;
|
|
167
|
+
/**
|
|
168
|
+
* Stamp `lastUsedAt` on the targeted tool. This is the "recently
|
|
169
|
+
* used" hook the Extension's webview uses when a user clicks a
|
|
170
|
+
* toolbox entry.
|
|
171
|
+
*/
|
|
172
|
+
recordUsage(id: string, scope?: ToolboxScope, when?: Date): Promise<ExternalTool | null>;
|
|
173
|
+
/**
|
|
174
|
+
* Combined view: user + workspace scopes merged, sorted by recent
|
|
175
|
+
* usage. Workspace tools overlay user tools (workspace entries win
|
|
176
|
+
* on `id` collision).
|
|
177
|
+
*/
|
|
178
|
+
listMerged(): Promise<ToolboxList>;
|
|
179
|
+
/** Expose the underlying store (CLI / Bridge use it for path-level access). */
|
|
180
|
+
getStore(): ToolboxStore;
|
|
181
|
+
private isDefaultId;
|
|
182
|
+
}
|
|
183
|
+
//#endregion
|
|
184
|
+
export { reindexOrder as _, ToolboxFileBackend as a, touchLastUsedAt as b, ToolboxStoreOptions as c, DefaultToolSeed as d, PersistedToolbox as f, mergeWithDefaults as g, ToolboxPatch as h, FsToolboxFileBackend as i, WORKSPACE_TOOLBOX_RELATIVE_PATH as l, TOOLBOX_JSON_SCHEMA_VERSION as m, ToolboxCore as n, ToolboxStore as o, ResolvedToolbox as p, ToolboxCoreOptions as r, ToolboxStoreHooks as s, DefaultToolImmutableError as t, BUILTIN_DEFAULT_TOOLS as u, sortByRecentFirst as v, sortByUserOrder as y };
|
|
185
|
+
//# sourceMappingURL=index-DaW7IYA-.d.mts.map
|