pan-wizard 2.9.1 → 3.5.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.
Files changed (75) hide show
  1. package/README.md +31 -9
  2. package/agents/pan-conductor.md +189 -0
  3. package/agents/pan-counterfactual.md +112 -0
  4. package/agents/pan-debugger.md +15 -1
  5. package/agents/pan-distiller.md +82 -0
  6. package/agents/pan-document_code.md +21 -0
  7. package/agents/pan-executor.md +16 -0
  8. package/agents/pan-hardener.md +113 -0
  9. package/agents/pan-integration-checker.md +2 -0
  10. package/agents/pan-knowledge.md +81 -0
  11. package/agents/pan-meta-reviewer.md +91 -0
  12. package/agents/pan-optimizer.md +242 -0
  13. package/agents/pan-plan-checker.md +2 -0
  14. package/agents/pan-previewer.md +98 -0
  15. package/agents/pan-project-researcher.md +4 -4
  16. package/agents/pan-reviewer.md +2 -0
  17. package/agents/pan-verifier.md +2 -0
  18. package/bin/install-lib.cjs +197 -0
  19. package/bin/install.js +2048 -1959
  20. package/commands/pan/cost.md +132 -0
  21. package/commands/pan/exec-phase.md +15 -0
  22. package/commands/pan/focus-auto.md +168 -3
  23. package/commands/pan/focus-exec.md +21 -1
  24. package/commands/pan/focus-scan.md +6 -0
  25. package/commands/pan/git.md +223 -0
  26. package/commands/pan/knowledge.md +129 -0
  27. package/commands/pan/learn.md +61 -0
  28. package/commands/pan/map-codebase.md +15 -0
  29. package/commands/pan/mcp-bridge.md +145 -0
  30. package/commands/pan/milestone-done.md +9 -0
  31. package/commands/pan/optimize.md +86 -0
  32. package/commands/pan/plan-phase.md +11 -0
  33. package/commands/pan/preview.md +114 -0
  34. package/commands/pan/profile.md +37 -0
  35. package/commands/pan/review-deep.md +128 -0
  36. package/commands/pan/verify-phase.md +11 -0
  37. package/commands/pan/what-if.md +146 -0
  38. package/hooks/dist/pan-cost-logger.js +102 -0
  39. package/hooks/dist/pan-statusline.js +154 -108
  40. package/hooks/dist/pan-trace-logger.js +197 -0
  41. package/package.json +1 -1
  42. package/pan-wizard-core/bin/lib/bridge.cjs +269 -0
  43. package/pan-wizard-core/bin/lib/bus.cjs +251 -0
  44. package/pan-wizard-core/bin/lib/codebase.cjs +118 -0
  45. package/pan-wizard-core/bin/lib/commands.cjs +1 -0
  46. package/pan-wizard-core/bin/lib/constants.cjs +44 -1
  47. package/pan-wizard-core/bin/lib/context-budget.cjs +27 -0
  48. package/pan-wizard-core/bin/lib/core.cjs +91 -6
  49. package/pan-wizard-core/bin/lib/cost.cjs +359 -0
  50. package/pan-wizard-core/bin/lib/distill.cjs +510 -0
  51. package/pan-wizard-core/bin/lib/focus.cjs +108 -3
  52. package/pan-wizard-core/bin/lib/git.cjs +407 -0
  53. package/pan-wizard-core/bin/lib/init.cjs +5 -5
  54. package/pan-wizard-core/bin/lib/knowledge.cjs +331 -0
  55. package/pan-wizard-core/bin/lib/memory.cjs +252 -0
  56. package/pan-wizard-core/bin/lib/optimize.cjs +653 -0
  57. package/pan-wizard-core/bin/lib/phase.cjs +40 -13
  58. package/pan-wizard-core/bin/lib/preview.cjs +480 -0
  59. package/pan-wizard-core/bin/lib/review-deep.cjs +280 -0
  60. package/pan-wizard-core/bin/lib/roadmap.cjs +4 -4
  61. package/pan-wizard-core/bin/lib/state.cjs +2 -2
  62. package/pan-wizard-core/bin/lib/verify.cjs +34 -1
  63. package/pan-wizard-core/bin/lib/whatif.cjs +289 -0
  64. package/pan-wizard-core/bin/pan-tools.cjs +317 -4
  65. package/pan-wizard-core/templates/playbook.md +53 -0
  66. package/pan-wizard-core/templates/preview-report.md +93 -0
  67. package/pan-wizard-core/templates/roadmap.md +24 -24
  68. package/pan-wizard-core/templates/state.md +12 -9
  69. package/pan-wizard-core/workflows/exec-phase.md +97 -0
  70. package/pan-wizard-core/workflows/learn.md +91 -0
  71. package/pan-wizard-core/workflows/optimize.md +139 -0
  72. package/pan-wizard-core/workflows/plan-phase.md +28 -1
  73. package/pan-wizard-core/workflows/quick.md +7 -0
  74. package/pan-wizard-core/workflows/verify-phase.md +16 -0
  75. package/scripts/build-hooks.js +3 -1
