@jaybeeuu/agent-cortex 2.7.0 → 2.9.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 (87) hide show
  1. package/CHANGELOG.md +412 -0
  2. package/README.md +87 -8
  3. package/agents/README.md +4 -4
  4. package/agents/guppi/agent.md +162 -0
  5. package/agents/guppi/claude/frontmatter.json +6 -0
  6. package/agents/guppi/pi/frontmatter.json +6 -0
  7. package/agents/plan/agent.md +6 -0
  8. package/agents/ralph/agent.md +17 -16
  9. package/agents/ralph/claude/wake.md +4 -4
  10. package/agents/ralph/pi/wake.md +15 -20
  11. package/agents/ralph-plan/agent.md +6 -0
  12. package/bin/agent-cortex.mjs +20 -1
  13. package/bin/installers/claude.mjs +1 -20
  14. package/bin/installers/pi.mjs +8 -2
  15. package/extensions/interrupt-bookmark/README.md +129 -0
  16. package/extensions/interrupt-bookmark/index.test.ts +717 -0
  17. package/extensions/interrupt-bookmark/index.ts +354 -0
  18. package/extensions/interrupt-bookmark/package.json +20 -0
  19. package/extensions/post-merge-watch/README.md +133 -0
  20. package/extensions/post-merge-watch/index.test.ts +247 -0
  21. package/extensions/post-merge-watch/index.ts +123 -0
  22. package/extensions/post-merge-watch/package.json +16 -0
  23. package/extensions/post-merge-watch/watch.test.ts +469 -0
  24. package/extensions/post-merge-watch/watch.ts +431 -0
  25. package/extensions/session-clear/README.md +74 -0
  26. package/extensions/session-clear/index.test.ts +524 -0
  27. package/extensions/session-clear/index.ts +159 -0
  28. package/extensions/session-clear/package.json +16 -0
  29. package/extensions/skill-stats/README.md +84 -3
  30. package/extensions/skill-stats/index.ts +62 -3
  31. package/extensions/skill-stats/package.json +1 -1
  32. package/extensions/skill-stats/rollup.test.ts +643 -0
  33. package/extensions/skill-stats/rollup.ts +415 -0
  34. package/extensions/skill-stats/timeline.ts +101 -0
  35. package/lib/cli.mjs +42 -1
  36. package/lib/self-update.mjs +553 -0
  37. package/package.json +1 -1
  38. package/scripts/lib/manifest.mjs +29 -0
  39. package/skills/engineering/implement-task/SKILL.md +124 -0
  40. package/skills/engineering/tdd/SKILL.md +2 -0
  41. package/skills/planning/create-task/REFERENCE.md +15 -6
  42. package/skills/planning/create-task/SKILL.md +1 -1
  43. package/skills/planning/create-task/pipeline.json +8 -0
  44. package/skills/planning/create-task/scripts/create-chores.mjs +27 -18
  45. package/skills/planning/create-task/templates/code.md +8 -3
  46. package/skills/planning/create-task/templates/document.md +8 -3
  47. package/skills/planning/create-task/templates/fix.md +8 -3
  48. package/skills/planning/create-task/templates/housekeeping.md +8 -4
  49. package/skills/planning/create-task/templates/post-merge.md +67 -0
  50. package/skills/planning/create-task/templates/review.md +8 -3
  51. package/skills/planning/create-task/templates/verify.md +8 -3
  52. package/skills/productivity/bd-tool/SKILL.md +55 -0
  53. package/skills/review/review-defects/EXAMPLES.md +198 -0
  54. package/skills/review/review-defects/SKILL.md +121 -0
  55. package/skills/review/review-report/EXAMPLES.md +114 -0
  56. package/skills/review/review-report/SKILL.md +138 -0
  57. package/skills/review/review-report/scripts/report.mjs +1032 -0
  58. package/skills/style/style-tests/EXAMPLES.md +30 -0
  59. package/skills/style/style-tests/SKILL.md +10 -6
  60. package/skills/workflow/hitl-queue/SKILL.md +134 -0
  61. package/skills/workflow/hitl-queue/scripts/queue.mjs +626 -0
  62. package/skills/workflow/plan/SKILL.md +27 -3
  63. package/skills/workflow/prioritise-work/CHALLENGE.md +139 -0
  64. package/skills/workflow/prioritise-work/SKILL.md +150 -0
  65. package/skills/workflow/prioritise-work/scripts/challenge.mjs +505 -0
  66. package/skills/workflow/prioritise-work/scripts/strategy.mjs +566 -0
  67. package/skills/workflow/prioritise-work/templates/strategy.md +61 -0
  68. package/skills/workflow/ralph/REFERENCE.md +124 -27
  69. package/skills/workflow/ralph/SKILL.md +24 -15
  70. package/skills/workflow/ralph/scripts/post-merge-check.mjs +651 -0
  71. package/skills/workflow/run-pipeline-stage/SKILL.md +37 -22
  72. package/skills/workflow/run-pipeline-stage/playbooks/code.md +14 -8
  73. package/skills/workflow/run-pipeline-stage/playbooks/document.md +2 -2
  74. package/skills/workflow/run-pipeline-stage/playbooks/fix.md +2 -2
  75. package/skills/workflow/run-pipeline-stage/playbooks/housekeeping.md +1 -1
  76. package/skills/workflow/run-pipeline-stage/playbooks/post-merge.md +54 -0
  77. package/skills/workflow/run-pipeline-stage/playbooks/review.md +37 -3
  78. package/skills/workflow/run-pipeline-stage/playbooks/verify.md +2 -2
  79. package/skills/workflow/run-pipeline-stage/prompts/stage-runner.md +55 -11
  80. package/skills/workflow/run-pipeline-stage/scripts/recover-brief.mjs +805 -0
  81. package/skills/workflow/run-pipeline-stage/scripts/trail-entry.mjs +702 -0
  82. package/skills/workflow/score-bead/FORMAT.md +73 -0
  83. package/skills/workflow/score-bead/SKILL.md +112 -0
  84. package/skills/workflow/score-bead/scripts/rice.mjs +664 -0
  85. package/skills/workflow/using-agent-skills/SKILL.md +21 -8
  86. package/token-map.README.md +27 -0
  87. package/token-map.json +16 -4
