codymaster 4.4.4 → 4.5.1

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 (190) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +29 -14
  3. package/commands/demo.md +1 -1
  4. package/dist/context-bus.js +70 -0
  5. package/dist/context-db.js +265 -0
  6. package/dist/continuity.js +12 -0
  7. package/dist/file-watcher.js +79 -0
  8. package/dist/index.js +152 -1
  9. package/dist/l0-indexer.js +158 -0
  10. package/dist/mcp-context-server.js +400 -0
  11. package/dist/migrate-json-to-sqlite.js +126 -0
  12. package/dist/skill-chain.js +19 -3
  13. package/dist/token-budget.js +108 -0
  14. package/dist/uri-resolver.js +203 -0
  15. package/package.json +7 -1
  16. package/skills/_shared/helpers.md +50 -14
  17. package/skills/cm-autopilot/SKILL.md +29 -0
  18. package/skills/cm-autopilot/scripts/autopilot.py +190 -0
  19. package/skills/cm-continuity/SKILL.md +90 -28
  20. package/skills/cm-quality-gate/SKILL.md +11 -1
  21. package/skills/cm-safe-deploy/SKILL.md +38 -2
  22. package/skills/cm-security-gate/SKILL.md +158 -34
  23. package/skills/cm-skill-chain/SKILL.md +47 -1
  24. package/skills/cm-start/SKILL.md +11 -2
  25. package/skills/cm-test-gate/SKILL.md +3 -0
  26. package/skills/boxme-git-config/SKILL.md +0 -56
  27. package/skills/boxme-local-dev/SKILL.md +0 -66
  28. package/skills/jobs-to-be-done/SKILL.md +0 -266
  29. package/skills/jobs-to-be-done/references/case-studies.md +0 -154
  30. package/skills/jobs-to-be-done/references/competitive-strategy.md +0 -280
  31. package/skills/jobs-to-be-done/references/diagnostics.md +0 -158
  32. package/skills/jobs-to-be-done/references/innovation-process.md +0 -392
  33. package/skills/jobs-to-be-done/references/organizational-change.md +0 -328
  34. package/skills/marketplace-report-crawler/SKILL.md +0 -176
  35. package/skills/marketplace-report-crawler/config/accounts.json +0 -41
  36. package/skills/marketplace-report-crawler/config/report-types.json +0 -422
  37. package/skills/marketplace-report-crawler/config/sessions.json +0 -3
  38. package/skills/marketplace-report-crawler/scripts/ab-wrapper.sh +0 -102
  39. package/skills/marketplace-report-crawler/scripts/browser-actions/lazada/lazada-actions.js +0 -114
  40. package/skills/marketplace-report-crawler/scripts/browser-actions/shopee/shopee-actions.js +0 -94
  41. package/skills/marketplace-report-crawler/scripts/browser-actions/tiktok/tiktok-actions.js +0 -272
  42. package/skills/marketplace-report-crawler/scripts/crawl-runner.js +0 -281
  43. package/skills/marketplace-report-crawler/scripts/session-check.sh +0 -72
  44. package/skills/marketplace-report-crawler/scripts/session-manager.sh +0 -349
  45. package/skills/marketplace-report-crawler/scripts/setup-folders.sh +0 -83
  46. package/skills/medical-research/SKILL.md +0 -194
  47. package/skills/medical-research/scripts/evidence_checker.py +0 -288
  48. package/skills/mom-test/SKILL.md +0 -267
  49. package/skills/mom-test/references/avoiding-bad-data.md +0 -221
  50. package/skills/mom-test/references/case-studies.md +0 -306
  51. package/skills/mom-test/references/commitment-advancement.md +0 -219
  52. package/skills/mom-test/references/finding-conversations.md +0 -251
  53. package/skills/mom-test/references/processing-learning.md +0 -256
  54. package/skills/mom-test/references/question-patterns.md +0 -198
  55. package/skills/pandasai-analytics/SKILL.md +0 -251
  56. package/skills/release-it/SKILL.md +0 -235
  57. package/skills/release-it/references/anti-patterns.md +0 -279
  58. package/skills/release-it/references/capacity-planning.md +0 -285
  59. package/skills/release-it/references/chaos-engineering.md +0 -325
  60. package/skills/release-it/references/deployment-strategies.md +0 -331
  61. package/skills/release-it/references/observability.md +0 -301
  62. package/skills/release-it/references/stability-patterns.md +0 -355
  63. package/skills/skill-creator-ultra/.agents/workflows/skill-audit.md +0 -37
  64. package/skills/skill-creator-ultra/.agents/workflows/skill-compare.md +0 -34
  65. package/skills/skill-creator-ultra/.agents/workflows/skill-export.md +0 -51
  66. package/skills/skill-creator-ultra/.agents/workflows/skill-generate.md +0 -39
  67. package/skills/skill-creator-ultra/.agents/workflows/skill-scaffold.md +0 -52
  68. package/skills/skill-creator-ultra/.agents/workflows/skill-simulate.md +0 -25
  69. package/skills/skill-creator-ultra/.agents/workflows/skill-stats.md +0 -31
  70. package/skills/skill-creator-ultra/.agents/workflows/skill-validate.md +0 -25
  71. package/skills/skill-creator-ultra/README.md +0 -1242
  72. package/skills/skill-creator-ultra/SKILL.md +0 -388
  73. package/skills/skill-creator-ultra/agents/analyzer.md +0 -274
  74. package/skills/skill-creator-ultra/agents/comparator.md +0 -202
  75. package/skills/skill-creator-ultra/agents/grader.md +0 -223
  76. package/skills/skill-creator-ultra/assets/eval_review.html +0 -146
  77. package/skills/skill-creator-ultra/eval-viewer/generate_review.py +0 -471
  78. package/skills/skill-creator-ultra/eval-viewer/viewer.html +0 -1325
  79. package/skills/skill-creator-ultra/examples/example_anthropic_frontend.md +0 -109
  80. package/skills/skill-creator-ultra/examples/example_anthropic_pdf.md +0 -116
  81. package/skills/skill-creator-ultra/examples/example_api_docs.md +0 -189
  82. package/skills/skill-creator-ultra/examples/example_db_migration.md +0 -253
  83. package/skills/skill-creator-ultra/examples/example_git_commit.md +0 -111
  84. package/skills/skill-creator-ultra/install.ps1 +0 -289
  85. package/skills/skill-creator-ultra/install.sh +0 -313
  86. package/skills/skill-creator-ultra/phases/phase1_interview.md +0 -202
  87. package/skills/skill-creator-ultra/phases/phase2_extract.md +0 -55
  88. package/skills/skill-creator-ultra/phases/phase3_detect.md +0 -57
  89. package/skills/skill-creator-ultra/phases/phase4_generate.md +0 -543
  90. package/skills/skill-creator-ultra/phases/phase5_test.md +0 -319
  91. package/skills/skill-creator-ultra/phases/phase6_eval.md +0 -301
  92. package/skills/skill-creator-ultra/phases/phase7_iterate.md +0 -103
  93. package/skills/skill-creator-ultra/phases/phase8_optimize.md +0 -113
  94. package/skills/skill-creator-ultra/resources/advanced_patterns.md +0 -499
  95. package/skills/skill-creator-ultra/resources/anti_patterns.md +0 -376
  96. package/skills/skill-creator-ultra/resources/blueprints.md +0 -498
  97. package/skills/skill-creator-ultra/resources/checklist.md +0 -243
  98. package/skills/skill-creator-ultra/resources/composition_cookbook.md +0 -291
  99. package/skills/skill-creator-ultra/resources/description_optimization.md +0 -90
  100. package/skills/skill-creator-ultra/resources/eval_guide.md +0 -133
  101. package/skills/skill-creator-ultra/resources/industry_questions.md +0 -189
  102. package/skills/skill-creator-ultra/resources/interview_questions.md +0 -200
  103. package/skills/skill-creator-ultra/resources/pattern_detection.md +0 -200
  104. package/skills/skill-creator-ultra/resources/prompt_engineering.md +0 -531
  105. package/skills/skill-creator-ultra/resources/schemas.md +0 -430
  106. package/skills/skill-creator-ultra/resources/script_integration.md +0 -593
  107. package/skills/skill-creator-ultra/resources/scripts_guide.md +0 -339
  108. package/skills/skill-creator-ultra/resources/skill_template.md +0 -124
  109. package/skills/skill-creator-ultra/resources/skill_writing_guide.md +0 -634
  110. package/skills/skill-creator-ultra/resources/versioning_guide.md +0 -193
  111. package/skills/skill-creator-ultra/scripts/ci_eval.py +0 -200
  112. package/skills/skill-creator-ultra/scripts/package_skill.py +0 -165
  113. package/skills/skill-creator-ultra/scripts/simulate_skill.py +0 -398
  114. package/skills/skill-creator-ultra/scripts/skill_audit.py +0 -611
  115. package/skills/skill-creator-ultra/scripts/skill_compare.py +0 -265
  116. package/skills/skill-creator-ultra/scripts/skill_export.py +0 -334
  117. package/skills/skill-creator-ultra/scripts/skill_scaffold.py +0 -403
  118. package/skills/skill-creator-ultra/scripts/skill_stats.py +0 -339
  119. package/skills/skill-creator-ultra/scripts/validate_skill.py +0 -411
  120. package/skills/tailwind-mastery/SKILL.md +0 -229
  121. package/skills/vercel-react-best-practices/AGENTS.md +0 -3373
  122. package/skills/vercel-react-best-practices/README.md +0 -123
  123. package/skills/vercel-react-best-practices/SKILL.md +0 -143
  124. package/skills/vercel-react-best-practices/rules/_sections.md +0 -46
  125. package/skills/vercel-react-best-practices/rules/_template.md +0 -28
  126. package/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
  127. package/skills/vercel-react-best-practices/rules/advanced-init-once.md +0 -42
  128. package/skills/vercel-react-best-practices/rules/advanced-use-latest.md +0 -39
  129. package/skills/vercel-react-best-practices/rules/async-api-routes.md +0 -38
  130. package/skills/vercel-react-best-practices/rules/async-defer-await.md +0 -80
  131. package/skills/vercel-react-best-practices/rules/async-dependencies.md +0 -51
  132. package/skills/vercel-react-best-practices/rules/async-parallel.md +0 -28
  133. package/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
  134. package/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -59
  135. package/skills/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
  136. package/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
  137. package/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
  138. package/skills/vercel-react-best-practices/rules/bundle-preload.md +0 -50
  139. package/skills/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
  140. package/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
  141. package/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
  142. package/skills/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
  143. package/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -107
  144. package/skills/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
  145. package/skills/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
  146. package/skills/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
  147. package/skills/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
  148. package/skills/vercel-react-best-practices/rules/js-early-exit.md +0 -50
  149. package/skills/vercel-react-best-practices/rules/js-flatmap-filter.md +0 -60
  150. package/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
  151. package/skills/vercel-react-best-practices/rules/js-index-maps.md +0 -37
  152. package/skills/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
  153. package/skills/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
  154. package/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
  155. package/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
  156. package/skills/vercel-react-best-practices/rules/rendering-activity.md +0 -26
  157. package/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
  158. package/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
  159. package/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
  160. package/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
  161. package/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
  162. package/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
  163. package/skills/vercel-react-best-practices/rules/rendering-resource-hints.md +0 -85
  164. package/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +0 -68
  165. package/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
  166. package/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +0 -75
  167. package/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
  168. package/skills/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
  169. package/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
  170. package/skills/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
  171. package/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
  172. package/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
  173. package/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
  174. package/skills/vercel-react-best-practices/rules/rerender-memo.md +0 -44
  175. package/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
  176. package/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +0 -82
  177. package/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
  178. package/skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +0 -64
  179. package/skills/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
  180. package/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md +0 -59
  181. package/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
  182. package/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
  183. package/skills/vercel-react-best-practices/rules/server-auth-actions.md +0 -96
  184. package/skills/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
  185. package/skills/vercel-react-best-practices/rules/server-cache-react.md +0 -76
  186. package/skills/vercel-react-best-practices/rules/server-dedup-props.md +0 -65
  187. package/skills/vercel-react-best-practices/rules/server-hoist-static-io.md +0 -142
  188. package/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
  189. package/skills/vercel-react-best-practices/rules/server-serialization.md +0 -38
  190. package/skills/web-design-guidelines/SKILL.md +0 -39
