@fooksky/lodestar 0.2.2 → 0.2.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.
package/README.md CHANGED
@@ -1,74 +1,41 @@
1
1
  # Lodestar
2
2
 
3
- Lodestar 是 DeepSeek Harness(DSH)的开发工作流插件,让 Agent 从需求确认、方案评审、实施授权,一直推进到验证和交付,并通过项目内的材料与结构化状态恢复工作。
3
+ Lodestar 是 DeepSeek Harness(DSH)的开发工作流插件,帮助 Agent 确认需求、评审方案、获得实施授权,再执行、验证和交付。项目内的文档与结构化状态让工作可恢复;仅设计任务也能记录设计交付。
4
4
 
5
5
  ## 提供什么
6
6
 
7
- - **`dev-workflow` skill**:指导需求澄清、设计取舍、授权判断、任务组织和验收。
7
+ - **`lodestar` skill**:指导需求澄清、设计取舍、授权判断、任务组织和验收。
8
8
  - **`lodestar_change` 工具**:维护 change 的文档版本、决定、验收项、执行引用、验证记录及流程状态,校验阶段前置条件。
9
- - **可选“开发工作流”preset**:为新会话提供流程入口,默认关闭,复用部署已有的原生工具。
9
+ - **可选「Lodestar · 开发工作流」模式**:为会话添加流程提示,复用部署已有工具与 Teams,默认关闭。
10
10
 
11
- 写代码、运行测试和分工协作使用 DSH 原生工具与 Agent Teams。Lodestar 不承担跨需求调度,不创建或切换分支,也不自动提交、推送或发布。工具校验记录的结构和关联;用户授权的含义及证据是否足以支持交付仍由 Lead 判断。
11
+ 模式是提示适配器,不会安装工具、复制 profile、选择模型或扩大权限。写代码、测试和协作使用 DSH 原生能力;授权的含义与证据是否充分由 Lead 判断。Lodestar 不创建分支、不跨需求调度,也不自动提交、推送或发布。
12
12
 
13
13
  ## 开始使用
14
14
 
15
- 包名为 `@fooksky/lodestar`,通过 DSH 的插件管理安装并启用核心插件。运行需要 Node.js 24+、Git,以及提供文件、工作目录和 subprocess 等服务的兼容 DSH 宿主;版本要求见 [package.json](package.json)。
15
+ 通过 DSH 的插件管理安装 `@fooksky/lodestar` 并启用核心插件。需要 Node.js 24+、Git,以及提供文件、工作目录和 subprocess 服务的兼容 DSH 宿主;兼容版本见 [package.json](package.json)。
16
16
 
17
- 在会话中加载 `dev-workflow` skill,再用自然语言说明目标,例如:
17
+ 在会话中加载 `lodestar` skill,再说明目标:
18
18
 
19
19
  > 帮我设计并实现这个功能:……
20
20
  >
21
- > 继续 change `20261108-example`,先检查当前状态和未完成事项。
21
+ > 继续 change `20261108-example`,先检查状态和未完成事项。
22
22
  >
23
23
  > 这次只需要设计方案,先不要实施。
24
24
 
25
- 核心流程可在兼容会话中直接使用。也可启用可选 preset,在新会话开始前选择“开发工作流”;已有会话通过加载 skill 进入流程。选择 preset 本身不构成实施授权。
25
+ 若需要模式入口,进入侧栏「插件」→「已安装」→ `@fooksky/lodestar` 详情,在「包含的组件」中启用默认关闭的 `dev-workflow-preset`,再于新会话开始前选择「Lodestar · 开发工作流」。已有会话可直接加载 skill;选择模式本身不构成实施授权。支持模式指南的宿主可展示「模式说明 / 如何使用」;旧宿主会忽略指南字段,仍可阅读随包文档。完整步骤、能力要求与恢复方法见 [使用指南:模式说明 / 如何使用](skills/dev-workflow/USER_GUIDE.md)。
26
26
 
27
27
  ## 材料与工作区
28
28
 
29
- 默认一个独立需求对应一个 change、一条分支、一个 worktree 和一个 Lead。用户或外部助手先准备工作区;代码、知识、change 材料和需保留的证据均在本 worktree 内维护。
29
+ 默认一个独立需求对应一个 change、一条分支、一个 worktree 和一个 Lead。由用户或外部助手先准备工作区;代码、知识、change 材料和需保留的证据均在本 worktree 内维护。
30
30
 
31
- 材料保存在项目的 `.dev-docs/changes/<change-id>/`:
31
+ 材料保存在 `.dev-docs/changes/<change-id>/`:`intent.md` 记录真实需求,`spec.md` 记录方案与验收,实施授权后才创建 `plan.md`;`state.json` 由工具维护版本与关联。仅设计交付不需要实施计划。工具接受 `schemaVersion: 2`,旧格式或损坏记录会报错,不自动迁移或修复。
32
32
 