@@ -16,7 +16,63 @@ A skill that is *loaded* frequently but *never read* may be burning context budg
16
16
 
17
17
  ## Data
18
18
 
19
- Usage data is stored in `~/.pi/agent-cortex/skill-usage.json` — a single file across all projects, with per-project breakdowns so you can slice by project.
19
+ Usage data is stored in `~/.pi/agent-cortex/` — global, across all projects, with per-project
20
+ breakdowns so you can slice by project. There are two files, with different fidelity:
21
+
22
+ | File | Fidelity | Kept for |
23
+ |---|---|---|
24
+ | `skill-usage.json` | Per-skill counters, per-project breakdown, and a 200-event ring of recent events | Until a skill has been unused for ~3 months (existing age-out) |
25
+ | `skill-usage-daily.json` | One record per skill per day: loaded / invoked / read counts and the distinct projects seen that day | 365 days by default, pruned on every write |
26
+
27
+ The counters answer "what is my all-time shape, and what happened in the last few minutes". The
28
+ daily rollups answer "how has my usage changed over months" without scanning session transcripts.
29
+ The rollups are a second file beside the counters, not a replacement: the counters and their
30
+ 200-event ring are unchanged by this feature.
31
+
32
+ ### Retention and size policy
33
+
34
+ - **Retention window: 365 days by default.** Override it per machine with
35
+ `AGENT_CORTEX_SKILL_STATS_RETENTION_DAYS` (a positive whole number of days). Invalid values fall
36
+ back to the default.
37
+ - **Pruning happens on write, not on read.** Every save drops day records older than the window, so a
38
+ long-lived install can never accumulate more than the window's worth of days. The `timeline` view
39
+ only reads; it prunes nothing.
40
+ - **Each record is fixed-size.** Counts are numbers, the distinct-project list per skill-day is capped
41
+ at 50 entries, and a stored project path is truncated to 120 characters, so one skill-day's record
42
+ cannot grow with the number of events that day or with working-directory depth. Two long paths that
43
+ share their first 120 characters count as one project.
44
+ - **The file has a hard ceiling of 2,920,000 bytes, enforced on every write.** That is 365 days x 40
45
+ skills x 200 bytes per skill-day (the counts plus one realistic project path); the 40 sizes the
46
+ budget and is not a limit on how many skills an install may have. A realistic file is far smaller:
47
+ 994,668 bytes for 40 skills used every day of the window, two events each and a short project path
48
+ (`/proj/a`), and 1,272,068 bytes for the same usage with a 26-character project path. A retention
49
+ window longer than 365 days does not raise the ceiling, so the detail it implies is shed by the
50
+ rule below.
51
+ When a write would exceed the ceiling, `saveRollups` drops the per-skill-day project lists first —
52
+ the loaded / invoked / read counts and every day survive, and every number the timeline renders is
53
+ unchanged. Only if the counts alone exceed the ceiling does it drop the oldest days, continuing the
54
+ direction pruning already takes. `saveRollups` returns what this write gave up
55
+ (`shedProjectLists`, `droppedDays`) and the size it wrote, and it keeps running totals in the file
56
+ under `shed`, so `/skill-stats timeline` reports the loss after a reload rather than leaving the
57
+ user to find out only by looking. The rendered line names the day of the most recent shedding
58
+ write, how many project lists and how many days went in total, and the ceiling that forced it.
59
+ - **A ceiling shed moves the reported start; ordinary pruning does not.** When shedding drops whole
60
+ days, those days were inside the retention window, so `since` moves to the oldest day the file
61
+ still holds and the header can never claim a day that was deleted. Days that age out of the window
62
+ are different: they were real history and the rendered retention line explains them, so `since`
63
+ keeps the first-ever day.
64
+ - **The file is written minified** — it is read by the extension, not by a human. The suite fills
65
+ every cap at once (40 skills x 365 days x 50 project paths), asserts the 22,033,268 raw bytes are
66
+ written as at most 2,920,000, and asserts a second year of data leaves the file byte-for-byte
67
+ unchanged.
68
+
69
+ ### History before the rollups
70
+
71
+ Rollups start with the first skill event recorded after this version was installed. Anything earlier
72
+ is reported as **unavailable**, not as zero usage, and no data point is invented for it. A ceiling
73
+ shed that deletes days reports on the same screen, so a moved start is explained rather than silent.
74
+ Backfilling from old session transcripts is a possible follow-up, and deliberately not part of this
75
+ feature.
20
76
 
