agentworkshop 0.8.3 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/B4iJT5PX2.js +2 -0
  3. package/.output/public/_nuxt/BNUaS1jv.js +20 -0
  4. package/.output/public/_nuxt/BhJA-E372.js +1 -0
  5. package/.output/public/_nuxt/Bq8YzXzs2.js +1 -0
  6. package/.output/public/_nuxt/Cf7ER7e2.js +1 -0
  7. package/.output/public/_nuxt/{DrlnrdvY2.js → DPnjnDtg.js} +1 -1
  8. package/.output/public/_nuxt/DgTqKyYF2.js +1 -0
  9. package/.output/public/_nuxt/MmlCf-EZ.js +1 -0
  10. package/.output/public/_nuxt/builds/latest.json +1 -1
  11. package/.output/public/_nuxt/builds/meta/8a151630-3285-41b8-a1e5-063fee2002ac.json +1 -0
  12. package/.output/public/_nuxt/{entry.C7koBPom.css → entry.D6nBdXet.css} +1 -1
  13. package/.output/public/_nuxt/{ontology.JqJ6PjV1.css → ontology.D4P756Tc.css} +1 -1
  14. package/.output/public/_nuxt/pipeline.NFs5z5V-.css +1 -0
  15. package/.output/server/chunks/_/character-asset.repo.mjs +1 -1
  16. package/.output/server/chunks/_/chart-repo.mjs +1 -1
  17. package/.output/server/chunks/_/chart-repo.mjs.map +1 -1
  18. package/.output/server/chunks/_/eda-db.mjs +12 -0
  19. package/.output/server/chunks/_/eda-db.mjs.map +1 -1
  20. package/.output/server/chunks/_/host-bindings.mjs +1 -1
  21. package/.output/server/chunks/_/nitro.mjs +1977 -1951
  22. package/.output/server/chunks/_/scene-layout.repo.mjs +1 -1
  23. package/.output/server/chunks/_/template-repo.mjs +97 -0
  24. package/.output/server/chunks/_/template-repo.mjs.map +1 -0
  25. package/.output/server/chunks/build/{TownView-CUbzOT_M.mjs → TownView-CcUPLqF1.mjs} +3 -3
  26. package/.output/server/chunks/build/{TownView-CUbzOT_M.mjs.map → TownView-CcUPLqF1.mjs.map} +1 -1
  27. package/.output/server/chunks/build/{_id_-JaGx0yBE.mjs → _id_-AgACEyL6.mjs} +13 -13
  28. package/.output/server/chunks/build/{_id_-JaGx0yBE.mjs.map → _id_-AgACEyL6.mjs.map} +1 -1
  29. package/.output/server/chunks/build/{_id_-BHWZiRQZ.mjs → _id_-B3yCK2lD.mjs} +8 -8
  30. package/.output/server/chunks/build/{_id_-BHWZiRQZ.mjs.map → _id_-B3yCK2lD.mjs.map} +1 -1
  31. package/.output/server/chunks/build/{_wsId_-C4DKkEqv.mjs → _wsId_-kcDriA4i.mjs} +4 -4
  32. package/.output/server/chunks/build/{_wsId_-C4DKkEqv.mjs.map → _wsId_-kcDriA4i.mjs.map} +1 -1
  33. package/.output/server/chunks/build/{analysis-tNpFLtMt.mjs → analysis-CMsMTMCg.mjs} +3 -3
  34. package/.output/server/chunks/build/{analysis-tNpFLtMt.mjs.map → analysis-CMsMTMCg.mjs.map} +1 -1
  35. package/.output/server/chunks/build/{daq-DHsYtWC-.mjs → daq-DFQQOtcZ.mjs} +7 -7
  36. package/.output/server/chunks/build/{daq-DHsYtWC-.mjs.map → daq-DFQQOtcZ.mjs.map} +1 -1
  37. package/.output/server/chunks/build/{dcw-DnjOM6p1.mjs → dcw-8415S3Km.mjs} +7 -7
  38. package/.output/server/chunks/build/{dcw-DnjOM6p1.mjs.map → dcw-8415S3Km.mjs.map} +1 -1
  39. package/.output/server/chunks/build/{logs-C4vKFkHQ.mjs → logs-C-dWpJ80.mjs} +3 -3
  40. package/.output/server/chunks/build/{logs-C4vKFkHQ.mjs.map → logs-C-dWpJ80.mjs.map} +1 -1
  41. package/.output/server/chunks/build/{ontology-B_0Vm6j-.mjs → ontology-DoXAsa2y.mjs} +62 -62
  42. package/.output/server/chunks/build/ontology-DoXAsa2y.mjs.map +1 -0
  43. package/.output/server/chunks/build/{operations-D8D6-Jm-.mjs → operations-Ch6tZIKo.mjs} +3 -3
  44. package/.output/server/chunks/build/{operations-D8D6-Jm-.mjs.map → operations-Ch6tZIKo.mjs.map} +1 -1
  45. package/.output/server/chunks/build/{pages-Dac4icQC.mjs → pages-CQOfwKB4.mjs} +4 -4
  46. package/.output/server/chunks/build/{pages-Dac4icQC.mjs.map → pages-CQOfwKB4.mjs.map} +1 -1
  47. package/.output/server/chunks/build/pipeline-eo2RWN3f.mjs +226 -0
  48. package/.output/server/chunks/build/pipeline-eo2RWN3f.mjs.map +1 -0
  49. package/.output/server/chunks/build/{town-LkDwWnKA.mjs → town-DLFB4SZl.mjs} +4 -4
  50. package/.output/server/chunks/build/{town-LkDwWnKA.mjs.map → town-DLFB4SZl.mjs.map} +1 -1
  51. package/.output/server/chunks/build/{useDaqAddNode-CRorxgOY.mjs → useDaqAddNode-D_1EBuR3.mjs} +2 -2
  52. package/.output/server/chunks/build/{useDaqAddNode-CRorxgOY.mjs.map → useDaqAddNode-D_1EBuR3.mjs.map} +1 -1
  53. package/.output/server/chunks/build/{useDaqDetailBinding-Ck-YUW9J.mjs → useDaqDetailBinding-j05iSApd.mjs} +2 -2
  54. package/.output/server/chunks/build/{useDaqDetailBinding-Ck-YUW9J.mjs.map → useDaqDetailBinding-j05iSApd.mjs.map} +1 -1
  55. package/.output/server/chunks/build/{useDaqDetailFrames-CLMoreaz.mjs → useDaqDetailFrames-BKciVJ78.mjs} +2 -2
  56. package/.output/server/chunks/build/{useDaqDetailFrames-CLMoreaz.mjs.map → useDaqDetailFrames-BKciVJ78.mjs.map} +1 -1
  57. package/.output/server/chunks/build/{useDaqDetailHistory-BVNQXwC_.mjs → useDaqDetailHistory-DgemICkr.mjs} +2 -2
  58. package/.output/server/chunks/build/{useDaqDetailHistory-BVNQXwC_.mjs.map → useDaqDetailHistory-DgemICkr.mjs.map} +1 -1
  59. package/.output/server/chunks/build/{useDaqDetailNode-BC0e9OfX.mjs → useDaqDetailNode-Cn7_og6t.mjs} +3 -3
  60. package/.output/server/chunks/build/{useDaqDetailNode-BC0e9OfX.mjs.map → useDaqDetailNode-Cn7_og6t.mjs.map} +1 -1
  61. package/.output/server/chunks/build/{useDaqDetailParams-D173iwFg.mjs → useDaqDetailParams-DX_vjFyK.mjs} +2 -2
  62. package/.output/server/chunks/build/{useDaqDetailParams-D173iwFg.mjs.map → useDaqDetailParams-DX_vjFyK.mjs.map} +1 -1
  63. package/.output/server/chunks/build/{useDaqFilters-CC-o_21d.mjs → useDaqFilters-DMS4GN20.mjs} +3 -3
  64. package/.output/server/chunks/build/{useDaqFilters-CC-o_21d.mjs.map → useDaqFilters-DMS4GN20.mjs.map} +1 -1
  65. package/.output/server/chunks/build/{useDaqOptimizations-4vK2w1yn.mjs → useDaqOptimizations-OPbdy5YB.mjs} +2 -2
  66. package/.output/server/chunks/build/{useDaqOptimizations-4vK2w1yn.mjs.map → useDaqOptimizations-OPbdy5YB.mjs.map} +1 -1
  67. package/.output/server/chunks/build/{useDaqStream-BHKpSJFd.mjs → useDaqStream-CS1G6iro.mjs} +1 -1
  68. package/.output/server/chunks/build/{useDaqStream-BHKpSJFd.mjs.map → useDaqStream-CS1G6iro.mjs.map} +1 -1
  69. package/.output/server/chunks/build/{useDaqTemplates-CsXSc7yI.mjs → useDaqTemplates-DqhRYo88.mjs} +2 -2
  70. package/.output/server/chunks/build/{useDaqTemplates-CsXSc7yI.mjs.map → useDaqTemplates-DqhRYo88.mjs.map} +1 -1
  71. package/.output/server/chunks/build/{useDashboardData-DuKjuJTz.mjs → useDashboardData-CeaMjEA9.mjs} +3 -3
  72. package/.output/server/chunks/build/{useDashboardData-DuKjuJTz.mjs.map → useDashboardData-CeaMjEA9.mjs.map} +1 -1
  73. package/.output/server/chunks/build/{useDcwAddNode-C5DcxsHF.mjs → useDcwAddNode-Cytz_odQ.mjs} +2 -2
  74. package/.output/server/chunks/build/{useDcwAddNode-C5DcxsHF.mjs.map → useDcwAddNode-Cytz_odQ.mjs.map} +1 -1
  75. package/.output/server/chunks/build/{useDcwCards-0bAVo6uB.mjs → useDcwCards-BKCFqkRd.mjs} +2 -2
  76. package/.output/server/chunks/build/{useDcwCards-0bAVo6uB.mjs.map → useDcwCards-BKCFqkRd.mjs.map} +1 -1
  77. package/.output/server/chunks/build/{useDcwDetailScope-BNFOlt2v.mjs → useDcwDetailScope-CvdvcKAv.mjs} +3 -3
  78. package/.output/server/chunks/build/{useDcwDetailScope-BNFOlt2v.mjs.map → useDcwDetailScope-CvdvcKAv.mjs.map} +1 -1
  79. package/.output/server/chunks/build/{useDcwDetailTemplates-DSH-o0tE.mjs → useDcwDetailTemplates-CC2FcEge.mjs} +2 -2
  80. package/.output/server/chunks/build/{useDcwDetailTemplates-DSH-o0tE.mjs.map → useDcwDetailTemplates-CC2FcEge.mjs.map} +1 -1
  81. package/.output/server/chunks/build/{useDcwFilter-W61BFUcT.mjs → useDcwFilter-CVoiXbZh.mjs} +2 -2
  82. package/.output/server/chunks/build/{useDcwFilter-W61BFUcT.mjs.map → useDcwFilter-CVoiXbZh.mjs.map} +1 -1
  83. package/.output/server/chunks/build/{useDcwLedger-DsColLdc.mjs → useDcwLedger-Cd-ckHoJ.mjs} +2 -2
  84. package/.output/server/chunks/build/{useDcwLedger-DsColLdc.mjs.map → useDcwLedger-Cd-ckHoJ.mjs.map} +1 -1
  85. package/.output/server/chunks/build/{useDcwLineMutations-Cx4Ir7g3.mjs → useDcwLineMutations-BOQs-fw3.mjs} +2 -2
  86. package/.output/server/chunks/build/{useDcwLineMutations-Cx4Ir7g3.mjs.map → useDcwLineMutations-BOQs-fw3.mjs.map} +1 -1
  87. package/.output/server/chunks/build/{useDcwLineRun-DQ0vB08z.mjs → useDcwLineRun-D9qvcyTM.mjs} +2 -2
  88. package/.output/server/chunks/build/{useDcwLineRun-DQ0vB08z.mjs.map → useDcwLineRun-D9qvcyTM.mjs.map} +1 -1
  89. package/.output/server/chunks/build/{useDcwParamApprovals-CYspRuDk.mjs → useDcwParamApprovals-D36q4can.mjs} +2 -2
  90. package/.output/server/chunks/build/{useDcwParamApprovals-CYspRuDk.mjs.map → useDcwParamApprovals-D36q4can.mjs.map} +1 -1
  91. package/.output/server/chunks/build/{useDcwProducts-CTbm_5S_.mjs → useDcwProducts-BozctrwT.mjs} +2 -2
  92. package/.output/server/chunks/build/{useDcwProducts-CTbm_5S_.mjs.map → useDcwProducts-BozctrwT.mjs.map} +1 -1
  93. package/.output/server/chunks/build/{useDcwQuery-E0yjZs7G.mjs → useDcwQuery-C8FikKgu.mjs} +2 -2
  94. package/.output/server/chunks/build/{useDcwQuery-E0yjZs7G.mjs.map → useDcwQuery-C8FikKgu.mjs.map} +1 -1
  95. package/.output/server/chunks/build/{useDcwQuickActions-BvT5VFOY.mjs → useDcwQuickActions-IyQ8Rkpe.mjs} +2 -2
  96. package/.output/server/chunks/build/{useDcwQuickActions-BvT5VFOY.mjs.map → useDcwQuickActions-IyQ8Rkpe.mjs.map} +1 -1
  97. package/.output/server/chunks/build/{useDcwRecipes-zngShyk0.mjs → useDcwRecipes-k9HGhMwF.mjs} +2 -2
  98. package/.output/server/chunks/build/{useDcwRecipes-zngShyk0.mjs.map → useDcwRecipes-k9HGhMwF.mjs.map} +1 -1
  99. package/.output/server/chunks/build/{useDcwStream-82IdjJKk.mjs → useDcwStream-BnBOiawo.mjs} +1 -1
  100. package/.output/server/chunks/build/{useDcwStream-82IdjJKk.mjs.map → useDcwStream-BnBOiawo.mjs.map} +1 -1
  101. package/.output/server/chunks/build/{useDcwTemplates-CpHrcnvJ.mjs → useDcwTemplates-CnyYOOy0.mjs} +2 -2
  102. package/.output/server/chunks/build/{useDcwTemplates-CpHrcnvJ.mjs.map → useDcwTemplates-CnyYOOy0.mjs.map} +1 -1
  103. package/.output/server/chunks/build/{useDcwWrites-BlOhljp9.mjs → useDcwWrites-Cco590iv.mjs} +2 -2
  104. package/.output/server/chunks/build/{useDcwWrites-BlOhljp9.mjs.map → useDcwWrites-Cco590iv.mjs.map} +1 -1
  105. package/.output/server/chunks/build/{useLogsScope-BRyy550Y.mjs → useLogsScope-C-yrta-v.mjs} +2 -2
  106. package/.output/server/chunks/build/{useLogsScope-BRyy550Y.mjs.map → useLogsScope-C-yrta-v.mjs.map} +1 -1
  107. package/.output/server/chunks/routes/api/workshop/assets/index.post.mjs +1 -1
  108. package/.output/server/chunks/routes/api/workshop/assets/index2.post.mjs +1 -1
  109. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -1
  110. package/.output/server/chunks/routes/api/workshop/channels/_id/activate.post.mjs +1 -1
  111. package/.output/server/chunks/routes/api/workshop/channels/_id/chat/index.post.mjs +1 -1
  112. package/.output/server/chunks/routes/api/workshop/channels/_id/index.post.mjs +1 -1
  113. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +1 -1
  114. package/.output/server/chunks/routes/api/workshop/channels/_id/index4.post.mjs +1 -1
  115. package/.output/server/chunks/routes/api/workshop/channels/_id/line.put.mjs +1 -1
  116. package/.output/server/chunks/routes/api/workshop/channels/index.get.mjs +1 -1
  117. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +1 -1
  118. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id_.delete.mjs +1 -1
  119. package/.output/server/chunks/routes/api/workshop/eda/index8.get.mjs +33 -0
  120. package/.output/server/chunks/routes/api/workshop/eda/index8.get.mjs.map +1 -0
  121. package/.output/server/chunks/routes/api/workshop/eda/index8.post.mjs +41 -0
  122. package/.output/server/chunks/routes/api/workshop/eda/index8.post.mjs.map +1 -0
  123. package/.output/server/chunks/routes/api/workshop/eda/templates/_id_.delete.mjs +36 -0
  124. package/.output/server/chunks/routes/api/workshop/eda/templates/_id_.delete.mjs.map +1 -0
  125. package/.output/server/chunks/routes/api/workshop/eda/templates/_id_.get.mjs +37 -0
  126. package/.output/server/chunks/routes/api/workshop/eda/templates/_id_.get.mjs.map +1 -0
  127. package/.output/server/chunks/routes/api/workshop/eda/templates/_id_.patch.mjs +42 -0
  128. package/.output/server/chunks/routes/api/workshop/eda/templates/_id_.patch.mjs.map +1 -0
  129. package/.output/server/chunks/routes/api/workshop/index10.post.mjs +33 -0
  130. package/.output/server/chunks/routes/api/workshop/index10.post.mjs.map +1 -0
  131. package/.output/server/chunks/routes/api/workshop/index2.post.mjs +45 -46
  132. package/.output/server/chunks/routes/api/workshop/index2.post.mjs.map +1 -1
  133. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +46 -23
  134. package/.output/server/chunks/routes/api/workshop/index3.post.mjs.map +1 -1
  135. package/.output/server/chunks/routes/api/workshop/index4.post.mjs +10 -9
  136. package/.output/server/chunks/routes/api/workshop/index4.post.mjs.map +1 -1
  137. package/.output/server/chunks/routes/api/workshop/index5.post.mjs +22 -19
  138. package/.output/server/chunks/routes/api/workshop/index5.post.mjs.map +1 -1
  139. package/.output/server/chunks/routes/api/workshop/index6.post.mjs +18 -42
  140. package/.output/server/chunks/routes/api/workshop/index6.post.mjs.map +1 -1
  141. package/.output/server/chunks/routes/api/workshop/index7.post.mjs +43 -17
  142. package/.output/server/chunks/routes/api/workshop/index7.post.mjs.map +1 -1
  143. package/.output/server/chunks/routes/api/workshop/index8.post.mjs +13 -15
  144. package/.output/server/chunks/routes/api/workshop/index8.post.mjs.map +1 -1
  145. package/.output/server/chunks/routes/api/workshop/index9.post.mjs +18 -4
  146. package/.output/server/chunks/routes/api/workshop/index9.post.mjs.map +1 -1
  147. package/.output/server/chunks/routes/api/workshop/process-model/datasets.post.mjs +1 -1
  148. package/.output/server/chunks/routes/api/workshop/process-model/eligibility.mjs +1 -1
  149. package/.output/server/chunks/routes/api/workshop/process-model/experiments.mjs +1 -1
  150. package/.output/server/chunks/routes/api/workshop/teams/_id/deploy.post.mjs +1 -1
  151. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +1 -1
  152. package/.output/server/chunks/routes/renderer.mjs +1 -1
  153. package/.output/server/chunks/virtual/entry.mjs +140 -43
  154. package/.output/server/chunks/virtual/entry.mjs.map +1 -1
  155. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  156. package/.output/server/chunks/virtual/precomputed.mjs.map +1 -1
  157. package/.output/server/package.json +1 -1
  158. package/README-zh.md +8 -5
  159. package/README.md +8 -5
  160. package/app/components/AwChart.vue +14 -0
  161. package/app/pages/ontology/index.vue +1 -1
  162. package/app/pages/studio/pipeline.vue +812 -0
  163. package/app/utils/chart-pipeline.ts +193 -0
  164. package/config.yml +1 -1
  165. package/docs/cli.en.md +2 -2
  166. package/docs/cli.md +2 -2
  167. package/docs/plugins.en.md +1 -1
  168. package/docs/plugins.md +1 -1
  169. package/docs/sdk.en.md +1 -1
  170. package/docs/sdk.md +1 -1
  171. package/i18n/locales/en.ts +46 -0
  172. package/i18n/locales/zh-CN.ts +46 -0
  173. package/package.json +1 -1
  174. package/scripts/check-docs-sync.mjs +1 -1
  175. package/scripts/e2e-eda-pipeline.mjs +286 -0
  176. package/scripts/e2e-resume-crash.mjs +20 -6
  177. package/scripts/e2e-timezone-settings.mjs +4 -2
  178. package/server/api/workshop/analysis/index.post.ts +54 -0
  179. package/server/api/workshop/eda/templates/[id].delete.ts +14 -0
  180. package/server/api/workshop/eda/templates/[id].get.ts +15 -0
  181. package/server/api/workshop/eda/templates/[id].patch.ts +20 -0
  182. package/server/api/workshop/eda/templates/index.get.ts +11 -0
  183. package/server/api/workshop/eda/templates/index.post.ts +20 -0
  184. package/server/services/workshop/eda/chart-repo.ts +1 -1
  185. package/server/services/workshop/eda/eda-db.ts +13 -0
  186. package/server/services/workshop/eda/template-repo.ts +101 -0
  187. package/.output/public/_nuxt/Bbk1XCCM.js +0 -14
  188. package/.output/public/_nuxt/CMzExk8F.js +0 -1
  189. package/.output/public/_nuxt/D6FhDrYe2.js +0 -1
  190. package/.output/public/_nuxt/DF9ETYJ32.js +0 -1
  191. package/.output/public/_nuxt/DoChWkff.js +0 -1
  192. package/.output/public/_nuxt/YNhAoK-R2.js +0 -1
  193. package/.output/public/_nuxt/builds/meta/fd0033e4-1eaa-42f8-9a04-3132717a703b.json +0 -1
  194. package/.output/server/chunks/build/ontology-B_0Vm6j-.mjs.map +0 -1
  195. /package/.output/public/_nuxt/{DgrK8UCQ.js → BvRk9kiK2.js} +0 -0
  196. /package/.output/public/_nuxt/{DxH5focQ2.js → DxH5focQ.js} +0 -0