package/CHANGELOG.md CHANGED
@@ -4,6 +4,39 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  Categories: 🚀 **Improvements** | 🐛 **Bug Fixes** | 🔒 **Security**
6
6
 
7
+ ## [4.5.0] - 2026-03-31
8
+
9
+ ### 🚀 Improvements — Context Backbone v5 (Smart Spine)
10
+
11
+ - **SQLite + FTS5 Storage Layer** — Learnings and decisions migrated from flat JSON to a WAL-mode SQLite database (`.cm/context.db`) with full-text search via FTS5 virtual tables. BM25-ranked `cm_query` replaces linear JSON scans. FTS5 indexes are kept in sync automatically via `AFTER INSERT`/`AFTER DELETE` triggers.
12
+ - **L0 / L1 / L2 Progressive Loading** — Every memory resource is now available at three granularities. L0 compact indexes (`learnings-index.md`, `skeleton-index.md`) reduce context cost by up to 96% for the common "just give me a summary" case. L0 is pre-generated on every `addLearning()` write and refreshable on demand.
13
+ - **cm:// URI Scheme** — Unified content addressing for all CodyMaster resources. Skills reference context by URI (`cm://memory/learnings`, `cm://skills/cm-tdd/L0`, `cm://pipeline/current`) and the resolver handles depth selection, caching, and fallbacks transparently.
14
+ - **MCP Context Server** — Standalone stdio MCP server (`src/mcp-context-server.ts`) exposing 7 tools to Claude Desktop and any MCP-compatible client:
15
+ - `cm_query` — FTS5 search across learnings + decisions with scope filter
16
+ - `cm_resolve` — resolve any `cm://` URI at L0/L1/L2
17
+ - `cm_bus_read` / `cm_bus_write` — read/publish to the context bus
18
+ - `cm_budget_check` — pre-flight token budget check by category
19
+ - `cm_memory_decay` — TTL-based archival with `dry_run` option
20
+ - `cm_index_refresh` — regenerate L0 indexes on demand
21
+ - **Token Budget Enforcement** — 200k-token window pre-allocated by category in `.cm/token-budget.json`. Budget checked at load time; overages return a remediation suggestion. Configurable per-project.
22
+ - **Context Bus** — `.cm/context-bus.json` tracks skill chain state across steps. Each skill publishes its output; downstream skills read what upstream steps produced via `cm://pipeline/current`. Integrated into `createChainExecution()` and `advanceChain()`.
23
+ - **File Watcher** — `src/file-watcher.ts` (chokidar) watches `.cm/memory/*.json` and auto-regenerates the L0 learnings index on change with 300ms debounce.
24
+ - **JSON → SQLite Migration** — One-time migration utility (`src/migrate-json-to-sqlite.ts`) reads existing `learnings.json` / `decisions.json`, inserts into SQLite, and creates `.backup` files. Handles both camelCase and snake_case legacy field names.
25
+ - **New CLI commands** — `cm continuity index` (regenerate L0 indexes), `cm continuity budget` (show token allocation table), `cm continuity bus` (pretty-print context bus), `cm continuity mcp` (print Claude Desktop config snippet).
26
+ - **Test suite expanded** — 4 new test files covering SQLite CRUD + FTS5 relevance, context bus roundtrip, token budget enforcement, and L0 index generation. Test count: 78 → 92 (all passing).
27
+
28
+ ## [4.4.5] - 2026-03-30
29
+
30
+ ### 🔒 Security
31
+
32
+ - **Security Checkpoints Upgraded** — Deployed unified security updates across `cm-security-gate`, `cm-quality-gate`, `cm-safe-deploy`, and `cm-test-gate`.
33
+
34
+ ## [4.4.4] - 2026-03-29
35
+
36
+ ### 🐛 Bug Fixes
37
+
38
+ - **Version Bump** — Minor bug fixes and dependency updates.
39
+
7
40
  ## [4.4.3] - 2026-03-29