33
- ```text
34
- intent.md 真实需求与范围
35
- spec.md 方案与验收要求
36
- plan.md 实施计划与交付材料
37
- state.json 工具维护的状态、版本和关联
38
- ```
39
-
40
- Lead 按阶段编写正文,`lodestar_change` 原子更新状态,并复用项目已有的 `.dev-docs/index.md` 和 `knowledge/`。状态仅接受 `schemaVersion: 2`,旧格式或损坏记录会明确报错,不自动迁移或修复。
41
-
42
- ## 状态工具
43
-
44
- 每次调用显式提供 `projectRoot`。Git 项目根必须与调用 Agent 的工作目录属于同一 checkout;普通目录项目根必须位于 Agent 工作目录内。
45
-
46
- | Action | 用途 |
47
- |---|---|
48
- | `workspace` | 观察当前工作区、分支及 HEAD |
49
- | `list` | 分页列出 change 及其阶段、状态和绑定情况 |
50
- | `get` | 读取 change 或指定部分,检查文档一致性和阻塞项 |
51
- | `create` | 创建 change 并绑定当前工作区 |
52
- | `update` | 使用 `expectedRevision` 原子提交有类型的领域操作 |
53
-
54
- 例如,调用 `lodestar_change` 观察已准备的工作区,再创建 change:
33
+ 每次调用 `lodestar_change` 显式传入 `projectRoot`。Git 项目根须与调用 Agent 的工作目录属于同一 checkout,普通目录须位于 Agent 工作目录内。`workspace` 观察工作区,`list` 和 `get` 读取状态,`create` 创建 change,`update` 以 `expectedRevision` 原子提交领域操作。
55
34
 
56
35
  ```json
57
36
  {"action":"workspace","projectRoot":"."}
58
37
  ```
59
38
 
60
- ```json
61
- {"action":"create","projectRoot":".","changeId":"20261108-example","title":"示例需求"}
62
- ```
63
-
64
- 文档登记、分支重绑及恢复规则见 [skill](skills/dev-workflow/SKILL.md) 和 [工作区参考](skills/dev-workflow/references/workspace.md);确切参数以 [工具 schema](src/schema.js) 为准。
65
-
66
- ## 项目文档
67
-
68
- - [仓库开发约定](AGENTS.md):开发环境、宿主接口边界、验证及发布流程。
69
- - [分支与 worktree 隔离设计](docs/branch-management.md):当前工作区与持久绑定契约。
70
- - [首版设计](docs/design.md) 与 [提案](docs/proposal.md):设计背景和历史范围。
71
- - [场景清单](tests/scenarios.md):真实模型授权理解、Team 协作和中断恢复的行为验收。
72
- - [Agent 角色调查](docs/research/agent-presets.md)、[开发模式调查](docs/research/development-mode.md)、[工作流调研](docs/research/workflow-survey.md) 与 [会话成本案例](docs/research/labwarden-session-cost.md)。
39
+ 流程规则见 [skill](skills/dev-workflow/SKILL.md),工作区规则见 [工作区参考](skills/dev-workflow/references/workspace.md),确切参数见 [工具 schema](src/schema.js)。
73
40
 
