pneuma-skills 1.18.8 → 2.0.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 +16 -10
- package/bin/pneuma.ts +311 -1
- package/core/mode-loader.ts +7 -0
- package/core/types/index.ts +2 -0
- package/core/types/mode-manifest.ts +43 -0
- package/dist/assets/{EditorPanel-BleuERxH.js → EditorPanel-0akZRyo5.js} +1 -1
- package/dist/assets/Launcher-CCi-6n7c.js +1 -0
- package/dist/assets/{ScaffoldConfirm-y_ee3Dfd.js → ScaffoldConfirm-CUg6eQ0U.js} +1 -1
- package/dist/assets/{TerminalPanel-Cn7WlSTk.js → TerminalPanel-BsmX9W8R.js} +1 -1
- package/dist/assets/{ar-SA-G6X2FPQ2-D3jsaCPH.js → ar-SA-G6X2FPQ2-CyJjWFnD.js} +1 -1
- package/dist/assets/{arc-DNF_Rvhl.js → arc-R5iRnrLz.js} +1 -1
- package/dist/assets/{az-AZ-76LH7QW2-B1w4wSUT.js → az-AZ-76LH7QW2-1n7ob6V6.js} +1 -1
- package/dist/assets/{bg-BG-XCXSNQG7-Cb8Z7rZq.js → bg-BG-XCXSNQG7-CaBcp9qd.js} +1 -1
- package/dist/assets/{blockDiagram-38ab4fdb-CP_JiaKU.js → blockDiagram-38ab4fdb-B1X3_GFX.js} +1 -1
- package/dist/assets/{bn-BD-2XOGV67Q-ChAjeqCN.js → bn-BD-2XOGV67Q-BtA4rXnE.js} +1 -1
- package/dist/assets/{c4Diagram-3d4e48cf-Bas06DhA.js → c4Diagram-3d4e48cf-BtqYi13m.js} +1 -1
- package/dist/assets/{ca-ES-6MX7JW3Y-B9H8UnNU.js → ca-ES-6MX7JW3Y-DUBFlXlo.js} +1 -1
- package/dist/assets/channel-gedPNWcr.js +1 -0
- package/dist/assets/{classDiagram-70f12bd4-Crf6gDW8.js → classDiagram-70f12bd4-DPYb9XVZ.js} +1 -1
- package/dist/assets/{classDiagram-v2-f2320105-Cw4vriY9.js → classDiagram-v2-f2320105-CmfvQEAX.js} +1 -1
- package/dist/assets/clone-BJt3SdgM.js +1 -0
- package/dist/assets/{createText-2e5e7dd3-B6z6IYvt.js → createText-2e5e7dd3-ByQRkWgK.js} +1 -1
- package/dist/assets/{cs-CZ-2BRQDIVT-DbtValfJ.js → cs-CZ-2BRQDIVT-OKf3CBFB.js} +1 -1
- package/dist/assets/{da-DK-5WZEPLOC-D0CZnl6S.js → da-DK-5WZEPLOC-BKcaFv7b.js} +1 -1
- package/dist/assets/{de-DE-XR44H4JA-BwUK-XWk.js → de-DE-XR44H4JA-BRDaTV6M.js} +1 -1
- package/dist/assets/{download-DLP4jMAA.js → download-B98bty0V.js} +1 -1
- package/dist/assets/{edges-e0da2a9e-DobexeDC.js → edges-e0da2a9e-DDhb7mIg.js} +1 -1
- package/dist/assets/{el-GR-BZB4AONW-Vu07mCI5.js → el-GR-BZB4AONW-DTlDpPbe.js} +1 -1
- package/dist/assets/{erDiagram-9861fffd-CCSTBb8R.js → erDiagram-9861fffd-DBVXKikK.js} +1 -1
- package/dist/assets/{es-ES-U4NZUMDT-iUcic2nH.js → es-ES-U4NZUMDT-DDLgPUOO.js} +1 -1
- package/dist/assets/{eu-ES-A7QVB2H4-BgU9SWVI.js → eu-ES-A7QVB2H4-Bz2xzMob.js} +1 -1
- package/dist/assets/{fa-IR-HGAKTJCU-BTCkvyWh.js → fa-IR-HGAKTJCU-P4zcEtxA.js} +1 -1
- package/dist/assets/{fi-FI-Z5N7JZ37-DWVFBCwg.js → fi-FI-Z5N7JZ37-D2q89-9c.js} +1 -1
- package/dist/assets/{flowDb-956e92f1-DwO84EWT.js → flowDb-956e92f1-BSfxVv-C.js} +1 -1
- package/dist/assets/{flowDiagram-66a62f08-CuDeqby5.js → flowDiagram-66a62f08-DPHp_TrQ.js} +1 -1
- package/dist/assets/flowDiagram-v2-96b9c2cf-DO_9RAPt.js +1 -0
- package/dist/assets/{flowchart-elk-definition-4a651766-C-Ogp6Jp.js → flowchart-elk-definition-4a651766-B-9INMbf.js} +1 -1
- package/dist/assets/{fr-FR-RHASNOE6-CVlNocmm.js → fr-FR-RHASNOE6-CYGGgFGJ.js} +1 -1
- package/dist/assets/{ganttDiagram-c361ad54-BAxD7Eoo.js → ganttDiagram-c361ad54-Lt3a4i9C.js} +1 -1
- package/dist/assets/{gitGraphDiagram-72cf32ee-CK_I_0zd.js → gitGraphDiagram-72cf32ee-CAJ5Ogtn.js} +1 -1
- package/dist/assets/{gl-ES-HMX3MZ6V-DLvyrdOn.js → gl-ES-HMX3MZ6V-CyN6LVPa.js} +1 -1
- package/dist/assets/{graph-C7CuZfOA.js → graph-CPcTKuJe.js} +1 -1
- package/dist/assets/{he-IL-6SHJWFNN-BElIsMIp.js → he-IL-6SHJWFNN-Bm8KblEy.js} +1 -1
- package/dist/assets/{hi-IN-IWLTKZ5I-CkNV-BOU.js → hi-IN-IWLTKZ5I-Ch9nEDMX.js} +1 -1
- package/dist/assets/{hu-HU-A5ZG7DT2-2S9Y7Svn.js → hu-HU-A5ZG7DT2-CjXf6kKD.js} +1 -1
- package/dist/assets/{id-ID-SAP4L64H-BjaLm4l6.js → id-ID-SAP4L64H-C_87xASV.js} +1 -1
- package/dist/assets/{index-3862675e-Cnnvl-8u.js → index-3862675e-CWsCtFSt.js} +1 -1
- package/dist/assets/{index-CQTyt1YM.js → index-44rIdSy5.js} +1 -1
- package/dist/assets/index-9_ngsavx.css +1 -0
- package/dist/assets/{index-DupDxaBk.js → index-BOvq7HF2.js} +4 -4
- package/dist/assets/{index-Dc0SptmK.js → index-Dg5w1pZN.js} +1 -1
- package/dist/assets/{index-DuLlGGas.js → index-Dsva36SB.js} +23 -23
- package/dist/assets/{infoDiagram-f8f76790-D0MyaMnN.js → infoDiagram-f8f76790-BhC7MVmC.js} +1 -1
- package/dist/assets/{it-IT-JPQ66NNP-DDKE0SJO.js → it-IT-JPQ66NNP-C4W_W79I.js} +1 -1
- package/dist/assets/{ja-JP-DBVTYXUO-DY6X7qK7.js → ja-JP-DBVTYXUO-DC8KJuas.js} +1 -1
- package/dist/assets/{journeyDiagram-49397b02-qgIUb-89.js → journeyDiagram-49397b02-BhQRP25G.js} +1 -1
- package/dist/assets/{kaa-6HZHGXH3-DiuMBUla.js → kaa-6HZHGXH3-Cs-7ua_I.js} +1 -1
- package/dist/assets/{kab-KAB-ZGHBKWFO-6e4XQ-tz.js → kab-KAB-ZGHBKWFO-DPFqm_A6.js} +1 -1
- package/dist/assets/{kk-KZ-P5N5QNE5-DfjIixsJ.js → kk-KZ-P5N5QNE5-Cf7o_GJW.js} +1 -1
- package/dist/assets/{km-KH-HSX4SM5Z-BhRmMVE_.js → km-KH-HSX4SM5Z-BeUIhFSc.js} +1 -1
- package/dist/assets/{ko-KR-MTYHY66A-Bjn9mXnA.js → ko-KR-MTYHY66A-CKQWpLZ0.js} +1 -1
- package/dist/assets/{ku-TR-6OUDTVRD-DJr9jfEi.js → ku-TR-6OUDTVRD-DAQg2oMr.js} +1 -1
- package/dist/assets/{layout-Dd69otLm.js → layout-Bx0l_BKn.js} +1 -1
- package/dist/assets/{line-DRfgXn85.js → line-CqdhvoBg.js} +1 -1
- package/dist/assets/{linear-DGr1PTPp.js → linear-BD2kl1Br.js} +1 -1
- package/dist/assets/{lt-LT-XHIRWOB4-ppVjyPnr.js → lt-LT-XHIRWOB4-qBbyF_JI.js} +1 -1
- package/dist/assets/{lv-LV-5QDEKY6T-CGS8BspW.js → lv-LV-5QDEKY6T-D2FWxPw_.js} +1 -1
- package/dist/assets/{manifest-BvnrtaQm.js → manifest-BmEn3LvA.js} +13 -6
- package/dist/assets/manifest-C0moSD5y.js +28 -0
- package/dist/assets/{manifest-BI8slOVt.js → manifest-D1rKRD_L.js} +15 -6
- package/dist/assets/{manifest-neauP7Gc.js → manifest-grHl8OxZ.js} +7 -3
- package/dist/assets/{manifest-BkKz5q4X.js → manifest-k4uV77LO.js} +17 -10
- package/dist/assets/{mindmap-definition-fc14e90a-AFmcyPtp.js → mindmap-definition-fc14e90a-BacEaxyV.js} +1 -1
- package/dist/assets/{mr-IN-CRQNXWMA-BHH01ypW.js → mr-IN-CRQNXWMA-DDvShQEG.js} +1 -1
- package/dist/assets/{my-MM-5M5IBNSE-t572CDde.js → my-MM-5M5IBNSE--mZq5Lsm.js} +1 -1
- package/dist/assets/{nb-NO-T6EIAALU-BiNtPMS2.js → nb-NO-T6EIAALU-C29pR6hl.js} +1 -1
- package/dist/assets/{nl-NL-IS3SIHDZ-DD-YrS7Y.js → nl-NL-IS3SIHDZ-BhRRuqV1.js} +1 -1
- package/dist/assets/{nn-NO-6E72VCQL-CAdSOdj3.js → nn-NO-6E72VCQL-DMn4kFnF.js} +1 -1
- package/dist/assets/{oc-FR-POXYY2M6-CggnZuUm.js → oc-FR-POXYY2M6-DimVPddm.js} +1 -1
- package/dist/assets/{pa-IN-N4M65BXN-CgQSRavt.js → pa-IN-N4M65BXN-DLzOv-Nt.js} +1 -1
- package/dist/assets/{percentages-BXMCSKIN-Cy39z5Py.js → percentages-BXMCSKIN-oPUMUK28.js} +7 -7
- package/dist/assets/{pica-C6y9YaE7.js → pica-BdG-S0W_.js} +1 -1
- package/dist/assets/{pieDiagram-8a3498a8-CywqbnUP.js → pieDiagram-8a3498a8-DD808_p6.js} +1 -1
- package/dist/assets/{pl-PL-T2D74RX3-DhZysyag.js → pl-PL-T2D74RX3-BVjLL-KO.js} +1 -1
- package/dist/assets/{pneuma-mode-DObfMJkD.js → pneuma-mode-BstV4WWa.js} +3 -3
- package/dist/assets/pneuma-mode-C8lXPcZY.js +6 -0
- package/dist/assets/{pneuma-mode-BawXqZD4.js → pneuma-mode-CvAzc7or.js} +1 -1
- package/dist/assets/{pneuma-mode-CvRaQvup.js → pneuma-mode-DA-nYcMo.js} +1 -1
- package/dist/assets/{pneuma-mode-tKG2TfhL.js → pneuma-mode-DzSNT6KB.js} +3 -3
- package/dist/assets/{pt-BR-5N22H2LF-DqmnKHfj.js → pt-BR-5N22H2LF-pjOi5yYu.js} +1 -1
- package/dist/assets/{pt-PT-UZXXM6DQ-Dr61yFqO.js → pt-PT-UZXXM6DQ-C0zzmeZg.js} +1 -1
- package/dist/assets/{quadrantDiagram-120e2f19-BBlGHWao.js → quadrantDiagram-120e2f19-2FBFHV1g.js} +1 -1
- package/dist/assets/{rasterize-34PCWURX-VXG9AwQG.js → rasterize-34PCWURX-BuR7lHwM.js} +1 -1
- package/dist/assets/{requirementDiagram-deff3bca-TQYdVQGJ.js → requirementDiagram-deff3bca-DgdDm7sw.js} +1 -1
- package/dist/assets/{ro-RO-JPDTUUEW-CAtABelS.js → ro-RO-JPDTUUEW-DrTbqAZB.js} +1 -1
- package/dist/assets/{ru-RU-B4JR7IUQ-C_3zWMxA.js → ru-RU-B4JR7IUQ-Dwoiqt7A.js} +1 -1
- package/dist/assets/{sankeyDiagram-04a897e0-BnnEsTPi.js → sankeyDiagram-04a897e0-DA6RPxOH.js} +1 -1
- package/dist/assets/{sequenceDiagram-704730f1-CMwpQj1K.js → sequenceDiagram-704730f1-D6rBSEZx.js} +1 -1
- package/dist/assets/{si-LK-N5RQ5JYF-BusDWMm7.js → si-LK-N5RQ5JYF-DEyeLAPX.js} +1 -1
- package/dist/assets/{sk-SK-C5VTKIMK-CQpZ58Ns.js → sk-SK-C5VTKIMK-DrrUEhZF.js} +1 -1
- package/dist/assets/{sl-SI-NN7IZMDC-dKFYj_L9.js → sl-SI-NN7IZMDC-LHNZL1i8.js} +1 -1
- package/dist/assets/{stateDiagram-587899a1-BUVV6Afi.js → stateDiagram-587899a1-BNbQ_MDY.js} +1 -1
- package/dist/assets/{stateDiagram-v2-d93cdb3a-eJtAzvCh.js → stateDiagram-v2-d93cdb3a-CLIyBUgq.js} +1 -1
- package/dist/assets/{styles-6aaf32cf-Kdv8aCGY.js → styles-6aaf32cf-JOpKCqiC.js} +1 -1
- package/dist/assets/{styles-9a916d00-CGR3lcaC.js → styles-9a916d00-lHkzP7SR.js} +1 -1
- package/dist/assets/{styles-c10674c1-BOkM08QZ.js → styles-c10674c1-DnuoD4Pf.js} +1 -1
- package/dist/assets/{subset-shared.chunk-CjkDX8VC.js → subset-shared.chunk-CN75hxTG.js} +1 -1
- package/dist/assets/{subset-worker.chunk-piclBFAr.js → subset-worker.chunk-BKXWmKBH.js} +1 -1
- package/dist/assets/{sv-SE-XGPEYMSR-B8RTK6WL.js → sv-SE-XGPEYMSR-CTNDbM3s.js} +1 -1
- package/dist/assets/{svgDrawCommon-08f97a94-B2mIk0L0.js → svgDrawCommon-08f97a94-Da2dJTri.js} +1 -1
- package/dist/assets/{ta-IN-2NMHFXQM-BQtdS-Ss.js → ta-IN-2NMHFXQM-ByyMZMP5.js} +1 -1
- package/dist/assets/{th-TH-HPSO5L25-B-yXVmv_.js → th-TH-HPSO5L25-CNejeYu_.js} +1 -1
- package/dist/assets/{timeline-definition-85554ec2-156uBejc.js → timeline-definition-85554ec2-4kZpETv4.js} +1 -1
- package/dist/assets/{toBlob-BLi9egoc.js → toBlob-WxcBwMU6.js} +1 -1
- package/dist/assets/{toCanvas-fcJ0RdLx.js → toCanvas-B_D439gh.js} +1 -1
- package/dist/assets/{toImg-CYywIo5R.js → toImg-DRze7wY3.js} +1 -1
- package/dist/assets/{tr-TR-DEFEU3FU-5fpLXM1X.js → tr-TR-DEFEU3FU-6my8X0k8.js} +1 -1
- package/dist/assets/{uk-UA-QMV73CPH-BxPzifFa.js → uk-UA-QMV73CPH-KDqsoc0U.js} +1 -1
- package/dist/assets/{vi-VN-M7AON7JQ-CS2A77bJ.js → vi-VN-M7AON7JQ-Bi4HhiiT.js} +1 -1
- package/dist/assets/{xychartDiagram-e933f94c-CZyrBggG.js → xychartDiagram-e933f94c-3fzlFPno.js} +1 -1
- package/dist/assets/{zh-CN-LNUGB5OW-DRQ1XwJd.js → zh-CN-LNUGB5OW-DHhoDUCR.js} +1 -1
- package/dist/assets/{zh-HK-E62DVLB3-CgKd6NNi.js → zh-HK-E62DVLB3-lR9JAu6O.js} +1 -1
- package/dist/assets/{zh-TW-RAJ6MFWO-BNfMd8MA.js → zh-TW-RAJ6MFWO-BBleOG0l.js} +1 -1
- package/dist/index.html +5 -2
- package/index.html +3 -0
- package/modes/doc/manifest.ts +18 -5
- package/modes/doc/skill/SKILL.md +75 -4
- package/modes/draw/manifest.ts +16 -5
- package/modes/draw/skill/SKILL.md +9 -0
- package/modes/evolve/manifest.ts +65 -0
- package/modes/evolve/pneuma-mode.ts +35 -0
- package/modes/evolve/skill/SKILL.md +44 -0
- package/modes/evolve/skill/scripts/_shared.ts +179 -0
- package/modes/evolve/skill/scripts/extract-tool-flow.ts +116 -0
- package/modes/evolve/skill/scripts/list-sessions.ts +78 -0
- package/modes/evolve/skill/scripts/search-messages.ts +119 -0
- package/modes/evolve/skill/scripts/session-digest.ts +90 -0
- package/modes/evolve/skill/scripts/session-stats.ts +110 -0
- package/modes/evolve/viewer/EvolutionPreview.tsx +507 -0
- package/modes/mode-maker/manifest.ts +7 -3
- package/modes/mode-maker/seed/manifest.ts +7 -2
- package/modes/mode-maker/seed/skill/SKILL.md +40 -1
- package/modes/mode-maker/skill/SKILL.md +30 -1
- package/modes/slide/manifest.ts +20 -9
- package/package.json +1 -1
- package/server/__tests__/e2e-skill-effectiveness.test.ts +255 -0
- package/server/__tests__/evolution-agent.test.ts +152 -0
- package/server/__tests__/evolution-proposal.test.ts +359 -0
- package/server/evolution-agent.ts +438 -0
- package/server/evolution-proposal.ts +399 -0
- package/server/evolution-routes.ts +254 -0
- package/server/index.ts +6 -0
- package/dist/assets/Launcher-CZR8la9p.js +0 -1
- package/dist/assets/channel-BBUf9t84.js +0 -1
- package/dist/assets/clone-CaGGICgt.js +0 -1
- package/dist/assets/flowDiagram-v2-96b9c2cf-xRcXFevM.js +0 -1
- package/dist/assets/index-CcSl8aZo.css +0 -1
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ When humans and code agents co-create content, they need more than a chat window
|
|
|
24
24
|
|
|
25
25
|
**Skills** — Domain-specific knowledge and seed templates injected into the agent per mode. A presentation skill teaches layout, rhythm, and export; a document skill teaches prose and structure. Skills version and evolve with each release, and sessions persist across runs — the agent picks up where it left off.
|
|
26
26
|
|
|
27
|
-
**Continuous Learning**
|
|
27
|
+
**Continuous Learning** — Skills aren't static presets. The Evolution Agent mines cross-session conversation history to extract user preferences and style patterns, then augments the preset skill with learned knowledge. Run `pneuma evolve <mode>` to analyze your history, review AI-generated proposals with evidence citations, and apply them to personalize your experience.
|
|
28
28
|
|
|
29
29
|
**Distribution** — A complete ecosystem for sharing capabilities. Build a custom mode with AI assistance via Mode Maker, publish to the marketplace, and let anyone `pneuma mode add` it instantly.
|
|
30
30
|
|
|
@@ -36,6 +36,7 @@ When humans and code agents co-create content, they need more than a chat window
|
|
|
36
36
|
| **slide** | HTML presentations — content sets, drag-reorder, presenter mode, PDF/image export |
|
|
37
37
|
| **draw** | Excalidraw whiteboard with `.excalidraw` file editing |
|
|
38
38
|
| **mode-maker** | Create custom modes with AI — fork, play-test, publish |
|
|
39
|
+
| **evolve** | Evolution Agent — analyze history, propose skill improvements, apply/rollback |
|
|
39
40
|
|
|
40
41
|
## Prerequisites
|
|
41
42
|
|
|
@@ -84,6 +85,7 @@ Modes:
|
|
|
84
85
|
slide Presentation editing mode (HTML slides with iframe preview)
|
|
85
86
|
draw Excalidraw whiteboard drawing mode
|
|
86
87
|
mode-maker Create and develop custom modes with AI
|
|
88
|
+
evolve Launch the Evolution Agent for skill learning
|
|
87
89
|
/path/to/mode Load mode from a local directory
|
|
88
90
|
github:user/repo Load mode from a GitHub repository
|
|
89
91
|
github:user/repo#branch Load mode from a specific branch/tag
|
|
@@ -99,6 +101,7 @@ Options:
|
|
|
99
101
|
--dev Force dev mode (Vite)
|
|
100
102
|
|
|
101
103
|
Subcommands:
|
|
104
|
+
evolve <mode> Analyze history and propose skill improvements
|
|
102
105
|
mode add <url> Install a remote mode to ~/.pneuma/modes/
|
|
103
106
|
mode list List published modes on the R2 registry
|
|
104
107
|
mode publish Publish the current workspace as a mode
|
|
@@ -172,7 +175,7 @@ When Claude Code edits files, chokidar detects the changes and pushes updated co
|
|
|
172
175
|
| **ViewerContract** | Preview component, context extraction, file workspace model, agent-callable actions | Custom renderers, viewport tracking, action protocols |
|
|
173
176
|
| **AgentBackend** | Launch, resume, kill, capability declaration | Other agents (Codex, Aider) |
|
|
174
177
|
|
|
175
|
-
Contracts are defined in `core/types/` with
|
|
178
|
+
Contracts are defined in `core/types/` with 316 tests across 20 test files.
|
|
176
179
|
|
|
177
180
|
## Project Structure
|
|
178
181
|
|
|
@@ -193,7 +196,8 @@ pneuma-skills/
|
|
|
193
196
|
│ ├── doc/ # Doc Mode — markdown editing
|
|
194
197
|
│ ├── slide/ # Slide Mode — presentation editing
|
|
195
198
|
│ ├── draw/ # Draw Mode — Excalidraw whiteboard
|
|
196
|
-
│
|
|
199
|
+
│ ├── mode-maker/ # Mode Maker — create custom modes with AI
|
|
200
|
+
│ └── evolve/ # Evolve Mode — evolution agent dashboard
|
|
197
201
|
│ ├── manifest.ts # Mode manifest (fork, play, publish workflow)
|
|
198
202
|
│ ├── seed/ # Template files for new modes
|
|
199
203
|
│ ├── skill/ # Skill prompt for mode development
|
|
@@ -212,7 +216,10 @@ pneuma-skills/
|
|
|
212
216
|
│ ├── terminal-manager.ts # PTY terminal sessions
|
|
213
217
|
│ ├── path-resolver.ts # Binary PATH resolution (cross-platform)
|
|
214
218
|
│ ├── system-bridge.ts # OS-level operations (open, reveal, openUrl)
|
|
215
|
-
│
|
|
219
|
+
│ ├── mode-maker-routes.ts # Mode Maker API routes (fork, play, publish, reset)
|
|
220
|
+
│ ├── evolution-agent.ts # Evolution Agent launcher (spawns CC with analysis tools)
|
|
221
|
+
│ ├── evolution-proposal.ts # Proposal CRUD + apply/rollback + CLAUDE.md sync
|
|
222
|
+
│ └── evolution-routes.ts # Evolution API routes (/api/evolve/*)
|
|
216
223
|
├── src/
|
|
217
224
|
│ ├── App.tsx # Root layout (dynamic viewer from store)
|
|
218
225
|
│ ├── store.ts # Zustand state (session, messages, viewer)
|
|
@@ -276,6 +283,8 @@ pneuma-skills/
|
|
|
276
283
|
- **Image upload** — Drag & drop or paste images into chat
|
|
277
284
|
- **Viewer context enrichment** — `<viewer-context>` XML blocks align agent perception with user viewport
|
|
278
285
|
- **Viewer action protocol** — Agent can invoke viewer capabilities (navigate, toggle UI, capture)
|
|
286
|
+
- **Evolution Agent** — `pneuma evolve <mode>` analyzes conversation history, proposes skill improvements with evidence
|
|
287
|
+
- **Proposal lifecycle** — Review, apply, rollback, discard, or fork proposals into custom modes
|
|
279
288
|
- **Windows compatibility** — Cross-platform PATH resolution, terminal, browser opening, process management
|
|
280
289
|
- **Debug mode** — `--debug` flag shows enriched CLI payloads for each message
|
|
281
290
|
|
|
@@ -298,13 +307,10 @@ pneuma-skills/
|
|
|
298
307
|
- [x] Launcher process management — Monitor and kill child processes
|
|
299
308
|
- [x] Next-gen visual redesign — Ethereal Tech aesthetic (glassmorphism, cinematic dark UI)
|
|
300
309
|
- [x] Export & image capture — Slide export via `@zumer/snapdom`
|
|
310
|
+
- [x] Evolution Agent — AI-native continuous skill learning (`pneuma evolve <mode>`)
|
|
311
|
+
- [x] Skill effectiveness optimization — standardized claudeMdSection + YAML frontmatter for native skill discovery
|
|
301
312
|
- [ ] Additional agent backends — Codex CLI, custom agents
|
|
302
|
-
|
|
303
|
-
### v2.0 — Continuous Learning
|
|
304
|
-
|
|
305
|
-
- [ ] Cross-session preference extraction — mine conversation history to discover user style, tone, and layout preferences
|
|
306
|
-
- [ ] Dynamic skill augmentation — automatically append learned preferences to preset skills at session start
|
|
307
|
-
- [ ] In-session adaptation — agent refines its approach in real-time based on user feedback patterns
|
|
313
|
+
- [ ] In-session adaptation — agent refines its approach in real-time based on feedback within a session
|
|
308
314
|
|
|
309
315
|
## Acknowledgements
|
|
310
316
|
|
package/bin/pneuma.ts
CHANGED
|
@@ -276,8 +276,308 @@ function checkClaudeCode() {
|
|
|
276
276
|
}
|
|
277
277
|
}
|
|
278
278
|
|
|
279
|
+
async function handleEvolveCommand(args: string[]) {
|
|
280
|
+
let workspace = process.cwd();
|
|
281
|
+
let modeName = "";
|
|
282
|
+
let subAction = ""; // "apply", "rollback", "show", or "" (propose)
|
|
283
|
+
|
|
284
|
+
for (let i = 0; i < args.length; i++) {
|
|
285
|
+
const arg = args[i];
|
|
286
|
+
if (arg === "--workspace" && i + 1 < args.length) {
|
|
287
|
+
workspace = resolve(args[++i]);
|
|
288
|
+
} else if (arg === "--mode" && i + 1 < args.length) {
|
|
289
|
+
modeName = args[++i];
|
|
290
|
+
} else if (["apply", "rollback", "show", "list"].includes(arg)) {
|
|
291
|
+
subAction = arg;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
workspace = resolve(workspace);
|
|
296
|
+
|
|
297
|
+
const {
|
|
298
|
+
loadProposal, loadLatestProposal, listProposals,
|
|
299
|
+
applyProposal, rollbackProposal, formatProposalForDisplay,
|
|
300
|
+
} = await import("../server/evolution-proposal.js");
|
|
301
|
+
|
|
302
|
+
if (subAction === "list") {
|
|
303
|
+
const proposals = listProposals(workspace);
|
|
304
|
+
if (proposals.length === 0) {
|
|
305
|
+
p.log.info("No evolution proposals found.");
|
|
306
|
+
} else {
|
|
307
|
+
p.log.info(`${proposals.length} proposal(s):`);
|
|
308
|
+
for (const prop of proposals) {
|
|
309
|
+
const changesCount = prop.changes.length;
|
|
310
|
+
p.log.message(` ${prop.id} [${prop.status}] ${prop.mode} ${changesCount} change(s) ${prop.createdAt}`);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (subAction === "show") {
|
|
317
|
+
const proposal = loadLatestProposal(workspace);
|
|
318
|
+
if (!proposal) {
|
|
319
|
+
p.log.error("No proposals found. Run `pneuma evolve` first.");
|
|
320
|
+
process.exit(1);
|
|
321
|
+
}
|
|
322
|
+
console.log(formatProposalForDisplay(proposal));
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
if (subAction === "apply") {
|
|
327
|
+
const proposal = loadLatestProposal(workspace);
|
|
328
|
+
if (!proposal) {
|
|
329
|
+
p.log.error("No proposals found. Run `pneuma evolve` first.");
|
|
330
|
+
process.exit(1);
|
|
331
|
+
}
|
|
332
|
+
if (proposal.status !== "pending") {
|
|
333
|
+
p.log.error(`Proposal ${proposal.id} is already ${proposal.status}.`);
|
|
334
|
+
process.exit(1);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
console.log(formatProposalForDisplay(proposal));
|
|
338
|
+
console.log("");
|
|
339
|
+
|
|
340
|
+
const confirm = await p.confirm({ message: "Apply this proposal?" });
|
|
341
|
+
if (p.isCancel(confirm) || !confirm) {
|
|
342
|
+
p.log.info("Cancelled.");
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const result = applyProposal(workspace, proposal.id);
|
|
347
|
+
if (result.success) {
|
|
348
|
+
p.log.success(`Applied ${result.appliedFiles.length} file(s). Use \`pneuma evolve rollback\` to revert.`);
|
|
349
|
+
for (const f of result.appliedFiles) {
|
|
350
|
+
p.log.step(` ✓ ${f}`);
|
|
351
|
+
}
|
|
352
|
+
} else {
|
|
353
|
+
p.log.error(`Apply failed: ${result.error}`);
|
|
354
|
+
}
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (subAction === "rollback") {
|
|
359
|
+
const proposals = listProposals(workspace);
|
|
360
|
+
const applied = proposals.find(p => p.status === "applied");
|
|
361
|
+
if (!applied) {
|
|
362
|
+
p.log.error("No applied proposals to rollback.");
|
|
363
|
+
process.exit(1);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
const confirm = await p.confirm({ message: `Rollback proposal ${applied.id}?` });
|
|
367
|
+
if (p.isCancel(confirm) || !confirm) {
|
|
368
|
+
p.log.info("Cancelled.");
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
const result = rollbackProposal(workspace, applied.id);
|
|
373
|
+
if (result.success) {
|
|
374
|
+
p.log.success(`Rolled back ${result.restoredFiles.length} file(s).`);
|
|
375
|
+
for (const f of result.restoredFiles) {
|
|
376
|
+
p.log.step(` ✓ ${f}`);
|
|
377
|
+
}
|
|
378
|
+
} else {
|
|
379
|
+
p.log.error(`Rollback failed: ${result.error}`);
|
|
380
|
+
}
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Default: launch evolution agent as a standard pneuma session
|
|
385
|
+
let port = 0;
|
|
386
|
+
let noOpen = false;
|
|
387
|
+
let noPrompt = false;
|
|
388
|
+
let debug = false;
|
|
389
|
+
let forceDev = false;
|
|
390
|
+
|
|
391
|
+
// Re-parse flags from the evolve subcommand args
|
|
392
|
+
for (let i = 0; i < args.length; i++) {
|
|
393
|
+
const arg = args[i];
|
|
394
|
+
if (arg === "--port" && i + 1 < args.length) {
|
|
395
|
+
port = Number(args[++i]);
|
|
396
|
+
} else if (arg === "--no-open") {
|
|
397
|
+
noOpen = true;
|
|
398
|
+
} else if (arg === "--no-prompt") {
|
|
399
|
+
noPrompt = true;
|
|
400
|
+
} else if (arg === "--debug") {
|
|
401
|
+
debug = true;
|
|
402
|
+
} else if (arg === "--dev") {
|
|
403
|
+
forceDev = true;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Resolve target mode from --mode flag or existing session
|
|
408
|
+
if (!modeName) {
|
|
409
|
+
const session = loadSession(workspace);
|
|
410
|
+
if (session?.mode) {
|
|
411
|
+
modeName = session.mode;
|
|
412
|
+
} else {
|
|
413
|
+
// Check if targetMode was passed via config (from Launcher)
|
|
414
|
+
const configPath = join(workspace, ".pneuma", "config.json");
|
|
415
|
+
try {
|
|
416
|
+
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
417
|
+
if (config.targetMode) modeName = config.targetMode;
|
|
418
|
+
} catch {}
|
|
419
|
+
}
|
|
420
|
+
if (!modeName) {
|
|
421
|
+
p.cancel("No mode specified and no .pneuma/session.json found.\nUse: pneuma evolve --mode <mode> --workspace <path>");
|
|
422
|
+
process.exit(1);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
checkClaudeCode();
|
|
427
|
+
|
|
428
|
+
// 1. Resolve target mode and build evolution data
|
|
429
|
+
let resolved: ResolvedMode;
|
|
430
|
+
try {
|
|
431
|
+
resolved = await resolveModeSource(modeName, PROJECT_ROOT);
|
|
432
|
+
} catch (err) {
|
|
433
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
434
|
+
p.cancel(`Failed to resolve mode "${modeName}": ${msg}`);
|
|
435
|
+
process.exit(1);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
if (resolved.type !== "builtin") {
|
|
439
|
+
registerExternalMode(resolved.name, resolved.path);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
let manifest: ModeManifest;
|
|
443
|
+
try {
|
|
444
|
+
manifest = await loadModeManifest(resolved.name);
|
|
445
|
+
} catch (err) {
|
|
446
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
447
|
+
p.cancel(`Failed to load mode "${resolved.name}": ${msg}`);
|
|
448
|
+
process.exit(1);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
p.log.step(`Evolving skill for ${manifest.displayName} mode...`);
|
|
452
|
+
p.log.info(`Workspace: ${workspace}`);
|
|
453
|
+
|
|
454
|
+
// 2. Build evolution prompt + metadata, save metadata as initParams
|
|
455
|
+
const { buildEvolutionPrompt, buildEvolutionMetadata } = await import("../server/evolution-agent.js");
|
|
456
|
+
const evolutionPrompt = buildEvolutionPrompt({ workspace, manifest });
|
|
457
|
+
const metadata = buildEvolutionMetadata({ workspace, manifest });
|
|
458
|
+
|
|
459
|
+
// Save metadata to .pneuma/config.json so the viewer dashboard can read it
|
|
460
|
+
const pneumaDir = join(workspace, ".pneuma");
|
|
461
|
+
mkdirSync(pneumaDir, { recursive: true });
|
|
462
|
+
writeFileSync(join(pneumaDir, "config.json"), JSON.stringify(metadata, null, 2));
|
|
463
|
+
|
|
464
|
+
// 3. Install evolve skill (so agent has dashboard context in SKILL.md)
|
|
465
|
+
const evolveManifest = await loadModeManifest("evolve");
|
|
466
|
+
const evolveModeSourceDir = join(PROJECT_ROOT, "modes", "evolve");
|
|
467
|
+
installSkill(workspace, evolveManifest.skill, evolveModeSourceDir, {}, evolveManifest.viewerApi);
|
|
468
|
+
|
|
469
|
+
// 4. Determine dev vs production mode
|
|
470
|
+
const distDir = resolve(PROJECT_ROOT, "dist");
|
|
471
|
+
const isDev = forceDev || !existsSync(join(distDir, "index.html"));
|
|
472
|
+
const effectivePort = port || (isDev ? 17007 : 17996);
|
|
473
|
+
|
|
474
|
+
// 5. Start server with evolution routes
|
|
475
|
+
const { server, wsBridge, port: actualPort } = startServer({
|
|
476
|
+
port: effectivePort,
|
|
477
|
+
workspace,
|
|
478
|
+
watchPatterns: [],
|
|
479
|
+
...(isDev ? {} : { distDir }),
|
|
480
|
+
modeName: "evolve",
|
|
481
|
+
projectRoot: PROJECT_ROOT,
|
|
482
|
+
debug,
|
|
483
|
+
forceDev: isDev,
|
|
484
|
+
initParams: metadata as unknown as Record<string, string | number>,
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
// 6. Launch agent via ClaudeCodeBackend (fresh session, bypassPermissions)
|
|
488
|
+
const backend = new ClaudeCodeBackend(actualPort);
|
|
489
|
+
const session = backend.launch({
|
|
490
|
+
cwd: workspace,
|
|
491
|
+
permissionMode: "bypassPermissions",
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
p.log.info(`Agent session: ${session.sessionId}`);
|
|
495
|
+
|
|
496
|
+
// 7. Inject evolution prompt as greeting (dynamic, not from manifest)
|
|
497
|
+
wsBridge.injectGreeting(session.sessionId, evolutionPrompt);
|
|
498
|
+
console.log("[pneuma] Sent evolution prompt to agent");
|
|
499
|
+
|
|
500
|
+
// 8. Start Vite (dev) or serve dist (prod), open browser
|
|
501
|
+
let viteProc: ReturnType<typeof Bun.spawn> | null = null;
|
|
502
|
+
let browserPort = actualPort;
|
|
503
|
+
|
|
504
|
+
if (isDev) {
|
|
505
|
+
const VITE_PORT = 17996;
|
|
506
|
+
p.log.step(`Starting Vite dev server on port ${VITE_PORT}...`);
|
|
507
|
+
|
|
508
|
+
const viteEnv: Record<string, string> = {
|
|
509
|
+
...process.env as Record<string, string>,
|
|
510
|
+
VITE_API_PORT: String(actualPort),
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
viteProc = Bun.spawn(
|
|
514
|
+
["bunx", "vite", "--port", String(VITE_PORT)],
|
|
515
|
+
{ cwd: PROJECT_ROOT, stdout: "pipe", stderr: "pipe", env: viteEnv },
|
|
516
|
+
);
|
|
517
|
+
|
|
518
|
+
let vitePortResolved = false;
|
|
519
|
+
browserPort = await new Promise<number>((resolvePort) => {
|
|
520
|
+
const timeout = setTimeout(() => {
|
|
521
|
+
if (!vitePortResolved) { vitePortResolved = true; resolvePort(VITE_PORT); }
|
|
522
|
+
}, 10_000);
|
|
523
|
+
|
|
524
|
+
const pipeAndParse = async (stream: ReadableStream<Uint8Array>) => {
|
|
525
|
+
const reader = stream.getReader();
|
|
526
|
+
const decoder = new TextDecoder();
|
|
527
|
+
while (true) {
|
|
528
|
+
const { done, value } = await reader.read();
|
|
529
|
+
if (done) break;
|
|
530
|
+
const text = decoder.decode(value, { stream: true });
|
|
531
|
+
for (const line of text.split("\n")) {
|
|
532
|
+
if (line.trim()) console.log(`[vite] ${line}`);
|
|
533
|
+
if (!vitePortResolved) {
|
|
534
|
+
const match = line.match(/Local:\s+https?:\/\/[^:]+:(\d+)/);
|
|
535
|
+
if (match) {
|
|
536
|
+
vitePortResolved = true;
|
|
537
|
+
clearTimeout(timeout);
|
|
538
|
+
resolvePort(parseInt(match[1], 10));
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
if (viteProc!.stdout && typeof viteProc!.stdout !== "number") pipeAndParse(viteProc!.stdout);
|
|
545
|
+
if (viteProc!.stderr && typeof viteProc!.stderr !== "number") pipeAndParse(viteProc!.stderr);
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// 9. Open browser with evolution mode dashboard
|
|
550
|
+
const debugParam = debug ? "&debug=1" : "";
|
|
551
|
+
const browserUrl = `http://localhost:${browserPort}?session=${session.sessionId}&mode=evolve${debugParam}`;
|
|
552
|
+
console.log(`[pneuma] ready ${browserUrl}`);
|
|
553
|
+
|
|
554
|
+
if (!noOpen) {
|
|
555
|
+
p.log.success(`Ready → ${browserUrl}`);
|
|
556
|
+
try {
|
|
557
|
+
if (process.platform === "win32") {
|
|
558
|
+
Bun.spawn(["cmd", "/c", "start", "", browserUrl], { stdout: "ignore", stderr: "ignore" });
|
|
559
|
+
} else {
|
|
560
|
+
const opener = process.platform === "darwin" ? "open" : "xdg-open";
|
|
561
|
+
Bun.spawn([opener, browserUrl], { stdout: "ignore", stderr: "ignore" });
|
|
562
|
+
}
|
|
563
|
+
} catch {
|
|
564
|
+
p.log.warn(`Could not open browser. Visit: ${browserUrl}`);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// 10. Graceful shutdown
|
|
569
|
+
const shutdown = async () => {
|
|
570
|
+
viteProc?.kill();
|
|
571
|
+
await backend.killAll();
|
|
572
|
+
server.stop(true);
|
|
573
|
+
p.outro("Goodbye!");
|
|
574
|
+
process.exit(0);
|
|
575
|
+
};
|
|
576
|
+
process.on("SIGINT", shutdown);
|
|
577
|
+
process.on("SIGTERM", shutdown);
|
|
578
|
+
}
|
|
579
|
+
|
|
279
580
|
async function main() {
|
|
280
|
-
// Read version from package.json
|
|
281
581
|
const pkgPath = join(PROJECT_ROOT, "package.json");
|
|
282
582
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
283
583
|
|
|
@@ -352,6 +652,16 @@ async function main() {
|
|
|
352
652
|
// Unknown mode subcommand — fall through to normal mode resolution
|
|
353
653
|
}
|
|
354
654
|
|
|
655
|
+
// Evolve subcommand — AI-native skill evolution
|
|
656
|
+
// Find "evolve" in rawArgs (may be preceded by flags like --dev)
|
|
657
|
+
const evolveIdx = rawArgs.findIndex(a => a === "evolve");
|
|
658
|
+
if (evolveIdx !== -1) {
|
|
659
|
+
// Pass all args except "evolve" itself to the handler
|
|
660
|
+
const evolveArgs = [...rawArgs.slice(0, evolveIdx), ...rawArgs.slice(evolveIdx + 1)];
|
|
661
|
+
await handleEvolveCommand(evolveArgs);
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
|
|
355
665
|
const { mode, workspace, port, noOpen, debug, forceDev, noPrompt, skipSkill } = parseArgs(process.argv);
|
|
356
666
|
|
|
357
667
|
// Launcher mode — no mode arg → start marketplace UI
|
package/core/mode-loader.ts
CHANGED
|
@@ -61,6 +61,13 @@ const builtinModes: Record<string, ModeSource> = {
|
|
|
61
61
|
definitionLoader: () =>
|
|
62
62
|
import("../modes/mode-maker/pneuma-mode.js").then((m) => m.default),
|
|
63
63
|
},
|
|
64
|
+
evolve: {
|
|
65
|
+
type: "builtin",
|
|
66
|
+
manifestLoader: () =>
|
|
67
|
+
import("../modes/evolve/manifest.js").then((m) => m.default),
|
|
68
|
+
definitionLoader: () =>
|
|
69
|
+
import("../modes/evolve/pneuma-mode.js").then((m) => m.default),
|
|
70
|
+
},
|
|
64
71
|
};
|
|
65
72
|
|
|
66
73
|
/** 外部 mode 注册表 — 由 CLI 在启动时通过 registerExternalMode 注册 */
|
package/core/types/index.ts
CHANGED
|
@@ -159,6 +159,47 @@ export interface ViewerApiConfig {
|
|
|
159
159
|
};
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
+
/**
|
|
163
|
+
* Skill 演进配置 — 定义 Evolution Agent 的目标方向和可用工具。
|
|
164
|
+
*
|
|
165
|
+
* Evolution Agent 是一个独立的 Agent 过程,分析用户历史并增强 skill 文件。
|
|
166
|
+
* 它输出一个 proposal(附带证据和引用),用户审核后可 apply 或取消。
|
|
167
|
+
*/
|
|
168
|
+
export interface EvolutionConfig {
|
|
169
|
+
/**
|
|
170
|
+
* 演进方向 — 给 Evolution Agent 的目标描述。
|
|
171
|
+
* 告诉 Agent 这个 Mode 的 skill 应该朝什么方向个性化。
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* "Learn the user's presentation style preferences: typography choices,
|
|
175
|
+
* color palette tendencies, layout density, slide structure patterns.
|
|
176
|
+
* Augment the skill to guide the main agent toward these preferences
|
|
177
|
+
* as defaults while respecting explicit user instructions."
|
|
178
|
+
*/
|
|
179
|
+
directive: string;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* 额外的数据获取工具(预留,第一版不实现)。
|
|
183
|
+
* 框架已内置基础工具(读取 CC 历史等),这里声明 Mode 特有的。
|
|
184
|
+
*/
|
|
185
|
+
tools?: EvolutionTool[];
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Evolution Agent 可用的外部数据获取工具(预留)。
|
|
190
|
+
* 第一版不实现,框架内置工具足够。
|
|
191
|
+
*/
|
|
192
|
+
export interface EvolutionTool {
|
|
193
|
+
/** 工具名称 */
|
|
194
|
+
name: string;
|
|
195
|
+
/** 工具描述(给 Agent 看的) */
|
|
196
|
+
description: string;
|
|
197
|
+
/** 实现方式 */
|
|
198
|
+
type: "command" | "http" | "mcp";
|
|
199
|
+
/** 具体配置 */
|
|
200
|
+
config: Record<string, unknown>;
|
|
201
|
+
}
|
|
202
|
+
|
|
162
203
|
/** Mode 的完整声明式描述 */
|
|
163
204
|
export interface ModeManifest {
|
|
164
205
|
/** Mode 唯一标识 (e.g. "doc", "slide") */
|
|
@@ -182,4 +223,6 @@ export interface ModeManifest {
|
|
|
182
223
|
init?: InitConfig;
|
|
183
224
|
/** Viewer 自描述 API — 纯数据声明,后端可读,自动注入 CLAUDE.md */
|
|
184
225
|
viewerApi?: ViewerApiConfig;
|
|
226
|
+
/** Skill 演进配置 — 定义 Evolution Agent 的演进方向 (可选) */
|
|
227
|
+
evolution?: EvolutionConfig;
|
|
185
228
|
}
|