@@ -0,0 +1,193 @@
1
+ /**
2
+ * EDA 管道前端工具 —— 数据后处理(用户代码,仅浏览器执行) + 通用图表 option 构建 + PNG 导出。
3
+ *
4
+ * 安全边界:transform 代码只在用户自己的浏览器里 new Function 执行(行业惯例,同
5
+ * Observable/Jupyter 客户端单元格),永不发往服务端 eval;服务端只存代码文本。
6
+ */
7
+ import type { EChartsOption } from 'echarts'
8
+
9
+ export interface PipelineRow {
10
+ [key: string]: unknown
11
+ }
12
+
13
+ /** 行内数值判定(null/undefined/空串不算数) */
14
+ export function isNum(v: unknown): v is number {
15
+ return typeof v === 'number' && Number.isFinite(v)
16
+ }
17
+
18
+ /** 推断数据列(保序;数值列/时间列/其他) */
19
+ export function deriveFields(rows: PipelineRow[]): { name: string, numeric: boolean }[] {
20
+ const cols = new Map<string, { numeric: number, seen: number }>()
21
+ for (const row of rows.slice(0, 200)) {
22
+ for (const [k, v] of Object.entries(row)) {
23
+ const c = cols.get(k) ?? { numeric: 0, seen: 0 }
24
+ c.seen += 1
25
+ if (isNum(v)) c.numeric += 1
26
+ cols.set(k, c)
27
+ }
28
+ }
29
+ return [...cols.entries()].map(([name, c]) => ({ name, numeric: c.numeric > 0 && c.numeric >= c.seen * 0.6 }))
30
+ }
31
+
32
+ /**
33
+ * 执行用户后处理代码。约定:代码里定义 `function transform(rows) { return rows }`,
34
+ * 返回新行数组;亦可就地 filter/map。任何异常都收敛为 { error },不抛出拖垮页面。
35
+ */
36
+ export function runTransform(rows: PipelineRow[], code: string): { rows: PipelineRow[], error: string } {
37
+ const trimmed = code.trim()
38
+ if (!trimmed) return { rows, error: '' }
39
+ try {
40
+ const fn = new Function('rows', `"use strict";\n${trimmed}\n;return transform(rows);`) as (rows: PipelineRow[]) => PipelineRow[]
41
+ const out = fn(rows)
42
+ if (!Array.isArray(out)) return { rows, error: 'transform 必须返回数组。' }
43
+ return { rows: out as PipelineRow[], error: '' }
44
+ }
45
+ catch (err) {
46
+ return { rows, error: err instanceof Error ? `${err.name}: ${err.message}` : String(err) }
47
+ }
48
+ }
49
+
50
+ export interface PipelineConfig {
51
+ xField: string
52
+ yFields: string[]
53
+ groupField?: string
54
+ agg: 'avg' | 'sum' | 'min' | 'max' | 'count'
55
+ title?: string
56
+ yMin?: number | null
57
+ yMax?: number | null
58
+ refLine?: number | null
59
+ }
60
+
61
+ const AGG_FN: Record<PipelineConfig['agg'], (vals: number[]) => number> = {
62
+ avg: vs => vs.reduce((a, b) => a + b, 0) / Math.max(vs.length, 1),
63
+ sum: vs => vs.reduce((a, b) => a + b, 0),
64
+ min: vs => Math.min(...vs),
65
+ max: vs => Math.max(...vs),
66
+ count: vs => vs.length,
67
+ }
68
+
69
+ /** 按 x 分桶聚合(groupField 存在时再按组拆系列) */
70
+ export function aggregateRows(rows: PipelineRow[], cfg: PipelineConfig): { categories: string[], series: Map<string, Array<number | null>> } {
71
+ const agg = AGG_FN[cfg.agg] ?? AGG_FN.avg
72
+ const buckets = new Map<string, Map<string, Map<string, number[]>>>()
73
+ for (const row of rows) {
74
+ const rawX = row[cfg.xField]
75
+ if (rawX === undefined || rawX === null) continue
76
+ const x = String(rawX)
77
+ const group = cfg.groupField ? String(row[cfg.groupField] ?? '—') : '__all__'
78
+ const bucket = buckets.get(x) ?? new Map<string, Map<string, number[]>>()
79
+ const cell = bucket.get(group) ?? new Map<string, number[]>()
80
+ for (const yf of cfg.yFields) {
81
+ const arr = cell.get(yf) ?? []
82
+ const v = row[yf]
83
+ if (isNum(v)) arr.push(v)
84
+ cell.set(yf, arr)
85
+ }
86
+ bucket.set(group, cell)
87
+ buckets.set(x, bucket)
88
+ }
89
+ const categories = [...buckets.keys()]
90
+ const series = new Map<string, Array<number | null>>()
91
+ const groups = new Set<string>()
92
+ for (const b of buckets.values()) for (const g of b.keys()) groups.add(g)
93
+ for (const g of groups) {
94
+ for (const yf of cfg.yFields) {
95
+ const key = groups.size > 1 || cfg.yFields.length > 1 ? `${g === '__all__' ? '' : `${g} · `}${yf}` : g === '__all__' ? yf : g
96
+ series.set(key, categories.map((x) => {
97
+ const vals = (buckets.get(x)?.get(g)?.get(yf) ?? []).filter(isNum)
98
+ return vals.length ? Math.round(agg(vals) * 1e6) / 1e6 : null
99
+ }))
100
+ }
101
+ }
102
+ return { categories, series }
103
+ }
104
+
105
+ /** 数值列直方图(等宽分箱) */
106
+ export function histogramBins(rows: PipelineRow[], field: string, bins = 20): { edges: number[], counts: number[] } {
107
+ const vals = rows.map(r => r[field]).filter(isNum)
108
+ if (!vals.length) return { edges: [], counts: [] }
109
+ const min = Math.min(...vals)
110
+ const max = Math.max(...vals)
111
+ const width = (max - min) / bins || 1
112
+ const counts = new Array<number>(bins).fill(0)
113
+ for (const v of vals) {
114
+ const idx = Math.min(Math.floor((v - min) / width), bins - 1)
115
+ counts[idx] = (counts[idx] ?? 0) + 1
116
+ }
117
+ const edges = counts.map((_, i) => Math.round((min + width * i) * 1e4) / 1e4)
118
+ return { edges, counts }
119
+ }
120
+
121
+ const PALETTE = ['#35e0a0', '#41c8f4', '#f5c451', '#e57373', '#9f8fef', '#63d8c6']
122
+
123
+ /** 通用 option:line/bar/scatter/pie/histogram 全走这里 */
124
+ export function buildPipelineOption(type: string, cfg: PipelineConfig, rows: PipelineRow[]): EChartsOption {
125
+ const title = cfg.title ? { title: { text: cfg.title, left: 'left', textStyle: { fontSize: 13 } } } : {}
126
+ const base = {
127
+ ...title,
128
+ color: PALETTE,
129
+ tooltip: { trigger: 'axis' as const },
130
+ legend: { type: 'scroll' as const, bottom: 0, textStyle: { fontSize: 11 } },
131
+ grid: { left: 56, right: 24, top: cfg.title ? 44 : 24, bottom: 56 },
132
+ toolbox: { right: 8, top: 0, feature: { saveAsImage: { pixelRatio: 2 } } },
133
+ }
134
+ if (type === 'histogram') {
135
+ const field = cfg.yFields[0] ?? cfg.xField
136
+ const { edges, counts } = histogramBins(rows, field)
137
+ return {
138
+ ...base,
139
+ tooltip: { trigger: 'axis' as const },
140
+ xAxis: { type: 'category' as const, data: edges.map(e => String(e)), axisLabel: { fontSize: 10 } },
141
+ yAxis: { type: 'value' as const, ...(cfg.yMin != null ? { min: cfg.yMin } : {}), ...(cfg.yMax != null ? { max: cfg.yMax } : {}) },
142
+ series: [{ type: 'bar', name: field, data: counts, barCategoryGap: '8%' }],
143
+ }
144
+ }
145
+ if (type === 'pie') {
146
+ const field = cfg.yFields[0] ?? ''
147
+ const data = rows.slice(0, 200).map(r => ({ name: String(r[cfg.xField] ?? '?'), value: isNum(r[field]) ? r[field] : 0 }))
148
+ return {
149
+ ...base,
150
+ tooltip: { trigger: 'item' as const },
151
+ legend: { type: 'scroll' as const, bottom: 0, textStyle: { fontSize: 11 } },
152
+ series: [{ type: 'pie', radius: ['38%', '68%'], data, label: { fontSize: 10 } }],
153
+ }
154
+ }
155
+ const { categories, series } = aggregateRows(rows, cfg)
156
+ const xAxis = {
157
+ type: 'category' as const,
158
+ data: categories,
159
+ axisLabel: { fontSize: 10, rotate: categories.length > 24 ? 40 : 0 },
160
+ }
161
+ const yAxis = {
162
+ type: 'value' as const,
163
+ ...(cfg.yMin != null ? { min: cfg.yMin } : {}),
164
+ ...(cfg.yMax != null ? { max: cfg.yMax } : {}),
165
+ }
166
+ const markLine = cfg.refLine != null
167
+ ? { markLine: { silent: true, symbol: 'none', lineStyle: { type: 'dashed' as const }, data: [{ yAxis: cfg.refLine }] } }
168
+ : {}
169
+ if (type === 'bar') {
170
+ return {
171
+ ...base,
172
+ xAxis, yAxis,
173
+ series: [...series.entries()].map(([name, data]) => ({ type: 'bar' as const, name, data, barMaxWidth: 32, ...markLine })),
174
+ }
175
+ }
176
+ if (type === 'scatter') {
177
+ return {
178
+ ...base,
179
+ tooltip: { trigger: 'item' as const },
180
+ xAxis: { ...xAxis, type: 'category' as const },
181
+ yAxis,
182
+ series: [...series.entries()].map(([name, data]) => ({ type: 'scatter' as const, name, data, symbolSize: 7, ...markLine })),
183
+ }
184
+ }
185
+ return {
186
+ ...base,
187
+ xAxis, yAxis,
188
+ series: [...series.entries()].map(([name, data]) => ({
189
+ type: 'line' as const, name, data, symbol: 'none', lineWidth: 1.6,
190
+ ...markLine,
191
+ })),
192
+ }
193
+ }
package/config.yml CHANGED
@@ -12,7 +12,7 @@
12
12
  app:
