@huanlin/dsh-plugin-yet-another-subagent 0.1.6 → 0.3.0

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.md CHANGED
@@ -10,14 +10,16 @@
10
10
 
11
11
  ## 架构
12
12
 
13
- 单 bundle,三入口(host `.` + invariant `./invariant` + client `./client`)。
13
+ 单 bundle,双入口(host `.` + client `./client`)。
14
+
15
+ > 不发布 `./invariant`:本插件的工具/RPC/projection 注册均无独立可分歧的运行时观察(HMR 安全性由测试证明),无内容可校验——按 DSH 0.1.2-rc.1 收紧后的 invariant 规则(禁止空 installer)省略该入口及其全部接线。
14
16
 
15
17
  - **Host 半**(`src/index.ts`):
16
18
  - 单一 `subagent` 工具,通过 `profile` 枚举参数选择 profile(非每 profile 一个工具)
17
19
  - 复用官方 `spawn` provider,支持前台(foreground)和后台(continuable / one-shot)两种模式
18
20
  - Profile 状态通过 settings seam 持久化到 `$DSH_HOME/settings.yaml`
19
21
  - RPC CRUD:`profiles.list` / `.add` / `.update` / `.remove`(专用 `/ya-subagent` 通道,不共享 `/api`)
20
- - 两个 session projection:`subagentProfile`(父会话 childId→profileId 映射 + callId→childId)+ `yaSubagentProgress`(子会话实时 toolcall/token/活动状态)
22
+ - 两个 session projection:`subagentProfile`(父会话 childId→profileId 映射 + callId→childId)+ `yaSubagentProgress`(子会话实时 toolcall/token/活动状态);wire view 已做引用记忆化,适配 dsh 0.1.2-alpha.3 起 change feed 的 `Object.is` 下发门控(内容不变即静默)
21
23
  - **Client 半**(`src/client/index.ts`):
22
24
  - `settings.section` — Profile 编辑页
23
25
  - `tool.call.toolview`(key `subagent`)— `SubagentCard` 工具调用卡片
@@ -71,7 +73,7 @@
71
73
  pnpm install # 安装开发依赖 + zod(唯一运行时 npm 依赖)
72
74
  pnpm run typecheck # tsc --noEmit(通过 ../dsh 解析 DSH 源码)
73
75
  pnpm test # vitest run
74
- pnpm run build # tsc + tsdown → lib/index.js, lib/invariant.js, lib/client.js
76
+ pnpm run build # tsc + tsdown → lib/index.js, lib/client.js
75
77
  ```
76
78
 
77
79
  ### 类型检查
@@ -95,13 +97,12 @@ dsh plugin --profile web add "link:D:/Projects/deepseek-harness/yet-another-suba
95
97
  ```sh
96
98
  pnpm run typecheck # 0 errors
97
99
  pnpm test # 55 tests passing
