@chatcode/cco-better-sidebar 0.18.0-alpha.4 → 0.18.0-rc.3

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.
Files changed (46) hide show
  1. package/README.md +5 -4
  2. package/README_EN.md +5 -4
  3. package/cordis.patch.yml +6 -5
  4. package/lib/client-editor.js +11116 -700
  5. package/lib/client-mermaid.js +10689 -276
  6. package/lib/client-registry.js +2256 -1650
  7. package/lib/client-terminal.js +262 -262
  8. package/lib/client.js +2255 -1649
  9. package/lib/index.js +63 -42
  10. package/lib/types/client/builtins/tabs.d.ts +9 -0
  11. package/lib/types/client/icons.d.ts +26 -8
  12. package/lib/types/client/service.d.ts +1 -1
  13. package/lib/types/config.d.ts +4 -3
  14. package/lib/types/context-types.d.ts +12 -14
  15. package/lib/types/prefs-shared.d.ts +1 -1
  16. package/lib/types/pty-deps.d.ts +1 -1
  17. package/lib/types/ui-tweaks/index.d.ts +2 -3
  18. package/package.json +2 -2
  19. package/src/client/BrowserView.tsx +1 -1
  20. package/src/client/DiffTab.tsx +1 -1
  21. package/src/client/EditorHost.tsx +1 -1
  22. package/src/client/FileTree.tsx +10 -5
  23. package/src/client/FreeWindow.tsx +2 -1
  24. package/src/client/GitView.tsx +7 -3
  25. package/src/client/SideCardSection.tsx +2 -8
  26. package/src/client/Sidebar.tsx +2 -2
  27. package/src/client/TabBar.tsx +2 -4
  28. package/src/client/TextEditor.tsx +2 -1
  29. package/src/client/TreePanel.tsx +1 -2
  30. package/src/client/UsageHeatmapSection.tsx +1 -1
  31. package/src/client/builtins/tabs.tsx +9 -2
  32. package/src/client/builtins/viewers.tsx +2 -1
  33. package/src/client/icons.tsx +57 -4
  34. package/src/client/intercept.tsx +1 -1
  35. package/src/client/md-toc.tsx +1 -1
  36. package/src/client/mermaid.tsx +2 -1
  37. package/src/client/open-with-settings.tsx +1 -1
  38. package/src/client/service.ts +1 -1
  39. package/src/client/ui-tweaks/branding.tsx +2 -2
  40. package/src/config.ts +22 -2
  41. package/src/context-types.ts +5 -15
  42. package/src/index.ts +22 -20
  43. package/src/prefs-shared.ts +1 -1
  44. package/src/pty-deps.ts +2 -2
  45. package/src/ui-tweaks/config.ts +1 -1
  46. package/src/ui-tweaks/index.ts +7 -13
