mulch-cli 0.4.3 → 0.6.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 (193) hide show
  1. package/README.md +24 -4
  2. package/package.json +11 -16
  3. package/src/api.ts +310 -0
  4. package/src/cli.ts +54 -0
  5. package/src/commands/add.ts +61 -0
  6. package/src/commands/compact.ts +924 -0
  7. package/src/commands/delete.ts +103 -0
  8. package/src/commands/diff.ts +209 -0
  9. package/src/commands/doctor.ts +586 -0
  10. package/src/commands/edit.ts +253 -0
  11. package/src/commands/init.ts +33 -0
  12. package/src/commands/learn.ts +170 -0
  13. package/src/commands/onboard.ts +362 -0
  14. package/src/commands/prime.ts +327 -0
  15. package/src/commands/prune.ts +128 -0
  16. package/src/commands/query.ts +177 -0
  17. package/src/commands/ready.ts +194 -0
  18. package/src/commands/record.ts +959 -0
  19. package/src/commands/search.ts +234 -0
  20. package/src/commands/setup.ts +823 -0
  21. package/src/commands/status.ts +83 -0
  22. package/src/commands/sync.ts +224 -0
  23. package/src/commands/update.ts +112 -0
  24. package/src/commands/validate.ts +107 -0
  25. package/src/index.ts +50 -0
  26. package/src/schemas/config.ts +31 -0
  27. package/src/schemas/index.ts +18 -0
  28. package/src/schemas/record-schema.ts +177 -0
  29. package/src/schemas/record.ts +83 -0
  30. package/src/utils/bm25.ts +243 -0
  31. package/src/utils/budget.ts +157 -0
  32. package/src/utils/config.ts +117 -0
  33. package/src/utils/expertise.ts +379 -0
  34. package/src/utils/format.ts +767 -0
  35. package/src/utils/git.ts +89 -0
  36. package/src/utils/index.ts +54 -0
  37. package/src/utils/json-output.ts +13 -0
  38. package/src/utils/lock.ts +82 -0
  39. package/src/utils/markers.ts +51 -0
  40. package/src/utils/scoring.ts +101 -0
  41. package/src/utils/version.ts +46 -0
  42. package/dist/cli.d.ts +0 -3
  43. package/dist/cli.d.ts.map +0 -1
  44. package/dist/cli.js +0 -50
  45. package/dist/cli.js.map +0 -1
  46. package/dist/commands/add.d.ts +0 -3
  47. package/dist/commands/add.d.ts.map +0 -1
  48. package/dist/commands/add.js +0 -47
  49. package/dist/commands/add.js.map +0 -1
  50. package/dist/commands/compact.d.ts +0 -5
  51. package/dist/commands/compact.d.ts.map +0 -1
  52. package/dist/commands/compact.js +0 -709
  53. package/dist/commands/compact.js.map +0 -1
  54. package/dist/commands/delete.d.ts +0 -3
  55. package/dist/commands/delete.d.ts.map +0 -1
  56. package/dist/commands/delete.js +0 -82
  57. package/dist/commands/delete.js.map +0 -1
  58. package/dist/commands/diff.d.ts +0 -11
  59. package/dist/commands/diff.d.ts.map +0 -1
  60. package/dist/commands/diff.js +0 -170
  61. package/dist/commands/diff.js.map +0 -1
  62. package/dist/commands/doctor.d.ts +0 -3
  63. package/dist/commands/doctor.d.ts.map +0 -1
  64. package/dist/commands/doctor.js +0 -391
  65. package/dist/commands/doctor.js.map +0 -1
  66. package/dist/commands/edit.d.ts +0 -3
  67. package/dist/commands/edit.d.ts.map +0 -1
  68. package/dist/commands/edit.js +0 -210
  69. package/dist/commands/edit.js.map +0 -1
  70. package/dist/commands/init.d.ts +0 -3
  71. package/dist/commands/init.d.ts.map +0 -1
  72. package/dist/commands/init.js +0 -30
  73. package/dist/commands/init.js.map +0 -1
  74. package/dist/commands/learn.d.ts +0 -12
  75. package/dist/commands/learn.d.ts.map +0 -1
  76. package/dist/commands/learn.js +0 -130
  77. package/dist/commands/learn.js.map +0 -1
  78. package/dist/commands/onboard.d.ts +0 -10
  79. package/dist/commands/onboard.d.ts.map +0 -1
  80. package/dist/commands/onboard.js +0 -286
  81. package/dist/commands/onboard.js.map +0 -1
  82. package/dist/commands/prime.d.ts +0 -3
  83. package/dist/commands/prime.d.ts.map +0 -1
  84. package/dist/commands/prime.js +0 -242
  85. package/dist/commands/prime.js.map +0 -1
  86. package/dist/commands/prune.d.ts +0 -8
  87. package/dist/commands/prune.d.ts.map +0 -1
  88. package/dist/commands/prune.js +0 -90
  89. package/dist/commands/prune.js.map +0 -1
  90. package/dist/commands/query.d.ts +0 -3
  91. package/dist/commands/query.d.ts.map +0 -1
  92. package/dist/commands/query.js +0 -118
  93. package/dist/commands/query.js.map +0 -1
  94. package/dist/commands/ready.d.ts +0 -3
  95. package/dist/commands/ready.d.ts.map +0 -1
  96. package/dist/commands/ready.js +0 -160
  97. package/dist/commands/ready.js.map +0 -1
  98. package/dist/commands/record.d.ts +0 -13
  99. package/dist/commands/record.d.ts.map +0 -1
  100. package/dist/commands/record.js +0 -688
  101. package/dist/commands/record.js.map +0 -1
  102. package/dist/commands/search.d.ts +0 -3
  103. package/dist/commands/search.d.ts.map +0 -1
  104. package/dist/commands/search.js +0 -163
  105. package/dist/commands/search.js.map +0 -1
  106. package/dist/commands/setup.d.ts +0 -29
  107. package/dist/commands/setup.d.ts.map +0 -1
  108. package/dist/commands/setup.js +0 -548
  109. package/dist/commands/setup.js.map +0 -1
  110. package/dist/commands/status.d.ts +0 -3
  111. package/dist/commands/status.d.ts.map +0 -1
  112. package/dist/commands/status.js +0 -61
  113. package/dist/commands/status.js.map +0 -1
  114. package/dist/commands/sync.d.ts +0 -3
  115. package/dist/commands/sync.d.ts.map +0 -1
  116. package/dist/commands/sync.js +0 -176
  117. package/dist/commands/sync.js.map +0 -1
  118. package/dist/commands/update.d.ts +0 -3
  119. package/dist/commands/update.d.ts.map +0 -1
  120. package/dist/commands/update.js +0 -72
  121. package/dist/commands/update.js.map +0 -1
  122. package/dist/commands/validate.d.ts +0 -3
  123. package/dist/commands/validate.d.ts.map +0 -1
  124. package/dist/commands/validate.js +0 -86
  125. package/dist/commands/validate.js.map +0 -1
  126. package/dist/index.d.ts +0 -7
  127. package/dist/index.d.ts.map +0 -1
  128. package/dist/index.js +0 -8
  129. package/dist/index.js.map +0 -1
  130. package/dist/schemas/config.d.ts +0 -17
  131. package/dist/schemas/config.d.ts.map +0 -1
  132. package/dist/schemas/config.js +0 -16
  133. package/dist/schemas/config.js.map +0 -1
  134. package/dist/schemas/index.d.ts +0 -5
  135. package/dist/schemas/index.d.ts.map +0 -1
  136. package/dist/schemas/index.js +0 -3
  137. package/dist/schemas/index.js.map +0 -1
  138. package/dist/schemas/record-schema.d.ts +0 -379
  139. package/dist/schemas/record-schema.d.ts.map +0 -1
  140. package/dist/schemas/record-schema.js +0 -148
  141. package/dist/schemas/record-schema.js.map +0 -1
  142. package/dist/schemas/record.d.ts +0 -60
  143. package/dist/schemas/record.d.ts.map +0 -1
  144. package/dist/schemas/record.js +0 -2
  145. package/dist/schemas/record.js.map +0 -1
  146. package/dist/utils/bm25.d.ts +0 -39
  147. package/dist/utils/bm25.d.ts.map +0 -1
  148. package/dist/utils/bm25.js +0 -171
  149. package/dist/utils/bm25.js.map +0 -1
  150. package/dist/utils/budget.d.ts +0 -35
  151. package/dist/utils/budget.d.ts.map +0 -1
  152. package/dist/utils/budget.js +0 -114
  153. package/dist/utils/budget.js.map +0 -1
  154. package/dist/utils/config.d.ts +0 -12
  155. package/dist/utils/config.d.ts.map +0 -1
  156. package/dist/utils/config.js +0 -89
  157. package/dist/utils/config.js.map +0 -1
  158. package/dist/utils/expertise.d.ts +0 -57
  159. package/dist/utils/expertise.d.ts.map +0 -1
  160. package/dist/utils/expertise.js +0 -264
  161. package/dist/utils/expertise.js.map +0 -1
  162. package/dist/utils/format.d.ts +0 -31
  163. package/dist/utils/format.d.ts.map +0 -1
  164. package/dist/utils/format.js +0 -556
  165. package/dist/utils/format.js.map +0 -1
  166. package/dist/utils/git.d.ts +0 -6
  167. package/dist/utils/git.d.ts.map +0 -1
  168. package/dist/utils/git.js +0 -81
  169. package/dist/utils/git.js.map +0 -1
  170. package/dist/utils/index.d.ts +0 -8
  171. package/dist/utils/index.d.ts.map +0 -1
  172. package/dist/utils/index.js +0 -8
  173. package/dist/utils/index.js.map +0 -1
  174. package/dist/utils/json-output.d.ts +0 -8
  175. package/dist/utils/json-output.d.ts.map +0 -1
  176. package/dist/utils/json-output.js +0 -7
  177. package/dist/utils/json-output.js.map +0 -1
  178. package/dist/utils/lock.d.ts +0 -6
  179. package/dist/utils/lock.d.ts.map +0 -1
  180. package/dist/utils/lock.js +0 -70
  181. package/dist/utils/lock.js.map +0 -1
  182. package/dist/utils/markers.d.ts +0 -22
  183. package/dist/utils/markers.d.ts.map +0 -1
  184. package/dist/utils/markers.js +0 -42
  185. package/dist/utils/markers.js.map +0 -1
  186. package/dist/utils/scoring.d.ts +0 -73
  187. package/dist/utils/scoring.d.ts.map +0 -1
  188. package/dist/utils/scoring.js +0 -80
  189. package/dist/utils/scoring.js.map +0 -1
  190. package/dist/utils/version.d.ts +0 -15
  191. package/dist/utils/version.d.ts.map +0 -1
  192. package/dist/utils/version.js +0 -48
  193. package/dist/utils/version.js.map +0 -1
