dsh-context 0.49.4 → 0.51.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/README.md +5 -4
- package/lib/client.js +902 -360
- package/lib/index.d.ts +45 -23
- package/lib/index.js +88 -55
- package/package.json +9 -4
package/lib/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import "@deepseek-ai/dsh-session";
|
|
3
3
|
import { Context } from "@deepseek-ai/cordis";
|
|
4
4
|
//#region src/host/config.d.ts
|
|
5
|
-
interface Config {
|
|
5
|
+
export interface Config {
|
|
6
6
|
/** Cap on kept per-step request records (the hard step backstop). */
|
|
7
7
|
maxRequestSteps?: number;
|
|
8
8
|
/** Newest whole-turn window kept; trimming crosses whole turns, never mid-turn. */
|
|
@@ -23,7 +23,7 @@ interface Config {
|
|
|
23
23
|
* The cordis `Config` validator: strict on keys, defaults on the schema fields; tolerates `undefined` (a patch row without a `config:`
|
|
24
24
|
* block — defaults win).
|
|
25
25
|
*/
|
|
26
|
-
declare const Config: z.ZodPreprocess<z.ZodObject<{
|
|
26
|
+
export declare const Config: z.ZodPreprocess<z.ZodObject<{
|
|
27
27
|
maxRequestSteps: z.ZodDefault<z.ZodNumber>;
|
|
28
28
|
maxKeptTurns: z.ZodDefault<z.ZodNumber>;
|
|
29
29
|
maxEvents: z.ZodDefault<z.ZodNumber>;
|
|
@@ -128,13 +128,21 @@ interface TimelineState {
|
|
|
128
128
|
*/
|
|
129
129
|
archived: SurfaceNode[];
|
|
130
130
|
/**
|
|
131
|
-
* Session-cost raw material: cumulative billed-token totals per
|
|
132
|
-
* model
|
|
133
|
-
* totals — never trimmed, so
|
|
134
|
-
*
|
|
135
|
-
*
|
|
131
|
+
* Session-cost raw material: cumulative billed-token totals per
|
|
132
|
+
* (provider, model), split into pricing periods for DeepSeek (see
|
|
133
|
+
* SessionCostUsage / CostModelUsage). Running totals — never trimmed, so
|
|
134
|
+
* the estimate always covers the COMPLETE session log even after the
|
|
135
|
+
* request/event retention bounds cut in. Absent until a usage-reporting
|
|
136
|
+
* request with a known model folds.
|
|
136
137
|
*/
|
|
137
138
|
cost?: SessionCostUsage;
|
|
139
|
+
/**
|
|
140
|
+
* Whole-session human-input tally (see Snapshot.humanInputs): every
|
|
141
|
+
* non-injection `user/message` plus every answered `ask_user_question`
|
|
142
|
+
* result. Running total — never trimmed, like `cost`/`timing`. Absent until
|
|
143
|
+
* the first human input folds.
|
|
144
|
+
*/
|
|
145
|
+
humanInputs?: number;
|
|
138
146
|
archiveFloor?: number;
|
|
139
147
|
/**
|
|
140
148
|
* The detail collections' revision marker (see ContextTimelineDetail):
|
|
@@ -339,6 +347,14 @@ interface Snapshot {
|
|
|
339
347
|
* hosts; clients treat absence as zero.
|
|
340
348
|
*/
|
|
341
349
|
toolCalls?: number;
|
|
350
|
+
/**
|
|
351
|
+
* Whole-session human-input tally: every non-injection `user/message`
|
|
352
|
+
* (the user's own messages) plus every answered `ask_user_question`
|
|
353
|
+
* result (one per answer submission). A running total over the COMPLETE
|
|
354
|
+
* log — turns the retained window no longer holds still count. Absent
|
|
355
|
+
* from older hosts; clients treat absence as zero.
|
|
356
|
+
*/
|
|
357
|
+
humanInputs?: number;
|
|
342
358
|
/**
|
|
343
359
|
* Split-generation head fields — present exactly when the host serves the
|
|
344
360
|
* SLIM head (the heavy collections moved to the on-demand detail channel,
|
|
@@ -359,9 +375,9 @@ interface Snapshot {
|
|
|
359
375
|
requests: RequestRecord[];
|
|
360
376
|
events: ContextEventRecord[];
|
|
361
377
|
/**
|
|
362
|
-
* Cumulative session-cost raw material (per-
|
|
363
|
-
* token totals — see SessionCostUsage). Absent until a
|
|
364
|
-
*
|
|
378
|
+
* Cumulative session-cost raw material (per-provider, per-model billed
|
|
379
|
+
* token totals — see SessionCostUsage). Absent until a request with a
|
|
380
|
+
* known model reports usage.
|
|
365
381
|
*/
|
|
366
382
|
cost?: SessionCostUsage;
|
|
367
383
|
/**
|
|
@@ -558,22 +574,28 @@ interface TimingTotals {
|
|
|
558
574
|
/** Per-tool-name tallies behind the timing card's ranking (bounded). */
|
|
559
575
|
tools: Record<string, ToolTimingTotals>;
|
|
560
576
|
}
|
|
561
|
-
/**
|
|
562
|
-
|
|
577
|
+
/**
|
|
578
|
+
* One billed model's cumulative totals split by pricing period. Providers
|
|
579
|
+
* without period-based pricing book everything under `peak` (the list-price
|
|
580
|
+
* period); DeepSeek splits at fold time — peak windows bill at list price,
|
|
581
|
+
* off-peak (all other hours) at half.
|
|
582
|
+
*/
|
|
583
|
+
interface CostModelUsage {
|
|
563
584
|
peak?: CostBucketTotals;
|
|
564
585
|
off?: CostBucketTotals;
|
|
565
586
|
}
|
|
566
587
|
/**
|
|
567
588
|
* The session-cost estimate's raw material: cumulative provider-reported
|
|
568
|
-
* token totals
|
|
569
|
-
*
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
* usage.
|
|
589
|
+
* billed-token totals, keyed by the request envelope's DSH provider id (''
|
|
590
|
+
* when a log carries none) and then by its model id — the exact (provider,
|
|
591
|
+
* model) faces the Client's model-price book resolves (the models.dev
|
|
592
|
+
* registry, client/modelPrices.ts). Running totals per key; absent until a
|
|
593
|
+
* request with a known model reports usage.
|
|
573
594
|
*/
|
|
574
595
|
interface SessionCostUsage {
|
|
575
|
-
|
|
576
|
-
|
|
596
|
+
[provider: string]: {
|
|
597
|
+
[model: string]: CostModelUsage;
|
|
598
|
+
};
|
|
577
599
|
}
|
|
578
600
|
/** One model-visible message on the surface, with its heuristic token price. */
|
|
579
601
|
interface SurfaceNode {
|
|
@@ -688,8 +710,8 @@ interface ContextHeaders {
|
|
|
688
710
|
}
|
|
689
711
|
//#endregion
|
|
690
712
|
//#region src/host/index.d.ts
|
|
691
|
-
declare const name = "dsh-context";
|
|
692
|
-
declare const inject: string[];
|
|
693
|
-
declare function apply(ctx: Context, config: Config): void;
|
|
713
|
+
export declare const name = "dsh-context";
|
|
714
|
+
export declare const inject: string[];
|
|
715
|
+
export declare function apply(ctx: Context, config: Config): void;
|
|
694
716
|
//#endregion
|
|
695
|
-
export {
|
|
717
|
+
export type { Category, ContextEventRecord, ContextHeaders, ContextTimeline, ContextTimelineDetail, HeaderRecord, HeaderTool, HeadersState, RequestRecord, Snapshot, SurfaceNode, TimelineCounts, TimelineLast, TimelineState };
|
package/lib/index.js
CHANGED
|
@@ -293,6 +293,29 @@ function resolveBounds(config) {
|
|
|
293
293
|
return Config.parse(config ?? {});
|
|
294
294
|
}
|
|
295
295
|
//#endregion
|
|
296
|
+
//#region src/shared/providers.ts
|
|
297
|
+
/**
|
|
298
|
+
* The provider-id seam between dsh request envelopes and the models.dev
|
|
299
|
+
* registry: client/cost.ts resolves price-book branches through it, and
|
|
300
|
+
* host/fold.ts uses the DeepSeek resolution to split the session-cost totals
|
|
301
|
+
* into peak/off-peak periods. Only the renames live here — an id absent
|
|
302
|
+
* from the table passes through verbatim.
|
|
303
|
+
*/
|
|
304
|
+
const MODELS_DEV_PROVIDER_IDS = {
|
|
305
|
+
"deepseek-official": "deepseek",
|
|
306
|
+
"kimi-coding": "moonshotai",
|
|
307
|
+
"minimax-cn": "minimax",
|
|
308
|
+
"zai-coding-cn": "zhipuai"
|
|
309
|
+
};
|
|
310
|
+
/** The models.dev provider id that prices a dsh provider (identity for unmapped ids). */
|
|
311
|
+
function modelsDevProviderOf(dshProviderId) {
|
|
312
|
+
return MODELS_DEV_PROVIDER_IDS[dshProviderId] ?? dshProviderId;
|
|
313
|
+
}
|
|
314
|
+
/** Whether a dsh provider prices through DeepSeek's period-based list (peak / half-price off-peak). */
|
|
315
|
+
function isDeepSeekProvider(dshProviderId) {
|
|
316
|
+
return modelsDevProviderOf(dshProviderId) === "deepseek";
|
|
317
|
+
}
|
|
318
|
+
//#endregion
|
|
296
319
|
//#region src/shared/estimate.ts
|
|
297
320
|
/**
|
|
298
321
|
* Token heuristics shared by the host fold and the client boundary — the
|
|
@@ -1274,31 +1297,16 @@ function tokenCountOf(value) {
|
|
|
1274
1297
|
return null;
|
|
1275
1298
|
}
|
|
1276
1299
|
/**
|
|
1277
|
-
*
|
|
1278
|
-
*
|
|
1279
|
-
*
|
|
1280
|
-
* here). The name must carry a DeepSeek marker (`v4` or `deepseek`) so a
|
|
1281
|
-
* foreign flash/pro-named model (gemini-2.0-flash) is never priced.
|
|
1282
|
-
*/
|
|
1283
|
-
function costFamilyOf(model) {
|
|
1284
|
-
if (model === void 0) return null;
|
|
1285
|
-
const m = model.toLowerCase();
|
|
1286
|
-
if (!m.includes("v4") && !m.includes("deepseek")) return null;
|
|
1287
|
-
if (m.includes("flash")) return "flash";
|
|
1288
|
-
if (m.includes("pro")) return "pro";
|
|
1289
|
-
return null;
|
|
1290
|
-
}
|
|
1291
|
-
/**
|
|
1292
|
-
* DeepSeek's peak windows (Beijing Time, UTC+8): 09:00-12:00 and 14:00-18:00
|
|
1293
|
-
* on weekdays; off-peak (half the peak rate) covers all other hours plus all
|
|
1294
|
-
* of Saturday and Sunday.
|
|
1300
|
+
* DeepSeek's peak windows (the official list: UTC 01:00–04:00 and 06:00–10:00,
|
|
1301
|
+
* Monday through Friday — Beijing Time 09:00–12:00 and 14:00–18:00). All other
|
|
1302
|
+
* hours, plus entire weekends, bill at the half-price off-peak rate.
|
|
1295
1303
|
*/
|
|
1296
1304
|
function isPeakUtc(time) {
|
|
1297
|
-
const
|
|
1298
|
-
const day =
|
|
1305
|
+
const at = new Date(time);
|
|
1306
|
+
const day = at.getUTCDay();
|
|
1299
1307
|
if (day === 0 || day === 6) return false;
|
|
1300
|
-
const h =
|
|
1301
|
-
return h >=
|
|
1308
|
+
const h = at.getUTCHours();
|
|
1309
|
+
return h >= 1 && h < 4 || h >= 6 && h < 10;
|
|
1302
1310
|
}
|
|
1303
1311
|
/**
|
|
1304
1312
|
* Fold one billed request into the session-cost totals, cloning along the
|
|
@@ -1306,29 +1314,42 @@ function isPeakUtc(time) {
|
|
|
1306
1314
|
* previous state — the apply contract never mutates it in place). The
|
|
1307
1315
|
* buckets arrive sanitized ({@link BilledUsage}), so the totals stay at the
|
|
1308
1316
|
* schemas' non-negative safe integers no matter what the provider reported.
|
|
1317
|
+
* The key is the request envelope's (provider, model) face — the exact
|
|
1318
|
+
* lookup the Client's model-price book resolves (models.dev). A request
|
|
1319
|
+
* without a provider still accumulates (under the '' key) and the Client
|
|
1320
|
+
* prices it when the model id is unambiguous; without a model there is
|
|
1321
|
+
* nothing to price. DeepSeek's period-based list splits the buckets
|
|
1322
|
+
* (peak windows at list price, all other hours half price); every other
|
|
1323
|
+
* provider books everything under the list-price period.
|
|
1309
1324
|
*/
|
|
1310
1325
|
function accumulateCost(st, time, usage) {
|
|
1311
|
-
const
|
|
1312
|
-
if (
|
|
1313
|
-
const
|
|
1314
|
-
const
|
|
1315
|
-
const
|
|
1316
|
-
const
|
|
1326
|
+
const model = st.model;
|
|
1327
|
+
if (model === void 0) return;
|
|
1328
|
+
const provider = st.provider ?? "";
|
|
1329
|
+
const period = isDeepSeekProvider(provider) && !isPeakUtc(time) ? "off" : "peak";
|
|
1330
|
+
const models = st.cost?.[provider] ?? {};
|
|
1331
|
+
const periods = models[model] ?? {};
|
|
1332
|
+
const b = periods[period] ?? {
|
|
1317
1333
|
uncached: 0,
|
|
1318
1334
|
cacheRead: 0,
|
|
1319
1335
|
cacheWrite: 0,
|
|
1320
1336
|
output: 0
|
|
1321
1337
|
};
|
|
1322
|
-
const
|
|
1323
|
-
|
|
1338
|
+
const nextPeriods = { ...periods };
|
|
1339
|
+
nextPeriods[period] = {
|
|
1324
1340
|
uncached: b.uncached + usage.input,
|
|
1325
1341
|
cacheRead: b.cacheRead + usage.cacheRead,
|
|
1326
1342
|
cacheWrite: b.cacheWrite + usage.cacheWrite,
|
|
1327
1343
|
output: b.output + usage.output
|
|
1328
1344
|
};
|
|
1329
|
-
const
|
|
1330
|
-
|
|
1331
|
-
|
|
1345
|
+
const nextModels = {
|
|
1346
|
+
...models,
|
|
1347
|
+
[model]: nextPeriods
|
|
1348
|
+
};
|
|
1349
|
+
st.cost = {
|
|
1350
|
+
...st.cost ?? {},
|
|
1351
|
+
[provider]: nextModels
|
|
1352
|
+
};
|
|
1332
1353
|
}
|
|
1333
1354
|
/**
|
|
1334
1355
|
* Advance the fold over ONE committed session event under the projection
|
|
@@ -1340,6 +1361,13 @@ function accumulateCost(st, time, usage) {
|
|
|
1340
1361
|
*/
|
|
1341
1362
|
/** The timing card's per-tool ranking cap: the busiest 16 names are kept. */
|
|
1342
1363
|
const TOOL_TIMING_CAP = 16;
|
|
1364
|
+
/**
|
|
1365
|
+
* The interactive Q&A tool (`dsh-tool-ask-user`): its settled result IS the
|
|
1366
|
+
* user's answer, so it folds into the human-input tally alongside the user's
|
|
1367
|
+
* own messages. One result = one answer submission, however many questions
|
|
1368
|
+
* the prompt carried.
|
|
1369
|
+
*/
|
|
1370
|
+
const ASK_USER_TOOL = "ask_user_question";
|
|
1343
1371
|
/** The decode buckets of the generation split, in card order (see TimingTotals). */
|
|
1344
1372
|
const DECODE_KINDS = [
|
|
1345
1373
|
"reasoning",
|
|
@@ -1600,7 +1628,7 @@ function applyTimeline(state, event, bounds) {
|
|
|
1600
1628
|
if (source.form === "notice" && typeof source.summary === "string" && source.summary !== "") rec.detail = source.summary;
|
|
1601
1629
|
}
|
|
1602
1630
|
s.events.push(rec);
|
|
1603
|
-
}
|
|
1631
|
+
} else s.humanInputs = (s.humanInputs ?? 0) + 1;
|
|
1604
1632
|
break;
|
|
1605
1633
|
}
|
|
1606
1634
|
case "tool/result": {
|
|
@@ -1613,6 +1641,7 @@ function applyTimeline(state, event, bounds) {
|
|
|
1613
1641
|
const s = ensure();
|
|
1614
1642
|
bumpDetailRev(s);
|
|
1615
1643
|
const node = applySurface(s, event, event.type, data, toolMsg);
|
|
1644
|
+
if (node.tool === ASK_USER_TOOL) s.humanInputs = (s.humanInputs ?? 0) + 1;
|
|
1616
1645
|
if (pendingEntry !== void 0) pushFileOps(s, opsOfCall({
|
|
1617
1646
|
seq: event.seq,
|
|
1618
1647
|
time: event.time,
|
|
@@ -1775,6 +1804,7 @@ function headFieldsOf(state) {
|
|
|
1775
1804
|
},
|
|
1776
1805
|
images: state.surface.reduce((n, node) => n + (node.imgs ?? 0), 0),
|
|
1777
1806
|
toolCalls: state.surface.reduce((n, node) => node.cat === "tool" ? n + 1 : n, 0),
|
|
1807
|
+
humanInputs: state.humanInputs ?? 0,
|
|
1778
1808
|
requests: [],
|
|
1779
1809
|
events: [],
|
|
1780
1810
|
nodes: [],
|
|
@@ -1782,18 +1812,18 @@ function headFieldsOf(state) {
|
|
|
1782
1812
|
archive: []
|
|
1783
1813
|
};
|
|
1784
1814
|
if (state.cost !== void 0) {
|
|
1785
|
-
const copyFam = (f) => {
|
|
1786
|
-
if (f === void 0) return void 0;
|
|
1787
|
-
const out = {};
|
|
1788
|
-
if (f.peak !== void 0) out.peak = { ...f.peak };
|
|
1789
|
-
if (f.off !== void 0) out.off = { ...f.off };
|
|
1790
|
-
return out;
|
|
1791
|
-
};
|
|
1792
1815
|
const cost = {};
|
|
1793
|
-
const
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1816
|
+
for (const provider in state.cost) {
|
|
1817
|
+
const models = {};
|
|
1818
|
+
for (const model in state.cost[provider]) {
|
|
1819
|
+
const periods = state.cost[provider][model];
|
|
1820
|
+
const copy = {};
|
|
1821
|
+
if (periods.peak !== void 0) copy.peak = { ...periods.peak };
|
|
1822
|
+
if (periods.off !== void 0) copy.off = { ...periods.off };
|
|
1823
|
+
models[model] = copy;
|
|
1824
|
+
}
|
|
1825
|
+
cost[provider] = models;
|
|
1826
|
+
}
|
|
1797
1827
|
result.cost = cost;
|
|
1798
1828
|
}
|
|
1799
1829
|
if (state.timing !== void 0) {
|
|
@@ -2331,10 +2361,12 @@ const costBucketsSchema = z.object({
|
|
|
2331
2361
|
cacheWrite: z.number().int().nonnegative(),
|
|
2332
2362
|
output: z.number().int().nonnegative()
|
|
2333
2363
|
}).strict();
|
|
2334
|
-
const
|
|
2364
|
+
const costModelSchema = z.object({
|
|
2335
2365
|
peak: costBucketsSchema.optional(),
|
|
2336
2366
|
off: costBucketsSchema.optional()
|
|
2337
2367
|
}).strict();
|
|
2368
|
+
const costModelsSchema = z.record(z.string(), costModelSchema);
|
|
2369
|
+
const costUsageSchema = z.record(z.string(), costModelsSchema);
|
|
2338
2370
|
const toolTimingSchema = z.object({
|
|
2339
2371
|
calls: z.number().int().nonnegative(),
|
|
2340
2372
|
ms: z.number().nonnegative()
|
|
@@ -2387,15 +2419,13 @@ const contextTimelineSchema = z.object({
|
|
|
2387
2419
|
current: currentSchema,
|
|
2388
2420
|
images: z.number().int().nonnegative().optional(),
|
|
2389
2421
|
toolCalls: z.number().int().nonnegative().optional(),
|
|
2422
|
+
humanInputs: z.number().int().nonnegative().optional(),
|
|
2390
2423
|
counts: countsSchema.optional(),
|
|
2391
2424
|
last: lastSchema.optional(),
|
|
2392
2425
|
detailRev: z.number().int().nonnegative().optional(),
|
|
2393
2426
|
requests: z.array(requestRecordSchema).optional(),
|
|
2394
2427
|
events: z.array(contextEventSchema).optional(),
|
|
2395
|
-
cost:
|
|
2396
|
-
flash: costFamilySchema.optional(),
|
|
2397
|
-
pro: costFamilySchema.optional()
|
|
2398
|
-
}).strict().optional(),
|
|
2428
|
+
cost: costUsageSchema.optional(),
|
|
2399
2429
|
timing: timingTotalsSchema.optional(),
|
|
2400
2430
|
systems: z.array(systemPromptNodeSchema).optional(),
|
|
2401
2431
|
nodes: z.array(surfaceNodeSchema).optional(),
|
|
@@ -2431,12 +2461,10 @@ const timelineStateSchema = z.object({
|
|
|
2431
2461
|
requests: z.array(requestRecordSchema),
|
|
2432
2462
|
events: z.array(contextEventSchema),
|
|
2433
2463
|
archived: z.array(surfaceNodeSchema),
|
|
2434
|
-
cost:
|
|
2435
|
-
flash: costFamilySchema.optional(),
|
|
2436
|
-
pro: costFamilySchema.optional()
|
|
2437
|
-
}).strict().optional(),
|
|
2464
|
+
cost: costUsageSchema.optional(),
|
|
2438
2465
|
archiveFloor: z.number().optional(),
|
|
2439
2466
|
timing: timingTotalsSchema.optional(),
|
|
2467
|
+
humanInputs: z.number().int().nonnegative().optional(),
|
|
2440
2468
|
stepStart: z.object({
|
|
2441
2469
|
time: z.number(),
|
|
2442
2470
|
firstToken: z.number().optional(),
|
|
@@ -2511,7 +2539,7 @@ function createContextTimelineDefinition(config, slim) {
|
|
|
2511
2539
|
},
|
|
2512
2540
|
init: () => createTimelineState(),
|
|
2513
2541
|
apply: (state, event) => applyTimeline(state, event, bounds),
|
|
2514
|
-
stateVersion:
|
|
2542
|
+
stateVersion: 18
|
|
2515
2543
|
};
|
|
2516
2544
|
}
|
|
2517
2545
|
//#endregion
|
|
@@ -2614,6 +2642,11 @@ const SettingsSchema = z$1.object({
|
|
|
2614
2642
|
]).default("all").loose(),
|
|
2615
2643
|
defaultGranularity: z$1.union(["step", "turn"]).default("step"),
|
|
2616
2644
|
defaultTrendMode: z$1.union(["total", "delta"]).default("total").loose(),
|
|
2645
|
+
defaultToolSort: z$1.union([
|
|
2646
|
+
"size",
|
|
2647
|
+
"count",
|
|
2648
|
+
"name"
|
|
2649
|
+
]).default("count").loose(),
|
|
2617
2650
|
defaultFileSort: z$1.union([
|
|
2618
2651
|
"count",
|
|
2619
2652
|
"latest",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-context",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.51.0",
|
|
4
4
|
"description": "A DeepSeek Harness plugin for context insight and management, with context dashboard and context command, for understanding how the context is made of, and how it evolves.",
|
|
5
5
|
"author": "bowenliang123",
|
|
6
6
|
"repository": {
|
|
@@ -107,8 +107,12 @@
|
|
|
107
107
|
"@deepseek-ai/dsh-session": "0.1.2-rc.1",
|
|
108
108
|
"@deepseek-ai/dsh-session-projection": "0.1.2-rc.1",
|
|
109
109
|
"@deepseek-ai/dsh-settings": "0.1.2-rc.1",
|
|
110
|
+
"@deepseek-ai/dsh-util-workspace-path": "0.1.5-rc.1",
|
|
110
111
|
"@deepseek-ai/schemastery": "^3.18.2",
|
|
112
|
+
"@opencode-ai/models": "^0.0.72",
|
|
111
113
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
114
|
+
"@tailwindcss/node": "4.3.3",
|
|
115
|
+
"@tailwindcss/oxide": "4.3.3",
|
|
112
116
|
"@types/node": "^26.2.0",
|
|
113
117
|
"@types/react": "^18.3.31",
|
|
114
118
|
"@types/react-dom": "^18.3.7",
|
|
@@ -116,13 +120,14 @@
|
|
|
116
120
|
"eslint-plugin-sonarjs": "^4.2.0",
|
|
117
121
|
"husky": "^9.1.7",
|
|
118
122
|
"jsdom": "^30.0.1",
|
|
119
|
-
"lightningcss": "
|
|
120
|
-
"oxlint": "1.
|
|
123
|
+
"lightningcss": "1.32.0",
|
|
124
|
+
"oxlint": "1.82.0",
|
|
121
125
|
"oxlint-tsgolint": "7.0.2001",
|
|
122
126
|
"playwright-core": "^1.62.1",
|
|
123
127
|
"react": "^18.3.1",
|
|
124
128
|
"react-dom": "^18.3.1",
|
|
125
|
-
"
|
|
129
|
+
"tailwindcss": "4.3.3",
|
|
130
|
+
"tsdown": "^0.23.0",
|
|
126
131
|
"typescript": "^7.0.2",
|
|
127
132
|
"vitest": "^4.1.11",
|
|
128
133
|
"zod": "^4.4.3"
|