harper-kb 0.2.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 (146) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +288 -0
  3. package/config.yaml +13 -0
  4. package/dist/core/embeddings.d.ts +31 -0
  5. package/dist/core/embeddings.d.ts.map +1 -0
  6. package/dist/core/embeddings.js +199 -0
  7. package/dist/core/embeddings.js.map +1 -0
  8. package/dist/core/entries.d.ts +101 -0
  9. package/dist/core/entries.d.ts.map +1 -0
  10. package/dist/core/entries.js +304 -0
  11. package/dist/core/entries.js.map +1 -0
  12. package/dist/core/history.d.ts +31 -0
  13. package/dist/core/history.d.ts.map +1 -0
  14. package/dist/core/history.js +119 -0
  15. package/dist/core/history.js.map +1 -0
  16. package/dist/core/knowledge-base.d.ts +49 -0
  17. package/dist/core/knowledge-base.d.ts.map +1 -0
  18. package/dist/core/knowledge-base.js +117 -0
  19. package/dist/core/knowledge-base.js.map +1 -0
  20. package/dist/core/search.d.ts +34 -0
  21. package/dist/core/search.d.ts.map +1 -0
  22. package/dist/core/search.js +327 -0
  23. package/dist/core/search.js.map +1 -0
  24. package/dist/core/tags.d.ts +39 -0
  25. package/dist/core/tags.d.ts.map +1 -0
  26. package/dist/core/tags.js +97 -0
  27. package/dist/core/tags.js.map +1 -0
  28. package/dist/core/triage.d.ts +61 -0
  29. package/dist/core/triage.d.ts.map +1 -0
  30. package/dist/core/triage.js +136 -0
  31. package/dist/core/triage.js.map +1 -0
  32. package/dist/core/webhook-endpoints.d.ts +46 -0
  33. package/dist/core/webhook-endpoints.d.ts.map +1 -0
  34. package/dist/core/webhook-endpoints.js +85 -0
  35. package/dist/core/webhook-endpoints.js.map +1 -0
  36. package/dist/hooks.d.ts +67 -0
  37. package/dist/hooks.d.ts.map +1 -0
  38. package/dist/hooks.js +53 -0
  39. package/dist/hooks.js.map +1 -0
  40. package/dist/http-utils.d.ts +38 -0
  41. package/dist/http-utils.d.ts.map +1 -0
  42. package/dist/http-utils.js +133 -0
  43. package/dist/http-utils.js.map +1 -0
  44. package/dist/index.d.ts +27 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +78 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/mcp/protocol.d.ts +25 -0
  49. package/dist/mcp/protocol.d.ts.map +1 -0
  50. package/dist/mcp/protocol.js +105 -0
  51. package/dist/mcp/protocol.js.map +1 -0
  52. package/dist/mcp/server.d.ts +28 -0
  53. package/dist/mcp/server.d.ts.map +1 -0
  54. package/dist/mcp/server.js +144 -0
  55. package/dist/mcp/server.js.map +1 -0
  56. package/dist/mcp/tools.d.ts +26 -0
  57. package/dist/mcp/tools.d.ts.map +1 -0
  58. package/dist/mcp/tools.js +706 -0
  59. package/dist/mcp/tools.js.map +1 -0
  60. package/dist/oauth/authorize.d.ts +28 -0
  61. package/dist/oauth/authorize.d.ts.map +1 -0
  62. package/dist/oauth/authorize.js +421 -0
  63. package/dist/oauth/authorize.js.map +1 -0
  64. package/dist/oauth/init.d.ts +18 -0
  65. package/dist/oauth/init.d.ts.map +1 -0
  66. package/dist/oauth/init.js +30 -0
  67. package/dist/oauth/init.js.map +1 -0
  68. package/dist/oauth/keys.d.ts +34 -0
  69. package/dist/oauth/keys.d.ts.map +1 -0
  70. package/dist/oauth/keys.js +101 -0
  71. package/dist/oauth/keys.js.map +1 -0
  72. package/dist/oauth/metadata.d.ts +23 -0
  73. package/dist/oauth/metadata.d.ts.map +1 -0
  74. package/dist/oauth/metadata.js +57 -0
  75. package/dist/oauth/metadata.js.map +1 -0
  76. package/dist/oauth/middleware.d.ts +23 -0
  77. package/dist/oauth/middleware.d.ts.map +1 -0
  78. package/dist/oauth/middleware.js +65 -0
  79. package/dist/oauth/middleware.js.map +1 -0
  80. package/dist/oauth/register.d.ts +15 -0
  81. package/dist/oauth/register.d.ts.map +1 -0
  82. package/dist/oauth/register.js +78 -0
  83. package/dist/oauth/register.js.map +1 -0
  84. package/dist/oauth/token.d.ts +16 -0
  85. package/dist/oauth/token.d.ts.map +1 -0
  86. package/dist/oauth/token.js +184 -0
  87. package/dist/oauth/token.js.map +1 -0
  88. package/dist/oauth/validate.d.ts +40 -0
  89. package/dist/oauth/validate.d.ts.map +1 -0
  90. package/dist/oauth/validate.js +61 -0
  91. package/dist/oauth/validate.js.map +1 -0
  92. package/dist/resources/HistoryResource.d.ts +41 -0
  93. package/dist/resources/HistoryResource.d.ts.map +1 -0
  94. package/dist/resources/HistoryResource.js +61 -0
  95. package/dist/resources/HistoryResource.js.map +1 -0
  96. package/dist/resources/KnowledgeBaseResource.d.ts +60 -0
  97. package/dist/resources/KnowledgeBaseResource.d.ts.map +1 -0
  98. package/dist/resources/KnowledgeBaseResource.js +118 -0
  99. package/dist/resources/KnowledgeBaseResource.js.map +1 -0
  100. package/dist/resources/KnowledgeEntryResource.d.ts +61 -0
  101. package/dist/resources/KnowledgeEntryResource.d.ts.map +1 -0
  102. package/dist/resources/KnowledgeEntryResource.js +191 -0
  103. package/dist/resources/KnowledgeEntryResource.js.map +1 -0
  104. package/dist/resources/MeResource.d.ts +31 -0
  105. package/dist/resources/MeResource.d.ts.map +1 -0
  106. package/dist/resources/MeResource.js +40 -0
  107. package/dist/resources/MeResource.js.map +1 -0
  108. package/dist/resources/QueryLogResource.d.ts +22 -0
  109. package/dist/resources/QueryLogResource.d.ts.map +1 -0
  110. package/dist/resources/QueryLogResource.js +66 -0
  111. package/dist/resources/QueryLogResource.js.map +1 -0
  112. package/dist/resources/ServiceKeyResource.d.ts +52 -0
  113. package/dist/resources/ServiceKeyResource.d.ts.map +1 -0
  114. package/dist/resources/ServiceKeyResource.js +151 -0
  115. package/dist/resources/ServiceKeyResource.js.map +1 -0
  116. package/dist/resources/TagResource.d.ts +27 -0
  117. package/dist/resources/TagResource.d.ts.map +1 -0
  118. package/dist/resources/TagResource.js +41 -0
  119. package/dist/resources/TagResource.js.map +1 -0
  120. package/dist/resources/TriageResource.d.ts +53 -0
  121. package/dist/resources/TriageResource.d.ts.map +1 -0
  122. package/dist/resources/TriageResource.js +120 -0
  123. package/dist/resources/TriageResource.js.map +1 -0
  124. package/dist/resources/WebhookEndpointResource.d.ts +63 -0
  125. package/dist/resources/WebhookEndpointResource.d.ts.map +1 -0
  126. package/dist/resources/WebhookEndpointResource.js +115 -0
  127. package/dist/resources/WebhookEndpointResource.js.map +1 -0
  128. package/dist/types.d.ts +378 -0
  129. package/dist/types.d.ts.map +1 -0
  130. package/dist/types.js +8 -0
  131. package/dist/types.js.map +1 -0
  132. package/dist/webhooks/github.d.ts +25 -0
  133. package/dist/webhooks/github.d.ts.map +1 -0
  134. package/dist/webhooks/github.js +165 -0
  135. package/dist/webhooks/github.js.map +1 -0
  136. package/dist/webhooks/middleware.d.ts +19 -0
  137. package/dist/webhooks/middleware.d.ts.map +1 -0
  138. package/dist/webhooks/middleware.js +144 -0
  139. package/dist/webhooks/middleware.js.map +1 -0
  140. package/dist/webhooks/types.d.ts +18 -0
  141. package/dist/webhooks/types.d.ts.map +1 -0
  142. package/dist/webhooks/types.js +5 -0
  143. package/dist/webhooks/types.js.map +1 -0
  144. package/package.json +69 -0
  145. package/schema/knowledge.graphql +136 -0
  146. package/schema/oauth.graphql +45 -0
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Knowledge Base Search
3
+ *
4
+ * Supports keyword, semantic (vector), and hybrid search modes.
5
+ * Applies applicability context filtering to boost/demote results.
6
+ * Logs all queries to the QueryLog table for analytics.
7
+ *
8
+ * All queries are scoped by kbId for multi-tenant isolation.
9
+ */
10
+ import type { SearchParams, SearchResult, KnowledgeEntry, ApplicabilityContext } from '../types.ts';
11
+ /**
12
+ * Search the knowledge base.
13
+ *
14
+ * @param params - Search parameters including kbId, query, mode, tags, limit, context
15
+ * @returns Scored and sorted search results
16
+ */
17
+ export declare function search(params: SearchParams): Promise<SearchResult[]>;
18
+ /**
19
+ * Filter and re-score results based on applicability context.
20
+ *
21
+ * If the caller provides their environment context, results that match get a
22
+ * score boost, while results that specify a different scope get a score penalty
23
+ * (but are NOT hidden). Context dimensions are generic key-value pairs — each
24
+ * KB defines its own (e.g., product version, tier, region, platform).
25
+ */
26
+ export declare function filterByApplicability(results: SearchResult[], context: ApplicabilityContext): SearchResult[];
27
+ /**
28
+ * List entries without search scoring.
29
+ *
30
+ * Returns entries sorted by updatedAt (newest first), with no relevance
31
+ * scoring. Used for browse mode where there's no search query.
32
+ */
33
+ export declare function listEntries(kbId: string, tags?: string[], limit?: number): Promise<Omit<KnowledgeEntry, 'embedding'>[]>;
34
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/core/search.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AA8CpG;;;;;GAKG;AACH,wBAAsB,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAiC1E;AAiJD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,oBAAoB,GAAG,YAAY,EAAE,CAsC5G;AAgED;;;;;GAKG;AACH,wBAAsB,WAAW,CAChC,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,EAAE,EACf,KAAK,GAAE,MAAW,GAChB,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,EAAE,CAAC,CA2B9C"}
@@ -0,0 +1,327 @@
1
+ /**
2
+ * Knowledge Base Search
3
+ *
4
+ * Supports keyword, semantic (vector), and hybrid search modes.
5
+ * Applies applicability context filtering to boost/demote results.
6
+ * Logs all queries to the QueryLog table for analytics.
7
+ *
8
+ * All queries are scoped by kbId for multi-tenant isolation.
9
+ */
10
+ import crypto from 'node:crypto';
11
+ import { generateEmbedding } from "./embeddings.js";
12
+ /** Default number of results to return */
13
+ const DEFAULT_LIMIT = 10;
14
+ /**
15
+ * Convert a Harper database record to a plain SearchResult object.
16
+ *
17
+ * Harper records use non-enumerable properties, so object spread
18
+ * ({...record}) produces an empty object. We must explicitly read
19
+ * each field.
20
+ */
21
+ function toSearchResult(record, score, matchType) {
22
+ const entry = record;
23
+ return {
24
+ id: entry.id,
25
+ kbId: entry.kbId,
26
+ title: entry.title,
27
+ content: entry.content,
28
+ tags: entry.tags,
29
+ appliesTo: entry.appliesTo,
30
+ source: entry.source,
31
+ sourceUrl: entry.sourceUrl,
32
+ references: entry.references,
33
+ confidence: entry.confidence,
34
+ addedBy: entry.addedBy,
35
+ reviewedBy: entry.reviewedBy,
36
+ supersedesId: entry.supersedesId,
37
+ supersededById: entry.supersededById,
38
+ siblingIds: entry.siblingIds,
39
+ relatedIds: entry.relatedIds,
40
+ metadata: entry.metadata,
41
+ deprecated: entry.deprecated,
42
+ createdAt: entry.createdAt,
43
+ updatedAt: entry.updatedAt,
44
+ score,
45
+ matchType,
46
+ };
47
+ }
48
+ /** Score boost factor for applicability matches */
49
+ const APPLICABILITY_BOOST = 1.2;
50
+ /** Score penalty factor for applicability mismatches */
51
+ const APPLICABILITY_PENALTY = 0.8;
52
+ /**
53
+ * Search the knowledge base.
54
+ *
55
+ * @param params - Search parameters including kbId, query, mode, tags, limit, context
56
+ * @returns Scored and sorted search results
57
+ */
58
+ export async function search(params) {
59
+ const { kbId, query, tags, limit = DEFAULT_LIMIT, context, mode = 'hybrid' } = params;
60
+ let results;
61
+ switch (mode) {
62
+ case 'keyword':
63
+ results = await keywordSearch(kbId, query, tags, limit);
64
+ break;
65
+ case 'semantic':
66
+ results = await semanticSearch(kbId, query, limit);
67
+ break;
68
+ case 'hybrid':
69
+ default:
70
+ results = await hybridSearch(kbId, query, tags, limit);
71
+ break;
72
+ }
73
+ // Apply applicability filtering (boost/demote based on context)
74
+ if (context) {
75
+ results = filterByApplicability(results, context);
76
+ }
77
+ // Re-sort by score after applicability adjustments
78
+ results.sort((a, b) => b.score - a.score);
79
+ // Trim to limit
80
+ results = results.slice(0, limit);
81
+ // Log the search query for analytics
82
+ await logQuery(kbId, query, context, results);
83
+ return results;
84
+ }
85
+ /**
86
+ * Perform keyword-based search using Harper's condition-based search.
87
+ */
88
+ async function keywordSearch(kbId, query, tags, limit = DEFAULT_LIMIT) {
89
+ // Run the title search
90
+ const titleResults = await collectResults(databases.kb.KnowledgeEntry.search({
91
+ conditions: [
92
+ { attribute: 'kbId', comparator: 'equals', value: kbId },
93
+ { attribute: 'title', comparator: 'contains', value: query },
94
+ { attribute: 'deprecated', comparator: 'equals', value: false },
95
+ ],
96
+ limit: limit * 2, // Fetch extra for merging
97
+ }));
98
+ // Also search by content
99
+ const contentResults = await collectResults(databases.kb.KnowledgeEntry.search({
100
+ conditions: [
101
+ { attribute: 'kbId', comparator: 'equals', value: kbId },
102
+ { attribute: 'content', comparator: 'contains', value: query },
103
+ { attribute: 'deprecated', comparator: 'equals', value: false },
104
+ ],
105
+ limit: limit * 2,
106
+ }));
107
+ // Merge and deduplicate
108
+ const seenIds = new Set();
109
+ const results = [];
110
+ // Title matches get higher score
111
+ for (const entry of titleResults) {
112
+ const typed = entry;
113
+ if (typed.id && !seenIds.has(typed.id)) {
114
+ seenIds.add(typed.id);
115
+ results.push(toSearchResult(entry, 1.0, 'keyword'));
116
+ }
117
+ }
118
+ // Content matches get lower score
119
+ for (const entry of contentResults) {
120
+ const typed = entry;
121
+ if (typed.id && !seenIds.has(typed.id)) {
122
+ seenIds.add(typed.id);
123
+ results.push(toSearchResult(entry, 0.7, 'keyword'));
124
+ }
125
+ }
126
+ // Filter by tags if needed (post-filter since conditions are ANDed)
127
+ if (tags && tags.length > 0) {
128
+ return results.filter((r) => {
129
+ const entryTags = r.tags || [];
130
+ return tags.some((tag) => entryTags.includes(tag));
131
+ });
132
+ }
133
+ return results;
134
+ }
135
+ /**
136
+ * Perform semantic (vector) search using HNSW index.
137
+ */
138
+ async function semanticSearch(kbId, query, limit = DEFAULT_LIMIT) {
139
+ let queryVector;
140
+ try {
141
+ queryVector = await generateEmbedding(query);
142
+ }
143
+ catch (error) {
144
+ logger?.warn?.('Semantic search failed — embedding model not available:', error.message);
145
+ return [];
146
+ }
147
+ const rawResults = await collectResults(databases.kb.KnowledgeEntry.search({
148
+ conditions: [{ attribute: 'kbId', comparator: 'equals', value: kbId }],
149
+ sort: { attribute: 'embedding', target: queryVector },
150
+ limit: limit * 2, // Fetch extra to allow for deprecated filtering
151
+ }));
152
+ const results = [];
153
+ for (const entry of rawResults) {
154
+ const typed = entry;
155
+ if (typed.deprecated)
156
+ continue; // Skip deprecated entries
157
+ // Calculate cosine similarity score (HNSW returns nearest first)
158
+ // Score decreases with position (1.0 for first result, decreasing)
159
+ const positionScore = 1.0 - results.length / (limit * 2);
160
+ results.push(toSearchResult(entry, Math.max(0.1, positionScore), 'semantic'));
161
+ if (results.length >= limit)
162
+ break;
163
+ }
164
+ return results;
165
+ }
166
+ /**
167
+ * Perform hybrid search: run both keyword and semantic, merge and deduplicate.
168
+ */
169
+ async function hybridSearch(kbId, query, tags, limit = DEFAULT_LIMIT) {
170
+ // Run both searches in parallel
171
+ const [keywordResults, semanticResults] = await Promise.all([
172
+ keywordSearch(kbId, query, tags, limit),
173
+ semanticSearch(kbId, query, limit),
174
+ ]);
175
+ // Merge and deduplicate
176
+ const resultMap = new Map();
177
+ // Add keyword results
178
+ for (const result of keywordResults) {
179
+ resultMap.set(result.id, result);
180
+ }
181
+ // Merge semantic results (combine scores if entry appears in both)
182
+ for (const result of semanticResults) {
183
+ const existing = resultMap.get(result.id);
184
+ if (existing) {
185
+ // Entry found in both — combine scores and mark as hybrid
186
+ existing.score = ((existing.score + result.score) / 2) * 1.3; // Boost for appearing in both
187
+ existing.matchType = 'hybrid';
188
+ }
189
+ else {
190
+ resultMap.set(result.id, result);
191
+ }
192
+ }
193
+ const merged = Array.from(resultMap.values());
194
+ merged.sort((a, b) => b.score - a.score);
195
+ return merged.slice(0, limit);
196
+ }
197
+ /**
198
+ * Filter and re-score results based on applicability context.
199
+ *
200
+ * If the caller provides their environment context, results that match get a
201
+ * score boost, while results that specify a different scope get a score penalty
202
+ * (but are NOT hidden). Context dimensions are generic key-value pairs — each
203
+ * KB defines its own (e.g., product version, tier, region, platform).
204
+ */
205
+ export function filterByApplicability(results, context) {
206
+ return results.map((result) => {
207
+ const appliesTo = result.appliesTo;
208
+ if (!appliesTo) {
209
+ return result;
210
+ }
211
+ let matchCount = 0;
212
+ let mismatchCount = 0;
213
+ let totalFields = 0;
214
+ for (const key of Object.keys(appliesTo)) {
215
+ if (context[key] === undefined)
216
+ continue;
217
+ totalFields++;
218
+ const matches = isVersionRange(appliesTo[key])
219
+ ? versionMatches(context[key], appliesTo[key])
220
+ : context[key] === appliesTo[key];
221
+ if (matches) {
222
+ matchCount++;
223
+ }
224
+ else {
225
+ mismatchCount++;
226
+ }
227
+ }
228
+ if (totalFields === 0) {
229
+ return result;
230
+ }
231
+ let adjustedScore = result.score;
232
+ if (matchCount > 0) {
233
+ adjustedScore *= APPLICABILITY_BOOST;
234
+ }
235
+ if (mismatchCount > 0) {
236
+ adjustedScore *= APPLICABILITY_PENALTY;
237
+ }
238
+ return { ...result, score: adjustedScore };
239
+ });
240
+ }
241
+ /**
242
+ * Detect whether a value looks like a semver range (starts with a range prefix).
243
+ */
244
+ function isVersionRange(value) {
245
+ return /^[>=<~^]/.test(value);
246
+ }
247
+ /**
248
+ * Simple version matching.
249
+ * Supports exact match and basic semver range prefixes (>=, <=, ~, ^).
250
+ * For production use, consider a proper semver library.
251
+ */
252
+ function versionMatches(actual, required) {
253
+ // Strip common prefixes for comparison
254
+ const cleanActual = actual.replace(/^[v=]/, '');
255
+ const cleanRequired = required.replace(/^[v=]/, '');
256
+ // Exact match
257
+ if (cleanActual === cleanRequired)
258
+ return true;
259
+ // Range prefix checks (simplified)
260
+ if (required.startsWith('>=')) {
261
+ return cleanActual >= required.slice(2);
262
+ }
263
+ if (required.startsWith('<=')) {
264
+ return cleanActual <= required.slice(2);
265
+ }
266
+ // For ~ and ^ ranges, just check major.minor match
267
+ if (required.startsWith('~') || required.startsWith('^')) {
268
+ const reqParts = required.slice(1).split('.');
269
+ const actParts = cleanActual.split('.');
270
+ return reqParts[0] === actParts[0] && (reqParts.length < 2 || reqParts[1] === actParts[1]);
271
+ }
272
+ return false;
273
+ }
274
+ /**
275
+ * Log a search query to the QueryLog table for analytics.
276
+ */
277
+ async function logQuery(kbId, query, context, results) {
278
+ try {
279
+ await databases.kb.QueryLog.put({
280
+ id: crypto.randomUUID(),
281
+ kbId,
282
+ query,
283
+ context: context || null,
284
+ resultCount: results.length,
285
+ topResultId: results.length > 0 ? results[0].id : null,
286
+ });
287
+ }
288
+ catch (error) {
289
+ // Don't fail the search if logging fails
290
+ logger?.warn?.('Failed to log search query:', error.message);
291
+ }
292
+ }
293
+ /**
294
+ * List entries without search scoring.
295
+ *
296
+ * Returns entries sorted by updatedAt (newest first), with no relevance
297
+ * scoring. Used for browse mode where there's no search query.
298
+ */
299
+ export async function listEntries(kbId, tags, limit = 30) {
300
+ const { stripEmbedding } = await import("./entries.js");
301
+ const conditions = [
302
+ { attribute: 'kbId', comparator: 'equals', value: kbId },
303
+ { attribute: 'deprecated', comparator: 'equals', value: false },
304
+ ];
305
+ if (tags && tags.length > 0) {
306
+ for (const tag of tags) {
307
+ conditions.push({ attribute: 'tags', comparator: 'contains', value: tag });
308
+ }
309
+ }
310
+ const records = await collectResults(databases.kb.KnowledgeEntry.search({
311
+ conditions,
312
+ sort: { attribute: 'updatedAt', descending: true },
313
+ limit,
314
+ }));
315
+ return records.map((record) => stripEmbedding(record));
316
+ }
317
+ /**
318
+ * Collect all results from an async iterable into an array.
319
+ */
320
+ async function collectResults(iterable) {
321
+ const results = [];
322
+ for await (const item of iterable) {
323
+ results.push(item);
324
+ }
325
+ return results;
326
+ }
327
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/core/search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Tag Management
3
+ *
4
+ * Manages knowledge base tags, including listing and synchronizing
5
+ * tag counts when entries are created, updated, or deleted.
6
+ *
7
+ * Tags are scoped per knowledge base. The tag ID is a composite key
8
+ * of `${kbId}:${tagName}` to allow the same tag name across different KBs.
9
+ */
10
+ import type { KnowledgeTag } from '../types.ts';
11
+ /**
12
+ * List knowledge tags for a specific knowledge base.
13
+ *
14
+ * @param kbId - Knowledge base identifier
15
+ * @param limit - Maximum number of tags to return (default 500)
16
+ * @returns Tags from the KnowledgeTag table scoped to this KB
17
+ */
18
+ export declare function listTags(kbId: string, limit?: number): Promise<KnowledgeTag[]>;
19
+ /**
20
+ * Get a single tag by name within a knowledge base.
21
+ *
22
+ * @param kbId - Knowledge base identifier
23
+ * @param tagName - Tag name
24
+ * @returns The tag record, or null if not found
25
+ */
26
+ export declare function getTag(kbId: string, tagName: string): Promise<KnowledgeTag | null>;
27
+ /**
28
+ * Synchronize tag counts when entries are created, updated, or deleted.
29
+ *
30
+ * For tags added (in newTags but not in previousTags), increment entryCount
31
+ * or create the tag with count 1. For tags removed (in previousTags but not
32
+ * in newTags), decrement entryCount.
33
+ *
34
+ * @param kbId - Knowledge base identifier
35
+ * @param newTags - Tags on the entry after the change
36
+ * @param previousTags - Tags on the entry before the change (empty for new entries)
37
+ */
38
+ export declare function syncTags(kbId: string, newTags: string[], previousTags?: string[]): Promise<void>;
39
+ //# sourceMappingURL=tags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../src/core/tags.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAShD;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CASjF;AAED;;;;;;GAMG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAGxF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA2CtG"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Tag Management
3
+ *
4
+ * Manages knowledge base tags, including listing and synchronizing
5
+ * tag counts when entries are created, updated, or deleted.
6
+ *
7
+ * Tags are scoped per knowledge base. The tag ID is a composite key
8
+ * of `${kbId}:${tagName}` to allow the same tag name across different KBs.
9
+ */
10
+ /**
11
+ * Build a composite tag ID from kbId and tag name.
12
+ */
13
+ function tagId(kbId, tagName) {
14
+ return `${kbId}:${tagName}`;
15
+ }
16
+ /**
17
+ * List knowledge tags for a specific knowledge base.
18
+ *
19
+ * @param kbId - Knowledge base identifier
20
+ * @param limit - Maximum number of tags to return (default 500)
21
+ * @returns Tags from the KnowledgeTag table scoped to this KB
22
+ */
23
+ export async function listTags(kbId, limit = 500) {
24
+ const results = [];
25
+ for await (const tag of databases.kb.KnowledgeTag.search({
26
+ conditions: [{ attribute: 'kbId', comparator: 'equals', value: kbId }],
27
+ limit,
28
+ })) {
29
+ results.push(tag);
30
+ }
31
+ return results;
32
+ }
33
+ /**
34
+ * Get a single tag by name within a knowledge base.
35
+ *
36
+ * @param kbId - Knowledge base identifier
37
+ * @param tagName - Tag name
38
+ * @returns The tag record, or null if not found
39
+ */
40
+ export async function getTag(kbId, tagName) {
41
+ const tag = await databases.kb.KnowledgeTag.get(tagId(kbId, tagName));
42
+ return tag;
43
+ }
44
+ /**
45
+ * Synchronize tag counts when entries are created, updated, or deleted.
46
+ *
47
+ * For tags added (in newTags but not in previousTags), increment entryCount
48
+ * or create the tag with count 1. For tags removed (in previousTags but not
49
+ * in newTags), decrement entryCount.
50
+ *
51
+ * @param kbId - Knowledge base identifier
52
+ * @param newTags - Tags on the entry after the change
53
+ * @param previousTags - Tags on the entry before the change (empty for new entries)
54
+ */
55
+ export async function syncTags(kbId, newTags, previousTags) {
56
+ const prev = new Set(previousTags || []);
57
+ const next = new Set(newTags);
58
+ // Tags that were added
59
+ const added = newTags.filter((tag) => !prev.has(tag));
60
+ // Tags that were removed
61
+ const removed = (previousTags || []).filter((tag) => !next.has(tag));
62
+ // Increment counts for added tags
63
+ for (const tagName of added) {
64
+ const id = tagId(kbId, tagName);
65
+ const existing = await databases.kb.KnowledgeTag.get(id);
66
+ if (existing) {
67
+ await databases.kb.KnowledgeTag.put({
68
+ ...existing,
69
+ id,
70
+ kbId,
71
+ entryCount: (existing.entryCount || 0) + 1,
72
+ });
73
+ }
74
+ else {
75
+ await databases.kb.KnowledgeTag.put({
76
+ id,
77
+ kbId,
78
+ entryCount: 1,
79
+ });
80
+ }
81
+ }
82
+ // Decrement counts for removed tags
83
+ for (const tagName of removed) {
84
+ const id = tagId(kbId, tagName);
85
+ const existing = await databases.kb.KnowledgeTag.get(id);
86
+ if (existing) {
87
+ const currentCount = existing.entryCount || 0;
88
+ await databases.kb.KnowledgeTag.put({
89
+ ...existing,
90
+ id,
91
+ kbId,
92
+ entryCount: Math.max(0, currentCount - 1),
93
+ });
94
+ }
95
+ }
96
+ }
97
+ //# sourceMappingURL=tags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tags.js","sourceRoot":"","sources":["../../src/core/tags.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Triage Queue Management
3
+ *
4
+ * Handles the intake queue for new knowledge submissions from webhooks
5
+ * and other sources. Items go through pending -> processing -> accepted/dismissed.
6
+ *
7
+ * All operations are scoped by kbId for multi-tenant isolation.
8
+ */
9
+ import type { TriageItem, TriageAction, TriageProcessOptions } from '../types.ts';
10
+ /**
11
+ * Submit a new item to the triage queue.
12
+ *
13
+ * @param kbId - Knowledge base identifier
14
+ * @param source - Source identifier (e.g., "github-webhook", "slack-bot", "manual")
15
+ * @param summary - Brief summary of the knowledge to triage
16
+ * @param rawPayload - Original raw payload from the source
17
+ * @param sourceId - Optional deduplication key from the source system
18
+ * @returns The created triage item
19
+ */
20
+ export declare function submitTriage(kbId: string, source: string, summary: string, rawPayload?: unknown, sourceId?: string): Promise<TriageItem>;
21
+ /**
22
+ * Find a triage item by its source-specific ID for deduplication.
23
+ *
24
+ * @param kbId - Knowledge base identifier
25
+ * @param sourceId - The source-specific identifier
26
+ * @returns The matching triage item, or null if not found
27
+ */
28
+ export declare function findBySourceId(kbId: string, sourceId: string): Promise<TriageItem | null>;
29
+ /**
30
+ * Process a triage item with the given action.
31
+ *
32
+ * - "accepted": Optionally creates a new knowledge entry from provided data
33
+ * - "dismissed": Marks the item as dismissed
34
+ * - "linked": Links the triage item to an existing knowledge entry
35
+ *
36
+ * @param id - Triage item ID
37
+ * @param action - Action to take
38
+ * @param processedBy - Who processed this item
39
+ * @param options - Additional options (entry data for accept, linked entry ID)
40
+ * @returns The updated triage item
41
+ * @throws Error if the triage item does not exist
42
+ */
43
+ export declare function processTriage(id: string, action: TriageAction, processedBy: string, options?: TriageProcessOptions): Promise<TriageItem>;
44
+ /**
45
+ * List pending triage items for a specific knowledge base.
46
+ *
47
+ * @param kbId - Knowledge base identifier
48
+ * @param limit - Maximum number of items to return (default 200)
49
+ * @returns Array of triage items with status "pending"
50
+ */
51
+ export declare function listPending(kbId: string, limit?: number): Promise<TriageItem[]>;
52
+ /**
53
+ * Dismiss a triage item.
54
+ *
55
+ * Convenience method that calls processTriage with action "dismissed".
56
+ *
57
+ * @param id - Triage item ID
58
+ * @param processedBy - Who dismissed this item
59
+ */
60
+ export declare function dismissTriage(id: string, processedBy: string): Promise<void>;
61
+ //# sourceMappingURL=triage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triage.d.ts","sourceRoot":"","sources":["../../src/core/triage.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,oBAAoB,EAAuB,MAAM,aAAa,CAAC;AAEvG;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CACjC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,OAAO,EACpB,QAAQ,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CAgBrB;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAW/F;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CAClC,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,YAAY,EACpB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,oBAAoB,GAC5B,OAAO,CAAC,UAAU,CAAC,CAyCrB;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAYlF;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAElF"}