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
@@ -0,0 +1,400 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * CodyMaster MCP Context Server
5
+ *
6
+ * Exposes 7 tools over JSON-RPC 2.0 / stdio (Content-Length framing):
7
+ * cm_query — FTS5 search across learnings + decisions
8
+ * cm_resolve — resolve a cm:// URI at L0/L1/L2
9
+ * cm_bus_read — read context bus state
10
+ * cm_bus_write — publish skill output to context bus
11
+ * cm_budget_check — check token budget for a category
12
+ * cm_memory_decay — TTL cleanup for learnings
13
+ * cm_index_refresh — regenerate L0 indexes
14
+ *
15
+ * Usage (stdio MCP):
16
+ * node dist/mcp-context-server.js --project /path/to/project
17
+ *
18
+ * Claude Desktop config:
19
+ * {
20
+ * "mcpServers": {
21
+ * "cm-context": {
22
+ * "command": "node",
23
+ * "args": ["/path/to/dist/mcp-context-server.js", "--project", "/path/to/project"]
24
+ * }
25
+ * }
26
+ * }
27
+ */
28
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
29
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
30
+ return new (P || (P = Promise))(function (resolve, reject) {
31
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
32
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
33
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
34
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
35
+ });
36
+ };
37
+ var __importDefault = (this && this.__importDefault) || function (mod) {
38
+ return (mod && mod.__esModule) ? mod : { "default": mod };
39
+ };
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ const path_1 = __importDefault(require("path"));
42
+ const context_db_1 = require("./context-db");
43
+ const uri_resolver_1 = require("./uri-resolver");
44
+ const context_bus_1 = require("./context-bus");
45
+ const token_budget_1 = require("./token-budget");
46
+ const l0_indexer_1 = require("./l0-indexer");
47
+ // ─── Config ──────────────────────────────────────────────────────────────────
48
+ const SERVER_NAME = 'cm-context';
49
+ const SERVER_VERSION = '1.0.0';
50
+ function getProjectPath() {
51
+ const args = process.argv.slice(2);
52
+ const idx = args.indexOf('--project');
53
+ if (idx !== -1 && args[idx + 1])
54
+ return path_1.default.resolve(args[idx + 1]);
55
+ return process.env.CM_PROJECT_PATH ? path_1.default.resolve(process.env.CM_PROJECT_PATH) : process.cwd();
56
+ }
57
+ const PROJECT_PATH = getProjectPath();
58
+ function cmQuery(args) {
59
+ const { query = '', scope = 'all', filter_scope, limit = 10 } = args;
60
+ const dbPath = (0, context_db_1.getDbPath)(PROJECT_PATH);
61
+ (0, context_db_1.openDb)(dbPath);
62
+ const results = [];
63
+ if (scope === 'all' || scope === 'learnings') {
64
+ const learnings = (0, context_db_1.queryLearnings)(dbPath, query, filter_scope, limit);
65
+ for (const l of learnings) {
66
+ results.push(Object.assign({ type: 'learning' }, l));
67
+ }
68
+ }
69
+ if (scope === 'all' || scope === 'decisions') {
70
+ const decisions = (0, context_db_1.queryDecisions)(dbPath, query, limit);
71
+ for (const d of decisions) {
72
+ results.push(Object.assign({ type: 'decision' }, d));
73
+ }
74
+ }
75
+ return {
76
+ query,
77
+ scope,
78
+ count: results.length,
79
+ results,
80
+ };
81
+ }
82
+ function cmResolve(args) {
83
+ const { uri, depth = 'L1' } = args;
84
+ const resolved = (0, uri_resolver_1.resolve)(uri, PROJECT_PATH, depth);
85
+ return {
86
+ uri: resolved.uri,
87
+ depth: resolved.depth,
88
+ found: resolved.found,
89
+ tokenEstimate: resolved.tokenEstimate,
90
+ content: resolved.content,
91
+ };
92
+ }
93
+ function cmBusRead() {
94
+ const bus = (0, context_bus_1.readBus)(PROJECT_PATH);
95
+ if (!bus) {
96
+ return { active: false, message: 'No active context bus. Start a skill chain first.' };
97
+ }
98
+ return { active: true, bus };
99
+ }
100
+ function cmBusWrite(args) {
101
+ const { skill, summary, affected_files, output_path, metadata } = args;
102
+ if (!skill)
103
+ throw new Error('skill is required');
104
+ (0, context_bus_1.updateBusStep)(PROJECT_PATH, skill, {
105
+ summary: summary !== null && summary !== void 0 ? summary : '',
106
+ output_path: output_path !== null && output_path !== void 0 ? output_path : '',
107
+ affected_files: affected_files !== null && affected_files !== void 0 ? affected_files : [],
108
+ metadata: metadata !== null && metadata !== void 0 ? metadata : {},
109
+ });
110
+ const bus = (0, context_bus_1.readBus)(PROJECT_PATH);
111
+ return {
112
+ ok: true,
113
+ skill,
114
+ current_step: bus === null || bus === void 0 ? void 0 : bus.current_step,
115
+ pipeline: bus === null || bus === void 0 ? void 0 : bus.pipeline,
116
+ };
117
+ }
118
+ function cmBudgetCheck(args) {
119
+ const { category, text, token_count } = args;
120
+ if (!category)
121
+ throw new Error('category is required');
122
+ const budget = (0, token_budget_1.loadBudget)(PROJECT_PATH);
123
+ const tokens = token_count !== null && token_count !== void 0 ? token_count : (text ? (0, token_budget_1.estimateTokens)(text) : 0);
124
+ const check = (0, token_budget_1.checkBudget)(budget, category, tokens);
125
+ return {
126
+ category,
127
+ tokens_requested: tokens,
128
+ allowed: check.allowed,
129
+ remaining: check.remaining,
130
+ suggestion: check.suggestion,
131
+ };
132
+ }
133
+ function cmMemoryDecay(args) {
134
+ const { dry_run = false } = args;
135
+ const dbPath = (0, context_db_1.getDbPath)(PROJECT_PATH);
136
+ const db = (0, context_db_1.openDb)(dbPath);
137
+ const now = new Date();
138
+ // Find learnings past TTL
139
+ const candidates = db.prepare(`
140
+ SELECT id, what_failed, created_at, ttl
141
+ FROM learnings
142
+ WHERE status = 'active'
143
+ AND ttl IS NOT NULL
144
+ AND ttl > 0
145
+ `).all();
146
+ const expired = [];
147
+ for (const row of candidates) {
148
+ const created = new Date(row.created_at);
149
+ const daysSince = (now.getTime() - created.getTime()) / (1000 * 60 * 60 * 24);
150
+ if (daysSince >= row.ttl) {
151
+ expired.push(row.id);
152
+ }
153
+ }
154
+ if (!dry_run && expired.length > 0) {
155
+ const placeholders = expired.map(() => '?').join(',');
156
+ db.prepare(`UPDATE learnings SET status = 'archived' WHERE id IN (${placeholders})`).run(...expired);
157
+ }
158
+ return {
159
+ dry_run,
160
+ expired_count: expired.length,
161
+ expired_ids: expired,
162
+ message: dry_run
163
+ ? `${expired.length} learnings would be archived (dry run)`
164
+ : `${expired.length} learnings archived`,
165
+ };
166
+ }
167
+ function cmIndexRefresh(args) {
168
+ const { target = 'all' } = args;
169
+ if (target === 'all') {
170
+ const result = (0, l0_indexer_1.refreshAllIndexes)(PROJECT_PATH);
171
+ return {
172
+ target,
173
+ learnings: { generated: true, tokens: (0, token_budget_1.estimateTokens)(result.learnings) },
174
+ skeleton: { generated: true, tokens: (0, token_budget_1.estimateTokens)(result.skeleton) },
175
+ };
176
+ }
177
+ if (target === 'learnings') {
178
+ const { generateLearningsIndex } = require('./l0-indexer');
179
+ const content = generateLearningsIndex(PROJECT_PATH);
180
+ return { target, learnings: { generated: true, tokens: (0, token_budget_1.estimateTokens)(content) } };
181
+ }
182
+ if (target === 'skeleton') {
183
+ const { generateSkeletonIndex } = require('./l0-indexer');
184
+ const content = generateSkeletonIndex(PROJECT_PATH);
185
+ return { target, skeleton: { generated: true, tokens: (0, token_budget_1.estimateTokens)(content) } };
186
+ }
187
+ throw new Error(`Unknown target: ${target}. Valid: learnings, skeleton, all`);
188
+ }
189
+ // ─── Tool Registry ─────────────────────────────────────────────────────────────
190
+ const TOOLS = [
191
+ {
192
+ name: 'cm_query',
193
+ description: 'FTS5 semantic search across CodyMaster learnings and decisions stored in SQLite.',
194
+ inputSchema: {
195
+ type: 'object',
196
+ properties: {
197
+ query: { type: 'string', description: 'Search query (FTS5 syntax supported)' },
198
+ scope: {
199
+ type: 'string',
200
+ enum: ['learnings', 'decisions', 'all'],
201
+ description: 'Which collection to search (default: all)',
202
+ },
203
+ filter_scope: {
204
+ type: 'string',
205
+ description: 'Optional scope filter for learnings (e.g. "module", "global")',
206
+ },
207
+ limit: { type: 'number', description: 'Max results per collection (default: 10)' },
208
+ },
209
+ required: ['query'],
210
+ },
211
+ },
212
+ {
213
+ name: 'cm_resolve',
214
+ description: 'Resolve a cm:// URI to content at the specified depth (L0=compact, L1=overview, L2=full).',
215
+ inputSchema: {
216
+ type: 'object',
217
+ properties: {
218
+ uri: {
219
+ type: 'string',
220
+ description: 'cm:// URI (e.g. cm://memory/learnings, cm://skills/cm-tdd, cm://pipeline/current)',
221
+ },
222
+ depth: {
223
+ type: 'string',
224
+ enum: ['L0', 'L1', 'L2'],
225
+ description: 'Loading depth (default: L1)',
226
+ },
227
+ },
228
+ required: ['uri'],
229
+ },
230
+ },
231
+ {
232
+ name: 'cm_bus_read',
233
+ description: 'Read the current context bus state — pipeline name, current step, and shared skill outputs.',
234
+ inputSchema: { type: 'object', properties: {} },
235
+ },
236
+ {
237
+ name: 'cm_bus_write',
238
+ description: 'Publish a skill completion event to the context bus so subsequent skills can read it.',
239
+ inputSchema: {
240
+ type: 'object',
241
+ properties: {
242
+ skill: { type: 'string', description: 'Skill name (e.g. cm-brainstorm-idea)' },
243
+ summary: { type: 'string', description: 'Human-readable outcome summary' },
244
+ affected_files: {
245
+ type: 'array',
246
+ items: { type: 'string' },
247
+ description: 'Files created/modified by this skill',
248
+ },
249
+ output_path: { type: 'string', description: 'Primary output file path' },
250
+ metadata: { type: 'object', description: 'Arbitrary key-value metadata' },
251
+ },
252
+ required: ['skill'],
253
+ },
254
+ },
255
+ {
256
+ name: 'cm_budget_check',
257
+ description: 'Check whether loading content for a given category is within token budget.',
258
+ inputSchema: {
259
+ type: 'object',
260
+ properties: {
261
+ category: {
262
+ type: 'string',
263
+ description: 'Budget category (e.g. skill_index_L0, memory_learnings, context_retrieval)',
264
+ },
265
+ text: { type: 'string', description: 'Text to estimate tokens for (optional)' },
266
+ token_count: { type: 'number', description: 'Pre-computed token count (overrides text)' },
267
+ },
268
+ required: ['category'],
269
+ },
270
+ },
271
+ {
272
+ name: 'cm_memory_decay',
273
+ description: 'Archive learnings whose TTL has expired. Run periodically to keep the memory lean.',
274
+ inputSchema: {
275
+ type: 'object',
276
+ properties: {
277
+ dry_run: {
278
+ type: 'boolean',
279
+ description: 'If true, reports what would be archived without changing data (default: false)',
280
+ },
281
+ },
282
+ },
283
+ },
284
+ {
285
+ name: 'cm_index_refresh',
286
+ description: 'Regenerate L0 compact indexes for learnings and/or skeleton to keep context fresh.',
287
+ inputSchema: {
288
+ type: 'object',
289
+ properties: {
290
+ target: {
291
+ type: 'string',
292
+ enum: ['learnings', 'skeleton', 'all'],
293
+ description: 'Which index to refresh (default: all)',
294
+ },
295
+ },
296
+ },
297
+ },
298
+ ];
299
+ // ─── MCP stdio protocol (JSON-RPC 2.0, Content-Length framing) ───────────────
300
+ function sendMessage(msg) {
301
+ const json = JSON.stringify(msg);
302
+ const header = `Content-Length: ${Buffer.byteLength(json)}\r\n\r\n`;
303
+ process.stdout.write(header + json);
304
+ }
305
+ function respond(id, result) {
306
+ sendMessage({ jsonrpc: '2.0', id, result });
307
+ }
308
+ function respondError(id, code, message) {
309
+ sendMessage({ jsonrpc: '2.0', id, error: { code, message } });
310
+ }
311
+ function handleRequest(msg) {
312
+ return __awaiter(this, void 0, void 0, function* () {
313
+ const { id, method, params } = msg;
314
+ if (method === 'initialize') {
315
+ respond(id, {
316
+ protocolVersion: '2024-11-05',
317
+ capabilities: { tools: {} },
318
+ serverInfo: { name: SERVER_NAME, version: SERVER_VERSION },
319
+ });
320
+ return;
321
+ }
322
+ if (method === 'notifications/initialized')
323
+ return;
324
+ if (method === 'tools/list') {
325
+ respond(id, { tools: TOOLS });
326
+ return;
327
+ }
328
+ if (method === 'tools/call') {
329
+ const { name, arguments: args } = (params || {});
330
+ try {
331
+ let result;
332
+ const a = args || {};
333
+ if (name === 'cm_query')
334
+ result = cmQuery(a);
335
+ else if (name === 'cm_resolve')
336
+ result = cmResolve(a);
337
+ else if (name === 'cm_bus_read')
338
+ result = cmBusRead();
339
+ else if (name === 'cm_bus_write')
340
+ result = cmBusWrite(a);
341
+ else if (name === 'cm_budget_check')
342
+ result = cmBudgetCheck(a);
343
+ else if (name === 'cm_memory_decay')
344
+ result = cmMemoryDecay(a);
345
+ else if (name === 'cm_index_refresh')
346
+ result = cmIndexRefresh(a);
347
+ else
348
+ throw new Error(`Unknown tool: ${name}`);
349
+ respond(id, {
350
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
351
+ });
352
+ }
353
+ catch (err) {
354
+ respond(id, {
355
+ content: [{ type: 'text', text: `Error: ${err.message}` }],
356
+ isError: true,
357
+ });
358
+ }
359
+ return;
360
+ }
361
+ if (id !== undefined) {
362
+ respondError(id, -32601, `Method not found: ${method}`);
363
+ }
364
+ });
365
+ }
366
+ // ─── Stdin reader (Content-Length framed) ────────────────────────────────────
367
+ let buffer = Buffer.alloc(0);
368
+ process.stdin.on('data', (chunk) => __awaiter(void 0, void 0, void 0, function* () {
369
+ buffer = Buffer.concat([buffer, chunk]);
370
+ while (true) {
371
+ const sep = buffer.indexOf('\r\n\r\n');
372
+ if (sep === -1)
373
+ break;
374
+ const header = buffer.slice(0, sep).toString();
375
+ const match = header.match(/Content-Length:\s*(\d+)/i);
376
+ if (!match) {
377
+ buffer = buffer.slice(sep + 4);
378
+ break;
379
+ }
380
+ const contentLength = parseInt(match[1], 10);
381
+ const bodyStart = sep + 4;
382
+ if (buffer.length < bodyStart + contentLength)
383
+ break;
384
+ const body = buffer.slice(bodyStart, bodyStart + contentLength).toString('utf8');
385
+ buffer = buffer.slice(bodyStart + contentLength);
386
+ try {
387
+ const msg = JSON.parse(body);
388
+ yield handleRequest(msg);
389
+ }
390
+ catch (_a) {
391
+ // ignore malformed messages
392
+ }
393
+ }
394
+ }));
395
+ process.stdin.on('end', () => {
396
+ (0, context_db_1.closeDb)((0, context_db_1.getDbPath)(PROJECT_PATH));
397
+ process.exit(0);
398
+ });
399
+ process.on('SIGTERM', () => { (0, context_db_1.closeDb)((0, context_db_1.getDbPath)(PROJECT_PATH)); process.exit(0); });
400
+ process.on('SIGINT', () => { (0, context_db_1.closeDb)((0, context_db_1.getDbPath)(PROJECT_PATH)); process.exit(0); });
@@ -0,0 +1,126 @@
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.migrateJsonToSqlite = migrateJsonToSqlite;
7
+ exports.exportSqliteToJson = exportSqliteToJson;
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const context_db_1 = require("./context-db");
11
+ function migrateJsonToSqlite(projectPath) {
12
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3;
13
+ const cmDir = path_1.default.join(projectPath, '.cm');
14
+ const dbPath = (0, context_db_1.getDbPath)(projectPath);
15
+ (0, context_db_1.openDb)(dbPath);
16
+ const result = {
17
+ learnings: { migrated: 0, skipped: 0 },
18
+ decisions: { migrated: 0, skipped: 0 },
19
+ dbPath,
20
+ backupCreated: false,
21
+ };
22
+ // ── Migrate learnings ─────────────────────────────────────────────────────
23
+ const learningsPath = path_1.default.join(cmDir, 'memory', 'learnings.json');
24
+ if (fs_1.default.existsSync(learningsPath)) {
25
+ // Backup
26
+ const backupPath = learningsPath + '.backup';
27
+ fs_1.default.copyFileSync(learningsPath, backupPath);
28
+ result.backupCreated = true;
29
+ let raw = [];
30
+ try {
31
+ raw = JSON.parse(fs_1.default.readFileSync(learningsPath, 'utf-8'));
32
+ }
33
+ catch ( /* invalid JSON — skip */_4) { /* invalid JSON — skip */ }
34
+ for (const l of raw) {
35
+ try {
36
+ const now = new Date().toISOString();
37
+ const learning = {
38
+ id: (_a = l.id) !== null && _a !== void 0 ? _a : `L-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
39
+ what_failed: (_d = (_c = (_b = l.whatFailed) !== null && _b !== void 0 ? _b : l.what_failed) !== null && _c !== void 0 ? _c : l.error) !== null && _d !== void 0 ? _d : '(unknown)',
40
+ why_failed: (_g = (_f = (_e = l.whyFailed) !== null && _e !== void 0 ? _e : l.why_failed) !== null && _f !== void 0 ? _f : l.cause) !== null && _g !== void 0 ? _g : '',
41
+ how_to_prevent: (_k = (_j = (_h = l.howToPrevent) !== null && _h !== void 0 ? _h : l.how_to_prevent) !== null && _j !== void 0 ? _j : l.prevention) !== null && _k !== void 0 ? _k : '',
42
+ scope: (_l = l.scope) !== null && _l !== void 0 ? _l : 'global',
43
+ ttl: (_m = l.ttl) !== null && _m !== void 0 ? _m : 60,
44
+ reinforce_count: (_p = (_o = l.reinforceCount) !== null && _o !== void 0 ? _o : l.reinforce_count) !== null && _p !== void 0 ? _p : 0,
45
+ status: (_q = l.status) !== null && _q !== void 0 ? _q : 'active',
46
+ created_at: (_s = (_r = l.date) !== null && _r !== void 0 ? _r : l.timestamp) !== null && _s !== void 0 ? _s : now,
47
+ updated_at: (_u = (_t = l.date) !== null && _t !== void 0 ? _t : l.timestamp) !== null && _u !== void 0 ? _u : now,
48
+ agent: l.agent,
49
+ task_id: (_v = l.taskId) !== null && _v !== void 0 ? _v : l.task_id,
50
+ module: l.module,
51
+ };
52
+ (0, context_db_1.insertLearning)(dbPath, learning);
53
+ result.learnings.migrated++;
54
+ }
55
+ catch (_5) {
56
+ result.learnings.skipped++;
57
+ }
58
+ }
59
+ }
60
+ // ── Migrate decisions ─────────────────────────────────────────────────────
61
+ const decisionsPath = path_1.default.join(cmDir, 'memory', 'decisions.json');
62
+ if (fs_1.default.existsSync(decisionsPath)) {
63
+ const backupPath = decisionsPath + '.backup';
64
+ fs_1.default.copyFileSync(decisionsPath, backupPath);
65
+ let raw = [];
66
+ try {
67
+ raw = JSON.parse(fs_1.default.readFileSync(decisionsPath, 'utf-8'));
68
+ }
69
+ catch ( /* invalid JSON — skip */_6) { /* invalid JSON — skip */ }
70
+ for (const d of raw) {
71
+ try {
72
+ const now = new Date().toISOString();
73
+ const decision = {
74
+ id: (_w = d.id) !== null && _w !== void 0 ? _w : `D-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
75
+ decision: (_x = d.decision) !== null && _x !== void 0 ? _x : '(unknown)',
76
+ rationale: (_y = d.rationale) !== null && _y !== void 0 ? _y : '',
77
+ scope: (_z = d.scope) !== null && _z !== void 0 ? _z : 'global',
78
+ status: (_0 = d.status) !== null && _0 !== void 0 ? _0 : 'active',
79
+ superseded_by: (_1 = d.supersededBy) !== null && _1 !== void 0 ? _1 : d.superseded_by,
80
+ created_at: (_3 = (_2 = d.date) !== null && _2 !== void 0 ? _2 : d.timestamp) !== null && _3 !== void 0 ? _3 : now,
81
+ agent: d.agent,
82
+ };
83
+ (0, context_db_1.insertDecision)(dbPath, decision);
84
+ result.decisions.migrated++;
85
+ }
86
+ catch (_7) {
87
+ result.decisions.skipped++;
88
+ }
89
+ }
90
+ }
91
+ return result;
92
+ }
93
+ function exportSqliteToJson(projectPath) {
94
+ const cmDir = path_1.default.join(projectPath, '.cm');
95
+ const memDir = path_1.default.join(cmDir, 'memory');
96
+ const dbPath = (0, context_db_1.getDbPath)(projectPath);
97
+ const db = (0, context_db_1.openDb)(dbPath);
98
+ fs_1.default.mkdirSync(memDir, { recursive: true });
99
+ // Export learnings
100
+ const learnings = db.prepare(`
101
+ SELECT id, what_failed, why_failed, how_to_prevent, scope, ttl,
102
+ reinforce_count as reinforceCount, status, created_at as date,
103
+ agent, task_id as taskId, module
104
+ FROM learnings
105
+ WHERE status != 'archived'
106
+ ORDER BY created_at DESC
107
+ `).all();
108
+ const learningsPath = path_1.default.join(memDir, 'learnings.json');
109
+ fs_1.default.writeFileSync(learningsPath, JSON.stringify(learnings, null, 2), 'utf-8');
110
+ // Export decisions
111
+ const decisions = db.prepare(`
112
+ SELECT id, decision, rationale, scope, status,
113
+ superseded_by as supersededBy, created_at as date, agent
114
+ FROM decisions
115
+ WHERE status != 'archived'
116
+ ORDER BY created_at DESC
117
+ `).all();
118
+ const decisionsPath = path_1.default.join(memDir, 'decisions.json');
119
+ fs_1.default.writeFileSync(decisionsPath, JSON.stringify(decisions, null, 2), 'utf-8');
120
+ return {
121
+ learnings: learnings.length,
122
+ decisions: decisions.length,
123
+ learningsPath,
124
+ decisionsPath,
125
+ };
126
+ }
@@ -16,6 +16,7 @@ exports.formatChainProgressBar = formatChainProgressBar;
16
16
  exports.getCurrentSkill = getCurrentSkill;