98
- pnpm run build # lib/index.js + lib/invariant.js + lib/client.js
100
+ pnpm run build # lib/index.js + lib/client.js
99
101
  ```
100
102
 
101
103
  ### 产物验证
102
104
 
103
105
  - `lib/index.js` — Host bundle
104
- - `lib/invariant.js` — Invariant companion
105
106
  - `lib/client.js` — Client bundle(CSS-modules inline,`d` 前缀 hash 防 CSS 类名数字开头)
106
107
  - `cordis.patch.yml` — Bundle patch layer
107
108
 
package/lib/client.js CHANGED
@@ -111,7 +111,6 @@ window.__ModuleLoader__.load({
111
111
  const binding = sessions.binding(childId);
112
112
  if (binding === void 0) return;
113
113
  const face = binding.session.projections.faceOf("yaSubagentProgress");
114
- if (face === void 0) return;
115
114
  const snapshot = face.getSnapshot();
116
115
  setProgress(snapshot ?? void 0);
117
116
  return face.subscribe(() => {
@@ -132,7 +131,6 @@ window.__ModuleLoader__.load({
132
131
  const binding = sessions.binding(sessionId);
133
132
  if (binding === void 0) return;
134
133
  const face = binding.session.projections.faceOf("subagentProfile");
135
- if (face === void 0) return;
136
134
  const read = () => {
137
135
  return face.getSnapshot()?.calls?.[callId];
138
136
  };
@@ -309,7 +307,6 @@ window.__ModuleLoader__.load({
309
307
  const binding = sessions.binding(sessionId);
310
308
  if (binding === void 0) return;
311
309
  const face = binding.session.projections.faceOf("subagentProfile");
312
- if (face === void 0) return;
313
310
  const read = () => {
314
311
  const snap = face.getSnapshot();
315
312
  setChildren(snap?.children ?? {});
@@ -326,7 +323,6 @@ window.__ModuleLoader__.load({
326
323
  const binding = sessions.binding(childId);
327
324
  if (binding === void 0) return;
328
325
  const face = binding.session.projections.faceOf("yaSubagentProgress");
329
- if (face === void 0) return;
330
326
  const snapshot = face.getSnapshot();
331
327
  setProgress(snapshot ?? void 0);
332
328
  return face.subscribe(() => {
@@ -366,11 +362,8 @@ window.__ModuleLoader__.load({
366
362
  const childProjectionChildren = {};
367
363
  const binding = sessions.binding(entry.id);
368
364
  if (binding !== void 0) {
369
- const face = binding.session.projections.faceOf("subagentProfile");
370
- if (face !== void 0) {
371
- const snap = face.getSnapshot();
372
- if (snap?.children !== void 0) for (const [k, v] of Object.entries(snap.children)) childProjectionChildren[k] = v;
373
- }
365
+ const snap = binding.session.projections.faceOf("subagentProfile").getSnapshot();
366
+ if (snap?.children !== void 0) for (const [k, v] of Object.entries(snap.children)) childProjectionChildren[k] = v;
374
367
  }
375
368
  const children = entry.hasChildren === true ? buildTree(sessions, entry.id, childProjectionChildren, profileLabelOf, visited) : [];
376
369
  nodes.push({
@@ -642,7 +635,7 @@ window.__ModuleLoader__.load({
642
635
  * @param props - settings.section runtime share + locale + inject.
643
636
  * @returns the page element.
644
637
  */
645
- function SettingsPage({ rpc, fetchProfiles, t }) {
638
+ function SettingsPage({ rpc, fetchProfiles, fetchModelCatalog, t }) {
646
639
  const [profiles, setProfiles] = (0, react.useState)([]);
647
640
  const [drafts, setDrafts] = (0, react.useState)([]);
648
641
  const [expanded, setExpanded] = (0, react.useState)(/* @__PURE__ */ new Set());
@@ -661,23 +654,27 @@ window.__ModuleLoader__.load({
661
654
  setLoading(true);
662
655
  setError(void 0);
663
656
  try {
664
- const [list, toolsResult, modelsResult] = await Promise.all([
657
+ const [list, toolsResult, catalog] = await Promise.all([
665
658
  fetchProfiles(),
666
659
  callRpc(rpc, "tools.list", {}),
667
- rpc.call("/api", "llm.models", {})
660
+ fetchModelCatalog().catch(() => void 0)
668
661
  ]);
669
662
  setProfiles(list);
670
663
  setDrafts(list.map((p) => ({ ...p })));
671
664
  if (toolsResult.ok) setToolList(toolsResult.value.tools);
672
665
  else setToolList([]);
673
- if (modelsResult.ok) setModelGroups(modelsResult.value.groups);
666
+ if (catalog !== void 0) setModelGroups(catalog.groups);
674
667
  else setModelGroups([]);
675
668
  } catch (err) {
676
669
  setError(err instanceof Error ? err.message : String(err));
677
670
  } finally {
678
671
  setLoading(false);
679
672
  }
680
- }, [fetchProfiles, rpc]);
673
+ }, [
674
+ fetchProfiles,
675
+ fetchModelCatalog,
676
+ rpc
677
+ ]);
681
678
  (0, react.useEffect)(() => {
682
679
  refresh();
683
680
  }, [refresh]);
@@ -814,6 +811,7 @@ window.__ModuleLoader__.load({
814
811
  setRepairConfirmOpen(false);
815
812
  },
816
813
  title: t("repair.confirm.title"),
814
+ closeLabel: t("common.close"),
817
815
  footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
818
816
  type: "button",
819
817
  className: classMap.secondaryButton,
@@ -844,6 +842,7 @@ window.__ModuleLoader__.load({
844
842
  setRepairError(void 0);
845
843
  },
846
844
  title: t("repair.result.title"),
845
+ closeLabel: t("common.close"),
847
846
  footer: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
848
847
  type: "button",
849
848
  className: classMap.secondaryButton,
@@ -895,6 +894,7 @@ window.__ModuleLoader__.load({
895
894
  setConfirmDelete(void 0);
896
895
  },
897
896
  title: t("row.delete.confirm"),
897
+ closeLabel: t("common.close"),
898
898
  footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
899
899
  type: "button",
900
900
  className: classMap.secondaryButton,
@@ -1337,6 +1337,7 @@ window.__ModuleLoader__.load({
1337
1337
  /** All override-language dictionaries for the `ya-subagent` namespace. */
1338
1338
  const dicts = {
1339
1339
  ja: {
1340
+ "common.close": "閉じる",
1340
1341
  "nav": "サブエージェント",
1341
1342
  "page.title": "サブエージェント設定",
1342
1343
  "page.empty": "設定されたプロファイルがありません。下に追加してください。",
@@ -1416,6 +1417,7 @@ window.__ModuleLoader__.load({
1416
1417
  "repair.error": "修復に失敗しました"
1417
1418
  },
1418
1419
  de: {
1420
+ "common.close": "Schließen",
1419
1421
  "nav": "Subagenten",
1420
1422
  "page.title": "Subagenten-Profile",
1421
1423
  "page.empty": "Keine Profile konfiguriert. Fügen Sie unten eines hinzu.",
@@ -1495,6 +1497,7 @@ window.__ModuleLoader__.load({
1495
1497
  "repair.error": "Reparatur fehlgeschlagen"
1496
1498
  },
1497
1499
  fr: {
1500
+ "common.close": "Fermer",
1498
1501
  "nav": "Sous-agents",
1499
1502
  "page.title": "Profils de sous-agents",
1500
1503
  "page.empty": "Aucun profil configuré. Ajoutez-en un ci-dessous.",
@@ -1574,6 +1577,7 @@ window.__ModuleLoader__.load({
1574
1577
  "repair.error": "Échec de la réparation"
1575
1578
  },
1576
1579
  pt: {
1580
+ "common.close": "Fechar",
1577
1581
  "nav": "Subagentes",
1578
1582
  "page.title": "Perfis de subagentes",
1579
1583
  "page.empty": "Nenhum perfil configurado. Adicione um abaixo.",
@@ -1653,6 +1657,7 @@ window.__ModuleLoader__.load({
1653
1657
  "repair.error": "Falha no reparo"
1654
1658
  },
1655
1659
  ko: {
1660
+ "common.close": "닫기",
1656
1661
  "nav": "하위 에이전트",
1657
1662
  "page.title": "하위 에이전트 프로필",
1658
1663
  "page.empty": "구성된 프로필이 없습니다. 아래에서 추가하세요.",
@@ -1732,6 +1737,7 @@ window.__ModuleLoader__.load({
1732
1737
  "repair.error": "복구 실패"
1733
1738
  },
1734
1739
  ar: {
1740
+ "common.close": "إغلاق",
1735
1741
  "nav": "الوكلاء الفرعيون",
1736
1742
  "page.title": "ملفات الوكلاء الفرعيين",
1737
1743
  "page.empty": "لم يتم تكوين أي ملف شخصي. أضف واحدًا أدناه.",
@@ -1811,6 +1817,7 @@ window.__ModuleLoader__.load({
1811
1817
  "repair.error": "فشل الإصلاح"
1812
1818
  },
1813
1819
  hi: {
1820
+ "common.close": "बंद करें",
1814
1821
  "nav": "उप-एजेंट",
1815
1822
  "page.title": "उप-एजेंट प्रोफ़ाइल",
1816
1823
  "page.empty": "कोई प्रोफ़ाइल कॉन्फ़िगर नहीं है। नीचे एक जोड़ें।",
@@ -1890,6 +1897,7 @@ window.__ModuleLoader__.load({
1890
1897
  "repair.error": "मरम्मत विफल"
1891
1898
  },
1892
1899
  id: {
1900
+ "common.close": "Tutup",
1893
1901
  "nav": "Sub-agen",
1894
1902
  "page.title": "Profil Sub-agen",
1895
1903
  "page.empty": "Belum ada profil yang dikonfigurasi. Tambahkan satu di bawah.",
@@ -1969,6 +1977,7 @@ window.__ModuleLoader__.load({
1969
1977
  "repair.error": "Perbaikan gagal"
1970
1978
  },
1971
1979
  tr: {
1980
+ "common.close": "Kapat",
1972
1981
  "nav": "Alt Aracılar",
1973
1982
  "page.title": "Alt Aracı Profilleri",
1974
1983
  "page.empty": "Yapılandırılmış profil yok. Aşağıya bir tane ekleyin.",
@@ -2048,6 +2057,7 @@ window.__ModuleLoader__.load({
2048
2057
  "repair.error": "Onarım başarısız"
2049
2058
  },
2050
2059
  vi: {
2060
+ "common.close": "Đóng",
2051
2061
  "nav": "Đại lý con",
2052
2062
  "page.title": "Hồ sơ đại lý con",
2053
2063
  "page.empty": "Chưa có hồ sơ nào được cấu hình. Hãy thêm một hồ sơ bên dưới.",
@@ -2127,6 +2137,7 @@ window.__ModuleLoader__.load({
2127
2137
  "repair.error": "Sửa thất bại"
2128
2138
  },
2129
2139
  th: {
2140
+ "common.close": "ปิด",
2130
2141
  "nav": "ตัวแทนย่อย",
2131
2142
  "page.title": "โปรไฟล์ตัวแทนย่อย",
2132
2143
  "page.empty": "ยังไม่มีการกำหนดโปรไฟล์ เพิ่มโปรไฟล์ด้านล่าง",
@@ -2206,6 +2217,7 @@ window.__ModuleLoader__.load({
2206
2217
  "repair.error": "ซ่อมแซมล้มเหลว"
2207
2218
  },
2208
2219
  ru: {
2220
+ "common.close": "Закрыть",
2209
2221
  "nav": "Суб-агенты",
2210
2222
  "page.title": "Профили суб-агентов",
2211
2223
  "page.empty": "Нет настроенных профилей. Добавьте один ниже.",
@@ -2285,6 +2297,7 @@ window.__ModuleLoader__.load({
2285
2297
  "repair.error": "Сбой восстановления"
2286
2298
  },
2287
2299
  it: {
2300
+ "common.close": "Chiudi",
2288
2301
  "nav": "Sotto-agenti",
2289
2302
  "page.title": "Profili sotto-agente",
2290
2303
  "page.empty": "Nessun profilo configurato. Aggiungine uno qui sotto.",
@@ -2364,6 +2377,7 @@ window.__ModuleLoader__.load({
2364
2377
  "repair.error": "Riparazione non riuscita"
2365
2378
  },
2366
2379
  nl: {
2380
+ "common.close": "Sluiten",
2367
2381
  "nav": "Sub-agenten",
2368
2382
  "page.title": "Sub-agentprofielen",
2369
2383
  "page.empty": "Geen profielen geconfigureerd. Voeg er hieronder een toe.",
@@ -2443,6 +2457,7 @@ window.__ModuleLoader__.load({
2443
2457
  "repair.error": "Reparatie mislukt"
2444
2458
  },
2445
2459
  sv: {
2460
+ "common.close": "Stäng",
2446
2461
  "nav": "Subagenter",
2447
2462
  "page.title": "Subagentprofiler",
2448
2463
  "page.empty": "Inga profiler konfigurerade. Lägg till en nedan.",
@@ -2522,6 +2537,7 @@ window.__ModuleLoader__.load({
2522
2537
  "repair.error": "Repareringen misslyckades"
2523
2538
  },
2524
2539
  pl: {
2540
+ "common.close": "Zamknij",
2525
2541
  "nav": "Pod-agenci",
2526
2542
  "page.title": "Profile pod-agentów",
2527
2543
  "page.empty": "Brak skonfigurowanych profili. Dodaj jeden poniżej.",
@@ -2601,6 +2617,7 @@ window.__ModuleLoader__.load({
2601
2617
  "repair.error": "Nie udało się naprawić"
2602
2618
  },
2603
2619
  "zh-HK": {
2620
+ "common.close": "關閉",
2604
2621
  "nav": "子代理",
2605
2622
  "page.title": "子代理設定",
2606
2623
  "page.empty": "暫無設定,請在下方新增。",
@@ -2680,6 +2697,7 @@ window.__ModuleLoader__.load({
2680
2697
  "repair.error": "修復失敗"
2681
2698
  },
2682
2699
  "zh-TW": {
2700
+ "common.close": "關閉",
2683
2701
  "nav": "子代理",
2684
2702
  "page.title": "子代理設定",
2685
2703
  "page.empty": "目前沒有設定,請在下方新增。",
@@ -2759,6 +2777,7 @@ window.__ModuleLoader__.load({
2759
2777
  "repair.error": "修復失敗"
2760
2778
  },
2761
2779
  "zh-MO": {
2780
+ "common.close": "關閉",
2762
2781
  "nav": "子代理",
2763
2782
  "page.title": "子代理設定",
2764
2783
  "page.empty": "暫無設定,請在下方新增。",
@@ -2844,6 +2863,7 @@ window.__ModuleLoader__.load({
2844
2863
  const NS = "ya-subagent";
2845
2864
  /** English dictionary. */
2846
2865
  const en = {
2866
+ "common.close": "Close",
2847
2867
  "nav": "Subagents",
2848
2868
  "page.title": "Subagent Profiles",
2849
2869
  "page.empty": "No profiles configured. Add one below.",
@@ -2908,7 +2928,7 @@ window.__ModuleLoader__.load({
2908
2928
  "tree.state.settled": "settled",
2909
2929
  "repair.button": "Repair session history",
2910
2930
  "repair.confirm.title": "Repair session history?",
2911
- "repair.confirm.body": "Scans every session log under $DSH_HOME/sessions and stamps \"ignorable\" on legacy ya-subagent/started events so the harness can load them again. Each modified file is backed up to .bak first.",
2931
+ "repair.confirm.body": "Scans every session log under $DSH_HOME/sessions and removes legacy ya-subagent/started events (renumbering later entries) so the harness can load the logs again. Each modified file is backed up to .bak first.",
2912
2932
  "repair.confirm.warning": "If dsh is running, a session being written right now may conflict; prefer running this when no agent is active.",
2913
2933
  "repair.confirm.cancel": "Cancel",
2914
2934
  "repair.confirm.proceed": "Repair",
@@ -2924,6 +2944,7 @@ window.__ModuleLoader__.load({
2924
2944
  };
2925
2945
  /** Chinese dictionary. */
2926
2946
  const zh = {
2947
+ "common.close": "关闭",
2927
2948
  "nav": "子代理",
2928
2949
  "page.title": "子代理配置",
2929
2950
  "page.empty": "暂无配置,请在下方添加。",
@@ -2988,7 +3009,7 @@ window.__ModuleLoader__.load({
2988
3009
  "tree.state.settled": "已结束",
2989
3010
  "repair.button": "修复历史会话",
2990
3011
  "repair.confirm.title": "修复历史会话?",
2991
- "repair.confirm.body": "将扫描 $DSH_HOME/sessions 下的所有会话日志,为遗留的 ya-subagent/started 事件补上 \"ignorable\" 标记,使 harness 能重新加载。每个被修改的文件会先备份为 .bak。",
3012
+ "repair.confirm.body": "将扫描 $DSH_HOME/sessions 下的所有会话日志,删除遗留的 ya-subagent/started 事件(并重排后续序号),使 harness 能重新加载日志。每个被修改的文件会先备份为 .bak。",
2992
3013
  "repair.confirm.warning": "若 dsh 正在运行,正在写入的会话可能冲突;建议在无活跃代理时执行。",
2993
3014
  "repair.confirm.cancel": "取消",
2994
3015
  "repair.confirm.proceed": "修复",
@@ -3054,20 +3075,25 @@ window.__ModuleLoader__.load({
3054
3075
  ctx.logger.error("ya-subagent: post-reset profile label fetch failed", error);
3055
3076
  });
3056
3077
  });
3078
+ const fetchModelCatalogInternal = async () => {
3079
+ const result = await connection.rpc.call("/api", "session/modelCatalog", {});
3080
+ return result.ok ? result.value : void 0;
3081
+ };
3057
3082
  const cardInjected = () => ({
3058
3083
  sessions: ctx.sessions,
3059
3084
  profileLabelOf: (id) => profileLabels.get(id)
3060
3085
  });
3061
- ctx.effect(() => ctx.slots.register({
3086
+ ctx.slots.inject("tool.call.toolview", () => ctx.slots.register({
3062
3087
  name: "tool.call.toolview",
3063
3088
  key: "subagent",
3064
3089
  locale: NS,
3065
3090
  inject: cardInjected
3066
- }, SubagentCard), "ya-subagent: subagent toolview");
3091
+ }, SubagentCard));
3067
3092
  const fetchProfiles = fetchProfilesInternal;
3068
3093
  const settingsInjected = () => ({
3069
3094
  rpc: connection.rpc,
3070
3095
  fetchProfiles,
3096
+ fetchModelCatalog: fetchModelCatalogInternal,
3071
3097
  t
3072
3098
  });
3073
3099
  ctx.slots.inject("settings.section", () => ctx.slots.register({