dsh-mnemon-source-skills 0.5.7 → 0.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -194,6 +194,7 @@ window.__ModuleLoader__.load({
194
194
  "tab.market": "市场",
195
195
  "tab.trash": "回收站",
196
196
  "common.loading": "加载中",
197
+ "common.retry": "重试",
197
198
  "common.cancel": "取消",
198
199
  "common.close": "关闭",
199
200
  "common.delete": "删除",
@@ -526,6 +527,10 @@ window.__ModuleLoader__.load({
526
527
  "evolution.deleteTitle": "删除这条建议?",
527
528
  "evolution.deleteBody": "它生成的草案和证据引用会一起删掉,无法恢复。",
528
529
  "evolution.deleted": "已删除",
530
+ "evolution.missing": "该建议已删除",
531
+ "evolution.missingBody": "可以在左侧选择其他建议,或返回记录查看原始内容。",
532
+ "evolution.loadFailed": "无法加载这条建议",
533
+ "evolution.loadFailedBody": "请重试,或在左侧选择其他建议。",
529
534
  "tests.model": "全局模型",
530
535
  "tests.modelCard": "所选回测模型",
531
536
  "tests.modelAuto": "跟随默认"
@@ -543,6 +548,7 @@ window.__ModuleLoader__.load({
543
548
  "tab.market": "Market",
544
549
  "tab.trash": "Trash",
545
550
  "common.loading": "Loading",
551
+ "common.retry": "Retry",
546
552
  "common.cancel": "Cancel",
547
553
  "common.close": "Close",
548
554
  "common.delete": "Delete",
@@ -875,6 +881,10 @@ window.__ModuleLoader__.load({
875
881
  "evolution.deleteTitle": "Delete this suggestion?",
876
882
  "evolution.deleteBody": "Its draft and the evidence references it cites go with it, and this cannot be undone.",
877
883
  "evolution.deleted": "Deleted",
884
+ "evolution.missing": "This suggestion has been deleted",
885
+ "evolution.missingBody": "Select another suggestion on the left, or return to Evidence to read the original record.",
886
+ "evolution.loadFailed": "Could not load this suggestion",
887
+ "evolution.loadFailedBody": "Retry, or select another suggestion on the left.",
878
888
  "tests.model": "Global model",
879
889
  "tests.modelCard": "Selected model",
880
890
  "tests.modelAuto": "Follow default"
@@ -3661,11 +3671,14 @@ window.__ModuleLoader__.load({
3661
3671
  model: props.model.model
3662
3672
  };
3663
3673
  const [view, setView] = (0, react.useState)(null);
3674
+ const [loadError, setLoadError] = (0, react.useState)(null);
3675
+ const [reload, setReload] = (0, react.useState)(0);
3664
3676
  const [trajectories, setTrajectories] = (0, react.useState)(/* @__PURE__ */ new Map());
3665
3677
  const [busy, setBusy] = (0, react.useState)(false);
3666
3678
  const [deleting, setDeleting] = (0, react.useState)(false);
3667
3679
  (0, react.useEffect)(() => {
3668
3680
  let active = true;
3681
+ setLoadError(null);
3669
3682
  context.client.suggestion(props.id).then(async (value) => {
3670
3683
  if (!active) return;
3671
3684
  setView(value);
@@ -3675,15 +3688,34 @@ window.__ModuleLoader__.load({
3675
3688
  loaded.set(reference.trajectoryId, await context.client.trajectory(reference.trajectoryId).catch(() => null));
3676
3689
  }
3677
3690
  if (active) setTrajectories(loaded);
3678
- }).catch(context.fail);
3691
+ }).catch((error) => {
3692
+ if (!active) return;
3693
+ setView(null);
3694
+ if ((error instanceof Error ? error.message : String(error)) === "suggestion not found: " + props.id) setLoadError("missing");
3695
+ else {
3696
+ setLoadError("failed");
3697
+ context.fail(error);
3698
+ }
3699
+ });
3679
3700
  return () => {
3680
3701
  active = false;
3681
3702
  };
3682
3703
  }, [
3683
3704
  context.client,
3684
3705
  props.id,
3685
- context.revision
3706
+ context.revision,
3707
+ reload
3686
3708
  ]);
3709
+ if (loadError !== null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Empty, {
3710
+ glyph: "?",
3711
+ title: t(loadError === "missing" ? "evolution.missing" : "evolution.loadFailed"),
3712
+ action: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
3713
+ variant: "ghost",
3714
+ onClick: () => setReload((value) => value + 1),
3715
+ children: t("common.retry")
3716
+ }),
3717
+ children: t(loadError === "missing" ? "evolution.missingBody" : "evolution.loadFailedBody")
3718
+ });
3687
3719
  if (view === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Busy, { label: t("common.loading") });
3688
3720
  const { suggestion } = view;
3689
3721
  const canDraft = context.client.canAssist("skill-draft") && !(suggestion.action === "update" && view.skill === void 0);
package/lib/index.js CHANGED
@@ -423,6 +423,19 @@ function trashStamp(id) {
423
423
  const match = /^(\d{4}-\d{2}-\d{2})T(\d{2})-(\d{2})-(\d{2})-(\d{3})Z-/u.exec(id);
424
424
  return match === null ? void 0 : `${match[1]}T${match[2]}:${match[3]}:${match[4]}.${match[5]}Z`;
425
425
  }
426
+ /** References are navigation links, not evidence: keep the records when a suggestion is deleted. */
427
+ function pruneSuggestionLinks(ledger) {
428
+ const ids = new Set(ledger.suggestions.map((suggestion) => suggestion.id));
429
+ for (const review of ledger.reviews) {
430
+ if (review.suggestionIds === void 0) continue;
431
+ const kept = review.suggestionIds.filter((id) => ids.has(id));
432
+ if (kept.length !== review.suggestionIds.length) review.suggestions = Math.min(review.suggestions, kept.length);
433
+ if (kept.length === 0) delete review.suggestionIds;
434
+ else review.suggestionIds = kept;
435
+ }
436
+ for (const trajectory of ledger.trajectories) trajectory.suggestionIds = trajectory.suggestionIds.filter((id) => ids.has(id));
437
+ return ledger;
438
+ }
426
439
  /**
427
440
  * The Skills Source's own files under `<dataDir>/skills`. Every file is
428
441
  * replaced atomically; callers serialize writes with the storage lock.
@@ -478,7 +491,7 @@ var SkillsStore = class {
478
491
  ledger() {
479
492
  const value = object$1(this.readJson("ledger.json"));
480
493
  if (value === void 0) return emptyLedger();
481
- return {
494
+ return pruneSuggestionLinks({
482
495
  version: 1,
483
496
  generation: typeof value.generation === "number" ? value.generation : 0,
484
497
  suggestions: array(value.suggestions),
@@ -487,7 +500,7 @@ var SkillsStore = class {
487
500
  versions: array(value.versions),
488
501
  trajectories: array(value.trajectories),
489
502
  installs: array(value.installs)
490
- };
503
+ });
491
504
  }
492
505
  /**
493
506
  * What the user picked for draft and backtest runs, kept out of `fingerprint()`
@@ -527,6 +540,7 @@ var SkillsStore = class {
527
540
  this.writeJson("preferences.json", preferences);
528
541
  }
529
542
  saveLedger(ledger) {
543
+ pruneSuggestionLinks(ledger);
530
544
  ledger.generation += 1;
531
545
  ledger.reviews = ledger.reviews.slice(0, 200);
532
546
  const kept = /* @__PURE__ */ new Set();
@@ -558,7 +572,16 @@ var SkillsStore = class {
558
572
  if (!/^[a-z0-9-]{1,80}$/u.test(id)) throw new Error("invalid trajectory id");
559
573
  const value = object$1(this.readJson(join("trajectories", `${id}.json`)));
560
574
  if (value === void 0) throw new Error("trajectory not found: " + id);
561
- return value;
575
+ const trajectory = value;
576
+ const ids = new Set(this.ledger().suggestions.map((suggestion) => suggestion.id));
577
+ trajectory.suggestionIds = trajectory.suggestionIds.filter((id) => ids.has(id));
578
+ for (const annotation of trajectory.annotations) {
579
+ if (annotation.suggestionIds === void 0) continue;
580
+ const kept = annotation.suggestionIds.filter((id) => ids.has(id));
581
+ if (kept.length === 0) delete annotation.suggestionIds;
582
+ else annotation.suggestionIds = kept;
583
+ }
584
+ return trajectory;
562
585
  }
563
586
  saveTrajectory(trajectory) {
564
587
  this.writeJson(join("trajectories", `${trajectory.id}.json`), trajectory);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-mnemon-source-skills",
3
- "version": "0.5.7",
3
+ "version": "0.5.8",
4
4
  "description": "Skills Source for Composable View Memory: DSH skill management, evolution suggestions, evidence trajectories and eval sets.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -62,7 +62,7 @@
62
62
  "@types/node": "^22.0.0",
63
63
  "@types/react": "^18.3.0",
64
64
  "@types/react-dom": "^18.3.0",
65
- "dsh-mnemon": "^0.5.40",
65
+ "dsh-mnemon": "^0.5.41",
66
66
  "jsdom": "^26.0.0",
67
67
  "react": "^18.2.0",
68
68
  "react-dom": "^18.2.0",
@@ -12,6 +12,7 @@
12
12
  "tab.market": "市场",
13
13
  "tab.trash": "回收站",
14
14
  "common.loading": "加载中",
15
+ "common.retry": "重试",
15
16
  "common.cancel": "取消",
16
17
  "common.close": "关闭",
17
18
  "common.delete": "删除",
@@ -344,6 +345,10 @@
344
345
  "evolution.deleteTitle": "删除这条建议?",
345
346
  "evolution.deleteBody": "它生成的草案和证据引用会一起删掉,无法恢复。",
346
347
  "evolution.deleted": "已删除",
348
+ "evolution.missing": "该建议已删除",
349
+ "evolution.missingBody": "可以在左侧选择其他建议,或返回记录查看原始内容。",
350
+ "evolution.loadFailed": "无法加载这条建议",
351
+ "evolution.loadFailedBody": "请重试,或在左侧选择其他建议。",
347
352
  "tests.model": "全局模型",
348
353
  "tests.modelCard": "所选回测模型",
349
354
  "tests.modelAuto": "跟随默认"
@@ -361,6 +366,7 @@
361
366
  "tab.market": "Market",
362
367
  "tab.trash": "Trash",
363
368
  "common.loading": "Loading",
369
+ "common.retry": "Retry",
364
370
  "common.cancel": "Cancel",
365
371
  "common.close": "Close",
366
372
  "common.delete": "Delete",
@@ -693,6 +699,10 @@
693
699
  "evolution.deleteTitle": "Delete this suggestion?",
694
700
  "evolution.deleteBody": "Its draft and the evidence references it cites go with it, and this cannot be undone.",
695
701
  "evolution.deleted": "Deleted",
702
+ "evolution.missing": "This suggestion has been deleted",
703
+ "evolution.missingBody": "Select another suggestion on the left, or return to Evidence to read the original record.",
704
+ "evolution.loadFailed": "Could not load this suggestion",
705
+ "evolution.loadFailedBody": "Retry, or select another suggestion on the left.",
696
706
  "tests.model": "Global model",
697
707
  "tests.modelCard": "Selected model",
698
708
  "tests.modelAuto": "Follow default"