dsh-side-chat-plus 0.4.0-alpha.2 → 0.4.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/lib/index.js CHANGED
@@ -6,15 +6,6 @@ import { dshHomePath } from "@deepseek-ai/dsh-home-paths";
6
6
  import { SettingsConflictError } from "@deepseek-ai/dsh-settings";
7
7
  import z from "schemastery";
8
8
  //#region src/settings-shared.ts
9
- /**
10
- * Shared side-chat preference vocabulary (types + constants), consumed by
11
- * BOTH halves: the host registers the schemastery schema over these values
12
- * (index.ts) and the client reads/writes them through the plugin's own
13
- * fenced /sidechat settings routes. Kept free of schemastery so the browser
14
- * bundle never pulls the schema runtime in.
15
- */
16
- /** The user-settings namespace holding the side-chat preferences. */
17
- const SUBCHAT_PREFS_NS = "dsh-side-chat";
18
9
  /** Fallback prefs used whenever the settings document is unreachable or malformed. */
19
10
  const SUBCHAT_PREFS_DEFAULTS = {
20
11
  lookupDefault: false,
@@ -154,11 +145,18 @@ function optionalBoolean(payload, key) {
154
145
  /**
155
146
  * dsh-side-chat host half: the /sidechat JSON API. Every side chat is an
156
147
  * ORDINARY session (no `origin: 'subagent'`) whose `meta.parentSession` points
157
- * at the conversation that launched it, archived immediately so it appears in
158
- * neither the main session list nor the subagent catalog, and driven directly
159
- * through the live agent (followup). Model / reasoning-effort / permission are
148
+ * at the conversation that launched it, kept archived so it appears in neither
149
+ * the main session list nor the subagent catalog, and driven directly through
150
+ * the live agent (followup). Model / reasoning-effort / permission are
160
151
  * inherited from the launching conversation at creation and adjustable later.
161
152
  *
153
+ * DSH 0.1.7 admits archived sessions to no model step: its archived-session
154
+ * gate answers `{ kind: 'reject' }` on `agent/pre-step` for a session in the
155
+ * registry archive set, so a turn ends `blocked` before the first request. The
156
+ * archive is therefore lifted (unarchived) for exactly as long as a side chat
157
+ * has work queued and restored as soon as its agent settles — see
158
+ * `deliver`/`settleTurn` below.
159
+ *
162
160
  * All routes pass the same browser-trust fence as the /api gateway (loopback
163
161
  * or trusted authority; cross-site markers refuse).
164
162
  */
@@ -286,14 +284,13 @@ function openTurnStart(events) {
286
284
  if (lastEnd !== void 0 && lastEnd >= lastStart) return void 0;
287
285
  return lastStart;
288
286
  }
289
- /** Schemastery schema for the user-facing preferences (validated by the settings service). */
290
- const PrefsSchema = z.object({
287
+ const Config = z.object({
291
288
  lookupDefault: z.boolean().default(SUBCHAT_PREFS_DEFAULTS.lookupDefault),
292
289
  sendImmediately: z.boolean().default(SUBCHAT_PREFS_DEFAULTS.sendImmediately),
293
290
  defaultPrompt: z.string().default(SUBCHAT_PREFS_DEFAULTS.defaultPrompt),
294
291
  bringMode: z.union(["draft", "context"]).default(SUBCHAT_PREFS_DEFAULTS.bringMode),
295
292
  panelHome: z.union(["floating", "sidebar-right"]).default(SUBCHAT_PREFS_DEFAULTS.panelHome)
296
- });
293
+ }).volatile();
297
294
  /** The API method table bound to the plugin context and the live side-chat map. */
298
295
  function buildApi(ctx, sideChats, getSettings) {
299
296
  /** Persist the current live records (best-effort; never blocks the API). */
@@ -451,7 +448,65 @@ function buildApi(ctx, sideChats, getSettings) {
451
448
  goal
452
449
  };
453
450
  };
454
- /** Create one side chat: inherit, archive, record, deliver the first prompt. */
451
+ /**
452
+ * Serialize one side chat's archive/unarchive writes. Both registry calls go
453
+ * through the host registry's own operation queue, so enqueueing them in call
454
+ * order is what decides the final state; this chain keeps that order stable
455
+ * when a settling turn and a new delivery overlap.
456
+ */
457
+ const visibilityQueue = /* @__PURE__ */ new Map();
458
+ const queueVisibility = (childId, op) => {
459
+ const next = (visibilityQueue.get(childId) ?? Promise.resolve()).then(op, op);
460
+ visibilityQueue.set(childId, next.then(() => {}, () => {}));
461
+ return next;
462
+ };
463
+ /**
464
+ * Restore one side chat's session before a turn. Registries older than the
465
+ * 0.1.7 gate have no `unarchiveSession` (and need none): there the archive
466
+ * simply stays in place for the whole turn. A failed restore propagates: the
467
+ * caller must not deliver a prompt the gate will answer with `blocked`.
468
+ */
469
+ const unarchiveChild = (childId) => {
470
+ const unarchive = ctx.workspaceRegistry.unarchiveSession;
471
+ if (unarchive === void 0) return archiveChild(childId);
472
+ return queueVisibility(childId, () => unarchive.call(ctx.workspaceRegistry, childId));
473
+ };
474
+ /**
475
+ * Hide one side chat's session again once its agent has settled. Best-effort:
476
+ * a registry that reports the session active (or refuses the write) only
477
+ * leaves it visible until the next settle, never breaks a turn.
478
+ */
479
+ const archiveChild = (childId) => {
480
+ return queueVisibility(childId, () => ctx.workspaceRegistry.archiveSession(childId)).catch(() => {});
481
+ };
482
+ /** Count one settled turn and re-archive the session when the last one ends. */
483
+ const settleTurn = (record) => {
484
+ if (record.pendingTurns > 0) record.pendingTurns -= 1;
485
+ if (record.pendingTurns > 0) return;
486
+ archiveChild(record.childId);
487
+ };
488
+ /**
489
+ * Hand one prompt to a side chat: lift the archive, deliver, and let the
490
+ * agent's own idle boundary put the session back out of every list. `followup`
491
+ * opens the driver synchronously (the phase turns `running` before it
492
+ * returns), so observing `whenIdle` right after it can never miss the turn.
493
+ */
494
+ const deliver = async (record, message) => {
495
+ record.pendingTurns += 1;
496
+ try {
497
+ await unarchiveChild(record.childId);
498
+ record.handle.agent.followup(message);
499
+ } catch (error) {
500
+ settleTurn(record);
501
+ throw error;
502
+ }
503
+ record.handle.agent.whenIdle().then(() => {
504
+ settleTurn(record);
505
+ }, () => {
506
+ settleTurn(record);
507
+ });
508
+ };
509
+ /** Create one side chat: inherit, record, deliver the first prompt (hidden while idle). */
455
510
  const start = async (payload) => {
456
511
  const parentSessionId = requireString(payload, "parentSessionId");
457
512
  const content = requireContent(payload);
@@ -515,16 +570,17 @@ function buildApi(ctx, sideChats, getSettings) {
515
570
  } catch (error) {
516
571
  console.warn("[dsh-side-chat] permission inherit failed:", error instanceof Error ? error.message : String(error));
517
572
  }
518
- await ctx.workspaceRegistry.archiveSession(childId);
519
- sideChats.set(childId, {
573
+ const child = {
520
574
  childId,
521
575
  parentSessionId,
522
576
  handle,
523
577
  selection,
524
- createdAt: Date.now()
525
- });
578
+ createdAt: Date.now(),
579
+ pendingTurns: 0
580
+ };
581
+ sideChats.set(childId, child);
526
582
  persist();
527
- handle.agent.followup(userMessage(await durableContent(content, lookupEnabled)));
583
+ await deliver(child, userMessage(await durableContent(content, lookupEnabled)));
528
584
  return {
529
585
  childId,
530
586
  provider,
@@ -537,7 +593,20 @@ function buildApi(ctx, sideChats, getSettings) {
537
593
  const childId = requireString(payload, "childId");
538
594
  const content = requireContent(payload);
539
595
  const lookupEnabled = optionalBoolean(payload, "lookupEnabled");
540
- childOf(childId).followup(userMessage(await durableContent(content, lookupEnabled)));
596
+ const child = childOf(childId);
597
+ const record = sideChats.get(childId);
598
+ const message = userMessage(await durableContent(content, lookupEnabled));
599
+ if (record === void 0) {
600
+ await unarchiveChild(childId);
601
+ child.followup(message);
602
+ child.whenIdle().then(() => {
603
+ archiveChild(childId);
604
+ }, () => {
605
+ archiveChild(childId);
606
+ });
607
+ return { accepted: true };
608
+ }
609
+ await deliver(record, message);
541
610
  return { accepted: true };
542
611
  };
543
612
  /** List the side chats launched by one parent conversation. */
@@ -681,8 +750,7 @@ function buildApi(ctx, sideChats, getSettings) {
681
750
  text
682
751
  }],
683
752
  source: {
684
- kind: "plugin",
685
- plugin: "dsh-side-chat",
753
+ kind: "plugin:dsh-side-chat",
686
754
  form: "notice",
687
755
  summary
688
756
  }
@@ -797,8 +865,9 @@ function apply(ctx) {
797
865
  const sideChats = /* @__PURE__ */ new Map();
798
866
  let settingsFace;
799
867
  ctx.inject(["settings"], (sctx) => {
800
- const ns = SUBCHAT_PREFS_NS;
801
- sctx.settings.register(ns, PrefsSchema);
868
+ const ns = ctx.entry?.id;
869
+ if (ns === void 0) return;
870
+ sctx.effect(() => sctx.settings.configure({ auto: false }, ctx.fiber));
802
871
  const viewOf = () => {
803
872
  const descriptor = sctx.settings.describe({ redactSecrets: true }).find((c) => c.ns === ns);
804
873
  return descriptor === void 0 ? {
@@ -816,12 +885,25 @@ function apply(ctx) {
816
885
  return viewOf();
817
886
  }
818
887
  };
888
+ sctx.effect(() => () => {
889
+ settingsFace = void 0;
890
+ });
819
891
  });
820
892
  const api = buildApi(ctx, sideChats, () => settingsFace);
821
893
  ctx.effect(() => {
822
894
  return () => {
823
- for (const record of sideChats.values()) record.handle.dispose().catch(() => {});
895
+ const records = [...sideChats.values()];
824
896
  sideChats.clear();
897
+ (async () => {
898
+ for (const record of records) {
899
+ try {
900
+ await record.handle.dispose();
901
+ } catch {}
902
+ try {
903
+ await ctx.workspaceRegistry.archiveSession(record.childId);
904
+ } catch {}
905
+ }
906
+ })();
825
907
  };
826
908
  }, "dsh-side-chat: dispose side chats");
827
909
  ctx.effect(() => {
@@ -887,4 +969,4 @@ function apply(ctx) {
887
969
  }), "dsh-side-chat: /sidechat/api routes");
888
970
  }
889
971
  //#endregion
890
- export { apply, inject, name };
972
+ export { Config, apply, inject, name };
@@ -219,9 +219,19 @@ export interface SideModelSelectionRef {
219
219
  * instance, so the upstream export is reached through a loose signature.
220
220
  */
221
221
  export type SideInstallModelSelection = (agentCtx: Context, selection: SideModelSelectionRef) => () => void;
222
- /** The workspace registry face (archive a session durably). */
222
+ /**
223
+ * The workspace registry face. `archiveSession` hides a session from every
224
+ * grouping surface; `unarchiveSession` (0.1.6+) restores it. Both are writable
225
+ * through the registry's serialized operation queue.
226
+ */
223
227
  export interface SideWorkspaceRegistry {
224
228
  archiveSession(sessionId: string): Promise<void>;
229
+ /**
230
+ * Restore one archived session. The plugin lifts the archive for exactly as
231
+ * long as a side-chat turn has to run: DSH 0.1.7 rejects `agent/pre-step` for
232
+ * an archived session, so an archived side chat can never answer.
233
+ */
234
+ unarchiveSession?(sessionId: string): Promise<void>;
225
235
  }
226
236
  /** `sessionQuery.readSession` snapshot. */
227
237
  export interface SideSessionLogSnapshot {
@@ -323,12 +333,11 @@ export interface SideLocaleService {
323
333
  subscribe(fn: () => void): () => void;
324
334
  register(ns: string, locale: string, dict: Record<string, string>): () => void;
325
335
  }
326
- /** The host settings service face (namespace registration + read/write). */
336
+ /** DSH 0.1.7 profile-entry settings forms. */
327
337
  export interface SideSettingsService {
328
- register(ns: unknown, schema: unknown): {
329
- get(): unknown;
330
- watch(cb: (next: unknown, prev: unknown) => void): () => void;
331
- };
338
+ configure(presentation: {
339
+ auto?: boolean;
340
+ }, owner?: Context['fiber']): () => void;
332
341
  describe(opts: {
333
342
  redactSecrets?: boolean;
334
343
  }): Array<{
@@ -1,7 +1,10 @@
1
+ import z from 'schemastery';
1
2
  import type { Context } from './context-types.ts';
3
+ import { type SubchatPrefs } from './settings-shared.ts';
2
4
  /** Plugin identity for cordis.yml rows. */
3
5
  export declare const name = "dsh-side-chat-plus";
4
6
  /** Services required before mounting. */
5
7
  export declare const inject: string[];
8
+ export declare const Config: z<NoInfer<SubchatPrefs>, NoInfer<SubchatPrefs>, "volatile">;
6
9
  /** Host plugin body: register the /sidechat JSON API routes. */
7
10
  export declare function apply(ctx: Context): void;
@@ -1,12 +1,10 @@
1
1
  /**
2
2
  * Shared side-chat preference vocabulary (types + constants), consumed by
3
- * BOTH halves: the host registers the schemastery schema over these values
3
+ * BOTH halves: the host exports a live Config schema over these values
4
4
  * (index.ts) and the client reads/writes them through the plugin's own
5
5
  * fenced /sidechat settings routes. Kept free of schemastery so the browser
6
6
  * bundle never pulls the schema runtime in.
7
7
  */
8
- /** The user-settings namespace holding the side-chat preferences. */
9
- export declare const SUBCHAT_PREFS_NS = "dsh-side-chat";
10
8
  /** How a brought-back reply lands in the main conversation. */
11
9
  export type BringMode = 'draft' | 'context';
12
10
  /** Where the side-chat panel lives when a side chat is open. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-side-chat-plus",
3
- "version": "0.4.0-alpha.2",
3
+ "version": "0.4.1",
4
4
  "description": "侧边聊天 Plus (Side chat Plus) — DSH web plugin: select text in a conversation and ask it in a per-session side chat (hidden ordinary session, own right-side panel, inherits model/effort/permissions, lookup toggle).",
5
5
  "private": false,
6
6
  "type": "module",
@@ -60,64 +60,67 @@
60
60
  "lib/types/**/*.d.ts",
61
61
  "cordis.patch.yml",
62
62
  "dsh.plugin.json",
63
- "src"
63
+ "src",
64
+ "CHANGELOG.md",
65
+ "docs/official-sidebar-assessment.md"
64
66
  ],
65
67
  "license": "MIT",
66
68
  "dependencies": {
67
- "schemastery": "^3.18.0"
69
+ "schemastery": "npm:@deepseek-ai/schemastery@3.18.3"
68
70
  },
69
71
  "peerDependencies": {
70
- "@deepseek-ai/dsh-agent": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
71
- "@deepseek-ai/dsh-attachment": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
72
- "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
73
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
74
- "@deepseek-ai/dsh-client-ui-renderer": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
75
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
76
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
77
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
78
- "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
79
- "@deepseek-ai/dsh-llm": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
80
- "@deepseek-ai/dsh-session": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
81
- "@deepseek-ai/dsh-session-query": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
82
- "@deepseek-ai/dsh-workspace": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
83
- "@deepseek-ai/dsh-permission-presets": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
84
- "@deepseek-ai/dsh-sandbox-policy": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
85
- "@deepseek-ai/dsh-agent-presets": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
86
- "@deepseek-ai/dsh-settings": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
87
- "@deepseek-ai/dsh-home-paths": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-alpha.1 || ^0.1.6-0",
72
+ "@deepseek-ai/dsh-agent": "^0.1.7-0",
73
+ "@deepseek-ai/dsh-attachment": "^0.1.7-0",
74
+ "@deepseek-ai/dsh-client-locale": "^0.1.7-0",
75
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.7-0",
76
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.7-0",
77
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.7-0",
78
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.7-0",
79
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.7-0",
80
+ "@deepseek-ai/dsh-host-webserver": "^0.1.7-0",
81
+ "@deepseek-ai/dsh-llm": "^0.1.7-0",
82
+ "@deepseek-ai/dsh-session": "^0.1.7-0",
83
+ "@deepseek-ai/dsh-session-query": "^0.1.7-0",
84
+ "@deepseek-ai/dsh-workspace": "^0.1.7-0",
85
+ "@deepseek-ai/dsh-permission-presets": "^0.1.7-0",
86
+ "@deepseek-ai/dsh-sandbox-policy": "^0.1.7-0",
87
+ "@deepseek-ai/dsh-settings": "^0.1.7-0",
88
+ "@deepseek-ai/dsh-home-paths": "^0.1.7-0",
88
89
  "cordis": "^4.0.0-rc.7",
89
90
  "react": "^18.2.0",
90
- "react-dom": "^18.2.0"
91
+ "react-dom": "^18.2.0",
92
+ "@deepseek-ai/dsh-agent-preset-registry": "^0.1.7-0"
91
93
  },
92
94
  "devDependencies": {
93
- "@deepseek-ai/dsh-agent": "^0.1.5-alpha.2 || ^0.1.6-0",
94
- "@deepseek-ai/dsh-attachment": "^0.1.5-alpha.2 || ^0.1.6-0",
95
- "@deepseek-ai/dsh-client-locale": "^0.1.5-alpha.2 || ^0.1.6-0",
96
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.5-alpha.2 || ^0.1.6-0",
97
- "@deepseek-ai/dsh-client-ui-renderer": "^0.1.5-alpha.2 || ^0.1.6-0",
98
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.5-alpha.2 || ^0.1.6-0",
99
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.5-alpha.2 || ^0.1.6-0",
100
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.5-alpha.2 || ^0.1.6-0",
101
- "@deepseek-ai/dsh-host-webserver": "^0.1.5-alpha.2 || ^0.1.6-0",
102
- "@deepseek-ai/dsh-llm": "^0.1.5-alpha.2 || ^0.1.6-0",
103
- "@deepseek-ai/dsh-session": "^0.1.5-alpha.2 || ^0.1.6-0",
104
- "@deepseek-ai/dsh-session-query": "^0.1.5-alpha.2 || ^0.1.6-0",
105
- "@deepseek-ai/dsh-workspace": "^0.1.5-alpha.2 || ^0.1.6-0",
106
- "@deepseek-ai/dsh-permission-presets": "^0.1.5-alpha.2 || ^0.1.6-0",
107
- "@deepseek-ai/dsh-sandbox-policy": "^0.1.5-alpha.2 || ^0.1.6-0",
108
- "@deepseek-ai/dsh-agent-presets": "^0.1.5-alpha.2 || ^0.1.6-0",
109
- "@deepseek-ai/dsh-settings": "^0.1.5-alpha.2 || ^0.1.6-0",
110
- "@deepseek-ai/dsh-home-paths": "^0.1.5-alpha.2 || ^0.1.6-0",
95
+ "@deepseek-ai/dsh-agent": "0.1.7-alpha.1",
96
+ "@deepseek-ai/dsh-attachment": "0.1.7-alpha.1",
97
+ "@deepseek-ai/dsh-client-locale": "0.1.7-alpha.1",
98
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.7-alpha.1",
99
+ "@deepseek-ai/dsh-client-ui-renderer": "0.1.7-alpha.1",
100
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.7-alpha.1",
101
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.7-alpha.1",
102
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-alpha.1",
103
+ "@deepseek-ai/dsh-host-webserver": "0.1.7-alpha.1",
104
+ "@deepseek-ai/dsh-llm": "0.1.7-alpha.1",
105
+ "@deepseek-ai/dsh-session": "0.1.7-alpha.1",
106
+ "@deepseek-ai/dsh-session-query": "0.1.7-alpha.1",
107
+ "@deepseek-ai/dsh-workspace": "0.1.7-alpha.1",
108
+ "@deepseek-ai/dsh-permission-presets": "0.1.7-alpha.1",
109
+ "@deepseek-ai/dsh-sandbox-policy": "0.1.7-alpha.1",
110
+ "@deepseek-ai/dsh-settings": "0.1.7-alpha.1",
111
+ "@deepseek-ai/dsh-home-paths": "0.1.7-alpha.1",
111
112
  "@types/node": "^24.0.0",
112
113
  "@types/react": "~18.3.1",
113
114
  "@types/react-dom": "~18.3.1",
114
- "cordis": "^4.0.0-rc.7",
115
+ "cordis": "npm:@deepseek-ai/cordis@4.0.3",
115
116
  "lightningcss": "^1.32.0",
116
117
  "react": "^18.2.0",
117
118
  "react-dom": "18.2.0",
118
119
  "tsdown": "^0.22.2",
119
120
  "typescript": "^5.6.0",
120
- "vitest": "^4.1.8"
121
+ "vitest": "^4.1.8",
122
+ "@deepseek-ai/dsh-agent-preset-registry": "0.1.7-alpha.1",
123
+ "@deepseek-ai/dsh-session-format-catalog": "0.1.7-alpha.1"
121
124
  },
122
125
  "scripts": {
123
126
  "build": "node -e \"require('node:fs').rmSync('lib',{recursive:true,force:true})\" && tsc -p tsconfig.build.json && tsdown && node scripts/check-seed-exports.mjs",
@@ -1,89 +1,89 @@
1
- .root {
2
- position: relative;
3
- display: flex;
4
- align-items: center;
5
- min-width: 0;
6
- }
7
-
8
- .rail {
9
- display: flex;
10
- gap: 8px;
11
- overflow-x: auto;
12
- scrollbar-width: none;
13
- padding: 2px;
14
- }
15
-
16
- .rail::-webkit-scrollbar {
17
- display: none;
18
- }
19
-
20
- .item {
21
- position: relative;
22
- flex: none;
23
- }
24
-
25
- .thumbnail {
26
- display: block;
27
- width: 56px;
28
- height: 56px;
29
- padding: 0;
30
- overflow: hidden;
31
- border: 1px solid var(--dsw-color-border, rgba(0, 0, 0, 0.1));
32
- border-radius: 8px;
33
- background: none;
34
- cursor: pointer;
35
- }
36
-
37
- .thumbnail img {
38
- width: 100%;
39
- height: 100%;
40
- object-fit: cover;
41
- }
42
-
43
- .remove {
44
- position: absolute;
45
- top: -6px;
46
- right: -6px;
47
- display: flex;
48
- align-items: center;
49
- justify-content: center;
50
- width: 18px;
51
- height: 18px;
52
- padding: 0;
53
- border: none;
54
- border-radius: 50%;
55
- background: var(--dsw-color-surface-raised, #fff);
56
- box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
57
- color: var(--dsw-color-text-secondary, #646a73);
58
- cursor: pointer;
59
- opacity: 0;
60
- }
61
-
62
- .item:hover .remove,
63
- .remove:focus-visible {
64
- opacity: 1;
65
- }
66
-
67
- .arrow {
68
- position: absolute;
69
- z-index: 1;
70
- display: flex;
71
- align-items: center;
72
- justify-content: center;
73
- width: 22px;
74
- height: 22px;
75
- padding: 0;
76
- border: 1px solid var(--dsw-color-border, rgba(0, 0, 0, 0.1));
77
- border-radius: 50%;
78
- background: var(--dsw-color-surface-raised, #fff);
79
- color: var(--dsw-color-text-secondary, #646a73);
80
- cursor: pointer;
81
- }
82
-
83
- .arrowLeft {
84
- left: -10px;
85
- }
86
-
87
- .arrowRight {
88
- right: -10px;
89
- }
1
+ .root {
2
+ position: relative;
3
+ display: flex;
4
+ align-items: center;
5
+ min-width: 0;
6
+ }
7
+
8
+ .rail {
9
+ display: flex;
10
+ gap: 8px;
11
+ overflow-x: auto;
12
+ scrollbar-width: none;
13
+ padding: 2px;
14
+ }
15
+
16
+ .rail::-webkit-scrollbar {
17
+ display: none;
18
+ }
19
+
20
+ .item {
21
+ position: relative;
22
+ flex: none;
23
+ }
24
+
25
+ .thumbnail {
26
+ display: block;
27
+ width: 56px;
28
+ height: 56px;
29
+ padding: 0;
30
+ overflow: hidden;
31
+ border: 1px solid var(--dsw-color-border, rgba(0, 0, 0, 0.1));
32
+ border-radius: 8px;
33
+ background: none;
34
+ cursor: pointer;
35
+ }
36
+
37
+ .thumbnail img {
38
+ width: 100%;
39
+ height: 100%;
40
+ object-fit: cover;
41
+ }
42
+
43
+ .remove {
44
+ position: absolute;
45
+ top: -6px;
46
+ right: -6px;
47
+ display: flex;
48
+ align-items: center;
49
+ justify-content: center;
50
+ width: 18px;
51
+ height: 18px;
52
+ padding: 0;
53
+ border: none;
54
+ border-radius: 50%;
55
+ background: var(--dsw-color-surface-raised, #fff);
56
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
57
+ color: var(--dsw-color-text-secondary, #646a73);
58
+ cursor: pointer;
59
+ opacity: 0;
60
+ }
61
+
62
+ .item:hover .remove,
63
+ .remove:focus-visible {
64
+ opacity: 1;
65
+ }
66
+
67
+ .arrow {
68
+ position: absolute;
69
+ z-index: 1;
70
+ display: flex;
71
+ align-items: center;
72
+ justify-content: center;
73
+ width: 22px;
74
+ height: 22px;
75
+ padding: 0;
76
+ border: 1px solid var(--dsw-color-border, rgba(0, 0, 0, 0.1));
77
+ border-radius: 50%;
78
+ background: var(--dsw-color-surface-raised, #fff);
79
+ color: var(--dsw-color-text-secondary, #646a73);
80
+ cursor: pointer;
81
+ }
82
+
83
+ .arrowLeft {
84
+ left: -10px;
85
+ }
86
+
87
+ .arrowRight {
88
+ right: -10px;
89
+ }