13
13
  name: AgentWorkShop
14
14
  title: AgentWorkShop
15
- version: 0.8.3
15
+ version: 0.8.4
16
16
  description: 基于 Nuxt 4 的配置驱动运行范式
17
17
 
18
18
  # 运行模式(dev/prod 实际由启动命令决定,此处仅作运行时展示)
package/docs/cli.en.md CHANGED
@@ -62,7 +62,7 @@ pnpm tui # the terminal workbench
62
62
  ### 3. Quick use via npx (no global install)
63
63
 
64
64
  ```bash
65
- npx agentworkshop start # fetch and start (pin a version with: npx agentworkshop@0.8.3 start)
65
+ npx agentworkshop start # fetch and start (pin a version with: npx agentworkshop@0.8.4 start)
66
66
  npx agentworkshop doctor # subcommands work as usual
67
67
  npx -p agentworkshop aw doctor # use -p when you want the name aw
68
68
  ```
@@ -79,7 +79,7 @@ npx -p agentworkshop aw doctor # use -p when you want the name aw
79
79
  | Package manager | `pnpm@11.9.0` (`packageManager`, needed only for source development) |
80
80
  | Module format | ESM (`type: module`) |
81
81
  | License | `Apache-2.0` |
82
- | Current version | `0.8.3` (`package.json`) |
82
+ | Current version | `0.8.4` (`package.json`) |
83
83
 
