@deepseek-ai/dsh-host-frontend-static 0.1.6-alpha.1 → 0.1.7-alpha.1

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.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/host/frontend-static/README.md
5
- README.md: e616c048119fc1ce75ad29b002c3298b84169af9
6
- README.zh.md: 6cf55bb6d82f665754767f0a8c5b9cc68d8236d6
5
+ README.md: e9bf19b48acfbc8c1513b2b64226e17faf1dc2de
6
+ README.zh.md: 3021d6de08c6ab04732389423d0ae96846992dfe
package/README.md CHANGED
@@ -41,6 +41,8 @@ Compose this plugin in a browser-facing host that serves the built Web shell: it
41
41
 
42
42
  Requests are served from the dist root (the directory containing `distIndex`). The dist root and the configured index path render `index.html` with HTTP 200; any other existing file is served directly with its MIME type, and unknown extensions ship as `application/octet-stream`. A path that resolves outside the root is rejected with 403, so a crafted path cannot read files above the dist. An absent or non-file target inside the dist root — a missing file, a directory, or a missing configured index — returns an empty 404. Non-GET/HEAD requests without a matching named route are answered 405. Every successful index response is rendered through the webserver's `renderIndex`, so the boot manifest reaches the page on `/` and on the configured index path.
43
43
 
44
+ The served HTML carries one document base, `<base href="./">`, ahead of every injected resource row, so it freezes the entry directory the page was loaded from: the shell's own app-directory-relative references and the Host's plugin-resource rows both resolve under the mount that served the page. The same index therefore serves the origin root and whatever mount a prefix-stripping proxy owns; this plugin renders it only for the dist root and the configured index path.
45
+
44
46
  Root and configured-index responses call `ctx.connection.authorizeIndex` before reading HTML. A valid process token receives a 303 redirect plus the persistent browser cookie; an existing valid cookie serves the index; every other index request receives the Connection-owned 401 response. Non-index files remain public static assets. Connection owns the token, cookie, expiry, and signing-record semantics.
45
47
 
46
48
  ### Observable failures
@@ -57,7 +59,7 @@ Traversal returns 403 rather than an error page. An absent or non-file target in
57
59
 
58
60
  ### Design concept
59
61
 
60
- The package is one function plugin around `serveStatic`: `apply` resolves the dist root from `distIndex`, builds a `renderIndex` closure that runs `ctx.webServer.renderIndex` over the raw `index.html`, and registers the fallback handler under an effect scope. The seat is single-owner by the webserver's contract — a second registration throws — and effect-scoped, so disposing the fiber releases the seat.
62
+ The package is one function plugin around `serveStatic`: `apply` resolves the dist root from `distIndex`, builds a `renderIndex` closure that runs `ctx.webServer.renderIndex` over the raw `index.html` and splices the document base in after the opening head tag (after the raw taps, so it precedes their markup too), and registers the fallback handler under an effect scope. The seat is single-owner by the webserver's contract — a second registration throws — and effect-scoped, so disposing the fiber releases the seat.
61
63
 
62
64
  ### The traversal fence
63
65
 
package/README.zh.md CHANGED
@@ -41,6 +41,8 @@ kind: "package-reference"
41
41
 
42
42
  请求从 dist 根目录(包含 `distIndex` 的目录)提供。dist 根目录与配置的 index 路径以 HTTP 200 渲染 `index.html`;任何其他已有文件按自身 MIME 类型直接提供,未知扩展名按 `application/octet-stream` 提供。解析到根目录之外的路径以 403 拒绝,因此精心构造的路径无法读取 dist 之上的文件。dist 根目录内不存在或不是文件的目标——文件缺失、目录或配置的 index 缺失——返回空 404。没有匹配具名路由的非 GET/HEAD 请求返回 405。每个成功的 index 响应都经 webserver 的 `renderIndex` 渲染,因此启动 manifest(元数据清单)会通过 `/` 与配置的 index 路径送达页面。
43
43
 
44
+ 所服务的 HTML 携带唯一的文档 base `<base href="./">`,位于每一条注入资源行之前,因此它冻结页面加载时所处的入口目录:shell 自身的应用目录相对引用与宿主的插件资源行都在服务该页面的挂载下解析。同一份 index 因而既服务源站根目录,也服务剥离前缀的代理所拥有的任一挂载;本插件只为 dist 根目录与配置的 index 路径渲染它。
45
+
44
46
  根路径与配置的 index 响应会在读取 HTML 前调用 `ctx.connection.authorizeIndex`。有效进程 token 会得到 303 重定向与持久浏览器 cookie;已有有效 cookie 时直接提供 index;其他 index 请求得到 Connection 所有的 401 响应。非 index 文件仍是公开静态资源。Token、cookie、过期时间与签名记录语义都归 Connection 所有。
