sidekick-shared 0.24.4 → 0.25.0
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/CHANGELOG.md +59 -0
- package/README.md +200 -52
- package/dist/accountChangeSignal.d.ts +3 -0
- package/dist/accountChangeSignal.js +19 -0
- package/dist/accountChanges.d.ts +21 -0
- package/dist/accountChanges.js +151 -0
- package/dist/accountManager.d.ts +13 -0
- package/dist/accountManager.js +60 -32
- package/dist/accountRegistry.d.ts +3 -1
- package/dist/accountRegistry.js +64 -41
- package/dist/accounts.js +40 -19
- package/dist/autoSwitch.d.ts +2 -1
- package/dist/autoSwitch.js +32 -7
- package/dist/browser.d.ts +10 -3
- package/dist/browser.js +17 -1
- package/dist/codexProfiles.d.ts +14 -0
- package/dist/codexProfiles.js +268 -116
- package/dist/codexQuotaWatcher.d.ts +6 -0
- package/dist/codexQuotaWatcher.js +101 -47
- package/dist/context/sessionContext.js +2 -4
- package/dist/ensureDefaultAccounts.js +4 -4
- package/dist/index.d.ts +32 -15
- package/dist/index.js +54 -9
- package/dist/modelAliases.d.ts +13 -0
- package/dist/modelAliases.js +58 -0
- package/dist/modelCatalog.d.ts +32 -0
- package/dist/modelCatalog.js +145 -0
- package/dist/modelContext.d.ts +36 -3
- package/dist/modelContext.js +109 -34
- package/dist/modelInfo.d.ts +30 -1
- package/dist/modelInfo.js +116 -26
- package/dist/multiProviderQuotaService.d.ts +8 -0
- package/dist/multiProviderQuotaService.js +64 -3
- package/dist/node.d.ts +8 -2
- package/dist/node.js +11 -1
- package/dist/observedContextWindows.d.ts +13 -0
- package/dist/observedContextWindows.js +13 -0
- package/dist/observedSessionCollector.d.ts +75 -4
- package/dist/observedSessionCollector.js +452 -42
- package/dist/parsers/codexHistory.d.ts +32 -0
- package/dist/parsers/codexHistory.js +125 -0
- package/dist/parsers/mcpToolName.d.ts +26 -0
- package/dist/parsers/mcpToolName.js +31 -0
- package/dist/parsers/sessionActivityDetector.d.ts +6 -0
- package/dist/parsers/sessionActivityDetector.js +17 -0
- package/dist/parsers/sessionPathResolver.d.ts +11 -4
- package/dist/parsers/sessionPathResolver.js +11 -4
- package/dist/paths.d.ts +7 -3
- package/dist/paths.js +7 -3
- package/dist/providerIds.d.ts +11 -0
- package/dist/providerIds.js +9 -0
- package/dist/providerQuota.d.ts +3 -1
- package/dist/providerQuota.js +3 -0
- package/dist/providers/claudeCode.d.ts +11 -1
- package/dist/providers/claudeCode.js +222 -39
- package/dist/providers/codex.d.ts +39 -1
- package/dist/providers/codex.js +326 -39
- package/dist/providers/codexDatabase.d.ts +9 -0
- package/dist/providers/codexDatabase.js +107 -2
- package/dist/providers/diagnostics.d.ts +13 -0
- package/dist/providers/diagnostics.js +88 -0
- package/dist/providers/factory.d.ts +14 -0
- package/dist/providers/factory.js +57 -0
- package/dist/providers/openCode.d.ts +20 -1
- package/dist/providers/openCode.js +361 -11
- package/dist/providers/openCodeDatabase.d.ts +10 -0
- package/dist/providers/openCodeDatabase.js +69 -0
- package/dist/providers/types.d.ts +57 -2
- package/dist/providers/types.js +4 -0
- package/dist/quota.d.ts +4 -1
- package/dist/quota.js +3 -7
- package/dist/quotaHistory.d.ts +3 -2
- package/dist/quotaHistory.js +2 -2
- package/dist/quotaPoller.d.ts +13 -1
- package/dist/quotaPoller.js +65 -3
- package/dist/quotaSnapshots.js +8 -77
- package/dist/schemas/accountManager.d.ts +2 -2
- package/dist/schemas/accountManager.js +2 -4
- package/dist/schemas/accountStatus.d.ts +3 -0
- package/dist/schemas/accountStatus.js +1 -0
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/index.js +7 -2
- package/dist/schemas/observedSessionV1.d.ts +27 -26
- package/dist/schemas/observedSessionV1.js +6 -4
- package/dist/schemas/quota.d.ts +2 -2
- package/dist/schemas/quota.js +3 -6
- package/dist/schemas/quotaHistory.d.ts +2 -2
- package/dist/schemas/tokenEstimation.d.ts +1 -1
- package/dist/sessionMonitor.d.ts +15 -0
- package/dist/sessionMonitor.js +142 -0
- package/dist/sessionPreviews.d.ts +85 -0
- package/dist/sessionPreviews.js +549 -0
- package/dist/sessionTranscripts.js +10 -4
- package/dist/types/observedSessionV1.d.ts +6 -2
- package/dist/types/observedSessionV1.js +14 -8
- package/dist/writers/atomic.d.ts +20 -0
- package/dist/writers/atomic.js +190 -19
- package/package.json +22 -1
package/dist/writers/atomic.js
CHANGED
|
@@ -35,11 +35,42 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.atomicWriteJson = atomicWriteJson;
|
|
37
37
|
exports.atomicWriteJsonSync = atomicWriteJsonSync;
|
|
38
|
+
exports.atomicWriteFileSync = atomicWriteFileSync;
|
|
38
39
|
exports.updateJsonStoreAtomic = updateJsonStoreAtomic;
|
|
40
|
+
exports.withFileLockSync = withFileLockSync;
|
|
41
|
+
exports.updateJsonStoreAtomicSync = updateJsonStoreAtomicSync;
|
|
39
42
|
const crypto = __importStar(require("crypto"));
|
|
40
43
|
const fs = __importStar(require("fs"));
|
|
41
44
|
const path = __importStar(require("path"));
|
|
42
45
|
const LOCK_STALE_MS = 10_000;
|
|
46
|
+
/**
|
|
47
|
+
* How long to wait for a lock that is making no progress.
|
|
48
|
+
*
|
|
49
|
+
* This budget detects a wedged holder, not a long queue. It is measured from the
|
|
50
|
+
* last time the lock changed hands rather than from the first attempt, because a
|
|
51
|
+
* writer queued behind other healthy writers is waiting, not failing — see
|
|
52
|
+
* {@link acquireLock}.
|
|
53
|
+
*/
|
|
54
|
+
const LOCK_NO_PROGRESS_MS = 3_000;
|
|
55
|
+
/**
|
|
56
|
+
* A live async holder heartbeats every LOCK_STALE_MS / 3; an mtime frozen this
|
|
57
|
+
* long means the heartbeat timer is gone — the owner is dead (possibly with its
|
|
58
|
+
* PID recycled by the OS) or wedged beyond recovery. Reclaim regardless of the
|
|
59
|
+
* PID probe, which cannot tell a recycled PID from a live owner. Sync holders
|
|
60
|
+
* have no heartbeat; they usually hold locks for milliseconds, and even the
|
|
61
|
+
* slowest (a keychain read through `security` behind the auth-swap lock, up to
|
|
62
|
+
* a few seconds) stays far under this ceiling.
|
|
63
|
+
*/
|
|
64
|
+
const LOCK_ABANDONED_MS = 120_000;
|
|
65
|
+
/**
|
|
66
|
+
* Hard ceiling on how long a synchronous waiter blocks, regardless of queue
|
|
67
|
+
* progress. Progress resets are correct for async waiters, but a sync waiter
|
|
68
|
+
* blocks its process's event loop while queued, so healthy-queue churn must not
|
|
69
|
+
* extend the block indefinitely.
|
|
70
|
+
*/
|
|
71
|
+
const SYNC_LOCK_MAX_WAIT_MS = 15_000;
|
|
72
|
+
const LOCK_WAIT_INTERVAL_MS = 15;
|
|
73
|
+
const lockSleepView = new Int32Array(new SharedArrayBuffer(4));
|
|
43
74
|
async function syncDirectory(directory) {
|
|
44
75
|
let handle;
|
|
45
76
|
try {
|
|
@@ -91,12 +122,16 @@ async function atomicWriteJson(filePath, value) {
|
|
|
91
122
|
}
|
|
92
123
|
}
|
|
93
124
|
function atomicWriteJsonSync(filePath, value) {
|
|
125
|
+
atomicWriteFileSync(filePath, JSON.stringify(value, null, 2));
|
|
126
|
+
}
|
|
127
|
+
/** Raw-string sibling of {@link atomicWriteJsonSync} for non-JSON payloads. */
|
|
128
|
+
function atomicWriteFileSync(filePath, content, mode = 0o600) {
|
|
94
129
|
fs.mkdirSync(path.dirname(filePath), { recursive: true, mode: 0o700 });
|
|
95
130
|
const tempPath = `${filePath}.${process.pid}.${crypto.randomBytes(8).toString('hex')}.tmp`;
|
|
96
131
|
let descriptor;
|
|
97
132
|
try {
|
|
98
|
-
descriptor = fs.openSync(tempPath, 'wx',
|
|
99
|
-
fs.writeFileSync(descriptor,
|
|
133
|
+
descriptor = fs.openSync(tempPath, 'wx', mode);
|
|
134
|
+
fs.writeFileSync(descriptor, content, { encoding: 'utf8' });
|
|
100
135
|
fs.fsyncSync(descriptor);
|
|
101
136
|
fs.closeSync(descriptor);
|
|
102
137
|
descriptor = undefined;
|
|
@@ -142,8 +177,22 @@ async function updateJsonStoreAtomic(filePath, createEmpty, update) {
|
|
|
142
177
|
await releaseLock(lockPath, lock);
|
|
143
178
|
}
|
|
144
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* Waits for exclusive ownership of `lockPath`.
|
|
182
|
+
*
|
|
183
|
+
* The wait budget is reset every time the lock changes hands. A flat budget from
|
|
184
|
+
* the first attempt conflated two unrelated conditions — a wedged holder and a
|
|
185
|
+
* queue of healthy writers — so under real contention the writers at the back of
|
|
186
|
+
* the queue failed even though every lock was being acquired and released
|
|
187
|
+
* correctly. Each cycle costs three fsyncs (lock file, temp file, directory), so
|
|
188
|
+
* on slow storage a burst of concurrent captures drained slower than the budget.
|
|
189
|
+
*
|
|
190
|
+
* A stuck holder keeps the same token, so it makes no progress and still trips
|
|
191
|
+
* the timeout; the stale-reclaim path below still handles an owner that died.
|
|
192
|
+
*/
|
|
145
193
|
async function acquireLock(lockPath) {
|
|
146
|
-
|
|
194
|
+
let deadline = Date.now() + LOCK_NO_PROGRESS_MS;
|
|
195
|
+
let observedOwner = null;
|
|
147
196
|
while (true) {
|
|
148
197
|
try {
|
|
149
198
|
const handle = await fs.promises.open(lockPath, 'wx', 0o600);
|
|
@@ -159,29 +208,27 @@ async function acquireLock(lockPath) {
|
|
|
159
208
|
catch (error) {
|
|
160
209
|
if (error.code !== 'EEXIST')
|
|
161
210
|
throw error;
|
|
211
|
+
// The token identifies the current holder. mtime cannot stand in for it:
|
|
212
|
+
// the heartbeat keeps touching the file, so even a wedged holder looks
|
|
213
|
+
// fresh. A different token means the queue advanced.
|
|
214
|
+
const currentOwner = await fs.promises.readFile(lockPath, 'utf8').catch(() => null);
|
|
215
|
+
if (currentOwner !== null && currentOwner !== observedOwner) {
|
|
216
|
+
observedOwner = currentOwner;
|
|
217
|
+
deadline = Date.now() + LOCK_NO_PROGRESS_MS;
|
|
218
|
+
}
|
|
162
219
|
try {
|
|
163
220
|
const stat = await fs.promises.stat(lockPath);
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
let ownerAlive = Number.isInteger(ownerPid) && ownerPid > 0;
|
|
168
|
-
if (ownerAlive) {
|
|
169
|
-
try {
|
|
170
|
-
process.kill(ownerPid, 0);
|
|
171
|
-
}
|
|
172
|
-
catch (ownerError) {
|
|
173
|
-
ownerAlive = ownerError.code === 'EPERM';
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
if (!ownerAlive)
|
|
177
|
-
await fs.promises.rm(lockPath, { force: true });
|
|
221
|
+
const frozenMs = Date.now() - stat.mtimeMs;
|
|
222
|
+
if (frozenMs > LOCK_STALE_MS && !lockOwnerAlive(currentOwner, frozenMs)) {
|
|
223
|
+
await fs.promises.rm(lockPath, { force: true });
|
|
178
224
|
}
|
|
179
225
|
}
|
|
180
226
|
catch {
|
|
181
227
|
// The other writer released between checks.
|
|
182
228
|
}
|
|
183
|
-
if (Date.now() >= deadline)
|
|
184
|
-
throw new Error(`Timed out waiting for store lock: ${lockPath}`);
|
|
229
|
+
if (Date.now() >= deadline) {
|
|
230
|
+
throw new Error(`Timed out waiting for store lock: ${lockPath} (no progress for ${LOCK_NO_PROGRESS_MS}ms)`);
|
|
231
|
+
}
|
|
185
232
|
await new Promise((resolve) => setTimeout(resolve, 15));
|
|
186
233
|
}
|
|
187
234
|
}
|
|
@@ -198,3 +245,127 @@ async function releaseLock(lockPath, lock) {
|
|
|
198
245
|
// The lock was already released or replaced; never delete another owner's lock.
|
|
199
246
|
}
|
|
200
247
|
}
|
|
248
|
+
/**
|
|
249
|
+
* Whether the recorded owner of a stale lock should still be treated as alive.
|
|
250
|
+
* An mtime frozen past {@link LOCK_ABANDONED_MS} overrides the PID probe — see
|
|
251
|
+
* the constant for why the probe alone cannot be trusted at that age.
|
|
252
|
+
*/
|
|
253
|
+
function lockOwnerAlive(owner, frozenMs) {
|
|
254
|
+
if (frozenMs > LOCK_ABANDONED_MS)
|
|
255
|
+
return false;
|
|
256
|
+
const ownerPid = Number.parseInt((owner ?? '').split(':', 1)[0], 10);
|
|
257
|
+
if (!Number.isInteger(ownerPid) || ownerPid <= 0)
|
|
258
|
+
return false;
|
|
259
|
+
try {
|
|
260
|
+
process.kill(ownerPid, 0);
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
return error.code === 'EPERM';
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Synchronous counterpart of {@link acquireLock}, sharing its lock-file
|
|
269
|
+
* protocol so sync and async waiters exclude each other across processes.
|
|
270
|
+
*
|
|
271
|
+
* Two timeout rules apply instead of one: the same progress-based budget as the
|
|
272
|
+
* async path (a token that never changes trips it in LOCK_NO_PROGRESS_MS), plus
|
|
273
|
+
* an absolute {@link SYNC_LOCK_MAX_WAIT_MS} ceiling, because a sync waiter
|
|
274
|
+
* blocks its event loop while queued. Sync holders take no heartbeat — their
|
|
275
|
+
* critical sections must stay well under LOCK_STALE_MS (in-repo users are
|
|
276
|
+
* local-filesystem read-modify-writes, plus keychain reads behind the
|
|
277
|
+
* auth-swap locks that can take a few seconds).
|
|
278
|
+
*
|
|
279
|
+
* The caller must ensure `dirname(lockPath)` exists — a missing parent
|
|
280
|
+
* surfaces as a raw ENOENT, not a timeout.
|
|
281
|
+
*/
|
|
282
|
+
function withFileLockSync(lockPath, operation) {
|
|
283
|
+
const token = acquireLockSync(lockPath);
|
|
284
|
+
try {
|
|
285
|
+
return operation();
|
|
286
|
+
}
|
|
287
|
+
finally {
|
|
288
|
+
try {
|
|
289
|
+
if (fs.readFileSync(lockPath, 'utf8') === token)
|
|
290
|
+
fs.rmSync(lockPath, { force: true });
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
// The lock was already released or replaced; never delete another owner's lock.
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
function acquireLockSync(lockPath) {
|
|
298
|
+
const start = Date.now();
|
|
299
|
+
let deadline = start + LOCK_NO_PROGRESS_MS;
|
|
300
|
+
let observedOwner = null;
|
|
301
|
+
while (true) {
|
|
302
|
+
try {
|
|
303
|
+
const descriptor = fs.openSync(lockPath, 'wx', 0o600);
|
|
304
|
+
const token = `${process.pid}:${crypto.randomBytes(16).toString('hex')}`;
|
|
305
|
+
fs.writeFileSync(descriptor, token, 'utf8');
|
|
306
|
+
fs.fsyncSync(descriptor);
|
|
307
|
+
fs.closeSync(descriptor);
|
|
308
|
+
return token;
|
|
309
|
+
}
|
|
310
|
+
catch (error) {
|
|
311
|
+
if (error.code !== 'EEXIST')
|
|
312
|
+
throw error;
|
|
313
|
+
let currentOwner = null;
|
|
314
|
+
try {
|
|
315
|
+
currentOwner = fs.readFileSync(lockPath, 'utf8');
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
// The other writer released between checks.
|
|
319
|
+
}
|
|
320
|
+
if (currentOwner !== null && currentOwner !== observedOwner) {
|
|
321
|
+
observedOwner = currentOwner;
|
|
322
|
+
deadline = Date.now() + LOCK_NO_PROGRESS_MS;
|
|
323
|
+
}
|
|
324
|
+
try {
|
|
325
|
+
const stat = fs.statSync(lockPath);
|
|
326
|
+
const frozenMs = Date.now() - stat.mtimeMs;
|
|
327
|
+
if (frozenMs > LOCK_STALE_MS && !lockOwnerAlive(currentOwner, frozenMs)) {
|
|
328
|
+
fs.rmSync(lockPath, { force: true });
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
catch {
|
|
332
|
+
// The other writer released between checks.
|
|
333
|
+
}
|
|
334
|
+
const now = Date.now();
|
|
335
|
+
if (now >= deadline) {
|
|
336
|
+
throw new Error(`Timed out waiting for store lock: ${lockPath} (no progress for ${LOCK_NO_PROGRESS_MS}ms)`);
|
|
337
|
+
}
|
|
338
|
+
if (now - start >= SYNC_LOCK_MAX_WAIT_MS) {
|
|
339
|
+
throw new Error(`Timed out waiting for store lock: ${lockPath} (blocked synchronously for ${SYNC_LOCK_MAX_WAIT_MS}ms)`);
|
|
340
|
+
}
|
|
341
|
+
Atomics.wait(lockSleepView, 0, 0, LOCK_WAIT_INTERVAL_MS);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
/** Synchronous mirror of {@link updateJsonStoreAtomic}. */
|
|
346
|
+
function updateJsonStoreAtomicSync(filePath, createEmpty, update) {
|
|
347
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true, mode: 0o700 });
|
|
348
|
+
return withFileLockSync(`${filePath}.lock`, () => {
|
|
349
|
+
let latest = createEmpty();
|
|
350
|
+
let raw;
|
|
351
|
+
try {
|
|
352
|
+
raw = fs.readFileSync(filePath, 'utf8');
|
|
353
|
+
}
|
|
354
|
+
catch (error) {
|
|
355
|
+
if (error.code !== 'ENOENT')
|
|
356
|
+
throw error;
|
|
357
|
+
}
|
|
358
|
+
if (raw !== undefined) {
|
|
359
|
+
try {
|
|
360
|
+
latest = JSON.parse(raw);
|
|
361
|
+
}
|
|
362
|
+
catch {
|
|
363
|
+
const corruptPath = `${filePath}.corrupt-${Date.now()}-${crypto.randomBytes(4).toString('hex')}`;
|
|
364
|
+
fs.renameSync(filePath, corruptPath);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
const next = update(latest);
|
|
368
|
+
atomicWriteJsonSync(filePath, next);
|
|
369
|
+
return next;
|
|
370
|
+
});
|
|
371
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sidekick-shared",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0",
|
|
4
4
|
"description": "Shared data access layer for Sidekick — readers, types, providers, credentials, quota",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
@@ -35,42 +35,62 @@
|
|
|
35
35
|
"exports": {
|
|
36
36
|
".": {
|
|
37
37
|
"types": "./dist/index.d.ts",
|
|
38
|
+
"import": "./dist/index.js",
|
|
39
|
+
"require": "./dist/index.js",
|
|
38
40
|
"default": "./dist/index.js"
|
|
39
41
|
},
|
|
40
42
|
"./browser": {
|
|
41
43
|
"types": "./dist/browser.d.ts",
|
|
44
|
+
"import": "./dist/browser.js",
|
|
45
|
+
"require": "./dist/browser.js",
|
|
42
46
|
"default": "./dist/browser.js"
|
|
43
47
|
},
|
|
44
48
|
"./node": {
|
|
45
49
|
"types": "./dist/node.d.ts",
|
|
50
|
+
"import": "./dist/node.js",
|
|
51
|
+
"require": "./dist/node.js",
|
|
46
52
|
"default": "./dist/node.js"
|
|
47
53
|
},
|
|
48
54
|
"./schemas": {
|
|
49
55
|
"types": "./dist/schemas/index.d.ts",
|
|
56
|
+
"import": "./dist/schemas/index.js",
|
|
57
|
+
"require": "./dist/schemas/index.js",
|
|
50
58
|
"default": "./dist/schemas/index.js"
|
|
51
59
|
},
|
|
52
60
|
"./phrases": {
|
|
53
61
|
"types": "./dist/phrases.d.ts",
|
|
62
|
+
"import": "./dist/phrases.js",
|
|
63
|
+
"require": "./dist/phrases.js",
|
|
54
64
|
"default": "./dist/phrases.js"
|
|
55
65
|
},
|
|
56
66
|
"./modelContext": {
|
|
57
67
|
"types": "./dist/modelContext.d.ts",
|
|
68
|
+
"import": "./dist/modelContext.js",
|
|
69
|
+
"require": "./dist/modelContext.js",
|
|
58
70
|
"default": "./dist/modelContext.js"
|
|
59
71
|
},
|
|
60
72
|
"./modelInfo": {
|
|
61
73
|
"types": "./dist/modelInfo.d.ts",
|
|
74
|
+
"import": "./dist/modelInfo.js",
|
|
75
|
+
"require": "./dist/modelInfo.js",
|
|
62
76
|
"default": "./dist/modelInfo.js"
|
|
63
77
|
},
|
|
64
78
|
"./formatting": {
|
|
65
79
|
"types": "./dist/formatting.d.ts",
|
|
80
|
+
"import": "./dist/formatting.js",
|
|
81
|
+
"require": "./dist/formatting.js",
|
|
66
82
|
"default": "./dist/formatting.js"
|
|
67
83
|
},
|
|
68
84
|
"./statusline": {
|
|
69
85
|
"types": "./dist/statusline/index.d.ts",
|
|
86
|
+
"import": "./dist/statusline/index.js",
|
|
87
|
+
"require": "./dist/statusline/index.js",
|
|
70
88
|
"default": "./dist/statusline/index.js"
|
|
71
89
|
},
|
|
72
90
|
"./dist/*": {
|
|
73
91
|
"types": "./dist/*.d.ts",
|
|
92
|
+
"import": "./dist/*.js",
|
|
93
|
+
"require": "./dist/*.js",
|
|
74
94
|
"default": "./dist/*.js"
|
|
75
95
|
},
|
|
76
96
|
"./package.json": "./package.json"
|
|
@@ -131,6 +151,7 @@
|
|
|
131
151
|
"prettier": "3.8.4",
|
|
132
152
|
"typescript": "^5.7.0",
|
|
133
153
|
"typescript-eslint": "^8.0.0",
|
|
154
|
+
"vite": "^8.1.0",
|
|
134
155
|
"vitest": "^4.1.9"
|
|
135
156
|
},
|
|
136
157
|
"license": "MIT",
|