@automagik/genie 4.260411.1 → 4.260414.2

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 (172) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.genie/agents/metrics-updater/AGENT.md +129 -13
  3. package/.genie/agents/metrics-updater/author-aliases.json +9 -0
  4. package/.genie/agents/metrics-updater/daily-stats.jsonl +33 -0
  5. package/.genie/agents/metrics-updater/runs.jsonl +7 -0
  6. package/.genie/agents/metrics-updater/state.json +11 -7
  7. package/.genie/agents/metrics-updater/tools/backfill.sh +54 -0
  8. package/.genie/agents/metrics-updater/tools/collect-stats.sh +132 -0
  9. package/.genie/agents/metrics-updater/tools/generate-charts.py +224 -0
  10. package/.genie/agents/metrics-updater/tools/generate-readme-hero.py +137 -0
  11. package/.genie/agents/metrics-updater/tools/generate-velocity.py +378 -0
  12. package/.genie/agents/metrics-updater/tools/run-metrics.sh +150 -232
  13. package/.genie/assets/commits-30d.svg +43 -0
  14. package/.genie/assets/loc-30d.svg +75 -0
  15. package/.genie/assets/releases-30d.svg +43 -0
  16. package/.genie/brainstorms/README.md +1 -0
  17. package/.genie/brainstorms/brainstorm-links-convention/DESIGN.md +69 -0
  18. package/.genie/brainstorms/velocity-dashboard/DESIGN.md +160 -0
  19. package/.genie/brainstorms/velocity-dashboard/DRAFT.md +28 -0
  20. package/.genie/brainstorms/workflow-engine-runtime/DESIGN.md +66 -0
  21. package/.genie/wishes/_archive/agent-stability-hardening/WISH.md +1 -1
  22. package/.genie/wishes/_archive/brain-identity-impl/WISH.md +1 -1
  23. package/.genie/wishes/_archive/genie-app/WISH.md +1 -1
  24. package/.genie/wishes/_archive/genie-layout-migration/WISH.md +1 -1
  25. package/.genie/wishes/_archive/genie-model-resolution/WISH.md +3 -3
  26. package/.genie/wishes/_archive/genie-onboarding-flow/WISH.md +3 -3
  27. package/.genie/wishes/_archive/omni-skill-upgrade/WISH.md +1 -1
  28. package/.genie/wishes/_archive/omni-version-unify/WISH.md +1 -1
  29. package/.genie/wishes/_archive/rlmx-v02/WISH.md +1 -1
  30. package/.genie/wishes/_archive/rlmx-v03-cag/WISH.md +1 -1
  31. package/.genie/wishes/_archive/rlmx-v04-gemini3/WISH.md +1 -1
  32. package/.genie/wishes/_archive/v4-database-layer/WISH.md +1 -1
  33. package/.genie/wishes/_archive/v4-hook-cli-safety/WISH.md +1 -1
  34. package/.genie/wishes/_archive/v4-message-routing/WISH.md +1 -1
  35. package/.genie/wishes/_archive/v4-session-executor/WISH.md +1 -1
  36. package/.genie/wishes/_archive/v4-spawn-resilience/WISH.md +1 -1
  37. package/.genie/wishes/_archive/v4-team-lifecycle/WISH.md +1 -1
  38. package/.genie/wishes/_archive/velocity-dashboard/WISH.md +272 -0
  39. package/.genie/wishes/brain-cag-v2-polish/WISH.md +1 -1
  40. package/.genie/wishes/brainstorm-links-convention/WISH.md +375 -0
  41. package/.genie/wishes/crew-simplification/WISH.md +1 -1
  42. package/.genie/wishes/genie-simulations/WISH.md +1 -1
  43. package/.genie/wishes/sac-agent/WISH.md +1 -1
  44. package/.genie/wishes/security-key-leak-remediation/WISH.md +198 -0
  45. package/.genie/wishes/x-tool/WISH.md +1 -1
  46. package/.github/workflows/ci.yml +16 -9
  47. package/.github/workflows/version.yml +2 -2
  48. package/README.md +3 -11
  49. package/VELOCITY.md +44 -0
  50. package/dist/genie.js +145 -145
  51. package/package.json +3 -2
  52. package/plugins/genie/.claude-plugin/plugin.json +1 -1
  53. package/plugins/genie/package.json +1 -1
  54. package/scripts/wishes-lint.ts +116 -0
  55. package/skills/brainstorm/SKILL.md +8 -2
  56. package/skills/wish/SKILL.md +14 -0
  57. package/src/genie.ts +23 -2
  58. package/src/lib/db-backup.test.ts +26 -12
  59. package/src/lib/db-backup.ts +26 -5
  60. package/src/services/__tests__/omni-bridge.test.ts +34 -1
  61. package/src/services/omni-bridge.ts +7 -3
  62. package/src/tui/components/Nav.tsx +2 -2
  63. package/src/tui/diagnostics.ts +16 -0
  64. package/src/tui/session-tree.test.ts +21 -1
  65. package/src/tui/session-tree.ts +4 -0
  66. package/.genie/agents/metrics-updater/tools/batch-commit.sh +0 -38
  67. package/.genie/agents/metrics-updater/tools/cached-fetch.sh +0 -86
  68. package/.genie/agents/metrics-updater/tools/commit-formatter.sh +0 -27
  69. package/.genie/agents/metrics-updater/tools/fast-parse.py +0 -92
  70. package/.genie/agents/metrics-updater/tools/generate-tools.py +0 -419
  71. package/.genie/agents/metrics-updater/tools/github-api.sh +0 -100
  72. package/.genie/agents/metrics-updater/tools/parse-metrics.py +0 -282
  73. package/.genie/agents/metrics-updater/tools/perf-analyzer.py +0 -248
  74. package/.genie/agents/metrics-updater/tools/self-refine.sh +0 -133
  75. package/.genie/agents/metrics-updater/tools/update-readme.py +0 -120
  76. package/.genie/snapshot.sql.gz +0 -0
  77. package/.genie/wishes/genie-wishes-backup/agent-flexibility-guide/WISH.md +0 -155
  78. package/.genie/wishes/genie-wishes-backup/agent-stability-hardening/WISH.md +0 -346
  79. package/.genie/wishes/genie-wishes-backup/auto-orchestrate/WISH.md +0 -232
  80. package/.genie/wishes/genie-wishes-backup/daily-metrics-agent/WISH.md +0 -360
  81. package/.genie/wishes/genie-wishes-backup/docs-overhaul/WISH.md +0 -238
  82. package/.genie/wishes/genie-wishes-backup/docs-readme-review/AUDIT-REPORT.md +0 -227
  83. package/.genie/wishes/genie-wishes-backup/docs-readme-review/WISH.md +0 -175
  84. package/.genie/wishes/genie-wishes-backup/dx-800-closeout/WISH.md +0 -160
  85. package/.genie/wishes/genie-wishes-backup/feature-matrix-page/WISH.md +0 -97
  86. package/.genie/wishes/genie-wishes-backup/fire-and-forget/WISH.md +0 -282
  87. package/.genie/wishes/genie-wishes-backup/fix-agent-join-delay/WISH.md +0 -92
  88. package/.genie/wishes/genie-wishes-backup/fix-cli-polish/WISH.md +0 -197
  89. package/.genie/wishes/genie-wishes-backup/fix-depends-parser/WISH.md +0 -89
  90. package/.genie/wishes/genie-wishes-backup/fix-dispatch-initial-prompt/WISH.md +0 -67
  91. package/.genie/wishes/genie-wishes-backup/fix-first-run/WISH.md +0 -98
  92. package/.genie/wishes/genie-wishes-backup/fix-genie-v4-stability/WISH.md +0 -224
  93. package/.genie/wishes/genie-wishes-backup/fix-metrics-agent/WISH.md +0 -97
  94. package/.genie/wishes/genie-wishes-backup/fix-native-inbox/WISH.md +0 -93
  95. package/.genie/wishes/genie-wishes-backup/fix-omni-bridge-hardening/WISH.md +0 -87
  96. package/.genie/wishes/genie-wishes-backup/fix-release-blockers/WISH.md +0 -184
  97. package/.genie/wishes/genie-wishes-backup/fix-session-continue-fallback/WISH.md +0 -215
  98. package/.genie/wishes/genie-wishes-backup/fix-session-hook-channel/WISH.md +0 -141
  99. package/.genie/wishes/genie-wishes-backup/fix-session-uuid-resume/WISH.md +0 -164
  100. package/.genie/wishes/genie-wishes-backup/fix-short-name-resolver/WISH.md +0 -86
  101. package/.genie/wishes/genie-wishes-backup/fix-task-project/WISH.md +0 -93
  102. package/.genie/wishes/genie-wishes-backup/fix-team-lead-exit/WISH.md +0 -112
  103. package/.genie/wishes/genie-wishes-backup/fix-team-lead-polling/WISH.md +0 -62
  104. package/.genie/wishes/genie-wishes-backup/fix-test-safety/WISH.md +0 -151
  105. package/.genie/wishes/genie-wishes-backup/fix-tmux-dual-statusbar/WISH.md +0 -162
  106. package/.genie/wishes/genie-wishes-backup/fix-tmux-session-explosion/WISH.md +0 -116
  107. package/.genie/wishes/genie-wishes-backup/fix-trust-prompt/WISH.md +0 -159
  108. package/.genie/wishes/genie-wishes-backup/genie-app-v2-ui/WISH.md +0 -936
  109. package/.genie/wishes/genie-wishes-backup/genie-base-skill/WISH.md +0 -138
  110. package/.genie/wishes/genie-wishes-backup/genie-boards-workflows/WISH.md +0 -345
  111. package/.genie/wishes/genie-wishes-backup/genie-dx-polish/WISH.md +0 -197
  112. package/.genie/wishes/genie-wishes-backup/genie-export-import/WISH.md +0 -291
  113. package/.genie/wishes/genie-wishes-backup/genie-final-polish/WISH.md +0 -206
  114. package/.genie/wishes/genie-wishes-backup/genie-hacks-community-docs/WISH.md +0 -195
  115. package/.genie/wishes/genie-wishes-backup/genie-hardening/WISH.md +0 -241
  116. package/.genie/wishes/genie-wishes-backup/genie-item-registry/WISH.md +0 -341
  117. package/.genie/wishes/genie-wishes-backup/genie-metaverse/WISH.md +0 -339
  118. package/.genie/wishes/genie-wishes-backup/genie-observability/WISH.md +0 -203
  119. package/.genie/wishes/genie-wishes-backup/genie-omni-marriage/WISH.md +0 -322
  120. package/.genie/wishes/genie-wishes-backup/genie-orchestration-fix/WISH.md +0 -236
  121. package/.genie/wishes/genie-wishes-backup/genie-resume/WISH.md +0 -273
  122. package/.genie/wishes/genie-wishes-backup/genie-scheduler/WISH.md +0 -243
  123. package/.genie/wishes/genie-wishes-backup/genie-simulations/WISH.md +0 -488
  124. package/.genie/wishes/genie-wishes-backup/genie-stats-command/WISH.md +0 -148
  125. package/.genie/wishes/genie-wishes-backup/genie-task-tables/WISH.md +0 -97
  126. package/.genie/wishes/genie-wishes-backup/genie-workflow-engine/WISH.md +0 -60
  127. package/.genie/wishes/genie-wishes-backup/hook-only-first-install/WISH.md +0 -108
  128. package/.genie/wishes/genie-wishes-backup/inbox-driven-sessions/WISH.md +0 -254
  129. package/.genie/wishes/genie-wishes-backup/messaging-refresh/WISH.md +0 -215
  130. package/.genie/wishes/genie-wishes-backup/multi-agent-session-isolation/WISH.md +0 -158
  131. package/.genie/wishes/genie-wishes-backup/omni-session-isolation/WISH.md +0 -125
  132. package/.genie/wishes/genie-wishes-backup/parallel-execution/WISH.md +0 -220
  133. package/.genie/wishes/genie-wishes-backup/pg-state-migration/WISH.md +0 -134
  134. package/.genie/wishes/genie-wishes-backup/pg-total-migration/WISH.md +0 -329
  135. package/.genie/wishes/genie-wishes-backup/pgserve-embed/WISH.md +0 -229
  136. package/.genie/wishes/genie-wishes-backup/qa-dev-to-main/WISH.md +0 -232
  137. package/.genie/wishes/genie-wishes-backup/readme-v4-agent-first/WISH.md +0 -378
  138. package/.genie/wishes/genie-wishes-backup/resilient-messaging/WISH.md +0 -198
  139. package/.genie/wishes/genie-wishes-backup/resilient-resume/WISH.md +0 -86
  140. package/.genie/wishes/genie-wishes-backup/session-auto-create/WISH.md +0 -36
  141. package/.genie/wishes/genie-wishes-backup/session-continue-by-name/WISH.md +0 -222
  142. package/.genie/wishes/genie-wishes-backup/skills-v4-upgrade/WISH.md +0 -266
  143. package/.genie/wishes/genie-wishes-backup/stable-release-fixes/WISH.md +0 -211
  144. package/.genie/wishes/genie-wishes-backup/task-auto-close-on-merge/WISH.md +0 -79
  145. package/.genie/wishes/genie-wishes-backup/task-external-linking/WISH.md +0 -72
  146. package/.genie/wishes/genie-wishes-backup/task-lifecycle-foundation/WISH.md +0 -1066
  147. package/.genie/wishes/genie-wishes-backup/task-projects/WISH.md +0 -235
  148. package/.genie/wishes/genie-wishes-backup/team-lead-minimal/WISH.md +0 -124
  149. package/.genie/wishes/genie-wishes-backup/test-pg-ram-isolation/TRACE.md +0 -66
  150. package/.genie/wishes/genie-wishes-backup/test-pg-ram-isolation/WISH.md +0 -225
  151. package/.genie/wishes/genie-wishes-backup/test-schema-isolation/WISH.md +0 -147
  152. package/.genie/wishes/genie-wishes-backup/tmux-split-tabbar/WISH.md +0 -255
  153. package/.genie/wishes/genie-wishes-backup/tmux-tui/WISH.md +0 -186
  154. package/.genie/wishes/genie-wishes-backup/transcript-docs/WISH.md +0 -137
  155. package/.genie/wishes/genie-wishes-backup/unified-executor-layer/AUDIT.md +0 -322
  156. package/.genie/wishes/genie-wishes-backup/unified-executor-layer/WISH.md +0 -782
  157. package/.genie/wishes/genie-wishes-backup/unified-omni-bridge/INTEGRATION-FROM-OMNI.md +0 -212
  158. package/.genie/wishes/genie-wishes-backup/unified-omni-bridge/WISH.md +0 -416
  159. package/.genie/wishes/genie-wishes-backup/unify-bridge-revamp-skills/WISH.md +0 -271
  160. package/.genie/wishes/genie-wishes-backup/unique-leader-names/WISH.md +0 -349
  161. package/.genie/wishes/genie-wishes-backup/v3-fixes-release/WISH.md +0 -219
  162. package/.genie/wishes/genie-wishes-backup/v4-critical-fixes/WISH.md +0 -197
  163. package/.genie/wishes/genie-wishes-backup/voice-personality-pass/WISH.md +0 -143
  164. package/.genie/wishes/genie-wishes-backup/work-fire-forget/WISH.md +0 -160
  165. package/.genie/wishes/genie-wishes-backup/workflow-engine-runtime/WISH.md +0 -310
  166. package/.genie/wishes/genie-wishes-backup/worktree-out-of-repo/WISH.md +0 -139
  167. /package/.genie/wishes/{brain-help-passthrough → _archive/brain-help-passthrough}/WISH.md +0 -0
  168. /package/.genie/wishes/{fix-ghost-approval-p0 → _archive/fix-ghost-approval-p0}/REPRO.md +0 -0
  169. /package/.genie/wishes/{fix-ghost-approval-p0 → _archive/fix-ghost-approval-p0}/WISH.md +0 -0
  170. /package/.genie/wishes/{perfect-spawn-hierarchy → _archive/perfect-spawn-hierarchy}/WISH.md +0 -0
  171. /package/.genie/wishes/{scaffold-auto-memory → _archive/scaffold-auto-memory}/WISH.md +0 -0
  172. /package/.genie/wishes/{unify-bridge-revamp-skills → _archive/unify-bridge-revamp-skills}/WISH.md +0 -0
