@coralai/sps-cli 0.65.92 → 0.65.94
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/console/routes/play.d.ts.map +1 -1
- package/dist/console/routes/play.js +24 -2
- package/dist/console/routes/play.js.map +1 -1
- package/dist/providers/serve/servablePath.d.ts +9 -0
- package/dist/providers/serve/servablePath.d.ts.map +1 -0
- package/dist/providers/serve/servablePath.js +53 -0
- package/dist/providers/serve/servablePath.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"play.d.ts","sourceRoot":"","sources":["../../../src/console/routes/play.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"play.d.ts","sourceRoot":"","sources":["../../../src/console/routes/play.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAkBvE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB,8DAA8D;IAC9D,gBAAgB,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAC3C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAmGzD;AAiBD,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,GAAG,IAAI,CAmBtH"}
|
|
@@ -19,10 +19,12 @@
|
|
|
19
19
|
import { createReadStream } from 'node:fs';
|
|
20
20
|
import { stat } from 'node:fs/promises';
|
|
21
21
|
import { extname, join } from 'node:path';
|
|
22
|
+
import { Readable } from 'node:stream';
|
|
22
23
|
import { Hono } from 'hono';
|
|
23
24
|
import { isRealUnderRoot } from '../../core/pathFence.js';
|
|
24
25
|
import { verifyPlayToken } from '../../providers/serve/playToken.js';
|
|
25
26
|
import { servable } from '../../providers/serve/servable.js';
|
|
27
|
+
import { servablePath } from '../../providers/serve/servablePath.js';
|
|
26
28
|
/** Cookie 寿命由 sps 定,**不继承令牌的 5 分钟** —— 否则表现是"玩到第 5 分钟图开始裂"。 */
|
|
27
29
|
const COOKIE_MAX_AGE_S = 60 * 60;
|
|
28
30
|
const COOKIE_NAME = 'sps_play';
|
|
@@ -77,6 +79,12 @@ export function createPlayRoute(deps) {
|
|
|
77
79
|
const raw = at >= 0 ? c.req.path.slice(at + marker.length) : '';
|
|
78
80
|
const rel = raw ? raw.split('/').map(decodeURIComponent).join('/') : 'index.html';
|
|
79
81
|
const target = join(root, rel.endsWith('/') ? `${rel}index.html` : rel);
|
|
82
|
+
// 🔴 **路径判据**(与下面的内容判据是两条,别合并):
|
|
83
|
+
// 只做内容闸不做路径闸的后果实测过 —— `docs/PRD.md` 200 可取,而它是作者的产品设计文档、
|
|
84
|
+
// 31/31 个项目都有、路径可预测。**"内容能不能给"和"这个路径该不该给"是两个问题。**
|
|
85
|
+
const pathBad = servablePath(rel);
|
|
86
|
+
if (pathBad)
|
|
87
|
+
return err(403, 'NOT_SERVABLE', pathBad.detail);
|
|
80
88
|
// 围栏:**realpath 之后**判 —— 项目树里会长出什么由 agent 决定,它自造的软链字符串判据挡不住
|
|
81
89
|
if (!(await isRealUnderRoot(target, root)))
|
|
82
90
|
return err(403, 'NOT_SERVABLE', '路径越出服务根');
|
|
@@ -112,20 +120,34 @@ export function createPlayRoute(deps) {
|
|
|
112
120
|
return c.body(null, 416, { ...headers, 'content-range': `bytes */${st.size}` });
|
|
113
121
|
}
|
|
114
122
|
if (range) {
|
|
115
|
-
const stream = createReadStream(target, { start: range.start, end: range.end });
|
|
123
|
+
const stream = toWeb(createReadStream(target, { start: range.start, end: range.end }));
|
|
116
124
|
return c.body(stream, 206, {
|
|
117
125
|
...headers,
|
|
118
126
|
'content-range': `bytes ${range.start}-${range.end}/${st.size}`,
|
|
119
127
|
'content-length': String(range.end - range.start + 1),
|
|
120
128
|
});
|
|
121
129
|
}
|
|
122
|
-
return c.body(createReadStream(target), 200, {
|
|
130
|
+
return c.body(toWeb(createReadStream(target)), 200, {
|
|
123
131
|
...headers,
|
|
124
132
|
'content-length': String(st.size),
|
|
125
133
|
});
|
|
126
134
|
});
|
|
127
135
|
return app;
|
|
128
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* Node 流 → web 流。
|
|
139
|
+
*
|
|
140
|
+
* 🔴 **不能把 Node 流强转成 `ReadableStream` 塞给 `c.body()`。**
|
|
141
|
+
* 实测(2026-08-19 上线当天):`createReadStream(...) as unknown as ReadableStream` 类型是绿的,
|
|
142
|
+
* 运行时 undici 会抛 `ERR_INVALID_STATE: ReadableStream is already closed`,
|
|
143
|
+
* 而且是**未捕获异常 ⇒ 整个 console 进程退出**(所有租户一起断)。
|
|
144
|
+
* 表现是"**响应先回了 200,然后服务挂掉**" —— 日志里那条 200 让人以为这次请求是成功的。
|
|
145
|
+
* > 判据:**`as unknown as X` 是把类型系统关掉,不是把类型改对。**
|
|
146
|
+
* > 它压掉的那个错误会原地变成运行时错误,而运行时错误的落点可能比编译错误远得多。
|
|
147
|
+
*/
|
|
148
|
+
function toWeb(stream) {
|
|
149
|
+
return Readable.toWeb(stream);
|
|
150
|
+
}
|
|
129
151
|
/** 只支持单段 `bytes=a-b` / `bytes=a-` / `bytes=-n`。多段不支持 —— 回 null 当整份发,不是错。 */
|
|
130
152
|
export function parseRange(header, size) {
|
|
131
153
|
if (!header)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"play.js","sourceRoot":"","sources":["../../../src/console/routes/play.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"play.js","sourceRoot":"","sources":["../../../src/console/routes/play.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"servablePath.d.ts","sourceRoot":"","sources":["../../../src/providers/serve/servablePath.ts"],"names":[],"mappings":"AA4BA,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAErE;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAiB9D"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module providers/serve/servablePath
|
|
3
|
+
* @description **服务**路的**路径**判据。与 `servable`(内容判据)是**两条**,分开命名。
|
|
4
|
+
*
|
|
5
|
+
* @layer providers
|
|
6
|
+
*
|
|
7
|
+
* 🔴 **补这条的原因是一个真实的洞**(studio 2026-08-19 实测):
|
|
8
|
+
* 我先做了内容闸(拒归档)就以为服务面守住了 —— 而 `docs/PRD.md` **能取到 200**,
|
|
9
|
+
* studio 自己的 `/play` 对同一路径是 404。
|
|
10
|
+
* `docs/PRD.md` 是作者的产品设计文档,**31/31 个项目都有、路径可预测**。
|
|
11
|
+
* > 判据:**"内容能不能给"和"这个路径该不该给"是两个问题** ——
|
|
12
|
+
* > 一个归档判据全绿,不代表这个文件属于游戏运行时。
|
|
13
|
+
*
|
|
14
|
+
* 🔴 方向:服务面**怕多发**(与发布同侧,与同步相反)⇒ 用**拒绝名单 + 结构性规则**,
|
|
15
|
+
* 宁可拦错也不放过;拦错的表现是"少一个文件"(看得见),放过的表现是**内容被带走**(看不见)。
|
|
16
|
+
*
|
|
17
|
+
* ⚠️ 名单会过期 —— 配套的是**拒绝时把路径报出去**,不是"尽量列全"。
|
|
18
|
+
*/
|
|
19
|
+
import { extname } from 'node:path';
|
|
20
|
+
/** 顶层目录:不是游戏运行时需要的东西。 */
|
|
21
|
+
const BLOCKED_TOP_DIRS = new Set(['docs', 'memory', 'scripts', 'node_modules', 'test', 'tests']);
|
|
22
|
+
/** 具名文件:agent/作者的指令与内部产物,不该被玩家取走。 */
|
|
23
|
+
const BLOCKED_NAMES = new Set([
|
|
24
|
+
'claude.md', 'agents.md', 'template.md', 'readme.md',
|
|
25
|
+
'package.json', 'package-lock.json', 'tsconfig.json',
|
|
26
|
+
]);
|
|
27
|
+
/**
|
|
28
|
+
* @param rel 相对**服务根**的路径(已归一,不含前导斜杠)
|
|
29
|
+
*/
|
|
30
|
+
export function servablePath(rel) {
|
|
31
|
+
if (!rel)
|
|
32
|
+
return { code: 'PATH_BLOCKED', detail: '空路径' };
|
|
33
|
+
const segs = rel.split('/');
|
|
34
|
+
for (const s of segs) {
|
|
35
|
+
if (!s || s === '..')
|
|
36
|
+
return { code: 'PATH_BLOCKED', detail: `非法路径段:${rel}` };
|
|
37
|
+
// 🔴 承重条款:`.claude/` `.sps/` `.git/` 全靠这一条。
|
|
38
|
+
// 将来谁为了 `.well-known/` 放宽它,会在不知情下把这道门整个打开。
|
|
39
|
+
if (s.startsWith('.'))
|
|
40
|
+
return { code: 'PATH_BLOCKED', detail: `点开头路径段:${rel}` };
|
|
41
|
+
}
|
|
42
|
+
if (BLOCKED_TOP_DIRS.has(segs[0])) {
|
|
43
|
+
return { code: 'PATH_BLOCKED', detail: `${segs[0]}/ 不是运行时内容:${rel}` };
|
|
44
|
+
}
|
|
45
|
+
const base = segs.at(-1).toLowerCase();
|
|
46
|
+
if (BLOCKED_NAMES.has(base))
|
|
47
|
+
return { code: 'PATH_BLOCKED', detail: `内部文件:${rel}` };
|
|
48
|
+
// `.md` 一律不服务:游戏运行时不需要 markdown,而作者文档大多是 md
|
|
49
|
+
if (extname(base) === '.md')
|
|
50
|
+
return { code: 'PATH_BLOCKED', detail: `markdown 不属于运行时:${rel}` };
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=servablePath.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"servablePath.js","sourceRoot":"","sources":["../../../src/providers/serve/servablePath.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,yBAAyB;AACzB,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AACjG,qCAAqC;AACrC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;IAC5B,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW;IACpD,cAAc,EAAE,mBAAmB,EAAE,eAAe;CACrD,CAAC,CAAC;AAIH;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACzD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI;YAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,GAAG,EAAE,EAAE,CAAC;QAC9E,4CAA4C;QAC5C,8CAA8C;QAC9C,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,UAAU,GAAG,EAAE,EAAE,CAAC;IAClF,CAAC;IACD,IAAI,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAW,CAAC,EAAE,CAAC;QAC5C,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,aAAa,GAAG,EAAE,EAAE,CAAC;IACxE,CAAC;IACD,MAAM,IAAI,GAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAY,CAAC,WAAW,EAAE,CAAC;IACnD,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,GAAG,EAAE,EAAE,CAAC;IACpF,4CAA4C;IAC5C,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,KAAK;QAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,mBAAmB,GAAG,EAAE,EAAE,CAAC;IAC/F,OAAO,IAAI,CAAC;AACd,CAAC"}
|