8
41
 
9
42
  ### 🚀 Improvements — The Self-Healing Update
package/README.md CHANGED
@@ -6,10 +6,10 @@
6
6
 
7
7
  ### Your AI Agent is smart. CodyMaster makes it *wise*.
8
8
 
9
- **68+ Skills · 11 Commands · 1 Plugin · 7+ Platforms · 6 Languages**
9
+ **68+ Skills · 18 Commands · 1 Plugin · 7+ Platforms · 6 Languages**
10
10
 
11
11
  <p align="center">
12
- <img alt="Version" src="https://img.shields.io/badge/version-4.4.3-blue.svg?cacheSeconds=2592000" />
12
+ <img alt="Version" src="https://img.shields.io/badge/version-4.5.0-blue.svg?cacheSeconds=2592000" />
13
13
  <img alt="Skills" src="https://img.shields.io/badge/skills-68+-success.svg" />
14
14
  <img alt="Platforms" src="https://img.shields.io/badge/platforms-7+-orange.svg" />
15
15
  <img alt="Open Source" src="https://img.shields.io/badge/license-MIT-purple.svg" />
@@ -105,9 +105,9 @@ graph LR
105
105
  class A,B,C,D,E,F,G,H,I,J,K,L phase;
106
106
  ```
107
107
 
108
- ### 🧠 The Unified Brain: 5-Tier Memory Architecture
108
+ ### 🧠 The Unified Brain: 5-Tier Memory + Smart Spine
109
109
 
110
- Your AI doesn't just execute — it **understands and remembers** using a multi-scale, 5-Tier Unified Brain system that persists across sessions and machines:
110
+ Your AI doesn't just execute — it **understands and remembers** using a multi-scale, 5-Tier + Smart Spine architecture that persists across sessions and machines:
111
111
 
112
112
  1. **Sensory Memory (Session)** — Immediate context of active files and terminals.
113
113
  2. **Working Memory (`cm-continuity`)** — Cross-session scratchpad. AI never repeats the same mistake.
@@ -115,10 +115,18 @@ Your AI doesn't just execute — it **understands and remembers** using a multi-
115
115
  4. **Semantic Memory (`cm-deep-search`)** — Local vector search across docs using `qmd`.
116
116
  5. **Structural Memory (`cm-codeintell`)** — AST-based CodeGraph. Up to 95% token compression for full codebase context.
117
117
 
118
+ 🦴 **Smart Spine (v4.5+)** — The nervous system connecting all 5 tiers:
119
+ - **SQLite + FTS5** — BM25-ranked keyword search replaces flat JSON scans.
120
+ - **Progressive Loading (L0/L1/L2)** — Context loaded at cheapest sufficient depth. 78% token savings.
121
+ - **cm:// URI Scheme** — Skills request context by URI, not file paths.
122
+ - **Token Budget** — 200k window pre-allocated by category. No more silent overflow.
123
+ - **Context Bus** — Skills share outputs in real-time within a chain.
124
+ - **MCP Server** — 7 tools exposed to Claude Desktop and any MCP client.
125
+
118
126
  ☁️ **The Cloud Brain (`cm-notebooklm`)**
119
127
  High-value knowledge and design patterns are synced to NotebookLM, providing a universal, cross-machine "Soul" for your project. Auto-generate podcasts and flashcards to onboard human developers alongside the AI.
120
128
 
121
- 📖 [Read the full Knowledge Architecture →](docs/knowledge-architecture.md)
129
+ 📖 [Read the full Knowledge Architecture →](docs/architecture/knowledge-architecture.md)
122
130
 
123
131
  ### 🛡️ Multi-Layer Protection (Your Codebase Won't Get Destroyed)
124
132
 
@@ -166,7 +174,7 @@ Don't know what the old code does? **`cm-dockit`** reads your entire codebase an
166
174
 
167
175
  Before diving into code for complex requests, **`cm-brainstorm-idea`** evaluates your product using multi-dimensional analysis (Tech, Product, Design, Business). It generates 2-3 qualified options using the 9 Windows (TRIZ) framework and provides a visual UI Preview via **Pencil.dev** or **Google Stitch** to validate the direction before detailed planning.
168
176
 
169
- 📖 [Read more about the UI Preview Phase →](docs/Brainstorm-UI-Preview.md)
177
+ 📖 [Read more about the UI Preview Phase →](docs/workflows/brainstorm-ui-preview.md)
170
178
 
171
179
 
172
180
  ### 🏭 AI Content Factory v2.0 & Visual Dashboard
@@ -294,14 +302,21 @@ The CLI will greet you and keep you organized on your long coding sessions!
294
302
  ## 🎮 Commands
295
303
 
296
304
  ```
