@dreki-gg/pi-plan-mode 0.2.0 → 0.3.0

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.
@@ -1,9 +1,14 @@
1
+ /**
2
+ * Pure utility functions for plan mode.
3
+ */
4
+
1
5
  export interface TodoItem {
2
6
  step: number;
3
7
  text: string;
4
8
  completed: boolean;
5
9
  }
6
10
 
11
+ // ── Destructive bash patterns (blocked in plan mode) ────────────────────────
7
12
  const DESTRUCTIVE_PATTERNS = [
8
13
  /\brm\b/i,
9
14
  /\brmdir\b/i,
@@ -40,6 +45,7 @@ const DESTRUCTIVE_PATTERNS = [
40
45
  /\b(vim?|nano|emacs|code|subl)\b/i,
41
46
  ];
42
47
 
48
+ // ── Safe read-only bash patterns (allowed in plan mode) ─────────────────────
43
49
  const SAFE_PATTERNS = [
44
50
  /^\s*cat\b/,
45
51
  /^\s*head\b/,
@@ -80,6 +86,7 @@ const SAFE_PATTERNS = [
80
86
  /^\s*git\s+ls-/i,
81
87
  /^\s*npm\s+(list|ls|view|info|search|outdated|audit)/i,
82
88
  /^\s*yarn\s+(list|info|why|audit)/i,
89
+ /^\s*pnpm\s+(list|ls|why|audit|outdated)/i,
83
90
  /^\s*node\s+--version/i,
84
91
  /^\s*python\s+--version/i,
85
92
  /^\s*curl\s/i,
@@ -94,24 +101,26 @@ const SAFE_PATTERNS = [
94
101
  ];
95
102
 
96
103
  export function isSafeCommand(command: string): boolean {
97
- const isDestructive = DESTRUCTIVE_PATTERNS.some((pattern) => pattern.test(command));
98
- const isSafe = SAFE_PATTERNS.some((pattern) => pattern.test(command));
104
+ const isDestructive = DESTRUCTIVE_PATTERNS.some((p) => p.test(command));
105
+ const isSafe = SAFE_PATTERNS.some((p) => p.test(command));
99
106
  return !isDestructive && isSafe;
100
107
  }
101
108
 
109
+ // ── Plan extraction ─────────────────────────────────────────────────────────
110
+
102
111
  export function cleanStepText(text: string): string {
103
112
  let cleaned = text
104
113
  .replace(/\*{1,2}([^*]+)\*{1,2}/g, '$1')
105
114
  .replace(/`([^`]+)`/g, '$1')
106
- .replace(
107
- /^(Use|Run|Execute|Create|Write|Read|Check|Verify|Update|Modify|Add|Remove|Delete|Install)\s+(the\s+)?/i,
108
- '',
109
- )
110
115
  .replace(/\s+/g, ' ')
111
116
  .trim();
112
117
 
113
- if (cleaned.length > 0) cleaned = cleaned[0].toUpperCase() + cleaned.slice(1);
114
- if (cleaned.length > 80) cleaned = `${cleaned.slice(0, 77)}...`;
118
+ if (cleaned.length > 0) {
119
+ cleaned = cleaned.charAt(0).toUpperCase() + cleaned.slice(1);
120
+ }
121
+ if (cleaned.length > 60) {
122
+ cleaned = `${cleaned.slice(0, 57)}...`;
123
+ }
115
124
  return cleaned;
116
125
  }
117
126
 
@@ -153,12 +162,18 @@ export function extractDoneSteps(message: string): number[] {
153
162
  export function markCompletedSteps(text: string, items: TodoItem[]): number {
154
163
  const doneSteps = extractDoneSteps(text);
155
164
  for (const step of doneSteps) {
156
- const item = items.find((candidate) => candidate.step === step);
165
+ const item = items.find((t) => t.step === step);
157
166
  if (item) item.completed = true;
158
167
  }
159
168
  return doneSteps.length;
160
169
  }
161
170
 
162
- export function formatTodoList(items: TodoItem[]): string {
163
- return items.map((item) => `${item.step}. ${item.text}`).join('\n');
171
+ // ── Plan name utilities ─────────────────────────────────────────────────────
172
+
173
+ export function toKebabCase(name: string): string {
174
+ return name
175
+ .toLowerCase()
176
+ .replace(/[^a-z0-9]+/g, '-')
177
+ .replace(/^-+|-+$/g, '')
178
+ .slice(0, 60);
164
179
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dreki-gg/pi-plan-mode",
3
- "version": "0.2.0",
4
- "description": "Cursor-like planning workflow for pi — read-only plan mode, questionnaire-first clarification, domain-model handoffs, and implementation-plan generation",
3
+ "version": "0.3.0",
4
+ "description": "Two-phase planning workflow for pi — plan with claude-opus-4-6:medium, execute with gpt-5.5:low, with .plans/ file-based handoff",
5
5
  "keywords": [
6
6
  "pi-package"
7
7
  ],
@@ -37,7 +37,7 @@
37
37
  "typescript": "^6.0.0"
38
38
  },
39
39
  "peerDependencies": {
40
- "@mariozechner/pi-coding-agent": "*",
41
- "@mariozechner/pi-tui": "*"
40
+ "@earendil-works/pi-coding-agent": "*",
41
+ "@earendil-works/pi-tui": "*"
42
42
  }
43
43
  }