74
- 采用 [MIT 许可证](LICENSE)。[GitHub 源码仓库](https://github.com/urzz/lodestar) 为私有仓库,npm 包公开分发;包内源码、skill 和文档均可公开下载。
41
+ 采用 [MIT 许可证](LICENSE)。[GitHub 源码仓库](https://github.com/urzz/lodestar) 为私有仓库,npm 包公开分发;维护约定、历史设计与测试材料保留在源码仓库,不随包分发。
package/index.js CHANGED
@@ -14,7 +14,7 @@ export async function apply(ctx) {
14
14
  ...references.map(name => readFile(new URL(`references/${name}.md`, resourceDirectory), 'utf8')),
15
15
  ]);
16
16
  const disposeSkill = ctx.skills.register({
17
- name: 'dev-workflow',
17
+ name: 'lodestar',
18
18
  description: 'Guide development changes through confirmed intent, reviewed specification, authorized planning, native execution and evidence-based delivery. Resume changes in .dev-docs without repeating valid confirmations.',
19
19
  source: 'bundled',
20
20
  path: fileURLToPath(new URL('SKILL.md', resourceDirectory)),
package/locale/en.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
- "name": "Development Workflow",
3
- "description": "Confirmed intent, reviewed design, native execution and evidence-based delivery. Optional development preset; never changes your default mode."
2
+ "name": "Lodestar · 开发工作流",
3
+ "description": "Confirm intent, review designs, reuse available tools and Teams, and deliver with evidence. Supports design-only work. Optional preset; preserves your default mode."
4
4
  }
package/locale/zh.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
- "name": "开发工作流",
3
- "description": "确认真实需求、审核方案、原生执行与证据交付。可选开发模式,不修改默认模式。"
2
+ "name": "Lodestar · 开发工作流",
3
+ "description": "确认真实需求、评审方案,使用已有工具与 Teams 执行并依据证据交付;支持仅设计。可选模式,不修改默认模式。"
4
4
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fooksky/lodestar",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "license": "MIT",
5
5
  "repository": { "type": "git", "url": "git+https://github.com/urzz/lodestar.git" },
6
6
  "publishConfig": { "access": "public", "registry": "https://registry.npmjs.org/", "provenance": false },
@@ -15,7 +15,7 @@
15
15
  "./package.json": "./package.json",
16
16
  "./locale/*.json": "./locale/*.json"
17
17
  },
18
- "files": ["index.js", "src", "cordis.patch.yml", "skills", "locale", "icon.svg", "README.md", "docs/design.md", "docs/branch-management.md", "docs/proposal.md", "docs/research", "tests/scenarios.md", "LICENSE"],
18
+ "files": ["index.js", "src", "cordis.patch.yml", "skills", "locale", "icon.svg", "README.md", "LICENSE"],
19
19
  "scripts": { "test": "node --test tests/*.test.js", "check": "node --check index.js && node --check src/state.js && node --check src/store.js && node --check src/tool.js && node --check src/schema.js && node --check src/workspace.js && node --check src/preset.js", "prepack": "pnpm check && pnpm test" },
20
20
  "icon": "./icon.svg",
21
21
  "dsh": { "bundle": { "patch": "./cordis.patch.yml" } },
@@ -1,4 +1,4 @@
1
- # 开发工作流
1
+ # Lodestar · 开发工作流
2
2
 
3
3
  用于开发变更和恢复既有 change。主线:确认真实意图 → 审核具体方案并获得实施授权 → 生成 plan → 原生执行与验证 → 交付。用户当前明确要求优先;调查、解释或仅设计请求不自动升级为实施。
4
4
 
@@ -14,7 +14,7 @@
14
14
 
15
15
  ## 授权与阶段
16
16
 
17
- 澄清时可调查,不写业务实现、脚手架或原型。需求确认后进 spec;具体方案审核且实施授权后进 plan;plan 及验收/步骤关联有效后进 execute。只要求设计时交付 spec 并停止,不创建实施 plan 或启动编码 goal。
17
+ 澄清时可调查,不写业务实现、脚手架或原型。需求确认后进 spec;具体方案审核且实施授权后进 plan;plan 及验收/步骤关联有效后进 execute。只要求设计时核对设计验收后以 close 的 delivery: design 从 spec 完成交付,不创建实施 plan 或启动编码 goal。
18
18
 
19
19
  真实用户表达可同时确认需求、审核方案并授权实施,在一次 update 登记多条决定;已授权范围继续推进,不机械重复询问。“设计没问题,先别做”只表示审核。沉默、跳过、工具审批或 goal 续轮不是用户决定。“继续”解除暂停,不补齐缺失的需求/方案决定。source 保存短摘录和可得 session/event 引用;没有事件定位时标为 Agent 记录并说明上下文,不伪造事件号。
20
20
 
@@ -30,6 +30,8 @@ bindingStatus 仅为 matched、mismatch 或 detached。mismatch 先核对工作
30
30
 
31
31
  ## 完成
32
32
 
33
+ 仅设计关闭使用 close 的 delivery: design,直接从 spec 到 done:当前 intent 已确认、当前 spec 已审核,当前验收索引及 required 项均有有效 passed 证据(无适用项时登记 noApplicableReason),无当前失败与 open blocker,并提供交付 evidenceRefs。已有 plan、执行记录或当前实施授权时不能改标设计交付。省略 delivery 沿用实施交付约束;设计关闭不代表实施完成。
34
+
33
35
  验收编号 A1、A2…稳定且不复用给新含义。所有 required 验收有当前有效 passed、无 open blocker,且真实需求满足时才交付;close 要写交付摘要、需求满足依据和知识处理结论。缺环境只能报告“已实现,验证未完成”。已满足需求、规格和必需验收即收敛,不追加无关优化。
34
36
 
35
37
  委派按需读取 references/delegation.md。浏览器与记忆不是必需依赖,但不能以 fixture 或截图生成冒充真实交互验收。长期知识只写稳定事实,可明确“无稳定知识变化”。完成后保留原 change 路径,不自动归档。
@@ -0,0 +1,62 @@
1
+ # Lodestar 使用指南
2
+
3
+ ## 模式说明
4
+
5
+ 「Lodestar · 开发工作流」是可选的 DSH 会话模式。它加入一段流程入口提示,让 Agent 加载公开技能 `lodestar`,通过 `lodestar_change` 维护开发变更,并复用当前部署已有的文件、终端、会话历史和 Teams 工具。它是提示适配器,不是额外的执行器;不会安装缺失工具、复制完整 profile、切换模型、改变权限或替用户批准实施。
6
+
7
+ 核心插件注册技能和状态工具,可在其他兼容模式中使用;可选 preset 默认关闭。模式内部标识仍为 `dev-workflow`,这是配置标识;用户加载技能时使用 `lodestar`。资源目录保留原名称以稳定随包路径。
8
+
9
+ 流程有两种交付范围:
10
+
11
+ | 范围 | 工作与完成条件 |
12
+ |---|---|
13
+ | 设计并实施 | 确认需求 → 评审具体方案并授权实施 → 计划 → 执行与验证 → 交付。必需验收要有有效通过证据。 |
14
+ | 仅设计 | 确认需求 → 评审方案 → 核对设计验收并交付。记录设计证据,以 `close` 的 `delivery: "design"` 从 spec 完成;不创建实施 plan,不启动编码。 |
15
+
16
+ 选择模式不等于授权实施。只调查或解释的请求按该范围处理,不必把每次问答都建成 change。原生工具的成功回执能证明操作结果,用户真实需求是否满足仍需 Lead 判断。
17
+
18
+ ## 如何使用
19
+
20
+ ### 1. 准备宿主与工作区
21
+
22
+ 需要 Node.js 24+、Git 和兼容 DSH;版本范围见 [包配置](../../package.json)。使用 DSH 的插件管理安装 `@fooksky/lodestar` 并启用核心插件。若需要模式入口,进入侧栏「插件」→「已安装」→ `@fooksky/lodestar` 详情,在「包含的组件」中打开 `dev-workflow-preset` 行的「启用组件」开关;该组件默认关闭。再在新会话开始前选择「Lodestar · 开发工作流」。支持模式指南的宿主可展示本指南的「模式说明 / 如何使用」;旧宿主忽略指南字段,不影响核心技能和随包文档的使用。
23
+
24
+ 核心需要宿主提供技能、工具、文件、工作目录和 subprocess 服务。完整开发模式还使用读写编辑、路径搜索、终端与 job、提问、会话历史及 Teams 能力。preset 仅检查可见工具并在提示中报告缺口,不会提供这些服务。部署缺少实际任务所需能力时,Agent 应说明缺口;浏览器、记忆及普通 subagent 仅在环境提供且任务需要时使用。受委派成员只检查自己的任务包所需能力。
25
+
26
+ 默认由用户或外部助手为每个独立需求准备分支和 worktree。Lodestar 会检查调用 Agent 的实际 cwd 与项目根,并把 change 绑定到工作区;不会创建或切换分支。明确指定在现有工作区执行的授权仍按用户范围处理。
27
+
28
+ ### 2. 进入流程并说明目标
29
+
30
+ 新会话可以选择「Lodestar · 开发工作流」。已有兼容会话可以直接要求加载 `lodestar` skill。
31
+
32
+ 例如:
33
+
34
+ > 加载 lodestar。请先调查登录失败的原因,给出可评审方案;我确认后再实施。
35
+
36
+ > 只设计导出功能,列出数据流、接口和验收要求,不写实现代码。
37
+
38
+ > 需求和方案已经按上述内容确认,授权实施;在已指定工作区继续,不重复询问。
39
+
40
+ Agent 先确认范围、调用 `workspace` 核对工作区,再按需要创建 change。已明确的需求、方案审核和实施授权可复用;「继续」本身不会补齐从未给出的授权。
41
+
42
+ ### 3. 查看材料与结果
43
+
44
+ 项目内 `.dev-docs/changes/<change-id>/` 保存需求 `intent.md`、方案 `spec.md`、实施计划 `plan.md`(授权实施后才创建)及工具状态 `state.json`。正文是语义依据,状态记录版本、决定、验收与证据关联。不要手改状态文件;正文先通过宿主文件工具写入,再登记版本。
45
+
46
+ 实施完成必须核对真实需求、必需验收和交付边界;仅设计完成必须核对当前需求确认、方案审核、设计验收及证据,无未解决阻塞。设计完成后如需实施,应明确新范围,再恢复相应阶段并获得实施授权,不能把设计交付说成已经实现。
47
+
48
+ ### 4. 恢复工作
49
+
50
+ > 加载 lodestar,继续 change `20261108-example`。先核对当前工作区、文档版本和剩余任务,复用仍有效的确认与证据。
51
+
52
+ 若不知道 change ID,可要求列出本工作区候选。Agent 应先读状态和相关材料,再查必要历史,不全量重跑。分支归属不匹配须先核对依据;明确分支改名或接管时单独重绑。detached 工作区仅可读;旧格式、损坏状态和缺失绑定需要报告,不自动修复。
53
+
54
+ ## 能力边界与故障处理
55
+
56
+ - 缺少 `lodestar_change`:检查核心插件是否启用;Agent 不应手工伪造状态。
57
+ - 模式提示缺少能力:补齐部署服务,或按当前任务缩小范围并如实报告未完成项;模式不会扩大权限。
58
+ - revision 冲突:重新读取并合并语义,避免盲重试;写入结果未知时先查已有记录。
59
+ - 缺少必要验证环境:报告具体阻断,不能把编译或 fixture 当作真实交互验收。
60
+ - 提交、推送、发布、安装及清理:依据用户明确授权执行;选择本模式并不授权这些动作。
61
+
62
+ 更细的 Agent 执行规则见 [技能正文](SKILL.md)、[工作区参考](references/workspace.md)、[恢复参考](references/recover.md);工具参数以 [schema](../../src/schema.js) 为准。返回 [README](../../README.md)。
@@ -8,6 +8,8 @@
8
8
 
9
9
  视觉检查分有界小包及时记结论;要求全量覆盖时不能静默抽样。缺浏览器等必需环境就报告具体阻断。测试通过但真实需求不足仍不得 close。
10
10
 
11
- 进入 deliver 需 required 当前有效 passed 且无 open blocker;close 再记录交付说明、需求满足依据、必需验收关联、知识处理结论。稳定知识只更新本 worktree 的现有主题并引用已有 README/架构,不读取其他 checkout 的实时知识、不保存调试流水账。可写“无稳定知识变化”。达到范围即收敛;未完成明确差距,不用“已实现”冒充全部验收通过。
11
+ 实施交付进入 deliver 需 required 当前有效 passed 且无 open blocker;close 再记录交付说明、需求满足依据、必需验收关联、知识处理结论。稳定知识只更新本 worktree 的现有主题并引用已有 README/架构,不读取其他 checkout 的实时知识、不保存调试流水账。可写“无稳定知识变化”。达到范围即收敛;未完成明确差距,不用“已实现”冒充全部验收通过。
12
+
13
+ 仅设计交付不经过实施 deliver:在 spec 使用 close 的 delivery: design,核对当前 intent 确认、spec 审核、验收及设计证据,提供非空 evidenceRefs,并确保无当前失败和 open blocker。不得已有 plan、执行记录或当前实施授权。它只证明设计交付;省略 delivery 的 close 仍按实施约束执行。
12
14
 
13
15
  PR/MR 地址、源/目标分支、评审与合入结果及证据写入既有 plan/交付材料;若合入是必需交付条件,close 前完成合入与集成验证;若边界是提交 PR,不声称已经合入。PR 反馈按原有阶段退回、版本和局部证据失效规则处理。需要保留的代码、知识与 change 材料随分支提交并经 PR/MR 集成,同一知识文件或 state 冲突需核对语义,文本合并成功不能代替验收。提交及 worktree 清理按明确授权执行,清理前保留未提交材料与证据;数据库、端口、账号及外部资源仍须单独隔离。
@@ -10,4 +10,4 @@
10
10
 
11
11
  同会话查询仍在写的成员和原生任务。跨会话旧 Team 不可达时核对成果,仅为剩余部分建新任务,通过 bind-step 为同一 P 编号重新绑定时提供 reason,previousBindings 保留旧引用和替代关系;旧成员写入归属不明时先解决,不能重复抢写相同路径。
12
12
 
13
- 读取状态不会触发全量重验。证据仍有效则沿用;必需证据丢失才补验。done 后独立新需求另建 change;原交付问题可记录原因退回对应阶段。暂停、等待、阻断保留阶段,不靠切模式或重建 change 绕过缺口。
13
+ 读取状态不会触发全量重验。证据仍有效则沿用;必需证据丢失才补验。done 后独立新需求另建 change;原交付问题可记录原因退回对应阶段。closure.delivery 为 design 时仅代表设计交付,省略则按既有实施交付理解。设计后明确要求继续实施,可通过 set-workflow 退回 spec(移除 closure),确认当前方案与实施授权后再登记 plan;不能把旧设计证据当作实现验收。暂停、等待、阻断保留阶段,不靠切模式或重建 change 绕过缺口。
@@ -4,6 +4,6 @@ spec 引用已确认 intent,说明预期行为、影响范围、职责/数据
4
4
 
5
5
  验收使用稳定 A 编号;删除的编号不复用。覆盖真实用户需求,不能只证明代码符合自己的方案。明确 required 项、实际被测对象与环境;确无适用验收时,在已审核 spec 中说明并登记显式依据,不以空集合绕过验收。
6
6
 
7
- 正文写入后登记 register-document,spec basedOn 当前 intent;set-acceptance 显式更新当前版本索引。来源明确、范围匹配且未撤回的审核可复用;“先别做”不是实施授权。仅设计请求到此交付并停止。
7
+ 正文写入后登记 register-document,spec basedOn 当前 intent;set-acceptance 显式更新当前版本索引。来源明确、范围匹配且未撤回的审核可复用;“先别做”不是实施授权。仅设计请求在当前 intent 确认、spec 审核和验收证据齐备后,用 close 的 delivery: design 从 spec 直接关闭到 done,附交付 evidenceRefs、summary、satisfaction 和 knowledge。required 项须当前有效 passed,无当前失败或 open blocker;无适用验收须登记 noApplicableReason。已有 plan、执行记录或当前实施授权时不能以 design 关闭;不为设计交付创建实施计划。
8
8
 
9
9
  语义改变时先暂停受影响成员,同次状态更新退回 spec 并使旧版本决定不再适用。用户已明确批准差异就引用该表达登记新版本决定,无需再问。排版变化有理由即可,不自动撤回确认;程序摘要不判断语义,Lead 负责分类。
package/src/preset.js CHANGED
@@ -1,3 +1,10 @@
1
+ import { readFile } from 'node:fs/promises';
2
+
3
+ const guideText = await readFile(new URL('../skills/dev-workflow/USER_GUIDE.md', import.meta.url), 'utf8');
4
+ // Inline host Markdown has no package-relative URL base; keep labels for local links.
5
+ const inlineGuide = guideText.replace(/\[([^\]]+)\]\((?!https?:\/\/)[^)]+\)/g, '$1');
6
+ const [explanation, usage] = inlineGuide.split('\n## 如何使用\n');
7
+
1
8
  export const name = 'dev-workflow-preset';
