dsh-more 0.1.1 → 0.1.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 (30) hide show
  1. package/README.md +23 -6
  2. package/README.zh-CN.md +36 -6
  3. package/cordis.patch.yml +2 -0
  4. package/dist/client.js +380 -16
  5. package/dist/fast-mode.js +34 -0
  6. package/dist/index.js +222 -57
  7. package/dist/types/generated/host-settings-schema.d.ts +23 -19
  8. package/dist/types/generated/patch-catalog.d.ts +16 -0
  9. package/dist/types/kernel/client/activation.d.ts +2 -2
  10. package/dist/types/kernel/host/settings.d.ts +7 -3
  11. package/dist/types/patches/fast-mode/host/settings.d.ts +6 -0
  12. package/dist/types/patches/model-capabilities/client/index.d.ts +1 -1
  13. package/dist/types/patches/projectless-tasks/client/groups.d.ts +1 -1
  14. package/dist/types/patches/terminal-clipboard/client/clipboard.d.ts +5 -0
  15. package/dist/types/patches/terminal-clipboard/client/index.d.ts +2 -0
  16. package/dist/types/patches/terminal-clipboard/client/terminal.d.ts +17 -0
  17. package/dist/types/patches/terminal-clipboard/host/index.d.ts +2 -0
  18. package/dist/types/patches/terminal-clipboard/shared.d.ts +1 -0
  19. package/dist/types/patches/terminal-host-stats/client/bar.d.ts +5 -0
  20. package/dist/types/patches/terminal-host-stats/client/index.d.ts +2 -0
  21. package/dist/types/patches/terminal-host-stats/client/monitor.d.ts +2 -0
  22. package/dist/types/patches/terminal-host-stats/host/disks.d.ts +8 -0
  23. package/dist/types/patches/terminal-host-stats/host/index.d.ts +2 -0
  24. package/dist/types/patches/terminal-host-stats/host/sample.d.ts +16 -0
  25. package/dist/types/patches/terminal-host-stats/shared.d.ts +16 -0
  26. package/dist/types/platform/dsh/client/runtime.d.ts +5 -2
  27. package/dist/types/platform/dsh/client/settings.d.ts +15 -1
  28. package/docs/desktop-compatibility.md +82 -0
  29. package/dsh.plugin.json +2 -2
  30. package/package.json +70 -61