21
77
  ## Installation
22
78
 
@@ -43,7 +99,8 @@ ln -sf $(pwd)/extensions/skill-stats ~/.pi/agent/extensions/skill-stats
43
99
  |---|---|
44
100
  | `/skill-stats` | Show usage dashboard with per-project slicing |
45
101
  | `/skill-stats --project ./relative/path` | Filter to a specific project |
46
- | `/skill-usage-reset` | Wipe all recorded data |
102
+ | `/skill-stats timeline` | Per-day, per-week and per-month counts and distinct skills, from the daily rollups |
103
+ | `/skill-usage-reset` | Wipe all recorded data, counters and rollups |
47
104
 
48
105
  ## Raw data
49
106
 
@@ -59,7 +116,7 @@ The JSON file at `~/.pi/agent-cortex/skill-usage.json` contains the full record:
59
116
  "readCount": 18,
60
117
  "lastUsed": "2026-06-07T...",
61
118
  "byProject": {
62
- "/home/jaybeeuu/src/agent-cortex": {
119
+ "/home/user/projects/app": {
63
120
  "loadedCount": 40,
64
121
  "invokedCount": 3,
65
122
  "readCount": 16,
@@ -72,3 +129,27 @@ The JSON file at `~/.pi/agent-cortex/skill-usage.json` contains the full record:
72
129
  "lastUpdated": "2026-06-07T..."
73
130
  }
74
131
  ```
132
+
133
+ The rollups in `~/.pi/agent-cortex/skill-usage-daily.json` are minified and keyed by day:
134
+
135
+ ```json
136
+ {
137
+ "version": 1,
138
+ "since": "2026-06-01",
139
+ "days": {
140
+ "2026-06-07": {
141
+ "bd-tool": { "loaded": 2, "invoked": 1, "read": 3, "projects": ["/home/user/projects/app"] }
142
+ }
143
+ },
144
+ "shed": { "on": "2026-06-08", "projectLists": 14600, "days": 0 }
145
+ }
146
+ ```
147
+
148
+ `since` is the first day a rollup is held for. It survives pruning, so the timeline can say where
149
+ the recorded history starts; it moves forward only when a ceiling shed deletes days, which nothing
150
+ else explains.
151
+
152
+ `shed` appears only after a write had to give up detail for the size ceiling, and holds the totals
153
+ dropped by shedding (`projectLists`, `days`) plus the day of the most recent such write. A file
154
+ written before this field existed has no `shed` key, and such a file loads and renders unchanged:
155
+ an absent record means nothing was shed.
@@ -4,13 +4,56 @@ import path from "node:path";
4
4
  // Re-export public API for tests and consumers
5
5
  export { type ProjectCounts, type SkillStats, type UsageStore, type RawEvent, loadStore, saveStore, ageOutStore } from "./store.js";
6
6
  export { recordUsage } from "./record.js";
7
+ export {
8
+ type DaySkillCounts,
9
+ type Granularity,
10
+ type RollupStore,
11
+ type SaveRollupsResult,
12
+ type ShedRecord,
13
+ type TimelineBucket,
14
+ DEFAULT_RETENTION_DAYS,
15
+ MAX_PROJECT_PATH_CHARS,
16
+ MAX_PROJECTS_PER_DAY,
17
+ MAX_ROLLUP_FILE_BYTES,
18
+ RETENTION_ENV,
19
+ bucketKey,
20
+ dayKey,
21
+ loadRollups,
22
+ oldestDay,
23
+ pruneRollups,
24
+ recordDailyUsage,
25
+ retentionCutoff,
26
+ retentionDays,
27
+ rollupFilePath,
28
+ saveRollups,
29
+ shiftDay,
30
+ timeline,
31
+ } from "./rollup.js";
32
+ export { formatTimeline, isTimelineRequest } from "./timeline.js";
7
33
  export { type SkillRecord, globalSkillDirs, scanSkills, extractSkillName, discoverProjectSkills, resolveSkillFromPath } from "./discover.js";
8
34
  export { formatTable } from "./format.js";
9
35
 
10
- import { loadStore, saveStore } from "./store.js";
36
+ import { loadStore, saveStore, type RawEvent } from "./store.js";
11
37
  import { recordUsage } from "./record.js";
12
38
  import { resolveSkillFromPath, globalSkillDirs, scanSkills, discoverProjectSkills } from "./discover.js";
13
39
  import { formatTable } from "./format.js";
40
+ import { loadRollups, recordDailyUsage, saveRollups } from "./rollup.js";
41
+ import { formatTimeline, isTimelineRequest } from "./timeline.js";
42
+
43
+ /**
44
+ * Record one usage event into the long-range rollups. The counters and the
45
+ * recent-event ring in the store are written by `recordUsage`/`saveStore` as
46
+ * before; this adds the per-day record beside them.
47
+ */
48
+ function recordRollup(
49
+ skillName: string,
50
+ source: RawEvent["source"],
51
+ project: string,
52
+ ): void {
53
+ const rollups = loadRollups();
54
+ recordDailyUsage(rollups, skillName, source, project);
55
+ saveRollups(rollups);
56
+ }
14
57
 
15
58
  // ── Extension entry point ─────────────────────────────────────────────────────
16
59
 
@@ -32,12 +75,16 @@ export default function (pi: ExtensionAPI) {
32
75
  if (!skills?.length) return;
33
76
 
34
77
  const store = loadStore();
78
+ const rollups = loadRollups();
35
79
  const project = ctx.cwd;
36
80
  for (const skill of skills) {
37
81
  const name = typeof skill === "string" ? skill : skill.name;
38
- if (name) recordUsage(store, name, "loaded", project);
82
+ if (!name) continue;
83
+ recordUsage(store, name, "loaded", project);
84
+ recordDailyUsage(rollups, name, "loaded", project);
39
85
  }
40
86
  saveStore(store);
87
+ saveRollups(rollups);
41
88
  });
42
89
 
43
90
  // ── 2. Track /skill:name invocations ──────────────────────────────────
@@ -48,6 +95,7 @@ export default function (pi: ExtensionAPI) {
48
95
  const store = loadStore();
49
96
  recordUsage(store, m[1], "invoked", ctx.cwd);
50
97
  saveStore(store);
98
+ recordRollup(m[1], "invoked", ctx.cwd);
51
99
  });
52
100
 
53
101
  // ── 3. Track SKILL.md reads by the LLM ────────────────────────────────
@@ -64,6 +112,7 @@ export default function (pi: ExtensionAPI) {
64
112
  const store = loadStore();
65
113
  recordUsage(store, skillName, "read", ctx.cwd);
66
114
  saveStore(store);
115
+ recordRollup(skillName, "read", ctx.cwd);
67
116
  });
68
117
 
69
118
  // ── 4. Track turns ────────────────────────────────────────────────────
@@ -88,8 +137,17 @@ export default function (pi: ExtensionAPI) {
88
137
  // ── 5. /skill-stats command ───────────────────────────────────────────
89
138
  pi.registerCommand("skill-stats", {
90
139
  description:
91
- "Show skill usage stats. Filter by project: /skill-stats --project <path>",
140
+ "Show skill usage stats. Filter by project: /skill-stats --project <path>. Long-range history: /skill-stats timeline",
92
141
  handler: async (args, ctx) => {
142
+ // The timeline view reads the daily rollups and nothing else — not the
143
+ // counters, and never a session transcript.
144
+ if (isTimelineRequest(args)) {
145
+ const output = formatTimeline(loadRollups());
146
+ ctx.ui.notify("Skill usage timeline from daily rollups.", "info");
147
+ console.log(output);
148
+ return;
149
+ }
150
+
93
151
  const store = loadStore();
94
152
 
95
153
  let projectFilter: string | null = null;
@@ -216,6 +274,7 @@ export default function (pi: ExtensionAPI) {
216
274
  lastUpdated: new Date().toISOString(),
217
275
  recentEvents: [],
218
276
  });
277
+ saveRollups({ version: 1, since: null, days: {} });
219
278
  ctx.ui.notify("Skill usage statistics reset.", "info");
220
279
  },
221
280
  });
@@ -4,7 +4,7 @@
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
7
- "test": "node --test --import tsx/esm index.test.ts",
7
+ "test": "node --test --import tsx/esm index.test.ts rollup.test.ts",
8
8
  "typecheck": "tsc --noEmit"
9
9
  },
10
10
  "devDependencies": {