2
9
  export const inject = ['tools', 'agentPresets', 'systemPrompt'];
3
10
 
@@ -9,10 +16,11 @@ export const requiredTools = [
9
16
  'team_task_list', 'team_task_get', 'team_task_update', 'team_task_create',
10
17
  'spawn_teammate', 'send_message', 'list_agents',
11
18
  ];
12
- export const modeText = '本会话采用开发工作流。开发变更先加载 dev-workflow,定位或创建 change,按当前阶段继续。只调查、解释或设计时遵守该范围;选择模式不构成实施、提交、发布或安装授权。受委派成员执行任务包并向 Lead 回报,不重复启动 Lead 需求确认流程。浏览器、记忆和普通 subagent 仅在部署提供且任务需要时使用。';
19
+ export const modeText = '本会话采用开发工作流。开发变更先加载 lodestar,定位或创建 change,按当前阶段继续。只调查、解释或设计时遵守该范围;选择模式不构成实施、提交、发布或安装授权。受委派成员执行任务包并向 Lead 回报,不重复启动 Lead 需求确认流程。浏览器、记忆和普通 subagent 仅在部署提供且任务需要时使用。';
13
20
  export const definition = {
14
- id: 'dev-workflow', name: '开发工作流',
15
- description: 'Confirmed intent, reviewed design and evidence-based development using native Teams.',
21
+ id: 'dev-workflow', name: 'Lodestar · 开发工作流',
22
+ description: '确认真实需求、评审方案,使用已有工具与 Teams 执行,并依据证据交付;也支持仅设计。',
23
+ guide: { explanation, usage },
16
24
  plugins: [{ id: 'dev-workflow-entry', name: '@fooksky/lodestar/preset', config: { entry: true } }],
17
25
  };
