# 本地归档接入验证(2026-09-12) 本轮把 `E:\归档`(约 90 GB / 45,055 个文件 / 4,937 个目录)接入本项目:四十条精选档案改为由真实归档生成,新增 **LOCAL ARCHIVE** 面板做全量检索与安全写操作。 实现说明见 [`../docs/LOCAL-ARCHIVE.md`](../docs/LOCAL-ARCHIVE.md),数据维护见 [`../content/README.md`](../content/README.md)。 ## 新增与改动 | 文件 | 类型 | 说明 | | --- | --- | --- | | `archive.config.json` | 新增 | 归档根目录、端口、索引与日志位置 | | `content/curated.mjs` | 新增 | 四十条档案的手写部分与对应的真实 `path` | | `scripts/archive-source.mjs` | 新增 | 扫描归档,生成 `archives.json`、`archive-index.json`、40 个 TXT | | `scripts/archive-service.mjs` | 新增 | 回环服务:令牌、路径围栏、检索、读写操作、目录监视 | | `scripts/archive-dev.mjs` | 新增 | 一条命令同时启动服务与 Vite | | `src/archive-service.ts` | 新增 | 浏览器端客户端,含静态快照降级 | | `src/archive-panel.ts` | 新增 | 检索与归档操作面板 | | `src/archive-panel.css` | 新增 | 面板样式,全部走 `--theme-*` 变量 | | `scripts/archive-content.mjs` | 改动 | `source` 接受 `file:`;TXT 模板改为归档口径 | | `src/main.ts` | 改动 | 导航新增 LOCAL ARCHIVE 按钮、点击分支、面板实例化;详情页 EXPORT 下载改为 SHOW IN FOLDER 定位 | | `src/data.ts` | 改动 | `ArchiveRecord` 增加可选的 `path` 与 `stats`(生成物写入的真实归档信息) | | `src/style.css`、`src/responsive.css` | 改动 | `.export-button` 改为双语按钮并加宽;新增被截断的 `.detail-path` | | `vite.config.ts` | 改动 | `server`/`preview` 增加 `/archive-api` 代理并注入令牌 | | `package.json` | 改动 | 新增 `dev:archive`、`archive:snapshot`、`archive:serve`;钩子改跑 `archive-source.mjs` | | `.gitignore` | 改动 | 忽略 `.archive-token` | | `content/README.md` | 改动 | 说明 `archives.json` 现在是生成物;`path` 的两个用途 | | `docs/LOCAL-ARCHIVE.md`、`verification/ARCHIVE-INTEGRATION.md` | 新增 | 用法、安全边界与实测记录 | **没有改动的**:`src/scene.ts`、`src/archive-loop.ts` 与阵列数学。五列、每列八份、`X-0NN` 稳定编号的约束原样保留,`archive-content.mjs` 的三条硬校验(五分类 / 四十条 / 每类八条)未放宽。 ## 证据 ### 1. 数据校验与构建 ``` $ npm run check:content ℹ tests 18 ℹ pass 18 ℹ fail 0 $ npx tsc --noEmit exit=0 $ npm run build 归档快照已更新:40 条精选档案,45055 个文件 / 4937 个目录 / 90.03 GB dist/assets/index-KZVOVeb_.js 993.68 kB │ gzip: 301.66 kB ✓ built in 2.48s Offline release 22cf358e6368842a: 818 files, 33.8 MiB. build exit=0 ``` `check:content` 的 18 项包含"下载 TXT 与 `archiveText` 逐字节一致(含 BOM)",即 40 个 TXT 与 `archives.json` 同步;放宽 `source` 协议后,`rejects unsafe URL`(`javascript:`)与 `rejects invalid URL`(`example.com`)两项仍如期失败,说明放宽没有引入注入面。 ### 2. 服务接口实测 | 用例 | 结果 | | --- | --- | | 无令牌 `GET /status` | `401`,正确拒绝 | | `GET /status` | `{"root":"E:\\归档","watching":true,"totals":{"files":45055,"dirs":4937,...},"sevenZip":true}` | | `POST /open {"path":"../Windows/system.ini"}` | `403`(越界拦截) | | `POST /reveal {"path":"C:\\Windows\\win.ini"}` | `403`(绝对路径拦截) | | `POST /open {"path":"不存在的目录/foo.txt"}` | `404` | | `POST /plan {"op":"mkdir"}` → `apply` | `blocked=null`,目录创建成功 | | `POST /plan {"op":"move"}` → `apply` | `files=1 bytes=18`,移动成功,源消失 | | 目标已存在时 `plan move` | `blocked="目标已存在,请换一个名字"` | | `plan move` 到 `D:\` | `403`(目标越界拦截) | | `POST /plan {"op":"extract","from":"07_日志与排查/LOG.7z"}` → `apply` | 解出 4 个文件,与包内条目数一致 | | `POST /apply` 缺少 `confirm` | `400`,且未创建任何目录 | | `GET /index`(gzip) | 7,767,411 字节 → 698,629 字节(约 9 倍) | | `POST /refresh` | 返回新的快照时间 | 操作日志按预期落盘: ```json {"at":"2026-09-12T02:10:44.855Z","op":"mkdir","from":null,"to":"_测试_归档操作","result":"ok"} {"at":"2026-09-12T02:10:44.872Z","op":"move","from":"_测试源文件.txt","to":"_测试_归档操作/测试源文件.txt","result":"ok"} {"at":"2026-09-12T02:10:44.946Z","op":"extract","from":"07_日志与排查/LOG.7z","to":"_测试_归档操作/LOG_解压","result":"ok"} ``` 测试产物已全部删除,归档中已无 `_测试_*` 条目。 ### 3. 自动更新 在归档根新建 `_自动更新测试.txt`,**不调用任何刷新接口**,等待 8 秒后检索: ``` 索引命中 1 条:_自动更新测试.txt 最近一次快照:09/12/2026 02:11:06 ``` 删除该文件后再次等待,快照随之更新为 `02:11:14`。递归监视器与防抖重生生效。 ### 4. 开发链路 ``` $ npm run dev 归档快照已更新:40 条精选档案,45055 个文件 / 4937 个目录 / 90.03 GB VITE v7.3.6 ready in 426 ms ➜ Local: http://127.0.0.1:5174/ (5173 已被占用) GET http://127.0.0.1:5174/ → 200, text/html GET http://127.0.0.1:5174/archive-api/status → 200, 返回真实 status(令牌由代理注入) GET http://127.0.0.1:5174/archive-api/search?q=runs.7z → 命中 2 条,含 01_人工智能/01_训练产物/runs.7z GET http://127.0.0.1:5174/archive-index.json → 200(静态降级路径可用) GET http://127.0.0.1:5174/src/archive-panel.ts → 200, 57,329 字节(Vite 转译无错) GET http://127.0.0.1:5174/src/archive-service.ts → 200, 15,727 字节 ``` ### 5. 产物复核 ``` dist/assets/index-KZVOVeb_.js : LOCAL ARCHIVE / local-archive / la-surface / archive-index.json / archive-api / 正在检测归档服务 全部命中 dist/assets/index-DeuQtmYI.css : .la-surface 命中 dist/archives/*.txt : 40 个 dist/archive-index.json : 7.41 MB(未进入 PWA 预缓存,818 files / 33.8 MiB 与改动前同量级) ``` ### 6. 详情页 EXPORT 改为定位文件位置 按用户要求,详情页右下角的 EXPORT(下载 TXT)改为 **SHOW IN FOLDER / 文件位置**:直接用该档案的真实 `path` 调 `/reveal`,在资源管理器中打开其所在位置。 改动点: - `src/main.ts:513` 的 `` 换成 `