dsh-codex-subscription 2.2.3 → 2.2.4

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 (3) hide show
  1. package/lib/client.js +169 -20
  2. package/lib/index.js +52 -8
  3. package/package.json +1 -1
package/lib/client.js CHANGED
@@ -3298,7 +3298,7 @@ window.__ModuleLoader__.load({
3298
3298
  const expire = () => {
3299
3299
  clear();
3300
3300
  generation++;
3301
- if (state !== "stopped") update("failed");
3301
+ if (state === "drawing") update("failed");
3302
3302
  };
3303
3303
  return {
3304
3304
  get state() {
@@ -4627,19 +4627,37 @@ window.__ModuleLoader__.load({
4627
4627
  //#endregion
4628
4628
  //#region src/client-locales.js
4629
4629
  const zh = {
4630
+ "diagnosticsSnapshotTime": "报告快照时间:",
4631
+ "diagnosticsUnresolved": "仍有其他未恢复的失败记录,见上方摘要。",
4632
+ "diagnosticSeverity_warning": "需关注",
4633
+ "diagnosticSeverity_info": "信息",
4634
+ "diagnosticNext_restart": "重启后重新生成报告;若版本仍不一致,检查插件更新是否生效。",
4635
+ "diagnosticNext_regenerate": "复现问题后立即重新生成报告;若仍不完整,连同操作步骤反馈。",
4636
+ "diagnosticNext_supported-options": "继续使用当前可选档位即可;新增能力需要适配验证,不建议手动填入未知参数。",
4637
+ "diagnosticNext_reproduce": "核对下列操作与时间是否对应你的问题;若持续失败,反馈操作步骤和本报告。",
4638
+ "diagnosticFinding_evidence-truncated": "部分旧记录或宿主作用域未包含在快照中,报告不能覆盖全部历史。",
4639
+ "diagnosticsNoRecordedFailure": "当前记录未发现失败;未执行的功能仍未验证。",
4640
+ "diagnosticFinding_version-mismatch": "前后端版本不一致,请重启 DSH 后重新生成报告。",
4641
+ "diagnosticFinding_collection-incomplete": "部分检查未能完成,请查看详情中的失败或超时项。",
4642
+ "diagnosticFinding_catalog-gap": "在线模型目录包含当前适配层尚未支持的档位或能力;不代表模型不可用。",
4643
+ "diagnosticFinding_recent-failure": "最近 15 分钟有操作或请求失败,且同一操作尚无后续成功记录。请结合发生时间查看详情。",
4644
+ "diagnosticReason_no-readiness-check": "无独立前置检查",
4645
+ "diagnosticReason_inspection-failed": "检查未完成",
4646
+ "diagnosticReason_inspection-timeout": "检查超时",
4647
+ "diagnosticSource_network": "网络请求(非完整回复)",
4630
4648
  "diagnosticReason_catalog-online": "在线目录已载入",
4631
4649
  "diagnosticReason_catalog-fallback": "使用备用目录",
4632
4650
  "diagnosticReason_storage-readable": "预测缓存可读",
4633
4651
  "diagnosticReason_tool-registered": "全局工具已注册",
4634
4652
  "diagnosticReason_tool-missing": "未找到全局工具",
4635
- "diagnosticsCoverageHint": "分别展示已检查的前置条件与最近 15 分钟的操作结果。请求完成不代表整个功能通过验收;未验证不等于故障。",
4653
+ "diagnosticsCoverageHint": "分别展示前置条件与最近 15 分钟的进程级证据;不限定当前账号或会话。接口响应、网络请求和工具结果不能替代完整功能验收。",
4636
4654
  "diagnosticsVersionMismatch": "前后端插件版本不同,请重载后重试。",
4637
4655
  "diagnosticsPartial": "部分信息未能采集,其余检查结果已保留。请在详情中查看失败或超时项。",
4638
4656
  "diagnosticsCapability": "功能",
4639
4657
  "diagnosticsReadiness": "前置条件",
4640
4658
  "diagnosticsEvidence": "近期操作证据",
4641
4659
  "diagnosticsUnverified": "尚未验证",
4642
- "diagnosticsHostCollected": "已采集宿主注册与选中结果(详情内)。这不证明界面可见或功能执行正常。",
4660
+ "diagnosticsHostCollected": "已采集宿主注册与选中结果。registrant 是宿主标签,可能被压缩,不能据此识别插件或判断干扰。",
4643
4661
  "diagnosticsHostUnknown": "宿主界面检查不可用或未挂载,不能据此判断插件干扰。",
4644
4662
  "diagnosticsDetails": "展开脱敏详情",
4645
4663
  "diagnosticsCopyFailed": "复制失败,可展开详情手动复制。",
@@ -4998,6 +5016,7 @@ window.__ModuleLoader__.load({
4998
5016
  unlimited: "不限额",
4999
5017
  monthlyCreditLimit: "Credits 月度消费上限",
5000
5018
  resetCredits: "额度重置",
5019
+ resetCreditsAvailable: "额度重置(可用 {count} 次)",
5001
5020
  resetCreditDefaultName: "额度重置",
5002
5021
  resetUse: "使用",
5003
5022
  resetPreparing: "准备中…",
@@ -5143,19 +5162,37 @@ window.__ModuleLoader__.load({
5143
5162
  imageRemoveAnnotation: "删除标注"
5144
5163
  };
5145
5164
  const en = {
5165
+ "diagnosticsSnapshotTime": "Report captured at:",
5166
+ "diagnosticsUnresolved": "Other failures remain without a later success; see the summary.",
5167
+ "diagnosticSeverity_warning": "Attention",
5168
+ "diagnosticSeverity_info": "Information",
5169
+ "diagnosticNext_restart": "Restart and regenerate. If versions still differ, check that the plugin update took effect.",
5170
+ "diagnosticNext_regenerate": "Regenerate immediately after reproducing. If collection remains incomplete, include the steps with your report.",
5171
+ "diagnosticNext_supported-options": "Keep using supported choices. New capabilities need adapter validation; do not insert unknown parameters manually.",
5172
+ "diagnosticNext_reproduce": "Match the operations and timestamps below to your problem. If failures persist, provide reproduction steps and this report.",
5173
+ "diagnosticFinding_evidence-truncated": "Older records or additional host scopes are omitted. This snapshot does not cover the entire history.",
5174
+ "diagnosticsNoRecordedFailure": "No failure in the current records; unused features remain unverified.",
5175
+ "diagnosticFinding_version-mismatch": "Client and server versions differ. Restart DSH and regenerate the report.",
5176
+ "diagnosticFinding_collection-incomplete": "Some checks could not finish. Inspect failed or timed-out collectors in the details.",
5177
+ "diagnosticFinding_catalog-gap": "The online catalog contains capabilities not supported by this adapter. This does not mean the model is unavailable.",
5178
+ "diagnosticFinding_recent-failure": "An operation or request failed within 15 minutes without a later success for the same operation. Inspect its timestamp and details.",
5179
+ "diagnosticReason_no-readiness-check": "No independent prerequisite check",
5180
+ "diagnosticReason_inspection-failed": "Check incomplete",
5181
+ "diagnosticReason_inspection-timeout": "Check timed out",
5182
+ "diagnosticSource_network": "Network request (not full reply)",
5146
5183
  "diagnosticReason_catalog-online": "Online catalog loaded",
5147
5184
  "diagnosticReason_catalog-fallback": "Fallback catalog",
5148
5185
  "diagnosticReason_storage-readable": "Forecast cache readable",
5149
5186
  "diagnosticReason_tool-registered": "Global tool registered",
5150
5187
  "diagnosticReason_tool-missing": "Global tool not found",
5151
- "diagnosticsCoverageHint": "Shows inspected prerequisites and operations observed in the last 15 minutes. Request completion is not end-to-end validation; unverified does not mean broken.",
5188
+ "diagnosticsCoverageHint": "Shows prerequisites and process-wide evidence from the last 15 minutes, not limited to this account or session. RPC, network and tool outcomes are not end-to-end validation.",
5152
5189
  "diagnosticsVersionMismatch": "Client and server versions differ. Reload and retry.",
5153
5190
  "diagnosticsPartial": "Some inspections failed or timed out. Other results are preserved; see details.",
5154
5191
  "diagnosticsCapability": "Capability",
5155
5192
  "diagnosticsReadiness": "Prerequisites",
5156
5193
  "diagnosticsEvidence": "Recent evidence",
5157
5194
  "diagnosticsUnverified": "Unverified",
5158
- "diagnosticsHostCollected": "Host registrations and selection are included in details, not proof of visibility or execution.",
5195
+ "diagnosticsHostCollected": "Host registrations and selection are included. Registrant labels may be minified; they do not identify packages or prove interference.",
5159
5196
  "diagnosticsHostUnknown": "Host inspection unavailable or unmounted; interference cannot be determined.",
5160
5197
  "diagnosticsDetails": "Redacted details",
5161
5198
  "diagnosticsCopyFailed": "Copy failed. Expand the details to copy manually.",
@@ -5514,6 +5551,7 @@ window.__ModuleLoader__.load({
5514
5551
  unlimited: "Unlimited",
5515
5552
  monthlyCreditLimit: "Monthly Credits spending cap",
5516
5553
  resetCredits: "Quota resets",
5554
+ resetCreditsAvailable: "Quota resets ({count} available)",
5517
5555
  resetCreditDefaultName: "Quota reset",
5518
5556
  resetUse: "Use",
5519
5557
  resetPreparing: "Preparing…",
@@ -5787,11 +5825,15 @@ window.__ModuleLoader__.load({
5787
5825
  .codexSubscriptionCreditBalance strong{font:600 18px/24px ui-monospace,SFMono-Regular,Consolas,monospace;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
5788
5826
  .codexSubscriptionCreditRows{display:flex;flex-direction:column;gap:6px}
5789
5827
  .codexSubscriptionResetMeta{display:flex;min-width:0;flex-direction:column;gap:1px}
5828
+ .codexSubscriptionResetDisclosure>summary{cursor:pointer;width:fit-content;color:var(--dsw-alias-label-primary);border-radius:6px}
5829
+ .codexSubscriptionResetDisclosure>summary:focus-visible{outline:2px solid currentColor;outline-offset:4px}
5830
+ .codexSubscriptionResetDisclosure[open]>summary{margin-bottom:10px}
5790
5831
  .codexSubscriptionResetBalance{display:flex;flex-direction:column;gap:8px}
5791
5832
  .codexSubscriptionResetCard{display:flex;align-items:center;justify-content:space-between;gap:10px;min-width:0;padding:9px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:9px;background:var(--dsw-alias-bg-module-platform)}
5792
- .codexSubscriptionResetCard .codexSubscriptionResetMeta{flex:1}
5833
+ .codexSubscriptionResetCard{flex-wrap:wrap}
5834
+ .codexSubscriptionResetCard .codexSubscriptionResetMeta{flex:1 1 180px}
5835
+ .codexSubscriptionResetCard .codexSubscriptionActions{width:auto;flex:0 0 auto}
5793
5836
  .codexSubscriptionResetCard strong{overflow:hidden;font-size:12px;line-height:18px;font-weight:500;text-overflow:ellipsis;white-space:nowrap}
5794
- .codexSubscriptionResetCard .codexSubscriptionActions{flex:0 0 auto}
5795
5837
  .codexSubscriptionResetCard .codexSubscriptionResetUse{min-height:28px;padding:0 10px}
5796
5838
  .codexSubscriptionResetBalance .codexSubscriptionActions{justify-content:flex-start}
5797
5839
  .codexSubscriptionResetFlow{display:flex;flex-direction:column;gap:10px;border-top:1px solid var(--dsw-alias-border-l2);padding-top:10px}
@@ -7533,7 +7575,7 @@ window.__ModuleLoader__.load({
7533
7575
  }
7534
7576
  //#endregion
7535
7577
  //#region src/version.js
7536
- const PACKAGE_VERSION = "2.2.3";
7578
+ const PACKAGE_VERSION = "2.2.4";
7537
7579
  //#endregion
7538
7580
  //#region src/client-recovery.js
7539
7581
  async function recoveryCall(rpc, endpoint, payload = {}, timeoutMs = 1e4) {
@@ -9512,6 +9554,89 @@ window.__ModuleLoader__.load({
9512
9554
  ]
9513
9555
  });
9514
9556
  }
9557
+ const areas = {
9558
+ catalog: "models",
9559
+ quota: "quota",
9560
+ search: "search",
9561
+ image: "images",
9562
+ model: "transport",
9563
+ login: "account",
9564
+ "quota-reset": "quota"
9565
+ };
9566
+ function diagnosticEvidence({ operations, history }, now) {
9567
+ return [...(operations?.events ?? []).map((e) => ({
9568
+ capability: e.capability,
9569
+ action: e.action,
9570
+ source: e.source,
9571
+ status: e.status,
9572
+ observedAt: e.observedAt
9573
+ })), ...(history?.events ?? []).map((e) => ({
9574
+ capability: areas[e.area],
9575
+ action: e.area,
9576
+ source: "network",
9577
+ status: e.status === "ok" ? "completed" : "failed",
9578
+ observedAt: e.observedAt
9579
+ }))].filter((e) => Number.isSafeInteger(e.observedAt) && now >= e.observedAt && now - e.observedAt <= 9e5).sort((a, b) => a.observedAt - b.observedAt);
9580
+ }
9581
+ function unresolvedFailures(events) {
9582
+ const failed = /* @__PURE__ */ new Map();
9583
+ for (const event of events) {
9584
+ const key = `${event.source}:${event.action}`;
9585
+ if (event.status === "failed") failed.set(key, event);
9586
+ else if (event.status === "completed") failed.delete(key);
9587
+ }
9588
+ return [...failed.values()];
9589
+ }
9590
+ //#endregion
9591
+ //#region src/diagnostic-summary.js
9592
+ function diagnosticSummary(report, now = Date.now()) {
9593
+ const findings = [];
9594
+ const checks = [...report.inspection?.checks ?? [], ...report.client?.checks ?? []];
9595
+ if (report.version && report.client?.version && report.version !== report.client.version) findings.push({
9596
+ code: "version-mismatch",
9597
+ severity: "warning",
9598
+ next: "restart",
9599
+ evidence: ["version", "client.version"]
9600
+ });
9601
+ if (!report.inspection || report.client?.status === "unknown" || checks.some((check) => ["inspection-failed", "inspection-timeout"].includes(check.reason))) findings.push({
9602
+ code: "collection-incomplete",
9603
+ severity: "warning",
9604
+ next: "regenerate",
9605
+ evidence: checks.filter((c) => c.status === "unknown").map((c) => c.id)
9606
+ });
9607
+ if (report.catalog?.unsupported?.length) findings.push({
9608
+ code: "catalog-gap",
9609
+ severity: "info",
9610
+ next: "supported-options",
9611
+ evidence: ["catalog.unsupported"]
9612
+ });
9613
+ const capturedAt = Date.parse(report.generatedAt);
9614
+ const failures = unresolvedFailures(diagnosticEvidence({
9615
+ operations: report.operations,
9616
+ history: report.requestHistory
9617
+ }, Number.isFinite(capturedAt) ? capturedAt : now));
9618
+ if (failures.length) findings.push({
9619
+ code: "recent-failure",
9620
+ severity: "warning",
9621
+ next: "reproduce",
9622
+ evidence: failures
9623
+ });
9624
+ if ((report.requestHistory?.dropped ?? 0) + (report.operations?.dropped ?? 0) > 0 || report.client?.truncated) findings.push({
9625
+ code: "evidence-truncated",
9626
+ severity: "info",
9627
+ next: "regenerate",
9628
+ evidence: [
9629
+ "requestHistory.dropped",
9630
+ "operations.dropped",
9631
+ "client.truncated"
9632
+ ]
9633
+ });
9634
+ return {
9635
+ scope: "recorded-evidence-only",
9636
+ findings,
9637
+ unverified: (report.inspection?.capabilities ?? []).filter((c) => c.execution === "not-verified" && c.readiness !== "not-applicable").length
9638
+ };
9639
+ }
9515
9640
  //#endregion
9516
9641
  //#region src/client-diagnostics.jsx
9517
9642
  function DiagnosticsCard({ rpc, t, diagnostics }) {
@@ -9527,9 +9652,13 @@ window.__ModuleLoader__.load({
9527
9652
  setCopyError(false);
9528
9653
  Promise.allSettled([recoveryCall(rpc, "diagnostics"), Promise.resolve().then(() => diagnostics?.collect())]).then(([server, client]) => {
9529
9654
  setError(server.status === "rejected");
9530
- setReport({
9655
+ const combined = {
9531
9656
  ...server.status === "fulfilled" ? server.value : clientDiagnostic(server.reason),
9532
9657
  client: client.status === "fulfilled" && client.value ? client.value : { status: "unknown" }
9658
+ };
9659
+ setReport({
9660
+ ...combined,
9661
+ summary: diagnosticSummary(combined)
9533
9662
  });
9534
9663
  }).finally(() => setBusy(false));
9535
9664
  };
@@ -9580,14 +9709,33 @@ window.__ModuleLoader__.load({
9580
9709
  className: "codexSubscriptionHelp",
9581
9710
  children: t("diagnosticsCoverageHint")
9582
9711
  }),
9583
- report.version && report.client?.version && report.version !== report.client.version ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
9584
- role: "status",
9585
- children: t("diagnosticsVersionMismatch")
9712
+ report.generatedAt ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
9713
+ className: "codexSubscriptionHelp",
9714
+ children: [
9715
+ t("diagnosticsSnapshotTime"),
9716
+ " ",
9717
+ new Date(report.generatedAt).toLocaleString()
9718
+ ]
9586
9719
  }) : null,
9587
- (report.inspection?.checks ?? []).some((item) => ["inspection-failed", "inspection-timeout"].includes(item.reason)) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
9720
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9588
9721
  role: "status",
9589
- children: t("diagnosticsPartial")
9590
- }) : null,
9722
+ children: report.summary?.findings.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", { children: report.summary.findings.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
9723
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t(`diagnosticSeverity_${item.severity}`) }),
9724
+ " · ",
9725
+ t(`diagnosticFinding_${item.code}`),
9726
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
9727
+ className: "codexSubscriptionHelp",
9728
+ children: t(`diagnosticNext_${item.next}`)
9729
+ }),
9730
+ item.code === "recent-failure" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", { children: item.evidence.map((event) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
9731
+ event.action,
9732
+ " · ",
9733
+ t(`diagnosticSource_${event.source}`),
9734
+ " · ",
9735
+ new Date(event.observedAt).toLocaleTimeString()
9736
+ ] }, `${event.source}:${event.action}`)) }) : null
9737
+ ] }, item.code)) }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("diagnosticsNoRecordedFailure") })
9738
+ }),
9591
9739
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
9592
9740
  style: {
9593
9741
  width: "100%",
@@ -9602,7 +9750,7 @@ window.__ModuleLoader__.load({
9602
9750
  ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: (report.inspection?.capabilities ?? []).map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
9603
9751
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: t(`diagnosticCapability_${item.id}`) }),
9604
9752
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("td", { children: [t(`diagnosticReason_${item.reason}`), item.blockedBy ? ` · ${t(`diagnosticCapability_${item.blockedBy}`)}` : ""] }),
9605
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: item.latest ? `${item.latest.action} · ${t(`diagnosticSource_${item.latest.source}`)} · ${t(`diagnosticOutcome_${item.latest.status}`)} · ${new Date(item.latest.observedAt).toLocaleTimeString()}` : t("diagnosticsUnverified") })
9753
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("td", { children: [item.latest ? `${item.latest.action} · ${t(`diagnosticSource_${item.latest.source}`)} · ${t(`diagnosticOutcome_${item.latest.status}`)} · ${new Date(item.latest.observedAt).toLocaleTimeString()}` : t("diagnosticsUnverified"), item.unresolved?.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("diagnosticsUnresolved") }) : null] })
9606
9754
  ] }, item.id)) })]
