@unifan/pi-unifan-zh 1.0.37 → 1.0.39

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.
@@ -387,33 +387,15 @@ export default function workflowExtension(pi: ExtensionAPI) {
387
387
  }
388
388
  });
389
389
 
390
- const WORKFLOW_SHORTCUTS: Record<string, string> = {
391
- "00": "00-next",
392
- "/00": "00-next",
393
- "01": "01-brainstorm",
394
- "/01": "01-brainstorm",
395
- "02": "02-plan",
396
- "/02": "02-plan",
397
- "03": "03-work",
398
- "/03": "03-work",
399
- "04": "04-review",
400
- "/04": "04-review",
401
- "05": "05-learn",
402
- "/05": "05-learn",
403
- };
404
-
405
- // 监听用户打断指令与极简快捷指令(如输入 01 自动转为 /skill:01-brainstorm)
390
+ // 监听用户打断指令:用户若输入“暂停”或“停止”,自动安全挂起 03 自主循环
406
391
  pi.on("input", async (event, ctx) => {
407
392
  if (event.source === "extension") return { action: "continue" };
408
393
 
409
- const raw = event.text.trim();
410
- const lower = raw.toLowerCase();
411
-
412
- // 1. 暂停/打断指令:用户若输入“暂停”或“停止”,自动安全挂起 03 自主循环
394
+ const text = event.text.trim().toLowerCase();
413
395
  if (
414
396
  workDriverInstance &&
415
397
  workDriverInstance.getStatus().isActive &&
416
- (lower === "暂停" || lower === "停止" || lower === "pause" || lower === "stop")
398
+ (text === "暂停" || text === "停止" || text === "pause" || text === "stop")
417
399
  ) {
418
400
  detachEscapeListener();
419
401
  await workDriverInstance.pause("用户手动输入暂停");
@@ -425,23 +407,6 @@ export default function workflowExtension(pi: ExtensionAPI) {
425
407
  return { action: "handled" };
426
408
  }
427
409
 
428
- // 2. 阶段编号快捷直达:输入 00~05 自动转换为 /skill:0x-xxx
429
- const match = raw.match(/^(\/?0[0-5])(?:\s+(.*))?$/);
430
- if (match) {
431
- const shortcutKey = match[1];
432
- const skillName = WORKFLOW_SHORTCUTS[shortcutKey];
433
- if (skillName) {
434
- // 若当前正在 03 自主干活中,切换阶段时先优雅暂停 03
435
- if (skillName !== "03-work" && workDriverInstance && workDriverInstance.getStatus().isActive) {
436
- detachEscapeListener();
437
- await workDriverInstance.pause(`用户通过快捷键切换至 ${skillName}`);
438
- ctx.ui?.setStatus?.("workflow", undefined);
439
- }
440
- const rest = match[2] ? ` ${match[2]}` : "";
441
- return { action: "transform", text: `/skill:${skillName}${rest}` };
442
- }
443
- }
444
-
445
410
  return { action: "continue" };
446
411
  });
447
412
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unifan/pi-workflow-zh",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Pi 复合工程工作流引擎(状态感知 / 断点续跑 / 输出压缩 / 自动化工具集)",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -8,22 +8,17 @@ export function isExplicit03WorkTrigger(prompt: string): boolean {
8
8
  const lower = trimmed.toLowerCase();
9
9
 
10
10
  // 1. Direct skill invocation or slash command
11
- if (
12
- lower.startsWith("/skill:03-work") ||
13
- lower === "/skill:03" ||
14
- lower.startsWith("03-work")
15
- ) {
11
+ if (lower.startsWith("/skill:03-work")) {
16
12
  return true;
17
13
  }
18
14
 
19
15
  // 2. Strict keywords and natural language commands to start/resume 03 work
20
16
  const strictPatterns = [
21
- /^(\/)?(03|03-work)$/i,
22
- /^开始(03|干活|编码|实现|写代码)/,
23
- /^执行(03|03-work|干活)/,
17
+ /^开始(干活|编码|实现|写代码)/,
18
+ /^执行03-work/,
24
19
  /^自主(干活|工作|编码)/,
25
- /^(继续|恢复)(干活|03|工作|work)/i,
26
- /^resume\s+(03|work)/i,
20
+ /^(继续|恢复)(干活|工作|work)/i,
21
+ /^resume\s+work/i,
27
22
  ];
28
23
 
29
24
  if (strictPatterns.some((p) => p.test(trimmed))) {
@@ -290,16 +290,10 @@ test("workflowExtension: registers tools and command cleanly", async () => {
290
290
  assert.ok(listeners.has("input"));
291
291
  assert.ok(listeners.has("agent_settled"));
292
292
 
293
- // Verify 00~05 shortcut transforms
293
+ // Verify input handler passes through standard inputs and handles pause
294
294
  const inputHandler = listeners.get("input");
295
- const res01 = await inputHandler({ text: "01", source: "interactive" }, {});
296
- assert.deepEqual(res01, { action: "transform", text: "/skill:01-brainstorm" });
297
-
298
- const res01WithText = await inputHandler({ text: "01 补充需求边界", source: "interactive" }, {});
299
- assert.deepEqual(res01WithText, { action: "transform", text: "/skill:01-brainstorm 补充需求边界" });
300
-
301
- const res00 = await inputHandler({ text: "00", source: "interactive" }, {});
302
- assert.deepEqual(res00, { action: "transform", text: "/skill:00-next" });
295
+ const resPassThrough = await inputHandler({ text: "/skill:01-brainstorm", source: "interactive" }, {});
296
+ assert.deepEqual(resPassThrough, { action: "continue" });
303
297
 
304
298
  const resNormal = await inputHandler({ text: "1. 选第一个方案", source: "interactive" }, {});
305
299
  assert.deepEqual(resNormal, { action: "continue" });
@@ -479,20 +473,19 @@ test("WorkLoopDriver: records failure history and triggers Stop-The-Line valve o
479
473
  test("isExplicit03WorkTrigger: accurately identifies 03-work invocations vs harmless inputs", async () => {
480
474
  // Should match explicit 03 triggers
481
475
  assert.equal(isExplicit03WorkTrigger("/skill:03-work"), true);
482
- assert.equal(isExplicit03WorkTrigger("/skill:03"), true);
483
- assert.equal(isExplicit03WorkTrigger("03-work"), true);
484
- assert.equal(isExplicit03WorkTrigger("03-work docs/plans/plan.md"), true);
485
- assert.equal(isExplicit03WorkTrigger("03"), true);
486
- assert.equal(isExplicit03WorkTrigger("/03"), true);
487
476
  assert.equal(isExplicit03WorkTrigger("开始干活"), true);
488
- assert.equal(isExplicit03WorkTrigger("开始03"), true);
489
477
  assert.equal(isExplicit03WorkTrigger("开始实现"), true);
490
- assert.equal(isExplicit03WorkTrigger("执行03"), true);
478
+ assert.equal(isExplicit03WorkTrigger("执行03-work"), true);
491
479
  assert.equal(isExplicit03WorkTrigger("继续干活"), true);
492
480
  assert.equal(isExplicit03WorkTrigger("恢复干活"), true);
493
481
  assert.equal(isExplicit03WorkTrigger("resume work"), true);
494
482
  assert.equal(isExplicit03WorkTrigger("【03-work 自主循环驱动引擎 · 自动化续跑指令】"), true);
495
483
 
484
+ // Alias /skill:03 or plain numbers must NEVER trigger (strictly require full skill name /skill:03-work)
485
+ assert.equal(isExplicit03WorkTrigger("/skill:03"), false);
486
+ assert.equal(isExplicit03WorkTrigger("03"), false);
487
+ assert.equal(isExplicit03WorkTrigger("/03"), false);
488
+
496
489
  // Must NEVER match other skills or normal dialogue (prevents false auto-starts!)
497
490
  assert.equal(isExplicit03WorkTrigger("00"), false);
498
491
  assert.equal(isExplicit03WorkTrigger("/skill:00-next"), false);
@@ -683,37 +676,22 @@ test("E2E Lifecycle: 01 brainstorm -> 02 plan -> 01 rollback -> 03 work -> compa
683
676
  assert.equal(state.recommendedSkill, "03-work");
684
677
  assert.equal(state.totalUnitsCount, 3);
685
678
 
686
- // 4. User is in 02, realizes requirements need changes -> Rolls back to 01!
687
- // (Simulate input event transform)
688
- const listeners = new Map();
689
- const mockPi = {
690
- registerTool() {},
691
- registerCommand() {},
692
- on(event, handler) {
693
- listeners.set(event, handler);
694
- },
695
- };
696
- workflowExtension(mockPi);
697
- const inputHandler = listeners.get("input");
698
-
699
- // User types "01 增加第三方登录"
700
- const transformRes = await inputHandler({ text: "01 增加第三方登录", source: "interactive" }, {});
701
- assert.deepEqual(transformRes, {
702
- action: "transform",
703
- text: "/skill:01-brainstorm 增加第三方登录",
704
- });
705
-
706
- // User updates brainstorm file
679
+ // 4. User is in 02, realizes requirements need changes -> Rolls back to 01 via /skill:01-brainstorm
680
+ // In standard Pi, user runs /skill:01-brainstorm to revisit requirements
707
681
  await writeFile(bsFile, "# Auth Requirements\nScope: login, register, oauth2", "utf-8");
708
682
 
709
- // 5. User returns to 02
710
- const returnTo02 = await inputHandler({ text: "02", source: "interactive" }, {});
711
- assert.deepEqual(returnTo02, {
712
- action: "transform",
713
- text: "/skill:02-plan",
714
- });
683
+ // 5. User returns to 02 via /skill:02-plan and updates the plan
684
+ await writeFile(
685
+ planFile,
686
+ "# Auth Plan\n### Unit 0 — DB Schema\n### Unit 1 — API Route & OAuth2\n### Unit 2 — Tests",
687
+ "utf-8",
688
+ );
715
689
 
716
- // 6. User enters 03 -> starts autonomous work
690
+ state = await detectWorkflowState(testRoot);
691
+ assert.equal(state.recommendedSkill, "03-work");
692
+
693
+ // 6. User enters 03 -> starts autonomous work via /skill:03-work
694
+ assert.equal(isExplicit03WorkTrigger("/skill:03-work"), true);
717
695
  const driver = new WorkLoopDriver(testRoot);
718
696
  const startRes = await driver.start(planFile);
719
697
  assert.equal(startRes.success, true);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unifan/pi-unifan-zh",
3
- "version": "1.0.37",
3
+ "version": "1.0.39",
4
4
  "description": "Pi Coding Agent 中文扩展全家桶与独立插件集",
5
5
  "type": "module",
6
6
  "main": "extensions/sessions/index.ts",