18
26
  export async function apply(ctx, config = {}) {
package/src/schema.js CHANGED
@@ -51,13 +51,23 @@ export function validateRelations(s, code = 'INVALID_STATE') {
51
51
  const decision = (kind, keys) => s.decisions.some(d => d.kind === kind && !removed.has(d.id) && current(d.subjects) && keys.every(k => d.subjects[k] && d.subjects[k] === s.documents[k]?.version));
52
52
  const level = ['intent','spec','plan','execute','deliver','done'].indexOf(s.workflow.phase);
53
53
  if (level >= 1) check(decision('intent-confirmation', ['intent']), 'Missing current intent confirmation');
54
- if (level >= 2) check(s.documents.spec && current(s.documents.spec.basedOn) && decision('spec-review', ['intent','spec']) && decision('implementation-authorization', ['intent','spec']), 'Missing current spec approval/authorization');
54
+ const design = s.closure?.delivery === 'design';
55
+ if (level >= 2) {
56
+ check(s.documents.spec && current(s.documents.spec.basedOn) && decision('spec-review', ['intent','spec']), 'Missing current spec approval');
57
+ if (!design) check(decision('implementation-authorization', ['intent','spec']), 'Missing current implementation authorization');
58
+ }
59
+ if (design) {
60
+ check(!s.documents.plan && !s.execution.length && !decision('implementation-authorization', ['intent','spec']), 'Design closure cannot replace implementation delivery');
61
+ check(s.closure.evidenceRefs.length > 0, 'Design closure requires evidence');
62
+ }
55
63
  if (level >= 3) {
56
- check(s.documents.plan && current(s.documents.plan.basedOn), 'Invalid current plan');
57
64
  check(s.acceptance?.specVersion === s.documents.spec.version, 'Missing current acceptance');
58
65
  check(s.acceptance.items.some(a => a.required) || s.acceptance.noApplicableReason, 'Empty required acceptance without rationale');
59
- check(s.execution.length || s.acceptance.noApplicableReason, 'Missing execution steps');
60
- check(s.acceptance.items.filter(a => a.required).every(a => s.execution.some(p => p.acceptanceIds.includes(a.id))), 'Missing acceptance step coverage');
66
+ if (!design) {
67
+ check(s.documents.plan && current(s.documents.plan.basedOn), 'Invalid current plan');
68
+ check(s.execution.length || s.acceptance.noApplicableReason, 'Missing execution steps');
69
+ check(s.acceptance.items.filter(a => a.required).every(a => s.execution.some(p => p.acceptanceIds.includes(a.id))), 'Missing acceptance step coverage');
70
+ }
61
71
  }
62
72
  if (level >= 4) {
63
73
  check(!s.blockers.some(b => b.status === 'open'), 'Open blockers prevent delivery');
@@ -88,7 +98,7 @@ const step = z.discriminatedUnion('mode', [
88
98
  const verification = z.object({ id, acceptanceIds: z.array(id).min(1), specVersion: version, outcome: z.enum(['passed', 'failed', 'not-run', 'not-applicable', 'stale']), method: text, subject: text, environment: text, evidenceRefs: z.array(text), summary: text, supersedes: id.optional(), carriedFrom: id.optional(), carryReason: text.optional(), observedAt: z.iso.datetime().optional() }).strict();
89
99
  const blocker = z.object({ id, description: text, status: z.enum(['open', 'resolved']), resolution: text.optional() }).strict();
90
100
  const workflow = z.object({ phase: phaseSchema, status, reason: text, nextAction: text }).strict();
91
- const closure = z.object({ summary: text, acceptanceIds: z.array(id), satisfaction: text, knowledge: text, evidenceRefs: z.array(text) }).strict();
101
+ const closure = z.object({ delivery: z.enum(['implementation', 'design']).optional(), summary: text, acceptanceIds: z.array(id), satisfaction: text, knowledge: text, evidenceRefs: z.array(text) }).strict();
92
102
  const op = (type, shape) => z.object({ type: z.literal(type), ...shape }).strict();
93
103
  export const workspaceSchema = z.discriminatedUnion('kind', [
94
104
  z.object({ kind: z.literal('directory') }).strict(),
package/src/state.js CHANGED
@@ -130,7 +130,7 @@ export function applyOperations(state, operations, { expectedRevision, documents
130
130
  requireThat(s.acceptance?.items.filter(a => a.required).every(a => op.acceptanceIds.includes(a.id)), 'Closure must cover all required acceptance');
131
131
  const { type, ...closure } = op;
132
132
  s.closure = { ...closure, recordedAt: at };
133
- s.workflow = { phase: 'done', status: 'active', reason: op.summary, nextAction: 'Delivered' }; break;
133
+ s.workflow = { phase: 'done', status: 'active', reason: op.summary, nextAction: op.delivery === 'design' ? 'Design delivered' : 'Delivered' }; break;
134
134
  }
135
135
  }
136
136
  summary.push(op.type);
package/src/tool.js CHANGED
@@ -22,7 +22,7 @@ export function hostSchema(schema) {
22
22
  export function createTool(ctx) {
23
23
  return {
24
24
  name: 'lodestar_change',
25
- description: 'Inspect the current workspace and manage branch-local development changes, including document versions, decisions, acceptance criteria, execution references, verification records, and lifecycle constraints. State updates in .dev-docs are atomic. projectRoot must belong to the calling Agent checkout. Load dev-workflow for workflow semantics. create binds the current branch; get/list expose bindingStatus; an intentional branch rename or reassignment uses a separate update with bind-workspace and reason. User decisions require real sources. This tool does not authorize implementation or schedule tasks. On revision conflicts, get and merge before retrying.',
25
+ description: 'Inspect the current workspace and manage branch-local development changes, including document versions, decisions, acceptance criteria, execution references, verification records, and lifecycle constraints. State updates in .dev-docs are atomic. projectRoot must belong to the calling Agent checkout. Load lodestar for workflow semantics. Design-only completion uses close with delivery: design from spec after review and design evidence, without an implementation plan. create binds the current branch; get/list expose bindingStatus; an intentional branch rename or reassignment uses a separate update with bind-workspace and reason. User decisions require real sources. This tool does not authorize implementation or schedule tasks. On revision conflicts, get and merge before retrying.',
26
26
  parameters: { type: 'object', ...hostSchema(inputSchema) },
27
27
  output: {
28
28
  schema: hostSchema(outputSchema),
package/src/workspace.js CHANGED
@@ -42,7 +42,10 @@ export async function inspectWorkspace(ctx, { cwd, projectRoot, signal, sandboxP
42
42
  const identify = async target => {
43
43
  const directory = fs.processPath(target);
44
44
  const probe = await query(directory, ['rev-parse', '--is-bare-repository']);
45
- if (probe.code === 128 && probe.err === 'fatal: not a git repository (or any of the parent directories): .git') return { kind: 'directory' };
45
+ if (probe.code === 128 && (
46
+ probe.err === 'fatal: not a git repository (or any of the parent directories): .git'
47
+ || /^fatal: not a git repository \(or any parent up to mount point .+\)\r?\nStopping at filesystem boundary \(GIT_DISCOVERY_ACROSS_FILESYSTEM not set\)\.$/.test(probe.err)
48
+ )) return { kind: 'directory' };
46
49
  const bare = checked(probe);
47
50
  if (bare === 'true') fail('INVALID_WORKSPACE', 'A bare repository has no development checkout.');
48
51
  if (bare !== 'false') fail('GIT_QUERY_FAILED', 'Unexpected Git repository probe output.');
@@ -1,60 +0,0 @@
1
- # 分支与 worktree 隔离设计
2
-
3
- 日期:2026-11-07。用户已确认完整 worktree 隔离、PR/MR 集成冲突和插件不承担调度,并明确授权在无新增待决事项时继续实现。本文把这些决定细化为实现契约;不包含安装、提交或推送授权。
4
-
5
- ## 1. 边界
6
-
7
- 一个独立需求默认对应一个 change、一条分支、一个 worktree 和一个 Lead。代码、`.dev-docs/knowledge/`、change 正文、state 和需要保留的证据全部位于当前 worktree。创建工作区继承基准提交中的知识快照,后续不实时读取其他 checkout 的材料,不使用共享材料根或符号链接。
8
-
9
- 外部助手负责 Issue 领取、跨需求分配、创建/选择 worktree 和启动会话。本插件只负责当前分支内的流程与状态;不新增调度器、跨工作区扫描、全局 current change、分支创建/切换/删除、自动 Git 提交或 PR API。既有工作区由用户/外部助手通过 DSH 原生能力准备。同一需求内部仍可用原生 Teams,Lead 单 owner 写主材料。
10
-
11
- ## 2. 当前工作区观察
12
-
13
- `lodestar_change` 增加只读 `action: workspace`。每个 action 在调用 Agent 的实际 cwd 和显式 projectRoot 上识别当前 Git checkout,返回有界 workspace 信息。Git 查询经宿主 subprocess 和调用会话的 sandbox policy 执行;不使用 Node child_process 或 shell,也不绕过文件 backend。Git 是运行依赖,缺少 Git/宿主服务、取消、权限拒绝、仓库损坏均保持错误,不伪装成非 Git。
14
-
15
- 通过 Git 的明确“not a git repository”诊断识别普通目录;固定查询语言并清除改变仓库发现的 Git 环境变量。普通目录继续支持工作流。bare 仓库拒绝使用。Git 支持标准 checkout、linked worktree、子模块与项目子目录;projectRoot 必须存在。
16
-
17
- 运行时信息包括实际 projectRoot、checkoutRoot、项目相对 checkout 的路径、分支和当前 HEAD。detached HEAD 可读不可写;unborn 命名分支允许使用,HEAD 为 null。分支和 HEAD 每次读取实际 Git 事实,不用 state 代替。
18
-
19
- Git 项目要求 Agent cwd 与 projectRoot 属于同一 checkout,不能从需求 worktree 指向主 checkout 的材料,即使会话有跨目录写权限。普通目录要求 projectRoot 位于 Agent cwd 内;cwd 可以是现有项目下任意目录,但 Git 情形仍按同一 checkout 判定。路径通过宿主 fs 规范化和 contains 比较,避免字符串路径别名绕过。
20
-
21
- ## 3. 持久绑定与版本
22
-
23
- 状态格式仅接受 `schemaVersion: 2`,`workspace` 必填,是以下二者之一:
24
-
25
- - Git:`{ kind: 'git', branch, baseCommit, projectPath }`。baseCommit 为首次绑定/重新绑定时的 HEAD,可为 null;它只记录来源,不参与 HEAD 相等或祖先检查。
26
- - 普通目录:`{ kind: 'directory' }`。
27
-
28
- 不把机器绝对路径、session owner 或可变当前 HEAD 存入版本化 state;移动/重新检出到其他机器或目录无需重写绑定。changeId 保持需求身份,branch 只是工作区关联。相同分支名不构成跨仓库身份或安全证明,复制材料不自动表示已经接管需求。
29
-
30
- 未知或旧 schema、缺失 workspace 均拒绝,不自动转换。list 不区分未受管目录;缺失或非法 state 的条目显示对应错误,不自动初始化或修复。
31
-
32
- `bind-workspace` 参数只有 reason,实际绑定由工具观察,不接受模型填写分支/路径/提交。用于命名分支重命名、确认后的分支接管、普通目录初始化为仓库后的显式重绑,不能修复缺失绑定或非法 schema。绑定作为独立 update,不能夹带业务变更;已有绑定替换时在 workspaceHistory 保留旧绑定、原因及时间,每项的 previous 必填。相同绑定重试不增加 revision;普通提交/rebase 后重复绑定同一分支和项目路径也不更新 baseCommit。
33
-
34
- ## 4. 读写规则
35
-
36
- 每个 action 的顶层 workspace 直接返回当前工作区观察,不嵌套 current/status;workspace action 不返回 bindingStatus。get 顶层 bindingStatus 仅为 matched、mismatch、detached,并以 binding 返回已存绑定;list 有效行 workspace 为已存绑定,同时返回 bindingStatus,顶层 workspace 仍为当前观察。历史 change 合入 main 后仍可 get/list,但不会自动把来源分支改为 main。
37
-
38
- create 自动绑定当前命名分支或普通目录。常规 update 在读 state 后、读取/发布业务变更前检查绑定。branch、项目相对路径或工作区种类不匹配时拒绝;缺失绑定的状态非法;detached 拒绝所有写入。绑定操作依然遵守 expectedRevision 和宿主 replaceIfVersion。
39
-
40
- 绑定是状态工具自身的写入保护,不是 Git/工作目录锁,也不能限制其他文件工具。运行期间禁止外部切分支、搬移目录或清理 worktree;同一 checkout 不安排不同需求并发切换分支。同一 change 的多 Lead 业务所有权仍由明确交接保证,CAS 不充当任务锁。
41
-
42
- ## 5. 工作流
43
-
44
- 先由外部选择隔离 worktree,再查询 workspace、创建 change;只有做普通解释/调查时可以不建 change。材料始终以当前 worktree 为唯一权威,不能复制后两处继续写。本插件不自动搬移或提交。
45
-
46
- 计划和委派包使用当前 worktree 的 projectRoot、changeId、预期分支和工作目录。知识只读写该分支的本地快照;跨需求依赖通过明确的 Git 集成引入。恢复先核对 workspace 和 change 绑定,再复用当前材料与授权;分支漂移不按相同 HEAD 猜测归属。分支重命名需要有理由的显式绑定,合入后的历史记录默认只读,不批量重绑。
47
-
48
- PR/MR 地址、源/目标分支、待评审/待合入结果及相关证据写入既有 plan/交付材料;状态机不接管远端 PR 生命周期。close 仍按本需求的验收契约:若合入是必需交付条件,合入及集成验证必须先满足;若交付边界是提交 PR,则 close 不声称已合入。PR 反馈修订沿用既有阶段退回、材料版本和证据失效机制。
49
-
50
- 需要保留的代码、知识与 change 材料随分支提交,通过 PR/MR 集成;同一知识文件和 state 的冲突必须核对语义,不能把文本合并成功当验收通过。worktree 清理前保留未提交材料及证据,清理属于外部明确操作。数据库、端口、测试账号和外部资源按需求隔离,Git worktree 只隔离文件。
51
-
52
- ## 6. 验证
53
-
54
- - 真实 Git 仓库建立两个 linked worktree,相同 change ID 各自保存、更新、知识修改互不影响;不读取主 checkout 实时知识。
55
- - 从 feature worktree 显式指向 main 材料根被拒绝;子目录项目在同一 checkout 可以使用。
56
- - 切分支后读显示 mismatch,普通写拒绝;显式绑定保留历史;分支正常提交或 rebase 不误锁。
57
- - detached 可读不可写,unborn 可写,bare/损坏仓库/缺少 Git/取消/权限错误不降级为普通目录。
58
- - 仅接受 schemaVersion: 2 且 workspace 必填;未知或旧 schema、缺失绑定拒绝,未受管目录在 list 中显示缺失或非法 state 错误;重绑历史 previous 必填,CAS 失败不发布。
59
- - 合并包含 change 材料后,目标分支可读历史且不会自动改其归属;移动工作区仍可按分支恢复。
60
- - 使用实际 DSH 文件、subprocess、sandbox 与注册服务测试;不安装到 profile。模型在真实 Issues/PR/Teams 中的长期行为另列为待观察,不用程序测试冒充。