9607
9755
  }),
9608
9756
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
@@ -10082,9 +10230,9 @@ window.__ModuleLoader__.load({
10082
10230
  className: "codexSubscriptionCreditBalance",
10083
10231
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("creditsBalance") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: visibleUsage.credits.unlimited ? t("unlimited") : `${visibleUsage.credits.balance ?? t("unavailable")} ${t("creditsUnit")}` })]
10084
10232
  }) : null,
10085
- visibleUsage?.resetCredits?.availableCount > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10086
- className: "codexSubscriptionCreditBalance",
10087
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("resetCredits") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResetCreditList, {
10233
+ visibleUsage?.resetCredits?.availableCount > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
10234
+ className: "codexSubscriptionCreditBalance codexSubscriptionResetDisclosure",
10235
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: fill(t("resetCreditsAvailable"), { count: visibleUsage.resetCredits.availableCount }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResetCreditList, {
10088
10236
  rpc,
10089
10237
  t,
10090
10238
  count: visibleUsage.resetCredits.availableCount,
@@ -10352,7 +10500,8 @@ window.__ModuleLoader__.load({
10352
10500
  declared: !!node,
10353
10501
  truncated: occupants.length > 16,
10354
10502
  occupants: occupants.slice(0, 16).map((value) => ({
10355
- owner: typeof value.registrant === "string" && packageName.test(value.registrant) ? value.registrant : "unknown",
10503
+ registrant: typeof value.registrant === "string" && packageName.test(value.registrant) ? value.registrant : "unknown",
10504
+ identity: "unverified-host-label",
10356
10505
  active: value.active === true
10357
10506
  }))
10358
10507
  };
package/lib/index.js CHANGED
@@ -370,7 +370,7 @@ const PREFERENCE_FIELDS = Object.freeze({
370
370
  });
371
371
  //#endregion
372
372
  //#region src/diagnostic-events.js
373
- const areas = /* @__PURE__ */ new Set([
373
+ const areas$1 = /* @__PURE__ */ new Set([
374
374
  "login",
375
375
  "model",
376
376
  "catalog",
@@ -394,7 +394,7 @@ function createDiagnosticEvents({ limit = 32, now = Date.now } = {}) {
394
394
  let dropped = 0, sequence = 0;
395
395
  return {
396
396
  record(area, value) {
397
- if (!areas.has(area) || !["ok", "failed"].includes(value?.status)) return;
397
+ if (!areas$1.has(area) || !["ok", "failed"].includes(value?.status)) return;
398
398
  events.push({
399
399
  sequence: ++sequence,
400
400
  area,
@@ -2951,7 +2951,7 @@ async function readSubscriptionCredentials(getAuth, readCredential, signal) {
2951
2951
  }
2952
2952
  //#endregion
2953
2953
  //#region src/version.js
2954
- const PACKAGE_VERSION = "2.2.3";
2954
+ const PACKAGE_VERSION = "2.2.4";
2955
2955
  const USER_AGENT = `dsh-codex-subscription/${PACKAGE_VERSION}`;
2956
2956
  //#endregion
2957
2957
  //#region src/model-catalog.js
@@ -4059,9 +4059,42 @@ const diagnosticCapabilities = Object.freeze([
4059
4059
  "storage",
4060
4060
  "host-ui"
4061
4061
  ]);
4062
+ const areas = {
4063
+ catalog: "models",
4064
+ quota: "quota",
4065
+ search: "search",
4066
+ image: "images",
4067
+ model: "transport",
4068
+ login: "account",
4069
+ "quota-reset": "quota"
4070
+ };
4071
+ function diagnosticEvidence({ operations, history }, now) {
4072
+ return [...(operations?.events ?? []).map((e) => ({
4073
+ capability: e.capability,
4074
+ action: e.action,
4075
+ source: e.source,
4076
+ status: e.status,
4077
+ observedAt: e.observedAt
4078
+ })), ...(history?.events ?? []).map((e) => ({
4079
+ capability: areas[e.area],
4080
+ action: e.area,
4081
+ source: "network",
4082
+ status: e.status === "ok" ? "completed" : "failed",
4083
+ observedAt: e.observedAt
4084
+ }))].filter((e) => Number.isSafeInteger(e.observedAt) && now >= e.observedAt && now - e.observedAt <= 9e5).sort((a, b) => a.observedAt - b.observedAt);
4085
+ }
4086
+ function unresolvedFailures(events) {
4087
+ const failed = /* @__PURE__ */ new Map();
4088
+ for (const event of events) {
4089
+ const key = `${event.source}:${event.action}`;
4090
+ if (event.status === "failed") failed.set(key, event);
4091
+ else if (event.status === "completed") failed.delete(key);
4092
+ }
4093
+ return [...failed.values()];
4094
+ }
4062
4095
  //#endregion
4063
4096
  //#region src/diagnostic-capabilities.js
4064
- function capabilityCoverage({ account, preference, runtime, catalog, tools, storage, checks, operations, now = Date.now() }) {
4097
+ function capabilityCoverage({ account, preference, runtime, catalog, tools, storage, checks, operations, history, now = Date.now() }) {
4065
4098
  const disabled = {
4066
4099
  images: preference.imageGeneration === false && preference.imageEditing === false,
4067
4100
  sketch: preference.imageSketch === false || preference.imageEditing === false,
@@ -4069,8 +4102,12 @@ function capabilityCoverage({ account, preference, runtime, catalog, tools, stor
4069
4102
  compaction: preference.compactionMode === "dsh",
4070
4103
  subagents: preference.subagentBackend === "dsh"
4071
4104
  };
4105
+ const observed = diagnosticEvidence({
4106
+ operations,
4107
+ history
4108
+ }, now);
4072
4109
  return diagnosticCapabilities.map((id) => {
4073
- let readiness = "unknown", reason = "not-instrumented", blockedBy;
4110
+ let readiness = "unknown", reason = "no-readiness-check", blockedBy;
4074
4111
  if (disabled[id]) {
4075
4112
  readiness = "not-applicable";
4076
4113
  reason = "disabled-or-host-owned";
@@ -4103,14 +4140,20 @@ function capabilityCoverage({ account, preference, runtime, catalog, tools, stor
4103
4140
  readiness = tools[id] ? "pass" : "warn";
4104
4141
  reason = tools[id] ? "tool-registered" : "tool-missing";
4105
4142
  }
4106
- const recent = (operations?.events ?? []).filter((event) => event.capability === id && now >= event.observedAt && now - event.observedAt <= 15 * 6e4).at(-1);
4143
+ const evidence = observed.filter((event) => event.capability === id || id === "transport" && event.source === "network");
4144
+ const failures = unresolvedFailures(evidence);
4145
+ const recent = evidence.at(-1);
4146
+ const relatedChecks = checks.filter((check) => check.capability === id || ["images", "sketch"].includes(id) && check.id === "tools");
4147
+ const collectionIssue = relatedChecks.find((check) => ["inspection-failed", "inspection-timeout"].includes(check.reason));
4148
+ if (collectionIssue && readiness === "unknown") reason = collectionIssue.reason;
4107
4149
  return {
4108
4150
  id,
4109
4151
  readiness,
4110
4152
  reason,
4111
4153
  ...blockedBy ? { blockedBy } : {},
4112
- checks: checks.filter((check) => check.capability === id).map((check) => check.id),
4154
+ checks: relatedChecks.map((check) => check.id),
4113
4155
  execution: recent ? "observed" : "not-verified",
4156
+ ...failures.length ? { unresolved: failures } : {},
4114
4157
  ...recent ? { latest: {
4115
4158
  action: recent.action,
4116
4159
  source: recent.source,
@@ -4417,7 +4460,8 @@ async function createSubscriptionDiagnostics({ auth, preferences, login = { phas
4417
4460
  tools: collected.tools,
4418
4461
  storage: collected.storage,
4419
4462
  checks,
4420
- operations: collected.operations
4463
+ operations: collected.operations,
4464
+ history: collected.history
4421
4465
  })
4422
4466
  },
4423
4467
  package: "dsh-codex-subscription",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-codex-subscription",
3
- "version": "2.2.3",
3
+ "version": "2.2.4",
4
4
  "description": "Use ChatGPT and Codex subscriptions in DeepSeek Harness with OAuth, quota, safe resets, web search, images, and Fast mode",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",