openfeel 1.3.2 → 1.3.3

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.
Files changed (54) hide show
  1. package/README.en.md +1 -0
  2. package/README.md +2 -1
  3. package/README.zh-CN.md +1 -0
  4. package/dist/commands/flow.d.ts.map +1 -1
  5. package/dist/commands/flow.js +98 -14
  6. package/dist/commands/flow.js.map +1 -1
  7. package/dist/commands/instructions.js +1 -1
  8. package/dist/commands/instructions.js.map +1 -1
  9. package/dist/commands/plan.d.ts.map +1 -1
  10. package/dist/commands/plan.js +9 -1
  11. package/dist/commands/plan.js.map +1 -1
  12. package/dist/core/archive/merge.js +8 -8
  13. package/dist/core/archive/merge.js.map +1 -1
  14. package/dist/core/artifact-graph/resolver.d.ts.map +1 -1
  15. package/dist/core/artifact-graph/resolver.js +8 -0
  16. package/dist/core/artifact-graph/resolver.js.map +1 -1
  17. package/dist/core/config.d.ts +12 -0
  18. package/dist/core/config.d.ts.map +1 -1
  19. package/dist/core/config.js +25 -3
  20. package/dist/core/config.js.map +1 -1
  21. package/dist/core/flow-manager.d.ts +26 -1
  22. package/dist/core/flow-manager.d.ts.map +1 -1
  23. package/dist/core/flow-manager.js +112 -9
  24. package/dist/core/flow-manager.js.map +1 -1
  25. package/dist/core/i18n-data/en.d.ts.map +1 -1
  26. package/dist/core/i18n-data/en.js +12 -0
  27. package/dist/core/i18n-data/en.js.map +1 -1
  28. package/dist/core/i18n-data/zh-CN.d.ts.map +1 -1
  29. package/dist/core/i18n-data/zh-CN.js +12 -0
  30. package/dist/core/i18n-data/zh-CN.js.map +1 -1
  31. package/dist/core/plan/stage.d.ts.map +1 -1
  32. package/dist/core/plan/stage.js +3 -1
  33. package/dist/core/plan/stage.js.map +1 -1
  34. package/dist/core/template-loader.d.ts.map +1 -1
  35. package/dist/core/template-loader.js +29 -18
  36. package/dist/core/template-loader.js.map +1 -1
  37. package/dist/core/update.d.ts.map +1 -1
  38. package/dist/core/update.js +16 -5
  39. package/dist/core/update.js.map +1 -1
  40. package/dist/core/view/entry.d.ts +13 -4
  41. package/dist/core/view/entry.d.ts.map +1 -1
  42. package/dist/core/view/entry.js +40 -16
  43. package/dist/core/view/entry.js.map +1 -1
  44. package/dist/core/workspace/structure.d.ts +21 -1
  45. package/dist/core/workspace/structure.d.ts.map +1 -1
  46. package/dist/core/workspace/structure.js +30 -11
  47. package/dist/core/workspace/structure.js.map +1 -1
  48. package/dsh/ADAPTER.md +14 -7
  49. package/dsh/README.md +3 -3
  50. package/dsh/lib/adapters/dashboard.js +2 -2
  51. package/dsh/lib/guard.js +78 -11
  52. package/dsh/lib/tools/shared.js +28 -14
  53. package/dsh/package.json +2 -2
  54. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../src/core/view/entry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../src/core/view/entry.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,27 @@
3
3
  */
4
4
  export declare function ensureDir(path: string): void;
5
5
  /**
6
- * 创建 .openfeel/ 完整目录结构
6
+ * 核心必需目录(init 时创建;被 flow / plan / kb / dev 模板直接依赖)。
7
+ * v1.3.3 P2-4:由 10 个固定目录瘦身为 4 核心 + 6 惰性,降低冷启动前置开销。
8
+ */
9
+ export declare const CORE_WORKSPACE_DIRS: readonly ["plan", "kb", "dev", "log"];
10
+ /**
11
+ * 惰性目录:首次使用时按需 `mkdir -p`(写路径已有/新增 `ensureLazyDir` 兜底)。
12
+ * 不参与 init 冷启动;缺失不视为工作区损坏。
13
+ */
14
+ export declare const LAZY_WORKSPACE_DIRS: readonly ["code_review", "bugs", "users", "tmp", "manual", "update_conflicts"];
15
+ /**
16
+ * 惰性目录清单(导出供 lint / 文档 / 测试复用)。
17
+ */
18
+ export declare const WORKSPACE_LAZY_DIRS: readonly string[];
19
+ /**
20
+ * 按需确保 `.openfeel/{name}` 惰性目录存在(幂等;仅接受 LAZY_WORKSPACE_DIRS 内的名字)。
21
+ * 供写路径在首次落盘前调用;未知目录名直接忽略(防御,不建任意目录)。
22
+ */
23
+ export declare function ensureLazyDir(projectPath: string, name: string): void;
24
+ /**
25
+ * 创建 .openfeel/ 目录结构(核心必需 + dev 子目录;惰性目录不建)。
26
+ * @returns 本次新建的目录相对路径列表(既有目录不重复计入)
7
27
  */