@@ -1,171 +0,0 @@
1
- /**
2
- * Default BM25 parameters optimized for expertise records
3
- */
4
- export const DEFAULT_BM25_PARAMS = {
5
- k1: 1.5,
6
- b: 0.75,
7
- };
8
- /**
9
- * Tokenize text into searchable terms
10
- */
11
- export function tokenize(text) {
12
- return text
13
- .toLowerCase()
14
- .replace(/[^\w\s-]/g, " ") // Replace punctuation with spaces (keep hyphens in words)
15
- .split(/\s+/)
16
- .filter((token) => token.length > 0);
17
- }
18
- /**
19
- * Extract searchable text from a record
20
- */
21
- export function extractRecordText(record) {
22
- const fieldTexts = {};
23
- const allParts = [];
24
- // Helper to add field text
25
- const addField = (name, value) => {
26
- if (typeof value === "string" && value.trim().length > 0) {
27
- fieldTexts[name] = value;
28
- allParts.push(value);
29
- }
30
- else if (Array.isArray(value)) {
31
- const arrayText = value
32
- .filter((item) => typeof item === "string")
33
- .join(" ");
34
- if (arrayText.trim().length > 0) {
35
- fieldTexts[name] = arrayText;
36
- allParts.push(arrayText);
37
- }
38
- }
39
- };
40
- // Extract type-specific fields
41
- switch (record.type) {
42
- case "pattern":
43
- addField("name", record.name);
44
- addField("description", record.description);
45
- addField("files", record.files);
46
- break;
47
- case "convention":
48
- addField("content", record.content);
49
- break;
50
- case "failure":
51
- addField("description", record.description);
52
- addField("resolution", record.resolution);
53
- break;
54
- case "decision":
55
- addField("title", record.title);
56
- addField("rationale", record.rationale);
57
- break;
58
- case "reference":
59
- addField("name", record.name);
60
- addField("description", record.description);
61
- addField("files", record.files);
62
- break;
63
- case "guide":
64
- addField("name", record.name);
65
- addField("description", record.description);
66
- break;
67
- }
68
- // Add common fields
69
- addField("tags", record.tags);
70
- return {
71
- allText: allParts.join(" "),
72
- fieldTexts,
73
- };
74
- }
75
- /**
76
- * Calculate term frequency in a document
77
- */
78
- function calculateTermFrequency(tokens) {
79
- const tf = new Map();
80
- for (const token of tokens) {
81
- tf.set(token, (tf.get(token) || 0) + 1);
82
- }
83
- return tf;
84
- }
85
- /**
86
- * Calculate inverse document frequency for all terms in the corpus
87
- */
88
- function calculateIDF(corpus) {
89
- const docCount = corpus.length;
90
- const docFreq = new Map();
91
- // Count how many documents contain each term
92
- for (const doc of corpus) {
93
- const uniqueTerms = new Set(doc.tokens);
94
- for (const term of uniqueTerms) {
95
- docFreq.set(term, (docFreq.get(term) || 0) + 1);
96
- }
97
- }
98
- // Calculate IDF for each term
99
- const idf = new Map();
100
- for (const [term, freq] of docFreq.entries()) {
101
- // IDF formula: log((N - df + 0.5) / (df + 0.5) + 1)
102
- // The +1 ensures positive values for common terms
103
- idf.set(term, Math.log((docCount - freq + 0.5) / (freq + 0.5) + 1));
104
- }
105
- return idf;
106
- }
107
- /**
108
- * Calculate BM25 score for a single document against a query
109
- */
110
- function calculateBM25Score(queryTokens, docTokens, docLength, avgDocLength, idf, params) {
111
- const tf = calculateTermFrequency(docTokens);
112
- let score = 0;
113
- for (const queryTerm of queryTokens) {
114
- const termFreq = tf.get(queryTerm) || 0;
115
- const termIDF = idf.get(queryTerm) || 0;
116
- // BM25 formula
117
- const numerator = termFreq * (params.k1 + 1);
118
- const denominator = termFreq + params.k1 * (1 - params.b + params.b * (docLength / avgDocLength));
119
- score += termIDF * (numerator / denominator);
120
- }
121
- return score;
122
- }
123
- /**
124
- * Search records using BM25 ranking
125
- */
126
- export function searchBM25(records, query, params = DEFAULT_BM25_PARAMS) {
127
- if (records.length === 0 || query.trim().length === 0) {
128
- return [];
129
- }
130
- const queryTokens = tokenize(query);
131
- if (queryTokens.length === 0) {
132
- return [];
133
- }
134
- // Extract and tokenize all documents
135
- const docs = records.map((record) => {
136
- const { allText, fieldTexts } = extractRecordText(record);
137
- const tokens = tokenize(allText);
138
- return { record, tokens, allText, fieldTexts };
139
- });
140
- // Calculate average document length
141
- const totalLength = docs.reduce((sum, doc) => sum + doc.tokens.length, 0);
142
- const avgDocLength = totalLength / docs.length;
143
- // Calculate IDF for all terms
144
- const idf = calculateIDF(docs);
145
- // Score each document
146
- const results = [];
147
- for (const doc of docs) {
148
- const score = calculateBM25Score(queryTokens, doc.tokens, doc.tokens.length, avgDocLength, idf, params);
149
- // Only include results with score > 0
150
- if (score > 0) {
151
- // Determine which fields matched
152
- const matchedFields = [];
153
- for (const [fieldName, fieldText] of Object.entries(doc.fieldTexts)) {
154
- const fieldTokens = tokenize(fieldText);
155
- const hasMatch = queryTokens.some((qt) => fieldTokens.includes(qt));
156
- if (hasMatch) {
157
- matchedFields.push(fieldName);
158
- }
159
- }
160
- results.push({
161
- record: doc.record,
162
- score,
163
- matchedFields,
164
- });
165
- }
166
- }
167
- // Sort by score descending
168
- results.sort((a, b) => b.score - a.score);
169
- return results;
170
- }
171
- //# sourceMappingURL=bm25.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bm25.js","sourceRoot":"","sources":["../../src/utils/bm25.ts"],"names":[],"mappings":"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"}
@@ -1,35 +0,0 @@
1
- import type { ExpertiseRecord } from "../schemas/record.js";
2
- import { type ScoredRecord } from "./scoring.js";
3
- export declare const DEFAULT_BUDGET = 4000;
4
- export interface DomainRecords {
5
- domain: string;
6
- records: ScoredRecord[];
7
- }
8
- export interface BudgetResult {
9
- /** Records kept, grouped by domain (preserves original domain order) */
10
- kept: DomainRecords[];
11
- /** Total number of records that were dropped */
12
- droppedCount: number;
13
- /** Number of domains that had records dropped */
14
- droppedDomainCount: number;
15
- }
16
- /**
17
- * Estimate token count from character count (chars / 4).
18
- */
19
- export declare function estimateTokens(text: string): number;
20
- /**
21
- * Apply a token budget to records across multiple domains.
22
- *
23
- * Records are prioritized by type (conventions first, then decisions, etc.),
24
- * then by classification (foundational > tactical > observational),
25
- * then by confirmation score (higher = higher priority),
26
- * then by recency (newest first).
27
- *
28
- * The formatRecord callback is used to estimate per-record token cost.
29
- */
30
- export declare function applyBudget(domains: DomainRecords[], budget: number, formatRecord: (record: ExpertiseRecord, domain: string) => string): BudgetResult;
31
- /**
32
- * Format the truncation summary line shown when records are dropped.
33
- */
34
- export declare function formatBudgetSummary(droppedCount: number, droppedDomainCount: number): string;
35
- //# sourceMappingURL=budget.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../src/utils/budget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAA8B,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,KAAK,YAAY,EAA4B,MAAM,cAAc,CAAC;AAE3E,eAAO,MAAM,cAAc,OAAO,CAAC;AAmBnC,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,wEAAwE;IACxE,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,gDAAgD;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAuBD;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,aAAa,EAAE,EACxB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,GAChE,YAAY,CA0Dd;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,GAAG,MAAM,CAK5F"}
@@ -1,114 +0,0 @@
1
- import { computeConfirmationScore } from "./scoring.js";
2
- export const DEFAULT_BUDGET = 4000;
3
- /** Priority order for record types (lower index = higher priority) */
4
- const TYPE_PRIORITY = [
5
- "convention",
6
- "decision",
7
- "pattern",
8
- "guide",
9
- "failure",
10
- "reference",
11
- ];
12
- /** Priority order for classifications (lower index = higher priority) */
13
- const CLASSIFICATION_PRIORITY = [
14
- "foundational",
15
- "tactical",
16
- "observational",
17
- ];
18
- /**
19
- * Sort records by priority: type order, then classification, then confirmation score
20
- * (higher score = higher priority), then recency (newest first).
21
- */
22
- function recordSortKey(r) {
23
- const typeIdx = TYPE_PRIORITY.indexOf(r.type);
24
- const classIdx = CLASSIFICATION_PRIORITY.indexOf(r.classification);
25
- const confirmationScore = computeConfirmationScore(r);
26
- const time = r.recorded_at ? new Date(r.recorded_at).getTime() : 0;
27
- return [typeIdx, classIdx, -confirmationScore, -time];
28
- }
29
- function compareRecords(a, b) {
30
- const ka = recordSortKey(a);
31
- const kb = recordSortKey(b);
32
- for (let i = 0; i < 4; i++) {
33
- if (ka[i] !== kb[i])
34
- return ka[i] - kb[i];
35
- }
36
- return 0;
37
- }
38
- /**
39
- * Estimate token count from character count (chars / 4).
40
- */
41
- export function estimateTokens(text) {
42
- return Math.ceil(text.length / 4);
43
- }
44
- /**
45
- * Apply a token budget to records across multiple domains.
46
- *
47
- * Records are prioritized by type (conventions first, then decisions, etc.),
48
- * then by classification (foundational > tactical > observational),
49
- * then by confirmation score (higher = higher priority),
50
- * then by recency (newest first).
51
- *
52
- * The formatRecord callback is used to estimate per-record token cost.
53
- */
54
- export function applyBudget(domains, budget, formatRecord) {
55
- // Flatten all records with their domain, then sort by priority
56
- const tagged = [];
57
- for (const d of domains) {
58
- for (const r of d.records) {
59
- tagged.push({ domain: d.domain, record: r });
60
- }
61
- }
62
- tagged.sort((a, b) => compareRecords(a.record, b.record));
63
- const totalRecords = tagged.length;
64
- let usedTokens = 0;
65
- const kept = new Set();
66
- for (let i = 0; i < tagged.length; i++) {
67
- const formatted = formatRecord(tagged[i].record, tagged[i].domain);
68
- const cost = estimateTokens(formatted);
69
- if (usedTokens + cost <= budget) {
70
- usedTokens += cost;
71
- kept.add(i);
72
- }
73
- }
74
- // Rebuild domain groups preserving original domain order and record order
75
- const domainOrder = domains.map((d) => d.domain);
76
- const result = [];
77
- const droppedDomains = new Set();
78
- for (const domainName of domainOrder) {
79
- const originalRecords = domains.find((d) => d.domain === domainName).records;
80
- const keptRecords = [];
81
- for (const rec of originalRecords) {
82
- // Find this record's index in the tagged array
83
- const idx = tagged.findIndex((t) => t.domain === domainName && t.record === rec);
84
- if (idx !== -1 && kept.has(idx)) {
85
- keptRecords.push(rec);
86
- }
87
- else if (idx !== -1) {
88
- droppedDomains.add(domainName);
89
- }
90
- }
91
- if (keptRecords.length > 0) {
92
- result.push({ domain: domainName, records: keptRecords });
93
- }
94
- else if (originalRecords.length > 0) {
95
- droppedDomains.add(domainName);
96
- }
97
- }
98
- const droppedCount = totalRecords - kept.size;
99
- return {
100
- kept: result,
101
- droppedCount,
102
- droppedDomainCount: droppedDomains.size,
103
- };
104
- }
105
- /**
106
- * Format the truncation summary line shown when records are dropped.
107
- */
108
- export function formatBudgetSummary(droppedCount, droppedDomainCount) {
109
- const domainPart = droppedDomainCount > 0
110
- ? ` across ${droppedDomainCount} domain${droppedDomainCount === 1 ? "" : "s"}`
111
- : "";
112
- return `... and ${droppedCount} more record${droppedCount === 1 ? "" : "s"}${domainPart} (use --budget <n> to show more)`;
113
- }
114
- //# sourceMappingURL=budget.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/utils/budget.ts"],"names":[],"mappings":"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"}
@@ -1,12 +0,0 @@
1
- import type { MulchConfig } from "../schemas/config.js";
2
- export declare const GITATTRIBUTES_LINE = ".mulch/expertise/*.jsonl merge=union";
3
- export declare const MULCH_README = "# .mulch/\n\nThis directory is managed by [mulch](https://github.com/jayminwest/mulch) \u2014 a structured expertise layer for coding agents.\n\n## Key Commands\n\n- `mulch init` \u2014 Initialize a .mulch directory\n- `mulch add` \u2014 Add a new domain\n- `mulch record` \u2014 Record an expertise record\n- `mulch edit` \u2014 Edit an existing record\n- `mulch query` \u2014 Query expertise records\n- `mulch prime [domain]` \u2014 Output a priming prompt (optionally scoped to one domain)\n- `mulch search` \u2014 Search records across domains\n- `mulch status` \u2014 Show domain statistics\n- `mulch validate` \u2014 Validate all records against the schema\n- `mulch prune` \u2014 Remove expired records\n\n## Structure\n\n- `mulch.config.yaml` \u2014 Configuration file\n- `expertise/` \u2014 JSONL files, one per domain\n";
4
- export declare function getMulchDir(cwd?: string): string;
5
- export declare function getConfigPath(cwd?: string): string;
6
- export declare function getExpertiseDir(cwd?: string): string;
7
- export declare function validateDomainName(domain: string): void;
8
- export declare function getExpertisePath(domain: string, cwd?: string): string;
9
- export declare function readConfig(cwd?: string): Promise<MulchConfig>;
10
- export declare function writeConfig(config: MulchConfig, cwd?: string): Promise<void>;
11
- export declare function initMulchDir(cwd?: string): Promise<void>;
12
- //# sourceMappingURL=config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAOxD,eAAO,MAAM,kBAAkB,yCACS,CAAC;AAEzC,eAAO,MAAM,YAAY,02BAqBxB,CAAC;AAEF,wBAAgB,WAAW,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAE/D;AAED,wBAAgB,aAAa,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAEjE;AAED,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAEnE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAMvD;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,GAAG,GAAE,MAAsB,GAC1B,MAAM,CAGR;AAED,wBAAsB,UAAU,CAC9B,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,WAAW,CAAC,CAItB;AAED,wBAAsB,WAAW,CAC/B,MAAM,EAAE,WAAW,EACnB,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,wBAAsB,YAAY,CAChC,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAkCf"}
@@ -1,89 +0,0 @@
1
- import { readFile, writeFile, mkdir } from "node:fs/promises";
2
- import { existsSync } from "node:fs";
3
- import { join } from "node:path";
4
- import yaml from "js-yaml";
5
- import { DEFAULT_CONFIG } from "../schemas/config.js";
6
- const MULCH_DIR = ".mulch";
7
- const CONFIG_FILE = "mulch.config.yaml";
8
- const EXPERTISE_DIR = "expertise";
9
- export const GITATTRIBUTES_LINE = ".mulch/expertise/*.jsonl merge=union";
10
- export const MULCH_README = `# .mulch/
11
-
12
- This directory is managed by [mulch](https://github.com/jayminwest/mulch) — a structured expertise layer for coding agents.
13
-
14
- ## Key Commands
15
-
16
- - \`mulch init\` — Initialize a .mulch directory
17
- - \`mulch add\` — Add a new domain
18
- - \`mulch record\` — Record an expertise record
19
- - \`mulch edit\` — Edit an existing record
20
- - \`mulch query\` — Query expertise records
21
- - \`mulch prime [domain]\` — Output a priming prompt (optionally scoped to one domain)
22
- - \`mulch search\` — Search records across domains
23
- - \`mulch status\` — Show domain statistics
24
- - \`mulch validate\` — Validate all records against the schema
25
- - \`mulch prune\` — Remove expired records
26
-
27
- ## Structure
28
-
29
- - \`mulch.config.yaml\` — Configuration file
30
- - \`expertise/\` — JSONL files, one per domain
31
- `;
32
- export function getMulchDir(cwd = process.cwd()) {
33
- return join(cwd, MULCH_DIR);
34
- }
35
- export function getConfigPath(cwd = process.cwd()) {
36
- return join(getMulchDir(cwd), CONFIG_FILE);
37
- }
38
- export function getExpertiseDir(cwd = process.cwd()) {
39
- return join(getMulchDir(cwd), EXPERTISE_DIR);
40
- }
41
- export function validateDomainName(domain) {
42
- if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(domain)) {
43
- throw new Error(`Invalid domain name: "${domain}". Only alphanumeric characters, hyphens, and underscores are allowed.`);
44
- }
45
- }
46
- export function getExpertisePath(domain, cwd = process.cwd()) {
47
- validateDomainName(domain);
48
- return join(getExpertiseDir(cwd), `${domain}.jsonl`);
49
- }
50
- export async function readConfig(cwd = process.cwd()) {
51
- const configPath = getConfigPath(cwd);
52
- const content = await readFile(configPath, "utf-8");
53
- return yaml.load(content);
54
- }
55
- export async function writeConfig(config, cwd = process.cwd()) {
56
- const configPath = getConfigPath(cwd);
57
- const content = yaml.dump(config, { lineWidth: -1 });
58
- await writeFile(configPath, content, "utf-8");
59
- }
60
- export async function initMulchDir(cwd = process.cwd()) {
61
- const mulchDir = getMulchDir(cwd);
62
- const expertiseDir = getExpertiseDir(cwd);
63
- await mkdir(mulchDir, { recursive: true });
64
- await mkdir(expertiseDir, { recursive: true });
65
- // Only write default config if none exists — preserve user customizations
66
- const configPath = getConfigPath(cwd);
67
- if (!existsSync(configPath)) {
68
- await writeConfig({ ...DEFAULT_CONFIG }, cwd);
69
- }
70
- // Create or append .gitattributes with merge=union for JSONL files
71
- const gitattributesPath = join(cwd, ".gitattributes");
72
- let existing = "";
73
- try {
74
- existing = await readFile(gitattributesPath, "utf-8");
75
- }
76
- catch {
77
- // File doesn't exist yet — will create it
78
- }
79
- if (!existing.includes(GITATTRIBUTES_LINE)) {
80
- const separator = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
81
- await writeFile(gitattributesPath, existing + separator + GITATTRIBUTES_LINE + "\n", "utf-8");
82
- }
83
- // Create .mulch/README.md if missing
84
- const readmePath = join(mulchDir, "README.md");
85
- if (!existsSync(readmePath)) {
86
- await writeFile(readmePath, MULCH_README, "utf-8");
87
- }
88
- }
89
- //# sourceMappingURL=config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
@@ -1,57 +0,0 @@
1
- import type { ExpertiseRecord, RecordType, Classification } from "../schemas/record.js";
2
- export declare function readExpertiseFile(filePath: string): Promise<ExpertiseRecord[]>;
3
- export declare function generateRecordId(record: ExpertiseRecord): string;
4
- export declare function appendRecord(filePath: string, record: ExpertiseRecord): Promise<void>;
5
- export declare function createExpertiseFile(filePath: string): Promise<void>;
6
- export declare function getFileModTime(filePath: string): Promise<Date | null>;
7
- export declare function writeExpertiseFile(filePath: string, records: ExpertiseRecord[]): Promise<void>;
8
- export declare function countRecords(records: ExpertiseRecord[]): number;
9
- export declare function filterByType(records: ExpertiseRecord[], type: string): ExpertiseRecord[];
10
- export declare function filterByClassification(records: ExpertiseRecord[], classification: string): ExpertiseRecord[];
11
- export declare function filterByFile(records: ExpertiseRecord[], file: string): ExpertiseRecord[];
12
- export declare function findDuplicate(existing: ExpertiseRecord[], newRecord: ExpertiseRecord): {
13
- index: number;
14
- record: ExpertiseRecord;
15
- } | null;
16
- export type ResolveResult = {
17
- ok: true;
18
- index: number;
19
- record: ExpertiseRecord;
20
- } | {
21
- ok: false;
22
- error: string;
23
- };
24
- /**
25
- * Resolve an identifier to a record within a domain.
26
- * Accepts: full ID (mx-abc123), bare hash (abc123), or prefix (abc / mx-abc).
27
- * Returns the unique matching record or an error if not found / ambiguous.
28
- */
29
- export declare function resolveRecordId(records: ExpertiseRecord[], identifier: string): ResolveResult;
30
- /**
31
- * Search records using BM25 ranking algorithm.
32
- * Returns records sorted by relevance (highest score first).
33
- */
34
- export declare function searchRecords(records: ExpertiseRecord[], query: string): ExpertiseRecord[];
35
- export interface DomainHealth {
36
- governance_utilization: number;
37
- stale_count: number;
38
- type_distribution: Record<RecordType, number>;
39
- classification_distribution: Record<Classification, number>;
40
- oldest_timestamp: string | null;
41
- newest_timestamp: string | null;
42
- }
43
- /**
44
- * Check if a record is stale based on classification and shelf life.
45
- */
46
- export declare function isRecordStale(record: ExpertiseRecord, now: Date, shelfLife: {
47
- tactical: number;
48
- observational: number;
49
- }): boolean;
50
- /**
51
- * Calculate comprehensive health metrics for a domain.
52
- */
53
- export declare function calculateDomainHealth(records: ExpertiseRecord[], maxEntries: number, shelfLife: {
54
- tactical: number;
55
- observational: number;
56
- }): DomainHealth;
57
- //# sourceMappingURL=expertise.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"expertise.d.ts","sourceRoot":"","sources":["../../src/utils/expertise.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGxF,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,EAAE,CAAC,CAc5B;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAuBhE;AAED,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,IAAI,CAAC,CAMf;AAED,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzE;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAO3E;AAED,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,eAAe,EAAE,GACzB,OAAO,CAAC,IAAI,CAAC,CAef;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAE/D;AAED,wBAAgB,YAAY,CAC1B,OAAO,EAAE,eAAe,EAAE,EAC1B,IAAI,EAAE,MAAM,GACX,eAAe,EAAE,CAEnB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,eAAe,EAAE,EAC1B,cAAc,EAAE,MAAM,GACrB,eAAe,EAAE,CAEnB;AAED,wBAAgB,YAAY,CAC1B,OAAO,EAAE,eAAe,EAAE,EAC1B,IAAI,EAAE,MAAM,GACX,eAAe,EAAE,CAQnB;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,eAAe,EAAE,EAC3B,SAAS,EAAE,eAAe,GACzB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GAAG,IAAI,CAyDnD;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GACpD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,eAAe,EAAE,EAC1B,UAAU,EAAE,MAAM,GACjB,aAAa,CAqCf;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,eAAe,EAAE,EAC1B,KAAK,EAAE,MAAM,GACZ,eAAe,EAAE,CAGnB;AAED,MAAM,WAAW,YAAY;IAC3B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC9C,2BAA2B,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAC5D,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,IAAI,EACT,SAAS,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACrD,OAAO,CAqBT;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,eAAe,EAAE,EAC1B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACrD,YAAY,CA2Dd"}