package/lib/index.js CHANGED
@@ -3,6 +3,7 @@ import { mkdir, open, opendir, readFile, readdir, realpath, rename, rm, stat, wr
3
3
  import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
4
4
  import { WebSocket, WebSocketServer } from "ws";
5
5
  import z from "schemastery";
6
+ import z$1 from "@deepseek-ai/schemastery";
6
7
  import { createHash, randomUUID } from "node:crypto";
7
8
  import { once } from "node:events";
8
9
  import { chmodSync, createWriteStream, existsSync, readFileSync, realpathSync, statSync } from "node:fs";
@@ -11,9 +12,41 @@ import { execFile, spawn } from "node:child_process";
11
12
  import { SettingsConflictError } from "@deepseek-ai/dsh-settings";
12
13
  import { homedir, userInfo } from "node:os";
13
14
  import { defineTool } from "@deepseek-ai/dsh-tools";
14
- import z$1 from "@deepseek-ai/schemastery";
15
15
  import { workspaceDomainState } from "@deepseek-ai/dsh-workspace";
16
16
  import { YAMLMap, YAMLSeq, parse, parseDocument, stringify } from "yaml";
17
+ //#region src/ui-tweaks/config.ts
18
+ /**
19
+ * dsh-ui-tweaks configuration: conversation font size (px), markdown table
20
+ * style, and feature toggles. Every field
21
+ * defaults at the schema boundary, so a hand-edited settings document and the
22
+ * Settings panel stay consistent.
23
+ * @module dsh-ui-tweaks/config
24
+ */
25
+ /** Settings document namespace owned by this plugin. */
26
+ const UI_TWEAKS_SETTINGS_NAMESPACE = "better-sidebar";
27
+ /** Configuration schema with documented defaults. */
28
+ const Config$1 = z$1.object({
29
+ fontSize: z$1.number().min(10).max(32).default(16),
30
+ codeFontScale: z$1.number().min(50).max(150).default(81),
31
+ codeFontSize: z$1.number().min(8).max(32),
32
+ lineHeight: z$1.number().min(0).max(64).default(16),
33
+ tableStyle: z$1.union(["default", "claude"]).default("default"),
34
+ gitBarEnabled: z$1.boolean().default(false),
35
+ archiveManagerEnabled: z$1.boolean().default(false),
36
+ mcpManagerEnabled: z$1.boolean().default(false),
37
+ initCommandEnabled: z$1.boolean().default(false),
38
+ whaleIndicatorEnabled: z$1.boolean().default(false),
39
+ preciseCacheHitEnabled: z$1.boolean().default(false),
40
+ notificationsEnabled: z$1.boolean().default(false),
41
+ notifyOnlyWhenHidden: z$1.boolean().default(true),
42
+ notifyOnComplete: z$1.boolean().default(true),
43
+ notifyOnInteraction: z$1.boolean().default(true),
44
+ notifyTitleFlash: z$1.boolean().default(true),
45
+ notifySystemNotification: z$1.boolean().default(true),
46
+ notifySound: z$1.boolean().default(false),
47
+ suggestModel: z$1.string()
48
+ });
49
+ //#endregion
17
50
  //#region src/prefs-shared.ts
18
51
  /**
19
52
  * Shared "Side card" preference vocabulary (types + constants), consumed by
@@ -23,7 +56,7 @@ import { YAMLMap, YAMLSeq, parse, parseDocument, stringify } from "yaml";
23
56
  * the browser bundle never pulls the schema runtime in.
24
57
  */
25
58
  /** The user-settings namespace holding the side card preferences. */
26
- const SIDEBAR_PREFS_NS = "dsh-better-sidebar";
59
+ const SIDEBAR_PREFS_NS = "better-sidebar";
27
60
  /** Fallback prefs used whenever the settings document is unreachable or malformed. */
28
61
  const SIDEBAR_PREFS_DEFAULTS = {
29
62
  openByDefault: false,
@@ -65,7 +98,7 @@ const SIDEBAR_PREFS_DEFAULTS = {
65
98
  * @module dsh-better-sidebar/config
66
99
  */
67
100
  /** Schemastery schema for the plugin configuration. */
68
- const Config = z.object({
101
+ const HostConfig = z.object({
69
102
  readLimit: z.number().step(1).min(1).default(524288),
70
103
  mediaLimit: z.number().step(1).min(1).default(20971520),
71
104
  uploadLimit: z.number().step(1).min(1).default(134217728),
@@ -148,6 +181,20 @@ const PrefsSchema = z.object({
148
181
  viewersEnabled: z.dict(z.boolean()).default({}),
149
182
  pluginSettings: z.dict(z.dict(z.any())).default({})
150
183
  });
184
+ function live(schema) {
185
+ Reflect.set(schema.meta, "volatile", true);
186
+ return schema;
187
+ }
188
+ function liveFields(schema) {
189
+ if (schema.type !== "object" || schema.dict === void 0) throw new TypeError("Live settings schema must be an object");
190
+ return Object.fromEntries(Object.entries(schema.dict).map(([key, field]) => [key, live(field)]));
191
+ }
192
+ /** One entry schema: deployment fields stay fixed while sidebar and UI preferences are live-editable. */
193
+ const Config = z.object({
194
+ ...HostConfig.dict,
195
+ ...liveFields(PrefsSchema),
196
+ ...liveFields(Config$1)
197
+ });
151
198
  //#endregion
152
199
  //#region src/wire.ts
153
200
  /** One API failure with its wire code and HTTP status. */
@@ -1361,7 +1408,7 @@ async function cherryPick(cwd, hash, selected) {
1361
1408
  * agent terminal tools are simply not registered.
1362
1409
  *
1363
1410
  * Version contract: the plugin must stay in sync with DSH core —
1364
- * `@deepseek-ai/dsh-subprocess-local` declares `"node-pty": "^1.1.0"` in
1411
+ * `@deepseek-ai/dsh-subprocess-local` declares `"node-pty": "1.2.0-beta.15"` in
1365
1412
  * its `dependencies`. Both sides then resolve the SAME pnpm store entry
1366
1413
  * (same range, same integrity → one native binding, no drift). Do NOT
1367
1414
  * switch to a fork (e.g. @lydell/node-pty) or a different range without
@@ -1372,7 +1419,7 @@ async function cherryPick(cwd, hash, selected) {
1372
1419
  * range DSH core declares (`@deepseek-ai/dsh-subprocess-local`): the same
1373
1420
  * range keeps pnpm resolving both to one physical package.
1374
1421
  */
1375
- const DSH_NODE_PTY_RANGE = "^1.1.0";
1422
+ const DSH_NODE_PTY_RANGE = "1.2.0-beta.15";
1376
1423
  /**
1377
1424
  * The WebSocket close-code-1011 reason the host sends when node-pty is
1378
1425
  * unavailable. The client recognizes this exact marker and fetches the full
@@ -3225,39 +3272,6 @@ async function performAllUpdates(checks) {
3225
3272
  return results;
3226
3273
  }
3227
3274
  //#endregion
3228
- //#region src/ui-tweaks/config.ts
3229
- /**
3230
- * dsh-ui-tweaks configuration: conversation font size (px), markdown table
3231
- * style, and feature toggles. Every field
3232
- * defaults at the schema boundary, so a hand-edited settings document and the
3233
- * Settings panel stay consistent.
3234
- * @module dsh-ui-tweaks/config
3235
- */
3236
- /** Settings document namespace owned by this plugin. */
3237
- const UI_TWEAKS_SETTINGS_NAMESPACE = "ui-tweaks";
3238
- /** Configuration schema with documented defaults. */
3239
- const Config$1 = z$1.object({
3240
- fontSize: z$1.number().min(10).max(32).default(16),
3241
- codeFontScale: z$1.number().min(50).max(150).default(81),
3242
- codeFontSize: z$1.number().min(8).max(32),
3243
- lineHeight: z$1.number().min(0).max(64).default(16),
3244
- tableStyle: z$1.union(["default", "claude"]).default("default"),
3245
- gitBarEnabled: z$1.boolean().default(false),
3246
- archiveManagerEnabled: z$1.boolean().default(false),
3247
- mcpManagerEnabled: z$1.boolean().default(false),
3248
- initCommandEnabled: z$1.boolean().default(false),
3249
- whaleIndicatorEnabled: z$1.boolean().default(false),
3250
- preciseCacheHitEnabled: z$1.boolean().default(false),
3251
- notificationsEnabled: z$1.boolean().default(false),
3252
- notifyOnlyWhenHidden: z$1.boolean().default(true),
3253
- notifyOnComplete: z$1.boolean().default(true),
3254
- notifyOnInteraction: z$1.boolean().default(true),
3255
- notifyTitleFlash: z$1.boolean().default(true),
3256
- notifySystemNotification: z$1.boolean().default(true),
3257
- notifySound: z$1.boolean().default(false),
3258
- suggestModel: z$1.string()
3259
- });
3260
- //#endregion
3261
3275
  //#region src/ui-tweaks/turn-outcome.ts
3262
3276
  /** Projection key the browser notifier reads through list-row `projectionValues`. */
3263
3277
  const TURN_OUTCOME_PROJECTION_KEY = "dshTurnOutcome";
@@ -5857,10 +5871,11 @@ function installMcpWeb(ctx, backend) {
5857
5871
  //#endregion
5858
5872
  //#region src/ui-tweaks/index.ts
5859
5873
  function apply$1(ctx) {
5860
- ctx.settings.register(UI_TWEAKS_SETTINGS_NAMESPACE, Config$1, { applies: "live" });
5861
5874
  installTurnOutcomeProjection(ctx);
5862
5875
  installUITweaksWeb(ctx, new UITweaksWebBackend(ctx));
5863
- const readConfig = () => ctx.settings.get(UI_TWEAKS_SETTINGS_NAMESPACE);
5876
+ const readConfig = () => {
5877
+ return ctx.settings.describe().find((candidate) => candidate.ns === "better-sidebar")?.value ?? {};
5878
+ };
5864
5879
  installGitWeb(ctx, new GitBackend(ctx, readConfig));
5865
5880
  installArchiveWeb(ctx, new ArchiveBackend(ctx));
5866
5881
  installMcpWeb(ctx, new McpBackend(ctx));
@@ -6468,7 +6483,6 @@ function apply(ctx, config) {
6468
6483
  };
6469
6484
  ctx.inject(["settings"], (sctx) => {
6470
6485
  const ns = SIDEBAR_PREFS_NS;
6471
- const scope = sctx.settings.register(ns, PrefsSchema);
6472
6486
  const viewOf = () => {
6473
6487
  const descriptor = sctx.settings.describe({ redactSecrets: true }).find((candidate) => candidate.ns === ns);
6474
6488
  return descriptor === void 0 ? {
@@ -6490,6 +6504,13 @@ function apply(ctx, config) {
6490
6504
  return viewOf();
6491
6505
  }
6492
6506
  };
6507
+ const scope = { get: () => {
6508
+ const value = viewOf().value;
6509
+ return {
6510
+ ...SIDEBAR_PREFS_DEFAULTS,
6511
+ ...typeof value === "object" && value !== null ? value : {}
6512
+ };
6513
+ } };
6493
6514
  syncToolsGate(scope);
6494
6515
  const syncOpenToolsGate = () => {
6495
6516
  if (scope.get().agentOpenTools) {
@@ -6504,7 +6525,7 @@ function apply(ctx, config) {
6504
6525
  }
6505
6526
  };
6506
6527
  syncOpenToolsGate();
6507
- scope.watch(() => {
6528
+ sctx.on("loader/volatile-update", () => {
6508
6529
  syncToolsGate(scope);
6509
6530
  syncOpenToolsGate();
6510
6531
  });
@@ -1,3 +1,12 @@
1
+ /**
2
+ * The 7 built-in tab descriptors: the plugin registers its own pages
3
+ * (editor / git / terminal / browser / diff) through
4
+ * the same {@link BetterSidebarService} external plugins use — eating its
5
+ * own dogfood. The terminal descriptor owns its quota (`TERMINAL_LIMIT`)
6
+ * and mints `terminal:<uuid>` ids through `createTab`; the browser mints
7
+ * `browser:<n>` the same way (no quota). The editor IS the files window
8
+ * (the old standalone explorer merged into it).
9
+ */
1
10
  import type { Context } from '../../context-types.ts';
2
11
  import type { TabDescriptor } from '../service.ts';
3
12
  /** How many UI-owned terminals may be open at once (agent-owned ones are uncapped). */
@@ -1,11 +1,29 @@
1
- /**
2
- * Icons the sidebar needs beyond the primitives set: a terminal glyph (the
3
- * icon library has none), a diff glyph, and the two panel-toggle glyphs for
4
- * the top-right cluster. Per-tab icons live on the tab descriptors
5
- * (`descriptor.icon`), not in a type-keyed switch — the icon mapping was
6
- * registry-ized with the tab types.
7
- */
8
- import type { IconProps } from '@deepseek-ai/dsh-client-ui-primitives';
1
+ export interface IconProps {
2
+ size?: number;
3
+ className?: string;
4
+ }
5
+ export declare const IconListPenOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
6
+ export declare const IconRefreshOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
7
+ export declare const IconRefreshOutline14: ({ size, className }: IconProps) => import("react").JSX.Element;
8
+ export declare const IconChevronRightOutline14: ({ size, className }: IconProps) => import("react").JSX.Element;
9
+ export declare const IconChevronLeftOutline14: ({ size, className }: IconProps) => import("react").JSX.Element;
10
+ export declare const IconChevronDownOutline14: ({ size, className }: IconProps) => import("react").JSX.Element;
11
+ export declare const IconCodeOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
12
+ export declare const IconCopyOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
13
+ export declare const IconDownloadOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
14
+ export declare const IconLinkOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
15
+ export declare const IconLinkOutline14: ({ size, className }: IconProps) => import("react").JSX.Element;
16
+ export declare const IconBranchOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
17
+ export declare const IconTrashOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
18
+ export declare const IconWarningOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
19
+ export declare const IconCloseFill14: ({ size, className }: IconProps) => import("react").JSX.Element;
20
+ export declare const IconCloseOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
21
+ export declare const IconLoadingOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
22
+ export declare const IconPlusOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
23
+ export declare const IconSettingsOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
24
+ export declare const IconFolderOpen16: ({ size, className }: IconProps) => import("react").JSX.Element;
25
+ export declare const IconPanelLeftOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
26
+ export declare const IconCheckOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
9
27
  /** User-manual glyph: an open book in the sidebar's 1.5px outline style. */
10
28
  export declare const IconBookOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
11
29
  /**
@@ -418,7 +418,7 @@ export declare function matchUrlTarget(tabs: readonly TabDescriptor[], url: URL)
418
418
  * The plugin version this service instance reports. Keep in lockstep with
419
419
  * `package.json`'s version — `tests/service.spec.ts` asserts the pair.
420
420
  */
421
- export declare const SIDEBAR_SERVICE_VERSION = "0.18.0-alpha.0";
421
+ export declare const SIDEBAR_SERVICE_VERSION = "0.18.0-alpha.4";
422
422
  /**
423
423
  * Monotonic capability list consumers use to gate new API usage (features
424
424
  * are never removed). Each string names a v0.12.0+ capability:
@@ -5,10 +5,11 @@
5
5
  * @module dsh-better-sidebar/config
6
6
  */
7
7
  import z from 'schemastery';
8
+ import { type UITweaksConfig } from './ui-tweaks/config.ts';
8
9
  import { type SidebarPrefs } from './prefs-shared.ts';
9
10
  export { SIDEBAR_PREFS_DEFAULTS, SIDEBAR_PREFS_NS, TERMINAL_FONT_SIZE_DEFAULT, TERMINAL_FONT_SIZE_MAX, TERMINAL_FONT_SIZE_MIN, TITLE_BAR_STRIP_DEFAULT, TITLE_BAR_STRIP_MAX, TITLE_BAR_STRIP_MIN, WIDTH_PERCENT_DEFAULT, WIDTH_PERCENT_MAX, WIDTH_PERCENT_MIN, type SidebarPrefs, } from './prefs-shared.ts';
10
11
  /** Tunable sidebar host limits (every field optional; defaults fill in). */
11
- export interface SidebarConfig {
12
+ export interface SidebarConfig extends Partial<SidebarPrefs>, UITweaksConfig {
12
13
  /** Read cap of one text file (bytes); larger files return truncated. */
13
14
  readLimit?: number;
14
15
  /** Media route cap (bytes); larger binaries are refused. */
@@ -56,8 +57,6 @@ export interface CodingPlanConfig {
56
57
  /** Catalogue request timeout in milliseconds. */
57
58
  requestTimeoutMs?: number;
58
59
  }
59
- /** Schemastery schema for the plugin configuration. */
60
- export declare const Config: z<SidebarConfig>;
61
60
  /** Fully defaulted sidebar host settings. */
62
61
  export interface ResolvedSidebarConfig {
63
62
  readLimit: number;
@@ -93,3 +92,5 @@ export interface ResolvedCodingPlanConfig {
93
92
  export declare function resolveSidebarConfig(config: SidebarConfig | undefined): ResolvedSidebarConfig;
94
93
  /** Schemastery schema for the user-facing preferences (validated by the settings service). */
95
94
  export declare const PrefsSchema: z<SidebarPrefs>;
95
+ /** One entry schema: deployment fields stay fixed while sidebar and UI preferences are live-editable. */
96
+ export declare const Config: z<SidebarConfig>;
@@ -427,21 +427,10 @@ export interface SidebarInvariantsService {
427
427
  /** Reserve one package's checks and install them in the service's child fiber. */
428
428
  register(packageName: string, installer: (ctx: Context, fail: (message: string) => never) => void | Promise<void>): () => void;
429
429
  }
430
- /** The settings service face (mirror of @deepseek-ai/dsh-settings' SettingsProvider). */
430
+ /** The settings service face (mirror of @deepseek-ai/dsh-settings' SettingsForms). */
431
431
  export interface SidebarSettingsService {
432
- /**
433
- * Register one namespace schema (the resolved value layers schema defaults,
434
- * then the composition base, then the user document).
435
- */
436
- register<T>(ns: string, schema: unknown, options?: {
437
- base?: Partial<T>;
438
- applies?: 'live' | 'restart';
439
- }): {
440
- get(): T;
441
- watch(callback: (next: T, prev: T) => void | Promise<void>): () => void;
442
- update(patch: object): Promise<void>;
443
- replace(section: object): Promise<void>;
444
- };
432
+ /** Whether the active profile accepts form edits. */
433
+ readonly writable: boolean;
445
434
  /** Redacted descriptors of every registered namespace (secrets stripped). */
446
435
  describe(options?: {
447
436
  redactSecrets?: boolean;
@@ -455,6 +444,15 @@ export interface SidebarSettingsService {
455
444
  }>;
456
445
  /** Service-level merge write with the revision guard (a stale writer is refused). */
457
446
  update(ns: string, patch: object, expectedRevision?: number): Promise<void>;
447
+ /** Apply path edits without restating fields hidden from the caller. */
448
+ mutate(ns: string, ops: readonly ({
449
+ op: 'set';
450
+ path: readonly string[];
451
+ value: unknown;
452
+ } | {
453
+ op: 'unset';
454
+ path: readonly string[];
455
+ })[], expectedRevision?: number): Promise<void>;
458
456
  }
459
457
  /**
460
458
  * The tools service face (mirror of @deepseek-ai/dsh-tools' ToolRuntime).
@@ -6,7 +6,7 @@
6
6
  * the browser bundle never pulls the schema runtime in.
7
7
  */
8
8
  /** The user-settings namespace holding the side card preferences. */
9
- export declare const SIDEBAR_PREFS_NS = "dsh-better-sidebar";
9
+ export declare const SIDEBAR_PREFS_NS = "better-sidebar";
10
10
  /** User-facing side card preferences (new-conversation defaults). */
11
11
  export interface SidebarPrefs {
12
12
  /** Whether a brand-new conversation opens the side card by default. */
@@ -6,7 +6,7 @@ export type NodePtyModule = typeof nodePtyNs;
6
6
  * range DSH core declares (`@deepseek-ai/dsh-subprocess-local`): the same
7
7
  * range keeps pnpm resolving both to one physical package.
8
8
  */
9
- export declare const DSH_NODE_PTY_RANGE = "^1.1.0";
9
+ export declare const DSH_NODE_PTY_RANGE = "1.2.0-beta.15";
10
10
  /**
11
11
  * The WebSocket close-code-1011 reason the host sends when node-pty is
12
12
  * unavailable. The client recognizes this exact marker and fetches the full
@@ -1,9 +1,8 @@
1
1
  /**
2
2
  * dsh-ui-tweaks — server half.
3
3
  *
4
- * Registers the `ui-tweaks` settings namespace so users can tune the
5
- * conversation UI either from the Settings panel or by editing the settings
6
- * document directly (settings.yaml `ui-tweaks:` section). All rendering work
4
+ * Uses the owning sidebar entry's live settings so users can tune the
5
+ * conversation UI from the Settings panel. All rendering work
7
6
  * happens in the browser bundle (`src/client`), which reads and writes this
8
7
  * namespace through the same-origin route mounted here — the Web settings RPC
9
8
  * only exposes a fixed allowlist of namespaces since rc.6, so a custom route is
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chatcode/cco-better-sidebar",
3
- "version": "0.18.0-alpha.4",
3
+ "version": "0.18.0-rc.3",
4
4
  "description": "ChatCode CLI Web plugin: a VS Code-like right sidebar (explorer / editor / terminal / git / browser), isolated per conversation session. Exposes a service for other plugins to register sidebar tabs and file viewers.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -139,7 +139,7 @@
139
139
  "clsx": "^2.1.1",
140
140
  "dompurify": "^3.4.14",
141
141
  "mermaid": "^11.16.1",
142
- "node-pty": "^1.1.0",
142
+ "node-pty": "1.2.0-beta.15",
143
143
  "react-icons": "5.7.0",
144
144
  "rxjs": "^7.8.2",
145
145
  "schemastery": "^3.18.0",
@@ -23,7 +23,7 @@ import {
23
23
  IconLinkOutline14,
24
24
  IconRefreshOutline14,
25
25
  IconWarningOutline16,
26
- } from '@deepseek-ai/dsh-client-ui-primitives'
26
+ } from './icons.tsx'
27
27
  import { VscLinkExternal } from 'react-icons/vsc'
28
28
  import { api } from './api.ts'
29
29
  import { embeddabilityOf, isAllowedLoopbackUrl, normalizeBrowserUrl } from './browser.ts'
@@ -8,7 +8,7 @@
8
8
  * very content it shows.
9
9
  */
10
10
  import { useCallback, useEffect, useState } from 'react'
11
- import { IconRefreshOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'
11
+ import { IconRefreshOutline16 } from './icons.tsx'
12
12
  import type { SessionScope } from './api.ts'
13
13
  import { api } from './api.ts'
14
14
  import type { SidebarDiffRef } from './state.ts'
@@ -25,7 +25,7 @@
25
25
  import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react'
26
26
  import { createElement } from 'react'
27
27
  import clsx from 'clsx'
28
- import { IconCheckOutline16, IconFolderOpen16, IconRefreshOutline14 } from '@deepseek-ai/dsh-client-ui-primitives'
28
+ import { IconCheckOutline16, IconFolderOpen16, IconRefreshOutline14 } from './icons.tsx'
29
29
  import type { Context } from '../context-types.ts'
30
30
  import { api, isOutsideWorkspaceMessage, mediaUrl, type SessionScope } from './api.ts'
31
31
  import { BinaryDownload } from './binary-download.tsx'
@@ -23,15 +23,20 @@
23
23
  import { useCallback, useEffect, useRef, useState, type DragEvent, type MouseEvent, type ReactNode } from 'react'
24
24
  import { createPortal } from 'react-dom'
25
25
  import clsx from 'clsx'
26
- import {
27
- IconChevronRightOutline14, IconCodeOutline16, IconCopyOutline16, IconDownloadOutline16,
28
- IconLinkOutline16, Menu, type MenuEntry, type MenuItem, writeClipboard,
29
- } from '@deepseek-ai/dsh-client-ui-primitives'
26
+ import { Menu, type MenuEntry, type MenuItem, writeClipboard } from '@deepseek-ai/dsh-client-ui-primitives'
30
27
  import { SiCursor, SiZedindustries } from 'react-icons/si'
31
28
  import { VscFile, VscFolder, VscFolderOpened, VscLinkExternal, VscPin, VscPinned } from 'react-icons/vsc'
32
29
  import { api, downloadUrl, isOutsideWorkspaceMessage, type FsEntry } from './api.ts'
33
30
  import { FenceErrorNotice } from './FenceErrorNotice.tsx'
34
- import { IconUploadOutline16, IconVscode16 } from './icons.tsx'
31
+ import {
32
+ IconChevronRightOutline14,
33
+ IconCodeOutline16,
34
+ IconCopyOutline16,
35
+ IconDownloadOutline16,
36
+ IconLinkOutline16,
37
+ IconUploadOutline16,
38
+ IconVscode16,
39
+ } from './icons.tsx'
35
40
  import type { OpenWithTarget } from './open-with.ts'
36
41
  import { relativeTo } from './paths.ts'
37
42
  import { t } from './locales.ts'
@@ -16,7 +16,8 @@
16
16
  */
17
17
  import { useEffect, useRef, useState, type ReactNode } from 'react'
18
18
  import clsx from 'clsx'
19
- import { IconCloseFill14, Menu } from '@deepseek-ai/dsh-client-ui-primitives'
19
+ import { Menu } from '@deepseek-ai/dsh-client-ui-primitives'
20
+ import { IconCloseFill14 } from './icons.tsx'
20
21
  import type { FloatWindow, SidebarTab } from './state.ts'
21
22
  import { FLOAT_MIN_H, FLOAT_MIN_W } from './state.ts'
22
23
  import { t } from './locales.ts'
@@ -10,10 +10,14 @@
10
10
  * file changes appear without a manual refresh.
11
11
  */
12
12
  import { useCallback, useEffect, useRef, useState, type MouseEvent, type ReactNode } from 'react'
13
+ import { Button, Input, Menu, Modal, writeClipboard } from '@deepseek-ai/dsh-client-ui-primitives'
13
14
  import {
14
- Button, IconBranchOutline16, IconCodeOutline16, IconCopyOutline16, IconRefreshOutline16,
15
- IconTrashOutline16, Input, Menu, Modal, writeClipboard,
16
- } from '@deepseek-ai/dsh-client-ui-primitives'
15
+ IconBranchOutline16,
16
+ IconCodeOutline16,
17
+ IconCopyOutline16,
18
+ IconRefreshOutline16,
19
+ IconTrashOutline16,
20
+ } from './icons.tsx'
17
21
  import type { GitLogEntry, GitStatusEntry, GitStatusResult, GitWorktree, SessionScope } from './api.ts'
18
22
  import { api } from './api.ts'
19
23
  import { isWithinWorkspace, relativeTo } from './paths.ts'
@@ -41,14 +41,7 @@
41
41
  * shell.
42
42
  */
43
43
  import { Fragment, useEffect, useMemo, useRef, useState, type ReactNode } from 'react'
44
- import {
45
- IconChevronDownOutline14,
46
- IconPlusOutline16,
47
- IconSettingsOutline16,
48
- Input,
49
- Menu,
50
- Modal,
51
- } from '@deepseek-ai/dsh-client-ui-primitives'
44
+ import { Input, Menu, Modal } from '@deepseek-ai/dsh-client-ui-primitives'
52
45
  import clsx from 'clsx'
53
46
  // Type-only: pulls the settings shell's SlotMap merges ('settings.section').
54
47
  import type {} from '@deepseek-ai/dsh-client-ui-settings/client'
@@ -63,6 +56,7 @@ import {
63
56
  type TitleBarScheme,
64
57
  } from '../prefs-shared.ts'
65
58
  import { api } from './api.ts'
59
+ import { IconChevronDownOutline14, IconPlusOutline16, IconSettingsOutline16 } from './icons.tsx'
66
60
  import { parsePrefs } from './prefs.ts'
67
61
  import { AddPluginModal, type PluginKind } from './add-plugin-modal.tsx'
68
62
  import {
@@ -36,7 +36,7 @@ import { createElement, memo, useCallback, useEffect, useMemo, useRef, useState,
36
36
  import { useSyncExternalStore } from 'react'
37
37
  import { createPortal } from 'react-dom'
38
38
  import clsx from 'clsx'
39
- import { IconCloseFill14, Tooltip } from '@deepseek-ai/dsh-client-ui-primitives'
39
+ import { Tooltip } from '@deepseek-ai/dsh-client-ui-primitives'
40
40
  import type { Context } from '../context-types.ts'
41
41
  import { appendToDraft } from './conversation-draft.ts'
42
42
  import {
@@ -47,7 +47,7 @@ import {
47
47
  type DropZone, type SidebarState, type SidebarStore, type SidebarTab, type SplitNode,
48
48
  } from './state.ts'
49
49
  import { collectPinnedTabs, createPinnedVirtualTab, getPinnedHomeScope, injectPinnedIntoTree, isPinnedVirtualId, isPinnedVirtualTab, parsePinnedVirtualId, type PinnedTabEntry } from './pinned.ts'
50
- import { IconBookOutline16, IconPinOutline16 } from './icons.tsx'
50
+ import { IconBookOutline16, IconCloseFill14, IconPinOutline16 } from './icons.tsx'
51
51
  import { IconPanelBottomOutline16, IconPanelRightOutline16 } from './icons.tsx'
52
52
  import { Workbench, type WorkbenchActions } from './split-pane.tsx'
53
53
  import { isNarrowWidth, useViewportSize } from './breakpoints.ts'
@@ -10,13 +10,11 @@
10
10
  */
11
11
  import { useEffect, useRef, useState, type ReactNode } from 'react'
12
12
  import clsx from 'clsx'
13
- import {
14
- IconCloseFill14, IconPlusOutline16, Menu,
15
- } from '@deepseek-ai/dsh-client-ui-primitives'
13
+ import { Menu } from '@deepseek-ai/dsh-client-ui-primitives'
16
14
  import type { SidebarTab } from './state.ts'
17
15
  import { isAgentTabId } from './state.ts'
18
16
  import { isPinnedVirtualTab } from './pinned.ts'
19
- import { IconPinOutline16 } from './icons.tsx'
17
+ import { IconCloseFill14, IconPinOutline16, IconPlusOutline16 } from './icons.tsx'
20
18
  import { t } from './locales.ts'
21
19
  import css from './sidebar.module.css'
22
20
 
@@ -19,7 +19,8 @@ import clsx from 'clsx'
19
19
  import { EditorState } from '@codemirror/state'
20
20
  import { EditorView as CodeMirrorView, keymap, lineNumbers } from '@codemirror/view'
21
21
  import { defaultKeymap, history, historyKeymap } from '@codemirror/commands'
22
- import { IconCheckOutline16, MarkdownText } from '@deepseek-ai/dsh-client-ui-primitives'
22
+ import { MarkdownText } from '@deepseek-ai/dsh-client-ui-primitives'
23
+ import { IconCheckOutline16 } from './icons.tsx'
23
24
  import { markdownTextProps } from './markdown-labels.tsx'
24
25
  import { api, htmlUrl } from './api.ts'
25
26
  import { rewriteLocalImageUrls } from './markdown-images.ts'
@@ -17,11 +17,10 @@
17
17
  */
18
18
  import { useEffect, useRef, useState, type InputHTMLAttributes } from 'react'
19
19
  import clsx from 'clsx'
20
- import { IconFolderOpen16, IconRefreshOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'
21
20
  import { api } from './api.ts'
22
21
  import type { SidebarStore } from './state.ts'
23
22
  import { FileTree } from './FileTree.tsx'
24
- import { IconUploadOutline16 } from './icons.tsx'
23
+ import { IconFolderOpen16, IconRefreshOutline16, IconUploadOutline16 } from './icons.tsx'
25
24
  import type { OpenWithTarget } from './open-with.ts'
26
25
  import { t } from './locales.ts'
27
26
  import { resolveSidebarPath } from './produced-files.ts'
@@ -4,7 +4,7 @@ import {
4
4
  IconChevronRightOutline14,
5
5
  IconLoadingOutline16,
6
6
  IconRefreshOutline14,
7
- } from '@deepseek-ai/dsh-client-ui-primitives'
7
+ } from './icons.tsx'
8
8
  import clsx from 'clsx'
9
9
  // Type-only: pulls the settings shell's SlotMap merges ('settings.section').
10
10
  import type {} from '@deepseek-ai/dsh-client-ui-settings/client'
@@ -7,7 +7,6 @@
7
7
  * `browser:<n>` the same way (no quota). The editor IS the files window
8
8
  * (the old standalone explorer merged into it).
9
9
  */
10
- import { IconBranchOutline16, IconCodeOutline16, IconFolderOpen16, IconPanelLeftOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'
11
10
  import type { Context } from '../../context-types.ts'
12
11
  import { allLeaves, isAgentTabId, type SidebarState } from '../state.ts'
13
12
  import { t } from '../locales.ts'
@@ -18,7 +17,15 @@ import { lazyChunkComponent } from '../lazy-chunk.tsx'
18
17
  import { GitView } from '../GitView.tsx'
19
18
  import { DiffTab } from '../DiffTab.tsx'
20
19
  import { BrowserView } from '../BrowserView.tsx'
21
- import { IconTerminalOutline16, IconDiffOutline16, IconGlobeOutline16 } from '../icons.tsx'
20
+ import {
21
+ IconBranchOutline16,
22
+ IconCodeOutline16,
23
+ IconDiffOutline16,
24
+ IconFolderOpen16,
25
+ IconGlobeOutline16,
26
+ IconPanelLeftOutline16,
27
+ IconTerminalOutline16,
28
+ } from '../icons.tsx'
22
29
  import { TERMINAL_FONT_SIZE_MAX, TERMINAL_FONT_SIZE_MIN } from '../../prefs-shared.ts'
23
30
  import type { ComponentType } from 'react'
24
31
  import type { SessionScope } from '../api.ts'
@@ -22,11 +22,12 @@
22
22
  * and `icon` — so the Side card settings page can render the enable/disable
23
23
  * inventory without hardcoding (eating our own dogfood).
24
24
  */
25
- import { IconCodeOutline16, IconDownloadOutline16 } from '@deepseek-ai/dsh-client-ui-primitives'
26
25
  import { lazyChunkComponent } from '../lazy-chunk.tsx'
27
26
  import { PdfView } from '../PdfView.tsx'
28
27
  import { BinaryDownload } from '../binary-download.tsx'
29
28
  import {
29
+ IconCodeOutline16,
30
+ IconDownloadOutline16,
30
31
  IconImageOutline16,
31
32
  IconMarkdownOutline16,
32
33
  IconPdfOutline16,