@@ -0,0 +1,34 @@
1
+ // src/patches/fast-mode/host/settings.ts
2
+ import z from "@deepseek-ai/schemastery";
3
+
4
+ // src/platform/dsh/host/settings.ts
5
+ function liveSetting(schema) {
6
+ const volatile = Reflect.get(schema, "volatile");
7
+ return typeof volatile === "function" ? volatile.call(schema) : schema;
8
+ }
9
+
10
+ // src/patches/fast-mode/shared.ts
11
+ var DEFAULT_FAST_MODE_SETTINGS = {
12
+ defaultEnabled: false,
13
+ serviceTier: "priority",
14
+ speed: 1.5,
15
+ enableAnthropicFastMode: true,
16
+ customBodyParams: {},
17
+ customHeaders: {}
18
+ };
19
+
20
+ // src/patches/fast-mode/host/settings.ts
21
+ var Config = z.object({
22
+ defaultEnabled: liveSetting(z.boolean().default(DEFAULT_FAST_MODE_SETTINGS.defaultEnabled)),
23
+ serviceTier: liveSetting(z.string().default(DEFAULT_FAST_MODE_SETTINGS.serviceTier)),
24
+ speed: liveSetting(z.number().default(DEFAULT_FAST_MODE_SETTINGS.speed)),
25
+ enableAnthropicFastMode: liveSetting(z.boolean().default(DEFAULT_FAST_MODE_SETTINGS.enableAnthropicFastMode)),
26
+ customBodyParams: liveSetting(z.dict(z.any()).default({})),
27
+ customHeaders: liveSetting(z.dict(z.string()).default({}))
28
+ });
29
+ function apply() {
30
+ }
31
+ export {
32
+ Config,
33
+ apply
34
+ };
package/dist/index.js CHANGED
@@ -180,7 +180,7 @@ function retainedRuntimeContexts(seed) {
180
180
  const event = seed[index];
181
181
  if (event?.type !== "user/message") continue;
182
182
  const source = event.data.source;
183
- if (source.plugin !== RUNTIME_CONTEXT_PLUGIN) continue;
183
+ if (source.kind !== "runtime-context" && source.plugin !== RUNTIME_CONTEXT_PLUGIN) continue;
184
184
  if (source.form === "snapshot" && Array.isArray(source.sections)) {
185
185
  const sections = source.sections.filter((section) => {
186
186
  const value = section;
@@ -760,11 +760,11 @@ function installLiveSessionHandleTracker(ctx) {
760
760
  tracker.originalResume = originalResume;
761
761
  tracker.createDescriptor = Object.getOwnPropertyDescriptor(registry, "create");
762
762
  tracker.resumeDescriptor = Object.getOwnPropertyDescriptor(registry, "resume");
763
- tracker.wrappedCreate = async function(options) {
764
- return trackedHandle(tracker, await originalCreate.call(this, options));
763
+ tracker.wrappedCreate = async function(options2) {
764
+ return trackedHandle(tracker, await originalCreate.call(this, options2));
765
765
  };
766
- tracker.wrappedResume = async function(options) {
767
- return trackedHandle(tracker, await originalResume.call(this, options));
766
+ tracker.wrappedResume = async function(options2) {
767
+ return trackedHandle(tracker, await originalResume.call(this, options2));
768
768
  };
769
769
  tracker.references = 1;
770
770
  registry[TRACKER] = tracker;
@@ -991,10 +991,10 @@ ${body}`;
991
991
  function sourceLabel(event) {
992
992
  const source = event.data.source;
993
993
  if (source.kind === "user") return "\u7528\u6237";
994
- if (source.kind === "plugin") return `\u4E0A\u4E0B\u6587 \xB7 ${singleLine(source.plugin) || "\u63D2\u4EF6"}`;
994
+ if (source.kind === "plugin") return `\u4E0A\u4E0B\u6587 \xB7 ${singleLine(source.plugin ?? "") || "\u63D2\u4EF6"}`;
995
995
  return "\u4E0A\u4E0B\u6587";
996
996
  }
997
- function conversationMarkdown(events, options) {
997
+ function conversationMarkdown(events, options2) {
998
998
  const sections = [];
999
999
  const renderedCalls = /* @__PURE__ */ new Set();
1000
1000
  const callNames = /* @__PURE__ */ new Map();
@@ -1026,7 +1026,7 @@ function conversationMarkdown(events, options) {
1026
1026
  if (event.type === "tool/result") {
1027
1027
  const callId = String(event.data.message.source.callId);
1028
1028
  const block = event.data.message.content[0];
1029
- const failed = block?.type === "tool-result" && block.isError === true;
1029
+ const failed = event.data.message.isError === true || block?.type === "tool-result" && block.isError === true;
1030
1030
  const resultContent = block?.type === "tool-result" ? block.content : event.data.message.content;
1031
1031
  const name2 = singleLine(callNames.get(callId) ?? callId) || "\u672A\u547D\u540D\u5DE5\u5177";
1032
1032
  sections.push(messageSection(
@@ -1036,11 +1036,11 @@ function conversationMarkdown(events, options) {
1036
1036
  ));
1037
1037
  }
1038
1038
  }
1039
- const title = singleLine(options.title) || "\u672A\u547D\u540D\u4F1A\u8BDD";
1040
- const exportedAt = isoTime(options.exportedAt ?? Date.now());
1039
+ const title = singleLine(options2.title) || "\u672A\u547D\u540D\u4F1A\u8BDD";
1040
+ const exportedAt = isoTime(options2.exportedAt ?? Date.now());
1041
1041
  const header2 = [
1042
1042
  `# ${title}`,
1043
- `- \u4F1A\u8BDD ID\uFF1A${singleLine(options.sessionId)}`,
1043
+ `- \u4F1A\u8BDD ID\uFF1A${singleLine(options2.sessionId)}`,
1044
1044
  `- \u5BFC\u51FA\u65F6\u95F4\uFF1A${exportedAt}`,
1045
1045
  `- \u8BB0\u5F55\u6761\u76EE\uFF1A${String(sections.length)}`
1046
1046
  ].join("\n\n");
@@ -1160,7 +1160,8 @@ function settingValue(value) {
1160
1160
  return typeof get === "function" ? get.call(value) : value;
1161
1161
  }
1162
1162
  function readSettings(ctx, namespace) {
1163
- if (typeof ctx.settings.get === "function") return ctx.settings.get(namespace);
1163
+ const legacy = ctx.settings;
1164
+ if (typeof legacy.get === "function") return legacy.get(namespace);
1164
1165
  return ctx.settings.describe().find((entry) => entry.ns === namespace)?.value;
1165
1166
  }
1166
1167
 
@@ -1235,9 +1236,9 @@ function installDeepSeekReasoning(ctx) {
1235
1236
  if (config.reasoningEffort !== void 0 || revised.reasoningEffort === void 0) return prepared;
1236
1237
  return Object.freeze({ ...prepared, adapterDefaults: Object.freeze({ ...prepared.adapterDefaults, reasoningEffort: true }) });
1237
1238
  };
1238
- const stream = (options) => {
1239
+ const stream = (options2) => {
1239
1240
  try {
1240
- return originalStream.call(llm, revise(options, active ? ruleFor(scope, options.provider, options.model) : void 0));
1241
+ return originalStream.call(llm, revise(options2, active ? ruleFor(scope, options2.provider, options2.model) : void 0));
1241
1242
  } catch (error) {
1242
1243
  if (!(error instanceof LlmError)) throw error;
1243
1244
  return (async function* () {
@@ -1424,6 +1425,9 @@ var hostPatch5 = {
1424
1425
  // src/patches/fast-mode/host/index.ts
1425
1426
  import { AsyncLocalStorage } from "node:async_hooks";
1426
1427
 
1428
+ // src/patches/fast-mode/host/settings.ts
1429
+ import z2 from "@deepseek-ai/schemastery";
1430
+
1427
1431
  // src/patches/fast-mode/shared.ts
1428
1432
  var FAST_MODE_PATCH_ID = "fast-mode";
1429
1433
  var FAST_MODE_SETTINGS_NS = "dsh-more/fast-mode";
@@ -1436,6 +1440,16 @@ var DEFAULT_FAST_MODE_SETTINGS = {
1436
1440
  customHeaders: {}
1437
1441
  };
1438
1442
 
1443
+ // src/patches/fast-mode/host/settings.ts
1444
+ var Config = z2.object({
1445
+ defaultEnabled: liveSetting(z2.boolean().default(DEFAULT_FAST_MODE_SETTINGS.defaultEnabled)),
1446
+ serviceTier: liveSetting(z2.string().default(DEFAULT_FAST_MODE_SETTINGS.serviceTier)),
1447
+ speed: liveSetting(z2.number().default(DEFAULT_FAST_MODE_SETTINGS.speed)),
1448
+ enableAnthropicFastMode: liveSetting(z2.boolean().default(DEFAULT_FAST_MODE_SETTINGS.enableAnthropicFastMode)),
1449
+ customBodyParams: liveSetting(z2.dict(z2.any()).default({})),
1450
+ customHeaders: liveSetting(z2.dict(z2.string()).default({}))
1451
+ });
1452
+
1439
1453
  // src/patches/fast-mode/host/index.ts
1440
1454
  var activeFastSessionStorage = new AsyncLocalStorage();
1441
1455
  var fastSessions = /* @__PURE__ */ new Set();
@@ -1455,11 +1469,11 @@ function toggleFastSession(sessionId) {
1455
1469
  var interceptorInstalled = false;
1456
1470
  var currentSettings = { ...DEFAULT_FAST_MODE_SETTINGS };
1457
1471
  function readSettings2(ctx) {
1458
- const descriptor = ctx.settings?.describe?.().find((entry) => entry.ns === FAST_MODE_SETTINGS_NS);
1459
- if (!descriptor || typeof descriptor.value !== "object" || descriptor.value === null) {
1472
+ const value = readSettings(ctx, FAST_MODE_SETTINGS_NS);
1473
+ if (typeof value !== "object" || value === null) {
1460
1474
  return { ...DEFAULT_FAST_MODE_SETTINGS };
1461
1475
  }
1462
- const val = descriptor.value;
1476
+ const val = value;
1463
1477
  return {
1464
1478
  defaultEnabled: typeof val.defaultEnabled === "boolean" ? val.defaultEnabled : false,
1465
1479
  serviceTier: typeof val.serviceTier === "string" && val.serviceTier ? val.serviceTier : "priority",
@@ -1518,7 +1532,7 @@ function patchFastRequest(input, init) {
1518
1532
  }
1519
1533
  function bindFastStream(stream, store) {
1520
1534
  const iterator = stream[Symbol.asyncIterator]();
1521
- const pull = (run) => activeFastSessionStorage.run(store, run);
1535
+ const pull = (run2) => activeFastSessionStorage.run(store, run2);
1522
1536
  const bound = {
1523
1537
  [Symbol.asyncIterator]() {
1524
1538
  return bound;
@@ -1534,29 +1548,38 @@ function installFastModeInterceptor() {
1534
1548
  interceptorInstalled = true;
1535
1549
  const originalFetch = globalThis.fetch;
1536
1550
  globalThis.fetch = async function(input, init) {
1551
+ let patched = { input, init };
1537
1552
  try {
1538
- const patched = patchFastRequest(input, init);
1539
- return await originalFetch.call(this, patched.input, patched.init);
1553
+ patched = patchFastRequest(input, init);
1540
1554
  } catch (error) {
1541
1555
  console.warn("fast-mode fetch interceptor error, sending the original request", error);
1542
- return originalFetch.call(this, input, init);
1543
1556
  }
1557
+ return originalFetch.call(this, patched.input, patched.init);
1544
1558
  };
1545
1559
  }
1546
1560
  var hostPatch6 = {
1547
1561
  id: FAST_MODE_PATCH_ID,
1548
1562
  setup: (ctx) => {
1549
- currentSettings = readSettings2(ctx);
1563
+ const legacy = ctx.settings;
1564
+ legacy.register?.(FAST_MODE_SETTINGS_NS, Config);
1565
+ const refreshSettings = () => {
1566
+ currentSettings = readSettings2(ctx);
1567
+ };
1568
+ refreshSettings();
1569
+ const disposeSettings = ctx.on("settings/document-updated", (namespace) => {
1570
+ if (namespace === FAST_MODE_SETTINGS_NS) refreshSettings();
1571
+ });
1550
1572
  installFastModeInterceptor();
1551
- const dispose = ctx.on("llm/stream", (options, next) => {
1552
- if (options?.purpose === "session-title" || options?.purpose === "compaction") return next();
1553
- const sessionId = options?.sessionId === void 0 ? void 0 : String(options.sessionId);
1573
+ const dispose = ctx.on("llm/stream", (options2, next) => {
1574
+ if (options2?.purpose === "session-title" || options2?.purpose === "compaction") return next();
1575
+ const sessionId = options2?.sessionId === void 0 ? void 0 : String(options2.sessionId);
1554
1576
  const enabled = sessionId !== void 0 && isFastSession(sessionId) || currentSettings.defaultEnabled;
1555
1577
  if (!enabled) return next();
1556
1578
  return bindFastStream(next(), { sessionId, isFast: true });
1557
1579
  }, { global: true, prepend: true });
1558
1580
  return () => {
1559
1581
  if (typeof dispose === "function") dispose();
1582
+ if (typeof disposeSettings === "function") disposeSettings();
1560
1583
  };
1561
1584
  },
1562
1585
  routes: ({ ctx }) => ({
@@ -1588,10 +1611,9 @@ var hostPatch6 = {
1588
1611
  customBodyParams: typeof payload.customBodyParams === "object" && payload.customBodyParams !== null ? payload.customBodyParams : {},
1589
1612
  customHeaders: typeof payload.customHeaders === "object" && payload.customHeaders !== null ? payload.customHeaders : {}
1590
1613
  };
1614
+ if (!descriptor || typeof ctx.settings?.mutate !== "function") throw new Error("\u52A0\u901F\u914D\u7F6E\u5C1A\u672A\u6CE8\u518C\uFF0C\u65E0\u6CD5\u4FDD\u5B58");
1615
+ await ctx.settings.mutate(FAST_MODE_SETTINGS_NS, [{ op: "set", path: [], value: next }], descriptor.revision);
1591
1616
  currentSettings = next;
1592
- if (typeof ctx.settings?.mutate === "function") {
1593
- await ctx.settings.mutate(FAST_MODE_SETTINGS_NS, [{ op: "set", path: [], value: next }], descriptor?.revision ?? 0);
1594
- }
1595
1617
  return next;
1596
1618
  }
1597
1619
  })
@@ -1667,14 +1689,14 @@ var hostPatch7 = {
1667
1689
  const lifetime = new AbortController();
1668
1690
  const forwarded = /* @__PURE__ */ new WeakSet();
1669
1691
  const fiber = ctx.inject(["llm"], (scope) => {
1670
- scope.on("llm/stream", (options, next) => {
1671
- if (options.purpose !== "session-title" || forwarded.has(options)) return next();
1692
+ scope.on("llm/stream", (options2, next) => {
1693
+ if (options2.purpose !== "session-title" || forwarded.has(options2)) return next();
1672
1694
  status.requests += 1;
1673
1695
  const signal = AbortSignal.any([
1674
1696
  lifetime.signal,
1675
- ...options.signal ? [options.signal] : []
1697
+ ...options2.signal ? [options2.signal] : []
1676
1698
  ]);
1677
- const revised = { ...options, system: TITLE_SYSTEM_PROMPT, maxTokens: Math.max(options.maxTokens ?? 0, 2048), signal };
1699
+ const revised = { ...options2, system: TITLE_SYSTEM_PROMPT, maxTokens: Math.max(options2.maxTokens ?? 0, 2048), signal };
1678
1700
  async function* dispatch() {
1679
1701
  if (revised.reasoningEffort === void 0) {
1680
1702
  const info = await scope.llm.resolveModelInfo(revised.provider, revised.model, signal);
@@ -1736,10 +1758,10 @@ function decodeSessionGroups(value) {
1736
1758
  }
1737
1759
 
1738
1760
  // src/patches/projectless-tasks/host/groups.ts
1739
- import z2 from "@deepseek-ai/schemastery";
1761
+ import z3 from "@deepseek-ai/schemastery";
1740
1762
  import { SessionId as SessionId7 } from "@deepseek-ai/dsh-session";
1741
1763
  import { WorkspaceId } from "@deepseek-ai/dsh-workspace";
1742
- var SessionGroupsSchema = z2.object({ assignments: z2.dict(z2.string()).default({}) });
1764
+ var SessionGroupsSchema = z3.object({ assignments: z3.dict(z3.string()).default({}) });
1743
1765
  async function moveSessionGroup(ctx, payload) {
1744
1766
  const sessionId = SessionId7(requireString(payload, "sessionId"));
1745
1767
  if (typeof payload !== "object" || payload === null || !("workspaceId" in payload) || !(payload.workspaceId === null || typeof payload.workspaceId === "string" && payload.workspaceId.length > 0)) {
@@ -1778,8 +1800,9 @@ var hostPatch8 = {
1778
1800
  id: PROJECTLESS_TASKS_PATCH_ID,
1779
1801
  setup: (ctx) => {
1780
1802
  const fiber = ctx.inject(["settings"], (scope) => {
1781
- if (typeof scope.settings.register === "function") {
1782
- scope.settings.register(SESSION_GROUPS_NAMESPACE, SessionGroupsSchema);
1803
+ const legacy = scope.settings;
1804
+ if (typeof legacy.register === "function") {
1805
+ legacy.register(SESSION_GROUPS_NAMESPACE, SessionGroupsSchema);
1783
1806
  }
1784
1807
  });
1785
1808
  return () => {
@@ -1789,8 +1812,144 @@ var hostPatch8 = {
1789
1812
  routes: ({ ctx }) => ({ prepare: (payload) => prepareTask(payload), move: (payload) => moveSessionGroup(ctx, payload) })
1790
1813
  };
1791
1814
 
1815
+ // src/patches/terminal-clipboard/shared.ts
1816
+ var TERMINAL_CLIPBOARD_PATCH_ID = "terminal-clipboard";
1817
+
1818
+ // src/patches/terminal-clipboard/host/index.ts
1819
+ var hostPatch9 = {
1820
+ id: TERMINAL_CLIPBOARD_PATCH_ID,
1821
+ routes: () => ({ status: () => ({ available: true }) })
1822
+ };
1823
+
1824
+ // src/patches/terminal-host-stats/shared.ts
1825
+ var TERMINAL_HOST_STATS_ID = "terminal-host-stats";
1826
+
1827
+ // src/patches/terminal-host-stats/host/sample.ts
1828
+ import { statfs } from "node:fs/promises";
1829
+ import { cpus, freemem, homedir as homedir2, totalmem } from "node:os";
1830
+
1831
+ // src/patches/terminal-host-stats/host/disks.ts
1832
+ import { execFile } from "node:child_process";
1833
+ import { readdir, readFile } from "node:fs/promises";
1834
+ import { join as join2 } from "node:path";
1835
+ import { promisify } from "node:util";
1836
+ var run = promisify(execFile);
1837
+ var options = { timeout: 4e3, maxBuffer: 1024 * 1024, windowsHide: true };
1838
+ function linuxCounters(source, wholeDisks) {
1839
+ const disks = /* @__PURE__ */ new Map();
1840
+ for (const line of source.trim().split("\n")) {
1841
+ const fields = line.trim().split(/\s+/);
1842
+ const name2 = fields[2];
1843
+ if (!name2 || !wholeDisks.has(name2) || /^(?:loop|ram|zram|dm-|md\d)/.test(name2)) continue;
1844
+ const read2 = Number(fields[5]) * 512;
1845
+ const write2 = Number(fields[9]) * 512;
1846
+ if (Number.isSafeInteger(read2) && read2 >= 0 && Number.isSafeInteger(write2) && write2 >= 0) disks.set(name2, { read: read2, write: write2 });
1847
+ }
1848
+ return disks;
1849
+ }
1850
+ function macCounters(source) {
1851
+ const disks = /* @__PURE__ */ new Map();
1852
+ for (const block of source.split(/(?=^\+-o )/m)) {
1853
+ const id = block.match(/^\+-o .*?\bid (0x[\da-f]+)/i)?.[1];
1854
+ const stats = block.match(/"Statistics"\s*=\s*\{([^}\n]*)\}/)?.[1];
1855
+ if (!id || !stats) continue;
1856
+ const read2 = stats.match(/"Bytes \(Read\)"\s*=\s*(\d+)/)?.[1];
1857
+ const write2 = stats.match(/"Bytes \(Write\)"\s*=\s*(\d+)/)?.[1];
1858
+ if (read2 && write2) disks.set(id, { read: Number(read2), write: Number(write2) });
1859
+ }
1860
+ return disks;
1861
+ }
1862
+ function windowsCounters(source) {
1863
+ const disks = /* @__PURE__ */ new Map();
1864
+ for (const line of source.trim().split(/\r?\n/)) {
1865
+ const match = /^(\d+)(?:\s[^|]*)?\|(\d+)\|(\d+)$/.exec(line.trim());
1866
+ if (match) disks.set(match[1], { read: Number(match[2]), write: Number(match[3]) });
1867
+ }
1868
+ return disks;
1869
+ }
1870
+ async function readDiskCounters() {
1871
+ if (process.platform === "linux") {
1872
+ const [devices, stats] = await Promise.all([readdir("/sys/block"), readFile("/proc/diskstats", "utf8")]);
1873
+ return linuxCounters(stats, new Set(devices));
1874
+ }
1875
+ if (process.platform === "darwin") {
1876
+ const { stdout } = await run("/usr/sbin/ioreg", ["-r", "-c", "IOBlockStorageDriver", "-d", "1", "-w", "0"], options);
1877
+ return macCounters(stdout);
1878
+ }
1879
+ if (process.platform === "win32" && process.env.SystemRoot) {
1880
+ const powershell = join2(process.env.SystemRoot, "System32/WindowsPowerShell/v1.0/powershell.exe");
1881
+ const script = "Get-CimInstance Win32_PerfRawData_PerfDisk_PhysicalDisk | ForEach-Object { '{0}|{1}|{2}' -f $_.Name,$_.DiskReadBytesPersec,$_.DiskWriteBytesPersec }";
1882
+ const { stdout } = await run(powershell, ["-NoProfile", "-NonInteractive", "-Command", script], options);
1883
+ return windowsCounters(stdout);
1884
+ }
1885
+ return /* @__PURE__ */ new Map();
1886
+ }
1887
+
1888
+ // src/patches/terminal-host-stats/host/sample.ts
1889
+ async function readHost() {
1890
+ const [disk, counters] = await Promise.all([
1891
+ statfs(homedir2()).then(({ bavail, blocks, bsize }) => blocks > 0 && bavail >= 0 ? { available: bavail * bsize, total: blocks * bsize } : null).catch(() => null),
1892
+ readDiskCounters().catch(() => /* @__PURE__ */ new Map())
1893
+ ]);
1894
+ const cores = cpus();
1895
+ const cpu = { count: cores.length, idle: 0, total: 0 };
1896
+ for (const { times } of cores) {
1897
+ cpu.idle += times.idle;
1898
+ cpu.total += times.user + times.nice + times.sys + times.idle + times.irq;
1899
+ }
1900
+ const total = totalmem();
1901
+ const memory = total > 0 ? { used: total - freemem(), total } : null;
1902
+ return { at: performance.now(), cpu, memory, disk, counters };
1903
+ }
1904
+ function diskRate(before, after, seconds) {
1905
+ let matched = false;
1906
+ let read2 = 0;
1907
+ let write2 = 0;
1908
+ for (const [id, now] of after) {
1909
+ const prev = before.get(id);
1910
+ if (!prev || now.read < prev.read || now.write < prev.write) continue;
1911
+ read2 += now.read - prev.read;
1912
+ write2 += now.write - prev.write;
1913
+ matched = true;
1914
+ }
1915
+ return matched ? { read: read2 / seconds, write: write2 / seconds } : null;
1916
+ }
1917
+ function createSampler(collect = readHost) {
1918
+ let previous;
1919
+ let cached;
1920
+ let pending;
1921
+ const sample = async () => {
1922
+ const now = await collect();
1923
+ const result = { cpuPercent: null, memory: now.memory, disk: now.disk, io: null };
1924
+ const elapsed = now.at - (previous?.at ?? now.at);
1925
+ if (previous && elapsed > 0 && elapsed <= 15e3) {
1926
+ const total = now.cpu.total - previous.cpu.total;
1927
+ const idle = now.cpu.idle - previous.cpu.idle;
1928
+ if (now.cpu.count === previous.cpu.count && total > 0 && idle >= 0 && idle <= total) {
1929
+ result.cpuPercent = Math.round(100 * (1 - idle / total));
1930
+ }
1931
+ result.io = diskRate(previous.counters, now.counters, elapsed / 1e3);
1932
+ }
1933
+ previous = now;
1934
+ cached = result;
1935
+ return result;
1936
+ };
1937
+ return () => {
1938
+ if (previous && cached && performance.now() - previous.at < 1e3) return Promise.resolve(cached);
1939
+ return pending ??= sample().finally(() => {
1940
+ pending = void 0;
1941
+ });
1942
+ };
1943
+ }
1944
+
1945
+ // src/patches/terminal-host-stats/host/index.ts
1946
+ var hostPatch10 = {
1947
+ id: TERMINAL_HOST_STATS_ID,
1948
+ routes: () => ({ sample: createSampler() })
1949
+ };
1950
+
1792
1951
  // src/generated/host-registry.ts
1793
- var HOST_PATCHES = [hostPatch, hostPatch2, hostPatch3, hostPatch4, hostPatch5, hostPatch6, hostPatch7, hostPatch8];
1952
+ var HOST_PATCHES = [hostPatch, hostPatch2, hostPatch3, hostPatch4, hostPatch5, hostPatch6, hostPatch7, hostPatch8, hostPatch9, hostPatch10];
1794
1953
 
1795
1954
  // src/generated/patch-catalog.ts
1796
1955
  var PATCH_CATALOG = [
@@ -1801,7 +1960,9 @@ var PATCH_CATALOG = [
1801
1960
  { "id": "model-capabilities", "name": "\u6A21\u578B\u80FD\u529B\u914D\u7F6E", "description": "\u5728\u6A21\u578B\u914D\u7F6E\u9875\u8BBE\u7F6E\u6BCF\u4E2A\u6A21\u578B\u7684\u8BC6\u56FE\u80FD\u529B\u3001\u53EF\u9009\u601D\u8003\u7C7B\u578B\u4E0E\u601D\u8003\u53C2\u6570\u683C\u5F0F", "defaultEnabled": true, "order": 500, "clientKind": "standalone" },
1802
1961
  { "id": "fast-mode", "name": "\u52A0\u901F", "description": "\u5728\u8F93\u5165\u6846\u548C /fast \u547D\u4EE4\u4E2D\u5F00\u5173\u52A0\u901F\u3002\u54CD\u5E94\u66F4\u5FEB\uFF0C\u4F46\u4F1A\u66F4\u5FEB\u6D88\u8017\u989D\u5EA6", "defaultEnabled": true, "order": 550, "clientKind": "standalone" },
1803
1962
  { "id": "session-auto-title", "name": "\u4F1A\u8BDD\u81EA\u52A8\u547D\u540D", "description": "\u65B0\u4F1A\u8BDD\u9996\u6761\u9700\u6C42\u540E\uFF0C\u4F7F\u7528\u5F53\u524D\u6A21\u578B\u751F\u6210\u300C\u7C7B\u578B \xB7 \u5177\u4F53\u4EFB\u52A1\u300D\u6807\u9898\uFF1B\u4FDD\u7559\u624B\u52A8\u547D\u540D\uFF0C\u5931\u8D25\u65F6\u4FDD\u7559\u539F\u6709\u6807\u9898", "defaultEnabled": true, "order": 600, "clientKind": "standalone" },
1804
- { "id": "projectless-tasks", "name": "\u72EC\u7ACB\u4EFB\u52A1", "description": "\u5728\u5DE5\u4F5C\u533A\u4E0B\u62C9\u6846\u521B\u5EFA\u72EC\u7ACB\u4EFB\u52A1\u5E76\u4FDD\u7559\u8349\u7A3F\uFF0C\u4E5F\u53EF\u5C06\u672A\u5206\u7EC4\u4F1A\u8BDD\u79FB\u5165\u5DE5\u4F5C\u533A\u5217\u8868", "defaultEnabled": true, "order": 700, "clientKind": "standalone" }
1963
+ { "id": "projectless-tasks", "name": "\u72EC\u7ACB\u4EFB\u52A1", "description": "\u5728\u5DE5\u4F5C\u533A\u4E0B\u62C9\u6846\u521B\u5EFA\u72EC\u7ACB\u4EFB\u52A1\u5E76\u4FDD\u7559\u8349\u7A3F\uFF0C\u4E5F\u53EF\u5C06\u672A\u5206\u7EC4\u4F1A\u8BDD\u79FB\u5165\u5DE5\u4F5C\u533A\u5217\u8868", "defaultEnabled": true, "order": 700, "clientKind": "standalone" },
1964
+ { "id": "terminal-clipboard", "name": "\u7EC8\u7AEF\u590D\u5236\u7C98\u8D34", "description": "\u53F3\u4FA7\u7EC8\u7AEF\u9009\u4E2D\u81EA\u52A8\u590D\u5236\u3002Ctrl+C \u590D\u5236\u9009\u533A\uFF0C\u65E0\u9009\u533A\u65F6\u4E2D\u65AD\u547D\u4EE4\u3002Ctrl+V \u6216\u53F3\u952E\u7C98\u8D34\u7EAF\u6587\u672C\uFF0C\u81EA\u52A8\u6E05\u9664\u7EC8\u7AEF\u989C\u8272\u63A7\u5236\u7801\u3002", "defaultEnabled": true, "order": 800, "clientKind": "standalone" },
1965
+ { "id": "terminal-host-stats", "name": "\u7EC8\u7AEF\u4E3B\u673A\u72B6\u6001", "description": "\u5728\u53F3\u4FA7\u7EC8\u7AEF\u9876\u90E8\u663E\u793A\u4E3B\u673A CPU\u3001\u5185\u5B58\u3001\u78C1\u76D8\u53EF\u7528\u7A7A\u95F4\u548C\u5B9E\u65F6\u8BFB\u5199\u901F\u7387", "defaultEnabled": true, "order": 810, "clientKind": "standalone" }
1805
1966
  ];
1806
1967
  var DEFAULT_PATCH_SETTINGS = {
1807
1968
  "message-edit": true,
@@ -1811,7 +1972,9 @@ var DEFAULT_PATCH_SETTINGS = {
1811
1972
  "model-capabilities": true,
1812
1973
  "fast-mode": true,
1813
1974
  "session-auto-title": true,
1814
- "projectless-tasks": true
1975
+ "projectless-tasks": true,
1976
+ "terminal-clipboard": true,
1977
+ "terminal-host-stats": true
1815
1978
  };
1816
1979
  function decodePatchSettings(value) {
1817
1980
  if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
@@ -1887,40 +2050,43 @@ var HostPatchActivation = class {
1887
2050
  };
1888
2051
 
1889
2052
  // src/kernel/host/settings.ts
1890
- import z4 from "@deepseek-ai/schemastery";
2053
+ import z5 from "@deepseek-ai/schemastery";
1891
2054
 
1892
2055
  // src/generated/host-settings-schema.ts
1893
- import z3 from "@deepseek-ai/schemastery";
1894
- var PatchSettingsSchema = z3.object({
1895
- "message-edit": z3.boolean().default(true),
1896
- "message-delete": z3.boolean().default(true),
1897
- "session-delete": z3.boolean().default(true),
1898
- "conversation-markdown-export": z3.boolean().default(true),
1899
- "model-capabilities": z3.boolean().default(true),
1900
- "fast-mode": z3.boolean().default(true),
1901
- "session-auto-title": z3.boolean().default(true),
1902
- "projectless-tasks": z3.boolean().default(true)
2056
+ import z4 from "@deepseek-ai/schemastery";
2057
+ var PatchSettingsSchema = z4.object({
2058
+ "message-edit": z4.boolean().default(true),
2059
+ "message-delete": z4.boolean().default(true),
2060
+ "session-delete": z4.boolean().default(true),
2061
+ "conversation-markdown-export": z4.boolean().default(true),
2062
+ "model-capabilities": z4.boolean().default(true),
2063
+ "fast-mode": z4.boolean().default(true),
2064
+ "session-auto-title": z4.boolean().default(true),
2065
+ "projectless-tasks": z4.boolean().default(true),
2066
+ "terminal-clipboard": z4.boolean().default(true),
2067
+ "terminal-host-stats": z4.boolean().default(true)
1903
2068
  });
1904
2069
 
1905
2070
  // src/kernel/host/settings.ts
1906
2071
  var PATCH_SETTINGS_NAMESPACE2 = PATCH_SETTINGS_NAMESPACE;
1907
- var PatchConfig = z4.object(Object.fromEntries(
2072
+ var PatchConfig = z5.object(Object.fromEntries(
1908
2073
  Object.entries(PatchSettingsSchema.dict ?? {}).map(([key, schema2]) => [key, liveSetting(schema2)])
1909
2074
  ));
1910
2075
  function installPatchSettings(ctx, activation, config = DEFAULT_PATCH_SETTINGS) {
1911
- if (typeof ctx.settings.installSection !== "function") {
2076
+ const settings = ctx.settings;
2077
+ if (typeof settings.installSection !== "function") {
1912
2078
  const refresh = () => {
1913
2079
  const values = typeof config === "object" && config !== null ? Object.fromEntries(Object.entries(config).map(([key, value]) => [key, settingValue(value)])) : config;
1914
- const settings = decodePatchSettings(values);
1915
- if (settings === void 0) throw new TypeError("Invalid DSH More patch configuration");
1916
- activation.apply(settings);
2080
+ const settings2 = decodePatchSettings(values);
2081
+ if (settings2 === void 0) throw new TypeError("Invalid DSH More patch configuration");
2082
+ activation.apply(settings2);
1917
2083
  };
1918
2084
  ctx.on("loader/volatile-update", refresh);
1919
2085
  refresh();
1920
2086
  return;
1921
2087
  }
1922
2088
  let source = () => DEFAULT_PATCH_SETTINGS;
1923
- ctx.settings.installSection(ctx, PATCH_SETTINGS_NAMESPACE2, PatchSettingsSchema, DEFAULT_PATCH_SETTINGS, {
2089
+ settings.installSection(ctx, PATCH_SETTINGS_NAMESPACE2, PatchSettingsSchema, DEFAULT_PATCH_SETTINGS, {
1924
2090
  setSource: (next) => {
1925
2091
  source = next;
1926
2092
  },
@@ -2068,7 +2234,6 @@ function registerPatchApi(ctx, patches, confirmationSecret, isEnabled) {
2068
2234
  var name = PLUGIN_NAME;
2069
2235
  var inject = [
2070
2236
  "webServer",
2071
- "webRuntime",
2072
2237
  "agents",
2073
2238
  "sessions",
2074
2239
  "connection",
@@ -1,20 +1,24 @@
1
1
  import z from '@deepseek-ai/schemastery';
2
- export declare const PatchSettingsSchema: z<Schemastery.ObjectS<{
3
- "message-edit": z<boolean, boolean>;
4
- "message-delete": z<boolean, boolean>;
5
- "session-delete": z<boolean, boolean>;
6
- "conversation-markdown-export": z<boolean, boolean>;
7
- "model-capabilities": z<boolean, boolean>;
8
- "fast-mode": z<boolean, boolean>;
9
- "session-auto-title": z<boolean, boolean>;
10
- "projectless-tasks": z<boolean, boolean>;
11
- }>, Schemastery.ObjectT<{
12
- "message-edit": z<boolean, boolean>;
13
- "message-delete": z<boolean, boolean>;
14
- "session-delete": z<boolean, boolean>;
15
- "conversation-markdown-export": z<boolean, boolean>;
16
- "model-capabilities": z<boolean, boolean>;
17
- "fast-mode": z<boolean, boolean>;
18
- "session-auto-title": z<boolean, boolean>;
19
- "projectless-tasks": z<boolean, boolean>;
20
- }>>;
2
+ export declare const PatchSettingsSchema: z<Schemastery.ObjectS<NoInfer<{
3
+ "message-edit": z<boolean, boolean, "defined">;
4
+ "message-delete": z<boolean, boolean, "defined">;
5
+ "session-delete": z<boolean, boolean, "defined">;
6
+ "conversation-markdown-export": z<boolean, boolean, "defined">;
7
+ "model-capabilities": z<boolean, boolean, "defined">;
8
+ "fast-mode": z<boolean, boolean, "defined">;
9
+ "session-auto-title": z<boolean, boolean, "defined">;
10
+ "projectless-tasks": z<boolean, boolean, "defined">;
11
+ "terminal-clipboard": z<boolean, boolean, "defined">;
12
+ "terminal-host-stats": z<boolean, boolean, "defined">;
13
+ }>>, Schemastery.ObjectT<NoInfer<{
14
+ "message-edit": z<boolean, boolean, "defined">;
15
+ "message-delete": z<boolean, boolean, "defined">;
16
+ "session-delete": z<boolean, boolean, "defined">;
17
+ "conversation-markdown-export": z<boolean, boolean, "defined">;
18
+ "model-capabilities": z<boolean, boolean, "defined">;
19
+ "fast-mode": z<boolean, boolean, "defined">;
20
+ "session-auto-title": z<boolean, boolean, "defined">;
21
+ "projectless-tasks": z<boolean, boolean, "defined">;
22
+ "terminal-clipboard": z<boolean, boolean, "defined">;
23
+ "terminal-host-stats": z<boolean, boolean, "defined">;
24
+ }>>, "plain">;
@@ -54,6 +54,20 @@ export declare const PATCH_CATALOG: readonly [{
54
54
  readonly defaultEnabled: true;
55
55
  readonly order: 700;
56
56
  readonly clientKind: "standalone";
57
+ }, {
58
+ readonly id: "terminal-clipboard";
59
+ readonly name: "终端复制粘贴";
60
+ readonly description: "右侧终端选中自动复制。Ctrl+C 复制选区,无选区时中断命令。Ctrl+V 或右键粘贴纯文本,自动清除终端颜色控制码。";
61
+ readonly defaultEnabled: true;
62
+ readonly order: 800;
63
+ readonly clientKind: "standalone";
64
+ }, {
65
+ readonly id: "terminal-host-stats";
66
+ readonly name: "终端主机状态";
67
+ readonly description: "在右侧终端顶部显示主机 CPU、内存、磁盘可用空间和实时读写速率";
68
+ readonly defaultEnabled: true;
69
+ readonly order: 810;
70
+ readonly clientKind: "standalone";
57
71
  }];
58
72
  export type PatchId = typeof PATCH_CATALOG[number]['id'];
59
73
  export interface PatchSettings {
@@ -65,6 +79,8 @@ export interface PatchSettings {
65
79
  "fast-mode": boolean;
66
80
  "session-auto-title": boolean;
67
81
  "projectless-tasks": boolean;
82
+ "terminal-clipboard": boolean;
83
+ "terminal-host-stats": boolean;
68
84
  }
69
85
  export declare const DEFAULT_PATCH_SETTINGS: PatchSettings;
70
86
  export declare function decodePatchSettings(value: unknown): PatchSettings | undefined;
@@ -1,5 +1,5 @@
1
- import type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client';
2
- import type { SettingsScopeSnapshot } from '@deepseek-ai/dsh-client-ui-settings/client';
1
+ import type { SettingsScope } from '../../platform/dsh/client/settings.js';
2
+ import type { SettingsScopeSnapshot } from '../../platform/dsh/client/settings.js';
3
3
  import { type PatchId, type PatchSettings } from '../../generated/patch-catalog.js';
4
4
  export interface PatchActivationSource {
5
5
  getSnapshot(): PatchSettings;
@@ -1,11 +1,15 @@
1
1
  import type { Context } from '@deepseek-ai/cordis';
2
2
  import z from '@deepseek-ai/schemastery';
3
3
  import type { HostPatchActivation } from './activation.js';
4
+ export type LegacyInstallSection = <T>(ctx: Context, namespace: string, schema: z<T>, defaults: T, hooks: {
5
+ setSource(source: () => T): void;
6
+ onChange(): void;
7
+ }) => void;
4
8
  export declare const PATCH_SETTINGS_NAMESPACE = "dsh-more";
5
- export declare const PatchConfig: z<Schemastery.ObjectS<{
9
+ export declare const PatchConfig: z<Schemastery.ObjectS<NoInfer<{
6
10
  [k: string]: z<any>;
7
- }>, Schemastery.ObjectT<{
11
+ }>>, Schemastery.ObjectT<NoInfer<{
8
12
  [k: string]: z<any>;
9
- }>>;
13
+ }>>, "plain">;
10
14
  /** Bind persisted DSH settings to live Host patch activation. */
11
15
  export declare function installPatchSettings(ctx: Context, activation: HostPatchActivation, config?: unknown): void;
@@ -0,0 +1,6 @@
1
+ import z from '@deepseek-ai/schemastery';
2
+ import { type FastModeSettings } from '../shared.js';
3
+ /** Companion entry projects the existing namespace into the host's settings forms. */
4
+ export declare const Config: z<FastModeSettings>;
5
+ /** The host owns persistence; the fast-mode patch consumes the live descriptor. */
6
+ export declare function apply(): void;
@@ -1,4 +1,4 @@
1
- import type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client';
1
+ import type { SettingsScope } from '../../../platform/dsh/client/settings.js';
2
2
  export type {} from '@deepseek-ai/dsh-client-ui-settings';
3
3
  import type { PatchActivationSource } from '../../../kernel/client/activation.js';
4
4
  import type { ClientPatch } from '../../../kernel/client/patch.js';
@@ -4,7 +4,7 @@ import type { SessionId } from '@deepseek-ai/dsh-session/types';
4
4
  import type { SessionListState } from '@deepseek-ai/dsh-api-session-controller/client';
5
5
  import type { WorkspaceSnapshot } from '@deepseek-ai/dsh-api-workspace-controller/client';
6
6
  import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
7
- import type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client';
7
+ import type { SettingsScope } from '../../../platform/dsh/client/settings.js';
8
8
  import type { PatchActivationSource } from '../../../kernel/client/activation.js';
9
9
  import { type SessionGroups } from '../groups.js';
10
10
  /** Only the sidebar receives grouping metadata; execution and workspace selection use native cwd. */
@@ -0,0 +1,5 @@
1
+ import { type TerminalHandle } from './terminal.js';
2
+ type Resolve = (root: HTMLElement) => TerminalHandle | undefined;
3
+ /** Delegation handles terminal tabs/remounts without a global MutationObserver. */
4
+ export declare function installTerminalClipboard(doc: Document, resolve?: Resolve): () => void;
5
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { ClientPatch } from '../../../kernel/client/patch.js';
2
+ export declare const clientPatch: ClientPatch;