84
84
  ## 2. First start (the Claude Code experience)
85
85
 
package/docs/cli.md CHANGED
@@ -60,7 +60,7 @@ pnpm tui # 终端工作台
60
60
  ### 3. npx 快速使用(免全局安装)
61
61
 
62
62
  ```bash
63
- npx agentworkshop start # 拉取并启动(可锁定版本: npx agentworkshop@0.8.3 start)
63
+ npx agentworkshop start # 拉取并启动(可锁定版本: npx agentworkshop@0.8.4 start)
64
64
  npx agentworkshop doctor # 子命令照常可用
65
65
  npx -p agentworkshop aw doctor # 需要 aw 这个名字时用 -p 指定包
66
66
  ```
@@ -76,7 +76,7 @@ npx -p agentworkshop aw doctor # 需要 aw 这个名字时用 -p 指定包
76
76
  | 包管理器 | `pnpm@11.9.0`(`packageManager`,仅源码开发需要) |
77
77
  | 模块形态 | ESM(`type: module`) |
78
78
  | 许可证 | `Apache-2.0` |
79
- | 当前版本 | `0.8.3`(`package.json`) |
79
+ | 当前版本 | `0.8.4`(`package.json`) |
80
80
 
81
81
  ## 二、首次启动(Claude Code 式)
