@zhushanwen/pi-plan 0.4.6 → 0.4.8

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
@@ -2,8 +2,6 @@
2
2
 
3
3
  轻量级规划模式 pi extension:`/plan [描述]` 触发,产出结构化 plan 文件。与 coding-workflow 的区别:无 gate / review / retrospect,只负责「想清楚再动手」的计划产出(ADR pi-ext-021 prompt-only readonly / pi-ext-022 session-manager state)。
4
4
 
5
- > 本 README 的核心概念词条(Plan Mode / Plan File / Brainstorming)迁自 `docs/extensions/glossary.md`「Extension 专属概念」(2026-09-13)。
6
-
7
5
  ## 用法
8
6
 
9
7
  ```
@@ -26,7 +24,7 @@
26
24
 
27
25
  ## Plan File
28
26
 
29
- Plan Mode 的产出物,存储在 `.xyz-harness/{slug}/plan.md`(slug 截断 30 字符)。含 YAML frontmatter 与模板章节。进入 plan mode 时自动扫描既有 plan 文件供续写。
27
+ Plan Mode 的产出物,存储在 `.taiji-harness/{slug}/plan.md`(slug 截断 30 字符)。含 YAML frontmatter 与模板章节。进入 plan mode 时自动扫描既有 plan 文件供续写。
30
28
 
31
29
  ## 模板
32
30
 
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@zhushanwen/pi-plan",
3
- "version": "0.4.6",
3
+ "version": "0.4.8",
4
4
  "description": "Lightweight plan mode for Pi coding agent",
5
5
  "type": "module",
6
6
  "main": "index.ts",
7
- "xyz-agent": {
7
+ "taiji": {
8
8
  "role": "universal"
9
9
  },
10
10
  "pi": {
@@ -21,7 +21,7 @@
21
21
  "@earendil-works/pi-coding-agent": ">=0.73.0",
22
22
  "typebox": "*",
23
23
  "@earendil-works/pi-ai": "^0.84.4",
24
- "@zhushanwen/pi-goal": "0.14.2"
24
+ "@zhushanwen/pi-goal": "0.14.4"
25
25
  },
26
26
  "peerDependenciesMeta": {
27
27
  "@earendil-works/pi-ai": {
@@ -41,7 +41,7 @@
41
41
  "templates/"
42
42
  ],
43
43
  "dependencies": {
44
- "@xyz-agent/extension-protocol": "0.11.0",
44
+ "@zhushanwen/extension-protocol": "0.11.0",
45
45
  "@zhushanwen/pi-ext-guards": "0.4.0",
46
46
  "@zhushanwen/pi-extension-logger": "0.6.0"
47
47
  },
@@ -122,7 +122,7 @@ describe("registerPlanCommand", () => {
122
122
  await handler("Implement User Auth", ctx);
123
123
 
124
124
  expect(fs.mkdirSync).toHaveBeenCalledWith(
125
- "/tmp/test-project/.xyz-harness/implement-user-auth",
125
+ "/tmp/test-project/.taiji-harness/implement-user-auth",
126
126
  { recursive: true },
127
127
  );
128
128
  expect(pi.setActiveTools).toHaveBeenCalledWith(["read", "bash", "grep", "find", "ls", "plan"]);
@@ -130,7 +130,7 @@ describe("registerPlanCommand", () => {
130
130
  expect(pi.sendUserMessage).toHaveBeenCalledWith(expect.stringContaining("Implement User Auth"));
131
131
  expect(pi.appendEntry).toHaveBeenCalledWith("plan-state", {
132
132
  isActive: true,
133
- planFilePath: "/tmp/test-project/.xyz-harness/implement-user-auth/plan.md",
133
+ planFilePath: "/tmp/test-project/.taiji-harness/implement-user-auth/plan.md",
134
134
  requirement: "Implement User Auth",
135
135
  templateName: "",
136
136
  });
@@ -140,7 +140,7 @@ describe("registerPlanCommand", () => {
140
140
  await handler("Fix bug #123: 中文标题!", ctx);
141
141
 
142
142
  expect(fs.mkdirSync).toHaveBeenCalledWith(
143
- expect.stringContaining("/.xyz-harness/fix-bug-123"),
143
+ expect.stringContaining("/.taiji-harness/fix-bug-123"),
144
144
  { recursive: true },
145
145
  );
146
146
  });
@@ -150,7 +150,7 @@ describe("registerPlanCommand", () => {
150
150
  await handler("", ctx);
151
151
 
152
152
  expect(fs.mkdirSync).toHaveBeenCalledWith(
153
- "/tmp/test-project/.xyz-harness/untitled",
153
+ "/tmp/test-project/.taiji-harness/untitled",
154
154
  { recursive: true },
155
155
  );
156
156
  });
@@ -39,7 +39,7 @@ describe("PlanState", () => {
39
39
  {
40
40
  type: "custom",
41
41
  customType: "plan-state",
42
- data: { isActive: true, phase: "writing", planFilePath: ".xyz-harness/test/plan.md", requirement: "test", templateName: "feature-plan" },
42
+ data: { isActive: true, phase: "writing", planFilePath: ".taiji-harness/test/plan.md", requirement: "test", templateName: "feature-plan" },
43
43
  },
44
44
  ],
45
45
  },
@@ -56,7 +56,7 @@ describe("State persistence", () => {
56
56
  const mockPi = { appendEntry: vi.fn() } as unknown as ExtensionAPI;
57
57
  const state: PlanState = {
58
58
  isActive: true,
59
- planFilePath: ".xyz-harness/test/plan.md",
59
+ planFilePath: ".taiji-harness/test/plan.md",
60
60
  requirement: "test requirement",
61
61
  templateName: "feature-plan",
62
62
  };
@@ -66,7 +66,7 @@ describe("State persistence", () => {
66
66
  // 精确匹配:新写的 plan-state entry 无 phase 字段(V5② 守卫)
67
67
  expect(mockPi.appendEntry).toHaveBeenCalledWith("plan-state", {
68
68
  isActive: true,
69
- planFilePath: ".xyz-harness/test/plan.md",
69
+ planFilePath: ".taiji-harness/test/plan.md",
70
70
  requirement: "test requirement",
71
71
  templateName: "feature-plan",
72
72
  });
@@ -91,7 +91,7 @@ describe("State persistence", () => {
91
91
  data: {
92
92
  isActive: true,
93
93
  phase: "writing",
94
- planFilePath: ".xyz-harness/test/plan.md",
94
+ planFilePath: ".taiji-harness/test/plan.md",
95
95
  requirement: "test",
96
96
  templateName: "feature-plan",
97
97
  },
@@ -102,7 +102,7 @@ describe("State persistence", () => {
102
102
 
103
103
  const state = reconstructPlanState(mockCtx);
104
104
  expect(state.isActive).toBe(true);
105
- expect(state.planFilePath).toBe(".xyz-harness/test/plan.md");
105
+ expect(state.planFilePath).toBe(".taiji-harness/test/plan.md");
106
106
  });
107
107
 
108
108
  it("reconstructPlanState ignores the legacy phase field in old entries (D6 兼容读 — V5②)", () => {
@@ -116,7 +116,7 @@ describe("State persistence", () => {
116
116
  data: {
117
117
  isActive: true,
118
118
  phase: "brainstorming",
119
- planFilePath: ".xyz-harness/legacy/plan.md",
119
+ planFilePath: ".taiji-harness/legacy/plan.md",
120
120
  requirement: "legacy",
121
121
  templateName: "feature-plan",
122
122
  },
@@ -128,7 +128,7 @@ describe("State persistence", () => {
128
128
  const state = reconstructPlanState(mockCtx);
129
129
  expect(Object.keys(state).sort()).toEqual(["isActive", "planFilePath", "requirement", "templateName"]);
130
130
  expect(state.isActive).toBe(true);
131
- expect(state.planFilePath).toBe(".xyz-harness/legacy/plan.md");
131
+ expect(state.planFilePath).toBe(".taiji-harness/legacy/plan.md");
132
132
  expect(state.requirement).toBe("legacy");
133
133
  expect(state.templateName).toBe("feature-plan");
134
134
  });
package/src/command.ts CHANGED
@@ -58,10 +58,10 @@ export function registerPlanCommand(
58
58
  return;
59
59
  }
60
60
 
61
- // Reentry: check for existing plan files in .xyz-harness/
61
+ // Reentry: check for existing plan files in .taiji-harness/
62
62
  if (!state.isActive && !trimmed) {
63
63
  const projectDir = ctx.cwd;
64
- const harnessDir = path.join(projectDir, ".xyz-harness");
64
+ const harnessDir = path.join(projectDir, ".taiji-harness");
65
65
  const existingPlans = findExistingPlans(harnessDir);
66
66
  if (existingPlans.length > 0) {
67
67
  pi.sendUserMessage(
@@ -116,7 +116,7 @@ function handleStatus(
116
116
  );
117
117
  }
118
118
 
119
- /** Find existing plan.md files in .xyz-harness/ subdirectories */
119
+ /** Find existing plan.md files in .taiji-harness/ subdirectories */
120
120
  function findExistingPlans(harnessDir: string): string[] {
121
121
  try {
122
122
  return fs.readdirSync(harnessDir)
@@ -144,7 +144,7 @@ function handleEnterPlanMode(
144
144
  : "untitled";
145
145
 
146
146
  const projectDir = ctx.cwd;
147
- const planDir = path.join(projectDir, ".xyz-harness", slug);
147
+ const planDir = path.join(projectDir, ".taiji-harness", slug);
148
148
  fs.mkdirSync(planDir, { recursive: true });
149
149
  const planFilePath = path.join(planDir, "plan.md");
150
150
 
package/src/tool.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { StringEnum } from "@earendil-works/pi-ai";
2
2
  import type { ExtensionAPI, ExtensionContext, Theme, ThemeColor } from "@earendil-works/pi-coding-agent";
3
3
  import { Text } from "@earendil-works/pi-tui";
4
- import { firstContentText } from "@xyz-agent/extension-protocol";
4
+ import { firstContentText } from "@zhushanwen/extension-protocol";
5
5
  import { Type } from "typebox";
6
6
 
7
7
  import { detectGoalCapability, GOAL_FAILURE_RECOVERY, handlePlanComplete } from "./compact.js";