@coralai/sps-plugin-storage-sync 0.2.1 → 0.3.0

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.
@@ -1,26 +1,41 @@
1
- export type SyncRejection = {
2
- code: 'ABSOLUTE';
3
- rel: string;
4
- } | {
5
- code: 'DOT_SEGMENT';
6
- rel: string;
7
- } | {
8
- code: 'PARENT_SEGMENT';
9
- rel: string;
10
- } | {
11
- code: 'EMPTY_SEGMENT';
12
- rel: string;
13
- } | {
14
- code: 'ESCAPES_PROJECT';
15
- rel: string;
16
- };
17
1
  /**
18
- * 纯字符串这一半(**不含**软链检查 —— 那半必须走 `isRealUnderRoot`)。
2
+ * @module providers/storage/syncable
3
+ * @description **同步**这条路的安全下限。设计见 `object-storage-and-workspace-sync.md` §2.1 第五条。
4
+ *
5
+ * @layer providers
6
+ *
7
+ * 🔴🔴 **它与发布的下限方向相反,别互相抄。**
8
+ * ```
9
+ * 发布 publishable() 怕**多发** —— 树里会长出什么由 agent 决定,黑名单追不上 ⇒ **后缀白名单**
10
+ * 同步 syncable() 怕**少发** —— 用户会放 .blend / .psd / .aseprite ⇒ **不能用后缀白名单**
11
+ * ```
12
+ * 抄错方向的表现是:**用户的源文件不见了,而且不报错**。
13
+ * (「照搬一份现成的安全规则」恰恰是最容易顺手抄整份的时候。)
14
+ *
15
+ * 🔴 **声明决定"要什么",本模块决定"绝不给什么"** —— 后者不是产品知识,是主体安全,
16
+ * 且**不可被声明或配置放宽**。它防的是一件具体的事:项目树里有带活 token 的
17
+ * `.claude/settings.local.json`(实测:coral 那侧 `publishable('src/main.js')` 放行,
18
+ * 而 `readFile` 实际拿到 `ANTHROPIC_AUTH_TOKEN=sk-live-…`,落点还是公开可取的前缀)。
19
+ *
20
+ * 🔴 **真正拦住凭据的是"任一路径段以 `.` 开头"这一条**,不是别的:
21
+ * `settings.local.json` 本身后缀无害,是 `.claude/` 这个点开头段拦住的。
22
+ * ⇒ 将来谁"为了支持 `.well-known/` 放宽点开头",会在不知情的情况下把底线整个打开。
23
+ * > 判据:**守卫要标注它靠哪一条在生效** —— 否则放宽的人以为自己在动一条无关的规则。
24
+ */
25
+ import { type SyncRejection as ShapeRejection, syncableShape } from '@coralai/sps-plugin-api';
26
+ export { syncableShape };
27
+ /**
28
+ * 完整的拒绝理由 = **形状**(契约包那 4 个)+ **围栏**(这一个)。
19
29
  *
20
- * 单独抽出来不是为了复用,是为了让**两半都必须被调用**这件事在类型上看得见:
21
- * 只调这一半的实现会"看起来对",而它恰恰漏掉了唯一挡得住 agent 自造软链的那道。
30
+ * ⚠️ 两者不该合并进契约包:形状是纯字符串判断,任何地方都能算;
31
+ * `ESCAPES_PROJECT` realpath、要项目根,是**运行时**的结果。
32
+ * 合进去会让"只调形状那一半"看起来像完整判据 —— 而那正是漏掉软链的写法。
22
33
  */
23
- export declare function syncableShape(rel: string): SyncRejection | null;
34
+ export type SyncRejection = ShapeRejection | {
35
+ code: 'ESCAPES_PROJECT';
36
+ rel: string;
37
+ };
38
+ export type SyncRejectCode = SyncRejection['code'];
24
39
  /**
25
40
  * 完整判据 = 形状 + **realpath 围栏**。
26
41
  *
package/dist/syncable.js CHANGED
@@ -22,29 +22,11 @@
22
22
  * ⇒ 将来谁"为了支持 `.well-known/` 放宽点开头",会在不知情的情况下把底线整个打开。
23
23
  * > 判据:**守卫要标注它靠哪一条在生效** —— 否则放宽的人以为自己在动一条无关的规则。
24
24
  */
25
- import { isRealUnderRoot } from '@coralai/sps-plugin-api';
26
- /**
27
- * 纯字符串这一半(**不含**软链检查 —— 那半必须走 `isRealUnderRoot`)。
28
- *
29
- * 单独抽出来不是为了复用,是为了让**两半都必须被调用**这件事在类型上看得见:
30
- * 只调这一半的实现会"看起来对",而它恰恰漏掉了唯一挡得住 agent 自造软链的那道。
31
- */
32
- export function syncableShape(rel) {
33
- if (!rel)
34
- return { code: 'EMPTY_SEGMENT', rel };
35
- if (rel.startsWith('/'))
36
- return { code: 'ABSOLUTE', rel };
37
- for (const seg of rel.split('/')) {
38
- if (!seg)
39
- return { code: 'EMPTY_SEGMENT', rel };
40
- if (seg === '..')
41
- return { code: 'PARENT_SEGMENT', rel };
42
- // ← 承重的是这条:`.claude/`、`.git/`、`.sps/` 全靠它
43
- if (seg.startsWith('.'))
44
- return { code: 'DOT_SEGMENT', rel };
45
- }
46
- return null;
47
- }
25
+ import { isRealUnderRoot, syncableShape, } from '@coralai/sps-plugin-api';
26
+ // 🔴 形状判据的真源在 `@coralai/sps-plugin-api` —— **两个地方要用同一份**:
27
+ // 这里(同步时判每个文件)与宿主(写 sync-scope 声明时判每条 include)。
28
+ // 各写一份的话,写入口放行的声明会在同步时被静默挡掉,而配置的人看不到。
29
+ export { syncableShape };
48
30
  /**
49
31
  * 完整判据 = 形状 + **realpath 围栏**。
50
32
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coralai/sps-plugin-storage-sync",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "工作区 → 对象存储同步:把节点本地盘上的用户产物搬到共享面(S3 兼容桶)。",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -28,7 +28,7 @@
28
28
  "access": "public"
29
29
  },
30
30
  "dependencies": {
31
- "@coralai/sps-plugin-api": "^0.14.0"
31
+ "@coralai/sps-plugin-api": "^0.16.0"
32
32
  },
33
33
  "optionalDependencies": {
34
34
  "minio": "^8.0.7"