82
82
 
@@ -9,7 +9,7 @@
9
9
  >
10
10
  > Applies to: plugin system v2 has been available since **v0.7.29** (frontend component
11
11
  > injection / plugin settings / plugin i18n / runtime services surface); this document
12
- > describes **v0.8.3**. `ctx.sdkVersion` is currently `0.3.0`.
12
+ > describes **v0.8.4**. `ctx.sdkVersion` is currently `0.3.0`.
13
13
 
14
14
  ## 1. Folder layout & quick start
15
15
 
package/docs/plugins.md CHANGED
@@ -6,7 +6,7 @@
6
6
  > 本文是唯一权威参考;`docs/site/plugins/` 的分页文档与本文同源。
7
7
  >
8
8
  > 适用版本:插件系统 v2 自 **v0.7.29** 起可用(前端组件注入 / 插件设置 / 插件 i18n /
9
- > 运行时服务面);本文档对应当前版本 **v0.8.3**。`ctx.sdkVersion` 当前为 `0.3.0`。
9
+ > 运行时服务面);本文档对应当前版本 **v0.8.4**。`ctx.sdkVersion` 当前为 `0.3.0`。
10
10
 
11
11
  ## 一、目录结构与快速开始
12
12
 
package/docs/sdk.en.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  **SDK version constants**: server-side `SDK_VERSION = '0.3.0'`, browser-side `CLIENT_SDK_VERSION = '0.3.0'`.
9
9
  These two constants are the **interface version of the SDK itself** and evolve **independently**
