dsh-side-chat-plus 0.3.3 → 0.4.0-alpha.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
@@ -1,5 +1,5 @@
1
1
  import { randomUUID } from "node:crypto";
2
- import { mkdir, writeFile } from "node:fs/promises";
2
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
3
3
  import { dirname } from "node:path";
4
4
  import * as agentApi from "@deepseek-ai/dsh-agent";
5
5
  import { dshHomePath } from "@deepseek-ai/dsh-home-paths";
@@ -20,7 +20,8 @@ const SUBCHAT_PREFS_DEFAULTS = {
20
20
  lookupDefault: false,
21
21
  sendImmediately: true,
22
22
  defaultPrompt: "",
23
- bringMode: "draft"
23
+ bringMode: "draft",
24
+ panelHome: "sidebar-right"
24
25
  };
25
26
  //#endregion
26
27
  //#region src/trust-fence.ts
@@ -170,7 +171,6 @@ const inject = [
170
171
  "agents",
171
172
  "workspaceRegistry",
172
173
  "sessionQuery",
173
- "sandboxPolicy",
174
174
  "permissionPresets",
175
175
  "agentPresets",
176
176
  "llm",
@@ -190,6 +190,24 @@ const RECORD_FILE = "dsh-side-chat-sessions.json";
190
190
  function recordFilePath() {
191
191
  return dshHomePath(RECORD_FILE);
192
192
  }
193
+ /** Read the durable side-chat record list (absent/malformed → empty). */
194
+ async function readRecords() {
195
+ try {
196
+ const raw = await readFile(recordFilePath(), "utf8");
197
+ const parsed = JSON.parse(raw);
198
+ if (!Array.isArray(parsed)) return [];
199
+ return parsed.filter((entry) => {
200
+ const record = entry;
201
+ return typeof record?.childId === "string" && typeof record?.parentSessionId === "string";
202
+ }).map((entry) => ({
203
+ childId: entry.childId,
204
+ parentSessionId: entry.parentSessionId,
205
+ createdAt: typeof entry.createdAt === "number" ? entry.createdAt : 0
206
+ }));
207
+ } catch {
208
+ return [];
209
+ }
210
+ }
193
211
  /** Persist the live side-chat record list (the "record" a future cleanup consumes). */
194
212
  async function writeRecords(records) {
195
213
  const path = recordFilePath();
@@ -273,7 +291,8 @@ const PrefsSchema = z.object({
273
291
  lookupDefault: z.boolean().default(SUBCHAT_PREFS_DEFAULTS.lookupDefault),
274
292
  sendImmediately: z.boolean().default(SUBCHAT_PREFS_DEFAULTS.sendImmediately),
275
293
  defaultPrompt: z.string().default(SUBCHAT_PREFS_DEFAULTS.defaultPrompt),
276
- bringMode: z.union(["draft", "context"]).default(SUBCHAT_PREFS_DEFAULTS.bringMode)
294
+ bringMode: z.union(["draft", "context"]).default(SUBCHAT_PREFS_DEFAULTS.bringMode),
295
+ panelHome: z.union(["floating", "sidebar-right"]).default(SUBCHAT_PREFS_DEFAULTS.panelHome)
277
296
  });
278
297
  /** The API method table bound to the plugin context and the live side-chat map. */
279
298
  function buildApi(ctx, sideChats, getSettings) {
@@ -387,12 +406,20 @@ function buildApi(ctx, sideChats, getSettings) {
387
406
  const childId = requireString(payload, "childId");
388
407
  const line = requireString(payload, "line");
389
408
  const child = childOf(childId);
390
- return { executed: await ctx.commands.execute(child, line, new AbortController().signal) !== void 0 };
409
+ return { executed: await ctx.commands.execute(child, line, [], new AbortController().signal) !== void 0 };
391
410
  };
411
+ /**
412
+ * Read a side chat's event log through the session-query service. DSH 0.1.6
413
+ * deprecated the Session's synchronous event getters (`snapshotEvents`,
414
+ * `eventAt`, `ownEvents`); `readSession` is the live-preferred asynchronous
415
+ * read that supersedes them, and the transcript routes already use it.
416
+ */
417
+ const sessionEvents = async (sessionId) => (await ctx.sessionQuery.readSession(sessionId)).events;
392
418
  /** Fold one side-chat agent's plan/goal state for its composer chrome. */
393
- const state = (payload) => {
419
+ const state = async (payload) => {
394
420
  const childId = requireString(payload, "childId");
395
- const events = childOf(childId).session.events ?? [];
421
+ childOf(childId);
422
+ const events = await sessionEvents(childId);
396
423
  let planActive = false;
397
424
  let planWanted = null;
398
425
  let goal = null;
@@ -482,7 +509,7 @@ function buildApi(ctx, sideChats, getSettings) {
482
509
  });
483
510
  try {
484
511
  const explicitPreset = typeof record.preset === "string" && record.preset !== "" ? record.preset : void 0;
485
- const parentPreset = ctx.permissionPresets.current(parent.session.events ?? []);
512
+ const parentPreset = ctx.permissionPresets.current(parent.session);
486
513
  const preset = explicitPreset ?? parentPreset;
487
514
  if (preset !== "custom") ctx.permissionPresets.set(handle.agent.session, preset);
488
515
  } catch (error) {
@@ -514,15 +541,14 @@ function buildApi(ctx, sideChats, getSettings) {
514
541
  return { accepted: true };
515
542
  };
516
543
  /** List the side chats launched by one parent conversation. */
517
- const list = (payload) => {
544
+ const list = async (payload) => {
518
545
  const parentSessionId = requireString(payload, "parentSessionId");
519
546
  const items = [];
520
547
  for (const record of sideChats.values()) {
521
548
  if (record.parentSessionId !== parentSessionId) continue;
522
- const agent = record.handle.agent;
523
- const status = agent.status;
549
+ const status = record.handle.agent.status;
524
550
  const statusRunning = status === "running";
525
- const eventRunningSince = openTurnStart(agent.session.events ?? []);
551
+ const eventRunningSince = status === void 0 ? openTurnStart(await sessionEvents(record.childId)) : void 0;
526
552
  const running = statusRunning || status === void 0 && eventRunningSince !== void 0;
527
553
  const runningSince = running ? eventRunningSince ?? Date.now() : void 0;
528
554
  items.push({
@@ -552,7 +578,8 @@ function buildApi(ctx, sideChats, getSettings) {
552
578
  maxImageBytes: l.maxImageBytes,
553
579
  maxImagesPerMessage: l.maxImagesPerMessage,
554
580
  maxMessageImageBytes: l.maxMessageImageBytes,
555
- maxImagePixels: l.maxImagePixels
581
+ maxImagePixels: l.maxImagePixels,
582
+ ...l.maxImageDimension === void 0 ? {} : { maxImageDimension: l.maxImageDimension }
556
583
  };
557
584
  };
558
585
  /** Read one durable image's bytes for transcript rendering. */
@@ -697,15 +724,26 @@ function buildApi(ctx, sideChats, getSettings) {
697
724
  };
698
725
  /** Permission-preset options for the side-chat selector. */
699
726
  const permissions = () => {
700
- const select = ctx.permissionPresets.selectFor({});
701
- return {
702
- options: select.options.map((o) => ({
703
- value: o.value,
704
- name: o.name,
705
- ...o.description === void 0 ? {} : { description: o.description }
706
- })),
707
- current: select.currentValue
727
+ const presets = ctx.permissionPresets;
728
+ const toOption = (o) => ({
729
+ value: o.value,
730
+ name: o.name,
731
+ ...o.description === void 0 ? {} : { description: o.description }
732
+ });
733
+ const catalog = presets.catalog;
734
+ if (typeof catalog === "function") return {
735
+ options: catalog.call(presets).options.map(toOption),
736
+ current: presets.defaultPreset ?? "custom"
708
737
  };
738
+ const selectFor = presets.selectFor;
739
+ if (typeof selectFor === "function") {
740
+ const select = selectFor.call(presets, {});
741
+ return {
742
+ options: select.options.map(toOption),
743
+ current: select.currentValue
744
+ };
745
+ }
746
+ throw new SidechatError("permissions-unavailable", "the permission-presets service exposes neither catalog() nor selectFor()", 503);
709
747
  };
710
748
  return {
711
749
  "sidechat.start": start,
@@ -786,6 +824,13 @@ function apply(ctx) {
786
824
  sideChats.clear();
787
825
  };
788
826
  }, "dsh-side-chat: dispose side chats");
827
+ ctx.effect(() => {
828
+ (async () => {
829
+ for (const record of await readRecords()) try {
830
+ await ctx.workspaceRegistry.archiveSession(record.childId);
831
+ } catch {}
832
+ })();
833
+ }, "dsh-side-chat: re-archive recorded side chats");
789
834
  ctx.effect(() => ctx.webServer.register({
790
835
  kind: "prefix",
791
836
  path: "/sidechat/api",
@@ -161,6 +161,7 @@ export declare const api: {
161
161
  maxImagesPerMessage: number;
162
162
  maxMessageImageBytes: number;
163
163
  maxImagePixels: number;
164
+ maxImageDimension?: number;
164
165
  }>>;
165
166
  attachment: (args: {
166
167
  childId: string;
@@ -52,6 +52,7 @@ export declare const zh: {
52
52
  'image.unsupported': string;
53
53
  'image.tooMany': string;
54
54
  'image.fileTooLarge': string;
55
+ 'image.dimensionTooLarge': string;
55
56
  settingsNav: string;
56
57
  'settings.lookupTitle': string;
57
58
  'settings.lookupDesc': string;
@@ -66,6 +67,15 @@ export declare const zh: {
66
67
  'settings.bringModeDraftDesc': string;
67
68
  'settings.bringModeContextTitle': string;
68
69
  'settings.bringModeContextDesc': string;
70
+ 'settings.panelHomeTitle': string;
71
+ 'settings.panelHomeDesc': string;
72
+ 'settings.panelHomeFloatingTitle': string;
73
+ 'settings.panelHomeFloatingDesc': string;
74
+ 'settings.panelHomeDockTitle': string;
75
+ 'settings.panelHomeDockDesc': string;
76
+ 'dock.title': string;
77
+ 'dock.unavailable': string;
78
+ 'dock.openFailed': string;
69
79
  'insert.direct': string;
70
80
  'insert.summarize': string;
71
81
  'insert.summarizing': string;
@@ -138,6 +148,7 @@ export declare const en: {
138
148
  'image.unsupported': string;
139
149
  'image.tooMany': string;
140
150
  'image.fileTooLarge': string;
151
+ 'image.dimensionTooLarge': string;
141
152
  settingsNav: string;
142
153
  'settings.lookupTitle': string;
143
154
  'settings.lookupDesc': string;
@@ -152,6 +163,15 @@ export declare const en: {
152
163
  'settings.bringModeDraftDesc': string;
153
164
  'settings.bringModeContextTitle': string;
154
165
  'settings.bringModeContextDesc': string;
166
+ 'settings.panelHomeTitle': string;
167
+ 'settings.panelHomeDesc': string;
168
+ 'settings.panelHomeFloatingTitle': string;
169
+ 'settings.panelHomeFloatingDesc': string;
170
+ 'settings.panelHomeDockTitle': string;
171
+ 'settings.panelHomeDockDesc': string;
172
+ 'dock.title': string;
173
+ 'dock.unavailable': string;
174
+ 'dock.openFailed': string;
155
175
  'insert.direct': string;
156
176
  'insert.summarize': string;
157
177
  'insert.summarizing': string;
@@ -38,11 +38,14 @@ export interface SideSessionEvent {
38
38
  surfaceOp?: 'append' | 'replace' | 'remove';
39
39
  sourceEventSeqs?: number[];
40
40
  }
41
- /** The live session face the host reads (header + append-only event log). */
41
+ /**
42
+ * The live session face the host reads. Event reads go through
43
+ * `sessionQuery.readSession` instead: DSH 0.1.6 deprecated the Session's
44
+ * synchronous event getters (`events` before 0.1.5, `snapshotEvents` after).
45
+ */
42
46
  export interface SideSession {
43
47
  id: string;
44
48
  header: SideSessionHeader;
45
- events?: readonly SideSessionEvent[];
46
49
  requestHeader?: () => {
47
50
  config?: {
48
51
  provider?: string;
@@ -192,23 +195,24 @@ export interface SideSessionLogSnapshot {
192
195
  export interface SideSessionQuery {
193
196
  readSession(sessionId: string): Promise<SideSessionLogSnapshot>;
194
197
  }
195
- /** Sandbox mode vocabulary (read from the session override). */
196
- export type SideSandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access';
197
- /** The sandbox policy face. */
198
- export interface SideSandboxPolicy {
199
- overrideOf(session: SideSession): SideSandboxMode | undefined;
200
- }
201
198
  /** One permission preset option. */
202
199
  export interface SidePresetOption {
203
200
  value: string;
204
201
  name: string;
205
202
  description?: string;
206
203
  }
207
- /** The permission presets face. */
204
+ /** The permission presets face (`current` reads the SESSION, not event rows). */
208
205
  export interface SidePermissionPresets {
209
- current(events: readonly SideSessionEvent[]): string;
206
+ current(session: SideSession): string;
210
207
  set(session: SideSession, name: string): void;
211
- selectFor(state: unknown): {
208
+ /** 0.1.6+: process-level catalog of selectable presets. */
209
+ catalog?(): {
210
+ options: SidePresetOption[];
211
+ };
212
+ /** 0.1.6+: the preset selected as the default for future sessions. */
213
+ defaultPreset?: string;
214
+ /** 0.1.5 and earlier: combined catalog plus current value. Removed in 0.1.6. */
215
+ selectFor?(state: unknown): {
212
216
  options: SidePresetOption[];
213
217
  currentValue: string;
214
218
  };
@@ -299,9 +303,35 @@ export interface SideSettingsService {
299
303
  }
300
304
  /** The client slots service face (settings.section registration). */
301
305
  export interface SideSlotsService {
302
- inject(name: string, factory: () => () => void): void;
306
+ inject(name: string, factory: () => () => void): () => void;
303
307
  register(options: Record<string, unknown>, component: unknown): () => void;
304
308
  }
309
+ /** One right-sidebar tab type definition (dsh-client-ui-sidebar-right contract, mirror). */
310
+ export interface SideTabDefinition {
311
+ /** Stable unique key; the body seat entry registers under the same key. */
312
+ id: string;
313
+ /** Discriminator used by `openTab(kind)` and the pane dispatch. */
314
+ kind: string;
315
+ /** Registry band ('builtin' | 'extension' | 'fallback'); defaults to the extension band. */
316
+ priority?: string;
317
+ /** Fresh title for the tab chip captured at open time. */
318
+ title(address: string): string;
319
+ }
320
+ /** The right-sidebar tab-type registry face (`ctx.sidebarRight.tabs`). */
321
+ export interface SideSidebarRightTabs {
322
+ /** Register a tab type; returns a disposer (hold it in the caller's ctx.effect). */
323
+ register(definition: SideTabDefinition): () => void;
324
+ }
325
+ /** The cross-plugin right-sidebar face (`ctx.sidebarRight`, ui-sidebar-right). */
326
+ export interface SideSidebarRight {
327
+ tabs: SideSidebarRightTabs;
328
+ /** Open a page type by kind in the mounted session; reveals the column. */
329
+ openTab(kind: string, options?: {
330
+ paneId?: string;
331
+ replaceTab?: boolean;
332
+ revealIfOpened?: boolean;
333
+ }): void;
334
+ }
305
335
  /** One durable image reference (mirror of ImageAttachmentRef). */
306
336
  export interface SideImageAttachmentRef {
307
337
  attachmentId: string;
@@ -318,6 +348,8 @@ export interface SideAttachmentStore {
318
348
  maxImagesPerMessage: number;
319
349
  maxMessageImageBytes: number;
320
350
  maxImagePixels: number;
351
+ /** 0.1.6+ per-image intrinsic width/height ceiling; absent on earlier lines. */
352
+ maxImageDimension?: number;
321
353
  mediaTypes: readonly string[];
322
354
  };
323
355
  validateImage(input: {
@@ -341,7 +373,7 @@ export interface SideCommandsService {
341
373
  name: string;
342
374
  description: string;
343
375
  }>;
344
- execute(agent: SideAgent, line: string, signal: AbortSignal): Promise<unknown>;
376
+ execute(agent: SideAgent, line: string, submittedAttachments: readonly unknown[], signal: AbortSignal): Promise<unknown>;
345
377
  }
346
378
  /** The per-session composer input face this plugin writes to (draft-only). */
347
379
  export interface SideSessionInput {
@@ -370,7 +402,6 @@ declare module 'cordis' {
370
402
  agents: SideAgentsService;
371
403
  workspaceRegistry: SideWorkspaceRegistry;
372
404
  sessionQuery: SideSessionQuery;
373
- sandboxPolicy: SideSandboxPolicy;
374
405
  permissionPresets: SidePermissionPresets;
375
406
  agentPresets: SideAgentPresets;
376
407
  llm: SideLlm;
@@ -9,6 +9,8 @@
9
9
  export declare const SUBCHAT_PREFS_NS = "dsh-side-chat";
10
10
  /** How a brought-back reply lands in the main conversation. */
11
11
  export type BringMode = 'draft' | 'context';
12
+ /** Where the side-chat panel lives when a side chat is open. */
13
+ export type PanelHome = 'floating' | 'sidebar-right';
12
14
  /** User-facing side-chat preferences. */
13
15
  export interface SubchatPrefs {
14
16
  /** Whether the "look up workspace / parent when needed" switch defaults on. */
@@ -19,6 +21,8 @@ export interface SubchatPrefs {
19
21
  defaultPrompt: string;
20
22
  /** How brought-back content lands: into the composer draft, or as a collapsed context row. */
21
23
  bringMode: BringMode;
24
+ /** Which container hosts the panel: the classic floating right-edge panel, or the new built-in right sidebar. */
25
+ panelHome: PanelHome;
22
26
  }
23
27
  /** Fallback prefs used whenever the settings document is unreachable or malformed. */
24
28
  export declare const SUBCHAT_PREFS_DEFAULTS: SubchatPrefs;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-side-chat-plus",
3
- "version": "0.3.3",
3
+ "version": "0.4.0-alpha.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",
@@ -67,47 +67,47 @@
67
67
  "schemastery": "^3.18.0"
68
68
  },
69
69
  "peerDependencies": {
70
- "@deepseek-ai/dsh-agent": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
71
- "@deepseek-ai/dsh-attachment": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
72
- "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
73
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
74
- "@deepseek-ai/dsh-client-ui-renderer": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
75
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
76
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
77
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
78
- "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
79
- "@deepseek-ai/dsh-llm": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
80
- "@deepseek-ai/dsh-session": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
81
- "@deepseek-ai/dsh-session-query": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
82
- "@deepseek-ai/dsh-workspace": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
83
- "@deepseek-ai/dsh-permission-presets": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
84
- "@deepseek-ai/dsh-sandbox-policy": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
85
- "@deepseek-ai/dsh-agent-presets": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
86
- "@deepseek-ai/dsh-settings": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
87
- "@deepseek-ai/dsh-home-paths": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
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",
88
88
  "cordis": "^4.0.0-rc.7",
89
89
  "react": "^18.2.0",
90
90
  "react-dom": "^18.2.0"
91
91
  },
92
92
  "devDependencies": {
93
- "@deepseek-ai/dsh-agent": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
94
- "@deepseek-ai/dsh-attachment": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
95
- "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
96
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
97
- "@deepseek-ai/dsh-client-ui-renderer": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
98
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
99
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
100
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
101
- "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
102
- "@deepseek-ai/dsh-llm": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
103
- "@deepseek-ai/dsh-session": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
104
- "@deepseek-ai/dsh-session-query": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
105
- "@deepseek-ai/dsh-workspace": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
106
- "@deepseek-ai/dsh-permission-presets": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
107
- "@deepseek-ai/dsh-sandbox-policy": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
108
- "@deepseek-ai/dsh-agent-presets": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
109
- "@deepseek-ai/dsh-settings": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
110
- "@deepseek-ai/dsh-home-paths": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0",
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",
111
111
  "@types/node": "^24.0.0",
112
112
  "@types/react": "~18.3.1",
113
113
  "@types/react-dom": "~18.3.1",
@@ -120,7 +120,8 @@
120
120
  "vitest": "^4.1.8"
121
121
  },
122
122
  "scripts": {
123
- "build": "node -e \"require('node:fs').rmSync('lib',{recursive:true,force:true})\" && tsc -p tsconfig.build.json && tsdown",
123
+ "build": "node -e \"require('node:fs').rmSync('lib',{recursive:true,force:true})\" && tsc -p tsconfig.build.json && tsdown && node scripts/check-seed-exports.mjs",
124
+ "check:seed": "node scripts/check-seed-exports.mjs",
124
125
  "typecheck": "tsc --noEmit",
125
126
  "bundle": "tsdown",
126
127
  "watch": "tsdown --watch",
package/src/client/api.ts CHANGED
@@ -93,7 +93,7 @@ export const api = {
93
93
  call<{ accepted: true }>('sidechat.inject', args),
94
94
  directory: () => call<SidechatDirectory>('sidechat.directory', {}),
95
95
  permissions: () => call<SidechatPermissions>('sidechat.permissions', {}),
96
- limits: () => call<{ mediaTypes: string[]; maxImageBytes: number; maxImagesPerMessage: number; maxMessageImageBytes: number; maxImagePixels: number }>('sidechat.limits', {}),
96
+ limits: () => call<{ mediaTypes: string[]; maxImageBytes: number; maxImagesPerMessage: number; maxMessageImageBytes: number; maxImagePixels: number; maxImageDimension?: number }>('sidechat.limits', {}),
97
97
  attachment: (args: { childId: string; attachmentId: string }) =>
98
98
  call<{ mediaType: string; data: string }>('sidechat.attachment', args),
99
99
  inherit: (args: { parentSessionId: string }) =>
@@ -56,6 +56,25 @@
56
56
  font-family: var(--dsw-font-family);
57
57
  font-size: 14px;
58
58
  pointer-events: auto;
59
+ transition: transform var(--ds-transition-duration-slow) var(--ds-ease-in-out);
60
+ }
61
+
62
+ /* Embedded in the built-in right sidebar (dock mode): fill the tab pane,
63
+ drop the floating chrome (fixed positioning, resize rail, own border). */
64
+ .panelEmbedded {
65
+ position: absolute;
66
+ inset: 0;
67
+ width: 100%;
68
+ border-left: none;
69
+ border-radius: 0;
70
+ }
71
+
72
+ /* A built-in sidebar overlay (fullscreen preview / floated panel) owns the
73
+ viewport: slide this panel out of the way; the layout margin is dropped by
74
+ the matching width effect so the main column reclaims the space. */
75
+ .panelConflictHidden {
76
+ transform: translateX(calc(100% + 24px));
77
+ pointer-events: none;
59
78
  }
60
79
 
61
80
  .panelResize {