297
- cm → Quick menu with Cody 🐹
298
- cm task add "..." → Add a task
299
- cm task list → View tasks
300
- cm status → Project health
301
- cm dashboard → Open Mission Control
302
- cm list → Browse 68+ skills
303
- cm profile → Your stats & achievements
304
- cm deploy <env> → Record deployment
305
+ cm → Quick menu with Cody 🐹
306
+ cm task add "..." → Add a task
307
+ cm task list → View tasks
308
+ cm status → Project health
309
+ cm dashboard → Open Mission Control
310
+ cm list → Browse 68+ skills
311
+ cm profile → Your stats & achievements
312
+ cm deploy <env> → Record deployment
313
+ cm continuity index → Regenerate L0 memory indexes
314
+ cm continuity budget → Show token budget allocation
315
+ cm continuity bus → View context bus state
316
+ cm continuity mcp → Print MCP server config
317
+ cm continuity migrate → Migrate JSON → SQLite
318
+ cm continuity export → Export SQLite → JSON
319
+ cm resolve <uri> → Resolve any cm:// URI
305
320
  ```
306
321
 
307
322
  **Slash Commands (inside AI agents):**
package/commands/demo.md CHANGED
@@ -24,7 +24,7 @@ Remember the chosen language and respond in it for all following steps.
24
24
 
25
25
  Show a warm, concise welcome. Include:
26
26
  - What CodyMaster is (1 sentence)
27
- - That it gives AI agents 34+ specialized skills
27
+ - That it gives AI agents 60+ specialized skills
28
28
  - That this demo will take ~2 minutes
29
29
 
30
30
  ## Step 3 — Show the Workflow
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.initBus = initBus;
7
+ exports.readBus = readBus;
8
+ exports.writeBus = writeBus;
9
+ exports.updateBusStep = updateBusStep;
10
+ const fs_1 = __importDefault(require("fs"));
11
+ const path_1 = __importDefault(require("path"));
12
+ // ─── Constants ──────────────────────────────────────────────────────────────
13
+ const CM_DIR = '.cm';
14
+ const BUS_FILE = 'context-bus.json';
15
+ function getBusPath(projectPath) {
16
+ return path_1.default.join(projectPath, CM_DIR, BUS_FILE);
17
+ }
18
+ // ─── Init ───────────────────────────────────────────────────────────────────
19
+ function initBus(projectPath, pipeline, sessionId) {
20
+ const now = new Date().toISOString();
21
+ const bus = {
22
+ version: '1.0',
23
+ session_id: sessionId,
24
+ pipeline,
25
+ current_step: '',
26
+ started_at: now,
27
+ updated_at: now,
28
+ shared_context: {},
29
+ resource_state: {
30
+ skeleton_generated: null,
31
+ learnings_indexed: null,
32
+ codegraph_indexed: null,
33
+ qmd_synced: null,
34
+ },
35
+ };
36
+ writeBus(projectPath, bus);
37
+ return bus;
38
+ }
39
+ // ─── Read ───────────────────────────────────────────────────────────────────
40
+ function readBus(projectPath) {
41
+ const busPath = getBusPath(projectPath);
42
+ if (!fs_1.default.existsSync(busPath))
43
+ return null;
44
+ try {
45
+ return JSON.parse(fs_1.default.readFileSync(busPath, 'utf-8'));
46
+ }
47
+ catch (_a) {
48
+ return null;
49
+ }
50
+ }
51
+ // ─── Write ──────────────────────────────────────────────────────────────────
52
+ function writeBus(projectPath, bus) {
53
+ const busPath = getBusPath(projectPath);
54
+ const dir = path_1.default.dirname(busPath);
55
+ if (!fs_1.default.existsSync(dir)) {
56
+ fs_1.default.mkdirSync(dir, { recursive: true });
57
+ }
58
+ fs_1.default.writeFileSync(busPath, JSON.stringify(bus, null, 2), 'utf-8');
59
+ }
60
+ // ─── Update Step ────────────────────────────────────────────────────────────
61
+ function updateBusStep(projectPath, skill, output) {
62
+ const bus = readBus(projectPath);
63
+ if (!bus) {
64
+ throw new Error(`Context bus not initialized at ${projectPath}. Call initBus() first.`);
65
+ }
66
+ bus.current_step = skill;
67
+ bus.updated_at = new Date().toISOString();
68
+ bus.shared_context[skill] = output;
69
+ writeBus(projectPath, bus);
70
+ }
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.openDb = openDb;
7
+ exports.closeDb = closeDb;
8
+ exports.insertLearning = insertLearning;
9
+ exports.getLearningById = getLearningById;
10
+ exports.queryLearnings = queryLearnings;
11
+ exports.insertDecision = insertDecision;
12
+ exports.queryDecisions = queryDecisions;
13
+ exports.upsertIndex = upsertIndex;
14
+ exports.getIndex = getIndex;
15
+ exports.writeSkillOutput = writeSkillOutput;
16
+ exports.getSkillOutputs = getSkillOutputs;
17
+ exports.getDbPath = getDbPath;
18
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
19
+ const path_1 = __importDefault(require("path"));
20
+ // ─── DB Cache (one connection per path) ─────────────────────────────────────
21
+ const dbCache = new Map();
22
+ function getDb(dbPath) {
23
+ if (dbCache.has(dbPath))
24
+ return dbCache.get(dbPath);
25
+ const db = new better_sqlite3_1.default(dbPath);
26
+ db.pragma('journal_mode = WAL');
27
+ db.pragma('foreign_keys = ON');
28
+ dbCache.set(dbPath, db);
29
+ return db;
30
+ }
31
+ // ─── Schema ─────────────────────────────────────────────────────────────────
32
+ const SCHEMA = `
33
+ CREATE TABLE IF NOT EXISTS learnings (
34
+ id TEXT PRIMARY KEY,
35
+ what_failed TEXT NOT NULL,
36
+ why_failed TEXT NOT NULL DEFAULT '',
37
+ how_to_prevent TEXT NOT NULL DEFAULT '',
38
+ scope TEXT DEFAULT 'global',
39
+ ttl INTEGER DEFAULT 60,
40
+ reinforce_count INTEGER DEFAULT 0,
41
+ status TEXT DEFAULT 'active',
42
+ created_at TEXT NOT NULL,
43
+ updated_at TEXT NOT NULL,
44
+ agent TEXT,
45
+ task_id TEXT,
46
+ module TEXT
47
+ );
48
+
49
+ CREATE VIRTUAL TABLE IF NOT EXISTS learnings_fts USING fts5(
50
+ what_failed, why_failed, how_to_prevent,
51
+ content=learnings, content_rowid=rowid
52
+ );
53
+
54
+ CREATE TRIGGER IF NOT EXISTS learnings_ai AFTER INSERT ON learnings BEGIN
55
+ INSERT INTO learnings_fts(rowid, what_failed, why_failed, how_to_prevent)
56
+ VALUES (new.rowid, new.what_failed, new.why_failed, new.how_to_prevent);
57
+ END;
58
+
59
+ CREATE TRIGGER IF NOT EXISTS learnings_ad AFTER DELETE ON learnings BEGIN
60
+ INSERT INTO learnings_fts(learnings_fts, rowid, what_failed, why_failed, how_to_prevent)
61
+ VALUES('delete', old.rowid, old.what_failed, old.why_failed, old.how_to_prevent);
62
+ END;
63
+
64
+ CREATE TABLE IF NOT EXISTS decisions (
65
+ id TEXT PRIMARY KEY,
66
+ decision TEXT NOT NULL,
67
+ rationale TEXT NOT NULL DEFAULT '',
68
+ scope TEXT DEFAULT 'global',
69
+ status TEXT DEFAULT 'active',
70
+ superseded_by TEXT,
71
+ created_at TEXT NOT NULL,
72
+ agent TEXT
73
+ );
74
+
75
+ CREATE VIRTUAL TABLE IF NOT EXISTS decisions_fts USING fts5(
76
+ decision, rationale,
77
+ content=decisions, content_rowid=rowid
78
+ );
79
+
80
+ CREATE TRIGGER IF NOT EXISTS decisions_ai AFTER INSERT ON decisions BEGIN
81
+ INSERT INTO decisions_fts(rowid, decision, rationale)
82
+ VALUES (new.rowid, new.decision, new.rationale);
83
+ END;
84
+
85
+ CREATE TRIGGER IF NOT EXISTS decisions_ad AFTER DELETE ON decisions BEGIN
86
+ INSERT INTO decisions_fts(decisions_fts, rowid, decision, rationale)
87
+ VALUES ('delete', old.rowid, old.decision, old.rationale);
88
+ END;
89
+
90
+ CREATE TABLE IF NOT EXISTS skill_outputs (
91
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
92
+ session_id TEXT NOT NULL,
93
+ chain_id TEXT,
94
+ skill TEXT NOT NULL,
95
+ output_path TEXT,
96
+ summary TEXT,
97
+ affected_files TEXT,
98
+ metadata TEXT,
99
+ created_at TEXT NOT NULL
100
+ );
101
+
102
+ CREATE TABLE IF NOT EXISTS indexes (
103
+ resource TEXT NOT NULL,
104
+ level TEXT NOT NULL,
105
+ content TEXT NOT NULL,
106
+ token_count INTEGER,
107
+ generated_at TEXT NOT NULL,
108
+ source_hash TEXT,
109
+ PRIMARY KEY (resource, level)
110
+ );
111
+
112
+ CREATE TABLE IF NOT EXISTS token_usage (
113
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
114
+ session_id TEXT NOT NULL,
115
+ category TEXT NOT NULL,
116
+ tokens_used INTEGER NOT NULL,
117
+ timestamp TEXT NOT NULL
118
+ );
119
+ `;
120
+ // ─── Open / Close ────────────────────────────────────────────────────────────
121
+ function openDb(dbPath) {
122
+ const db = getDb(dbPath);
123
+ db.exec(SCHEMA);
124
+ return db;
125
+ }
126
+ function closeDb(dbPath) {
127
+ const db = dbCache.get(dbPath);
128
+ if (db) {
129
+ try {
130
+ db.close();
131
+ }
132
+ catch ( /* already closed */_a) { /* already closed */ }
133
+ dbCache.delete(dbPath);
134
+ }
135
+ }
136
+ // ─── Learnings ───────────────────────────────────────────────────────────────
137
+ function insertLearning(dbPath, learning) {
138
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
139
+ const db = openDb(dbPath);
140
+ db.prepare(`
141
+ INSERT OR REPLACE INTO learnings
142
+ (id, what_failed, why_failed, how_to_prevent, scope, ttl, reinforce_count,
143
+ status, created_at, updated_at, agent, task_id, module)
144
+ VALUES
145
+ (@id, @what_failed, @why_failed, @how_to_prevent, @scope, @ttl, @reinforce_count,
146
+ @status, @created_at, @updated_at, @agent, @task_id, @module)
147
+ `).run({
148
+ id: learning.id,
149
+ what_failed: learning.what_failed,
150
+ why_failed: (_a = learning.why_failed) !== null && _a !== void 0 ? _a : '',
151
+ how_to_prevent: (_b = learning.how_to_prevent) !== null && _b !== void 0 ? _b : '',
152
+ scope: (_c = learning.scope) !== null && _c !== void 0 ? _c : 'global',
153
+ ttl: (_d = learning.ttl) !== null && _d !== void 0 ? _d : 60,
154
+ reinforce_count: (_e = learning.reinforce_count) !== null && _e !== void 0 ? _e : 0,
155
+ status: (_f = learning.status) !== null && _f !== void 0 ? _f : 'active',
156
+ created_at: learning.created_at,
157
+ updated_at: learning.updated_at,
158
+ agent: (_g = learning.agent) !== null && _g !== void 0 ? _g : null,
159
+ task_id: (_h = learning.task_id) !== null && _h !== void 0 ? _h : null,
160
+ module: (_j = learning.module) !== null && _j !== void 0 ? _j : null,
161
+ });
162
+ }
163
+ function getLearningById(dbPath, id) {
164
+ var _a;
165
+ const db = openDb(dbPath);
166
+ return (_a = db.prepare('SELECT * FROM learnings WHERE id = ?').get(id)) !== null && _a !== void 0 ? _a : null;
167
+ }
168
+ function queryLearnings(dbPath, query, scope, limit = 10) {
169
+ const db = openDb(dbPath);
170
+ if (!query.trim()) {
171
+ const sql = scope
172
+ ? "SELECT * FROM learnings WHERE scope = ? AND status != 'archived' ORDER BY created_at DESC LIMIT ?"
173
+ : "SELECT * FROM learnings WHERE status != 'archived' ORDER BY created_at DESC LIMIT ?";
174
+ return scope
175
+ ? db.prepare(sql).all(scope, limit)
176
+ : db.prepare(sql).all(limit);
177
+ }
178
+ // Sanitize scope for SQL (not user-facing, but defensive)
179
+ const scopeClause = scope ? `AND learnings.scope = '${scope.replace(/'/g, "''")}'` : '';
180
+ return db.prepare(`
181
+ SELECT learnings.* FROM learnings
182
+ JOIN learnings_fts ON learnings.rowid = learnings_fts.rowid
183
+ WHERE learnings_fts MATCH ?
184
+ AND learnings.status != 'archived'
185
+ ${scopeClause}
186
+ ORDER BY bm25(learnings_fts)
187
+ LIMIT ?
188
+ `).all(query, limit);
189
+ }
190
+ // ─── Decisions ───────────────────────────────────────────────────────────────
191
+ function insertDecision(dbPath, decision) {
192
+ var _a, _b, _c, _d, _e;
193
+ const db = openDb(dbPath);
194
+ db.prepare(`
195
+ INSERT OR REPLACE INTO decisions
196
+ (id, decision, rationale, scope, status, superseded_by, created_at, agent)
197
+ VALUES
198
+ (@id, @decision, @rationale, @scope, @status, @superseded_by, @created_at, @agent)
199
+ `).run({
200
+ id: decision.id,
201
+ decision: decision.decision,
202
+ rationale: (_a = decision.rationale) !== null && _a !== void 0 ? _a : '',
203
+ scope: (_b = decision.scope) !== null && _b !== void 0 ? _b : 'global',
204
+ status: (_c = decision.status) !== null && _c !== void 0 ? _c : 'active',
205
+ superseded_by: (_d = decision.superseded_by) !== null && _d !== void 0 ? _d : null,
206
+ created_at: decision.created_at,
207
+ agent: (_e = decision.agent) !== null && _e !== void 0 ? _e : null,
208
+ });
209
+ }
210
+ function queryDecisions(dbPath, query, limit = 10) {
211
+ const db = openDb(dbPath);
212
+ if (!query.trim()) {
213
+ return db.prepare("SELECT * FROM decisions WHERE status != 'archived' ORDER BY created_at DESC LIMIT ?").all(limit);
214
+ }
215
+ return db.prepare(`
216
+ SELECT decisions.* FROM decisions
217
+ JOIN decisions_fts ON decisions.rowid = decisions_fts.rowid
218
+ WHERE decisions_fts MATCH ?
219
+ AND decisions.status != 'archived'
220
+ ORDER BY bm25(decisions_fts)
221
+ LIMIT ?
222
+ `).all(query, limit);
223
+ }
224
+ // ─── Index Cache ─────────────────────────────────────────────────────────────
225
+ function upsertIndex(dbPath, resource, level, content, sourceHash) {
226
+ const db = openDb(dbPath);
227
+ const tokenCount = Math.ceil(content.length / 4);
228
+ db.prepare(`
229
+ INSERT OR REPLACE INTO indexes (resource, level, content, token_count, generated_at, source_hash)
230
+ VALUES (?, ?, ?, ?, ?, ?)
231
+ `).run(resource, level, content, tokenCount, new Date().toISOString(), sourceHash !== null && sourceHash !== void 0 ? sourceHash : null);
232
+ }
233
+ function getIndex(dbPath, resource, level) {
234
+ var _a;
235
+ const db = openDb(dbPath);
236
+ return (_a = db.prepare('SELECT * FROM indexes WHERE resource = ? AND level = ?').get(resource, level)) !== null && _a !== void 0 ? _a : null;
237
+ }
238
+ // ─── Skill Outputs ────────────────────────────────────────────────────────────
239
+ function writeSkillOutput(dbPath, output) {
240
+ var _a, _b, _c, _d, _e;
241
+ const db = openDb(dbPath);
242
+ db.prepare(`
243
+ INSERT INTO skill_outputs
244
+ (session_id, chain_id, skill, output_path, summary, affected_files, metadata, created_at)
245
+ VALUES
246
+ (@session_id, @chain_id, @skill, @output_path, @summary, @affected_files, @metadata, @created_at)
247
+ `).run({
248
+ session_id: output.session_id,
249
+ chain_id: (_a = output.chain_id) !== null && _a !== void 0 ? _a : null,
250
+ skill: output.skill,
251
+ output_path: (_b = output.output_path) !== null && _b !== void 0 ? _b : null,
252
+ summary: (_c = output.summary) !== null && _c !== void 0 ? _c : null,
253
+ affected_files: (_d = output.affected_files) !== null && _d !== void 0 ? _d : null,
254
+ metadata: (_e = output.metadata) !== null && _e !== void 0 ? _e : null,
255
+ created_at: output.created_at,
256
+ });
257
+ }
258
+ function getSkillOutputs(dbPath, sessionId) {
259
+ const db = openDb(dbPath);
260
+ return db.prepare('SELECT * FROM skill_outputs WHERE session_id = ? ORDER BY id ASC').all(sessionId);
261
+ }
262
+ // ─── DB Path Helper ──────────────────────────────────────────────────────────
263
+ function getDbPath(projectPath) {
264
+ return path_1.default.join(projectPath, '.cm', 'context.db');
265
+ }
@@ -19,6 +19,8 @@ exports.hasCmDir = hasCmDir;
19
19
  const fs_1 = __importDefault(require("fs"));