10
- from the npm package version (the `version` field in `package.json`, currently 0.8.3) —
10
+ from the npm package version (the `version` field in `package.json`, currently 0.8.4) —
11
11
  them being out of sync is expected. Never use `SDK_VERSION` to infer the package version, or the reverse.
12
12
  **Module format**: ESM only (only `import` / `export`; there is no CJS entry).
13
13
  **Types**: `sdk/index.d.mts` and `sdk/client.d.mts` ship with the package, so TypeScript projects
package/docs/sdk.md CHANGED
@@ -5,7 +5,7 @@
5
5
  > 零第三方运行时依赖,Node ≥ 23.4 与现代浏览器双端可用。
6
6
 
7
7
  **SDK 版本常量**:服务端 `SDK_VERSION = '0.3.0'`,浏览器端 `CLIENT_SDK_VERSION = '0.3.0'`。
8
- 这两个常量是 **SDK 自身接口的版本号**,与 npm 包版本(`package.json` 的 `version`,当前 0.8.3)
8
+ 这两个常量是 **SDK 自身接口的版本号**,与 npm 包版本(`package.json` 的 `version`,当前 0.8.4)
9
9
  **各自独立演进** —— 常数不同步是预期行为,不要拿 `SDK_VERSION` 去推断包版本,反之亦然。
