create-windy 0.9.1 → 0.10.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.
Files changed (253) hide show
  1. package/dist/cli.js +1769 -1277
  2. package/package.json +2 -2
  3. package/template/.agents/skills/windy-business-module/SKILL.md +33 -1
  4. package/template/.windy-template.json +6 -2
  5. package/template/AGENTS.md +4 -0
  6. package/template/README.md +2 -0
  7. package/template/apps/agent-server/Dockerfile +1 -1
  8. package/template/apps/agent-server/README.md +1 -1
  9. package/template/apps/agent-server/native/EXTENSIONS.md +2 -2
  10. package/template/apps/agent-server/native/parallel-harness.ts +2 -0
  11. package/template/apps/agent-server/native/storage-lifecycle.test.ts +2 -1
  12. package/template/apps/agent-server/package.json +42 -41
  13. package/template/apps/agent-server/plugins/downloads/README.md +1 -1
  14. package/template/apps/agent-server/plugins/drop-overlay/README.md +1 -1
  15. package/template/apps/agent-server/plugins/settings/README.md +1 -1
  16. package/template/apps/agent-server/plugins/skill-library/client-chunks.test.ts +4 -1
  17. package/template/apps/agent-server/plugins/theme/README.md +5 -1
  18. package/template/apps/agent-server/plugins/theme/source-tokens.ts +0 -1
  19. package/template/apps/agent-server/plugins/theme/tokens.json +0 -4
  20. package/template/apps/agent-server/plugins/tool-catalog/README.md +6 -3
  21. package/template/apps/agent-server/plugins/tool-catalog/discovery.mjs +13 -10
  22. package/template/apps/agent-server/plugins/tool-catalog/discovery.test.ts +68 -6
  23. package/template/apps/agent-server/runtime/compatibility.ts +7 -1
  24. package/template/apps/agent-server/runtime/dsh-engine.ts +2 -0
  25. package/template/apps/agent-server/runtime/questions-workflow.nodecheck.ts +2 -0
  26. package/template/apps/server/Dockerfile +2 -1
  27. package/template/apps/server/package.json +11 -11
  28. package/template/apps/server/scripts/validate-module-composition-once.ts +2 -0
  29. package/template/apps/server/scripts/validate-module-composition.ts +8 -4
  30. package/template/apps/server/src/admin/routes.test.ts +29 -1
  31. package/template/apps/server/src/admin/routes.ts +20 -2
  32. package/template/apps/server/src/agent/client-session/completion.ts +1 -1
  33. package/template/apps/server/src/agent/client-session/manifest-admission.ts +1 -1
  34. package/template/apps/server/src/agent/client-session/request.ts +1 -1
  35. package/template/apps/server/src/agent/context-version-routes.ts +37 -13
  36. package/template/apps/server/src/agent/run-facade.ts +1 -1
  37. package/template/apps/server/src/agent/run-input-verification.ts +1 -1
  38. package/template/apps/server/src/agent/run-routes.ts +1 -14
  39. package/template/apps/server/src/agent/run-start-preparation.ts +1 -1
  40. package/template/apps/server/src/agent/runtime-bootstrap-input.ts +2 -0
  41. package/template/apps/server/src/agent/runtime-bootstrap.ts +49 -157
  42. package/template/apps/server/src/agent/runtime-disabled-composition.ts +2 -1
  43. package/template/apps/server/src/agent/session-invalidation/authorization-revocation.ts +54 -0
  44. package/template/apps/server/src/agent/session-runtime-composition.ts +1 -51
  45. package/template/apps/server/src/agent/unavailable-routes.ts +13 -2
  46. package/template/apps/server/src/agent-workflow/runtime-composition.ts +3 -0
  47. package/template/apps/server/src/agent-workflow/service.ts +17 -1
  48. package/template/apps/server/src/ai-artifact/media-resource-route.test.ts +134 -0
  49. package/template/apps/server/src/ai-artifact/routes.ts +1 -1
  50. package/template/apps/server/src/ai-artifact/runtime.ts +12 -0
  51. package/template/apps/server/src/ai-runtime-readiness/operation-port.test-support.ts +1 -1
  52. package/template/apps/server/src/ai-runtime-readiness/operation-port.ts +8 -0
  53. package/template/apps/server/src/ai-runtime-security/internal-token.ts +14 -0
  54. package/template/apps/server/src/app/antivirus-composition.test.ts +63 -0
  55. package/template/apps/server/src/app/antivirus-composition.ts +29 -0
  56. package/template/apps/server/src/app/dsh-workbench-socket-audit.test.ts +2 -1
  57. package/template/apps/server/src/configuration/definition.ts +15 -11
  58. package/template/apps/server/src/document/facade-support.ts +2 -2
  59. package/template/apps/server/src/document/facade.ts +2 -2
  60. package/template/apps/server/src/document/output-artifact-composition.ts +9 -5
  61. package/template/apps/server/src/document/output-artifact.test-support.ts +1 -1
  62. package/template/apps/server/src/embedding/facade.ts +1 -1
  63. package/template/apps/server/src/embedding/input.ts +1 -1
  64. package/template/apps/server/src/embedding/routes.ts +1 -1
  65. package/template/apps/server/src/index.ts +60 -60
  66. package/template/apps/server/src/license/routes.ts +4 -1
  67. package/template/apps/server/src/license/runtime-business-access.test.ts +261 -0
  68. package/template/apps/server/src/media-runtime/composition.ts +157 -0
  69. package/template/apps/server/src/media-runtime/media-only-composition.ts +44 -0
  70. package/template/apps/server/src/media-runtime/module-ai-port-factory.test.ts +69 -0
  71. package/template/apps/server/src/media-runtime/module-ai-port-factory.ts +72 -0
  72. package/template/apps/server/src/{agent → media-runtime}/runtime-readiness-sources.ts +14 -6
  73. package/template/apps/server/src/media-runtime/shared-composition.ts +104 -0
  74. package/template/apps/server/src/module-composition.test.ts +22 -0
  75. package/template/apps/server/src/module-composition.ts +48 -0
  76. package/template/apps/server/src/module-host/ai-operation-port.ts +97 -30
  77. package/template/apps/server/src/module-host/ai-operation-speech-normalize.test.ts +1 -1
  78. package/template/apps/server/src/module-host/http-runtime.ts +9 -3
  79. package/template/apps/server/src/module-host/static-route-authorization.test.ts +6 -3
  80. package/template/apps/server/src/module-host/storage-authorization-binding.test.ts +4 -0
  81. package/template/apps/server/src/module-runtime-validation.ts +2 -0
  82. package/template/apps/server/src/observability/diagnostic-index.ts +26 -1
  83. package/template/apps/server/src/observability/diagnostic-repository.ts +40 -11
  84. package/template/apps/server/src/platform-http-runtime.ts +1 -1
  85. package/template/apps/server/src/runtime-feature.ts +5 -1
  86. package/template/apps/server/src/runtime.ts +3 -0
  87. package/template/apps/server/src/settings/drizzle-watermark-repository.ts +35 -4
  88. package/template/apps/server/src/settings/watermark-repository.ts +14 -0
  89. package/template/apps/server/src/settings/watermark-routes.test.ts +84 -2
  90. package/template/apps/server/src/settings/watermark-routes.ts +109 -0
  91. package/template/apps/server/src/settings/watermark-transfer.ts +79 -0
  92. package/template/apps/server/src/speech/facade-validation.ts +1 -1
  93. package/template/apps/server/src/speech/facade.ts +2 -2
  94. package/template/apps/server/src/startup-composition-validation.test.ts +32 -0
  95. package/template/apps/server/src/startup-finalization.ts +2 -0
  96. package/template/apps/server/src/startup-runtime.ts +77 -0
  97. package/template/apps/server/src/system/ai-runtime-build.ts +3 -0
  98. package/template/apps/server/src/system/ai-runtime-configuration.test.ts +36 -0
  99. package/template/apps/server/src/system/ai-runtime-configuration.ts +58 -0
  100. package/template/apps/server/src/system/diagnostic-routes.test.ts +45 -0
  101. package/template/apps/server/src/system/diagnostic-routes.ts +35 -0
  102. package/template/apps/server/src/system/environment-policy-reader.test.ts +74 -0
  103. package/template/apps/server/src/system/environment-policy-reader.ts +62 -0
  104. package/template/apps/server/src/system/feature-environment-assessment.test.ts +148 -0
  105. package/template/apps/server/src/system/feature-environment-assessment.ts +179 -0
  106. package/template/apps/server/src/system/host-diagnostics.test.ts +155 -0
  107. package/template/apps/server/src/system/host-diagnostics.ts +225 -0
  108. package/template/apps/server/src/system/menu-registry.test.ts +26 -0
  109. package/template/apps/server/src/system/menu-registry.ts +9 -7
  110. package/template/apps/server/src/system/operations.test.ts +5 -0
  111. package/template/apps/server/src/system/operations.ts +36 -12
  112. package/template/apps/server/src/system/role-authorization-postgres.integration.test.ts +181 -0
  113. package/template/apps/web/Dockerfile +7 -3
  114. package/template/apps/web/dev/dev-port.test.ts +6 -6
  115. package/template/apps/web/dev/dev-port.ts +1 -1
  116. package/template/apps/web/dev/start.ts +6 -1
  117. package/template/apps/web/index.html +1 -0
  118. package/template/apps/web/package.json +16 -16
  119. package/template/apps/web/runtime-server.test.ts +22 -1
  120. package/template/apps/web/runtime-server.ts +6 -0
  121. package/template/apps/web/src/App.vue +6 -3
  122. package/template/apps/web/src/assets/windy.svg +4 -0
  123. package/template/apps/web/src/components/auth/LoginForm.vue +2 -2
  124. package/template/apps/web/src/components/auth/PasswordChangeForm.vue +14 -3
  125. package/template/apps/web/src/components/common/FormDialog.vue +1 -1
  126. package/template/apps/web/src/components/license/LicenseFlow.webtest.ts +3 -0
  127. package/template/apps/web/src/components/license/LicenseMachineCodeQr.vue +99 -0
  128. package/template/apps/web/src/components/license/LicenseMachineCodeQr.webtest.ts +83 -0
  129. package/template/apps/web/src/components/license/LicensePairingCard.vue +1 -1
  130. package/template/apps/web/src/components/license/LicenseStatusCard.vue +14 -2
  131. package/template/apps/web/src/composables/useLoginFlow.ts +2 -2
  132. package/template/apps/web/src/composables/usePlatformSettings.ts +1 -1
  133. package/template/apps/web/src/composables/useWatermarkSettings.ts +1 -0
  134. package/template/apps/web/src/layout/AppSidebar.vue +5 -9
  135. package/template/apps/web/src/layout/AppSidebar.webtest.ts +4 -1
  136. package/template/apps/web/src/pages/auth/ChangePasswordPage.vue +67 -6
  137. package/template/apps/web/src/pages/auth/LoginPage.vue +3 -12
  138. package/template/apps/web/src/pages/configuration/components/ModuleConfigurationEditor.vue +30 -0
  139. package/template/apps/web/src/pages/configuration/components/ModuleConfigurationWorkbench.vue +25 -14
  140. package/template/apps/web/src/pages/configuration/components/TimeZoneSelect.vue +55 -0
  141. package/template/apps/web/src/pages/profile/PersonalSettingsPage.vue +64 -11
  142. package/template/apps/web/src/pages/profile/PersonalSettingsPage.webtest.ts +21 -1
  143. package/template/apps/web/src/pages/settings/BrandingSettingsSection.vue +7 -18
  144. package/template/apps/web/src/pages/settings/BrandingSettingsSection.webtest.ts +9 -4
  145. package/template/apps/web/src/pages/settings/GlobalSettingsPage.vue +51 -6
  146. package/template/apps/web/src/pages/settings/GlobalSettingsPage.webtest.ts +19 -3
  147. package/template/apps/web/src/pages/settings/WatermarkSettingsSection.vue +1 -0
  148. package/template/apps/web/src/pages/settings/WatermarkYamlTransfer.vue +211 -0
  149. package/template/apps/web/src/pages/system/DiagnosticLookupPage.vue +18 -3
  150. package/template/apps/web/src/pages/system/DiagnosticLookupPage.webtest.ts +4 -1
  151. package/template/apps/web/src/pages/system/SystemOperationsPage.vue +23 -0
  152. package/template/apps/web/src/pages/system/components/DiagnosticLogList.vue +120 -0
  153. package/template/apps/web/src/pages/system/components/OperationEnvironmentPanel.vue +237 -0
  154. package/template/apps/web/src/pages/system/components/OperationFeatureAssessmentPanel.vue +131 -0
  155. package/template/apps/web/src/pages/system/components/PagedSelectionList.vue +31 -24
  156. package/template/apps/web/src/pages/system/components/SystemResourceActions.vue +2 -1
  157. package/template/apps/web/src/pages/system/components/SystemResourceEditor.vue +11 -2
  158. package/template/apps/web/src/pages/system/components/SystemResourcePage.vue +1 -0
  159. package/template/apps/web/src/pages/system/components/SystemResourcePage.webtest.ts +6 -2
  160. package/template/apps/web/src/pages/system/components/agent-skills/AgentSkillImportDialog.vue +18 -9
  161. package/template/apps/web/src/pages/system/components/agent-workbench/SessionReplayTimeline.vue +18 -9
  162. package/template/apps/web/src/pages/system/components/agent-workbench/TestRunComposer.vue +66 -34
  163. package/template/apps/web/src/pages/system/components/agent-workbench/ToolCatalogPanel.vue +48 -33
  164. package/template/apps/web/src/pages/system/components/agent-workbench/ToolCatalogPanel.webtest.ts +9 -2
  165. package/template/apps/web/src/pages/system/components/agent-workbench/ToolRuleDetail.vue +23 -16
  166. package/template/apps/web/src/pages/system/components/dictionary-bulk/DictionaryBulkJobDetail.vue +10 -7
  167. package/template/apps/web/src/pages/system/components/user-account/RolePermissionSummary.vue +81 -57
  168. package/template/apps/web/src/pages/system/components/user-account/UserRoleSelector.vue +6 -4
  169. package/template/apps/web/src/pages/system/components/user-account/UserRoleSelector.webtest.ts +20 -4
  170. package/template/apps/web/src/pages/system/resource-config.ts +9 -0
  171. package/template/apps/web/src/pages/work-orders/WorkOrderListPage.vue +1 -1
  172. package/template/apps/web/src/router/disabled-feature-loading.webtest.ts +78 -0
  173. package/template/apps/web/src/router/index.ts +3 -6
  174. package/template/apps/web/src/router/manifest-routes.ts +2 -3
  175. package/template/apps/web/src/router/platform-admin-pages.ts +21 -62
  176. package/template/apps/web/src/router/platform-admin-route-bindings.ts +4 -4
  177. package/template/apps/web/src/services/diagnostics-api.ts +13 -1
  178. package/template/apps/web/src/services/operations-api.ts +4 -0
  179. package/template/apps/web/src/services/platform-settings-api.ts +35 -1
  180. package/template/apps/web/vite.config.ts +9 -3
  181. package/template/deploy/environment/windy.environment.example.yaml +53 -0
  182. package/template/docker-compose.yml +4 -2
  183. package/template/docs/architecture/agent-admin-workbench-implementation.md +1 -1
  184. package/template/docs/architecture/agent-admin-workbench-plan.md +1 -1
  185. package/template/docs/architecture/agent-workflow.md +8 -0
  186. package/template/docs/architecture/durable-jobs.md +17 -0
  187. package/template/docs/architecture/embedded-dsh-integration.md +1 -1
  188. package/template/docs/development/dsh-plugins.md +1 -1
  189. package/template/docs/development/performance-engineering.md +24 -0
  190. package/template/docs/operations/admin-settings-yaml.md +29 -0
  191. package/template/docs/operations/dsh-agent-migration.md +2 -2
  192. package/template/docs/operations/environment-capabilities.md +185 -0
  193. package/template/docs/platform/module-configuration.md +18 -3
  194. package/template/docs/platform/platform-authentication.md +1 -1
  195. package/template/package.json +10 -8
  196. package/template/packages/config/package.json +2 -2
  197. package/template/packages/config/src/definition.ts +14 -4
  198. package/template/packages/config/src/environment-loader.ts +27 -3
  199. package/template/packages/config/src/platform-ai-runtime.test.ts +94 -0
  200. package/template/packages/config/src/platform.ts +5 -2
  201. package/template/packages/database/drizzle/0065_durable_job_lease_snapshot_lookup.sql +1 -0
  202. package/template/packages/database/drizzle/0066_agent_source_sequence_bigint.sql +3 -0
  203. package/template/packages/database/drizzle/0067_media_runtime_access.sql +46 -0
  204. package/template/packages/database/drizzle/meta/0065_snapshot.json +15370 -0
  205. package/template/packages/database/drizzle/meta/0066_snapshot.json +15370 -0
  206. package/template/packages/database/drizzle/meta/0067_snapshot.json +15370 -0
  207. package/template/packages/database/drizzle/meta/_journal.json +21 -0
  208. package/template/packages/database/package.json +3 -3
  209. package/template/packages/database/src/schema/agent-session.ts +4 -3
  210. package/template/packages/database/src/schema/durable-jobs.ts +4 -0
  211. package/template/packages/database/src/schema/index.ts +3 -1
  212. package/template/packages/database/src/schema-durable-recovery.test.ts +21 -1
  213. package/template/packages/database/src/schema-source-sequence.test.ts +24 -0
  214. package/template/packages/example-work-order/package.json +2 -2
  215. package/template/packages/modules/package.json +1 -1
  216. package/template/packages/modules/src/admin-ui-boundary.test.ts +33 -0
  217. package/template/packages/modules/src/composition.ts +11 -28
  218. package/template/packages/modules/src/manifest.ts +2 -0
  219. package/template/packages/modules/src/menu-composition.ts +24 -0
  220. package/template/packages/modules/src/system-admin-routes.ts +2 -2
  221. package/template/packages/modules/src/system-admin-ui-catalog.ts +6 -1
  222. package/template/packages/modules/src/system-ai-api-bindings.ts +0 -16
  223. package/template/packages/modules/src/system-api-control-plane.ts +9 -1
  224. package/template/packages/modules/src/system-api-permissions.ts +7 -0
  225. package/template/packages/modules/src/system-api-watermark.ts +21 -0
  226. package/template/packages/modules/src/system-audit-actions.ts +3 -1
  227. package/template/packages/modules/src/system-features.ts +21 -3
  228. package/template/packages/modules/src/system-media-api-bindings.ts +97 -0
  229. package/template/packages/modules/src/system-module-audit-selection.ts +2 -0
  230. package/template/packages/modules/src/system-module-catalog.test.ts +13 -6
  231. package/template/packages/modules/src/system-module-catalog.ts +6 -241
  232. package/template/packages/modules/src/system-module-definitions.ts +260 -0
  233. package/template/packages/modules/src/system-modules-access.test.ts +2 -0
  234. package/template/packages/modules/src/system-modules.test.ts +7 -1
  235. package/template/packages/modules/src/system-modules.ts +25 -13
  236. package/template/packages/modules/src/system-permissions.ts +12 -0
  237. package/template/packages/server-sdk/package.json +1 -1
  238. package/template/packages/shared/index.ts +3 -0
  239. package/template/packages/shared/package.json +1 -1
  240. package/template/packages/shared/src/environment-assessment.ts +68 -0
  241. package/template/packages/shared/src/environment-policy.ts +205 -0
  242. package/template/packages/shared/src/license-console-capabilities.ts +7 -0
  243. package/template/packages/shared/src/license.ts +1 -0
  244. package/template/packages/shared/src/module-configuration.ts +2 -1
  245. package/template/scripts/operations/collect-device-info.py +230 -0
  246. package/template/apps/server/src/agent/module-ai-port-factory.ts +0 -41
  247. /package/template/apps/server/src/{agent → ai-runtime-security}/execution-grants.ts +0 -0
  248. /package/template/apps/server/src/{agent → ai-runtime-security}/idempotency-key.test.ts +0 -0
  249. /package/template/apps/server/src/{agent → ai-runtime-security}/idempotency-key.ts +0 -0
  250. /package/template/apps/server/src/{agent → ai-runtime-security}/provider-input-governance.test.ts +0 -0
  251. /package/template/apps/server/src/{agent → ai-runtime-security}/provider-input-governance.ts +0 -0
  252. /package/template/apps/server/src/{agent → media-runtime}/required-environment.ts +0 -0
  253. /package/template/apps/server/src/{agent → media-runtime}/runtime-readiness-sources.test.ts +0 -0
