create-windy 0.2.24 → 0.2.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +106 -2
- package/package.json +1 -1
- package/template/.windy-template.json +2 -2
- package/template/apps/server/src/agent/data-scope-routes.test.ts +5 -8
- package/template/apps/server/src/agent/routes.test.ts +4 -7
- package/template/apps/server/src/agent/tool-registry.test.ts +5 -8
- package/template/apps/server/src/foundation.ts +6 -0
- package/template/apps/server/src/http-app.test.ts +5 -2
- package/template/apps/server/src/license/runtime-service.test.ts +2 -5
- package/template/apps/server/src/mcp/adapter.test.ts +2 -5
- package/template/docs/platform/agent-runtime.md +3 -3
package/dist/cli.js
CHANGED
|
@@ -4058,10 +4058,28 @@ import { join as join12 } from "node:path";
|
|
|
4058
4058
|
|
|
4059
4059
|
// src/update/process.ts
|
|
4060
4060
|
import { spawn as spawn3 } from "node:child_process";
|
|
4061
|
+
var LOCAL_GIT_ENVIRONMENT_VARIABLES = [
|
|
4062
|
+
"GIT_ALTERNATE_OBJECT_DIRECTORIES",
|
|
4063
|
+
"GIT_CONFIG",
|
|
4064
|
+
"GIT_CONFIG_PARAMETERS",
|
|
4065
|
+
"GIT_CONFIG_COUNT",
|
|
4066
|
+
"GIT_OBJECT_DIRECTORY",
|
|
4067
|
+
"GIT_DIR",
|
|
4068
|
+
"GIT_WORK_TREE",
|
|
4069
|
+
"GIT_IMPLICIT_WORK_TREE",
|
|
4070
|
+
"GIT_GRAFT_FILE",
|
|
4071
|
+
"GIT_INDEX_FILE",
|
|
4072
|
+
"GIT_NO_REPLACE_OBJECTS",
|
|
4073
|
+
"GIT_REPLACE_REF_BASE",
|
|
4074
|
+
"GIT_PREFIX",
|
|
4075
|
+
"GIT_SHALLOW_FILE",
|
|
4076
|
+
"GIT_COMMON_DIR"
|
|
4077
|
+
];
|
|
4061
4078
|
async function captureProcess(command, args, cwd, inherit = false) {
|
|
4062
4079
|
return await new Promise((resolve4, reject) => {
|
|
4063
4080
|
const child = spawn3(command, args, {
|
|
4064
4081
|
cwd,
|
|
4082
|
+
env: withoutParentGitRepository(process.env),
|
|
4065
4083
|
stdio: inherit ? "inherit" : ["ignore", "pipe", "pipe"]
|
|
4066
4084
|
});
|
|
4067
4085
|
let stdout2 = "";
|
|
@@ -4080,6 +4098,13 @@ async function assertProcess(command, args, cwd, inherit = false) {
|
|
|
4080
4098
|
}
|
|
4081
4099
|
return result;
|
|
4082
4100
|
}
|
|
4101
|
+
function withoutParentGitRepository(source) {
|
|
4102
|
+
const environment = { ...source };
|
|
4103
|
+
for (const key of LOCAL_GIT_ENVIRONMENT_VARIABLES) {
|
|
4104
|
+
delete environment[key];
|
|
4105
|
+
}
|
|
4106
|
+
return environment;
|
|
4107
|
+
}
|
|
4083
4108
|
|
|
4084
4109
|
// src/update/transaction.ts
|
|
4085
4110
|
import {
|
|
@@ -4308,7 +4333,9 @@ var recipes = [
|
|
|
4308
4333
|
{ id: "starter-0.2.20-to-0.2.21", from: "0.2.20", to: "0.2.21" },
|
|
4309
4334
|
{ id: "starter-0.2.21-to-0.2.22", from: "0.2.21", to: "0.2.22" },
|
|
4310
4335
|
{ id: "starter-0.2.22-to-0.2.23", from: "0.2.22", to: "0.2.23" },
|
|
4311
|
-
{ id: "starter-0.2.23-to-0.2.24", from: "0.2.23", to: "0.2.24" }
|
|
4336
|
+
{ id: "starter-0.2.23-to-0.2.24", from: "0.2.23", to: "0.2.24" },
|
|
4337
|
+
{ id: "starter-0.2.24-to-0.2.25", from: "0.2.24", to: "0.2.25" },
|
|
4338
|
+
{ id: "starter-0.2.25-to-0.2.26", from: "0.2.25", to: "0.2.26" }
|
|
4312
4339
|
];
|
|
4313
4340
|
function resolveRecipeChain(sourceVersion, targetVersion) {
|
|
4314
4341
|
if (sourceVersion === targetVersion)
|
|
@@ -4400,13 +4427,39 @@ import { access as access3, readFile as readFile15 } from "node:fs/promises";
|
|
|
4400
4427
|
import { join as join16 } from "node:path";
|
|
4401
4428
|
|
|
4402
4429
|
// src/update/known-repairs.ts
|
|
4430
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
4403
4431
|
var wrongTextVersions = new Set(["0.2.12", "0.2.13"]);
|
|
4404
4432
|
var formattedBaselineVersions = new Set(["0.2.14", "0.2.15"]);
|
|
4433
|
+
var known023DownstreamHashes = new Map([
|
|
4434
|
+
[
|
|
4435
|
+
"apps/server/src/http-app.ts",
|
|
4436
|
+
"9fca4e4ef68d942993f8176f2d6c508607d7c54c71d80982c966132b3a2572ce"
|
|
4437
|
+
],
|
|
4438
|
+
[
|
|
4439
|
+
"apps/server/src/observability/http-observability.test.ts",
|
|
4440
|
+
"55598b65792606fe80bb5355b2004440ee05aa64f5eedc2662680219d3678fe2"
|
|
4441
|
+
],
|
|
4442
|
+
[
|
|
4443
|
+
"apps/server/src/observability/http-observability.ts",
|
|
4444
|
+
"90a2ee14a2b905c705deb086d8fbeeded5c1e9d345e7f83141c33fcd73f794f3"
|
|
4445
|
+
],
|
|
4446
|
+
[
|
|
4447
|
+
"docs/operations/observability.md",
|
|
4448
|
+
"f7618d173f9f985b15bf71f0c1c00338dad53395ba6c249c3ce3f9443e5e756f"
|
|
4449
|
+
],
|
|
4450
|
+
[
|
|
4451
|
+
"packages/modules/src/system-modules.ts",
|
|
4452
|
+
"81fb08f26e5baa3238606d62b9c46761a68c90f3967ea639b178c80c74c69fc1"
|
|
4453
|
+
]
|
|
4454
|
+
]);
|
|
4405
4455
|
var wrongExampleDescription = "创建时包含了 `work-order` 示例模块,用于演示 Module Manifest 接入;它不是生产工单产品,可以在正式开发前替换。";
|
|
4406
4456
|
var correctCoreDescription = "创建时未选择 `work-order` 示例模块,当前项目只包含平台模块。";
|
|
4407
4457
|
var wrongExampleRow = /^\|\s*示例工单\s*\|\s*已包含\s*\|$/m;
|
|
4408
4458
|
var correctCoreRow = /^\|\s*示例工单\s*\|\s*未包含\s*\|$/m;
|
|
4409
4459
|
function repairKnownDerivedFile(input) {
|
|
4460
|
+
const downstreamRepair = repairKnown023Downstream(input);
|
|
4461
|
+
if (downstreamRepair !== undefined)
|
|
4462
|
+
return downstreamRepair;
|
|
4410
4463
|
if (input.path !== "README.md" || input.includeExample || !input.targetContent.includes(correctCoreDescription) || !correctCoreRow.test(input.targetContent)) {
|
|
4411
4464
|
return;
|
|
4412
4465
|
}
|
|
@@ -4424,6 +4477,57 @@ function repairKnownDerivedFile(input) {
|
|
|
4424
4477
|
}
|
|
4425
4478
|
return input.content.replace(wrongExampleDescription, correctCoreDescription).replace(wrongExampleRow, targetRow);
|
|
4426
4479
|
}
|
|
4480
|
+
function repairKnown023Downstream(input) {
|
|
4481
|
+
if (input.sourceVersion !== "0.2.23" || known023DownstreamHashes.get(input.path) !== contentHash(input.content)) {
|
|
4482
|
+
return;
|
|
4483
|
+
}
|
|
4484
|
+
if (input.path === "apps/server/src/http-app.ts" || input.path === "packages/modules/src/system-modules.ts") {
|
|
4485
|
+
return input.targetContent;
|
|
4486
|
+
}
|
|
4487
|
+
if (input.path === "apps/server/src/observability/http-observability.ts") {
|
|
4488
|
+
return replaceKnown(input.content, ` if (!isImportantRequest(input.request.method, statusCode, durationMs)) {`, ` if (durationMs === undefined) return;
|
|
4489
|
+
if (!isImportantRequest(input.request.method, statusCode, durationMs)) {`);
|
|
4490
|
+
}
|
|
4491
|
+
if (input.path === "apps/server/src/observability/http-observability.test.ts") {
|
|
4492
|
+
const targetTest = extractTest(input.targetContent, "同一次 observation 重复完成时不重复记录日志");
|
|
4493
|
+
return targetTest ? replaceKnown(input.content, `
|
|
4494
|
+
});
|
|
4495
|
+
`, `
|
|
4496
|
+
${targetTest}
|
|
4497
|
+
});
|
|
4498
|
+
`) : undefined;
|
|
4499
|
+
}
|
|
4500
|
+
if (input.path === "docs/operations/observability.md") {
|
|
4501
|
+
const lifecycle = extractSectionLead(input.targetContent, "请求观测在全局 `onRequest` 建立", "## Server 指标");
|
|
4502
|
+
const verification = extractSectionLead(input.targetContent, "已验证:共享关联标识校验", "尚未由本页证明");
|
|
4503
|
+
const withLifecycle = lifecycle ? replaceKnown(input.content, `
|
|
4504
|
+
## Server 指标`, `
|
|
4505
|
+
${lifecycle}
|
|
4506
|
+
## Server 指标`) : undefined;
|
|
4507
|
+
return withLifecycle && verification ? replaceKnown(withLifecycle, /^已验证:共享关联标识校验.*Dockerfile 已声明 readiness `HEALTHCHECK`。$/m, verification.trim()) : undefined;
|
|
4508
|
+
}
|
|
4509
|
+
}
|
|
4510
|
+
function contentHash(content) {
|
|
4511
|
+
return createHash2("sha256").update(content).digest("hex");
|
|
4512
|
+
}
|
|
4513
|
+
function replaceKnown(content, search, replacement) {
|
|
4514
|
+
const replaced = content.replace(search, replacement);
|
|
4515
|
+
return replaced === content ? undefined : replaced;
|
|
4516
|
+
}
|
|
4517
|
+
function extractTest(content, title) {
|
|
4518
|
+
const marker = ` test("${title}"`;
|
|
4519
|
+
const start = content.indexOf(marker);
|
|
4520
|
+
if (start < 0)
|
|
4521
|
+
return;
|
|
4522
|
+
const end = content.indexOf(`
|
|
4523
|
+
});`, start);
|
|
4524
|
+
return end < 0 ? undefined : content.slice(start, end + 6);
|
|
4525
|
+
}
|
|
4526
|
+
function extractSectionLead(content, startText, endText) {
|
|
4527
|
+
const start = content.indexOf(startText);
|
|
4528
|
+
const end = content.indexOf(endText, start);
|
|
4529
|
+
return start < 0 || end < 0 ? undefined : content.slice(start, end);
|
|
4530
|
+
}
|
|
4427
4531
|
function normalizeMarkdownTables(content) {
|
|
4428
4532
|
return content.split(`
|
|
4429
4533
|
`).map((line) => {
|
|
@@ -4980,7 +5084,7 @@ async function planFile(path2, project, baseRoot, targetRoot, source, target, pr
|
|
|
4980
5084
|
targetContent: new TextDecoder().decode(theirs)
|
|
4981
5085
|
}) : undefined;
|
|
4982
5086
|
if (repaired !== undefined) {
|
|
4983
|
-
return ready(path2, ownership, "update", "
|
|
5087
|
+
return ready(path2, ownership, "update", "修复已发布版本的确定性派生差异", new TextEncoder().encode(repaired));
|
|
4984
5088
|
}
|
|
4985
5089
|
if (path2.startsWith("packages/database/drizzle/") && path2.endsWith(".sql")) {
|
|
4986
5090
|
if (source && !target)
|
package/package.json
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
import { buildScopeContext } from "../data-access/context.js";
|
|
3
|
-
import {
|
|
4
|
-
createFoundationSnapshot,
|
|
5
|
-
loadFoundationModules,
|
|
6
|
-
} from "../foundation.js";
|
|
3
|
+
import { createFoundationSnapshot, loadSystemModules } from "../foundation.js";
|
|
7
4
|
import { createServerRuntime } from "../runtime.js";
|
|
8
5
|
import { FakeRouteApp } from "../system/route-test-app.js";
|
|
9
6
|
import { createSystemRepositories } from "../system/seed.js";
|
|
@@ -31,13 +28,13 @@ describe("Agent Tool data scope", () => {
|
|
|
31
28
|
expect(
|
|
32
29
|
() =>
|
|
33
30
|
new GovernedToolRegistry(
|
|
34
|
-
|
|
31
|
+
loadSystemModules(),
|
|
35
32
|
missing as ModuleToolHandlers,
|
|
36
33
|
runtime,
|
|
37
34
|
),
|
|
38
35
|
).toThrow("缺少 Handler");
|
|
39
36
|
expect(
|
|
40
|
-
() => new GovernedToolRegistry(
|
|
37
|
+
() => new GovernedToolRegistry(loadSystemModules(), extra, runtime),
|
|
41
38
|
).toThrow("Handler 未声明");
|
|
42
39
|
});
|
|
43
40
|
|
|
@@ -67,7 +64,7 @@ describe("Agent Tool data scope", () => {
|
|
|
67
64
|
registerAgentRoutes(
|
|
68
65
|
app,
|
|
69
66
|
new GovernedToolRegistry(
|
|
70
|
-
|
|
67
|
+
loadSystemModules(),
|
|
71
68
|
createSystemToolHandlers(repositories, runtime),
|
|
72
69
|
runtime,
|
|
73
70
|
),
|
|
@@ -102,7 +99,7 @@ describe("Agent Tool data scope", () => {
|
|
|
102
99
|
registerAgentRoutes(
|
|
103
100
|
app,
|
|
104
101
|
new GovernedToolRegistry(
|
|
105
|
-
|
|
102
|
+
loadSystemModules(),
|
|
106
103
|
createSystemToolHandlers(createSystemRepositories(snapshot), runtime),
|
|
107
104
|
runtime,
|
|
108
105
|
),
|
|
@@ -3,10 +3,7 @@ import {
|
|
|
3
3
|
entitlementKey,
|
|
4
4
|
type FeatureFlagDefinition,
|
|
5
5
|
} from "@southwind-ai/shared";
|
|
6
|
-
import {
|
|
7
|
-
createFoundationSnapshot,
|
|
8
|
-
loadFoundationModules,
|
|
9
|
-
} from "../foundation.js";
|
|
6
|
+
import { createFoundationSnapshot, loadSystemModules } from "../foundation.js";
|
|
10
7
|
import { createServerRuntime } from "../runtime.js";
|
|
11
8
|
import type { RouteApp } from "../system/routes.js";
|
|
12
9
|
import { createSystemRepositories } from "../system/seed.js";
|
|
@@ -42,7 +39,7 @@ class FakeRouteApp implements RouteApp {
|
|
|
42
39
|
function routeFixture(features?: FeatureFlagDefinition[]) {
|
|
43
40
|
const runtime = createServerRuntime({ WINDY_DEV_ADMIN_TOKEN: "token_1" });
|
|
44
41
|
const app = new FakeRouteApp();
|
|
45
|
-
const modules =
|
|
42
|
+
const modules = loadSystemModules();
|
|
46
43
|
if (features) {
|
|
47
44
|
modules[0] = { ...modules[0]!, features };
|
|
48
45
|
}
|
|
@@ -67,7 +64,7 @@ describe("agent routes", () => {
|
|
|
67
64
|
createSystemRepositories(createFoundationSnapshot()),
|
|
68
65
|
runtime,
|
|
69
66
|
);
|
|
70
|
-
const manifestKeys =
|
|
67
|
+
const manifestKeys = loadSystemModules().flatMap((module) =>
|
|
71
68
|
module.tools.map(({ key }) => key),
|
|
72
69
|
);
|
|
73
70
|
|
|
@@ -198,7 +195,7 @@ describe("agent routes", () => {
|
|
|
198
195
|
registerAgentRoutes(
|
|
199
196
|
app,
|
|
200
197
|
new GovernedToolRegistry(
|
|
201
|
-
|
|
198
|
+
loadSystemModules(),
|
|
202
199
|
createSystemToolHandlers(repositories, runtime),
|
|
203
200
|
runtime,
|
|
204
201
|
),
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
import type { ModuleToolHandlers } from "./tool-registry.js";
|
|
3
|
-
import {
|
|
4
|
-
createFoundationSnapshot,
|
|
5
|
-
loadFoundationModules,
|
|
6
|
-
} from "../foundation.js";
|
|
3
|
+
import { createFoundationSnapshot, loadSystemModules } from "../foundation.js";
|
|
7
4
|
import { createServerRuntime } from "../runtime.js";
|
|
8
5
|
import { createSystemRepositories } from "../system/seed.js";
|
|
9
6
|
import { createSystemToolHandlers } from "./routes.js";
|
|
@@ -30,7 +27,7 @@ describe("Governed Tool Registry", () => {
|
|
|
30
27
|
},
|
|
31
28
|
});
|
|
32
29
|
const registry = new GovernedToolRegistry(
|
|
33
|
-
|
|
30
|
+
loadSystemModules(),
|
|
34
31
|
handlers,
|
|
35
32
|
fixture.runtime,
|
|
36
33
|
);
|
|
@@ -56,7 +53,7 @@ describe("Governed Tool Registry", () => {
|
|
|
56
53
|
}),
|
|
57
54
|
});
|
|
58
55
|
const registry = new GovernedToolRegistry(
|
|
59
|
-
|
|
56
|
+
loadSystemModules(),
|
|
60
57
|
invalidOutput,
|
|
61
58
|
fixture.runtime,
|
|
62
59
|
);
|
|
@@ -72,7 +69,7 @@ describe("Governed Tool Registry", () => {
|
|
|
72
69
|
expect(
|
|
73
70
|
() =>
|
|
74
71
|
new GovernedToolRegistry(
|
|
75
|
-
|
|
72
|
+
loadSystemModules(),
|
|
76
73
|
mismatchedScope,
|
|
77
74
|
fixture.runtime,
|
|
78
75
|
),
|
|
@@ -104,7 +101,7 @@ async function createFixture() {
|
|
|
104
101
|
runtime,
|
|
105
102
|
);
|
|
106
103
|
const registry = new GovernedToolRegistry(
|
|
107
|
-
|
|
104
|
+
loadSystemModules(),
|
|
108
105
|
handlers,
|
|
109
106
|
runtime,
|
|
110
107
|
);
|
|
@@ -45,6 +45,12 @@ export function loadFoundationModules(): ModuleManifest[] {
|
|
|
45
45
|
return registry.list();
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
export function loadSystemModules(): ModuleManifest[] {
|
|
49
|
+
const registry = createModuleRegistry();
|
|
50
|
+
for (const factory of systemModuleFactories) registry.register(factory);
|
|
51
|
+
return registry.list();
|
|
52
|
+
}
|
|
53
|
+
|
|
48
54
|
function collectMenus(modules: ModuleManifest[]): MenuNode[] {
|
|
49
55
|
return composeModuleMenus(modules);
|
|
50
56
|
}
|
|
@@ -39,8 +39,11 @@ describe("platform HTTP app observability", () => {
|
|
|
39
39
|
/^[A-Za-z0-9._-]{1,128}$/,
|
|
40
40
|
);
|
|
41
41
|
expect(
|
|
42
|
-
records.filter(
|
|
43
|
-
|
|
42
|
+
records.filter(
|
|
43
|
+
({ event, statusCode }) =>
|
|
44
|
+
event === "http.request.completed" && statusCode === 404,
|
|
45
|
+
),
|
|
46
|
+
).toHaveLength(2);
|
|
44
47
|
expect(observability.metrics.render()).toContain(
|
|
45
48
|
'windy_http_requests_total{method="GET",status_class="4xx"} 2',
|
|
46
49
|
);
|
|
@@ -18,10 +18,7 @@ import {
|
|
|
18
18
|
} from "../agent/routes.js";
|
|
19
19
|
import { GovernedToolRegistry } from "../agent/tool-registry.js";
|
|
20
20
|
import { runGuardedBackgroundTask } from "../background/task-guard.js";
|
|
21
|
-
import {
|
|
22
|
-
createFoundationSnapshot,
|
|
23
|
-
loadFoundationModules,
|
|
24
|
-
} from "../foundation.js";
|
|
21
|
+
import { createFoundationSnapshot, loadSystemModules } from "../foundation.js";
|
|
25
22
|
import {
|
|
26
23
|
evaluateRestrictedHttpRequest,
|
|
27
24
|
licenseRestrictedResponse,
|
|
@@ -266,7 +263,7 @@ function createFixture(
|
|
|
266
263
|
registerAgentRoutes(
|
|
267
264
|
app,
|
|
268
265
|
new GovernedToolRegistry(
|
|
269
|
-
|
|
266
|
+
loadSystemModules(),
|
|
270
267
|
createSystemToolHandlers(repositories, runtime),
|
|
271
268
|
runtime,
|
|
272
269
|
),
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { afterEach, describe, expect, test } from "bun:test";
|
|
2
2
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
3
3
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
4
|
-
import {
|
|
5
|
-
createFoundationSnapshot,
|
|
6
|
-
loadFoundationModules,
|
|
7
|
-
} from "../foundation.js";
|
|
4
|
+
import { createFoundationSnapshot, loadSystemModules } from "../foundation.js";
|
|
8
5
|
import { createServerRuntime } from "../runtime.js";
|
|
9
6
|
import { createSystemRepositories } from "../system/seed.js";
|
|
10
7
|
import { createSystemToolHandlers } from "../agent/routes.js";
|
|
@@ -104,7 +101,7 @@ describe("Platform MCP Adapter", () => {
|
|
|
104
101
|
});
|
|
105
102
|
|
|
106
103
|
function createFixture() {
|
|
107
|
-
const modules =
|
|
104
|
+
const modules = loadSystemModules();
|
|
108
105
|
const runtime = createServerRuntime(
|
|
109
106
|
{},
|
|
110
107
|
{
|
|
@@ -126,13 +126,13 @@ SSE 事件包括 `output.delta`、`tool.requested`、`tool.completed`、usage,
|
|
|
126
126
|
`run.completed`、`run.failed` 或 `run.cancelled` 终态。断线后使用已确认 sequence 作为
|
|
127
127
|
cursor 恢复;不要重新创建 Run 或重复执行 Tool。
|
|
128
128
|
|
|
129
|
-
## 从 create-windy 0.2.
|
|
129
|
+
## 从 create-windy 0.2.25 或更早版本升级
|
|
130
130
|
|
|
131
131
|
先检查计划,再应用连续 recipe:
|
|
132
132
|
|
|
133
133
|
```bash
|
|
134
|
-
bunx --bun create-windy@0.2.
|
|
135
|
-
bunx --bun create-windy@0.2.
|
|
134
|
+
bunx --bun create-windy@0.2.26 update --check
|
|
135
|
+
bunx --bun create-windy@0.2.26 update
|
|
136
136
|
bun install
|
|
137
137
|
```
|
|
138
138
|
|