10
10
  **模块形态**:ESM only(只有 `import` / `export`,没有 CJS 入口)。
11
11
  **类型**:`sdk/index.d.mts`、`sdk/client.d.mts` 随包发布,TS 项目零配置获得提示(覆盖范围见 §7)。
@@ -1744,6 +1744,7 @@ export default {
1744
1744
  graph: {
1745
1745
  viewGraph: 'Graph',
1746
1746
  viewTable: 'Table',
1747
+ baseline: 'baseline',
1747
1748
  hint: 'Click a node for details and neighbours; dashed = candidate influence, solid = observed / validated',
1748
1749
  searchEntity: 'Search entity key or name',
1749
1750
  largeGraph: '{n} entities — focus mode: search one entity to inspect its neighbourhood',
@@ -3279,6 +3280,51 @@ export default {
3279
3280
  promptTitle: 'Agent deep-analysis prompt (paste into a Channel)',
3280
3281
  copy: 'Copy',
3281
3282
  copied: 'Copied to clipboard',
3283
+ pipeline: {
3284
+ title: 'EDA Analysis Pipeline',
3285
+ sub: 'Fetch data → custom post-processing → chart config (save as template) → draw / export / online viewer',
3286
+ backToStudio: 'Back to Studio',
3287
+ s1: 'Fetch data',
3288
+ pickLine: 'Pick a line…',
3289
+ w15: 'Last 15 min',
3290
+ w60: 'Last 1 h',
3291
+ w240: 'Last 4 h',
3292
+ fetch: 'Fetch data',
3293
+ importPlaceholder: 'Paste CSV/TSV (header row):\nbatch,weight\nB1,32.5\nB2,32.7',
3294
+ importBtn: 'Import table',
3295
+ fetching: 'Fetching…',
3296
+ s2: 'Data table & post-processing (code your own aggregation/filter)',
3297
+ noRows: 'No data yet. Pick a line and nodes, then press Fetch.',
3298
+ rowsInfo: '{n} rows, previewing first {show}:',
3299
+ codePlaceholder: 'Define transform(rows) to filter/aggregate/derive columns and return the new row array (runs locally in your browser).',
3300
+ applyTransform: 'Apply transform',
3301
+ resetTransform: 'Reset to raw',
3302
+ transformedTo: 'Transformed: {n} rows.',
3303
+ s3: 'Chart config',
3304
+ chartType: 'Type',
3305
+ valueField: 'Value field',
3306
+ groupBy: 'Group by',
3307
+ agg: 'Agg',
3308
+ refLine: 'Ref line',
3309
+ chartTitle: 'Chart title',
3310
+ s4: 'Config templates (persisted; one-click re-plot on new data)',
3311
+ templateName: 'Template name…',
3312
+ templateSave: 'Save as template',
3313
+ templateSaved: 'Template saved.',
3314
+ templateApplied: 'Template "{name}" applied.',
3315
+ s5: 'Draw & output',
3316
+ draw: 'Draw',
3317
+ openViewer: 'Online viewer',
3318
+ download: 'Download PNG',
3319
+ saveChart: 'Save as chart',
3320
+ saveResult: 'Save as analysis result',
3321
+ savedChart: 'Chart saved (visible in Studio/Board).',
3322
+ savedResult: 'Analysis result saved (visible in ledger).',
3323
+ resultTitle: 'EDA pipeline analysis result',
3324
+ resultSummary: 'Pipeline analysis over {n} rows × {cols} numeric columns.',
3325
+ resultReport: 'Chart type {type}, {rows} rows; see metrics & context.',
3326
+ viewerHint: 'Scroll to zoom / toolbox top-right to save image',
3327
+ },
3282
3328
  },
3283
3329
  board: {
3284
3330
  title: 'EDA Board',
@@ -1744,6 +1744,7 @@ export default {
1744
1744
  graph: {
1745
1745
  viewGraph: '图',
1746
1746
  viewTable: '表',
1747
+ baseline: '基线',
1747
1748
  hint: '点击节点查看详情与邻接;虚线=候选影响,实线=已观测/已验证',
1748
1749
  searchEntity: '搜索实体 key 或名称',
1749
1750
  largeGraph: '实体较多({n} 个),已切换为聚焦模式:先搜索一个实体再看邻接',
@@ -3278,6 +3279,51 @@ export default {
3278
3279
  promptTitle: 'Agent 深度分析提示词(复制到 Channel 即可发起)',
3279
3280
  copy: '复制',
3280
3281
  copied: '已复制到剪贴板',
3282
+ pipeline: {
3283
+ title: 'EDA 分析管道',
3284
+ sub: '拉取数据 → 自定义后处理 → 图表配置(可存模板) → 绘图/导出/在线查看',
3285
+ backToStudio: '返回工坊',
3286
+ s1: '拉取数据',
3287
+ pickLine: '选择产线…',
3288
+ w15: '近 15 分钟',
3289
+ w60: '近 1 小时',
3290
+ w240: '近 4 小时',
3291
+ fetch: '拉取数据',
3292
+ importPlaceholder: '粘贴 CSV/TSV(首行表头):\n批次,克重\nB1,32.5\nB2,32.7',
3293
+ importBtn: '导入数据表',
3294
+ fetching: '拉取中…',
3295
+ s2: '数据表与后处理(可写代码聚合/筛选)',
3296
+ noRows: '尚未拉取数据。选择产线与测点后点「拉取数据」。',
3297
+ rowsInfo: '共 {n} 行,预览前 {show} 行:',
3298
+ codePlaceholder: '定义 transform(rows) 函数,做过滤/聚合/派生列,返回新行数组(在浏览器本地执行)。',
3299
+ applyTransform: '应用后处理',
3300
+ resetTransform: '还原原始数据',
3301
+ transformedTo: '后处理完成:{n} 行。',
3302
+ s3: '图表配置',
3303
+ chartType: '图型',
3304
+ valueField: '值字段',
3305
+ groupBy: '分组',
3306
+ agg: '聚合',
3307
+ refLine: '参考线',
3308
+ chartTitle: '图表标题',
3309
+ s4: '配置模板(持久化,换数据一键复绘)',
3310
+ templateName: '模板名…',
3311
+ templateSave: '保存为模板',
3312
+ templateSaved: '模板已保存。',
3313
+ templateApplied: '已应用模板「{name}」。',
3314
+ s5: '绘图与输出',
3315
+ draw: '开始绘图',
3316
+ openViewer: '在线查看',
3317
+ download: '下载 PNG',
3318
+ saveChart: '保存为图表',
3319
+ saveResult: '保存为分析结果',
3320
+ savedChart: '图表已保存(工坊/看板可见)。',
3321
+ savedResult: '分析结果已保存(台账可见)。',
3322
+ resultTitle: 'EDA 管道分析结果',
3323
+ resultSummary: '基于 {n} 行 × {cols} 个数值列的管道分析。',
3324
+ resultReport: '图型 {type},数据 {rows} 行;详见 metrics 与 context。',
3325
+ viewerHint: '滚轮缩放 / 工具箱右上角可存图',
3326
+ },
3281
3327
  },
3282
3328
  board: {
3283
3329
  title: 'EDA 看板',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentworkshop",
3
- "version": "0.8.3",
3
+ "version": "0.8.4",
4
4
  "type": "module",
5
5
  "description": "AgentWorkShop 软件开发系统 - 基于 Nuxt 4 的配置驱动运行范式",
6
6
  "license": "Apache-2.0",
@@ -292,7 +292,7 @@ section('[5/6] VitePress 模板安全:正文裸尖括号不得被当成未闭合
292
292
  // 占位符,Vue 会把它当成自定义元素并因缺少 </home> 直接**构建失败**
293
293
  // (实际发生过:plugins/guide.md 曾导致 `vitepress build` 报 Element is missing end tag)。
294
294
  // 行内代码/围栏代码里的尖括号会被 markdown-it 转义,是安全的 —— 先剥掉再扫。
295
- const SAFE_TAGS = new Set(['div', 'img', 'br', 'b', 'i', 'strong', 'em', 'a', 'span', 'code', 'pre', 'table', 'thead', 'tbody', 'tr', 'th', 'td', 'sub', 'sup', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'kbd', 'details', 'summary', 'picture', 'source', 'video', 'hr', 'small', 'figure', 'figcaption', 'section', 'input'])
295
+ const SAFE_TAGS = new Set(['div', 'img', 'br', 'b', 'i', 'strong', 'em', 'a', 'span', 'code', 'pre', 'table', 'thead', 'tbody', 'tr', 'th', 'td', 'sub', 'sup', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'kbd', 'details', 'summary', 'picture', 'source', 'video', 'audio', 'track', 'hr', 'small', 'figure', 'figcaption', 'section', 'input', 'blockquote', 'del', 'ins', 'mark'])
296
296
  const stripCode = md => md
297
297
  .replace(/^```[\s\S]*?^```/gm, '')
298
298
  .replace(/<!--[\s\S]*?-->/g, '')