17
17
  const crypto_1 = __importDefault(require("crypto"));
18
18
  const builtin_1 = require("./chains/builtin");
19
+ const context_bus_1 = require("./context-bus");
19
20
  // ─── Chain Matching ─────────────────────────────────────────────────────────
20
21
  // TRIZ #10: Preliminary Action — analyze task BEFORE dispatching
21
22
  /**
@@ -59,7 +60,7 @@ function findChain(chainId) {
59
60
  /**
60
61
  * Create a new chain execution from a chain definition.
61
62
  */
62
- function createChainExecution(chain, projectId, taskTitle, agent) {
63
+ function createChainExecution(chain, projectId, taskTitle, agent, projectPath) {
63
64
  const now = new Date().toISOString();
64
65
  const steps = chain.steps.map((step, index) => ({
65
66
  index,
@@ -74,7 +75,7 @@ function createChainExecution(chain, projectId, taskTitle, agent) {
74
75
  steps[0].status = 'running';
75
76
  steps[0].startedAt = now;
76
77
  }
77
- return {
78
+ const execution = {
78
79
  id: crypto_1.default.randomUUID(),
79
80
  chainId: chain.id,
80
81
  chainName: chain.name,
@@ -87,12 +88,20 @@ function createChainExecution(chain, projectId, taskTitle, agent) {
87
88
  startedAt: now,
88
89
  updatedAt: now,
89
90
  };
91
+ // Init context bus for this chain execution
92
+ if (projectPath) {
93
+ try {
94
+ (0, context_bus_1.initBus)(projectPath, chain.id, execution.id);
95
+ }
96
+ catch ( /* non-fatal: context bus is optional enhancement */_a) { /* non-fatal: context bus is optional enhancement */ }
97
+ }
98
+ return execution;
90
99
  }
91
100
  /**
92
101
  * Advance the chain to the next step. Marks current step as completed.
93
102
  * Returns the next step's skill name, or null if chain is complete.
94
103
  */
95
- function advanceChain(execution, output) {
104
+ function advanceChain(execution, output, projectPath) {
96
105
  const now = new Date().toISOString();
97
106
  const currentStep = execution.steps[execution.currentStepIndex];
98
107
  if (!currentStep) {
@@ -104,6 +113,13 @@ function advanceChain(execution, output) {
104
113
  if (output)
105
114
  currentStep.output = output;
106
115
  execution.updatedAt = now;
116
+ // Update context bus with completed step's output
117
+ if (projectPath) {
118
+ try {
119
+ (0, context_bus_1.updateBusStep)(projectPath, currentStep.skill, { summary: output });
120
+ }
121
+ catch ( /* non-fatal */_a) { /* non-fatal */ }
122
+ }
107
123
  // Find next non-skipped step
108
124
  let nextIndex = execution.currentStepIndex + 1;
109
125
  while (nextIndex < execution.steps.length) {