dsh-usage-state 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.en.md CHANGED
@@ -101,6 +101,7 @@ Expanding **Advanced** lets you override the source and endpoint, name a credent
101
101
 
102
102
  - **0.2 line only**: `engines.dsh` = `>=0.2.0-rc.2 <0.3.0-0` (this is what dsh-market's badge and install gate read). On an earlier host, install `0.3.2`.
103
103
  - `peerDependencies` carry `@deepseek-ai/dsh-settings` (`^0.2.0-rc.2`) and `@deepseek-ai/schemastery` (`^3.18.2`). The first one is deliberate: the runtime install gate only reads `@deepseek-ai/dsh*` peers, so declaring it makes a 0.1.x host **refuse the install** instead of accepting it and then failing to boot. Both are platform-provided; pnpm may print a `missing peer` warning for them, which is expected.
104
+ - Version `0.4.1` fixes `0.4.0`'s missing readings: the browser half's RPC contribution lacked the `create()` factory 0.2 requires, so `remote.usageState` never mounted — the UI showed **no readings at all** and mislabelled the cause as `Mode not supported`. The same release stops swallowing a rejected mount, says "reading" while the catalog is absent, and adds **real 0.2 registry contract tests** (revision 18). **Use `0.4.1`, not `0.4.0`.**
104
105
  - Version `0.4.0` migrates to the 0.2 settings model (`Config` + `configForms`, with cross-entry config read through `configEditor`). Verification and results: [`docs/implementation.md`](docs/implementation.md) §10; rationale: [`docs/design-consensus.md`](docs/design-consensus.md) revision 17.
105
106
  - Version `0.3.2` (last of the 0.1 line) only widened `engines.dsh`; **its claimed 0.2 compatibility was wrong** — on `0.2.0-rc.2` it fails the entire web boot because `settingsScope` does not exist there.
106
107
  - Published to npm as [`dsh-usage-state`](https://www.npmjs.com/package/dsh-usage-state); GitHub installs work too.
package/README.md CHANGED
@@ -125,6 +125,7 @@ dsh plugin --profile web add /path/to/dsh-usage-state
125
125
 
126
126
  - **只支持 DSH 0.2 线**:`engines.dsh` = `>=0.2.0-rc.2 <0.3.0-0`(市场读它做徽标与"可安装"判定)。0.2 之前的宿主请装 `0.3.2`。
127
127
  - `peerDependencies` 里有 `@deepseek-ai/dsh-settings`(`^0.2.0-rc.2`)与 `@deepseek-ai/schemastery`(`^3.18.2`):前者是**故意的**——平台的运行时安装闸门只读 `@deepseek-ai/dsh*` 的 peer,声明它可以让 0.1.x 宿主在**安装时**就拒绝,而不是装上之后把启动搞崩;两者都由平台提供,pnpm 可能为此打一行 `missing peer` 警告,属预期。
128
+ - 版本 `0.4.1`:修 `0.4.0` 的读数缺失——客户端 RPC contribution 的参数 codec 少了 0.2 要求的 `create()`,`remote.usageState` 因此从未挂载,界面表现为**没有任何读数**并误报 `Mode not supported`。同一轮还让挂载失败不再被静默吞掉、catalog 未到时改说「读取中」,并把**真实 0.2 registry 契约测试**写进单测(修订 18)。**请用 `0.4.1`,不要用 `0.4.0`。**
128
129
  - 版本 `0.4.0`:迁到 0.2 原生设置模型(`Config` + `configForms`,宿主侧 `configEditor` 读跨条目配置)。验证方式与结论见 [`docs/implementation.md`](docs/implementation.md) §10、决策见 [`docs/design-consensus.md`](docs/design-consensus.md) 修订 17。
129
130
  - 版本 `0.3.2`(0.1 线末版):仅放宽 `engines.dsh`;**它声称的 0.2 兼容是错的**(0.3.2 在 0.2.0-rc.2 上会因 `settingsScope` 不存在而让整个 web 启动失败)。
130
131
  - 同名发布在 npm([`dsh-usage-state`](https://www.npmjs.com/package/dsh-usage-state)),也可从 GitHub 直接安装。
package/lib/client.js CHANGED
@@ -7,6 +7,47 @@ window.__ModuleLoader__.load({
7
7
  let react = require("react");
8
8
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
9
9
  let react_jsx_runtime = require("react/jsx-runtime");
10
+ //#region src/client/contribution.ts
11
+ /** Absent or boolean — the one parameter this plugin's RPC takes. */
12
+ const forceSchema = { parse: (value) => value === void 0 ? void 0 : value === true };
13
+ /**
14
+ * A strict codec built without zod: `schema` is what the wire decodes through, and
15
+ * `create()` is the factory the platform's registry calls to obtain it.
16
+ */
17
+ const booleanOrUndefined = {
18
+ mode: "strict",
19
+ typeSymbol: "dsh-usage-state#Force",
20
+ create: () => forceSchema
21
+ };
22
+ const srcJson = { mode: "src-json" };
23
+ /** Must mirror `src/host/typert.ts`: the wire endpoint is `<namespace>/<method>`. */
24
+ const CONTRIBUTION = {
25
+ package: "dsh-usage-state",
26
+ descriptors: [{
27
+ id: "dsh-usage-state#usageState/getState",
28
+ service: "usageState",
29
+ namespace: "usageState",
30
+ method: "getState",
31
+ invocation: { kind: "direct" },
32
+ parameters: [{
33
+ name: "force",
34
+ wire: "force",
35
+ source: "json",
36
+ acceptsUndefined: true,
37
+ codec: booleanOrUndefined
38
+ }],
39
+ result: srcJson
40
+ }, {
41
+ id: "dsh-usage-state#usageState/describeCredentials",
42
+ service: "usageState",
43
+ namespace: "usageState",
44
+ method: "describeCredentials",
45
+ invocation: { kind: "direct" },
46
+ parameters: [],
47
+ result: srcJson
48
+ }]
49
+ };
50
+ //#endregion
10
51
  //#region src/shared/config.ts
11
52
  const DEFAULT_CONFIG = {
12
53
  models: [],
@@ -1067,6 +1108,10 @@ window.__ModuleLoader__.load({
1067
1108
  function describeStatus(input) {
1068
1109
  const { status, snapshot, display, now } = input;
1069
1110
  if (status.kind === "hidden") return [];
1111
+ if (status.kind === "loading") return [{
1112
+ kind: "state",
1113
+ state: "loading"
1114
+ }];
1070
1115
  if (status.kind === "unconfigured") return [{
1071
1116
  kind: "state",
1072
1117
  state: "unconfigured"
@@ -1287,12 +1332,15 @@ window.__ModuleLoader__.load({
1287
1332
  }
1288
1333
  }
1289
1334
  /** Map a provider resolution onto what the line can say about it. */
1290
- function statusOf(resolution) {
1335
+ function statusOf(resolution, catalogEmpty) {
1291
1336
  switch (resolution.reason) {
1292
1337
  case "hidden": return { kind: "hidden" };
1293
1338
  case "needs-endpoint": return { kind: "needs-endpoint" };
1294
1339
  case "unknown-source":
1295
- case "unsupported": return resolution.sourceId === null ? { kind: "unconfigured" } : { kind: "unsupported" };
1340
+ case "unsupported":
1341
+ if (resolution.sourceId === null) return { kind: "unconfigured" };
1342
+ if (catalogEmpty) return { kind: "loading" };
1343
+ return { kind: "unsupported" };
1296
1344
  case "auto":
1297
1345
  case "configured":
1298
1346
  if (resolution.key === void 0 || resolution.sourceId === null || resolution.mode === null) return { kind: "unconfigured" };
@@ -1323,11 +1371,15 @@ window.__ModuleLoader__.load({
1323
1371
  provider: current.provider,
1324
1372
  config,
1325
1373
  catalog: state.catalog
1326
- }));
1374
+ }), state.catalog.length === 0);
1327
1375
  const snapshot = status.kind === "ready" ? state.snapshots[status.key] : void 0;
1328
1376
  const sourceLabel = status.kind === "ready" ? state.catalog.find((entry) => entry.id === status.sourceId)?.displayName ?? status.sourceId : "";
1329
1377
  const fullParts = statusParts({
1330
- segments: describeStatus({
1378
+ segments: state.catalog.length === 0 && state.status === "error" && state.error !== void 0 ? [{
1379
+ kind: "state",
1380
+ state: "error",
1381
+ errorDetail: state.error
1382
+ }] : describeStatus({
1331
1383
  sourceLabel,
1332
1384
  status,
1333
1385
  snapshot,
@@ -1722,6 +1774,21 @@ window.__ModuleLoader__.load({
1722
1774
  this.publish({ credentialsError: messageOf(error) });
1723
1775
  }
1724
1776
  }
1777
+ /**
1778
+ * Record that the RPC contribution never mounted.
1779
+ *
1780
+ * Without this the only symptom is an empty catalog, which every surface reads
1781
+ * as "nothing configured yet" — the real cause has to be nameable, because it is
1782
+ * a plugin/host contract failure, not something the user can configure away.
1783
+ */
1784
+ failRemote(message) {
1785
+ this.publish({
1786
+ status: "error",
1787
+ error: message,
1788
+ catalog: [],
1789
+ snapshots: {}
1790
+ });
1791
+ }
1725
1792
  };
1726
1793
  //#endregion
1727
1794
  //#region src/client/index.tsx
@@ -1735,40 +1802,6 @@ window.__ModuleLoader__.load({
1735
1802
  ];
1736
1803
  const USAGE_STATE_NS = "usage-state";
1737
1804
  const POLL_INTERVAL_MS = 3e4;
1738
- /** Hand-rolled codecs: the browser bundle must not carry zod. */
1739
- const booleanOrUndefined = {
1740
- mode: "strict",
1741
- typeSymbol: "dsh-usage-state#Force",
1742
- schema: { parse: (value) => value === void 0 ? void 0 : value === true }
1743
- };
1744
- const srcJson = { mode: "src-json" };
1745
- /** Must mirror `src/host/typert.ts`: the wire endpoint is `<namespace>/<method>`. */
1746
- const CONTRIBUTION = {
1747
- package: "dsh-usage-state",
1748
- descriptors: [{
1749
- id: "dsh-usage-state#usageState/getState",
1750
- service: "usageState",
1751
- namespace: "usageState",
1752
- method: "getState",
1753
- invocation: { kind: "direct" },
1754
- parameters: [{
1755
- name: "force",
1756
- wire: "force",
1757
- source: "json",
1758
- acceptsUndefined: true,
1759
- codec: booleanOrUndefined
1760
- }],
1761
- result: srcJson
1762
- }, {
1763
- id: "dsh-usage-state#usageState/describeCredentials",
1764
- service: "usageState",
1765
- namespace: "usageState",
1766
- method: "describeCredentials",
1767
- invocation: { kind: "direct" },
1768
- parameters: [],
1769
- result: srcJson
1770
- }]
1771
- };
1772
1805
  function apply(ctx) {
1773
1806
  ctx.effect(() => ctx.locale.register(LOCALE_NS, {
1774
1807
  zh,
@@ -1815,7 +1848,11 @@ window.__ModuleLoader__.load({
1815
1848
  store.refresh(false);
1816
1849
  store.refreshModels();
1817
1850
  store.refreshCredentials();
1818
- }, () => void 0);
1851
+ }, (error) => {
1852
+ const message = error instanceof Error ? error.message : String(error);
1853
+ console.error("dsh-usage-state: remote contribution did not mount", error);
1854
+ store.failRemote(message);
1855
+ });
1819
1856
  return () => {
1820
1857
  cancelled = true;
1821
1858
  dispose?.();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-usage-state",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "type": "module",
5
5
  "description": "DSH plugin: show account balance (API mode) or coding-plan quota (5h/7d/30d) for the model in use",
6
6
  "license": "MIT",
@@ -28,12 +28,14 @@
28
28
  "./package.json": "./package.json"
29
29
  },
30
30
  "devDependencies": {
31
+ "@deepseek-ai/cordis": "^4.0.4",
31
32
  "@deepseek-ai/dsh-client-locale": "^0.2.0-rc.2",
32
33
  "@deepseek-ai/dsh-client-store": "^0.2.0-rc.2",
33
34
  "@deepseek-ai/dsh-client-ui-conversation": "^0.2.0-rc.2",
34
35
  "@deepseek-ai/dsh-client-ui-primitives": "^0.2.0-rc.2",
35
36
  "@deepseek-ai/dsh-client-ui-slots": "^0.2.0-rc.2",
36
37
  "@deepseek-ai/dsh-typert-loader": "^0.2.0-rc.2",
38
+ "@deepseek-ai/dsh-typert-registry": "^0.2.0-rc.2",
37
39
  "@deepseek-ai/schemastery": "^3.18.2",
38
40
  "@types/node": "^24.0.0",
39
41
  "@types/react": "~18.3.1",