@guanlin4924/devflow-pi 0.1.36 → 0.1.37

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
@@ -11,7 +11,7 @@ Devflow Pi 是一个面向项目研发交付的独立 OMP 产品入口,内置
11
11
  安装与启动:
12
12
 
13
13
  ```bash
14
- npm install -g @guanlin4924/devflow-pi@0.1.36
14
+ npm install -g @guanlin4924/devflow-pi@0.1.37
15
15
  cd /path/to/your-project
16
16
  devflow-pi init
17
17
  devflow-pi doctor
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guanlin4924/devflow-pi",
3
- "version": "0.1.36",
3
+ "version": "0.1.37",
4
4
  "type": "module",
5
5
  "description": "Devflow 专项研发 Pi,基于固定版本 OMP Runtime 组装研发状态机、代码智能、设计、实现与质量门禁。",
6
6
  "license": "UNLICENSED",
@@ -1468,6 +1468,30 @@ export default function devflowCore(pi: ExtensionAPI) {
1468
1468
  return { handled: true };
1469
1469
  }
1470
1470
  }
1471
+ // A step transition can succeed before the runtime manages to prepare the
1472
+ // fresh-session handoff. Keep approval useful in this recovery state, but
1473
+ // retry only the handoff; never repeat the already-persisted transition.
1474
+ if (controlState.phase === "blocked" && controlState.label === "会话轮换准备失败" && controlAction === "approve") {
1475
+ const inspected = await inspectWorkflow(ctx.cwd);
1476
+ if (!inspected.result.ok || !inspected.snapshot) {
1477
+ ctx.ui.notify(`会话交接重试失败:${inspected.result.stderr || inspected.result.stdout || "invalid inspector JSON"}`, "error");
1478
+ return { handled: true };
1479
+ }
1480
+ if (inspected.snapshot.action === "workflow_complete") {
1481
+ setControlState(ctx, initialControlState());
1482
+ ctx.ui.notify("工作流已完成。", "info");
1483
+ return { handled: true };
1484
+ }
1485
+ setControlState(ctx, waitingUserState("正在重试干净会话交接"));
1486
+ try {
1487
+ await requestControlledRollover(ctx, inspected.snapshot);
1488
+ ctx.ui.notify("已重新登记会话交接;当前回合结束后将自动切换到下一节点。", "info");
1489
+ } catch (error) {
1490
+ setControlState(ctx, { intent: "workflow-execute", phase: "blocked", label: "会话轮换准备失败" });
1491
+ ctx.ui.notify(`会话交接仍未完成:${String(error)}`, "error");
1492
+ }
1493
+ return { handled: true };
1494
+ }
1471
1495
  if (controlState.phase === "awaiting-approval" || controlState.phase === "waiting-user") {
1472
1496
  if (controlAction === "reject") {
1473
1497
  ctx.ui.notify("已保留当前步骤和产物。请直接说明需要修改的内容;未执行任何推进。", "info");
@@ -98,8 +98,22 @@ result = catch(:transition_done) do
98
98
  result = fail_result("handoff_integrity_failure", "rollover" => rollover)
99
99
  throw :transition_done, result
100
100
  end
101
- result = fail_result("rollover_in_progress", "rollover" => rollover)
102
- throw :transition_done, result
101
+ if expected_state_revision.is_a?(Integer) && expected_state_revision < revision - 1
102
+ # The state has moved beyond the revision captured by this prepared
103
+ # handoff. It is an orphan from an interrupted/retried runtime turn,
104
+ # not an active lock. Verify its immutable evidence, preserve the
105
+ # handoff file on disk, and replace the STATE pointer with a handoff
106
+ # for the current revision.
107
+ existing_path, = DevflowControlIO.resolve_control_path(root, rollover["handoff_path"], :handoff)
108
+ unless File.exist?(existing_path) && Digest::SHA256.hexdigest(File.binread(existing_path)) == rollover["handoff_sha256"]
109
+ result = fail_result("handoff_integrity_failure", "rollover" => rollover)
110
+ throw :transition_done, result
111
+ end
112
+ rollover = nil
113
+ else
114
+ result = fail_result("rollover_in_progress", "rollover" => rollover)
115
+ throw :transition_done, result
116
+ end
103
117
  elsif rollover && rollover["status"] == "claimed"
104
118
  result = fail_result("rollover_in_progress", "rollover" => rollover)
105
119
  throw :transition_done, result
@@ -132,7 +132,7 @@ module WorkflowStateValidator
132
132
  return
133
133
  end
134
134
  status = rollover["status"]
135
- unless %w[prepared claimed consumed failed].include?(status)
135
+ unless %w[prepared claimed consumed superseded failed].include?(status)
136
136
  issues << issue("error", "invalid_rollover_status", "STATE.rollover.status is invalid", status: status)
137
137
  return
138
138
  end
package/src/constants.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export const PRODUCT_NAME = "Devflow Pi";
2
- export const PRODUCT_VERSION = "0.1.36";
2
+ export const PRODUCT_VERSION = "0.1.37";
3
3
  export const PROJECT_SCHEMA_VERSION = 1;
4
4
  export const OMP_RUNTIME_VERSION = "17.2.7";
5
5