dominds 1.5.2 → 1.6.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/dist/apps/configuration-file.js +21 -0
- package/dist/apps/enabled-apps.js +3 -53
- package/dist/apps/local-package-root.js +41 -0
- package/dist/apps/runtime.js +10 -0
- package/dist/apps-host/client.js +124 -1
- package/dist/apps-host/host.js +53 -0
- package/dist/apps-host/ipc-types.js +61 -1
- package/dist/cli/install.js +41 -8
- package/dist/docs/app-constitution.md +22 -0
- package/dist/docs/app-constitution.zh.md +22 -0
- package/dist/llm/kernel-driver/runtime.js +112 -22
- package/dist/minds/load.js +20 -2
- package/dist/minds/system-prompt.js +4 -0
- package/dist/priming.js +2 -26
- package/dist/server/websocket-handler.js +5 -0
- package/dist/server.js +5 -2
- package/dist/shared/markdown-frontmatter.js +44 -0
- package/dist/shared/team_mgmt-manual.js +9 -0
- package/dist/skills/load.js +281 -0
- package/dist/static/assets/{_basePickBy-B-A5XrWM.js → _basePickBy-CFicLWwx.js} +3 -3
- package/dist/static/assets/{_basePickBy-B-A5XrWM.js.map → _basePickBy-CFicLWwx.js.map} +1 -1
- package/dist/static/assets/{_baseUniq-BANLb0cu.js → _baseUniq-DQTl8GFk.js} +2 -2
- package/dist/static/assets/{_baseUniq-BANLb0cu.js.map → _baseUniq-DQTl8GFk.js.map} +1 -1
- package/dist/static/assets/{arc-CYZYnojf.js → arc-Bc5lgJ6S.js} +2 -2
- package/dist/static/assets/{arc-CYZYnojf.js.map → arc-Bc5lgJ6S.js.map} +1 -1
- package/dist/static/assets/{architectureDiagram-VXUJARFQ-Cxf4pmYG.js → architectureDiagram-VXUJARFQ-DygUo6iw.js} +7 -7
- package/dist/static/assets/{architectureDiagram-VXUJARFQ-Cxf4pmYG.js.map → architectureDiagram-VXUJARFQ-DygUo6iw.js.map} +1 -1
- package/dist/static/assets/{blockDiagram-VD42YOAC-wvs0G30c.js → blockDiagram-VD42YOAC-0r3VY3gz.js} +7 -7
- package/dist/static/assets/{blockDiagram-VD42YOAC-wvs0G30c.js.map → blockDiagram-VD42YOAC-0r3VY3gz.js.map} +1 -1
- package/dist/static/assets/{c4Diagram-YG6GDRKO-BKFNexn4.js → c4Diagram-YG6GDRKO-pQD_vC1A.js} +3 -3
- package/dist/static/assets/{c4Diagram-YG6GDRKO-BKFNexn4.js.map → c4Diagram-YG6GDRKO-pQD_vC1A.js.map} +1 -1
- package/dist/static/assets/{channel-_1qpxJWy.js → channel-CHWYhNRt.js} +2 -2
- package/dist/static/assets/{channel-_1qpxJWy.js.map → channel-CHWYhNRt.js.map} +1 -1
- package/dist/static/assets/{chunk-4BX2VUAB-BIdC0phm.js → chunk-4BX2VUAB-K89xP4ET.js} +2 -2
- package/dist/static/assets/{chunk-4BX2VUAB-BIdC0phm.js.map → chunk-4BX2VUAB-K89xP4ET.js.map} +1 -1
- package/dist/static/assets/{chunk-55IACEB6-BNvGenQ9.js → chunk-55IACEB6-DHAy4AJ-.js} +2 -2
- package/dist/static/assets/{chunk-55IACEB6-BNvGenQ9.js.map → chunk-55IACEB6-DHAy4AJ-.js.map} +1 -1
- package/dist/static/assets/{chunk-B4BG7PRW-jmf-1Wv7.js → chunk-B4BG7PRW-BrImUg93.js} +5 -5
- package/dist/static/assets/{chunk-B4BG7PRW-jmf-1Wv7.js.map → chunk-B4BG7PRW-BrImUg93.js.map} +1 -1
- package/dist/static/assets/{chunk-DI55MBZ5-nmEmcikR.js → chunk-DI55MBZ5-_jVBMKQY.js} +4 -4
- package/dist/static/assets/{chunk-DI55MBZ5-nmEmcikR.js.map → chunk-DI55MBZ5-_jVBMKQY.js.map} +1 -1
- package/dist/static/assets/{chunk-FMBD7UC4-kGysaq_j.js → chunk-FMBD7UC4-BmGs24Z_.js} +2 -2
- package/dist/static/assets/{chunk-FMBD7UC4-kGysaq_j.js.map → chunk-FMBD7UC4-BmGs24Z_.js.map} +1 -1
- package/dist/static/assets/{chunk-QN33PNHL-8JwMLFIJ.js → chunk-QN33PNHL-Bu8ZzYdl.js} +2 -2
- package/dist/static/assets/{chunk-QN33PNHL-8JwMLFIJ.js.map → chunk-QN33PNHL-Bu8ZzYdl.js.map} +1 -1
- package/dist/static/assets/{chunk-QZHKN3VN-DZleEj00.js → chunk-QZHKN3VN-D4fM_-kX.js} +2 -2
- package/dist/static/assets/{chunk-QZHKN3VN-DZleEj00.js.map → chunk-QZHKN3VN-D4fM_-kX.js.map} +1 -1
- package/dist/static/assets/{chunk-TZMSLE5B-CXxl_uqH.js → chunk-TZMSLE5B-xK6Lo8h6.js} +2 -2
- package/dist/static/assets/{chunk-TZMSLE5B-CXxl_uqH.js.map → chunk-TZMSLE5B-xK6Lo8h6.js.map} +1 -1
- package/dist/static/assets/{classDiagram-2ON5EDUG-C-7R0QB6.js → classDiagram-2ON5EDUG-Bn36uVsZ.js} +6 -6
- package/dist/static/assets/{classDiagram-2ON5EDUG-C-7R0QB6.js.map → classDiagram-2ON5EDUG-Bn36uVsZ.js.map} +1 -1
- package/dist/static/assets/{classDiagram-v2-WZHVMYZB-C-7R0QB6.js → classDiagram-v2-WZHVMYZB-Bn36uVsZ.js} +6 -6
- package/dist/static/assets/{classDiagram-v2-WZHVMYZB-C-7R0QB6.js.map → classDiagram-v2-WZHVMYZB-Bn36uVsZ.js.map} +1 -1
- package/dist/static/assets/{clone-BwOKYSj8.js → clone-BUW9sxY1.js} +2 -2
- package/dist/static/assets/{clone-BwOKYSj8.js.map → clone-BUW9sxY1.js.map} +1 -1
- package/dist/static/assets/{cose-bilkent-S5V4N54A-BCBalM7p.js → cose-bilkent-S5V4N54A-BMTYUmA4.js} +2 -2
- package/dist/static/assets/{cose-bilkent-S5V4N54A-BCBalM7p.js.map → cose-bilkent-S5V4N54A-BMTYUmA4.js.map} +1 -1
- package/dist/static/assets/{dagre-6UL2VRFP-uV2ekQoj.js → dagre-6UL2VRFP-p-0HOF0Q.js} +7 -7
- package/dist/static/assets/{dagre-6UL2VRFP-uV2ekQoj.js.map → dagre-6UL2VRFP-p-0HOF0Q.js.map} +1 -1
- package/dist/static/assets/{diagram-PSM6KHXK-D-ZMog1-.js → diagram-PSM6KHXK-CfpXvSJR.js} +8 -8
- package/dist/static/assets/{diagram-PSM6KHXK-D-ZMog1-.js.map → diagram-PSM6KHXK-CfpXvSJR.js.map} +1 -1
- package/dist/static/assets/{diagram-QEK2KX5R-BThSELUH.js → diagram-QEK2KX5R-3T4XwT5a.js} +7 -7
- package/dist/static/assets/{diagram-QEK2KX5R-BThSELUH.js.map → diagram-QEK2KX5R-3T4XwT5a.js.map} +1 -1
- package/dist/static/assets/{diagram-S2PKOQOG-Di-YN5cd.js → diagram-S2PKOQOG-CPHGTwGV.js} +7 -7
- package/dist/static/assets/{diagram-S2PKOQOG-Di-YN5cd.js.map → diagram-S2PKOQOG-CPHGTwGV.js.map} +1 -1
- package/dist/static/assets/{erDiagram-Q2GNP2WA-lBZ9DITn.js → erDiagram-Q2GNP2WA-Bj7OGj2H.js} +5 -5
- package/dist/static/assets/{erDiagram-Q2GNP2WA-lBZ9DITn.js.map → erDiagram-Q2GNP2WA-Bj7OGj2H.js.map} +1 -1
- package/dist/static/assets/{flowDiagram-NV44I4VS-C_60PNQR.js → flowDiagram-NV44I4VS-DOGilHpN.js} +6 -6
- package/dist/static/assets/{flowDiagram-NV44I4VS-C_60PNQR.js.map → flowDiagram-NV44I4VS-DOGilHpN.js.map} +1 -1
- package/dist/static/assets/{ganttDiagram-JELNMOA3-Dvqq-VHJ.js → ganttDiagram-JELNMOA3-585cSoqi.js} +3 -3
- package/dist/static/assets/{ganttDiagram-JELNMOA3-Dvqq-VHJ.js.map → ganttDiagram-JELNMOA3-585cSoqi.js.map} +1 -1
- package/dist/static/assets/{gitGraphDiagram-V2S2FVAM-BTj8orRe.js → gitGraphDiagram-V2S2FVAM-gmTvHjpH.js} +8 -8
- package/dist/static/assets/{gitGraphDiagram-V2S2FVAM-BTj8orRe.js.map → gitGraphDiagram-V2S2FVAM-gmTvHjpH.js.map} +1 -1
- package/dist/static/assets/{graph-BqCzR2Nl.js → graph-Dtj8yklH.js} +3 -3
- package/dist/static/assets/{graph-BqCzR2Nl.js.map → graph-Dtj8yklH.js.map} +1 -1
- package/dist/static/assets/{index-DrTqAfFy.js → index-BvNwR1gS.js} +442 -246
- package/dist/static/assets/index-BvNwR1gS.js.map +1 -0
- package/dist/static/assets/{infoDiagram-HS3SLOUP-DlC6wsrv.js → infoDiagram-HS3SLOUP-BVq8aa78.js} +6 -6
- package/dist/static/assets/{infoDiagram-HS3SLOUP-DlC6wsrv.js.map → infoDiagram-HS3SLOUP-BVq8aa78.js.map} +1 -1
- package/dist/static/assets/{journeyDiagram-XKPGCS4Q-Dg_RgtQX.js → journeyDiagram-XKPGCS4Q-BY5Lcmin.js} +5 -5
- package/dist/static/assets/{journeyDiagram-XKPGCS4Q-Dg_RgtQX.js.map → journeyDiagram-XKPGCS4Q-BY5Lcmin.js.map} +1 -1
- package/dist/static/assets/{kanban-definition-3W4ZIXB7-DuGS3lId.js → kanban-definition-3W4ZIXB7-zEbpyocs.js} +3 -3
- package/dist/static/assets/{kanban-definition-3W4ZIXB7-DuGS3lId.js.map → kanban-definition-3W4ZIXB7-zEbpyocs.js.map} +1 -1
- package/dist/static/assets/{layout-FDz2bstZ.js → layout-Bst5DR3z.js} +5 -5
- package/dist/static/assets/{layout-FDz2bstZ.js.map → layout-Bst5DR3z.js.map} +1 -1
- package/dist/static/assets/{linear-CzsdvPGb.js → linear-TSyBw4eX.js} +2 -2
- package/dist/static/assets/{linear-CzsdvPGb.js.map → linear-TSyBw4eX.js.map} +1 -1
- package/dist/static/assets/{mindmap-definition-VGOIOE7T-WsAF5UNp.js → mindmap-definition-VGOIOE7T-I6ArhFTa.js} +4 -4
- package/dist/static/assets/{mindmap-definition-VGOIOE7T-WsAF5UNp.js.map → mindmap-definition-VGOIOE7T-I6ArhFTa.js.map} +1 -1
- package/dist/static/assets/{pieDiagram-ADFJNKIX-DJpRJ5ei.js → pieDiagram-ADFJNKIX-DdaOCLgH.js} +8 -8
- package/dist/static/assets/{pieDiagram-ADFJNKIX-DJpRJ5ei.js.map → pieDiagram-ADFJNKIX-DdaOCLgH.js.map} +1 -1
- package/dist/static/assets/{quadrantDiagram-AYHSOK5B-CMyIzTkY.js → quadrantDiagram-AYHSOK5B-Bp82x7cE.js} +3 -3
- package/dist/static/assets/{quadrantDiagram-AYHSOK5B-CMyIzTkY.js.map → quadrantDiagram-AYHSOK5B-Bp82x7cE.js.map} +1 -1
- package/dist/static/assets/{requirementDiagram-UZGBJVZJ-D_yqVXGu.js → requirementDiagram-UZGBJVZJ-eSQPrL7r.js} +4 -4
- package/dist/static/assets/{requirementDiagram-UZGBJVZJ-D_yqVXGu.js.map → requirementDiagram-UZGBJVZJ-eSQPrL7r.js.map} +1 -1
- package/dist/static/assets/{sankeyDiagram-TZEHDZUN-D4-cF724.js → sankeyDiagram-TZEHDZUN-DbMClHuR.js} +2 -2
- package/dist/static/assets/{sankeyDiagram-TZEHDZUN-D4-cF724.js.map → sankeyDiagram-TZEHDZUN-DbMClHuR.js.map} +1 -1
- package/dist/static/assets/{sequenceDiagram-WL72ISMW-B7J3gWYN.js → sequenceDiagram-WL72ISMW-CxQHJ2QR.js} +4 -4
- package/dist/static/assets/{sequenceDiagram-WL72ISMW-B7J3gWYN.js.map → sequenceDiagram-WL72ISMW-CxQHJ2QR.js.map} +1 -1
- package/dist/static/assets/{stateDiagram-FKZM4ZOC-DwEYYCcu.js → stateDiagram-FKZM4ZOC-BrJWwcfT.js} +9 -9
- package/dist/static/assets/{stateDiagram-FKZM4ZOC-DwEYYCcu.js.map → stateDiagram-FKZM4ZOC-BrJWwcfT.js.map} +1 -1
- package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-D4LOOQV5.js → stateDiagram-v2-4FDKWEC3-AOoa1rfD.js} +5 -5
- package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-D4LOOQV5.js.map → stateDiagram-v2-4FDKWEC3-AOoa1rfD.js.map} +1 -1
- package/dist/static/assets/{timeline-definition-IT6M3QCI-CyG-TJ_A.js → timeline-definition-IT6M3QCI-CGDQb8vq.js} +3 -3
- package/dist/static/assets/{timeline-definition-IT6M3QCI-CyG-TJ_A.js.map → timeline-definition-IT6M3QCI-CGDQb8vq.js.map} +1 -1
- package/dist/static/assets/{treemap-GDKQZRPO-yY4GiKmU.js → treemap-GDKQZRPO-DUkGxSl_.js} +5 -5
- package/dist/static/assets/{treemap-GDKQZRPO-yY4GiKmU.js.map → treemap-GDKQZRPO-DUkGxSl_.js.map} +1 -1
- package/dist/static/assets/{xychartDiagram-PRI3JC2R-5TYN_q15.js → xychartDiagram-PRI3JC2R-DhC3pydn.js} +3 -3
- package/dist/static/assets/{xychartDiagram-PRI3JC2R-5TYN_q15.js.map → xychartDiagram-PRI3JC2R-DhC3pydn.js.map} +1 -1
- package/dist/static/index.html +1 -1
- package/dist/team-config-updates.js +26 -0
- package/dist/team.js +23 -5
- package/dist/tools/team_mgmt.js +137 -0
- package/dist/tools/toolset-manual.js +12 -3
- package/package.json +1 -1
- package/dist/static/assets/index-DrTqAfFy.js.map +0 -1
|
@@ -206,6 +206,19 @@ Recommended user mental model:
|
|
|
206
206
|
- If `configuration.yaml` is missing, strategy falls back to defaults (`order=['local']`, `localRoots=['dominds-apps']`) and no explicit disables apply.
|
|
207
207
|
- If `resolution.yaml` is missing, the snapshot starts empty and the kernel re-materializes it from the declared dependency graph.
|
|
208
208
|
|
|
209
|
+
(Current: implemented) self-heal behavior for common entrypoints is:
|
|
210
|
+
|
|
211
|
+
- `dominds webui`: the server startup path initializes apps runtime and re-materializes `<rtws>/.apps/resolution.yaml`.
|
|
212
|
+
- `dominds tui` / `dominds run`: before entering interactive runtime, Dominds refreshes enabled-app runtime/tool proxies and re-materializes `resolution.yaml`.
|
|
213
|
+
- `dominds read` / `dominds manual`: Dominds refreshes enabled app tool proxies first; if the root manifest still declares dependencies, this also re-materializes `resolution.yaml`.
|
|
214
|
+
|
|
215
|
+
Self-heal only works when both prerequisites hold:
|
|
216
|
+
|
|
217
|
+
- root `.minds/app.yaml` still declares the correct app id (for example `web-dev`), and
|
|
218
|
+
- the current resolution strategy can actually resolve that app (for example, default `localRoots=['dominds-apps']` contains `dominds-apps/web-dev/`, and that package's install handshake / manifest also declares the same app id).
|
|
219
|
+
|
|
220
|
+
If the root manifest / team config uses the wrong app id (for example, still declaring the legacy id `web_dev` inside `dependencies[].id` or `members.<id>.from` while the app now installs as `web-dev`), refresh will still re-materialize `resolution.yaml` as empty. That means self-heal did run; it just correctly recomputed an empty result from incorrect source declarations.
|
|
221
|
+
|
|
209
222
|
So even without `<rtws>/.apps/configuration.yaml` or `<rtws>/.apps/resolution.yaml`, as long as `.minds/app.yaml` declares dependencies, the kernel still resolves local apps via the default strategy; if the root manifest has no dependencies, the effective enabled apps set is empty.
|
|
210
223
|
|
|
211
224
|
## App-provided `.minds/**` assets
|
|
@@ -306,6 +319,14 @@ dominds install ./dominds-apps/web-dev --local --enable
|
|
|
306
319
|
dominds install @longrun-ai/web-dev --enable
|
|
307
320
|
```
|
|
308
321
|
|
|
322
|
+
Web Dev App needs three names kept distinct to avoid drift:
|
|
323
|
+
|
|
324
|
+
- installable app id: `web-dev`
|
|
325
|
+
- local development directory: `dominds-apps/web-dev/`
|
|
326
|
+
- npm package name: `@longrun-ai/web-dev`
|
|
327
|
+
|
|
328
|
+
That means workspace `.minds/app.yaml` `dependencies[].id`, `.minds/team.yaml` `members.<id>.from`, and `<rtws>/.apps/resolution.yaml` `apps[].id` must all use `web-dev`; the directory and package naming surfaces also stay `web-dev` so the app no longer carries two spellings.
|
|
329
|
+
|
|
309
330
|
After installation, the user should expect these files to change:
|
|
310
331
|
|
|
311
332
|
- `.minds/app.yaml`: root dependency declaration is updated.
|
|
@@ -380,6 +401,7 @@ Requirements for the `playwright_interactive` toolset design:
|
|
|
380
401
|
Current prototype note (`dominds-apps/web-dev`, as of March 8, 2026):
|
|
381
402
|
|
|
382
403
|
- The app is already installable and contributes `web_tester` / `web_developer` teammates plus a live `playwright_interactive` toolset registration.
|
|
404
|
+
- The installable app id remains `web-dev`; the directory name and npm package also keep the same `web-dev` spelling so the app no longer carries split naming.
|
|
383
405
|
- `playwright_session_new/list/status/eval/attach/detach/close` and cross-dialog reminder sync are already implemented.
|
|
384
406
|
- `kind: "web"` sessions now create a real Playwright-backed browser/context/page runtime and report live page surfaces via session status/reminders.
|
|
385
407
|
- `kind: "electron"` is **not** at the same completion level yet: it still falls back to the older prototype runtime path and should be treated as unfinished.
|
|
@@ -205,6 +205,19 @@ rtws 是一次运行的工作区根目录(`process.cwd()`)。Kernel 在其
|
|
|
205
205
|
- 若 `configuration.yaml` 缺失:strategy 使用默认值(`order=['local']`,`localRoots=['dominds-apps']`),且没有显式 disable。
|
|
206
206
|
- 若 `resolution.yaml` 缺失:视为空快照,Kernel 会根据当前声明依赖重新解析并写回结果。
|
|
207
207
|
|
|
208
|
+
(现状:已实现)常规入口的自愈口径如下:
|
|
209
|
+
|
|
210
|
+
- `dominds webui`:server 启动链会初始化 apps runtime,并重新物化 `<rtws>/.apps/resolution.yaml`。
|
|
211
|
+
- `dominds tui` / `dominds run`:进入交互 runtime 前会刷新 enabled apps runtime / tool proxies,并重新物化 `resolution.yaml`。
|
|
212
|
+
- `dominds read` / `dominds manual`:会先刷新 enabled app tool proxies;若根 manifest 仍声明依赖,也会触发 `resolution.yaml` 的重新物化。
|
|
213
|
+
|
|
214
|
+
自愈成立的前提必须同时满足:
|
|
215
|
+
|
|
216
|
+
- 根 `.minds/app.yaml` 仍声明了正确的 app id(例如 `web-dev`)。
|
|
217
|
+
- 当前 resolution strategy 能解析到对应 app(例如默认 `localRoots=['dominds-apps']` 下存在 `dominds-apps/web-dev/`,且该包的 install handshake / manifest 也声明同一个 app id)。
|
|
218
|
+
|
|
219
|
+
若根 manifest / team.yaml 使用了错误的 app id(例如 app 已改为 `web-dev`,但 `dependencies[].id` 或 `members.<id>.from` 里仍保留 legacy `web_dev`),那么 refresh 仍会把 `resolution.yaml` 重新物化为空;这不是“自愈没跑”,而是“它按错误声明正确地重算出了空结果”。
|
|
220
|
+
|
|
208
221
|
因此,即使缺少 `<rtws>/.apps/configuration.yaml` 或 `<rtws>/.apps/resolution.yaml`,只要 `.minds/app.yaml` 声明了依赖,Kernel 仍会按默认策略去解析本地 app;反之若根 manifest 没有依赖,则最终 enabled apps 为空。
|
|
209
222
|
|
|
210
223
|
## App 可提供的 `.minds/**` 资产
|
|
@@ -304,6 +317,14 @@ dominds install ./dominds-apps/web-dev --local --enable
|
|
|
304
317
|
dominds install @longrun-ai/web-dev --enable
|
|
305
318
|
```
|
|
306
319
|
|
|
320
|
+
Web Dev App 需要明确区分三套命名,避免再次漂移:
|
|
321
|
+
|
|
322
|
+
- installable app id:`web-dev`
|
|
323
|
+
- 本地开发目录:`dominds-apps/web-dev/`
|
|
324
|
+
- npm package name:`@longrun-ai/web-dev`
|
|
325
|
+
|
|
326
|
+
也就是说,workspace `.minds/app.yaml` 的 `dependencies[].id`、`.minds/team.yaml` 的 `members.<id>.from`,以及 `<rtws>/.apps/resolution.yaml` 的 `apps[].id` 都应使用 `web-dev`;目录名与 package name 也统一保持 `web-dev`,避免同一 app 在不同层面出现双拼写。
|
|
327
|
+
|
|
307
328
|
安装完成后,用户应预期以下文件发生变化:
|
|
308
329
|
|
|
309
330
|
- `.minds/app.yaml`:增加根依赖声明。
|
|
@@ -378,6 +399,7 @@ members:
|
|
|
378
399
|
当前 prototype 说明(`dominds-apps/web-dev`,截至 2026-03-08):
|
|
379
400
|
|
|
380
401
|
- 该 app 已可安装,并已贡献 `web_tester` / `web_developer` teammate 与可用的 `playwright_interactive` toolset 注册。
|
|
402
|
+
- installable app id 当前固定为 `web-dev`;目录名与 npm package 名也保持 `web-dev`,避免多套命名并存。
|
|
381
403
|
- `playwright_session_new/list/status/eval/attach/detach/close` 与跨对话 reminder sync 已落地。
|
|
382
404
|
- `kind: "web"` 会话现在会创建真实的 Playwright browser/context/page runtime,并通过 status/reminder 报告实时页面 surface。
|
|
383
405
|
- `kind: "electron"` 还没有达到同等完成度:当前仍回落到旧的 prototype runtime 路径,应视为未完成能力。
|
|
@@ -265,6 +265,32 @@ function isRetriableLlmErrorCode(code) {
|
|
|
265
265
|
return false;
|
|
266
266
|
return RETRIABLE_LLM_ERROR_CODES.has(code);
|
|
267
267
|
}
|
|
268
|
+
function isOpenAiRetriableProcessingFailureMessage(lowerMessage) {
|
|
269
|
+
if (!lowerMessage.includes('processing your request')) {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
if (lowerMessage.includes('you can retry your request') ||
|
|
273
|
+
lowerMessage.includes('please retry your request')) {
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
return lowerMessage.includes('help.openai.com') && lowerMessage.includes('request id');
|
|
277
|
+
}
|
|
278
|
+
function isRetriableLlmMessage(message) {
|
|
279
|
+
const lower = message.toLowerCase();
|
|
280
|
+
if (lower.includes('fetch failed') || lower.includes('socket hang up')) {
|
|
281
|
+
return true;
|
|
282
|
+
}
|
|
283
|
+
if (lower.includes('terminated')) {
|
|
284
|
+
return true;
|
|
285
|
+
}
|
|
286
|
+
if (lower.includes('timeout') || lower.includes('timed out') || lower.includes('rate limit')) {
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
if (isOpenAiRetriableProcessingFailureMessage(lower)) {
|
|
290
|
+
return true;
|
|
291
|
+
}
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
268
294
|
function classifyLlmFailure(err) {
|
|
269
295
|
const fallbackMessage = err instanceof Error
|
|
270
296
|
? err.message || err.name
|
|
@@ -292,16 +318,7 @@ function classifyLlmFailure(err) {
|
|
|
292
318
|
? err
|
|
293
319
|
: undefined;
|
|
294
320
|
if (typeof msg === 'string' && msg.length > 0) {
|
|
295
|
-
|
|
296
|
-
if (lower.includes('fetch failed') || lower.includes('socket hang up')) {
|
|
297
|
-
return { kind: 'retriable', code: errCode ?? causeCode, message: msg };
|
|
298
|
-
}
|
|
299
|
-
if (lower.includes('terminated')) {
|
|
300
|
-
return { kind: 'retriable', code: errCode ?? causeCode, message: msg };
|
|
301
|
-
}
|
|
302
|
-
if (lower.includes('timeout') ||
|
|
303
|
-
lower.includes('timed out') ||
|
|
304
|
-
lower.includes('rate limit')) {
|
|
321
|
+
if (isRetriableLlmMessage(msg)) {
|
|
305
322
|
return { kind: 'retriable', code: errCode ?? causeCode, message: msg };
|
|
306
323
|
}
|
|
307
324
|
}
|
|
@@ -327,14 +344,7 @@ function classifyLlmFailure(err) {
|
|
|
327
344
|
if (isRetriableLlmErrorCode(code)) {
|
|
328
345
|
return { kind: 'retriable', code, message: msg };
|
|
329
346
|
}
|
|
330
|
-
|
|
331
|
-
if (lower.includes('fetch failed') || lower.includes('socket hang up')) {
|
|
332
|
-
return { kind: 'retriable', code: code ?? causeCode, message: msg };
|
|
333
|
-
}
|
|
334
|
-
if (lower.includes('terminated')) {
|
|
335
|
-
return { kind: 'retriable', code: code ?? causeCode, message: msg };
|
|
336
|
-
}
|
|
337
|
-
if (lower.includes('timeout') || lower.includes('timed out') || lower.includes('rate limit')) {
|
|
347
|
+
if (isRetriableLlmMessage(msg)) {
|
|
338
348
|
return { kind: 'retriable', code: code ?? causeCode, message: msg };
|
|
339
349
|
}
|
|
340
350
|
}
|
|
@@ -399,8 +409,23 @@ async function runLlmRequestWithRetry(params) {
|
|
|
399
409
|
const retryInitialDelayMs = normalizeRetryInitialDelayMs(params.retryInitialDelayMs);
|
|
400
410
|
const retryBackoffMultiplier = normalizeRetryBackoffMultiplier(params.retryBackoffMultiplier);
|
|
401
411
|
const retryMaxDelayMs = normalizeRetryMaxDelayMs(params.retryMaxDelayMs, retryInitialDelayMs);
|
|
412
|
+
const retryFlowStartedAtMs = Date.now();
|
|
413
|
+
let activeRetryContext;
|
|
402
414
|
for (let attempt = 0; attempt <= params.maxRetries; attempt++) {
|
|
403
415
|
try {
|
|
416
|
+
if (attempt > 0 && activeRetryContext) {
|
|
417
|
+
emitLlmRetryEventBestEffort({
|
|
418
|
+
dlg: params.dlg,
|
|
419
|
+
phase: 'running',
|
|
420
|
+
provider: params.provider,
|
|
421
|
+
attempt: attempt + 1,
|
|
422
|
+
totalAttempts,
|
|
423
|
+
maxRetries: params.maxRetries,
|
|
424
|
+
retriesRemaining: Math.max(0, params.maxRetries - attempt),
|
|
425
|
+
failure: activeRetryContext.failure,
|
|
426
|
+
errorText: activeRetryContext.errorText,
|
|
427
|
+
});
|
|
428
|
+
}
|
|
404
429
|
const res = await params.doRequest();
|
|
405
430
|
(0, problems_1.removeProblem)(providerProblemId);
|
|
406
431
|
return res;
|
|
@@ -496,14 +521,26 @@ async function runLlmRequestWithRetry(params) {
|
|
|
496
521
|
catch {
|
|
497
522
|
// best-effort
|
|
498
523
|
}
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
524
|
+
if (canRetry) {
|
|
525
|
+
const interruptionDetail = formatLlmRetryExhaustedInterruptionDetail({
|
|
526
|
+
language: params.dlg.getLastUserLanguageCode(),
|
|
527
|
+
provider: params.provider,
|
|
528
|
+
totalAttempts,
|
|
529
|
+
maxRetries: params.maxRetries,
|
|
530
|
+
elapsedMs: Date.now() - retryFlowStartedAtMs,
|
|
531
|
+
retryInitialDelayMs,
|
|
532
|
+
retryBackoffMultiplier,
|
|
533
|
+
retryMaxDelayMs,
|
|
534
|
+
errorText: detail,
|
|
535
|
+
});
|
|
536
|
+
throw new Error(interruptionDetail);
|
|
537
|
+
}
|
|
538
|
+
throw new Error(`LLM failed: ${failure.message}`);
|
|
502
539
|
}
|
|
503
540
|
const backoffMs = Math.min(retryMaxDelayMs, Math.max(0, Math.floor(retryInitialDelayMs * retryBackoffMultiplier ** attempt)));
|
|
504
541
|
emitLlmRetryEventBestEffort({
|
|
505
542
|
dlg: params.dlg,
|
|
506
|
-
phase: '
|
|
543
|
+
phase: 'waiting',
|
|
507
544
|
provider: params.provider,
|
|
508
545
|
attempt: attemptNo,
|
|
509
546
|
totalAttempts,
|
|
@@ -513,6 +550,10 @@ async function runLlmRequestWithRetry(params) {
|
|
|
513
550
|
failure,
|
|
514
551
|
errorText: detail,
|
|
515
552
|
});
|
|
553
|
+
activeRetryContext = {
|
|
554
|
+
failure,
|
|
555
|
+
errorText: detail,
|
|
556
|
+
};
|
|
516
557
|
log_1.log.warn(`Retrying LLM request after retriable error`, undefined, {
|
|
517
558
|
provider: params.provider,
|
|
518
559
|
attempt: attemptNo,
|
|
@@ -531,3 +572,52 @@ async function runLlmRequestWithRetry(params) {
|
|
|
531
572
|
}
|
|
532
573
|
throw new Error('LLM failed.');
|
|
533
574
|
}
|
|
575
|
+
function formatRetryElapsedDuration(language, elapsedMsRaw) {
|
|
576
|
+
const elapsedMs = Math.max(0, Math.floor(elapsedMsRaw));
|
|
577
|
+
if (elapsedMs < 1000) {
|
|
578
|
+
return `${elapsedMs}ms`;
|
|
579
|
+
}
|
|
580
|
+
const totalSeconds = elapsedMs / 1000;
|
|
581
|
+
if (totalSeconds < 60) {
|
|
582
|
+
const text = totalSeconds >= 10 ? totalSeconds.toFixed(1) : totalSeconds.toFixed(2);
|
|
583
|
+
return language === 'zh' ? `${text} 秒` : `${text}s`;
|
|
584
|
+
}
|
|
585
|
+
const wholeSeconds = Math.round(totalSeconds);
|
|
586
|
+
const minutes = Math.floor(wholeSeconds / 60);
|
|
587
|
+
const seconds = wholeSeconds % 60;
|
|
588
|
+
if (language === 'zh') {
|
|
589
|
+
return seconds === 0 ? `${minutes} 分钟` : `${minutes} 分 ${seconds} 秒`;
|
|
590
|
+
}
|
|
591
|
+
return seconds === 0 ? `${minutes}m` : `${minutes}m ${seconds}s`;
|
|
592
|
+
}
|
|
593
|
+
function formatLlmRetryExhaustedInterruptionDetail(args) {
|
|
594
|
+
const providerPath = `providers.${args.provider}`;
|
|
595
|
+
const durationText = formatRetryElapsedDuration(args.language, args.elapsedMs);
|
|
596
|
+
const trimmedError = args.errorText.trim();
|
|
597
|
+
if (args.language === 'zh') {
|
|
598
|
+
return (`LLM 自动重试已耗尽:provider=${args.provider},共尝试 ${args.totalAttempts} 次` +
|
|
599
|
+
`(初始请求 1 次 + 重试 ${args.maxRetries} 次),总耗时 ${durationText}。` +
|
|
600
|
+
`当前重试配置:llm_retry_max_retries=${args.maxRetries},` +
|
|
601
|
+
`llm_retry_initial_delay_ms=${args.retryInitialDelayMs},` +
|
|
602
|
+
`llm_retry_backoff_multiplier=${args.retryBackoffMultiplier},` +
|
|
603
|
+
`llm_retry_max_delay_ms=${args.retryMaxDelayMs}。` +
|
|
604
|
+
`若想增加重试次数或拉长重试间隔,请编辑 \`.minds/llm.yaml\` 中的 ` +
|
|
605
|
+
`\`${providerPath}.llm_retry_max_retries\`、` +
|
|
606
|
+
`\`${providerPath}.llm_retry_initial_delay_ms\`、` +
|
|
607
|
+
`\`${providerPath}.llm_retry_backoff_multiplier\`、` +
|
|
608
|
+
`\`${providerPath}.llm_retry_max_delay_ms\`,并检查 provider / network 稳定性。` +
|
|
609
|
+
`最后错误:${trimmedError}`);
|
|
610
|
+
}
|
|
611
|
+
return (`LLM automatic retries exhausted: provider=${args.provider}, ${args.totalAttempts} attempts total ` +
|
|
612
|
+
`(1 initial request + ${args.maxRetries} retries), elapsed ${durationText}. ` +
|
|
613
|
+
`Current retry config: llm_retry_max_retries=${args.maxRetries}, ` +
|
|
614
|
+
`llm_retry_initial_delay_ms=${args.retryInitialDelayMs}, ` +
|
|
615
|
+
`llm_retry_backoff_multiplier=${args.retryBackoffMultiplier}, ` +
|
|
616
|
+
`llm_retry_max_delay_ms=${args.retryMaxDelayMs}. ` +
|
|
617
|
+
`If you want more retries or longer retry intervals, edit ` +
|
|
618
|
+
`\`.minds/llm.yaml\`: \`${providerPath}.llm_retry_max_retries\`, ` +
|
|
619
|
+
`\`${providerPath}.llm_retry_initial_delay_ms\`, ` +
|
|
620
|
+
`\`${providerPath}.llm_retry_backoff_multiplier\`, ` +
|
|
621
|
+
`\`${providerPath}.llm_retry_max_delay_ms\`, and verify provider/network stability. ` +
|
|
622
|
+
`Last error: ${trimmedError}`);
|
|
623
|
+
}
|
package/dist/minds/load.js
CHANGED
|
@@ -11,6 +11,7 @@ const dialog_1 = require("../dialog");
|
|
|
11
11
|
const log_1 = require("../log");
|
|
12
12
|
const runtime_language_1 = require("../shared/runtime-language");
|
|
13
13
|
const time_1 = require("../shared/utils/time");
|
|
14
|
+
const load_1 = require("../skills/load");
|
|
14
15
|
const team_1 = require("../team");
|
|
15
16
|
const ctrl_1 = require("../tools/ctrl");
|
|
16
17
|
const shell_tools_1 = require("../tools/shell-tools");
|
|
@@ -142,6 +143,15 @@ async function loadAgentMinds(agentId, dialog, options) {
|
|
|
142
143
|
const knowledge = knowledgeRaw && knowledgeRaw.trim() !== '' ? knowledgeRaw : none;
|
|
143
144
|
const lessons = lessonsRaw && lessonsRaw.trim() !== '' ? lessonsRaw : none;
|
|
144
145
|
const envIntro = envIntroRaw && envIntroRaw.trim() !== '' ? envIntroRaw : '';
|
|
146
|
+
const workspaceSkills = await (0, load_1.loadWorkspaceSkills)({
|
|
147
|
+
rtwsRootAbs: process.cwd(),
|
|
148
|
+
memberId: agent.id,
|
|
149
|
+
language: workingLanguage,
|
|
150
|
+
});
|
|
151
|
+
const skillsText = (0, load_1.renderWorkspaceSkillsPrompt)({
|
|
152
|
+
language: workingLanguage,
|
|
153
|
+
skills: workspaceSkills,
|
|
154
|
+
});
|
|
145
155
|
// Introduction of all team members (mark "(self)" for the current agent)
|
|
146
156
|
const teamIntro = (0, system_prompt_1.formatTeamIntro)(team, agent.id, workingLanguage);
|
|
147
157
|
// Compose tool list from member's resolved toolsets and tools + built-in human tool
|
|
@@ -149,8 +159,15 @@ async function loadAgentMinds(agentId, dialog, options) {
|
|
|
149
159
|
// shell_specialists is intended for visible teammates only. Hidden members are exempt from this
|
|
150
160
|
// policy and may carry shell tools.
|
|
151
161
|
const agentIsShellSpecialist = team.shellSpecialists.includes(agent.id) || agent.hidden === true;
|
|
162
|
+
const dynamicToolsetNames = await team_1.Team.listDynamicToolsetNamesForMember({
|
|
163
|
+
member: agent,
|
|
164
|
+
taskDocPath: dialog?.taskDocPath,
|
|
165
|
+
});
|
|
152
166
|
const baseAgentTools = (() => {
|
|
153
|
-
const tools = agent.listTools({
|
|
167
|
+
const tools = agent.listTools({
|
|
168
|
+
onMissingToolset: missingToolsetPolicy,
|
|
169
|
+
dynamicToolsetNames,
|
|
170
|
+
});
|
|
154
171
|
if (agentIsShellSpecialist)
|
|
155
172
|
return tools;
|
|
156
173
|
return tools.filter((t) => !(t.type === 'func' && typeof t.name === 'string' && (0, shell_tools_1.isShellToolName)(t.name)));
|
|
@@ -179,7 +196,7 @@ async function loadAgentMinds(agentId, dialog, options) {
|
|
|
179
196
|
return out;
|
|
180
197
|
})();
|
|
181
198
|
const toolsetNames = agent
|
|
182
|
-
.listResolvedToolsetNames({ onMissing: missingToolsetPolicy })
|
|
199
|
+
.listResolvedToolsetNames({ onMissing: missingToolsetPolicy, dynamicToolsetNames })
|
|
183
200
|
.filter((name) => {
|
|
184
201
|
if (name === 'os')
|
|
185
202
|
return agentIsShellSpecialist;
|
|
@@ -247,6 +264,7 @@ async function loadAgentMinds(agentId, dialog, options) {
|
|
|
247
264
|
persona,
|
|
248
265
|
knowledge,
|
|
249
266
|
lessons,
|
|
267
|
+
skillsText,
|
|
250
268
|
envIntro,
|
|
251
269
|
teamIntro,
|
|
252
270
|
funcToolRulesText,
|
|
@@ -290,6 +290,8 @@ ${input.knowledge}
|
|
|
290
290
|
|
|
291
291
|
${input.lessons}
|
|
292
292
|
|
|
293
|
+
${input.skillsText}
|
|
294
|
+
|
|
293
295
|
## 运行环境
|
|
294
296
|
|
|
295
297
|
${input.envIntro}
|
|
@@ -381,6 +383,8 @@ ${input.knowledge}
|
|
|
381
383
|
|
|
382
384
|
${input.lessons}
|
|
383
385
|
|
|
386
|
+
${input.skillsText}
|
|
387
|
+
|
|
384
388
|
## Runtime Environment
|
|
385
389
|
|
|
386
390
|
${input.envIntro}
|
package/dist/priming.js
CHANGED
|
@@ -19,6 +19,7 @@ const promises_1 = __importDefault(require("fs/promises"));
|
|
|
19
19
|
const path_1 = __importDefault(require("path"));
|
|
20
20
|
const yaml_1 = __importDefault(require("yaml"));
|
|
21
21
|
const persistence_1 = require("./persistence");
|
|
22
|
+
const markdown_frontmatter_1 = require("./shared/markdown-frontmatter");
|
|
22
23
|
const storage_1 = require("./shared/types/storage");
|
|
23
24
|
const time_1 = require("./shared/utils/time");
|
|
24
25
|
const registry_1 = require("./tools/registry");
|
|
@@ -108,33 +109,8 @@ function scriptRefToAbsolutePath(scriptRef) {
|
|
|
108
109
|
}
|
|
109
110
|
return absPath;
|
|
110
111
|
}
|
|
111
|
-
function stripOptionalBom(text) {
|
|
112
|
-
if (text.charCodeAt(0) === 0xfeff) {
|
|
113
|
-
return text.slice(1);
|
|
114
|
-
}
|
|
115
|
-
return text;
|
|
116
|
-
}
|
|
117
112
|
function parseFrontmatter(raw) {
|
|
118
|
-
|
|
119
|
-
if (!normalized.startsWith('---\n')) {
|
|
120
|
-
return { body: normalized, frontmatter: {} };
|
|
121
|
-
}
|
|
122
|
-
const endWithBody = normalized.indexOf('\n---\n', 4);
|
|
123
|
-
const endAtEof = normalized.endsWith('\n---') ? normalized.length - '\n---'.length : -1;
|
|
124
|
-
const end = endWithBody >= 0 ? endWithBody : endAtEof;
|
|
125
|
-
if (end < 0)
|
|
126
|
-
return { body: normalized, frontmatter: {} };
|
|
127
|
-
const frontmatterText = normalized.slice(4, end);
|
|
128
|
-
const body = endWithBody >= 0
|
|
129
|
-
? normalized.slice(end + '\n---\n'.length)
|
|
130
|
-
: normalized.slice(end + '\n---'.length);
|
|
131
|
-
try {
|
|
132
|
-
const parsed = yaml_1.default.parse(frontmatterText);
|
|
133
|
-
return { body, frontmatter: isRecord(parsed) ? parsed : {} };
|
|
134
|
-
}
|
|
135
|
-
catch (error) {
|
|
136
|
-
throw new Error(`Invalid priming frontmatter: ${error instanceof Error ? error.message : String(error)}`);
|
|
137
|
-
}
|
|
113
|
+
return (0, markdown_frontmatter_1.parseMarkdownFrontmatter)(raw, 'priming');
|
|
138
114
|
}
|
|
139
115
|
function parseApplicableMemberIds(frontmatter) {
|
|
140
116
|
const raw = frontmatter['applicableMemberIds'] ?? frontmatter['applicable_members'];
|
|
@@ -1344,6 +1344,11 @@ function setupWebSocketServer(httpServer, clients, auth, serverWorkLanguage) {
|
|
|
1344
1344
|
}
|
|
1345
1345
|
});
|
|
1346
1346
|
(0, team_config_updates_1.startTeamConfigWatcher)();
|
|
1347
|
+
httpServer.once('close', () => {
|
|
1348
|
+
(0, team_config_updates_1.stopTeamConfigWatcher)();
|
|
1349
|
+
(0, team_config_updates_1.clearTeamConfigBroadcaster)();
|
|
1350
|
+
void wss.close();
|
|
1351
|
+
});
|
|
1347
1352
|
wss.on('connection', (ws, req) => {
|
|
1348
1353
|
const authCheck = (0, auth_1.getWebSocketAuthCheck)(req, auth);
|
|
1349
1354
|
if (authCheck.kind !== 'ok') {
|
package/dist/server.js
CHANGED
|
@@ -105,6 +105,7 @@ async function startServer(opts = {}) {
|
|
|
105
105
|
const mode = opts.mode || 'prod';
|
|
106
106
|
const port = opts.port ?? 5666;
|
|
107
107
|
const host = opts.host || '127.0.0.1';
|
|
108
|
+
const startBackendDriver = opts.startBackendDriver ?? true;
|
|
108
109
|
log.info(`Starting server in ${mode} mode on ${host}:${port} (working language: ${(0, runtime_language_1.getWorkLanguage)()} from ${source})`);
|
|
109
110
|
// WebSocket clients set
|
|
110
111
|
const clients = new Set();
|
|
@@ -131,8 +132,10 @@ async function startServer(opts = {}) {
|
|
|
131
132
|
await (0, runtime_1.initAppsRuntime)({ rtwsRootAbs: process.cwd(), kernel: { host, port } });
|
|
132
133
|
// Crash recovery: any dialogs left in "proceeding" state are surfaced as interrupted/resumable.
|
|
133
134
|
await (0, dialog_run_state_1.reconcileRunStatesAfterRestart)();
|
|
134
|
-
//
|
|
135
|
-
|
|
135
|
+
// Tests may opt out so the process can shut down cleanly without a driver stop API.
|
|
136
|
+
if (startBackendDriver) {
|
|
137
|
+
void (0, kernel_driver_1.runBackendDriver)();
|
|
138
|
+
}
|
|
136
139
|
// Start listening
|
|
137
140
|
await httpServer.start();
|
|
138
141
|
return { httpServer, auth, host, port, mode };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.stripOptionalBom = stripOptionalBom;
|
|
7
|
+
exports.normalizeMarkdownText = normalizeMarkdownText;
|
|
8
|
+
exports.parseMarkdownFrontmatter = parseMarkdownFrontmatter;
|
|
9
|
+
const yaml_1 = __importDefault(require("yaml"));
|
|
10
|
+
function isRecord(value) {
|
|
11
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
12
|
+
}
|
|
13
|
+
function stripOptionalBom(text) {
|
|
14
|
+
if (text.charCodeAt(0) === 0xfeff) {
|
|
15
|
+
return text.slice(1);
|
|
16
|
+
}
|
|
17
|
+
return text;
|
|
18
|
+
}
|
|
19
|
+
function normalizeMarkdownText(text) {
|
|
20
|
+
return stripOptionalBom(text).replace(/\r\n/g, '\n');
|
|
21
|
+
}
|
|
22
|
+
function parseMarkdownFrontmatter(raw, sourceLabel = 'markdown') {
|
|
23
|
+
const normalized = normalizeMarkdownText(raw);
|
|
24
|
+
if (!normalized.startsWith('---\n')) {
|
|
25
|
+
return { body: normalized, frontmatter: {} };
|
|
26
|
+
}
|
|
27
|
+
const endWithBody = normalized.indexOf('\n---\n', 4);
|
|
28
|
+
const endAtEof = normalized.endsWith('\n---') ? normalized.length - '\n---'.length : -1;
|
|
29
|
+
const end = endWithBody >= 0 ? endWithBody : endAtEof;
|
|
30
|
+
if (end < 0) {
|
|
31
|
+
return { body: normalized, frontmatter: {} };
|
|
32
|
+
}
|
|
33
|
+
const frontmatterText = normalized.slice(4, end);
|
|
34
|
+
const body = endWithBody >= 0
|
|
35
|
+
? normalized.slice(end + '\n---\n'.length)
|
|
36
|
+
: normalized.slice(end + '\n---'.length);
|
|
37
|
+
try {
|
|
38
|
+
const parsed = yaml_1.default.parse(frontmatterText);
|
|
39
|
+
return { body, frontmatter: isRecord(parsed) ? parsed : {} };
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
throw new Error(`Invalid ${sourceLabel} frontmatter: ${error instanceof Error ? error.message : String(error)}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -25,6 +25,7 @@ exports.TEAM_MGMT_MANUAL_TOPIC_KEYS = [
|
|
|
25
25
|
'team',
|
|
26
26
|
'member-properties',
|
|
27
27
|
'minds',
|
|
28
|
+
'skills',
|
|
28
29
|
'priming',
|
|
29
30
|
'env',
|
|
30
31
|
'permissions',
|
|
@@ -48,6 +49,9 @@ exports.TEAM_MGMT_MANUAL_TOPIC_META = {
|
|
|
48
49
|
minds: {
|
|
49
50
|
titleI18n: { zh: '角色资产(.minds/team/<id>/*)', en: 'Minds Assets (.minds/team/<id>/*)' },
|
|
50
51
|
},
|
|
52
|
+
skills: {
|
|
53
|
+
titleI18n: { zh: '技能(.minds/skills/*)', en: 'Skills (.minds/skills/*)' },
|
|
54
|
+
},
|
|
51
55
|
priming: {
|
|
52
56
|
titleI18n: {
|
|
53
57
|
zh: '启动脚本(.minds/priming/*)',
|
|
@@ -77,6 +81,7 @@ exports.TEAM_MGMT_MANUAL_UI_TOPIC_ORDER = [
|
|
|
77
81
|
'builtin-defaults',
|
|
78
82
|
'mcp',
|
|
79
83
|
'minds',
|
|
84
|
+
'skills',
|
|
80
85
|
'priming',
|
|
81
86
|
'env',
|
|
82
87
|
'troubleshooting',
|
|
@@ -97,6 +102,7 @@ exports.TEAM_MGMT_MANUAL_UI_TOOL_TOPICS_BY_KEY = {
|
|
|
97
102
|
// Other
|
|
98
103
|
mcp: ['mcp'],
|
|
99
104
|
minds: ['minds'],
|
|
105
|
+
skills: ['skills'],
|
|
100
106
|
priming: ['priming'],
|
|
101
107
|
env: ['env'],
|
|
102
108
|
troubleshooting: ['troubleshooting'],
|
|
@@ -106,6 +112,7 @@ exports.TEAM_MGMT_MANUAL_PANEL_TOPIC_ORDER = [
|
|
|
106
112
|
'permissions',
|
|
107
113
|
'team',
|
|
108
114
|
'toolsets',
|
|
115
|
+
'skills',
|
|
109
116
|
];
|
|
110
117
|
const EMPTY_TOOL_TOPICS = [];
|
|
111
118
|
exports.TEAM_MGMT_MANUAL_PANEL_TOOL_TOPICS_BY_KEY = {
|
|
@@ -113,6 +120,7 @@ exports.TEAM_MGMT_MANUAL_PANEL_TOOL_TOPICS_BY_KEY = {
|
|
|
113
120
|
permissions: ['permissions'],
|
|
114
121
|
team: ['team'],
|
|
115
122
|
toolsets: ['toolsets'],
|
|
123
|
+
skills: ['skills'],
|
|
116
124
|
};
|
|
117
125
|
function isTeamMgmtManualPanelTopicKey(value) {
|
|
118
126
|
return Object.prototype.hasOwnProperty.call(exports.TEAM_MGMT_MANUAL_PANEL_TOOL_TOPICS_BY_KEY, value);
|
|
@@ -122,6 +130,7 @@ exports.TEAM_MGMT_MANUAL_PANEL_TOPIC_META = {
|
|
|
122
130
|
permissions: exports.TEAM_MGMT_MANUAL_TOPIC_META.permissions,
|
|
123
131
|
team: exports.TEAM_MGMT_MANUAL_TOPIC_META.team,
|
|
124
132
|
toolsets: exports.TEAM_MGMT_MANUAL_TOPIC_META.toolsets,
|
|
133
|
+
skills: exports.TEAM_MGMT_MANUAL_TOPIC_META.skills,
|
|
125
134
|
};
|
|
126
135
|
function getTeamMgmtManualPanelTopicTitle(lang, key) {
|
|
127
136
|
const meta = exports.TEAM_MGMT_MANUAL_PANEL_TOPIC_META[key];
|