@@ -1,108 +1,154 @@
1
- #!/usr/bin/env node
2
- // Claude Code Statusline - PAN Edition
3
- // Shows: model | current task | directory | context usage
4
-
5
- const fs = require('fs');
6
- const path = require('path');
7
- const os = require('os');
8
-
9
- // Read JSON from stdin
10
- let input = '';
11
- process.stdin.setEncoding('utf8');
12
- process.stdin.on('data', chunk => input += chunk);
13
- process.stdin.on('end', () => {
14
- try {
15
- const data = JSON.parse(input);
16
- const model = data.model?.display_name || 'Claude';
17
- const dir = data.workspace?.current_dir || process.cwd();
18
- const session = data.session_id || '';
19
- const remaining = data.context_window?.remaining_percentage;
20
-
21
- // Context window display (shows USED percentage scaled to 80% limit)
22
- // Claude Code enforces an 80% context limit, so we scale to show 100% at that point
23
- let ctx = '';
24
- if (remaining != null) {
25
- const rem = Math.round(remaining);
26
- const rawUsed = Math.max(0, Math.min(100, 100 - rem));
27
- // Scale: 80% real usage = 100% displayed
28
- const used = Math.min(100, Math.round((rawUsed / 80) * 100));
29
-
30
- // Write context metrics to bridge file for the context-monitor PostToolUse hook.
31
- // The monitor reads this file to inject agent-facing warnings when context is low.
32
- if (session) {
33
- try {
34
- const bridgePath = path.join(os.tmpdir(), `claude-ctx-${session}.json`);
35
- const bridgeData = JSON.stringify({
36
- session_id: session,
37
- remaining_percentage: remaining,
38
- used_pct: used,
39
- timestamp: Math.floor(Date.now() / 1000)
40
- });
41
- fs.writeFileSync(bridgePath, bridgeData);
42
- } catch (e) {
43
- // Silent fail -- bridge is best-effort, don't break statusline
44
- }
45
- }
46
-
47
- // Build progress bar (10 segments)
48
- const filled = Math.floor(used / 10);
49
- const bar = '█'.repeat(filled) + '░'.repeat(10 - filled);
50
-
51
- // Color based on scaled usage (thresholds adjusted for new scale)
52
- if (used < 63) { // ~50% real
53
- ctx = ` \x1b[32m${bar} ${used}%\x1b[0m`;
54
- } else if (used < 81) { // ~65% real
55
- ctx = ` \x1b[33m${bar} ${used}%\x1b[0m`;
56
- } else if (used < 95) { // ~76% real
57
- ctx = ` \x1b[38;5;208m${bar} ${used}%\x1b[0m`;
58
- } else {
59
- ctx = ` \x1b[5;31m💀 ${bar} ${used}%\x1b[0m`;
60
- }
61
- }
62
-
63
- // Current task from todos
64
- let task = '';
65
- const homeDir = os.homedir();
66
- const todosDir = path.join(homeDir, '.claude', 'todos');
67
- if (session && fs.existsSync(todosDir)) {
68
- try {
69
- const files = fs.readdirSync(todosDir)
70
- .filter(f => f.startsWith(session) && f.includes('-agent-') && f.endsWith('.json'))
71
- .map(f => ({ name: f, mtime: fs.statSync(path.join(todosDir, f)).mtime }))
72
- .sort((a, b) => b.mtime - a.mtime);
73
-
74
- if (files.length > 0) {
75
- try {
76
- const todos = JSON.parse(fs.readFileSync(path.join(todosDir, files[0].name), 'utf8'));
77
- const inProgress = todos.find(t => t.status === 'in_progress');
78
- if (inProgress) task = inProgress.activeForm || '';
79
- } catch (e) {}
80
- }
81
- } catch (e) {
82
- // Silently fail on file system errors - don't break statusline
83
- }
84
- }
85
-
86
- // PAN update available?
87
- let panUpdate = '';
88
- const cacheFile = path.join(homeDir, '.claude', 'cache', 'pan-update-check.json');
89
- if (fs.existsSync(cacheFile)) {
90
- try {
91
- const cache = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
92
- if (cache.update_available) {
93
- panUpdate = '\x1b[33m⬆ /pan:update\x1b[0m ';
94
- }
95
- } catch (e) {}
96
- }
97
-
98
- // Output
99
- const dirname = path.basename(dir);
100
- if (task) {
101
- process.stdout.write(`${panUpdate}\x1b[2m${model}\x1b[0m \x1b[1m${task}\x1b[0m \x1b[2m${dirname}\x1b[0m${ctx}`);
102
- } else {
103
- process.stdout.write(`${panUpdate}\x1b[2m${model}\x1b[0m │ \x1b[2m${dirname}\x1b[0m${ctx}`);
104
- }
105
- } catch (e) {
106
- // Silent fail - don't break statusline on parse errors
107
- }
108
- });
1
+ #!/usr/bin/env node
2
+ // Claude Code Statusline - PAN Edition
3
+ // Shows: model | current task | directory | context | cache | thinking
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const os = require('os');
8
+
9
+ /**
10
+ * Build the statusline output string from the JSON payload Claude Code pipes
11
+ * to stdin. Pure function — no stdin, no stdout, no process exit. Safe to
12
+ * call from tests.
13
+ *
14
+ * @param {Object} data - Parsed stdin JSON from Claude Code.
15
+ * @param {Object} [deps] - Optional dep injection for testing.
16
+ * {fs, path, homeDir, tmpDir} — defaults to real modules + OS paths.
17
+ * @returns {string} The statusline content.
18
+ */
19
+ function buildStatuslineOutput(data, deps) {
20
+ const d = deps || {};
21
+ const fsMod = d.fs || fs;
22
+ const pathMod = d.path || path;
23
+ const homeDir = d.homeDir || os.homedir();
24
+ const tmpDir = d.tmpDir || os.tmpdir();
25
+
26
+ if (!data || typeof data !== 'object') return '';
27
+
28
+ const model = data.model?.display_name || 'Claude';
29
+ const dir = data.workspace?.current_dir || process.cwd();
30
+ const session = data.session_id || '';
31
+ const remaining = data.context_window?.remaining_percentage;
32
+
33
+ // Context window bar — shows USED percentage scaled so 80% real = 100% shown.
34
+ let ctx = '';
35
+ if (remaining != null) {
36
+ const rem = Math.round(remaining);
37
+ const rawUsed = Math.max(0, Math.min(100, 100 - rem));
38
+ const used = Math.min(100, Math.round((rawUsed / 80) * 100));
39
+
40
+ if (session && d.skipBridge !== true) {
41
+ try {
42
+ const bridgePath = pathMod.join(tmpDir, `claude-ctx-${session}.json`);
43
+ fsMod.writeFileSync(bridgePath, JSON.stringify({
44
+ session_id: session,
45
+ remaining_percentage: remaining,
46
+ used_pct: used,
47
+ timestamp: Math.floor(Date.now() / 1000),
48
+ }));
49
+ } catch { /* bridge is best-effort */ }
50
+ }
51
+
52
+ const filled = Math.floor(used / 10);
53
+ const bar = '█'.repeat(filled) + '░'.repeat(10 - filled);
54
+
55
+ if (used < 63) {
56
+ ctx = ` \x1b[32m${bar} ${used}%\x1b[0m`;
57
+ } else if (used < 81) {
58
+ ctx = ` \x1b[33m${bar} ${used}%\x1b[0m`;
59
+ } else if (used < 95) {
60
+ ctx = ` \x1b[38;5;208m${bar} ${used}%\x1b[0m`;
61
+ } else {
62
+ ctx = ` \x1b[5;31m💀 ${bar} ${used}%\x1b[0m`;
63
+ }
64
+ }
65
+
66
+ // E-8: Opus 4.7 indicators. Read from stdin data first (if present),
67
+ // else merge from optional bridge file `claude-pan-<session>.json` that
68
+ // an agent or external process can write.
69
+ let panExtras = null;
70
+ if (session) {
71
+ try {
72
+ const extrasPath = pathMod.join(tmpDir, `claude-pan-${session}.json`);
73
+ const extrasRaw = fsMod.readFileSync(extrasPath, 'utf8');
74
+ panExtras = JSON.parse(extrasRaw);
75
+ } catch { /* no extras is fine */ }
76
+ }
77
+
78
+ const thinkingActive = (data.thinking && data.thinking.active === true)
79
+ || (panExtras && panExtras.thinking_active === true);
80
+ const cacheHitRate = (data.cache && typeof data.cache.hit_rate_pct === 'number')
81
+ ? data.cache.hit_rate_pct
82
+ : (panExtras && typeof panExtras.cache_hit_rate_pct === 'number'
83
+ ? panExtras.cache_hit_rate_pct
84
+ : null);
85
+
86
+ let thinkingBadge = '';
87
+ if (thinkingActive) thinkingBadge = ' \x1b[35m🧠\x1b[0m';
88
+
89
+ let cacheBadge = '';
90
+ if (cacheHitRate != null) {
91
+ const pct = Math.max(0, Math.min(100, Math.round(cacheHitRate)));
92
+ // Color: green ≥70%, yellow 30-70%, dim <30% (warmup).
93
+ const color = pct >= 70 ? '\x1b[32m' : pct >= 30 ? '\x1b[33m' : '\x1b[2m';
94
+ cacheBadge = ` ${color}⚡${pct}%\x1b[0m`;
95
+ }
96
+
97
+ // Current task from todos
98
+ let task = '';
99
+ const todosDir = pathMod.join(homeDir, '.claude', 'todos');
100
+ let todosExists = false;
101
+ try { todosExists = fsMod.statSync(todosDir).isDirectory(); } catch { /* missing */ }
102
+ if (session && todosExists) {
103
+ try {
104
+ const files = fsMod.readdirSync(todosDir)
105
+ .filter(f => f.startsWith(session) && f.includes('-agent-') && f.endsWith('.json'))
106
+ .map(f => {
107
+ try { return { name: f, mtime: fsMod.statSync(pathMod.join(todosDir, f)).mtime }; }
108
+ catch { return null; }
109
+ })
110
+ .filter(Boolean)
111
+ .sort((a, b) => b.mtime - a.mtime);
112
+
113
+ if (files.length > 0) {
114
+ try {
115
+ const todos = JSON.parse(fsMod.readFileSync(pathMod.join(todosDir, files[0].name), 'utf8'));
116
+ const inProgress = todos.find(t => t.status === 'in_progress');
117
+ if (inProgress) task = inProgress.activeForm || '';
118
+ } catch { /* malformed todos file — skip */ }
119
+ }
120
+ } catch { /* fs errors — silent */ }
121
+ }
122
+
123
+ // PAN update available?
124
+ let panUpdate = '';
125
+ const cacheFile = pathMod.join(homeDir, '.claude', 'cache', 'pan-update-check.json');
126
+ try {
127
+ const cache = JSON.parse(fsMod.readFileSync(cacheFile, 'utf8'));
128
+ if (cache.update_available) panUpdate = '\x1b[33m⬆ /pan:update\x1b[0m │ ';
129
+ } catch { /* no update cache — silent */ }
130
+
131
+ const dirname = pathMod.basename(dir);
132
+ const head = `${panUpdate}\x1b[2m${model}\x1b[0m`;
133
+ const taskSegment = task ? ` │ \x1b[1m${task}\x1b[0m` : '';
134
+ const dirSegment = ` │ \x1b[2m${dirname}\x1b[0m`;
135
+ return `${head}${taskSegment}${dirSegment}${ctx}${cacheBadge}${thinkingBadge}`;
136
+ }
137
+
138
+ // ─── Stdin driver ───────────────────────────────────────────────────────────
139
+
140
+ if (require.main === module) {
141
+ let input = '';
142
+ process.stdin.setEncoding('utf8');
143
+ process.stdin.on('data', chunk => input += chunk);
144
+ process.stdin.on('end', () => {
145
+ try {
146
+ const data = JSON.parse(input);
147
+ process.stdout.write(buildStatuslineOutput(data));
148
+ } catch {
149
+ // Silent fail — don't break statusline on parse errors.
150
+ }
151
+ });
152
+ }
153
+
154
+ module.exports = { buildStatuslineOutput };
@@ -0,0 +1,197 @@
1
+ #!/usr/bin/env node
2
+ // pan-trace-logger — SubagentStop hook (v3.5+).
3
+ //
4
+ // Fires alongside pan-cost-logger on every SubagentStop event. If a trace
5
+ // session is active (.planning/optimization/current-session exists), this
6
+ // hook appends a completion event to the trace. This is the automatic
7
+ // instrumentation layer of the circular optimization loop — no extra user
8
+ // action required.
9
+ //
10
+ // Events logged per subagent:
11
+ // - completion: agent finished, tokens used, exit status
12
+ // - redundancy: detected when the same agent type ran twice in this session
13
+ // with similar token counts (rough heuristic for repeated work)
14
+ //
15
+ // Errors are swallowed — this hook must never block the main agent loop.
16
+
17
+ const fs = require('fs');
18
+ const path = require('path');
19
+
20
+ const PLANNING_DIR = '.planning';
21
+ const OPTIMIZE_DIR = 'optimization';
22
+ const TRACES_DIR = 'traces';
23
+ const CURRENT_SESSION_FILE = 'current-session';
24
+ const TRACE_EVENT_FILE = 'trace.jsonl';
25
+
26
+ function getOptimizeDir(cwd) {
27
+ return path.join(cwd, PLANNING_DIR, OPTIMIZE_DIR);
28
+ }
29
+
30
+ function getTracesDir(cwd) {
31
+ return path.join(getOptimizeDir(cwd), TRACES_DIR);
32
+ }
33
+
34
+ function getCurrentSessionId(cwd) {
35
+ try {
36
+ return fs.readFileSync(path.join(getOptimizeDir(cwd), CURRENT_SESSION_FILE), 'utf-8').trim() || null;
37
+ } catch {
38
+ return null;
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Ensure a trace session exists. If none is active, create a day-scoped
44
+ * auto-session so tracing works across the whole flow without manual init.
45
+ *
46
+ * @param {string} cwd
47
+ * @returns {string} The active session ID
48
+ */
49
+ function ensureSessionId(cwd) {
50
+ const existing = getCurrentSessionId(cwd);
51
+ if (existing) return existing;
52
+
53
+ // Create a day-scoped auto session
54
+ const now = new Date();
55
+ const stamp = now.toISOString().replace(/[-:T]/g, '').slice(0, 8); // YYYYMMDD
56
+ const sessionId = `sess_auto_${stamp}`;
57
+ try {
58
+ const sessionDir = path.join(getTracesDir(cwd), sessionId);
59
+ fs.mkdirSync(sessionDir, { recursive: true });
60
+ const meta = {
61
+ session_id: sessionId,
62
+ started_at: now.toISOString(),
63
+ description: 'auto-session (day-scoped)',
64
+ auto: true,
65
+ event_count: 0,
66
+ };
67
+ fs.writeFileSync(path.join(sessionDir, 'session.json'), JSON.stringify(meta, null, 2) + '\n');
68
+ const optimizeDir = getOptimizeDir(cwd);
69
+ fs.mkdirSync(optimizeDir, { recursive: true });
70
+ fs.writeFileSync(path.join(optimizeDir, CURRENT_SESSION_FILE), sessionId + '\n');
71
+ return sessionId;
72
+ } catch {
73
+ return sessionId; // Return the ID even if write fails — best effort
74
+ }
75
+ }
76
+
77
+ function extractNumber(obj, key) {
78
+ if (!obj || typeof obj !== 'object') return 0;
79
+ const v = obj[key];
80
+ return typeof v === 'number' ? v : 0;
81
+ }
82
+
83
+ /**
84
+ * Build trace event(s) from a SubagentStop payload.
85
+ * Pure function — no side effects.
86
+ *
87
+ * @param {Object} data - SubagentStop event payload
88
+ * @returns {Object[]} Array of trace event records
89
+ */
90
+ function buildTraceEvents(data, sessionId) {
91
+ if (!data || typeof data !== 'object') return [];
92
+ if (data.hook_event_name && data.hook_event_name !== 'SubagentStop') return [];
93
+
94
+ const ts = new Date().toISOString();
95
+ const agent = data.agent_type || data.subagent_type || 'unknown';
96
+ const inputTokens = extractNumber(data.usage, 'input_tokens');
97
+ const outputTokens = extractNumber(data.usage, 'output_tokens');
98
+ const cacheRead = extractNumber(data.usage, 'cache_read_input_tokens');
99
+ const totalTokens = inputTokens + outputTokens;
100
+
101
+ const events = [];
102
+
103
+ // Core completion event
104
+ events.push({
105
+ ts,
106
+ session: sessionId,
107
+ agent,
108
+ phase: data.phase || null,
109
+ type: 'decision',
110
+ category: 'agent_completion',
111
+ description: `${agent} completed`,
112
+ context: {
113
+ model: data.model || null,
114
+ input_tokens: inputTokens,
115
+ output_tokens: outputTokens,
116
+ cache_read_tokens: cacheRead,
117
+ total_tokens: totalTokens,
118
+ exit_code: data.exit_code || 0,
119
+ },
120
+ impact: 'trivial',
121
+ correction: null,
122
+ tokens_wasted: null,
123
+ });
124
+
125
+ // Heuristic: if output tokens > 3000 and no cache hits, flag as potential redundancy
126
+ // (expensive agent run that wasn't cached — may be repeated research)
127
+ if (outputTokens > 3000 && cacheRead === 0) {
128
+ events.push({
129
+ ts,
130
+ session: sessionId,
131
+ agent,
132
+ phase: data.phase || null,
133
+ type: 'redundancy',
134
+ category: 'uncached_heavy_run',
135
+ description: `${agent} produced ${outputTokens} output tokens with zero cache hits — possible repeated research`,
136
+ context: { output_tokens: outputTokens, cache_read_tokens: 0 },
137
+ impact: 'minor',
138
+ correction: null,
139
+ tokens_wasted: outputTokens,
140
+ });
141
+ }
142
+
143
+ return events;
144
+ }
145
+
146
+ /**
147
+ * Append trace events to the active session.
148
+ * Returns true if written, false if no session or write failed.
149
+ *
150
+ * @param {string} cwd
151
+ * @param {Object[]} events
152
+ * @param {string} sessionId
153
+ */
154
+ function appendTraceEvents(cwd, events, sessionId) {
155
+ if (!events.length) return false;
156
+ try {
157
+ const sessionDir = path.join(getTracesDir(cwd), sessionId);
158
+ fs.mkdirSync(sessionDir, { recursive: true });
159
+ const lines = events.map(e => JSON.stringify(e)).join('\n') + '\n';
160
+ fs.appendFileSync(path.join(sessionDir, TRACE_EVENT_FILE), lines, 'utf-8');
161
+ return true;
162
+ } catch {
163
+ return false;
164
+ }
165
+ }
166
+
167
+ // ─── Stdin driver ────────────────────────────────────────────────────────────
168
+
169
+ if (require.main === module) {
170
+ let input = '';
171
+ process.stdin.setEncoding('utf8');
172
+ process.stdin.on('data', chunk => (input += chunk));
173
+ process.stdin.on('end', () => {
174
+ try {
175
+ const data = JSON.parse(input);
176
+ const cwd = data.cwd || data.workspace?.current_dir || process.cwd();
177
+ // Always ensure a session exists — creates a day-scoped auto-session if needed
178
+ const sessionId = ensureSessionId(cwd);
179
+ const events = buildTraceEvents(data, sessionId);
180
+ appendTraceEvents(cwd, events, sessionId);
181
+ } catch {
182
+ // Silent fail
183
+ }
184
+ });
185
+ }
186
+
187
+ module.exports = {
188
+ buildTraceEvents,
189
+ appendTraceEvents,
190
+ getCurrentSessionId,
191
+ ensureSessionId,
192
+ PLANNING_DIR,
193
+ OPTIMIZE_DIR,
194
+ TRACES_DIR,
195
+ CURRENT_SESSION_FILE,
196
+ TRACE_EVENT_FILE,
197
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pan-wizard",
3
- "version": "2.9.1",
3
+ "version": "3.5.0",
4
4
  "description": "A lightweight workflow automation and context engineering system for Claude Code, OpenCode, Gemini CLI, Codex, and Copilot CLI.",
5
5
  "bin": {
6
6
  "pan-wizard": "bin/install.js"