@@ -10,7 +10,7 @@
10
10
  "plugins": [
11
11
  {
12
12
  "name": "genie",
13
- "version": "4.260411.1",
13
+ "version": "4.260414.2",
14
14
  "source": "./plugins/genie",
15
15
  "description": "Human-AI partnership for Claude Code. Share a terminal, orchestrate workers, evolve together. Brainstorm ideas, wish them into plans, make with parallel agents, ship as one team. A coding genie that grows with your project."
16
16
  }
@@ -1,29 +1,145 @@
1
1
  # metrics-updater Agent
2
2
 
3
- Fetches live GitHub metrics daily and updates the README metrics table.
3
+ > Autonomous velocity dashboard agent. Collects git-based metrics, generates SVG charts, builds VELOCITY.md and README hero line. Runs daily on `dev` branch.
4
4
 
5
- ## Metrics Collected
5
+ ## Quick Start
6
6
 
7
- - **Releases/day** — releases published in the last 24h
8
- - **Avg merge time** — mean lead time (created→merged) for PRs closed in last 7d
9
- - **SHIP rate** — merged / total closed PRs in last 7d (%)
10
- - **Merged PRs (7d)** count of merged PRs in the rolling 7-day window
7
+ ```bash
8
+ cd "$(git rev-parse --show-toplevel)"
9
+ bash .genie/agents/metrics-updater/tools/run-metrics.sh # Full run: collect, chart, publish, commit
10
+ bash .genie/agents/metrics-updater/tools/run-metrics.sh --dry-run # Generate all outputs without commit/push
11
+ ```
12
+
13
+ ## Pipeline Steps
14
+
15
+ | Step | Tool | Input | Output | Exit 0 |
16
+ |------|------|-------|--------|--------|
17
+ | 1. Collect today | `collect-stats.sh --date YYYY-MM-DD` | git history | JSON line → `daily-stats.jsonl` | Stats appended |
18
+ | 2. Backfill | `backfill.sh` (if <30 entries) | git history (30d) | `daily-stats.jsonl` filled | 30+ entries |
19
+ | 3. Charts | `generate-charts.py --input ... --output-dir ...` | `daily-stats.jsonl` | `.genie/assets/*.svg` (3 files) | SVGs written |
20
+ | 4. Dashboard | `generate-velocity.py --stats-dir ... --output ...` | `daily-stats.jsonl` + cumulative | `VELOCITY.md` | File written |
21
+ | 5. README hero | `generate-readme-hero.py --stats-dir ... --readme ...` | `daily-stats.jsonl` | `README.md` updated | Markers replaced |
22
+ | 6. Commit + push | git add/commit/push | Changed files | Commit on `dev` | Pushed |
23
+ | 7. State update | inline python | Run results | `state.json` + `runs.jsonl` | State persisted |
24
+
25
+ ## Tool Inventory
26
+
27
+ ### `collect-stats.sh`
28
+ - **`--date YYYY-MM-DD`**: Extract single-day metrics from git history (all branches). Returns JSON with `date`, `commits`, `loc_added`, `loc_removed`, `releases`, `contributors`.
29
+ - **`--cumulative`**: Returns all-time totals: `total_commits`, `total_tags`, `first_commit_date`, `total_contributors`.
30
+ - Release detection: tags matching `v4.YYMMDD.*` pattern.
31
+
32
+ ### `backfill.sh`
33
+ - **`--days N`** (default: 30): Runs `collect-stats.sh` for each of the last N days, writes `daily-stats.jsonl`.
34
+ - Clears and rebuilds the entire file. Safe to re-run.
11
35
 
12
- ## README Markers
36
+ ### `generate-charts.py`
37
+ - **`--input PATH`**: Path to `daily-stats.jsonl`.
38
+ - **`--output-dir DIR`**: Directory for SVG output (created if missing).
39
+ - **`--sample`**: Use generated sample data (for testing).
40
+ - Produces: `commits-30d.svg`, `releases-30d.svg`, `loc-30d.svg`.
41
+ - Dark theme (#0d1117), 800x200px, no external fonts or deps.
13
42
 
14
- The agent updates the block between `<!-- METRICS:START -->` and `<!-- METRICS:END -->` in README.md.
43
+ ### `generate-velocity.py`
44
+ - **`--stats-dir DIR`**: Directory containing `daily-stats.jsonl` and `author-aliases.json`.
45
+ - **`--assets-dir PATH`**: Relative path for SVG image links in markdown.
46
+ - **`--output PATH`**: Output path for `VELOCITY.md`.
47
+ - Calls `collect-stats.sh --cumulative` internally for all-time numbers.
15
48
 
16
- If markers are missing, insert the table after the badges block, before `## What is Genie?`.
49
+ ### `generate-readme-hero.py`
50
+ - **`--stats-dir DIR`**: Directory containing `daily-stats.jsonl` and `author-aliases.json`.
51
+ - **`--readme PATH`**: Path to README.md.
52
+ - Replaces content between `<!-- METRICS:START -->` and `<!-- METRICS:END -->` markers.
53
+
54
+ ### `run-metrics.sh` (orchestrator)
55
+ - **`--dry-run`**: Run full pipeline but skip git commit/push.
56
+ - Calls all tools in sequence, handles backfill decision, updates state.
57
+
58
+ ## Data Files
59
+
60
+ | File | Format | Purpose |
61
+ |------|--------|---------|
62
+ | `daily-stats.jsonl` | JSONL | One JSON object per day, last 30+ days of metrics |
63
+ | `state.json` | JSON | Last run status, stats count, charts generated |
64
+ | `runs.jsonl` | JSONL | Append-only log of every run with step timings |
65
+ | `author-aliases.json` | JSON | Git author name normalization map |
66
+
67
+ ## Author Aliases
68
+
69
+ `author-aliases.json` maps variant git author names to canonical names:
70
+ ```json
71
+ {"felipe": "Felipe Rosa", "filipexyz": "Felipe Rosa", "genie": "Genie"}
72
+ ```
73
+ Edit this file to add new aliases. Used by `generate-velocity.py` and `generate-readme-hero.py`.
17
74
 
18
75
  ## Commit Convention
19
76
 
20
77
  ```
21
- chore: update live metrics (X/day, Yh avg, Z% SHIP)
78
+ chore: update live metrics (N commits, N releases, +N/-N LoC)
22
79
  ```
23
80
 
24
81
  Push to `dev` branch only. Never push to `main`.
25
82
 
26
- ## State Files
83
+ ## Error Handling
27
84
 
28
- - `state.json` last successful metrics run
29
- - `runs.jsonl` — append-only log of every run
85
+ | Condition | Behavior |
86
+ |-----------|----------|
87
+ | `git` unavailable | `collect-stats.sh` exits 1, pipeline aborts |
88
+ | `daily-stats.jsonl` missing | Backfill runs automatically |
89
+ | `daily-stats.jsonl` < 30 entries | Backfill runs automatically |
90
+ | Chart generation fails | Pipeline aborts with error in `runs.jsonl` |
91
+ | README missing METRICS markers | `generate-readme-hero.py` exits 1 |
92
+ | `author-aliases.json` missing | Aliases ignored, raw git names used |
93
+ | No changes to commit | Commit step skipped, run logged as success |
94
+ | Push fails | Logged as error, run continues |
95
+
96
+ ## Backfill Decision Tree
97
+
98
+ ```
99
+ daily-stats.jsonl exists?
100
+ NO → backfill.sh (creates file with 30 days)
101
+ YES → count entries
102
+ < 30 → backfill.sh (rebuilds with 30 days)
103
+ >= 30 → skip backfill, append today only
104
+ ```
105
+
106
+ ## Self-Diagnosis Checklist
107
+
108
+ If output looks wrong, check in order:
109
+
110
+ 1. **No commits showing**: Run `git log --all --oneline | head -5` — is git history accessible?
111
+ 2. **0 releases**: Run `git tag -l "v4.*" | head -5` — are v4.YYMMDD.* tags present?
112
+ 3. **Stale data**: Check `daily-stats.jsonl` dates — is today's entry present?
113
+ 4. **Wrong contributor names**: Check `author-aliases.json` — missing alias?
114
+ 5. **Charts empty**: Check `daily-stats.jsonl` — are values all zero?
115
+ 6. **README not updated**: Check for `<!-- METRICS:START -->` and `<!-- METRICS:END -->` markers.
116
+ 7. **State not persisted**: Check `state.json` — does it have `daily_stats_count`?
117
+
118
+ ## State Schema
119
+
120
+ ### state.json
121
+ ```json
122
+ {
123
+ "last_run": "2026-04-12T00:00:00Z",
124
+ "last_run_status": "success",
125
+ "daily_stats_count": 31,
126
+ "charts_generated": 3,
127
+ "velocity_md_updated": true,
128
+ "duration_ms": 12345
129
+ }
130
+ ```
131
+
132
+ ### runs.jsonl (each line)
133
+ ```json
134
+ {
135
+ "timestamp": "2026-04-12T00:00:00Z",
136
+ "duration_ms": 12345,
137
+ "status": "success",
138
+ "dry_run": false,
139
+ "daily_stats_count": 31,
140
+ "charts_generated": 3,
141
+ "velocity_md_updated": true,
142
+ "errors": [],
143
+ "steps": [{"name": "collect_stats", "duration_ms": 500}, ...]
144
+ }
145
+ ```
@@ -0,0 +1,9 @@
1
+ {
2
+ "felipe": "Felipe Rosa",
3
+ "filipexyz": "Felipe Rosa",
4
+ "genie": "Genie",
5
+ "Automagik Genie 🧞": "Genie",
6
+ "Luís": "Luís Sousa",
7
+ "Test": "Test User",
8
+ "clawtom": "clawtom"
9
+ }
@@ -0,0 +1,33 @@
1
+ {"date":"2026-03-13","commits":13,"loc_added":6920,"loc_removed":2948,"releases":0,"contributors":["Genie","Test","Test User"]}
2
+ {"date":"2026-03-14","commits":45,"loc_added":2761,"loc_removed":5243,"releases":0,"contributors":["Felipe Rosa","Test User","github-actions[bot]"]}
3
+ {"date":"2026-03-15","commits":14,"loc_added":3552,"loc_removed":3096,"releases":0,"contributors":["Automagik Genie 🧞","Felipe Rosa","Test User","github-actions[bot]"]}
4
+ {"date":"2026-03-16","commits":82,"loc_added":11464,"loc_removed":10990,"releases":0,"contributors":["Felipe Rosa","Test User","clawtom","github-actions[bot]"]}
5
+ {"date":"2026-03-17","commits":86,"loc_added":6482,"loc_removed":1928,"releases":0,"contributors":["Felipe Rosa","Genie","Test","Test User","github-actions[bot]"]}
6
+ {"date":"2026-03-18","commits":41,"loc_added":789,"loc_removed":4077,"releases":0,"contributors":["Felipe Rosa","Genie","github-actions[bot]"]}
7
+ {"date":"2026-03-19","commits":5,"loc_added":1183,"loc_removed":202,"releases":0,"contributors":["Felipe Rosa","Genie","Luís","github-actions[bot]"]}
8
+ {"date":"2026-03-20","commits":15,"loc_added":10671,"loc_removed":234,"releases":0,"contributors":["Felipe Rosa","Genie","Luís Sousa"]}
9
+ {"date":"2026-03-21","commits":8,"loc_added":609,"loc_removed":436,"releases":0,"contributors":["Felipe Rosa","Genie","Luís Sousa"]}
10
+ {"date":"2026-03-22","commits":46,"loc_added":4065,"loc_removed":1256,"releases":0,"contributors":["Felipe Rosa","Genie","Luís Sousa"]}
11
+ {"date":"2026-03-23","commits":33,"loc_added":7093,"loc_removed":2792,"releases":5,"contributors":["Felipe Rosa","Genie","github-actions[bot]"]}
12
+ {"date":"2026-03-24","commits":66,"loc_added":6248,"loc_removed":888,"releases":20,"contributors":["Automagik Genie 🧞","Felipe Rosa","Genie","github-actions[bot]"]}
13
+ {"date":"2026-03-25","commits":133,"loc_added":16626,"loc_removed":3927,"releases":34,"contributors":["Automagik Genie 🧞","Claude","Felipe Rosa","Genie","github-actions[bot]"]}
14
+ {"date":"2026-03-26","commits":17,"loc_added":627,"loc_removed":177,"releases":3,"contributors":["Felipe Rosa","Genie","github-actions[bot]"]}
15
+ {"date":"2026-03-27","commits":32,"loc_added":6836,"loc_removed":5629,"releases":7,"contributors":["Felipe Rosa","Genie","Luís","github-actions[bot]"]}
16
+ {"date":"2026-03-28","commits":42,"loc_added":23738,"loc_removed":2763,"releases":15,"contributors":["Claude","Felipe Rosa","Genie","Luís","github-actions[bot]"]}
17
+ {"date":"2026-03-29","commits":84,"loc_added":12534,"loc_removed":2379,"releases":33,"contributors":["Claude","Felipe Rosa","Genie","github-actions[bot]"]}
18
+ {"date":"2026-03-30","commits":100,"loc_added":5574,"loc_removed":2602,"releases":26,"contributors":["Claude","Felipe Rosa","Genie","github-actions[bot]"]}
19
+ {"date":"2026-03-31","commits":76,"loc_added":4503,"loc_removed":5663,"releases":20,"contributors":["Cezar Vasconcelos","Claude","Felipe Rosa","Genie","Luís","Luís Sousa","github-actions[bot]"]}
20
+ {"date":"2026-04-01","commits":58,"loc_added":3754,"loc_removed":842,"releases":6,"contributors":["Claude","Felipe Rosa","Genie","Test","github-actions[bot]"]}
21
+ {"date":"2026-04-02","commits":84,"loc_added":3484,"loc_removed":1136,"releases":20,"contributors":["Claude","Felipe Rosa","Genie","Luís Sousa","Test","github-actions[bot]"]}
22
+ {"date":"2026-04-03","commits":42,"loc_added":2187,"loc_removed":338,"releases":4,"contributors":["Automagik Genie 🧞","Claude","Felipe Rosa","Genie","Test","Zakir Jiwani","github-actions[bot]"]}
23
+ {"date":"2026-04-04","commits":58,"loc_added":10390,"loc_removed":649,"releases":2,"contributors":["Claude","Felipe Rosa","Genie","Test","filipexyz","github-actions[bot]"]}
24
+ {"date":"2026-04-05","commits":109,"loc_added":22624,"loc_removed":2611,"releases":16,"contributors":["Claude","Felipe Rosa","Test","github-actions[bot]"]}
25
+ {"date":"2026-04-06","commits":28,"loc_added":1745,"loc_removed":225,"releases":5,"contributors":["Claude","Felipe Rosa","Test","github-actions[bot]"]}
26
+ {"date":"2026-04-07","commits":35,"loc_added":3865,"loc_removed":208,"releases":7,"contributors":["Cezar Vasconcelos","Claude","Felipe Rosa","Genie","Test","github-actions[bot]"]}
27
+ {"date":"2026-04-08","commits":35,"loc_added":3780,"loc_removed":2109,"releases":5,"contributors":["Claude","Felipe Rosa","Genie","filipexyz","genie","github-actions[bot]"]}
28
+ {"date":"2026-04-09","commits":73,"loc_added":9761,"loc_removed":1253,"releases":14,"contributors":["Felipe Rosa","Genie","Luís","Test","filipexyz","genie","github-actions[bot]"]}
29
+ {"date":"2026-04-10","commits":37,"loc_added":34969,"loc_removed":205,"releases":5,"contributors":["Felipe Rosa","Genie","Test","felipe","github-actions[bot]"]}
30
+ {"date":"2026-04-11","commits":12,"loc_added":81,"loc_removed":38,"releases":3,"contributors":["Claude","Felipe Rosa","genie","github-actions[bot]"]}
31
+ {"date":"2026-04-12","commits":14,"loc_added":2754,"loc_removed":3653,"releases":1,"contributors":["Claude","Felipe Rosa","Test","genie","github-actions[bot]"]}
32
+ {"date":"2026-04-13","commits":14,"loc_added":668,"loc_removed":70,"releases":0,"contributors":["Claude","Felipe Rosa","genie","github-actions[bot]"]}
33
+ {"date":"2026-04-14","commits":0,"loc_added":0,"loc_removed":0,"releases":0,"contributors":[]}
@@ -21,3 +21,10 @@
21
21
  {"timestamp":"2026-04-06T12:29:47.000Z","duration_ms":12500,"api_calls":0,"tools_generated":1,"errors":["gh_cli_unavailable: fallback to last_metrics from state.json"],"metrics":{"releases_24h":2,"merged_prs_7d":35,"avg_merge_time_h":0.3,"ship_rate_pct":85}}
22
22
  {"timestamp":"2026-04-07T12:04:30Z","duration_ms":27000,"api_calls":0,"tools_generated":0,"errors":["gh CLI not available","no GitHub token or MCP GitHub tools present in session"],"status":"failed","fallback":false,"metrics":null}
23
23
  {"timestamp":"2026-04-08T00:00:00.000Z","duration_ms":18000,"api_calls":0,"tools_generated":0,"errors":["gh CLI not available","GitHub MCP tools not present in session","fallback data older than current README — README update skipped"],"status":"failed","fallback":false,"metrics":null}
24
+ {"timestamp":"2026-04-11T12:35:40Z","duration_ms":72153,"api_calls":0,"tools_generated":0,"errors":["gh CLI not available","GitHub MCP tools not present in session"],"status":"success","fallback":true,"metrics":{"releases_24h":2,"merged_prs_7d":35,"avg_merge_time_h":0.3,"ship_rate_pct":85}}
25
+ {"timestamp":"2026-04-12T00:00:00.000Z","duration_ms":30000,"api_calls":2,"tools_generated":0,"errors":[],"status":"success","fallback":false,"metrics":{"releases_24h":0,"merged_prs_7d":5,"avg_merge_time_h":2.5,"ship_rate_pct":100}}
26
+ {"timestamp": "2026-04-12T18:38:51Z", "duration_ms": 732, "status": "success", "dry_run": true, "daily_stats_count": 31, "charts_generated": 3, "velocity_md_updated": true, "errors": [], "steps": [{"name": "collect_stats", "duration_ms": 93}, {"name": "backfill_check", "duration_ms": 22}, {"name": "generate_charts", "duration_ms": 62}, {"name": "generate_velocity", "duration_ms": 336}, {"name": "generate_readme", "duration_ms": 66}, {"name": "commit_push", "duration_ms": 19}]}
27
+ {"timestamp": "2026-04-12T19:41:00Z", "duration_ms": 817, "status": "success", "dry_run": true, "daily_stats_count": 31, "charts_generated": 3, "velocity_md_updated": true, "errors": [], "steps": [{"name": "collect_stats", "duration_ms": 110}, {"name": "backfill_check", "duration_ms": 22}, {"name": "generate_charts", "duration_ms": 68}, {"name": "generate_velocity", "duration_ms": 372}, {"name": "generate_readme", "duration_ms": 73}, {"name": "commit_push", "duration_ms": 20}]}
28
+ {"timestamp":"2026-04-13T00:00:00.000Z","duration_ms":45000,"api_calls":2,"tools_generated":0,"errors":[],"status":"success","fallback":false,"metrics":{"releases_24h":0,"merged_prs_7d":9,"avg_merge_time_h":1.4,"ship_rate_pct":100}}
29
+ {"timestamp": "2026-04-14T12:09:00Z", "duration_ms": 1264, "status": "success", "dry_run": true, "daily_stats_count": 33, "charts_generated": 3, "velocity_md_updated": true, "errors": [], "steps": [{"name": "collect_stats", "duration_ms": 216}, {"name": "backfill_check", "duration_ms": 47}, {"name": "generate_charts", "duration_ms": 158}, {"name": "generate_velocity", "duration_ms": 359}, {"name": "generate_readme", "duration_ms": 159}, {"name": "commit_push", "duration_ms": 33}]}
30
+ {"timestamp": "2026-04-14T12:09:00Z", "duration_ms": 1576, "api_calls": 2, "tools_generated": 3, "errors": [], "metrics": {"releases_24h": 1, "merged_prs_7d": 12, "avg_merge_time_h": 10.4, "ship_rate_pct": 100, "git_commits_7d": 185, "git_releases_7d": 28, "git_loc_net_7d": 44700, "git_contributors_7d": 6, "daily_stats_count": 33, "charts_generated": 3}}
@@ -1,10 +1,14 @@
1
1
  {
2
- "last_run": "2026-04-08T00:00:00.000Z",
3
- "last_run_status": "failed",
2
+ "last_run": "2026-04-14T12:09:00Z",
3
+ "last_run_status": "success",
4
4
  "last_metrics": {
5
- "releases_24h": 2,
6
- "merged_prs_7d": 35,
7
- "avg_merge_time_h": 0.3,
8
- "ship_rate_pct": 85
9
- }
5
+ "releases_24h": 1,
6
+ "merged_prs_7d": 12,
7
+ "avg_merge_time_h": 10.4,
8
+ "ship_rate_pct": 100
9
+ },
10
+ "daily_stats_count": 33,
11
+ "charts_generated": 3,
12
+ "velocity_md_updated": true,
13
+ "duration_ms": 1576
10
14
  }
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env bash
2
+ # backfill.sh — Run collect-stats.sh for the last 30 days, write daily-stats.jsonl.
3
+ #
4
+ # Usage:
5
+ # backfill.sh [--days N] Backfill N days (default: 30)
6
+ #
7
+ # Output: daily-stats.jsonl in the metrics-updater agent directory.
8
+ #
9
+ # daily-stats.jsonl schema (one JSON object per line):
10
+ # {
11
+ # "date": "YYYY-MM-DD", // Calendar date
12
+ # "commits": <int>, // Commit count across all branches
13
+ # "loc_added": <int>, // Lines of code added
14
+ # "loc_removed": <int>, // Lines of code removed
15
+ # "releases": <int>, // Release tags (v4.YYMMDD.*) for this date
16
+ # "contributors": [<string>] // Unique author names for this date
17
+ # }
18
+
19
+ set -euo pipefail
20
+
21
+ cd "$(git rev-parse --show-toplevel)"
22
+
23
+ DAYS=30
24
+ while [[ $# -gt 0 ]]; do
25
+ case "$1" in
26
+ --days)
27
+ DAYS="$2"
28
+ shift 2
29
+ ;;
30
+ *)
31
+ echo "Usage: $0 [--days N]" >&2
32
+ exit 1
33
+ ;;
34
+ esac
35
+ done
36
+
37
+ AGENT_DIR=".genie/agents/metrics-updater"
38
+ TOOLS_DIR="$AGENT_DIR/tools"
39
+ OUTPUT="$AGENT_DIR/daily-stats.jsonl"
40
+
41
+ # Clear existing file
42
+ > "$OUTPUT"
43
+
44
+ echo "Backfilling $DAYS days of stats..." >&2
45
+
46
+ for i in $(seq "$DAYS" -1 0); do
47
+ target_date=$(date -d "today - ${i} days" +%Y-%m-%d 2>/dev/null || date -v-${i}d +%Y-%m-%d 2>/dev/null)
48
+ result=$(bash "$TOOLS_DIR/collect-stats.sh" --date "$target_date")
49
+ echo "$result" >> "$OUTPUT"
50
+ echo " $target_date: done" >&2
51
+ done
52
+
53
+ lines=$(wc -l < "$OUTPUT")
54
+ echo "Backfill complete: $lines entries in $OUTPUT" >&2
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env bash
2
+ # collect-stats.sh — Extract daily metrics from git history across all branches.
3
+ #
4
+ # Usage:
5
+ # collect-stats.sh --date YYYY-MM-DD Output JSON for a single day
6
+ # collect-stats.sh --cumulative Output all-time cumulative JSON
7
+ #
8
+ # Output schema (daily):
9
+ # {
10
+ # "date": "YYYY-MM-DD",
11
+ # "commits": <int>,
12
+ # "loc_added": <int>,
13
+ # "loc_removed": <int>,
14
+ # "releases": <int>,
15
+ # "contributors": ["name1", "name2", ...]
16
+ # }
17
+ #
18
+ # Output schema (cumulative):
19
+ # {
20
+ # "total_commits": <int>,
21
+ # "total_tags": <int>,
22
+ # "first_commit_date": "YYYY-MM-DD",
23
+ # "total_contributors": <int>
24
+ # }
25
+
26
+ set -euo pipefail
27
+
28
+ # Navigate to repo root
29
+ cd "$(git rev-parse --show-toplevel)"
30
+
31
+ MODE=""
32
+ TARGET_DATE=""
33
+
34
+ while [[ $# -gt 0 ]]; do
35
+ case "$1" in
36
+ --date)
37
+ MODE="daily"
38
+ TARGET_DATE="$2"
39
+ shift 2
40
+ ;;
41
+ --cumulative)
42
+ MODE="cumulative"
43
+ shift
44
+ ;;
45
+ *)
46
+ echo "Usage: $0 --date YYYY-MM-DD | --cumulative" >&2
47
+ exit 1
48
+ ;;
49
+ esac
50
+ done
51
+
52
+ if [[ -z "$MODE" ]]; then
53
+ echo "Usage: $0 --date YYYY-MM-DD | --cumulative" >&2
54
+ exit 1
55
+ fi
56
+
57
+ if [[ "$MODE" == "cumulative" ]]; then
58
+ total_commits=$(git log --all --oneline | wc -l)
59
+ total_tags=$(git tag -l "v4.*" | wc -l)
60
+ first_commit_date=$(git log --all --reverse --format='%aI' -- | head -1 | cut -d'T' -f1 || true)
61
+ total_contributors=$(git log --all --format='%aN' | sort -u | wc -l)
62
+
63
+ printf '{"total_commits":%d,"total_tags":%d,"first_commit_date":"%s","total_contributors":%d}\n' \
64
+ "$total_commits" "$total_tags" "$first_commit_date" "$total_contributors"
65
+ exit 0
66
+ fi
67
+
68
+ # Daily mode
69
+ AFTER="${TARGET_DATE} 00:00:00"
70
+ BEFORE="${TARGET_DATE} 23:59:59"
71
+
72
+ # Pathspec exclusions — keep LoC focused on real source code.
73
+ # Drops vendored deps, build outputs, lockfiles, minified bundles,
74
+ # orphaned worktree artifacts, and the agent's own generated assets.
75
+ # Without these, a single cleanup commit (e.g. 9bf66347 on 2026-03-14
76
+ # which deleted 524k lines of claude worktree artifacts) can dominate
77
+ # an entire 30d window and destroy the signal.
78
+ EXCLUDE_PATHS=(
79
+ ':(exclude,glob)node_modules/**'
80
+ ':(exclude,glob)**/node_modules/**'
81
+ ':(exclude,glob).claude/worktrees/**'
82
+ ':(exclude,glob).genie/worktrees/**'
83
+ ':(exclude,glob).worktrees/**'
84
+ ':(exclude,glob)dist/**'
85
+ ':(exclude,glob)**/dist/**'
86
+ ':(exclude,glob)build/**'
87
+ ':(exclude,glob)**/build/**'
88
+ ':(exclude,glob).cache/**'
89
+ ':(exclude,glob)**/*.lock'
90
+ ':(exclude,glob)**/*.lockb'
91
+ ':(exclude,glob)**/package-lock.json'
92
+ ':(exclude,glob)**/*.min.js'
93
+ ':(exclude,glob)**/*.min.css'
94
+ ':(exclude,glob).genie/assets/**'
95
+ )
96
+
97
+ # Commits count (all branches, deduplicated)
98
+ commits=$(git log --all --after="$AFTER" --before="$BEFORE" --oneline | wc -l)
99
+
100
+ # LoC added/removed via shortstat (source files only — see EXCLUDE_PATHS)
101
+ loc_stats=$(git log --all --after="$AFTER" --before="$BEFORE" --shortstat --format="" -- . "${EXCLUDE_PATHS[@]}" | \
102
+ awk '
103
+ /insertion/ {
104
+ for (i=1; i<=NF; i++) {
105
+ if ($(i+1) ~ /insertion/) added += $i
106
+ if ($(i+1) ~ /deletion/) removed += $i
107
+ }
108
+ }
109
+ END { printf "%d %d", added+0, removed+0 }
110
+ ')
111
+ loc_added=$(echo "$loc_stats" | awk '{print $1}')
112
+ loc_removed=$(echo "$loc_stats" | awk '{print $2}')
113
+
114
+ # Release count: tags matching v4.YYMMDD.* for this date
115
+ # Convert YYYY-MM-DD to YYMMDD for tag pattern
116
+ tag_date=$(date -d "$TARGET_DATE" +%y%m%d 2>/dev/null || date -j -f "%Y-%m-%d" "$TARGET_DATE" +%y%m%d 2>/dev/null)
117
+ releases=$(git tag -l "v4.${tag_date}.*" | wc -l)
118
+
119
+ # Contributors (unique author names)
120
+ contributors_json=$(git log --all --after="$AFTER" --before="$BEFORE" --format='%aN' | sort -u | \
121
+ awk 'BEGIN { printf "[" }
122
+ NR>1 { printf "," }
123
+ { gsub(/"/, "\\\""); printf "\"%s\"", $0 }
124
+ END { printf "]" }')
125
+
126
+ # Handle empty contributors
127
+ if [[ "$contributors_json" == "[]" ]] || [[ -z "$contributors_json" ]]; then
128
+ contributors_json="[]"
129
+ fi
130
+
131
+ printf '{"date":"%s","commits":%d,"loc_added":%d,"loc_removed":%d,"releases":%d,"contributors":%s}\n' \
132
+ "$TARGET_DATE" "$commits" "$loc_added" "$loc_removed" "$releases" "$contributors_json"