@zhushanwen/pi-evolve-daily 0.1.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.
package/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { default } from "./src/index";
package/package.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "@zhushanwen/pi-evolve-daily",
3
+ "version": "0.1.0",
4
+ "description": "Daily evolution data collector — runs Python analyzer on first session of the day.",
5
+ "main": "src/index.ts",
6
+ "files": [
7
+ "src/",
8
+ "index.ts",
9
+ "skills/"
10
+ ],
11
+ "peerDependencies": {
12
+ "@mariozechner/pi-coding-agent": "*"
13
+ },
14
+ "scripts": {
15
+ "typecheck": "npx tsc --noEmit"
16
+ }
17
+ }
@@ -0,0 +1,189 @@
1
+ ---
2
+ name: evolve
3
+ description: "Analyze session usage data and generate evolution suggestions. Runs Python analyzer data through LLM analysis to produce actionable improvement recommendations for CLAUDE.md and skills. Trigger: /evolve, evolve, 进化分析, 分析使用模式, analyze usage."
4
+ ---
5
+
6
+ # Evolve — Usage Analysis & Suggestion Generator
7
+
8
+ ## Purpose
9
+
10
+ Analyze Pi agent usage data, identify trends and anomalies, and generate
11
+ evolution suggestions for CLAUDE.md and skill files.
12
+
13
+ ## When Triggered
14
+
15
+ User says "/evolve", "evolve", "进化分析", "分析使用模式", or wants to
16
+ analyze usage patterns.
17
+
18
+ ## Procedure
19
+
20
+ ### 1. Parse User Intent
21
+
22
+ - No args → analyze last 7 days, all dimensions
23
+ - `since=Nd` → analyze last N days
24
+ - "分析 skill" / "分析 CLAUDE.md" → focus on specific dimension
25
+ - Natural language: extract time range and focus area
26
+ - **Fallback**: If intent cannot be determined from the natural language input,
27
+ default to last 7 days, all dimensions. Do not ask clarifying questions.
28
+
29
+ ### 2. Read Data Sources
30
+
31
+ Read files from `~/.pi/agent/evolution-data/`:
32
+
33
+ **Required** (always read, analysis stops if missing):
34
+ - `daily-reports/*.json` — Python analyzer deep analysis (`.json` files only;
35
+ `.md` files are legacy, ignore them)
36
+
37
+ **Recommended** (read if available, enhance analysis):
38
+ - `history.jsonl` — applied suggestion history (for effect review)
39
+ - `metrics-history.json` — metric trends
40
+
41
+ **Optional** (read only when analyzing specific dimensions):
42
+ - `daily/*.json` — daily summaries (date, sessions, toolCalls, tokens)
43
+ - `skill-triggers.json` — skill usage statistics
44
+ - `tool-stats.json` — tool call statistics
45
+
46
+ Filter by user's requested time range. If requesting "last N days",
47
+ read files with dates >= (today - N days).
48
+
49
+ **Data integrity checks:**
50
+ - If daily-reports JSON fails to parse (corrupt/malformed), skip that file
51
+ and note it in the suggestion output, but continue with other files
52
+ - If history.jsonl is empty or has invalid JSON lines, skip it gracefully
53
+ - If `extract_context.py` times out or errors, skip the deep-dive for that
54
+ pattern but continue with other suggestion sources
55
+ - If skill-triggers.json or tool-stats.json are missing, skip optional
56
+ enhancements without error
57
+
58
+ **No data scenario:** If no daily-reports exist for the requested range,
59
+ tell the user: "No usage data available for the requested period. Ensure
60
+ the evolve-daily extension is installed and has had time to collect data."
61
+ Do NOT proceed to generate suggestions.
62
+
63
+ ### 3. Analyze
64
+
65
+ Use your judgment to identify:
66
+ - **Trends**: Increasing/decreasing patterns in tool usage, token consumption,
67
+ error rates
68
+ - **Anomalies**: Spikes in errors, sudden drops in efficiency
69
+ - **Opportunities**: Skills never triggered, redundant patterns, optimization
70
+ chances
71
+ - **Effect review**: Check history.jsonl for recently applied suggestions and
72
+ evaluate their impact using before/after metrics
73
+
74
+ #### 3a. Error Deep Dive (failure_refs → extract_context.py)
75
+
76
+ When `error_stats.top_error_patterns` contains high-severity patterns
77
+ (error count >= 5 or error rate > 20%), use `extract_context.py` to fetch
78
+ real failure cases for richer rationale:
79
+
80
+ ```bash
81
+ # 提取某个 error pattern 的典型案例(推荐用批量模式)
82
+ python3 ~/.pi/agent/scripts/pi-session-analyzer/extract_context.py \
83
+ --pattern "Could not find the exact text" \
84
+ --from-report ~/.pi/agent/evolution-data/daily-reports/YYYY-MM-DD.json \
85
+ --limit 2
86
+ ```
87
+
88
+ This returns the full tool call arguments, error content, and surrounding
89
+ context (user messages, retry behavior). Use this evidence to write more
90
+ specific suggestions.
91
+
92
+ `failure_refs` in `error_stats` contains one entry per error:
93
+ - `session_id` — identify the session
94
+ - `tool_call_id` — identify the specific tool call
95
+ - `pattern` — error pattern category
96
+ - `self_corrected` — whether AI retried successfully afterward
97
+
98
+ You can also extract a single case if you have a specific ref:
99
+ ```bash
100
+ python3 ~/.pi/agent/scripts/pi-session-analyzer/extract_context.py \
101
+ --session-id <session_id> --tool-call-id <tool_call_id>
102
+ ```
103
+
104
+ **Failure handling:** If extract_context.py exits with non-zero code or
105
+ produces no output, skip the deep-dive for that pattern. The analysis
106
+ will still produce suggestions from aggregate data.
107
+
108
+ #### 3b. Skill Trigger Source Analysis
109
+
110
+ `skill_stats` now includes three fields:
111
+ - `triggered_skills` — combined view (backward compatible)
112
+ - `ai_triggered` — skills triggered by AI reading SKILL.md via read tool
113
+ - `user_triggered` — skills triggered by user via `/skill:name` command
114
+
115
+ Use these to identify:
116
+ - **AI-only skills** — AI reads them proactively; check if description
117
+ triggers too eagerly or not enough
118
+ - **User-only skills** — users explicitly invoke them; check if AI should
119
+ also learn to use them autonomously
120
+ - **Mixed-trigger skills** — both paths used; healthy signal
121
+ - **Never-triggered skills** — candidates for removal or description improvement
122
+
123
+ ### 4. Generate Suggestions
124
+
125
+ For each actionable finding, create an EvolutionSuggestion object:
126
+
127
+ | Field | Value |
128
+ |-------|-------|
129
+ | id | Generate a UUID: `python3 -c "import uuid; print(uuid.uuid4())"` |
130
+ | target | "claude-md" or "skill" |
131
+ | targetPath | Absolute path to target .md file under `~/.pi/agent/` |
132
+ | severity | "high" (breaks workflow), "medium" (significant improvement), "low" (nice-to-have) |
133
+ | confidence | 0.0-1.0 based on data strength |
134
+ | title | One-line summary |
135
+ | description | Detailed description of the issue and proposed change |
136
+ | rationale | Data-backed reasoning (cite specific numbers; for error patterns, include evidence from extract_context.py) |
137
+ | instruction | Step-by-step modification instruction for the LLM to apply |
138
+ | status | "pending" |
139
+
140
+ **Constraints:**
141
+ - targetPath MUST be under `~/.pi/agent/` and end with `.md`
142
+ - Limit to 3-7 suggestions per run (prioritize by severity * confidence)
143
+ - Each suggestion must be independently actionable
144
+
145
+ ### 5. Write pending.json
146
+
147
+ Write to `~/.pi/agent/evolution-data/suggestions/pending.json`:
148
+
149
+ ```json
150
+ {
151
+ "generatedAt": "2026-05-31T14:00:00Z",
152
+ "reportUsed": {
153
+ "sources": ["daily-reports", "history.jsonl"],
154
+ "deepDivePatterns": ["Could not find the exact text"]
155
+ },
156
+ "suggestions": [
157
+ {
158
+ "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
159
+ "target": "skill",
160
+ "targetPath": "/Users/example/.pi/agent/skills/whitespace-fixer/SKILL.md",
161
+ "severity": "high",
162
+ "confidence": 0.85,
163
+ "title": "Optimize whitespace-fixer trigger to reduce edit failures",
164
+ "description": "whitespace-fixer has a 12% edit match failure rate...",
165
+ "rationale": "282 total errors in last 7 days, edit failure rate 9.2%",
166
+ "instruction": "In the SKILL.md description...",
167
+ "status": "pending"
168
+ }
169
+ ]
170
+ }
171
+ ```
172
+
173
+ Use the `write` tool to overwrite the file. **Note:** Any previously pending
174
+ suggestions will be replaced. The user should process them via `/evolve-apply`
175
+ before running a new `/evolve` analysis.
176
+
177
+ **If write fails**: Tell the user the write failed and the suggestions
178
+ were not persisted. Show the suggestions in the conversation output so the
179
+ user can manually save them. Do NOT silently lose the analysis results.
180
+
181
+ ### 6. Present Results
182
+
183
+ Show the user a summary:
184
+ - Number of suggestions generated (0 → report "No actionable suggestions found
185
+ this time")
186
+ - Top 3 by severity (include severity, title, and brief rationale for each)
187
+ - How to apply: "/evolve-apply list" to view all, "/evolve-apply apply N" to apply
188
+ - If zero severity/candidates found (all confidence < 0.3), report that no
189
+ actionable suggestions were found rather than forcing low-confidence output
@@ -0,0 +1,115 @@
1
+ ---
2
+ name: evolve-apply
3
+ description: "Manage evolution suggestion lifecycle: list, apply, skip, and rollback suggestions generated by /evolve. Trigger: /evolve-apply, evolve-apply, 应用建议, /evolve-rollback, evolve rollback."
4
+ ---
5
+
6
+ # Evolve-Apply — Suggestion Lifecycle Manager
7
+
8
+ ## Purpose
9
+
10
+ View, apply, skip, or rollback evolution suggestions from pending.json.
11
+
12
+ ## When Triggered
13
+
14
+ User says "/evolve-apply", "evolve-apply", "应用建议", "/evolve-rollback",
15
+ "evolve rollback", or wants to manage evolution suggestions.
16
+
17
+ ## Data Paths
18
+
19
+ - Pending: `~/.pi/agent/evolution-data/suggestions/pending.json`
20
+ - History: `~/.pi/agent/evolution-data/history.jsonl`
21
+ - Backups: `~/.pi/agent/evolution-data/backups/`
22
+
23
+ ## Procedure
24
+
25
+ ### Parse Command
26
+
27
+ - No args or "list" → LIST mode
28
+ - "apply N" → APPLY mode (0-indexed)
29
+ - "skip N" → SKIP mode (0-indexed)
30
+ - "rollback" → ROLLBACK mode
31
+
32
+ ---
33
+
34
+ ### LIST Mode
35
+
36
+ 1. Read `pending.json` using the `read` tool
37
+ 2. If file doesn't exist or suggestions array is empty:
38
+ "No pending suggestions. Run /evolve first to generate suggestions."
39
+ 3. Display each suggestion:
40
+ ```
41
+ [#0] [HIGH] Clean up dormant skills (confidence: 0.85)
42
+ Target: ~/.pi/agent/CLAUDE.md
43
+ Status: pending
44
+ Summary: <first 2 lines of description>
45
+ ```
46
+
47
+ ---
48
+
49
+ ### APPLY Mode
50
+
51
+ 1. Read `pending.json`, validate index N exists and status is "pending"
52
+ 2. Get suggestion at index N
53
+ 3. **Backup**: Use `bash` tool to run:
54
+ ```bash
55
+ mkdir -p ~/.pi/agent/evolution-data/backups
56
+ cp "<targetPath>" "~/.pi/agent/evolution-data/backups/<timestamp>-<filename>"
57
+ ```
58
+ Use ISO timestamp with colons replaced by dashes for the backup filename.
59
+ If cp fails → ABORT, tell user "Backup failed, cannot apply. Reason: ..."
60
+ 4. **Modify file**: Use `edit` or `write` tool to apply the suggestion's
61
+ `instruction` to `targetPath`. Follow the instruction precisely.
62
+ If edit fails → clean up backup file (`rm "<backupPath>"`), ABORT,
63
+ tell user reason, keep status as "pending",
64
+ do NOT update pending.json or append to history.jsonl.
65
+ 5. **Git commit**: Use `bash` tool:
66
+ ```bash
67
+ cd "$(dirname '<targetPath>')" && git add '<filename>' && git commit -m "evolve: <title>"
68
+ ```
69
+ If commit fails → CONTINUE (commitSha will be empty)
70
+ 6. **Update pending.json**: Change suggestion status to "applied". Use `write`
71
+ tool to overwrite the entire file.
72
+ 7. **Append to history.jsonl**: Use `bash` tool with python to ensure
73
+ valid single-line JSON (avoids heredoc issues with multi-line instruction):
74
+ ```bash
75
+ python3 -c "import json; print(json.dumps({'timestamp':'<ISO>','action':'apply','suggestionId':'<id>','targetPath':'<path>','backupPath':'<backup>','instruction':'<instruction text>','title':'<title>','commitSha':'<sha>'}, ensure_ascii=False))" >> ~/.pi/agent/evolution-data/history.jsonl
76
+ ```
77
+ Escape single quotes in values before passing to python -c.
78
+ 8. Confirm to user: "Applied suggestion #N: <title>. Backup at <backupPath>."
79
+
80
+ ---
81
+
82
+ ### SKIP Mode
83
+
84
+ 1. Read `pending.json`, validate index N exists and status is "pending"
85
+ 2. Update suggestion status to "rejected"
86
+ 3. Write back `pending.json` using `write` tool
87
+ 4. Confirm: "Skipped suggestion #N: <title>."
88
+
89
+ ---
90
+
91
+ ### ROLLBACK Mode
92
+
93
+ 1. Read `history.jsonl` (last line = most recent action)
94
+ 2. Find the most recent "apply" action that hasn't been rolled back
95
+ 3. Check if `backupPath` file exists
96
+ 4. **If backup exists**: Use `bash` tool to restore:
97
+ ```bash
98
+ cp "<backupPath>" "<targetPath>"
99
+ ```
100
+ Verify cp succeeded (exit code 0). If cp fails → ABORT, tell user.
101
+ If cp succeeded → commit:
102
+ ```bash
103
+ cd "$(dirname '<targetPath>')" && git add '<filename>' && git commit -m "evolve: rollback <title>"
104
+ ```
105
+ 5. **If backup missing**: Tell user "Cannot auto-restore: backup file not found
106
+ at <backupPath>. You may need to manually check git history." STOP HERE.
107
+ Do NOT proceed to steps 6-8. Do NOT update pending.json or history.jsonl.
108
+ 6. **Update pending.json** (only if step 4 succeeded): Find the suggestion
109
+ matching the suggestionId and change its status back to "pending".
110
+ Use `write` tool to overwrite.
111
+ 7. **Append rollback to history.jsonl** (only if step 4 succeeded):
112
+ ```bash
113
+ python3 -c "import json; print(json.dumps({'timestamp':'<ISO>','action':'rollback','suggestionId':'<id>','targetPath':'<path>','backupPath':'<backup>','instruction':'','title':'<title>','commitSha':'<sha>'}, ensure_ascii=False))" >> ~/.pi/agent/evolution-data/history.jsonl
114
+ ```
115
+ 8. Confirm (only if step 4 succeeded): "Rolled back: <title>. File restored from backup."
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: evolve-report
3
+ description: "View evolution daily reports and usage statistics. Shows session data, tool usage, token consumption, and trend analysis. Trigger: /evolve-report, evolve-report, 查看报告, 进化报告, /evolve-stats, evolve-stats."
4
+ ---
5
+
6
+ # Evolve-Report — Report & Statistics Viewer
7
+
8
+ ## Purpose
9
+
10
+ Display daily analysis reports and usage statistics from collected data.
11
+
12
+ ## When Triggered
13
+
14
+ User says "/evolve-report", "evolve-report", "查看报告", "进化报告",
15
+ "/evolve-stats", "evolve-stats", or wants to view evolution data.
16
+
17
+ ## Data Paths
18
+
19
+ - Daily reports: `~/.pi/agent/evolution-data/daily-reports/*.json`
20
+ (Only `.json` files are Python analyzer output. `.md` files are legacy from old evolution-engine, ignore them.)
21
+ - Daily summaries: `~/.pi/agent/evolution-data/daily/*.json`
22
+ (Generated by usage-tracker extension.)
23
+ - Metrics history: `~/.pi/agent/evolution-data/metrics-history.json`
24
+
25
+ ## Procedure
26
+
27
+ ### Parse Command
28
+
29
+ - No args → show today's report
30
+ - Date string (YYYY-MM-DD) → show that date's report
31
+ - `--list` → list all available reports
32
+ - `--stats` or "/evolve-stats" → show usage statistics overview
33
+
34
+ ### Show Report
35
+
36
+ 1. Use `bash` tool to check available reports:
37
+ ```bash
38
+ ls ~/.pi/agent/evolution-data/daily-reports/*.json 2>/dev/null
39
+ ```
40
+ 2. Read the requested report using `read` tool
41
+ 3. Present key information in a structured format:
42
+ - Session count and duration
43
+ - Tool call statistics (most used, error rates)
44
+ - Token consumption (input/output)
45
+ - Anomalies and signals
46
+ - Improvement suggestions (if any in the report)
47
+
48
+ ### List Reports
49
+
50
+ ```bash
51
+ ls -1 ~/.pi/agent/evolution-data/daily-reports/*.json 2>/dev/null | xargs -I{} basename {} .json
52
+ ```
53
+ Present as a numbered list of available dates.
54
+
55
+ ### Show Statistics
56
+
57
+ 1. Read multiple `daily/*.json` files for the requested period
58
+ 2. Aggregate and present:
59
+ - Total sessions, tool calls, tokens
60
+ - Per-tool usage breakdown
61
+ - Day-over-day trends
62
+ - Top skills triggered
63
+ - Error patterns
64
+
65
+ Use tables and summaries for readability. Highlight significant changes.
package/src/index.ts ADDED
@@ -0,0 +1,34 @@
1
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
2
+ import { existsSync, unlinkSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { join } from "node:path";
5
+
6
+ const ANALYZER_PATH = join(
7
+ homedir(),
8
+ ".pi/agent/scripts/pi-session-analyzer/analyze.py"
9
+ );
10
+ // daily-reports/ 目录复用旧 extension 的目录路径。
11
+ // 旧 extension 写入 .md 文件,新 evolve-daily 写入 .json 文件,天然不冲突。
12
+ // 删除旧 extension 后残留的 .md 文件可忽略。
13
+ const REPORTS_DIR = join(homedir(), ".pi/agent/evolution-data/daily-reports");
14
+
15
+ export default function evolveDailyExtension(pi: ExtensionAPI) {
16
+ pi.on("session_start", async () => {
17
+ const today = new Date().toISOString().slice(0, 10); // YYYY-MM-DD
18
+ const reportPath = join(REPORTS_DIR, `${today}.json`);
19
+
20
+ if (existsSync(reportPath)) return;
21
+
22
+ try {
23
+ await pi.exec(
24
+ "python3",
25
+ [ANALYZER_PATH, "--since", "1d", "--format", "json", "--output", reportPath],
26
+ { timeout: 30_000 }
27
+ );
28
+ } catch (e) {
29
+ // Clean up partial output if analyzer failed mid-write
30
+ try { unlinkSync(reportPath); } catch { /* already gone */ }
31
+ console.error("[evolve-daily] analyzer failed:", e);
32
+ }
33
+ });
34
+ }