8
28
  export declare function createWorkspace(projectPath: string): string[];
9
29
  //# sourceMappingURL=structure.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"structure.d.ts","sourceRoot":"","sources":["../../../src/core/workspace/structure.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAI5C;AAuBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CA8B7D"}
1
+ {"version":3,"file":"structure.d.ts","sourceRoot":"","sources":["../../../src/core/workspace/structure.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAI5C;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,uCAAwC,CAAC;AAEzE;;;GAGG;AACH,eAAO,MAAM,mBAAmB,gFAOtB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAAwB,CAAC;AAS1E;;;GAGG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAKrE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CA8B7D"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * 工作区目录创建
3
- * 负责创建项目下的 .openfeel/ 完整目录结构。
3
+ * 负责创建项目下的 .openfeel/ 目录结构(v1.3.3 P2-4:核心必需 + 其余惰性)。
4
4
  */
5
5
  import { mkdirSync, existsSync } from 'node:fs';
6
6
  import { resolve } from 'node:path';
@@ -12,19 +12,27 @@ export function ensureDir(path) {
12
12
  mkdirSync(path, { recursive: true });
13
13
  }
14
14
  }
15
- /** .openfeel/ 下的子目录清单 */
16
- const WORKSPACE_DIRS = [
17
- 'plan',
18
- 'kb',
19
- 'dev',
20
- 'log',
15
+ /**
16
+ * 核心必需目录(init 时创建;被 flow / plan / kb / dev 模板直接依赖)。
17
+ * v1.3.3 P2-4:由 10 个固定目录瘦身为 4 核心 + 6 惰性,降低冷启动前置开销。
18
+ */
19
+ export const CORE_WORKSPACE_DIRS = ['plan', 'kb', 'dev', 'log'];
20
+ /**
21
+ * 惰性目录:首次使用时按需 `mkdir -p`(写路径已有/新增 `ensureLazyDir` 兜底)。
22
+ * 不参与 init 冷启动;缺失不视为工作区损坏。
23
+ */
24
+ export const LAZY_WORKSPACE_DIRS = [
21
25
  'code_review',
22
26
  'bugs',
23
27
  'users',
24
28
  'tmp',
25
29
  'manual',
26
- 'update_conflicts', // 新增:update 冲突文件目录
30
+ 'update_conflicts',
27
31
  ];
32
+ /**
33
+ * 惰性目录清单(导出供 lint / 文档 / 测试复用)。
34
+ */
35
+ export const WORKSPACE_LAZY_DIRS = LAZY_WORKSPACE_DIRS;
28
36
  /**
29
37
  * dev/ 下的子目录清单
30
38
  * - `note`:团队共享开发笔记
@@ -32,7 +40,18 @@ const WORKSPACE_DIRS = [
32
40
  */
33
41
  const DEV_SUB_DIRS = ['note', 'current_archive'];
34
42
  /**
35
- * 创建 .openfeel/ 完整目录结构
43
+ * 按需确保 `.openfeel/{name}` 惰性目录存在(幂等;仅接受 LAZY_WORKSPACE_DIRS 内的名字)。
44
+ * 供写路径在首次落盘前调用;未知目录名直接忽略(防御,不建任意目录)。
45
+ */
46
+ export function ensureLazyDir(projectPath, name) {
47
+ if (!LAZY_WORKSPACE_DIRS.includes(name)) {
48
+ return;
49
+ }
50
+ ensureDir(resolve(projectPath, '.openfeel', name));
51
+ }
52
+ /**
53
+ * 创建 .openfeel/ 目录结构(核心必需 + dev 子目录;惰性目录不建)。
54
+ * @returns 本次新建的目录相对路径列表(既有目录不重复计入)
36
55
  */
37
56
  export function createWorkspace(projectPath) {
38
57
  const base = resolve(projectPath, '.openfeel');
@@ -42,8 +61,8 @@ export function createWorkspace(projectPath) {
42
61
  mkdirSync(base, { recursive: true });
43
62
  created.push('.openfeel/');
44
63
  }
45
- // 创建子目录
46
- for (const dir of WORKSPACE_DIRS) {
64
+ // 创建核心子目录
65
+ for (const dir of CORE_WORKSPACE_DIRS) {
47
66
  const fullPath = resolve(base, dir);
48
67
  if (!existsSync(fullPath)) {
49
68
  mkdirSync(fullPath, { recursive: true });
@@ -1 +1 @@
1
- {"version":3,"file":"structure.js","sourceRoot":"","sources":["../../../src/core/workspace/structure.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED,yBAAyB;AACzB,MAAM,cAAc,GAAG;IACrB,MAAM;IACN,IAAI;IACJ,KAAK;IACL,KAAK;IACL,aAAa;IACb,MAAM;IACN,OAAO;IACP,KAAK;IACL,QAAQ;IACR,kBAAkB,EAAG,mBAAmB;CACzC,CAAC;AAEF;;;;GAIG;AACH,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAEjD;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,UAAU;IACV,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC7B,CAAC;IAED,QAAQ;IACR,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,aAAa,GAAG,GAAG,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,eAAe;IACf,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACrC,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,iBAAiB,MAAM,GAAG,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"structure.js","sourceRoot":"","sources":["../../../src/core/workspace/structure.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAU,CAAC;AAEzE;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,aAAa;IACb,MAAM;IACN,OAAO;IACP,KAAK;IACL,QAAQ;IACR,kBAAkB;CACV,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAsB,mBAAmB,CAAC;AAE1E;;;;GAIG;AACH,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAEjD;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,WAAmB,EAAE,IAAY;IAC7D,IAAI,CAAE,mBAAyC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/D,OAAO;IACT,CAAC;IACD,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,UAAU;IACV,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC7B,CAAC;IAED,UAAU;IACV,KAAK,MAAM,GAAG,IAAI,mBAAmB,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,aAAa,GAAG,GAAG,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,eAAe;IACf,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACrC,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,iBAAiB,MAAM,GAAG,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
package/dsh/ADAPTER.md CHANGED
@@ -28,16 +28,23 @@ OpenFeel 采用「核心层 + 适配器层」架构(`claude/`、`kilo/`、`.op
28
28
  - **不解析**中文文本:优先消费 `--json`;失败读 `error.kind` / `error.code` / `error.detail`。
29
29
  - **不 shadow** 既有能力:DSH 已有的 `subagent` / `workflow` / `todo_write` 照常使用;
30
30
  `feel_next` 只给「该谁做」,实际派发交给 DSH。
31
- - **写入门禁**(v1.3.2):用 DSH `ctx.tools.guard()` 同步拒绝 `edit` / `write` / `apply_patch` /
32
- `str_replace_editor`;`.openfeel/**` 流程产物任意阶段可写(flow.json / `status.md` 除外),
33
- `.openfeel/` 外源码要求 `exec_running`。`pwsh` / `bash` 默认不守,是显式逃生通道;
34
- `enforce=always`(默认)对非 OpenFeel 工作区也拦截,可用 `project` / `off` opt-out。
31
+ - **写入门禁**(v1.3.3):用 DSH `ctx.tools.guard()` 同步拒绝 `edit` / `write` / `apply_patch` /
32
+ `str_replace_editor`;`.openfeel/**` 流程产物任意阶段可写(flow.json / `status.md` 除外)。
33
+ v1.3.3 起按**风险分层**:
34
+ - **bootstrap 例外**:工作区无 `.openfeel/` 时,全部目标为「新增文件」(`apply_patch` 还要求全部为
35
+ `*** Add File:`)→ 放行并提示补账本;已存在文件、`.openfeel/**`、Update/Delete/Move 仍拒绝;
36
+ - **doc/note 不绑相位**:`docs/**` 与 `.md/.mdx/.txt/.rst/.adoc` 在无活跃阶段或非 `exec_running`
37
+ 相位也可写;**混合目标从严**(任一源码 → 按源码规则);
38
+ - 源码(`src/**` 等)仍要求 `exec_running`;`pwsh` / `bash` 默认不守,是显式逃生通道;
39
+ - `enforce=always`(默认)对非 OpenFeel 工作区也拦截,可用 `project` / `off` opt-out。
40
+ - **审查归属**(v1.3.3):REV 可挂 op(`stageId.op-xxx`)或挂 stage(`op = stageId`,无 op 的 fast 场景);
41
+ stage 级 REV 参与 blocking 门,但**不参与** `flow attempt` / `flow retry`。
35
42
 
36
43
  ## 目录
37
44
 
38
45
  | 路径 | 内容 |
39
46
  |---|---|
40
- | `lib/guard.js` | 写入门禁:`enforce`、`.openfeel/**` 产物区、`exec_running`、apply_patch 目标解析 |
47
+ | `lib/guard.js` | 写入门禁:`enforce`、`.openfeel/**` 产物区、bootstrap 新增放行、doc/note 分层、apply_patch 目标解析 |
41
48
  | [`ACTION-GUIDE.md`](ACTION-GUIDE.md) | **给 OpenFeel 本体的操作指南**:剩余 5 项待办、验收标准、边界约定 |
42
49
  | `lib/index.js` | 插件入口(`name` / `inject` / `apply` / `normalizeConfig`) |
43
50
  | `lib/adapters/cli.js` | CLI 执行器:可执行文件解析、UTF-8/无色/无日志、退出码与 envelope 语义 |
@@ -47,7 +54,7 @@ OpenFeel 采用「核心层 + 适配器层」架构(`claude/`、`kilo/`、`.op
47
54
  | `lib/tools/shared.js` | 输出封装、参数编译、渲染 |
48
55
  | `lib/surface/command.js` | `/feel` 人类命令 |
49
56
  | `lib/surface/prompt.js` | `<feel_mode>` 系统提示段 |
50
- | `test/` | 契约 / 行为 / 门禁 / 真实注册表 四套验证(42 + 83 + 36 + 10 = 171 断言) |
57
+ | `test/` | 契约 / 行为 / 门禁 / 真实注册表 四套验证(42 + 83 + 46 + 10 = 181 断言) |
51
58
  | `docs/compat/` | OpenFeel v1.2.1 逆向兼容性契约(6 份;仅供回归参照,权威以 [docs/json-contract.md](https://github.com/Liuary/OpenFeel/blob/master/docs/json-contract.md) 为准) |
52
59
 
53
60
  ## 验证
@@ -56,7 +63,7 @@ OpenFeel 采用「核心层 + 适配器层」架构(`claude/`、`kilo/`、`.op
56
63
  cd dsh
57
64
  node test/contract.js # 42 — DSH schema 契约(真实 assertSupportedJsonSchema)
58
65
  node test/verify.js # 83 — 行为(真实 CLI + 真实 .openfeel 副本)
59
- node test/guard.js # 36 — 写入门禁(fake ToolExecution + 临时工作区)
66
+ node test/guard.js # 46 — 写入门禁(fake ToolExecution + 临时工作区)
60
67
  node test/integration.js # 10 — 真实 cordis + 真实 ToolRuntime 挂载
61
68
  ```
62
69
 
package/dsh/README.md CHANGED
@@ -196,14 +196,14 @@ provider 桥接层会把「只有 description、没有 type」的节点转成 `t
196
196
 
197
197
  ---
198
198
 
199
- ## 6.5 写入门禁(v1.3.2)
199
+ ## 6.5 写入门禁(v1.3.3)
200
200
 
201
201
  适配器在 `apply()` 中用 DSH 的 `ctx.tools.guard()` 注册同步守卫(`dsh/lib/guard.js`):
202
202
 
203
203
  - **只守** `edit` / `write` / `apply_patch` / `str_replace_editor`。`feel_*`、`pwsh`、`read`、`todo_write` 等不受影响。
204
204
  - `.openfeel/**` 是**流程产物区**:plan / scheme / review 产物在任意阶段可写;但 `.openfeel/flow.json` 与 `.openfeel/**/status.md` **始终拒绝**(用 `feel_*`)。受保护路径按**会话工作区 `<cwd>`** 判定;执行阶段仍可编辑其他项目的 `.openfeel/`(不做跨项目全局保护)。
205
- - `.openfeel/` 外的源码/文档:要求存在 `exec_running` 阶段;无活跃阶段或相位不符时拒绝,消息带 phase 与 `feel_flow action=advance` 建议。
206
- - 无 `.openfeel/`:`enforce=always` 拒绝所有文件写入(含 `.openfeel/plan`,防止绕过 init);`project`/`off` 放行。
205
+ - **v1.3.3 风险分层**——源码(`src/**` 等)仍要求存在 `exec_running` 阶段;**doc/note**(`docs/**` 与 `.md/.mdx/.txt/.rst/.adoc`)在无活跃阶段或非 `exec_running` 相位也放行;**混合目标从严**(任一源码 → 按源码规则)。
206
+ - **bootstrap 例外(v1.3.3)**:无 `.openfeel/` 时,全部目标为**新增文件**(`apply_patch` 须全部 `*** Add File:`)→ 放行并提示补账本;已存在文件、`.openfeel/**`、Update/Delete/Move 仍拒绝(`enforce=always` 下)。`project`/`off` 放行。
207
207
  - `apply_patch` 解析所有 patch 头(`*** Update/Add/Delete File:`、`*** Move to:`、`---/+++`);全部目标在 `.openfeel/**` 才内部放行,混合/无头保守拒绝。
208
208
  - `enforce=off` **完全不注册 guard**(连 flow.json/status.md 也不拦)。
209
209
  - `ctx.tools.guard` 缺失时记警告并降级;`ctx.effect` 负责 disposer,避免 HMR 累积。
@@ -191,7 +191,7 @@ export async function readSnapshot(cli, options = {}) {
191
191
  /** 相位标签由 `flow next` 下发;无权威值时退化为相位名(不维护本地映射)。 */
192
192
  phaseLabel: typeof next?.phaseLabel === 'string' ? next.phaseLabel : focusPhase,
193
193
  status: focusStage?.status ?? '',
194
- deps: Array.isArray(focusStage?.deps) ? focusStage.deps : [],
194
+ deps: Array.isArray(focusStage?.deps) ? [...focusStage.deps] : [],
195
195
  ops: focusStage?.ops ?? {},
196
196
  checkpoint: CHECKPOINT_OF_PHASE[focusPhase] ?? '',
197
197
  /** 负责该相位的 Agent(CLI 权威字段;无 flow next 时为 unknown)。 */
@@ -229,7 +229,7 @@ export async function readSnapshot(cli, options = {}) {
229
229
  id: stage.id ?? stage.name ?? '',
230
230
  phase: stage.phase ?? '',
231
231
  status: stage.status ?? '',
232
- deps: Array.isArray(stage.deps) ? stage.deps : [],
232
+ deps: Array.isArray(stage.deps) ? [...stage.deps] : [],
233
233
  workflowMode: stage.workflowMode ?? stage.workflow_mode ?? null,
234
234
  requirementId: stage.requirementId ?? null,
235
235
  reviewTier: stage.reviewTier ?? null,
package/dsh/lib/guard.js CHANGED
@@ -14,8 +14,8 @@
14
14
  * @module openfeel-dsh/guard
15
15
  */
16
16
 
17
- import { readFileSync, statSync } from 'node:fs';
18
- import { basename, join, resolve } from 'node:path';
17
+ import { existsSync, readFileSync, statSync } from 'node:fs';
18
+ import { basename, extname, join, resolve } from 'node:path';
19
19
 
20
20
  import { isProjectWorkspace, OPENFEEL_DIR } from './adapters/workspace.js';
21
21
 
@@ -40,6 +40,35 @@ export function normalizeForComparison(value, platform = process.platform) {
40
40
  return platform === 'win32' || platform === 'darwin' ? value.toLowerCase() : value;
41
41
  }
42
42
 
43
+ /** 文档/笔记类扩展名(写门禁按产物类型分层:doc/note 不绑相位)。 */
44
+ export const DOC_EXTENSIONS = Object.freeze(['.md', '.mdx', '.txt', '.rst', '.adoc']);
45
+
46
+ /**
47
+ * 是否为文档/笔记类目标(P0-4):扩展名命中,或位于**工作区根级 `docs/`** 下。
48
+ * v1.3.3 复核:`docs` 必须直接位于会话工作区下(`src/docs/x.ts` 不算文档,防源码借名绕过相位门)。
49
+ * 仅用于「放行 doc/note」;源代码仍按 `exec_running` 严格判定。
50
+ * @param {string} absolute 已归一化绝对路径
51
+ * @param {string} cwd 已归一化工作区
52
+ * @returns {boolean}
53
+ */
54
+ function isDocPath(absolute, cwd) {
55
+ if (DOC_EXTENSIONS.includes(extname(absolute).toLowerCase())) return true;
56
+ const docsRoot = normalizeTarget(cwd, 'docs');
57
+ return absolute === docsRoot
58
+ || absolute.startsWith(`${docsRoot}\\`)
59
+ || absolute.startsWith(`${docsRoot}/`);
60
+ }
61
+
62
+ /**
63
+ * 是否位于工作区内(bootstrap 例外边界;防 `..`/绝对路径写出工作区)。
64
+ * @param {string} absolute 已归一化绝对路径
65
+ * @param {string} cwd 已归一化工作区
66
+ * @returns {boolean}
67
+ */
68
+ function isUnderWorkspace(absolute, cwd) {
69
+ return absolute === cwd || absolute.startsWith(`${cwd}\\`) || absolute.startsWith(`${cwd}/`);
70
+ }
71
+
43
72
  /** flow.json 读取缓存(path → { mtimeMs, size, value })。 */
44
73
  const flowCache = new Map();
45
74
 
@@ -120,22 +149,32 @@ function extractPatchText(args) {
120
149
  }
121
150
 
122
151
  /**
123
- * 解析 apply_patch 的全部目标路径。
152
+ * 解析 apply_patch 的全部目标路径与变更类型。
124
153
  *
125
154
  * 只认 patch 头,避免正文里出现 `.openfeel/` 被误判。支持:
126
155
  * - `*** Update File:`, `*** Add File:`, `*** Delete File:`
127
156
  * - `*** Move to:`(要求同块 `*** Update File:` 源,否则拒绝)
128
157
  * - `--- a/path`, `+++ b/path`;忽略 `/dev/null`
129
158
  *
159
+ * 返回 `entries`(路径 + kind)供 bootstrap 例外判定「是否纯新增」:
160
+ * kind ∈ `add | update | delete | move`;同一路径出现多种 kind 时从严记 `update`。
161
+ *
130
162
  * @param {string} patch
131
- * @returns {{ ok: true, paths: string[] } | { ok: false, reason: string }}
163
+ * @returns {{ ok: true, paths: string[], entries: Array<{ path: string, kind: string }> } | { ok: false, reason: string }}
132
164
  */
133
165
  export function parsePatchTargets(patch) {
134
166
  const paths = [];
167
+ const kinds = new Map();
135
168
  const seen = new Set();
136
- const add = (raw) => {
169
+ const add = (raw, kind) => {
137
170
  const value = cleanPatchPath(raw);
138
171
  if (value === '' || value === '/dev/null') return;
172
+ const prev = kinds.get(value);
173
+ if (prev === undefined) {
174
+ kinds.set(value, kind);
175
+ } else if (prev !== kind) {
176
+ kinds.set(value, 'update'); // 同路径混合 kind → 从严(bootstrap 例外不成立)
177
+ }
139
178
  if (seen.has(value)) return;
140
179
  seen.add(value);
141
180
  paths.push(value);
@@ -147,19 +186,19 @@ export function parsePatchTargets(patch) {
147
186
  const update = /^\*\*\* Update File:\s*(.+?)\s*$/.exec(line);
148
187
  if (update !== null) {
149
188
  currentBlock = 'update';
150
- add(update[1]);
189
+ add(update[1], 'update');
151
190
  continue;
152
191
  }
153
192
  const addFile = /^\*\*\* Add File:\s*(.+?)\s*$/.exec(line);
154
193
  if (addFile !== null) {
155
194
  currentBlock = 'add';
156
- add(addFile[1]);
195
+ add(addFile[1], 'add');
157
196
  continue;
158
197
  }
159
198
  const deleteFile = /^\*\*\* Delete File:\s*(.+?)\s*$/.exec(line);
160
199
  if (deleteFile !== null) {
161
200
  currentBlock = 'delete';
162
- add(deleteFile[1]);
201
+ add(deleteFile[1], 'delete');
163
202
  continue;
164
203
  }
165
204
  const move = /^\*\*\* Move to:\s*(.+?)\s*$/.exec(line);
@@ -167,7 +206,7 @@ export function parsePatchTargets(patch) {
167
206
  if (currentBlock !== 'update') {
168
207
  return { ok: false, reason: '*** Move to: 缺少同块 *** Update File: 源路径' };
169
208
  }
170
- add(move[1]);
209
+ add(move[1], 'move');
171
210
  continue;
172
211
  }
173
212
  if (/^\*\*\* (?:Begin|End) Patch/.test(line)) {
@@ -175,13 +214,13 @@ export function parsePatchTargets(patch) {
175
214
  continue;
176
215
  }
177
216
  const diff = /^(?:---|\+\+\+) [ab]\/(.+?)\s*$/.exec(line);
178
- if (diff !== null) add(diff[1]);
217
+ if (diff !== null) add(diff[1], 'update');
179
218
  }
180
219
 
181
220
  if (paths.length === 0) {
182
221
  return { ok: false, reason: '无法从 patch 头确定目标路径' };
183
222
  }
184
- return { ok: true, paths };
223
+ return { ok: true, paths, entries: paths.map((path) => ({ path, kind: kinds.get(path) })) };
185
224
  }
186
225
 
187
226
  /**
@@ -253,6 +292,8 @@ export function createOpenFeelGuard(options = {}) {
253
292
  const fallbackCwd = typeof options.cwd === 'string' && options.cwd !== '' ? options.cwd : undefined;
254
293
 
255
294
  const t = (zh, en) => (english ? en : zh);
295
+ /** bootstrap 例外提示去重(按工作区路径)。 */
296
+ const bootstrapHinted = new Set();
256
297
 
257
298
  if (enforce === 'off') {
258
299
  // 完全关闭:连 flow.json/status.md 也不拦。
@@ -270,6 +311,7 @@ export function createOpenFeelGuard(options = {}) {
270
311
  const normalizedCwd = normalizeForComparison(resolvedCwd);
271
312
 
272
313
  let rawTargets;
314
+ let patchEntries = null;
273
315
  if (name === 'apply_patch') {
274
316
  const patch = extractPatchText(execution?.arguments);
275
317
  if (patch === undefined) {
@@ -286,6 +328,7 @@ export function createOpenFeelGuard(options = {}) {
286
328
  );
287
329
  }
288
330
  rawTargets = parsed.paths;
331
+ patchEntries = parsed.entries;
289
332
  } else {
290
333
  rawTargets = extractArgumentPaths(execution?.arguments);
291
334
  if (rawTargets.length === 0) {
@@ -297,6 +340,7 @@ export function createOpenFeelGuard(options = {}) {
297
340
  }
298
341
 
299
342
  const targets = rawTargets.map((target) => normalizeTarget(resolvedCwd, target));
343
+ const allDoc = targets.every((target) => isDocPath(target, normalizedCwd));
300
344
 
301
345
  // 受保护路径:guard 启用时始终拒绝(enforce=off 已提前返回)。
302
346
  if (targets.some((target) => isProtectedPath(target, normalizedCwd))) {
@@ -309,6 +353,25 @@ export function createOpenFeelGuard(options = {}) {
309
353
  const initialized = isProjectWorkspace(resolvedCwd);
310
354
  if (!initialized) {
311
355
  if (enforce === 'always') {
356
+ // P0-1 bootstrap 例外:空工作区 + 全部为「新增文件」→ 放行(最高风险等级不成立)。
357
+ // apply_patch 额外要求全部 block 为 `*** Add File:`(Update/Delete/Move/混合一律从严)。
358
+ // `.openfeel/**` 不适用:流程产物仍要求先 init(B8)。
359
+ const allNew = targets.every((target) => !existsSync(target));
360
+ const anyInternal = targets.some((target) => isUnderOpenFeel(target, normalizedCwd));
361
+ const allInside = targets.every((target) => isUnderWorkspace(target, normalizedCwd));
362
+ const addOnly = patchEntries === null || patchEntries.every((entry) => entry.kind === 'add');
363
+ if (allNew && addOnly && !anyInternal && allInside) {
364
+ if (!bootstrapHinted.has(normalizedCwd)) {
365
+ bootstrapHinted.add(normalizedCwd);
366
+ process.stderr.write(
367
+ `${t(
368
+ 'OpenFeel 写入门禁:[bootstrap] 工作区尚未初始化,已放行本次新增文件;建议稍后运行 `openfeel init` 补账本。',
369
+ 'OpenFeel write guard: [bootstrap] workspace not initialized; this new-file write was allowed. Run `openfeel init` later to record it.',
370
+ )}\n`,
371
+ );
372
+ }
373
+ return undefined;
374
+ }
312
375
  return t(
313
376
  'OpenFeel 写入门禁:当前工作区尚未初始化 OpenFeel(无 `.openfeel/`)。请先运行 `openfeel init` 并建立需求/阶段;或让用户把 profile 的 `enforce` 改为 `project` / `off`。',
314
377
  'OpenFeel write guard: this workspace is not OpenFeel-initialized (no `.openfeel/`). Run `openfeel init` and create a requirement/stage first; or ask the user to set `enforce` to `project` / `off`.',
@@ -331,6 +394,8 @@ export function createOpenFeelGuard(options = {}) {
331
394
  const active = activeStages(flow.value);
332
395
  if (active.length === 0) {
333
396
  if (allowGeneral && hasGeneralRequirement(flow.value)) return undefined;
397
+ // P0-4:doc/note 类产物不要求活跃阶段(收口后仍可写文档);混合目标从严。
398
+ if (allDoc) return undefined;
334
399
  return t(
335
400
  'OpenFeel 写入门禁:当前无活跃阶段,不能修改源码/文档。请先 feel_req add → claim → feel_stage add 建立阶段。',
336
401
  'OpenFeel write guard: no active stage, so source/docs are read-only. Create a stage via feel_req add → claim → feel_stage add.',
@@ -338,6 +403,8 @@ export function createOpenFeelGuard(options = {}) {
338
403
  }
339
404
 
340
405
  if (active.some((stage) => stage.phase === 'exec_running')) return undefined;
406
+ // P0-4:非 exec 相位仍允许 doc/note(研究记录、设计文档等);代码仍严格。
407
+ if (allDoc) return undefined;
341
408
 
342
409
  const summary = active
343
410
  .map((stage) => `${stage.id ?? '(unknown)'}=${stage.phase ?? '(unknown)'}`)
@@ -188,26 +188,40 @@ export function toWireEnvelope(action, payload) {
188
188
  }
189
189
 
190
190
  /**
191
- * 安全序列化:处理循环引用与不可序列化值,永不抛错。
191
+ * 安全序列化:只对**真环**(祖先路径上出现过的对象)写 `[循环引用]`;
192
+ * 同一对象的**重复引用**(DAG,如 focus.deps 与 stages[i].deps 指向同一数组)正常复制(P1-2)。
193
+ * 兼处理 BigInt / 不可序列化值,永不抛错。
192
194
  * @param {unknown} value
193
195
  * @returns {string}
194
196
  */
195
197
  export function stringifySafe(value) {
196
198
  try {
197
- /** @type {WeakSet<object>} */
198
- const seen = new WeakSet();
199
- return JSON.stringify(
200
- value,
201
- (_key, item) => {
202
- if (typeof item === 'object' && item !== null) {
203
- if (seen.has(item)) return '[循环引用]';
204
- seen.add(item);
199
+ /**
200
+ * @param {unknown} item
201
+ * @param {WeakSet<object>} ancestors
202
+ * @returns {unknown}
203
+ */
204
+ const clone = (item, ancestors) => {
205
+ if (typeof item === 'bigint') return item.toString();
206
+ if (typeof item === 'function' || typeof item === 'symbol') return undefined;
207
+ if (typeof item !== 'object' || item === null) return item;
208
+ // 保留 Date / URL 等自带 toJSON 的语义(与 JSON.stringify 一致)
209
+ if (typeof item.toJSON === 'function') return item.toJSON();
210
+ if (ancestors.has(item)) return '[循环引用]';
211
+ ancestors.add(item);
212
+ let out;
213
+ if (Array.isArray(item)) {
214
+ out = item.map((entry) => clone(entry, ancestors));
215
+ } else {
216
+ out = {};
217
+ for (const [key, entry] of Object.entries(item)) {
218
+ out[key] = clone(entry, ancestors);
205
219
  }
206
- if (typeof item === 'bigint') return item.toString();
207
- return item;
208
- },
209
- 2,
210
- );
220
+ }
221
+ ancestors.delete(item);
222
+ return out;
223
+ };
224
+ return JSON.stringify(clone(value, new WeakSet()), null, 2);
211
225
  } catch {
212
226
  return String(value);
213
227
  }
package/dsh/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openfeel-dsh",
3
- "version": "1.3.2",
3
+ "version": "1.3.3",
4
4
  "description": "OpenFeel × DSH — Feel 模式适配器:把 OpenFeel 的流水线、需求分发、版本归档与知识库接入 DeepSeek Harness",
5
5
  "type": "module",
6
6
  "private": true,
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "openfeel": {
34
34
  "adapter": "dsh",
35
- "requiresCli": ">=1.3.2"
35
+ "requiresCli": ">=1.3.3"
36
36
  },
37
37
  "keywords": [
38
38
  "openfeel",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openfeel",
3
- "version": "1.3.2",
3
+ "version": "1.3.3",
4
4
  "description": "AI Agent 开发流程治理 CLI 工具",
5
5
  "type": "module",
6
6
  "private": false,