@guanlin4924/devflow-pi 0.1.50 → 0.1.51

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guanlin4924/devflow-pi",
3
- "version": "0.1.50",
3
+ "version": "0.1.51",
4
4
  "type": "module",
5
5
  "description": "Devflow 专项研发 Pi,基于固定版本 OMP Runtime 组装研发状态机、代码智能、设计、实现与质量门禁。",
6
6
  "license": "UNLICENSED",
@@ -4,6 +4,7 @@ import { appendFile, mkdir, rename, writeFile } from "node:fs/promises";
4
4
  import path from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent";
7
+ import { Box, Text } from "@oh-my-pi/pi-tui";
7
8
  import {
8
9
  TASK_SUBAGENT_LIFECYCLE_CHANNEL,
9
10
  type SubagentLifecyclePayload,
@@ -27,6 +28,96 @@ type ProjectInitializationRequest = {
27
28
  mode: ProjectInitializationMode;
28
29
  };
29
30
 
31
+ const workflowStepNames: Record<string, string> = {
32
+ "requirement-triage": "需求梳理",
33
+ "requirement-wayfinder": "需求路径规划",
34
+ "domain-modeling": "领域建模",
35
+ "requirement-feasibility-review": "需求可行性审查",
36
+ "requirement-baseline": "需求基线确认",
37
+ "wireframe-proposal": "原型方案",
38
+ "wireframe-validate": "原型校验",
39
+ "wireframe-render": "原型预览生成",
40
+ "wireframe-review": "原型审查",
41
+ "api-contract": "接口契约",
42
+ "architecture-feasibility": "架构可行性评估",
43
+ "ui-spec": "界面规格",
44
+ "feature-breakdown": "功能拆分",
45
+ "frontend-tech-spec": "前端技术方案",
46
+ "backend-tech-spec": "后端技术方案",
47
+ "api-call-guide": "接口调用说明",
48
+ "api-supplement": "接口补充设计",
49
+ "integration-verify": "集成验证",
50
+ "change-plan": "变更计划",
51
+ "acceptance-test-design": "验收测试设计",
52
+ "phase-structure": "阶段结构确认",
53
+ "execute": "实现执行",
54
+ "code-index-refresh": "代码索引刷新",
55
+ "code-review": "代码审查",
56
+ "generate-mainflow-cases": "主流程用例生成",
57
+ "run-acceptance-tests": "冻结验收测试执行",
58
+ "release-closeout": "发布收尾与里程碑归档",
59
+ "dual-track-design": "前后端并行设计",
60
+ "acceptance-failed-remediation": "验收失败修复",
61
+ "diagnose": "验收失败诊断",
62
+ "execute-fix": "修复执行",
63
+ };
64
+
65
+ const workflowStatusNames: Record<string, string> = {
66
+ completed: "已完成",
67
+ current: "进行中",
68
+ pending: "未开始",
69
+ waiting_review: "等待审查",
70
+ blocked: "已阻塞",
71
+ failed: "执行失败",
72
+ cancelled: "已取消",
73
+ unknown: "未知",
74
+ };
75
+
76
+ const workflowActionNames: Record<string, string> = {
77
+ run_next_step: "执行下一步骤",
78
+ run_parallel_window: "执行并行步骤",
79
+ route_failure_branch: "进入失败处理分支",
80
+ await_user_confirmation: "等待人工确认",
81
+ recover_artifact_registry: "恢复工件登记",
82
+ workflow_complete: "功能交付已完成",
83
+ workflow_cancelled: "功能交付已取消",
84
+ blocked: "处理阻塞项",
85
+ };
86
+
87
+ function workflowSteps(snapshot: Record<string, unknown>): Array<{ id: string; label: string; status: string }> {
88
+ if (!Array.isArray(snapshot.workflow_steps)) return [];
89
+ return snapshot.workflow_steps.flatMap(step => {
90
+ if (!step || typeof step !== "object") return [];
91
+ const record = step as Record<string, unknown>;
92
+ const id = typeof record.id === "string" ? record.id : "";
93
+ if (!id) return [];
94
+ return [{
95
+ id,
96
+ label: typeof record.label === "string" && record.label ? record.label : id,
97
+ status: typeof record.status === "string" ? record.status : "unknown",
98
+ }];
99
+ });
100
+ }
101
+
102
+ function workflowStepName(id: string | undefined, fallback?: string): string {
103
+ if (id && workflowStepNames[id]) return workflowStepNames[id];
104
+ return fallback || id || "未开始";
105
+ }
106
+
107
+ function workflowStatusName(status: unknown): string {
108
+ return typeof status === "string" ? workflowStatusNames[status] ?? status : "未知";
109
+ }
110
+
111
+ function workflowActionName(action: unknown): string {
112
+ return typeof action === "string" ? workflowActionNames[action] ?? action : "正在确认";
113
+ }
114
+
115
+ function workflowPhaseName(phase: unknown): string {
116
+ if (typeof phase !== "string" || !phase) return "未开始";
117
+ if (phase.startsWith("feature-")) return "功能交付";
118
+ return phase;
119
+ }
120
+
30
121
  type ActiveExecutionContract = {
31
122
  contractId: string;
32
123
  feature: string;
@@ -897,20 +988,21 @@ function projectInitializationDirective(summary: string): string {
897
988
  }
898
989
 
899
990
  function explainWorkflowSnapshot(snapshot: Record<string, unknown> | null): string {
900
- if (!snapshot) return "Devflow 当前没有可解释的工作流状态。可使用 /devflow start <feature> 创建新 Feature。";
991
+ if (!snapshot) return "Devflow 当前没有可解释的工作流状态。可使用 /devflow start <功能名> 创建新功能。";
901
992
  const step = compactStep(snapshot.next_step) ?? compactStep(snapshot.current_step);
902
993
  const lines = [
903
- `Feature:${String(snapshot.current_feature ?? "未开始")}`,
904
- `状态:${String(snapshot.status ?? "unknown")}`,
905
- `动作:${String(snapshot.action ?? "unknown")}`,
906
- `Revision:${String(snapshot.revision ?? "unknown")}`,
994
+ `功能:${String(snapshot.current_feature ?? "未开始")}`,
995
+ `阶段:${workflowPhaseName(snapshot.current_phase)}`,
996
+ `状态:${workflowStatusName(snapshot.status)}`,
997
+ `动作:${workflowActionName(snapshot.action)}`,
998
+ `版本:${String(snapshot.revision ?? "未知")}`,
907
999
  ];
908
- if (step?.id) lines.push(`当前/下一步骤:${String(step.id)}${step.label ? `(${String(step.label)})` : ""}`);
909
- if (snapshot.checkpoint) lines.push(`Checkpoint:${String(snapshot.checkpoint)}`);
1000
+ if (step?.id) lines.push(`当前/下一节点:${workflowStepName(step.id, step.label)}`);
1001
+ if (snapshot.checkpoint) lines.push(`检查点:${String(snapshot.checkpoint)}`);
910
1002
  if (snapshot.action === "workflow_complete") {
911
- lines.push("结论:上一 Feature 已完成;可以使用 /devflow start <新功能名> 创建下一 Feature。");
1003
+ lines.push("结论:上一功能已完成;可以使用 /devflow start <功能名> 创建下一功能。");
912
1004
  } else {
913
- lines.push("结论:这是只读解释;未执行任何状态迁移或文件写入。");
1005
+ lines.push("结论:这是只读说明;未执行任何状态迁移或文件写入。");
914
1006
  }
915
1007
  return lines.join("\n");
916
1008
  }
@@ -1129,33 +1221,13 @@ export default function devflowCore(pi: ExtensionAPI) {
1129
1221
 
1130
1222
  type ProjectControlUi = {
1131
1223
  setStatus(key: string, text: string | undefined): void;
1132
- setWidget?(key: string, content: string[] | undefined, options?: { placement?: "aboveEditor" | "belowEditor" }): void;
1224
+ // OMP widgets accept either plain lines or a component factory. Keep this
1225
+ // interface structural because command contexts are supplied by OMP.
1226
+ setWidget?(key: string, content: unknown, options?: { placement?: "aboveEditor" | "belowEditor" }): void;
1133
1227
  };
1134
1228
 
1135
1229
  let projectControlRefreshRevision = 0;
1136
1230
 
1137
- function workflowSteps(snapshot: Record<string, unknown>): Array<{ id: string; label: string; status: string }> {
1138
- if (!Array.isArray(snapshot.workflow_steps)) return [];
1139
- return snapshot.workflow_steps.flatMap(step => {
1140
- if (!step || typeof step !== "object") return [];
1141
- const record = step as Record<string, unknown>;
1142
- const id = typeof record.id === "string" ? record.id : "";
1143
- if (!id) return [];
1144
- return [{
1145
- id,
1146
- label: typeof record.label === "string" && record.label ? record.label : id,
1147
- status: typeof record.status === "string" ? record.status : "unknown",
1148
- }];
1149
- });
1150
- }
1151
-
1152
- function workflowStepIcon(status: string): string {
1153
- if (status === "completed") return "✓";
1154
- if (status === "current") return "●";
1155
- if (status === "waiting_review") return "◆";
1156
- if (status === "blocked") return "!";
1157
- return "○";
1158
- }
1159
1231
 
1160
1232
  function projectActionLabel(snapshot: Record<string, unknown>): string {
1161
1233
  switch (snapshot.action) {
@@ -1166,11 +1238,11 @@ export default function devflowCore(pi: ExtensionAPI) {
1166
1238
  case "await_user_confirmation":
1167
1239
  return "审查产物后批准推进";
1168
1240
  case "recover_artifact_registry":
1169
- return "可执行安全恢复(仅 registry)";
1241
+ return "可执行安全恢复(仅工件登记)";
1170
1242
  case "workflow_complete":
1171
- return "当前 Feature 已完成";
1243
+ return "当前功能已完成";
1172
1244
  case "workflow_cancelled":
1173
- return "当前 Feature 已取消";
1245
+ return "当前功能已取消";
1174
1246
  case "blocked":
1175
1247
  return "先处理阻塞证据";
1176
1248
  default:
@@ -1184,59 +1256,78 @@ export default function devflowCore(pi: ExtensionAPI) {
1184
1256
  if (state.phase === "blocked") return `已阻塞:${state.label}`;
1185
1257
  if (snapshot.action === "await_user_confirmation") return "等待人工审查";
1186
1258
  if (snapshot.action === "blocked") return "已阻塞";
1187
- return "当前会话未运行 Agent";
1259
+ return "当前会话未运行智能体";
1188
1260
  }
1189
1261
 
1190
1262
  function projectControlPanel(snapshot: Record<string, unknown> | null, state: SessionControlState): string[] {
1191
1263
  if (!snapshot) {
1192
- return ["Devflow 当前 Feature 交付链路", "尚未读取到有效控制面状态。"];
1264
+ return ["Devflow 当前功能交付", "── 项目状态 ──", "尚未读取到有效控制面状态。"];
1193
1265
  }
1194
1266
  const steps = workflowSteps(snapshot);
1195
1267
  const completedCount = steps.filter(step => step.status === "completed").length;
1196
- const current = compactStep(snapshot.current_step) ?? compactStep(snapshot.next_step);
1268
+ const selectedStep = compactStep(snapshot.current_step) ?? compactStep(snapshot.next_step);
1269
+ const currentStep = selectedStep
1270
+ ? workflowStepName(selectedStep.id, selectedStep.label)
1271
+ : "未开始";
1272
+ const nextStep = steps.find(step => step.status !== "completed" && step.id !== selectedStep?.id)
1273
+ ?? steps.find(step => step.status !== "completed");
1197
1274
  const recovery = snapshot.recovery_plan && typeof snapshot.recovery_plan === "object"
1198
1275
  ? snapshot.recovery_plan as Record<string, unknown>
1199
1276
  : undefined;
1200
1277
  const recoveryLabel = recovery?.classification === "safe_repairable"
1201
- ? "已提供安全恢复方案(不推进步骤)"
1278
+ ? "可执行安全恢复(不会推进节点)"
1202
1279
  : snapshot.action === "blocked"
1203
- ? "没有可自动执行的重置方案;请先查看阻塞证据。"
1204
- : "当前无需恢复或重置。";
1205
- const chain = steps.length > 0
1206
- ? steps.map(step => `${workflowStepIcon(step.status)} ${step.label}`).join(" → ")
1207
- : "尚无可展示的已知工作流步骤。";
1280
+ ? "暂无自动重置方案,请先查看阻塞证据"
1281
+ : "当前无需恢复或重置";
1208
1282
  return [
1209
- `Devflow 当前 Feature 交付链路 · ${String(snapshot.current_feature ?? "未开始")}`,
1210
- `阶段:${String(snapshot.current_phase ?? "unknown")} Revision:${String(snapshot.revision ?? "unknown")}`,
1211
- `链路:${chain}`,
1212
- `进度:已完成 ${completedCount} / 当前已知 ${steps.length} 步`,
1213
- `当前节点:${current?.label ? String(current.label) : String(current?.id ?? "未开始")}`,
1214
- `工作流状态:${String(snapshot.status ?? "unknown")} 执行状态:${projectExecutionLabel(state, snapshot)}`,
1215
- `当前可执行操作:${projectActionLabel(snapshot)}`,
1216
- `恢复与重置:${recoveryLabel}`,
1283
+ `Devflow 当前功能交付 · ${String(snapshot.current_feature ?? "未开始")}`,
1284
+ `阶段:${workflowPhaseName(snapshot.current_phase)} 版本:${String(snapshot.revision ?? "未知")}`,
1285
+ "── 交付链路 ──",
1286
+ `进度:已完成 ${completedCount} / 当前已知 ${steps.length} 步 工作流:${workflowStatusName(snapshot.status)}`,
1287
+ `当前:${currentStep}${nextStep ? ` 后续:${workflowStepName(nextStep.id, nextStep.label)}` : ""}`,
1288
+ "── 当前节点 ──",
1289
+ `节点状态:${workflowStatusName(selectedStep?.status)} 执行状态:${projectExecutionLabel(state, snapshot)}`,
1290
+ `节点动作:${workflowActionName(snapshot.action)}`,
1291
+ "── 下一步执行 ──",
1292
+ `可执行操作:${projectActionLabel(snapshot)}`,
1293
+ "── 恢复与重置 ──",
1294
+ `处理建议:${recoveryLabel}`,
1217
1295
  ];
1218
1296
  }
1219
1297
 
1298
+ function projectControlWidget(lines: string[]) {
1299
+ return (_tui: unknown, theme: { fg(color: "accent" | "muted" | "dim", text: string): string; bold(text: string): string }) => {
1300
+ const panel = new Box(1, 0, undefined, {
1301
+ chars: { topLeft: "╭", topRight: "╮", bottomLeft: "╰", bottomRight: "╯", horizontal: "─", vertical: "│" },
1302
+ color: text => theme.fg("dim", text),
1303
+ });
1304
+ const content = lines.map((line, index) => {
1305
+ if (index === 0) return theme.bold(theme.fg("accent", line));
1306
+ if (line.startsWith("──")) return theme.fg("accent", line);
1307
+ return theme.fg("muted", line);
1308
+ }).join("\n");
1309
+ panel.addChild(new Text(content, 0, 0));
1310
+ return panel;
1311
+ };
1312
+ }
1313
+
1220
1314
  function refreshProjectControlPanel(ctx: { cwd: string; ui: ProjectControlUi }): void {
1221
1315
  const request = ++projectControlRefreshRevision;
1222
1316
  void inspectWorkflow(ctx.cwd).then(({ result, snapshot }) => {
1223
1317
  if (request !== projectControlRefreshRevision) return;
1224
1318
  const content = result.ok
1225
1319
  ? projectControlPanel(snapshot, controlState)
1226
- : ["Devflow 当前 Feature 交付链路", "状态读取失败;未执行任何恢复或状态迁移。"];
1227
- ctx.ui.setWidget?.("devflow-project-control", content, { placement: "aboveEditor" });
1320
+ : ["Devflow 当前功能交付", "── 项目状态 ──", "状态读取失败;未执行任何恢复或状态迁移。"];
1321
+ ctx.ui.setWidget?.("devflow-project-control", projectControlWidget(content), { placement: "aboveEditor" });
1228
1322
  }).catch(() => {
1229
1323
  if (request !== projectControlRefreshRevision) return;
1230
- ctx.ui.setWidget?.("devflow-project-control", ["Devflow 当前 Feature 交付链路", "状态读取失败;未执行任何恢复或状态迁移。"], { placement: "aboveEditor" });
1324
+ ctx.ui.setWidget?.("devflow-project-control", projectControlWidget(["Devflow 当前功能交付", "── 项目状态 ──", "状态读取失败;未执行任何恢复或状态迁移。"]), { placement: "aboveEditor" });
1231
1325
  });
1232
1326
  }
1233
1327
 
1234
1328
  function setControlState(ctx: {
1235
1329
  cwd: string;
1236
- ui: {
1237
- setStatus(key: string, text: string | undefined): void;
1238
- setWidget?(key: string, content: string[] | undefined, options?: { placement?: "aboveEditor" | "belowEditor" }): void;
1239
- };
1330
+ ui: ProjectControlUi;
1240
1331
  }, state: SessionControlState) {
1241
1332
  controlState = state;
1242
1333
  ctx.ui.setStatus("devflow-control", statusText(state));
@@ -1914,27 +2005,27 @@ export default function devflowCore(pi: ExtensionAPI) {
1914
2005
  const feature = typeof snapshot?.current_feature === "string" ? snapshot.current_feature : undefined;
1915
2006
  const status = typeof snapshot?.status === "string" ? snapshot.status : undefined;
1916
2007
  if (!inspected.result.ok || revision === undefined || !feature || !status || ["completed", "cancelled", "failed"].includes(status)) {
1917
- ctx.ui.notify("当前没有可取消的进行中 Feature。", "error");
2008
+ ctx.ui.notify("当前没有可取消的进行中功能。", "error");
1918
2009
  return;
1919
2010
  }
1920
- const reason = await ctx.ui.input("取消当前 Feature", "请输入取消原因");
2011
+ const reason = await ctx.ui.input("取消当前功能", "请输入取消原因");
1921
2012
  if (!reason?.trim()) return;
1922
2013
  const confirmed = await ctx.ui.confirm(
1923
- "确认取消当前 Feature",
1924
- `Feature:${feature}\n原因:${reason.trim()}\n\n将结束当前 Feature、释放项目占用并保留现有工件;未完成步骤不会被标记为完成。继续吗?`,
2014
+ "确认取消当前功能",
2015
+ `功能:${feature}\n原因:${reason.trim()}\n\n将结束当前功能、释放项目占用并保留现有工件;未完成步骤不会被标记为完成。继续吗?`,
1925
2016
  );
1926
2017
  if (!confirmed) return;
1927
2018
  const result = await runRuby(ctx.cwd, "workflow-orchestrator/scripts/advance_state.rb", [
1928
2019
  "--write", "--json", "--cancel", "--cancel-reason", reason.trim(), "--expected-revision", String(revision),
1929
2020
  ]);
1930
2021
  if (!controlPlaneSucceeded(result)) {
1931
- ctx.ui.notify(`取消当前 Feature 失败:${result.stderr || result.stdout}`, "error");
2022
+ ctx.ui.notify(`取消当前功能失败:${result.stderr || result.stdout}`, "error");
1932
2023
  return;
1933
2024
  }
1934
2025
  activeContract = undefined;
1935
2026
  contractAgentCalls = 0;
1936
2027
  setControlState(ctx, initialControlState());
1937
- ctx.ui.notify(`Feature“${feature}”已取消;现有工件已保留。`, "info");
2028
+ ctx.ui.notify(`功能“${feature}”已取消;现有工件已保留。`, "info");
1938
2029
  }
1939
2030
 
1940
2031
  async function openProjectControlPanel(ctx: ProjectControlCommandContext): Promise<void> {
@@ -1951,10 +2042,10 @@ export default function devflowCore(pi: ExtensionAPI) {
1951
2042
  if (["run_next_step", "run_parallel_window", "route_failure_branch"].includes(String(snapshot.action))) options.push("启动当前可执行步骤");
1952
2043
  if (snapshot.action === "await_user_confirmation") options.push("审查并批准推进…");
1953
2044
  if (hasSafeRecoveryPlan(snapshot)) options.push("执行安全恢复…");
1954
- if (typeof snapshot.current_feature === "string" && !["completed", "cancelled", "failed"].includes(String(snapshot.status))) options.push("取消当前 Feature…");
2045
+ if (typeof snapshot.current_feature === "string" && !["completed", "cancelled", "failed"].includes(String(snapshot.status))) options.push("取消当前功能…");
1955
2046
  options.push("关闭");
1956
2047
 
1957
- const selected = await ctx.ui.select(projectControlPanel(snapshot, controlState).join("\n"), options);
2048
+ const selected = await ctx.ui.select("项目控制操作", options);
1958
2049
  if (!selected || selected === "关闭") return;
1959
2050
  if (selected === "刷新状态") continue;
1960
2051
  if (selected === "查看状态说明") {
@@ -1978,7 +2069,7 @@ export default function devflowCore(pi: ExtensionAPI) {
1978
2069
  await executeSafeRecoveryFromPanel(ctx);
1979
2070
  return;
1980
2071
  }
1981
- if (selected === "取消当前 Feature…") {
2072
+ if (selected === "取消当前功能…") {
1982
2073
  await cancelFeatureFromPanel(ctx);
1983
2074
  return;
1984
2075
  }
package/src/constants.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export const PRODUCT_NAME = "Devflow Pi";
2
- export const PRODUCT_VERSION = "0.1.50";
2
+ export const PRODUCT_VERSION = "0.1.51";
3
3
  export const PROJECT_SCHEMA_VERSION = 1;
4
4
  export const OMP_RUNTIME_VERSION = "17.2.7";
5
5