- commit
- bf1e3db
- parent
- c42fb56
- author
- im_wower
- date
- 2026-03-30 03:11:17 +0800 CST
fix: restore artifact repo root fallback
2 files changed,
+34,
-6
+26,
-0
1@@ -4269,6 +4269,10 @@ test("handleConductorHttpRequest serves artifact files and robots.txt", async ()
2 const { repository, snapshot } = await createLocalApiFixture();
3
4 await withArtifactStoreFixture(async ({ artifactStore }) => {
5+ const repoDir = join(artifactStore.getArtifactsDir(), "repo", "demo-repo");
6+ mkdirSync(repoDir, { recursive: true });
7+ writeFileSync(join(repoDir, "log.html"), "<html><body>demo repo home</body></html>\n");
8+
9 await artifactStore.insertMessage({
10 conversationId: "conv_artifact",
11 id: "msg_artifact",
12@@ -4354,6 +4358,28 @@ test("handleConductorHttpRequest serves artifact files and robots.txt", async ()
13 assert.equal(sessionLatestResponse.status, 200);
14 assert.match(Buffer.from(sessionLatestResponse.body).toString("utf8"), /session_artifact/u);
15
16+ const repoIndexResponse = await handleConductorHttpRequest(
17+ {
18+ method: "GET",
19+ path: "/artifact/repo/demo-repo"
20+ },
21+ context
22+ );
23+ assert.equal(repoIndexResponse.status, 200);
24+ assert.match(repoIndexResponse.headers["content-type"], /^text\/html\b/u);
25+ assert.match(Buffer.from(repoIndexResponse.body).toString("utf8"), /demo repo home/u);
26+
27+ const repoLogResponse = await handleConductorHttpRequest(
28+ {
29+ method: "GET",
30+ path: "/artifact/repo/demo-repo/log.html"
31+ },
32+ context
33+ );
34+ assert.equal(repoLogResponse.status, 200);
35+ assert.match(repoLogResponse.headers["content-type"], /^text\/html\b/u);
36+ assert.match(Buffer.from(repoLogResponse.body).toString("utf8"), /demo repo home/u);
37+
38 const missingResponse = await handleConductorHttpRequest(
39 {
40 method: "GET",
1@@ -405,21 +405,23 @@ const LOCAL_API_ROUTES: LocalApiRouteDefinition[] = [
2 pathPattern: "/robots.txt",
3 summary: "返回允许 AI 访问 /artifact/ 的 robots.txt"
4 },
5+ // Keep the repo route ahead of the generic artifact route so repo root URLs
6+ // can fall back to log.html instead of being claimed by the generic matcher.
7 {
8- id: "service.artifact.read",
9+ id: "service.artifact.repo",
10 exposeInDescribe: false,
11 kind: "read",
12 method: "GET",
13- pathPattern: "/artifact/:artifact_scope/:artifact_file",
14- summary: "读取 artifact 静态文件"
15+ pathPattern: "/artifact/repo/:repo_name/*",
16+ summary: "读取 stagit 生成的 git 仓库静态页面"
17 },
18 {
19- id: "service.artifact.repo",
20+ id: "service.artifact.read",
21 exposeInDescribe: false,
22 kind: "read",
23 method: "GET",
24- pathPattern: "/artifact/repo/:repo_name/*",
25- summary: "读取 stagit 生成的 git 仓库静态页面"
26+ pathPattern: "/artifact/:artifact_scope/:artifact_file",
27+ summary: "读取 artifact 静态文件"
28 },
29 {
30 id: "service.code.read",