@@ -65,9 +65,9 @@ const options = computed(() =>
65
65
  description: `${role.code} · ${dataScopeLabel(role.dataScope)}`,
66
66
  })),
67
67
  );
68
- function rolePermissions(id: string): string[] {
69
- return roles.value.find((role) => role.id === id)?.permissionKeys || [];
70
- }
68
+ const rolesById = computed(
69
+ () => new Map(roles.value.map((role) => [role.id, role])),
70
+ );
71
71
 
72
72
  function dataScopeLabel(scope: string): string {
73
73
  return (
@@ -95,11 +95,13 @@ defineExpose({ reload: loadRoles });
95
95
  :model-value="modelValue"
96
96
  label="账号角色"
97
97
  multiple
98
+ grid
98
99
  @update:model-value="emit('update:modelValue', $event)"
99
100
  >
100
101
  <template #detail="{ id }">
101
102
  <RolePermissionSummary
102
- :permission-keys="rolePermissions(id)"
103
+ :role-name="rolesById.get(id)?.name ?? id"
104
+ :permission-keys="rolesById.get(id)?.permissionKeys ?? []"
103
105
  :permissions="permissions"
104
106
  />
105
107
  </template>
@@ -1,5 +1,10 @@
1
1
  import { afterEach, describe, expect, test, vi } from "vitest";
2
- import { flushPromises, mount } from "@vue/test-utils";
2
+ import {
3
+ DOMWrapper,
4
+ enableAutoUnmount,
5
+ flushPromises,
6
+ mount,
7
+ } from "@vue/test-utils";
3
8
  import UserRoleSelector from "./UserRoleSelector.vue";
4
9
 
5
10
  const api = vi.hoisted(() => ({ list: vi.fn() }));
@@ -11,6 +16,7 @@ vi.mock("@/services/system-api", async () => {
11
16
  return { ...actual, listSystemResource: api.list };
12
17
  });
13
18
 
19
+ enableAutoUnmount(afterEach);
14
20
  afterEach(() => vi.clearAllMocks());
15
21
 
16
22
  describe("UserRoleSelector", () => {
@@ -30,6 +36,7 @@ describe("UserRoleSelector", () => {
30
36
  pageSize: 10,
31
37
  });
32
38
  const wrapper = mount(UserRoleSelector, {
39
+ attachTo: document.body,
33
40
  props: {
34
41
  modelValue: [],
35
42
  permissions: [
@@ -63,9 +70,18 @@ describe("UserRoleSelector", () => {
63
70
  expect(wrapper.text()).toContain("部门负责人");
64
71
  expect(wrapper.text()).toContain("本部门及下级");
65
72
  expect(wrapper.text()).toContain("查看 2 项功能权限");
66
- await wrapper.get("summary").trigger("click");
67
- expect(wrapper.text()).toContain("用户账号");
68
- expect(wrapper.text()).toContain("管理用户、查看用户");
73
+ expect(wrapper.find('[role="dialog"]').exists()).toBe(false);
74
+ await wrapper
75
+ .get('[data-testid="role-permissions-trigger"]')
76
+ .trigger("click");
77
+ await flushPromises();
78
+ const drawer = new DOMWrapper(document.body).get('[role="dialog"]');
79
+ expect(drawer.text()).toContain("角色功能权限");
80
+ expect(drawer.text()).toContain("用户账号");
81
+ expect(drawer.text()).toContain("管理用户、查看用户");
82
+ await drawer.get('[data-slot="sheet-close"]').trigger("click");
83
+ await flushPromises();
84
+ expect(document.body.querySelector('[role="dialog"]')).toBeNull();
69
85
  await wrapper.get('input[type="checkbox"]').setValue(true);
70
86
  expect(wrapper.emitted("update:modelValue")?.at(-1)).toEqual([
71
87
  ["role_manager"],
@@ -38,6 +38,7 @@ export interface ResourceInlineToggle {
38
38
  export interface SystemResourceConfig {
39
39
  key: SystemResourceKey;
40
40
  apiResource: string;
41
+ entityLabel?: string;
41
42
  title: string;
42
43
  description: string;
43
44
  searchPlaceholder: string;
@@ -65,6 +66,7 @@ export const systemResourceConfigs: Record<
65
66
  > = {
66
67
  users: {
67
68
  key: "users",
69
+ entityLabel: "人员",
68
70
  apiResource: "users",
69
71
  title: "用户体系",
70
72
  description: "维护平台账号、展示名称、联系方式、角色和部门归属。",
@@ -88,6 +90,7 @@ export const systemResourceConfigs: Record<
88
90
  },
89
91
  roles: {
90
92
  key: "roles",
93
+ entityLabel: "角色",
91
94
  apiResource: "roles",
92
95
  title: "权限策略",
93
96
  description: "维护角色编码、数据权限和权限点集合。",
@@ -116,6 +119,7 @@ export const systemResourceConfigs: Record<
116
119
  },
117
120
  departments: {
118
121
  key: "departments",
122
+ entityLabel: "组织",
119
123
  apiResource: "departments",
120
124
  title: "部门组织",
121
125
  description:
@@ -137,6 +141,7 @@ export const systemResourceConfigs: Record<
137
141
  },
138
142
  menus: {
139
143
  key: "menus",
144
+ entityLabel: "菜单",
140
145
  apiResource: "menus",
141
146
  title: "菜单管理",
142
147
  description: "维护菜单标题、路径、权限点、功能开关联动和显示状态。",
@@ -157,6 +162,7 @@ export const systemResourceConfigs: Record<
157
162
  },
158
163
  dictionaries: {
159
164
  key: "dictionaries",
165
+ entityLabel: "字典",
160
166
  apiResource: "dictionaries",
161
167
  title: "字典管理",
162
168
  description: "维护平台枚举字典和字典项。",
@@ -178,6 +184,7 @@ export const systemResourceConfigs: Record<
178
184
  },
179
185
  features: {
180
186
  key: "features",
187
+ entityLabel: "功能开关",
181
188
  apiResource: "features",
182
189
  title: "功能开关",
183
190
  description:
@@ -203,6 +210,7 @@ export const systemResourceConfigs: Record<
203
210
  },
204
211
  licenses: {
205
212
  key: "licenses",
213
+ entityLabel: "License",
206
214
  apiResource: "licenses",
207
215
  title: "License",
208
216
  description: "查看和维护客户授权主体、机器码、公钥和过期时间。",
@@ -225,6 +233,7 @@ export const systemResourceConfigs: Record<
225
233
  // @windy-module system.audit begin
226
234
  auditLogs: {
227
235
  key: "auditLogs",
236
+ entityLabel: "审计日志",
228
237
  apiResource: "audit-logs",
229
238
  title: "审计日志",
230
239
  description: "查看 Guard、功能开关、CRUD 和业务操作产生的审计事件。",
@@ -96,7 +96,7 @@ const workflowLabels: Record<WorkOrderWorkflowStatus, string> = {
96
96
  <header class="space-y-2">
97
97
  <h1 class="text-2xl font-semibold text-foreground">工单管理</h1>
98
98
  <p class="text-sm text-muted-foreground">
99
- 示例业务模块提供的工单列表,入口、权限和功能开关均来自 Module Manifest。
99
+ 按部门和负责人跟踪待处理事项及处理进度。
100
100
  </p>
101
101
  </header>
102
102
 
@@ -0,0 +1,78 @@
1
+ import { expect, test, vi } from "vitest";
2
+ import { createMemoryHistory } from "vue-router";
3
+ import { createAppRouter, routes } from "./index";
4
+ import {
5
+ accessSnapshot,
6
+ authProvider,
7
+ // @windy-module system.license begin
8
+ licenseProvider,
9
+ // @windy-module system.license end
10
+ provider,
11
+ } from "./router-test-fixtures";
12
+
13
+ test.each(["disabled", "unknown", "unauthorized", "enabled"])(
14
+ "%s feature controls lazy admin page resolution",
15
+ async (mode) => {
16
+ const route = routes.find(
17
+ ({ meta }) => meta?.manifestRouteKey === "system.user",
18
+ );
19
+ const { featureKey, permissionKey } = route?.meta ?? {};
20
+ if (
21
+ !route ||
22
+ typeof featureKey !== "string" ||
23
+ typeof permissionKey !== "string"
24
+ ) {
25
+ throw new Error("用户体系管理路由必须声明 Feature 和 Permission");
26
+ }
27
+ const snapshot = accessSnapshot();
28
+ const feature = snapshot.features.find(({ key }) => key === featureKey);
29
+ if (!feature) throw new Error("测试快照缺少用户体系 Feature");
30
+ if (mode === "disabled") {
31
+ feature.enabled = false;
32
+ feature.allowed = false;
33
+ feature.reason = "feature-disabled";
34
+ }
35
+ if (mode === "unknown") {
36
+ snapshot.features = snapshot.features.filter(
37
+ ({ key }) => key !== featureKey,
38
+ );
39
+ }
40
+ if (mode === "unauthorized") {
41
+ snapshot.actor.permissionKeys = snapshot.actor.permissionKeys.filter(
42
+ (key) => key !== permissionKey,
43
+ );
44
+ }
45
+
46
+ const load = vi.fn(async () => ({ template: "<div>Optional</div>" }));
47
+ const router = createAppRouter(
48
+ createMemoryHistory(),
49
+ provider(snapshot),
50
+ // @windy-module system.license begin
51
+ licenseProvider(),
52
+ // @windy-module system.license end
53
+ authProvider(),
54
+ );
55
+ const matched = router.getRoutes().find(({ path }) => path === route.path);
56
+ if (!matched?.components) throw new Error("用户体系路由缺少页面");
57
+ matched.components.default = load;
58
+ await router.push(route.path);
59
+
60
+ expect(load).toHaveBeenCalledTimes(mode === "enabled" ? 1 : 0);
61
+ if (mode === "enabled") {
62
+ expect(router.currentRoute.value.path).toBe(route.path);
63
+ } else {
64
+ expect(router.currentRoute.value.name).toBe("access-denied");
65
+ expect(router.currentRoute.value.query.reason).toBe(
66
+ mode === "unauthorized" ? "missing-permission" : "feature-disabled",
67
+ );
68
+ }
69
+ },
70
+ );
71
+
72
+ test("内置管理页面均使用路由 loader", () => {
73
+ const platformRoutes = routes.filter(({ meta }) => meta?.manifestRouteKey);
74
+ expect(platformRoutes.length).toBeGreaterThan(0);
75
+ for (const route of platformRoutes) {
76
+ expect(typeof route.component).toBe("function");
77
+ }
78
+ });
@@ -7,13 +7,10 @@ import {
7
7
  } from "vue-router";
8
8
  // @windy-module system.audit begin
9
9
  // @windy-module system.audit end
10
- import DashboardPage from "@/pages/dashboard/DashboardPage.vue";
11
- import HomePage from "@/app/home/HomePage.vue";
12
10
  import { loginPageComponent } from "@/app/auth/login-page";
13
11
  import { errorPageComponents } from "@/app/error-pages";
14
12
  import AccessDeniedPage from "@/pages/AccessDeniedPage.vue";
15
13
  import ServiceUnavailablePage from "@/pages/ServiceUnavailablePage.vue";
16
- import ChangePasswordPage from "@/pages/auth/ChangePasswordPage.vue";
17
14
  // @windy-module system.license begin
18
15
  // @windy-module system.license end
19
16
  // @windy-module system.operations begin
@@ -94,19 +91,19 @@ const declaredRoutes: RouteRecordRaw[] = [
94
91
  {
95
92
  path: reservedWebRoutePaths.changePassword,
96
93
  name: "change-password",
97
- component: ChangePasswordPage,
94
+ component: () => import("@/pages/auth/ChangePasswordPage.vue"),
98
95
  meta: { title: "修改密码", layout: "auth" },
99
96
  },
100
97
  {
101
98
  path: reservedWebRoutePaths.home,
102
99
  name: "home",
103
- component: HomePage,
100
+ component: () => import("@/app/home/HomePage.vue"),
104
101
  meta: { title: "首页", layout: "app" },
105
102
  },
106
103
  {
107
104
  path: reservedWebRoutePaths.adminHome,
108
105
  name: "admin-home",
109
- component: DashboardPage,
106
+ component: () => import("@/pages/dashboard/DashboardPage.vue"),
110
107
  meta: { title: "工作台", layout: "admin" },
111
108
  },
112
109
  ...platformAdminRoutes,
@@ -2,8 +2,7 @@ import {
2
2
  systemAdminUiManifests,
3
3
  type ModuleAdminRouteDefinition,
4
4
  } from "@southwind-ai/modules/admin-ui";
5
- import type { Component } from "vue";
6
- import type { RouteRecordRaw } from "vue-router";
5
+ import type { RouteComponent, RouteRecordRaw } from "vue-router";
7
6
 
8
7
  export const webModuleManifests = systemAdminUiManifests();
9
8
 
@@ -14,7 +13,7 @@ const adminRouteByKey = new Map(
14
13
  );
15
14
 
16
15
  export interface ManifestRouteImplementation {
17
- component: Component;
16
+ component: RouteComponent | (() => Promise<{ default: RouteComponent }>);
18
17
  name?: string;
19
18
  props?: RouteRecordRaw["props"];
20
19
  }
@@ -1,79 +1,38 @@
1
- import type { Component } from "vue";
1
+ import type { RouteComponent } from "vue-router";
2
2
  import type { PlatformAdminPageKey } from "./platform-admin-route-bindings";
3
- // @windy-module system.audit begin
4
- import DiagnosticLookupPage from "@/pages/system/DiagnosticLookupPage.vue";
5
- // @windy-module system.audit end
6
- // @windy-module system.license begin
7
- import LicensePage from "@/pages/license/LicensePage.vue";
8
- // @windy-module system.license end
9
- // @windy-module system.operations begin
10
- import SystemOperationsPage from "@/pages/system/SystemOperationsPage.vue";
11
- // @windy-module system.operations end
12
- // @windy-module system.agent begin
13
- import AiRuntimePage from "@/pages/system/AiRuntimePage.vue";
14
- // @windy-module system.agent end
15
- // @windy-module system.agent begin
16
- import SystemAgentSkillsPage from "@/pages/system/SystemAgentSkillsPage.vue";
17
- // @windy-module system.agent end
18
- // @windy-module system.agent begin
19
- import AgentNativePage from "@/pages/system/AgentNativePage.vue";
20
- // @windy-module system.agent end
21
- // @windy-module system.agent begin
22
- import AgentToolsPage from "@/pages/system/AgentToolsPage.vue";
23
- // @windy-module system.agent end
24
- // @windy-module system.agent begin
25
- import AgentDebugPage from "@/pages/system/AgentDebugPage.vue";
26
- // @windy-module system.agent end
27
- // @windy-module system.agent begin
28
- import AgentSessionPage from "@/pages/system/AgentSessionPage.vue";
29
- // @windy-module system.agent end
30
- // @windy-module system.agent begin
31
- import AgentWorkflowPage from "@/pages/system/AgentWorkflowPage.vue";
32
- // @windy-module system.agent end
33
- // @windy-module system.notification begin
34
- import SystemNotificationsPage from "@/pages/system/SystemNotificationsPage.vue";
35
- // @windy-module system.notification end
36
- import SystemResourceRoutePage from "@/pages/system/SystemResourceRoutePage.vue";
37
- // @windy-module system.settings begin
38
- import GlobalSettingsPage from "@/pages/settings/GlobalSettingsPage.vue";
39
- // @windy-module system.settings end
40
- import PersonalSettingsPage from "@/pages/profile/PersonalSettingsPage.vue";
41
- import UiComponentPage from "@/pages/ui/UiComponentPage.vue";
42
- // @windy-module system.configuration begin
43
- import ModuleConfigurationPage from "@/pages/configuration/ModuleConfigurationPage.vue";
44
- // @windy-module system.configuration end
45
3
 
46
4
  export const platformAdminPageComponents: Partial<
47
- Record<PlatformAdminPageKey, Component>
5
+ Record<PlatformAdminPageKey, () => Promise<{ default: RouteComponent }>>
48
6
  > = {
49
- resource: SystemResourceRoutePage,
7
+ resource: () => import("@/pages/system/SystemResourceRoutePage.vue"),
50
8
  // @windy-module system.audit begin
51
- diagnostics: DiagnosticLookupPage,
9
+ diagnostics: () => import("@/pages/system/DiagnosticLookupPage.vue"),
52
10
  // @windy-module system.audit end
53
- profile: PersonalSettingsPage,
54
- "ui-components": UiComponentPage,
11
+ profile: () => import("@/pages/profile/PersonalSettingsPage.vue"),
12
+ "ui-components": () => import("@/pages/ui/UiComponentPage.vue"),
55
13
  // @windy-module system.settings begin
56
- settings: GlobalSettingsPage,
14
+ settings: () => import("@/pages/settings/GlobalSettingsPage.vue"),
57
15
  // @windy-module system.settings end
58
16
  // @windy-module system.license begin
59
- license: LicensePage,
17
+ license: () => import("@/pages/license/LicensePage.vue"),
60
18
  // @windy-module system.license end
61
19
  // @windy-module system.notification begin
62
- notification: SystemNotificationsPage,
20
+ notification: () => import("@/pages/system/SystemNotificationsPage.vue"),
63
21
  // @windy-module system.notification end
64
22
  // @windy-module system.operations begin
65
- operations: SystemOperationsPage,
23
+ operations: () => import("@/pages/system/SystemOperationsPage.vue"),
66
24
  // @windy-module system.operations end
67
- // @windy-module system.agent begin
68
- "agent-tools": AgentToolsPage,
69
- "agent-skills": SystemAgentSkillsPage,
70
- "agent-native": AgentNativePage,
71
- "agent-debug": AgentDebugPage,
72
- "agent-session": AgentSessionPage,
73
- "agent-workflow": AgentWorkflowPage,
74
- "ai-runtime": AiRuntimePage,
75
- // @windy-module system.agent end
25
+ // @windy-module system.agent-ui begin
26
+ "agent-tools": () => import("@/pages/system/AgentToolsPage.vue"),
27
+ "agent-skills": () => import("@/pages/system/SystemAgentSkillsPage.vue"),
28
+ "agent-native": () => import("@/pages/system/AgentNativePage.vue"),
29
+ "agent-debug": () => import("@/pages/system/AgentDebugPage.vue"),
30
+ "agent-session": () => import("@/pages/system/AgentSessionPage.vue"),
31
+ "agent-workflow": () => import("@/pages/system/AgentWorkflowPage.vue"),
32
+ "ai-runtime": () => import("@/pages/system/AiRuntimePage.vue"),
33
+ // @windy-module system.agent-ui end
76
34
  // @windy-module system.configuration begin
77
- configuration: ModuleConfigurationPage,
35
+ configuration: () =>
36
+ import("@/pages/configuration/ModuleConfigurationPage.vue"),
78
37
  // @windy-module system.configuration end
79
38
  };
@@ -10,7 +10,7 @@ export type PlatformAdminPageKey =
10
10
  | "license"
11
11
  | "notification"
12
12
  | "operations"
13
- // @windy-module system.agent begin
13
+ // @windy-module system.agent-ui begin
14
14
  | "agent-tools"
15
15
  | "agent-skills"
16
16
  | "agent-native"
@@ -18,7 +18,7 @@ export type PlatformAdminPageKey =
18
18
  | "agent-session"
19
19
  | "agent-workflow"
20
20
  | "ai-runtime"
21
- // @windy-module system.agent end
21
+ // @windy-module system.agent-ui end
22
22
  | "configuration"
23
23
  | "ui-components";
24
24
 
@@ -67,7 +67,7 @@ export const platformAdminRouteBindings: readonly PlatformAdminRouteBinding[] =
67
67
  // @windy-module system.operations begin
68
68
  { routeKey: "system.ops", page: "operations" },
69
69
  // @windy-module system.operations end
70
- // @windy-module system.agent begin
70
+ // @windy-module system.agent-ui begin
71
71
  { routeKey: "system.agent-tools", page: "agent-tools" },
72
72
  { routeKey: "system.agent-skill", page: "agent-skills" },
73
73
  { routeKey: "system.agent-workbench", page: "agent-native" },
@@ -75,7 +75,7 @@ export const platformAdminRouteBindings: readonly PlatformAdminRouteBinding[] =
75
75
  { routeKey: "system.agent-session", page: "agent-session" },
76
76
  { routeKey: "system.agent-workflow", page: "agent-workflow" },
77
77
  { routeKey: "system.ai-runtime", page: "ai-runtime" },
78
- // @windy-module system.agent end
78
+ // @windy-module system.agent-ui end
79
79
  // @windy-module system.configuration begin
80
80
  { routeKey: "system.config", page: "configuration" },
81
81
  // @windy-module system.configuration end
@@ -1,4 +1,4 @@
1
- import type { DiagnosticRecord } from "@southwind-ai/shared";
1
+ import type { DiagnosticRecord, PageResult } from "@southwind-ai/shared";
2
2
  import { apiRequest } from "./http";
3
3
 
4
4
  export type { DiagnosticRecord } from "@southwind-ai/shared";
@@ -10,3 +10,15 @@ export function getDiagnostic(id: string, signal: AbortSignal) {
10
10
  { suppressFailureHandler: true },
11
11
  );
12
12
  }
13
+
14
+ export function listDiagnostics(
15
+ page: number,
16
+ pageSize: number,
17
+ signal: AbortSignal,
18
+ ) {
19
+ return apiRequest<PageResult<DiagnosticRecord>>(
20
+ `/system/diagnostics?page=${page}&pageSize=${pageSize}`,
21
+ { signal, cache: "no-store" },
22
+ { suppressFailureHandler: true },
23
+ );
24
+ }
@@ -1,5 +1,7 @@
1
1
  import { apiRequest } from "./http";
2
2
  import type {
3
+ EnvironmentAssessmentSnapshot,
4
+ EnvironmentSnapshot,
3
5
  PageResult,
4
6
  SchedulerManualTriggerResponse,
5
7
  SchedulerOperationsSnapshot,
@@ -9,6 +11,8 @@ import type {
9
11
  } from "@southwind-ai/shared";
10
12
 
11
13
  export interface OperationSnapshot {
14
+ environment?: EnvironmentSnapshot;
15
+ featureAssessment?: EnvironmentAssessmentSnapshot;
12
16
  generatedAt: string;
13
17
  onlineUsers: Array<{
14
18
  sessionId: string;
@@ -1,4 +1,4 @@
1
- import { apiRequest } from "./http";
1
+ import { apiRequest, apiResponse } from "./http";
2
2
  import type {
3
3
  PlatformBrandingSettings,
4
4
  PlatformWatermarkPolicy,
@@ -42,3 +42,37 @@ export function updatePlatformWatermarkPolicy(
42
42
  body: JSON.stringify(policy),
43
43
  });
44
44
  }
45
+
46
+ const WATERMARK_YAML_PATH = "/system/settings/watermark/yaml";
47
+
48
+ export interface WatermarkYamlPreview {
49
+ revision: string;
50
+ changes: {
51
+ key:
52
+ | "enabled"
53
+ | "density"
54
+ | "contentFields"
55
+ | "opacityPercent"
56
+ | "fontSize";
57
+ before: boolean | string | number | string[];
58
+ after: boolean | string | number | string[];
59
+ }[];
60
+ }
61
+
62
+ export async function exportWatermarkYaml() {
63
+ return (await apiResponse(WATERMARK_YAML_PATH)).blob();
64
+ }
65
+
66
+ export function previewWatermarkYaml(yaml: string) {
67
+ return apiRequest<WatermarkYamlPreview>(`${WATERMARK_YAML_PATH}/preview`, {
68
+ method: "POST",
69
+ body: JSON.stringify({ yaml }),
70
+ });
71
+ }
72
+
73
+ export function importWatermarkYaml(yaml: string, revision: string) {
74
+ return apiRequest<PlatformWatermarkPolicy>(WATERMARK_YAML_PATH, {
75
+ method: "POST",
76
+ body: JSON.stringify({ yaml, revision }),
77
+ });
78
+ }
@@ -18,7 +18,9 @@ import { adminUiModuleRegistryPlugin } from "./src/router/admin-ui-module-regist
18
18
 
19
19
  const fingerprint =
20
20
  process.env.WINDY_DEV_FINGERPRINT || projectFingerprint(process.cwd());
21
- const devPort = Number(process.env.WINDY_DEV_PORT || 8_746);
21
+ const devPort = Number(
22
+ process.env.WINDY_DEV_PORT || process.env.WINDY_WEB_PORT || 28_746,
23
+ );
22
24
  const usePolling = process.env.WINDY_DEV_USE_POLLING === "1";
23
25
  const adminUiValidatorEntry = fileURLToPath(
24
26
  new URL("./scripts/validate-admin-ui-composition.ts", import.meta.url),
@@ -52,7 +54,9 @@ export default defineConfig({
52
54
  proxy: {
53
55
  // @windy-module system.agent begin
54
56
  "^/agent(?:$|[/?])": {
55
- target: process.env.API_UPSTREAM ?? "http://localhost:9747",
57
+ target:
58
+ process.env.API_UPSTREAM ??
59
+ `http://127.0.0.1:${process.env.WINDY_SERVER_PORT ?? "19747"}`,
56
60
  ws: true,
57
61
  bypass: (request) =>
58
62
  isDshWorkbenchPath(request.url ?? "/") ? undefined : "/index.html",
@@ -82,7 +86,9 @@ export default defineConfig({
82
86
  },
83
87
  },
84
88
  // @windy-module system.agent end
85
- "/api": process.env.API_UPSTREAM ?? "http://localhost:9747",
89
+ "/api":
90
+ process.env.API_UPSTREAM ??
91
+ `http://127.0.0.1:${process.env.WINDY_SERVER_PORT ?? "19747"}`,
86
92
  },
87
93
  },
88
94
  });
@@ -0,0 +1,53 @@
1
+ # Windy 环境与功能预设示例。复制为 windy.environment.yaml 后按项目修改。
2
+ # 首次生成:create-windy my-app --environment-profile windy.environment.yaml
3
+ # 运行时:Server 用 WINDY_ENVIRONMENT_PROFILE_FILE 指向此文件的只读挂载路径。
4
+ # build 控制生成裁剪,runtime 控制 Server 启动装配,features 提供评估建议。
5
+ schemaVersion: 1
6
+ build:
7
+ # 只填写 Windy 分发目录中存在的 Module;必需模块及依赖会自动补齐。
8
+ # 纯 CPU OCR 选择媒体运行时,Agent 作为独立模块按需选择。
9
+ modules:
10
+ - system
11
+ - system.identity
12
+ - system.settings
13
+ - system.configuration
14
+ - system.audit
15
+ - system.operations
16
+ - system.media-runtime
17
+ runtimes:
18
+ agent: false
19
+ document: true
20
+ speech: false
21
+ embedding: false
22
+ # runtime 缺省时沿用原有启动设置。使用以下组合时须开启 PLATFORM_ENABLE_AI_RUNTIME。
23
+ runtime:
24
+ agent: false
25
+ document: true
26
+ speech: false
27
+ embedding: false
28
+ antivirus:
29
+ packaged: false
30
+ enabled: false
31
+ features:
32
+ - key: system.ops
33
+ title: 系统运维总览
34
+ execution: none # none / cpu / local-gpu / remote
35
+ recommendedEnabled: true # 只是建议;管理员复核后在功能管理确认。
36
+
37
+
38
+ # 添加业务功能时,使用其 Manifest 中真实存在的 Feature Key,不填猜测的模块名。
39
+ # 例如 CPU OCR(下面是占位示例,需换成业务正式 Key 后再启用):
40
+ # - key: example.cpu-ocr
41
+ # title: CPU 文档识别
42
+ # execution: cpu
43
+ # recommendedEnabled: true
44
+ # supportedPlatforms: [linux] # 依据软件适配证据填写,不靠硬件猜测。
45
+ # supportedArchitectures: [arm64, x64] # 当前应用进程架构;外部推理节点需另验收。
46
+ # minMemoryGiB: 8 # 已验证的最低要求,不承诺处理速度。
47
+ # requiredEnvironmentKeys: [DOCUMENT_SERVER_URL] # 只检查是否配置,绝不显示凭据值。
48
+ #
49
+ # 本地 GPU 模型使用 local-gpu;缺少 NVIDIA 查询证据返回未知,不认定“没有 GPU”。
50
+ # 远程模型使用 remote,不会因本机无 GPU/内存少而直接判定不可用。
51
+ # 病毒扫描为独立可选功能,可选择不扫描;不能用 GPU 条件控制它。
52
+ # 未注册的 Feature 显示“未随包交付/请核对 Key”,未知条件不自动关闭功能。
53
+ # 通过声明条件不代表模型 readiness、驱动兼容、识别质量或业务性能验收通过。
@@ -49,10 +49,11 @@ services:
49
49
  WINDY_CONTAINERIZED: "1"
50
50
  BUN_CONFIG_NO_CLEAR_TERMINAL_ON_RELOAD: "true"
51
51
  WINDY_SYSTEM_USAGE_PATHS: /app/data/audit
52
- PLATFORM_ENABLE_AI: ${PLATFORM_ENABLE_AI:-false}
52
+ PLATFORM_ENABLE_AI_RUNTIME: ${PLATFORM_ENABLE_AI_RUNTIME:-${PLATFORM_ENABLE_AI:-false}}
53
+
53
54
  AGENT_SERVER_URL: http://agent-server:8080
54
- WINDY_PUBLIC_BASE_URL: "${WINDY_PUBLIC_BASE_URL:-}"
55
55
  AGENT_TOOL_HOST_URL: http://server:9747
56
+ WINDY_PUBLIC_BASE_URL: "${WINDY_PUBLIC_BASE_URL:-}"
56
57
  TOOL_SANDBOX_SOCKET: /run/windy-tool-sandbox/worker.sock
57
58
  AGENT_SERVER_INTERNAL_TOKEN: ${AGENT_SERVER_INTERNAL_TOKEN:-}
58
59
  WINDY_AGENT_WORKFLOW_MODEL_PRICING_JSON: ${WINDY_AGENT_WORKFLOW_MODEL_PRICING_JSON:-}
@@ -74,6 +75,7 @@ services:
74
75
  - ./apps/server:/app/apps/server
75
76
  - ./packages:/app/packages
76
77
  - server-audit-data:/app/data/audit
78
+
77
79
  - server-storage-data:/app/data/storage
78
80
  - tool-sandbox-ipc:/run/windy-tool-sandbox
79
81
  depends_on:
@@ -1,6 +1,6 @@
1
1
  # Agent 管理工作台技术实现
2
2
 
3
- 日期:2026-10-07。对应[方案](./agent-admin-workbench-plan.md)。本轮实现已合入 main,0.8.3 已按用户授权跳过 gate 直接发布,见[发布记录](../operations/create-windy-0.8.3-release.md);尚未证明下游升级或生产部署。
3
+ 日期:2026-10-07。对应[方案](./agent-admin-workbench-plan.md)。本轮实现已合入 main,0.8.3 已按用户授权跳过 gate 直接发布;尚未证明下游升级或生产部署。
4
4
 
5
5
  ## 交付入口与业务结果
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Agent 工具目录与调试工作台方案
2
2
 
3
- 日期:2026-10-07。状态:源码实现已合入 main,0.8.3 已按用户授权跳过 gate 直接发布,见[发布记录](../operations/create-windy-0.8.3-release.md);下游升级与部署待独立验收。
3
+ 日期:2026-10-07。状态:源码实现已合入 main,0.8.3 已按用户授权跳过 gate 直接发布;下游升级与部署待独立验收。
4
4
 
5
5
  ## 业务场景与验收边界
6
6
 
@@ -108,3 +108,11 @@ Composition Root 为 Workflow Repository、Evaluation Repository、Approval Adap
108
108
  Adapter、Governed Tool Host 与 Subagent Adapter 各绑定一个实现。生产使用 PostgreSQL Repository;
109
109
  进程内 Repository 只用于受限开发或契约验证,不能作为可恢复运行事实源。未知 Node、缺失 Adapter、
110
110
  重复 Key、Release 漂移或未声明 Manifest guard 必须在启动或接收命令时 fail closed。
111
+
112
+ ## 模型节点发布校验
113
+
114
+ 通用发布入口与项目发布入口共用发布 Service。保存 Release 前,Service 逐个检查模型节点的
115
+ `operationKey` 和 `promptKey`。当前 `promptKey` 保存版本坐标,必须与 Host 已装配的
116
+ Agent Operation Handler 的 `release.promptVersion` 完全一致。Operation 缺失、未声明
117
+ Release 或版本不匹配时,发布返回 `MODEL_PROMPT_RELEASE_MISMATCH`。项目入口仍需完成
118
+ 项目绑定授权。已有 Release 执行时继续使用 Runtime 的版本检查。