create-windy 0.3.0 → 0.3.2
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 +30 -3
- package/dist/cli.js +7640 -3255
- package/package.json +3 -3
- package/template/.windy-template.json +2 -2
- package/template/README.md +25 -3
- package/template/_gitignore +4 -0
- package/template/apps/agent-server/tests/__init__.py +1 -0
- package/template/apps/agent-server/tests/openai_provider_test_support.py +131 -0
- package/template/apps/agent-server/tests/test_openai_provider.py +7 -123
- package/template/apps/server/src/auth/routes.test-support.ts +94 -0
- package/template/apps/server/src/auth/routes.test.ts +20 -88
- package/template/apps/server/src/index.ts +17 -34
- package/template/apps/server/src/mcp/adapter.test.ts +3 -2
- package/template/apps/server/src/mcp/adapter.ts +9 -9
- package/template/apps/server/src/mcp/routes.ts +4 -3
- package/template/apps/server/src/platform-http-runtime.ts +87 -0
- package/template/apps/server/src/system/drizzle-system-configs.ts +319 -0
- package/template/apps/server/src/system/drizzle-system.ts +35 -315
- package/template/apps/server/src/system/resource-routes.ts +270 -0
- package/template/apps/server/src/system/routes.ts +3 -269
- package/template/apps/web/src/pages/system/components/SystemResourceLoadError.vue +21 -0
- package/template/apps/web/src/pages/system/components/SystemResourceLoadError.webtest.ts +17 -0
- package/template/apps/web/src/pages/system/components/SystemResourcePage.vue +5 -10
- package/template/docs/architecture/mcp-business-capabilities.md +107 -0
- package/template/docs/development/custom-login-page.md +3 -3
- package/template/docs/platform/agent-runtime.md +5 -5
- package/template/docs/platform/agent-tools.md +4 -0
- package/template/packages/modules/package.json +1 -1
- package/template/packages/modules/src/composition-fixtures.test-support.ts +164 -0
- package/template/packages/modules/src/composition.test.ts +5 -158
- package/template/packages/modules/src/system-api-operational.ts +234 -0
- package/template/packages/modules/src/system-api-permissions.ts +8 -229
- package/template/packages/modules/src/system-module-tasks.ts +86 -0
- package/template/packages/modules/src/system-modules-access.test.ts +60 -0
- package/template/packages/modules/src/system-modules.test.ts +0 -53
- package/template/packages/modules/src/system-modules.ts +2 -84
- package/template/packages/shared/index.ts +1 -0
- package/template/packages/shared/package.json +1 -1
- package/template/packages/shared/src/mcp.test.ts +12 -0
- package/template/packages/shared/src/mcp.ts +7 -0
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { ApiPermissionBinding } from "@southwind-ai/shared";
|
|
2
|
+
// @windy-module system.agent begin
|
|
3
|
+
import { MCP_API_PATH } from "@southwind-ai/shared";
|
|
4
|
+
// @windy-module system.agent end
|
|
2
5
|
import { binding, resourceBindings } from "./system-api-binding.js";
|
|
3
6
|
// @windy-module system.settings begin
|
|
4
7
|
import { watermarkApiPermissionBindings } from "./system-api-watermark.js";
|
|
@@ -6,6 +9,7 @@ import { watermarkApiPermissionBindings } from "./system-api-watermark.js";
|
|
|
6
9
|
// @windy-module system.data-governance begin
|
|
7
10
|
import { dataGovernanceApiPermissionBindings } from "./system-api-data-governance.js";
|
|
8
11
|
// @windy-module system.data-governance end
|
|
12
|
+
import { systemOperationalApiPermissionBindings } from "./system-api-operational.js";
|
|
9
13
|
|
|
10
14
|
export function systemApiPermissionBindings(): ApiPermissionBinding[] {
|
|
11
15
|
return [
|
|
@@ -26,9 +30,9 @@ export function systemApiPermissionBindings(): ApiPermissionBinding[] {
|
|
|
26
30
|
binding("POST", "/api/search", "system.search.read", "system.search"),
|
|
27
31
|
// @windy-module system.search end
|
|
28
32
|
// @windy-module system.agent begin
|
|
29
|
-
binding("GET",
|
|
30
|
-
binding("POST",
|
|
31
|
-
binding("DELETE",
|
|
33
|
+
binding("GET", MCP_API_PATH, "system.agent.read", "system.agent"),
|
|
34
|
+
binding("POST", MCP_API_PATH, "system.agent.read", "system.agent"),
|
|
35
|
+
binding("DELETE", MCP_API_PATH, "system.agent.read", "system.agent"),
|
|
32
36
|
// @windy-module system.agent end
|
|
33
37
|
...resourceBindings({
|
|
34
38
|
path: "users",
|
|
@@ -177,231 +181,6 @@ export function systemApiPermissionBindings(): ApiPermissionBinding[] {
|
|
|
177
181
|
"system.audit",
|
|
178
182
|
),
|
|
179
183
|
// @windy-module system.audit end
|
|
180
|
-
|
|
181
|
-
binding(
|
|
182
|
-
"POST",
|
|
183
|
-
"/api/system/storage/uploads",
|
|
184
|
-
"system.storage.create",
|
|
185
|
-
"system.storage",
|
|
186
|
-
),
|
|
187
|
-
binding(
|
|
188
|
-
"GET",
|
|
189
|
-
"/api/system/storage/uploads/:id",
|
|
190
|
-
"system.storage.create",
|
|
191
|
-
"system.storage",
|
|
192
|
-
),
|
|
193
|
-
binding(
|
|
194
|
-
"PUT",
|
|
195
|
-
"/api/system/storage/uploads/:id/parts/:partNumber",
|
|
196
|
-
"system.storage.create",
|
|
197
|
-
"system.storage",
|
|
198
|
-
),
|
|
199
|
-
binding(
|
|
200
|
-
"POST",
|
|
201
|
-
"/api/system/storage/uploads/:id/complete",
|
|
202
|
-
"system.storage.create",
|
|
203
|
-
"system.storage",
|
|
204
|
-
),
|
|
205
|
-
binding(
|
|
206
|
-
"DELETE",
|
|
207
|
-
"/api/system/storage/uploads/:id",
|
|
208
|
-
"system.storage.create",
|
|
209
|
-
"system.storage",
|
|
210
|
-
),
|
|
211
|
-
binding(
|
|
212
|
-
"GET",
|
|
213
|
-
"/api/system/storage/files/:id",
|
|
214
|
-
"system.storage.read",
|
|
215
|
-
"system.storage",
|
|
216
|
-
),
|
|
217
|
-
binding(
|
|
218
|
-
"GET",
|
|
219
|
-
"/api/platform/files/:id",
|
|
220
|
-
"system.settings.read",
|
|
221
|
-
"system.settings",
|
|
222
|
-
true,
|
|
223
|
-
),
|
|
224
|
-
// @windy-module system.storage end
|
|
225
|
-
// @windy-module system.operations begin
|
|
226
|
-
binding("GET", "/api/system/operations", "system.ops.read", "system.ops"),
|
|
227
|
-
// @windy-module system.operations end
|
|
228
|
-
// @windy-module system.notification begin
|
|
229
|
-
binding(
|
|
230
|
-
"GET",
|
|
231
|
-
"/api/notifications",
|
|
232
|
-
"system.notification.read",
|
|
233
|
-
"system.notification",
|
|
234
|
-
),
|
|
235
|
-
binding(
|
|
236
|
-
"GET",
|
|
237
|
-
"/api/notifications/preferences",
|
|
238
|
-
"system.notification.read",
|
|
239
|
-
"system.notification",
|
|
240
|
-
),
|
|
241
|
-
binding(
|
|
242
|
-
"PUT",
|
|
243
|
-
"/api/notifications/preferences",
|
|
244
|
-
"system.notification.read",
|
|
245
|
-
"system.notification",
|
|
246
|
-
),
|
|
247
|
-
binding(
|
|
248
|
-
"POST",
|
|
249
|
-
"/api/notifications/:id/read",
|
|
250
|
-
"system.notification.read",
|
|
251
|
-
"system.notification",
|
|
252
|
-
),
|
|
253
|
-
binding(
|
|
254
|
-
"PUT",
|
|
255
|
-
"/api/notifications/:id/favorite",
|
|
256
|
-
"system.notification.read",
|
|
257
|
-
"system.notification",
|
|
258
|
-
),
|
|
259
|
-
binding(
|
|
260
|
-
"DELETE",
|
|
261
|
-
"/api/notifications/:id/favorite",
|
|
262
|
-
"system.notification.read",
|
|
263
|
-
"system.notification",
|
|
264
|
-
),
|
|
265
|
-
binding(
|
|
266
|
-
"GET",
|
|
267
|
-
"/api/system/notifications/audience-options",
|
|
268
|
-
"system.notification.manage",
|
|
269
|
-
"system.notification",
|
|
270
|
-
),
|
|
271
|
-
binding(
|
|
272
|
-
"GET",
|
|
273
|
-
"/api/system/notifications/:id/deliveries",
|
|
274
|
-
"system.notification.manage",
|
|
275
|
-
"system.notification",
|
|
276
|
-
),
|
|
277
|
-
binding(
|
|
278
|
-
"GET",
|
|
279
|
-
"/api/system/notifications",
|
|
280
|
-
"system.notification.manage",
|
|
281
|
-
"system.notification",
|
|
282
|
-
),
|
|
283
|
-
binding(
|
|
284
|
-
"POST",
|
|
285
|
-
"/api/system/notifications",
|
|
286
|
-
"system.notification.manage",
|
|
287
|
-
"system.notification",
|
|
288
|
-
),
|
|
289
|
-
binding(
|
|
290
|
-
"PUT",
|
|
291
|
-
"/api/system/notifications/:id",
|
|
292
|
-
"system.notification.update",
|
|
293
|
-
"system.notification",
|
|
294
|
-
),
|
|
295
|
-
binding(
|
|
296
|
-
"GET",
|
|
297
|
-
"/api/system/notifications/:id/revisions",
|
|
298
|
-
"system.notification.manage",
|
|
299
|
-
"system.notification",
|
|
300
|
-
),
|
|
301
|
-
binding(
|
|
302
|
-
"DELETE",
|
|
303
|
-
"/api/system/notifications/:id",
|
|
304
|
-
"system.notification.manage",
|
|
305
|
-
"system.notification",
|
|
306
|
-
),
|
|
307
|
-
// @windy-module system.notification end
|
|
308
|
-
// @windy-module system.workflow begin
|
|
309
|
-
binding(
|
|
310
|
-
"GET",
|
|
311
|
-
"/api/workflow/work-items",
|
|
312
|
-
"system.workflow.read",
|
|
313
|
-
"system.workflow",
|
|
314
|
-
),
|
|
315
|
-
binding(
|
|
316
|
-
"GET",
|
|
317
|
-
"/api/workflow/work-items/:id",
|
|
318
|
-
"system.workflow.read",
|
|
319
|
-
"system.workflow",
|
|
320
|
-
),
|
|
321
|
-
binding(
|
|
322
|
-
"GET",
|
|
323
|
-
"/api/workflow/work-items/:id/history",
|
|
324
|
-
"system.workflow.read",
|
|
325
|
-
"system.workflow",
|
|
326
|
-
),
|
|
327
|
-
binding(
|
|
328
|
-
"POST",
|
|
329
|
-
"/api/workflow/work-items",
|
|
330
|
-
"system.workflow.create",
|
|
331
|
-
"system.workflow",
|
|
332
|
-
),
|
|
333
|
-
...["claim", "transfer", "approve", "reject", "cancel"].map((command) =>
|
|
334
|
-
binding(
|
|
335
|
-
"POST",
|
|
336
|
-
`/api/workflow/work-items/:id/${command}`,
|
|
337
|
-
"system.workflow.approve",
|
|
338
|
-
"system.workflow",
|
|
339
|
-
),
|
|
340
|
-
),
|
|
341
|
-
// @windy-module system.workflow end
|
|
342
|
-
// @windy-module system.scheduler begin
|
|
343
|
-
binding(
|
|
344
|
-
"GET",
|
|
345
|
-
"/api/system/scheduled-tasks",
|
|
346
|
-
"system.scheduler.read",
|
|
347
|
-
"system.scheduler",
|
|
348
|
-
),
|
|
349
|
-
binding(
|
|
350
|
-
"GET",
|
|
351
|
-
"/api/system/scheduled-task-runs",
|
|
352
|
-
"system.scheduler.read",
|
|
353
|
-
"system.scheduler",
|
|
354
|
-
),
|
|
355
|
-
binding(
|
|
356
|
-
"GET",
|
|
357
|
-
"/api/system/operations/scheduler",
|
|
358
|
-
"system.scheduler.read",
|
|
359
|
-
"system.scheduler",
|
|
360
|
-
),
|
|
361
|
-
binding(
|
|
362
|
-
"POST",
|
|
363
|
-
"/api/system/scheduled-tasks/:id/trigger",
|
|
364
|
-
"system.scheduler.manage",
|
|
365
|
-
"system.scheduler",
|
|
366
|
-
),
|
|
367
|
-
binding(
|
|
368
|
-
"POST",
|
|
369
|
-
"/api/system/scheduled-tasks/:id/runs/:runId/recover",
|
|
370
|
-
"system.scheduler.manage",
|
|
371
|
-
"system.scheduler",
|
|
372
|
-
),
|
|
373
|
-
// @windy-module system.scheduler end
|
|
374
|
-
// @windy-module system.bulk-data begin
|
|
375
|
-
binding(
|
|
376
|
-
"GET",
|
|
377
|
-
"/api/system/bulk-data/jobs",
|
|
378
|
-
"system.dict.read",
|
|
379
|
-
"system.bulk-data",
|
|
380
|
-
),
|
|
381
|
-
binding(
|
|
382
|
-
"GET",
|
|
383
|
-
"/api/system/bulk-data/jobs/:id",
|
|
384
|
-
"system.dict.read",
|
|
385
|
-
"system.bulk-data",
|
|
386
|
-
),
|
|
387
|
-
binding(
|
|
388
|
-
"GET",
|
|
389
|
-
"/api/system/bulk-data/jobs/:id/artifacts/:kind",
|
|
390
|
-
"system.dict.read",
|
|
391
|
-
"system.bulk-data",
|
|
392
|
-
),
|
|
393
|
-
binding(
|
|
394
|
-
"POST",
|
|
395
|
-
"/api/system/bulk-data/dictionaries/import",
|
|
396
|
-
"system.dict.manage",
|
|
397
|
-
"system.bulk-data",
|
|
398
|
-
),
|
|
399
|
-
binding(
|
|
400
|
-
"POST",
|
|
401
|
-
"/api/system/bulk-data/dictionaries/export",
|
|
402
|
-
"system.dict.read",
|
|
403
|
-
"system.bulk-data",
|
|
404
|
-
),
|
|
405
|
-
// @windy-module system.bulk-data end
|
|
184
|
+
...systemOperationalApiPermissionBindings(),
|
|
406
185
|
];
|
|
407
186
|
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { ModuleManifest } from "./manifest.js";
|
|
2
|
+
|
|
3
|
+
export const systemModuleTasks: ModuleManifest["tasks"] = [
|
|
4
|
+
// @windy-module system.scheduler begin
|
|
5
|
+
{
|
|
6
|
+
key: "system.scheduler.health-snapshot",
|
|
7
|
+
label: "调度器健康快照",
|
|
8
|
+
description: "周期验证调度、Guard、执行历史和重试链路可用。",
|
|
9
|
+
permissionKey: "system.scheduler.manage",
|
|
10
|
+
featureKey: "system.scheduler",
|
|
11
|
+
intervalSeconds: 300,
|
|
12
|
+
maxAttempts: 3,
|
|
13
|
+
retryDelaySeconds: 30,
|
|
14
|
+
},
|
|
15
|
+
// @windy-module system.scheduler end
|
|
16
|
+
// @windy-module system.notification begin
|
|
17
|
+
{
|
|
18
|
+
key: "system.notification.dispatch",
|
|
19
|
+
label: "通知发布与外部投递",
|
|
20
|
+
description: "发布到期通知并领取持久投递队列,执行渠道重试。",
|
|
21
|
+
permissionKey: "system.notification.manage",
|
|
22
|
+
featureKey: "system.notification",
|
|
23
|
+
intervalSeconds: 5,
|
|
24
|
+
maxAttempts: 3,
|
|
25
|
+
retryDelaySeconds: 30,
|
|
26
|
+
},
|
|
27
|
+
// @windy-module system.notification end
|
|
28
|
+
// @windy-module system.bulk-data begin
|
|
29
|
+
{
|
|
30
|
+
key: "system.bulk-data.dispatch",
|
|
31
|
+
label: "批量数据任务派发",
|
|
32
|
+
description: "领取一个已排队或到期重试的批量导入导出任务。",
|
|
33
|
+
permissionKey: "system.bulk-data.manage",
|
|
34
|
+
featureKey: "system.bulk-data",
|
|
35
|
+
intervalSeconds: 5,
|
|
36
|
+
maxAttempts: 3,
|
|
37
|
+
retryDelaySeconds: 30,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
key: "system.bulk-data.cleanup",
|
|
41
|
+
label: "批量数据文件清理",
|
|
42
|
+
description: "清理超过留存期限的源文件、结果和失败明细。",
|
|
43
|
+
permissionKey: "system.bulk-data.manage",
|
|
44
|
+
featureKey: "system.bulk-data",
|
|
45
|
+
intervalSeconds: 3_600,
|
|
46
|
+
maxAttempts: 3,
|
|
47
|
+
retryDelaySeconds: 60,
|
|
48
|
+
},
|
|
49
|
+
// @windy-module system.bulk-data end
|
|
50
|
+
// @windy-module system.storage begin
|
|
51
|
+
{
|
|
52
|
+
key: "system.storage.cleanup",
|
|
53
|
+
label: "文件存储清理",
|
|
54
|
+
description: "清理过期上传、文件、临时分片和超过宽限期的孤儿对象。",
|
|
55
|
+
permissionKey: "system.storage.manage",
|
|
56
|
+
featureKey: "system.storage",
|
|
57
|
+
intervalSeconds: 3_600,
|
|
58
|
+
maxAttempts: 3,
|
|
59
|
+
retryDelaySeconds: 60,
|
|
60
|
+
},
|
|
61
|
+
// @windy-module system.storage end
|
|
62
|
+
// @windy-module system.workflow begin
|
|
63
|
+
{
|
|
64
|
+
key: "system.workflow.timeout-dispatch",
|
|
65
|
+
label: "审批超时派发",
|
|
66
|
+
description: "补偿登记并执行一个到期审批任务,进程重启后继续处理。",
|
|
67
|
+
permissionKey: "system.workflow.manage",
|
|
68
|
+
featureKey: "system.workflow",
|
|
69
|
+
intervalSeconds: 5,
|
|
70
|
+
maxAttempts: 3,
|
|
71
|
+
retryDelaySeconds: 30,
|
|
72
|
+
},
|
|
73
|
+
// @windy-module system.workflow end
|
|
74
|
+
// @windy-module system.data-governance begin
|
|
75
|
+
{
|
|
76
|
+
key: "system.governed-export.dispatch",
|
|
77
|
+
label: "受治理导出派发",
|
|
78
|
+
description: "领取并执行一个已批准的敏感数据导出任务。",
|
|
79
|
+
permissionKey: "system.user.export",
|
|
80
|
+
featureKey: "system.rbac",
|
|
81
|
+
intervalSeconds: 5,
|
|
82
|
+
maxAttempts: 3,
|
|
83
|
+
retryDelaySeconds: 30,
|
|
84
|
+
},
|
|
85
|
+
// @windy-module system.data-governance end
|
|
86
|
+
];
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
// @windy-module system.agent begin
|
|
3
|
+
import { MCP_API_PATH } from "@southwind-ai/shared";
|
|
4
|
+
// @windy-module system.agent end
|
|
5
|
+
import { systemFoundationModule } from "./system-modules.js";
|
|
6
|
+
|
|
7
|
+
describe("系统模块管理面与 MCP 注册", () => {
|
|
8
|
+
test("管理面准入使用独立 Feature 与 access 权限", () => {
|
|
9
|
+
const manifest = systemFoundationModule();
|
|
10
|
+
|
|
11
|
+
expect(manifest.features).toContainEqual(
|
|
12
|
+
expect.objectContaining({ key: "system.admin", enabled: true }),
|
|
13
|
+
);
|
|
14
|
+
expect(manifest.permissions).toContainEqual(
|
|
15
|
+
expect.objectContaining({
|
|
16
|
+
key: "system.admin.access",
|
|
17
|
+
action: "access",
|
|
18
|
+
}),
|
|
19
|
+
);
|
|
20
|
+
expect(manifest.apiPermissions).toContainEqual({
|
|
21
|
+
method: "GET",
|
|
22
|
+
path: "/api/admin/bootstrap",
|
|
23
|
+
permissionKey: "system.admin.access",
|
|
24
|
+
featureKey: "system.admin",
|
|
25
|
+
anonymous: undefined,
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// @windy-module system.agent begin
|
|
30
|
+
test("MCP Streamable HTTP 入口统一绑定 Agent Feature 与读取权限", () => {
|
|
31
|
+
const bindings = systemFoundationModule().apiPermissions.filter(
|
|
32
|
+
({ path }) => path === MCP_API_PATH,
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
expect(bindings).toEqual([
|
|
36
|
+
{
|
|
37
|
+
method: "GET",
|
|
38
|
+
path: MCP_API_PATH,
|
|
39
|
+
permissionKey: "system.agent.read",
|
|
40
|
+
featureKey: "system.agent",
|
|
41
|
+
anonymous: undefined,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
method: "POST",
|
|
45
|
+
path: MCP_API_PATH,
|
|
46
|
+
permissionKey: "system.agent.read",
|
|
47
|
+
featureKey: "system.agent",
|
|
48
|
+
anonymous: undefined,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
method: "DELETE",
|
|
52
|
+
path: MCP_API_PATH,
|
|
53
|
+
permissionKey: "system.agent.read",
|
|
54
|
+
featureKey: "system.agent",
|
|
55
|
+
anonymous: undefined,
|
|
56
|
+
},
|
|
57
|
+
]);
|
|
58
|
+
});
|
|
59
|
+
// @windy-module system.agent end
|
|
60
|
+
});
|
|
@@ -317,59 +317,6 @@ describe("系统模块能力注册", () => {
|
|
|
317
317
|
]);
|
|
318
318
|
});
|
|
319
319
|
// @windy-module system.configuration end
|
|
320
|
-
|
|
321
|
-
test("管理面准入使用独立 Feature 与 access 权限", () => {
|
|
322
|
-
const manifest = systemFoundationModule();
|
|
323
|
-
|
|
324
|
-
expect(manifest.features).toContainEqual(
|
|
325
|
-
expect.objectContaining({ key: "system.admin", enabled: true }),
|
|
326
|
-
);
|
|
327
|
-
expect(manifest.permissions).toContainEqual(
|
|
328
|
-
expect.objectContaining({
|
|
329
|
-
key: "system.admin.access",
|
|
330
|
-
action: "access",
|
|
331
|
-
}),
|
|
332
|
-
);
|
|
333
|
-
expect(manifest.apiPermissions).toContainEqual({
|
|
334
|
-
method: "GET",
|
|
335
|
-
path: "/api/admin/bootstrap",
|
|
336
|
-
permissionKey: "system.admin.access",
|
|
337
|
-
featureKey: "system.admin",
|
|
338
|
-
anonymous: undefined,
|
|
339
|
-
});
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
// @windy-module system.agent begin
|
|
343
|
-
test("MCP Streamable HTTP 入口统一绑定 Agent Feature 与读取权限", () => {
|
|
344
|
-
const bindings = systemFoundationModule().apiPermissions.filter(
|
|
345
|
-
({ path }) => path === "/api/mcp",
|
|
346
|
-
);
|
|
347
|
-
|
|
348
|
-
expect(bindings).toEqual([
|
|
349
|
-
{
|
|
350
|
-
method: "GET",
|
|
351
|
-
path: "/api/mcp",
|
|
352
|
-
permissionKey: "system.agent.read",
|
|
353
|
-
featureKey: "system.agent",
|
|
354
|
-
anonymous: undefined,
|
|
355
|
-
},
|
|
356
|
-
{
|
|
357
|
-
method: "POST",
|
|
358
|
-
path: "/api/mcp",
|
|
359
|
-
permissionKey: "system.agent.read",
|
|
360
|
-
featureKey: "system.agent",
|
|
361
|
-
anonymous: undefined,
|
|
362
|
-
},
|
|
363
|
-
{
|
|
364
|
-
method: "DELETE",
|
|
365
|
-
path: "/api/mcp",
|
|
366
|
-
permissionKey: "system.agent.read",
|
|
367
|
-
featureKey: "system.agent",
|
|
368
|
-
anonymous: undefined,
|
|
369
|
-
},
|
|
370
|
-
]);
|
|
371
|
-
});
|
|
372
|
-
// @windy-module system.agent end
|
|
373
320
|
});
|
|
374
321
|
|
|
375
322
|
function flattenMenuKeys(
|
|
@@ -12,6 +12,7 @@ import { systemAuditActions } from "./system-audit-actions.js";
|
|
|
12
12
|
import { systemDataPolicies } from "./system-data-governance.js";
|
|
13
13
|
// @windy-module system.data-governance end
|
|
14
14
|
import { systemFeatures } from "./system-features.js";
|
|
15
|
+
import { systemModuleTasks } from "./system-module-tasks.js";
|
|
15
16
|
import { systemPermissions } from "./system-permissions.js";
|
|
16
17
|
|
|
17
18
|
export function systemFoundationModule(): ModuleManifest {
|
|
@@ -257,90 +258,7 @@ export function systemFoundationModule(): ModuleManifest {
|
|
|
257
258
|
...systemAgentToolSchemas,
|
|
258
259
|
// @windy-module system.agent end
|
|
259
260
|
],
|
|
260
|
-
tasks:
|
|
261
|
-
// @windy-module system.scheduler begin
|
|
262
|
-
{
|
|
263
|
-
key: "system.scheduler.health-snapshot",
|
|
264
|
-
label: "调度器健康快照",
|
|
265
|
-
description: "周期验证调度、Guard、执行历史和重试链路可用。",
|
|
266
|
-
permissionKey: "system.scheduler.manage",
|
|
267
|
-
featureKey: "system.scheduler",
|
|
268
|
-
intervalSeconds: 300,
|
|
269
|
-
maxAttempts: 3,
|
|
270
|
-
retryDelaySeconds: 30,
|
|
271
|
-
},
|
|
272
|
-
// @windy-module system.scheduler end
|
|
273
|
-
// @windy-module system.notification begin
|
|
274
|
-
{
|
|
275
|
-
key: "system.notification.dispatch",
|
|
276
|
-
label: "通知发布与外部投递",
|
|
277
|
-
description: "发布到期通知并领取持久投递队列,执行渠道重试。",
|
|
278
|
-
permissionKey: "system.notification.manage",
|
|
279
|
-
featureKey: "system.notification",
|
|
280
|
-
intervalSeconds: 5,
|
|
281
|
-
maxAttempts: 3,
|
|
282
|
-
retryDelaySeconds: 30,
|
|
283
|
-
},
|
|
284
|
-
// @windy-module system.notification end
|
|
285
|
-
// @windy-module system.bulk-data begin
|
|
286
|
-
{
|
|
287
|
-
key: "system.bulk-data.dispatch",
|
|
288
|
-
label: "批量数据任务派发",
|
|
289
|
-
description: "领取一个已排队或到期重试的批量导入导出任务。",
|
|
290
|
-
permissionKey: "system.bulk-data.manage",
|
|
291
|
-
featureKey: "system.bulk-data",
|
|
292
|
-
intervalSeconds: 5,
|
|
293
|
-
maxAttempts: 3,
|
|
294
|
-
retryDelaySeconds: 30,
|
|
295
|
-
},
|
|
296
|
-
{
|
|
297
|
-
key: "system.bulk-data.cleanup",
|
|
298
|
-
label: "批量数据文件清理",
|
|
299
|
-
description: "清理超过留存期限的源文件、结果和失败明细。",
|
|
300
|
-
permissionKey: "system.bulk-data.manage",
|
|
301
|
-
featureKey: "system.bulk-data",
|
|
302
|
-
intervalSeconds: 3_600,
|
|
303
|
-
maxAttempts: 3,
|
|
304
|
-
retryDelaySeconds: 60,
|
|
305
|
-
},
|
|
306
|
-
// @windy-module system.bulk-data end
|
|
307
|
-
// @windy-module system.storage begin
|
|
308
|
-
{
|
|
309
|
-
key: "system.storage.cleanup",
|
|
310
|
-
label: "文件存储清理",
|
|
311
|
-
description: "清理过期上传、文件、临时分片和超过宽限期的孤儿对象。",
|
|
312
|
-
permissionKey: "system.storage.manage",
|
|
313
|
-
featureKey: "system.storage",
|
|
314
|
-
intervalSeconds: 3_600,
|
|
315
|
-
maxAttempts: 3,
|
|
316
|
-
retryDelaySeconds: 60,
|
|
317
|
-
},
|
|
318
|
-
// @windy-module system.storage end
|
|
319
|
-
// @windy-module system.workflow begin
|
|
320
|
-
{
|
|
321
|
-
key: "system.workflow.timeout-dispatch",
|
|
322
|
-
label: "审批超时派发",
|
|
323
|
-
description: "补偿登记并执行一个到期审批任务,进程重启后继续处理。",
|
|
324
|
-
permissionKey: "system.workflow.manage",
|
|
325
|
-
featureKey: "system.workflow",
|
|
326
|
-
intervalSeconds: 5,
|
|
327
|
-
maxAttempts: 3,
|
|
328
|
-
retryDelaySeconds: 30,
|
|
329
|
-
},
|
|
330
|
-
// @windy-module system.workflow end
|
|
331
|
-
// @windy-module system.data-governance begin
|
|
332
|
-
{
|
|
333
|
-
key: "system.governed-export.dispatch",
|
|
334
|
-
label: "受治理导出派发",
|
|
335
|
-
description: "领取并执行一个已批准的敏感数据导出任务。",
|
|
336
|
-
permissionKey: "system.user.export",
|
|
337
|
-
featureKey: "system.rbac",
|
|
338
|
-
intervalSeconds: 5,
|
|
339
|
-
maxAttempts: 3,
|
|
340
|
-
retryDelaySeconds: 30,
|
|
341
|
-
},
|
|
342
|
-
// @windy-module system.data-governance end
|
|
343
|
-
],
|
|
261
|
+
tasks: systemModuleTasks,
|
|
344
262
|
tools: [
|
|
345
263
|
// @windy-module system.agent begin
|
|
346
264
|
...systemAgentTools,
|
|
@@ -7,6 +7,7 @@ export * from "./src/license-catalog.js";
|
|
|
7
7
|
export * from "./src/json.js";
|
|
8
8
|
export * from "./src/migration.js";
|
|
9
9
|
export * from "./src/migration-bundle-validation.js";
|
|
10
|
+
export * from "./src/mcp.js";
|
|
10
11
|
export * from "./src/module-configuration.js";
|
|
11
12
|
export * from "./src/correlation.js";
|
|
12
13
|
export * from "./src/notification.js";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { MCP_API_PATH, MCP_ROUTE_PATH, MCP_SERVER_INFO } from "./mcp.js";
|
|
3
|
+
|
|
4
|
+
describe("MCP public contract", () => {
|
|
5
|
+
test("HTTP 路径与 Server 身份使用稳定单一来源", () => {
|
|
6
|
+
expect(MCP_API_PATH).toBe(`/api${MCP_ROUTE_PATH}`);
|
|
7
|
+
expect(MCP_SERVER_INFO).toEqual({
|
|
8
|
+
name: "windy-platform",
|
|
9
|
+
version: "0.1.0",
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
});
|