20
20
  const path_1 = __importDefault(require("path"));
21
21
  const crypto_1 = __importDefault(require("crypto"));
22
+ const l0_indexer_1 = require("./l0-indexer");
23
+ const token_budget_1 = require("./token-budget");
22
24
  // ─── Constants ──────────────────────────────────────────────────────────────
23
25
  const CM_DIR = '.cm';
24
26
  const CONTINUITY_FILE = 'CONTINUITY.md';
@@ -55,6 +57,11 @@ function ensureCmDir(projectPath) {
55
57
  if (!fs_1.default.existsSync(configPath)) {
56
58
  fs_1.default.writeFileSync(configPath, generateDefaultConfig());
57
59
  }
60
+ // Initialize token budget if not present
61
+ const budgetPath = path_1.default.join(cmDir, 'token-budget.json');
62
+ if (!fs_1.default.existsSync(budgetPath)) {
63
+ fs_1.default.writeFileSync(budgetPath, JSON.stringify((0, token_budget_1.getDefaultBudget)(), null, 2));
64
+ }
58
65
  // Add .cm to .gitignore if not already there
59
66
  const gitignorePath = path_1.default.join(projectPath, '.gitignore');
60
67
  if (fs_1.default.existsSync(gitignorePath)) {
@@ -252,6 +259,11 @@ function addLearning(projectPath, learning) {
252
259
  catch ( /* empty */_a) { /* empty */ }
253
260
  learnings.push(fullLearning);
254
261
  fs_1.default.writeFileSync(learningsPath, JSON.stringify(learnings, null, 2));
262
+ // Refresh L0 index after adding a learning
263
+ try {
264
+ (0, l0_indexer_1.generateLearningsIndex)(projectPath);
265
+ }
266
+ catch ( /* non-fatal */_b) { /* non-fatal */ }
255
267
  return fullLearning;
256
268
  }
257
269
  function archiveLearnings(projectPath, learnings) {
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.startWatcher = startWatcher;
7
+ exports.stopWatcher = stopWatcher;
8
+ exports.isWatching = isWatching;
9
+ const chokidar_1 = __importDefault(require("chokidar"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const l0_indexer_1 = require("./l0-indexer");
12
+ // ─── Watcher ─────────────────────────────────────────────────────────────────
13
+ let watcher = null;
14
+ const debounceTimers = new Map();
15
+ function debounce(key, ms, fn) {
16
+ const existing = debounceTimers.get(key);
17
+ if (existing)
18
+ clearTimeout(existing);
19
+ debounceTimers.set(key, setTimeout(() => {
20
+ debounceTimers.delete(key);
21
+ fn();
22
+ }, ms));
23
+ }
24
+ /**
25
+ * Start watching `.cm/memory/learnings.json` and `.cm/memory/decisions.json`.
26
+ * On change, regenerates the L0 learnings index automatically.
27
+ */
28
+ function startWatcher(projectPath, options = {}) {
29
+ if (watcher)
30
+ return watcher;
31
+ const { debounceMs = 300, onRefresh, onError } = options;
32
+ const memoryDir = path_1.default.join(projectPath, '.cm', 'memory');
33
+ const watched = [
34
+ path_1.default.join(memoryDir, 'learnings.json'),
35
+ path_1.default.join(memoryDir, 'decisions.json'),
36
+ ];
37
+ watcher = chokidar_1.default.watch(watched, {
38
+ ignoreInitial: true,
39
+ persistent: false,
40
+ awaitWriteFinish: { stabilityThreshold: 100, pollInterval: 50 },
41
+ });
42
+ watcher.on('change', (filePath) => {
43
+ const basename = path_1.default.basename(filePath);
44
+ debounce(`refresh:${basename}`, debounceMs, () => {
45
+ try {
46
+ if (basename === 'learnings.json') {
47
+ (0, l0_indexer_1.generateLearningsIndex)(projectPath);
48
+ onRefresh === null || onRefresh === void 0 ? void 0 : onRefresh('learnings');
49
+ }
50
+ // decisions don't have an L0 index yet — placeholder for future
51
+ }
52
+ catch (err) {
53
+ onError === null || onError === void 0 ? void 0 : onError(err);
54
+ }
55
+ });
56
+ });
57
+ watcher.on('error', (err) => {
58
+ onError === null || onError === void 0 ? void 0 : onError(err);
59
+ });
60
+ return watcher;
61
+ }
62
+ /**
63
+ * Stop the active watcher and clear pending debounce timers.
64
+ */
65
+ function stopWatcher() {
66
+ for (const timer of debounceTimers.values())
67
+ clearTimeout(timer);
68
+ debounceTimers.clear();
69
+ if (watcher) {
70
+ watcher.close();
71
+ watcher = null;
72
+ }
73
+ }
74
+ /**
75
+ * Returns true if a watcher is currently active.
76
+ */
77
+ function isWatching() {
78
+ return watcher !== null;
79
+ }