45
47
 
46
48
  ### 可观察的失败
@@ -57,7 +59,7 @@ kind: "package-reference"
57
59
 
58
60
  ### 设计理念
59
61
 
60
- 本包是围绕 `serveStatic` 的一个函数插件:`apply` 从 `distIndex` 解析出 dist 根目录,构建一个对原始 `index.html` 运行 `ctx.webServer.renderIndex` 的 `renderIndex` 闭包,并在 effect 作用域下注册回退 handler。按 webserver 的约定,席位只有单一所有者——第二次注册会抛错——且受 effect 作用域约束,因此 dispose fiber 即释放席位。
62
+ 本包是围绕 `serveStatic` 的一个函数插件:`apply` 从 `distIndex` 解析出 dist 根目录,构建一个对原始 `index.html` 运行 `ctx.webServer.renderIndex` 并把文档 base 拼接在起始 head 标签之后的 `renderIndex` 闭包(在原始转换之后执行,因此也先于其标记),并在 effect 作用域下注册回退 handler。按 webserver 的约定,席位只有单一所有者——第二次注册会抛错——且受 effect 作用域约束,因此 dispose fiber 即释放席位。
61
63
 
62
64
  ### 遍历栅栏
63
65
 
package/lib/index.js CHANGED
@@ -82,7 +82,7 @@ function apply(ctx, config) {
82
82
  const distIndex = config.distIndex;
83
83
  const distRoot = dirname(distIndex);
84
84
  const renderIndex = async () => {
85
- return ctx.webServer.renderIndex(await readFile(distIndex, "utf8")).replace(/<head(?:\s[^>]*)?>/i, (open) => `${open}<base href="/">`);
85
+ return ctx.webServer.renderIndex(await readFile(distIndex, "utf8")).replace(/<head(?:\s[^>]*)?>/i, (open) => `${open}<base href="./">`);
86
86
  };
87
87
  ctx.effect(() => ctx.webServer.registerFallback(async (req, res) => {
88
88
  if (req.method !== "GET" && req.method !== "HEAD") {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-host-frontend-static",
3
3
  "description": "SPA dist server for the Web shell: owns the webserver fallback seat, serving explicit index entries and static assets with traversal rejection and 404 misses",
4
- "version": "0.1.6-alpha.1",
4
+ "version": "0.1.7-alpha.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -27,18 +27,18 @@
27
27
  ],
28
28
  "license": "MIT",
29
29
  "peerDependencies": {
30
- "@deepseek-ai/dsh-host-webserver": "^0.1.6-alpha.1",
31
- "@deepseek-ai/dsh-client-connection": "^0.1.6-alpha.1",
32
- "@deepseek-ai/cordis": "^4.0.2"
30
+ "@deepseek-ai/dsh-host-webserver": "^0.1.7-alpha.1",
31
+ "@deepseek-ai/dsh-client-connection": "^0.1.7-alpha.1",
32
+ "@deepseek-ai/cordis": "^4.0.3"
33
33
  },
34
34
  "dependencies": {
35
- "@deepseek-ai/schemastery": "^3.18.2"
35
+ "@deepseek-ai/schemastery": "^3.18.3"
36
36
  },
37
37
  "devDependencies": {
38
- "@deepseek-ai/cordis-plugin-loader": "^1.0.3",
39
- "@deepseek-ai/dsh-client-connection": "^0.1.6-alpha.1",
40
- "@deepseek-ai/dsh-credentials-local": "^0.1.6-alpha.1",
41
- "@deepseek-ai/dsh-host-webserver": "^0.1.6-alpha.1",
42
- "@deepseek-ai/cordis": "^4.0.2"
38
+ "@deepseek-ai/cordis-plugin-loader": "^1.0.4",
39
+ "@deepseek-ai/dsh-client-connection": "^0.1.7-alpha.1",
40
+ "@deepseek-ai/dsh-credentials-local": "^0.1.7-alpha.1",
41
+ "@deepseek-ai/dsh-host-webserver": "^0.1.7-alpha.1",
42
+ "@deepseek-ai/cordis": "^4.0.3"
43
43
  }
44
44
  }