@jungjaehoon/mama-core 1.8.1 → 2.0.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 (136) hide show
  1. package/dist/agent-graph/alias-write.js +3 -0
  2. package/dist/agent-graph/entity-resolve.js +3 -7
  3. package/dist/agent-graph/graph-query.js +5 -4
  4. package/dist/agent-graph/types.d.ts +30 -0
  5. package/dist/cases/store.d.ts +0 -4
  6. package/dist/cases/store.js +0 -66
  7. package/dist/cases/wiki-page-index.d.ts +0 -13
  8. package/dist/cases/wiki-page-index.js +0 -153
  9. package/dist/connectors/event-index.d.ts +1 -22
  10. package/dist/connectors/event-index.js +0 -157
  11. package/dist/context-compile/channel-grant.d.ts +46 -0
  12. package/dist/context-compile/channel-grant.js +66 -0
  13. package/dist/context-compile/compiler.js +5 -2
  14. package/dist/context-compile/index.d.ts +1 -0
  15. package/dist/context-compile/index.js +1 -0
  16. package/dist/context-compile/packet-store.d.ts +0 -1
  17. package/dist/context-compile/packet-store.js +0 -16
  18. package/dist/context-compile/source-readers.d.ts +1 -0
  19. package/dist/context-compile/source-readers.js +156 -23
  20. package/dist/context-compile/types.d.ts +17 -0
  21. package/dist/context-compile/visibility.js +28 -4
  22. package/dist/db-adapter/node-sqlite-adapter.js +4 -0
  23. package/dist/db-manager.d.ts +0 -13
  24. package/dist/db-manager.js +0 -66
  25. package/dist/decision-formatter.d.ts +0 -11
  26. package/dist/decision-formatter.js +0 -122
  27. package/dist/decision-tracker.d.ts +0 -12
  28. package/dist/decision-tracker.js +0 -50
  29. package/dist/edges/ref-validation.d.ts +1 -2
  30. package/dist/edges/ref-validation.js +33 -13
  31. package/dist/edges/store.d.ts +1 -3
  32. package/dist/edges/store.js +0 -214
  33. package/dist/edges/types.d.ts +10 -0
  34. package/dist/embedding-client.d.ts +0 -17
  35. package/dist/embedding-client.js +0 -80
  36. package/dist/embedding-server/mobile/auth.d.ts +1 -10
  37. package/dist/embedding-server/mobile/auth.js +0 -15
  38. package/dist/embeddings.d.ts +0 -12
  39. package/dist/embeddings.js +0 -68
  40. package/dist/entities/audit-metrics.d.ts +0 -5
  41. package/dist/entities/audit-metrics.js +0 -4
  42. package/dist/entities/candidate-generator.d.ts +1 -2
  43. package/dist/entities/candidate-generator.js +0 -412
  44. package/dist/entities/entity-list.d.ts +0 -1
  45. package/dist/entities/entity-list.js +0 -96
  46. package/dist/entities/entity-orphan-list.d.ts +0 -9
  47. package/dist/entities/entity-orphan-list.js +0 -88
  48. package/dist/entities/entity-search.d.ts +0 -1
  49. package/dist/entities/entity-search.js +0 -147
  50. package/dist/entities/errors.d.ts +0 -10
  51. package/dist/entities/errors.js +1 -25
  52. package/dist/entities/lineage-store.d.ts +0 -23
  53. package/dist/entities/lineage-store.js +0 -104
  54. package/dist/entities/policy-store.d.ts +0 -9
  55. package/dist/entities/policy-store.js +0 -188
  56. package/dist/entities/provenance-query.d.ts +0 -1
  57. package/dist/entities/provenance-query.js +0 -164
  58. package/dist/entities/resolution-engine.d.ts +1 -8
  59. package/dist/entities/resolution-engine.js +0 -66
  60. package/dist/entities/rollback-preview.d.ts +0 -4
  61. package/dist/entities/rollback-preview.js +0 -232
  62. package/dist/entities/store.d.ts +1 -10
  63. package/dist/entities/store.js +0 -49
  64. package/dist/index.d.ts +15 -31
  65. package/dist/index.js +4 -46
  66. package/dist/mama-api.d.ts +19 -1
  67. package/dist/mama-api.js +97 -2
  68. package/dist/memory/api.d.ts +9 -0
  69. package/dist/memory/api.js +68 -4
  70. package/dist/memory/event-store.d.ts +0 -1
  71. package/dist/memory/event-store.js +0 -15
  72. package/dist/memory/finding-store.d.ts +0 -1
  73. package/dist/memory/finding-store.js +0 -12
  74. package/dist/memory/scope-backfill.d.ts +0 -3
  75. package/dist/memory/scope-backfill.js +0 -74
  76. package/dist/memory/scope-store.d.ts +0 -1
  77. package/dist/memory/scope-store.js +0 -4
  78. package/dist/memory/truth-store.d.ts +0 -3
  79. package/dist/memory/truth-store.js +0 -22
  80. package/dist/memory/types.d.ts +0 -1
  81. package/dist/memory/types.js +0 -13
  82. package/dist/memory-store.d.ts +0 -16
  83. package/dist/memory-store.js +0 -51
  84. package/dist/ollama-client.d.ts +0 -9
  85. package/dist/ollama-client.js +0 -125
  86. package/dist/outcome-tracker.d.ts +0 -14
  87. package/dist/outcome-tracker.js +0 -44
  88. package/dist/progress-indicator.d.ts +0 -4
  89. package/dist/progress-indicator.js +0 -7
  90. package/dist/provenance/source-ref.d.ts +0 -9
  91. package/dist/provenance/source-ref.js +0 -145
  92. package/dist/query-intent.d.ts +0 -4
  93. package/dist/query-intent.js +0 -30
  94. package/dist/relevance-scorer.d.ts +0 -9
  95. package/dist/relevance-scorer.js +0 -81
  96. package/dist/search/feedback-store.d.ts +0 -1
  97. package/dist/search/feedback-store.js +0 -4
  98. package/dist/search/ranker-rescore.d.ts +0 -3
  99. package/dist/search/ranker-rescore.js +0 -27
  100. package/dist/search/ranker-trainer.d.ts +0 -8
  101. package/dist/search/ranker-trainer.js +0 -376
  102. package/dist/tier-validator.d.ts +0 -12
  103. package/dist/tier-validator.js +0 -56
  104. package/package.json +1 -10
  105. package/dist/cases/case-links.d.ts +0 -116
  106. package/dist/cases/case-links.js +0 -794
  107. package/dist/cases/composition-overrides.d.ts +0 -90
  108. package/dist/cases/composition-overrides.js +0 -724
  109. package/dist/cases/corrections.d.ts +0 -156
  110. package/dist/cases/corrections.js +0 -1045
  111. package/dist/cases/freshness.d.ts +0 -57
  112. package/dist/cases/freshness.js +0 -283
  113. package/dist/cases/live-state.d.ts +0 -48
  114. package/dist/cases/live-state.js +0 -256
  115. package/dist/cases/membership-explain.d.ts +0 -56
  116. package/dist/cases/membership-explain.js +0 -140
  117. package/dist/cases/membership-matcher.d.ts +0 -23
  118. package/dist/cases/membership-matcher.js +0 -193
  119. package/dist/cases/merge-split.d.ts +0 -61
  120. package/dist/cases/merge-split.js +0 -368
  121. package/dist/cases/role-inference.d.ts +0 -10
  122. package/dist/cases/role-inference.js +0 -85
  123. package/dist/cases/sqlite-transaction.d.ts +0 -10
  124. package/dist/cases/sqlite-transaction.js +0 -62
  125. package/dist/cases/target-ref.d.ts +0 -25
  126. package/dist/cases/target-ref.js +0 -22
  127. package/dist/cases/tombstone-sweeper.d.ts +0 -13
  128. package/dist/cases/tombstone-sweeper.js +0 -128
  129. package/dist/entities/entity-impact.d.ts +0 -41
  130. package/dist/entities/entity-impact.js +0 -140
  131. package/dist/entities/exact-merge-backfill.d.ts +0 -11
  132. package/dist/entities/exact-merge-backfill.js +0 -161
  133. package/dist/entities/lineage-backfill.d.ts +0 -12
  134. package/dist/entities/lineage-backfill.js +0 -101
  135. package/dist/memory-inject.d.ts +0 -24
  136. package/dist/memory-inject.js +0 -116
@@ -1,368 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mergeCases = mergeCases;
4
- exports.splitCase = splitCase;
5
- const node_crypto_1 = require("node:crypto");
6
- const canonicalize_js_1 = require("../canonicalize.js");
7
- const corrections_js_1 = require("./corrections.js");
8
- const sqlite_transaction_js_1 = require("./sqlite-transaction.js");
9
- const TERMINAL_CASE_STATUSES = new Set(['merged', 'archived', 'split']);
10
- const CHILD_UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
11
- function normalizeNow(value) {
12
- return value ?? new Date().toISOString();
13
- }
14
- function createdAtMs(now) {
15
- const parsed = Date.parse(now);
16
- return Number.isFinite(parsed) ? parsed : Date.now();
17
- }
18
- function nonEmpty(value) {
19
- return typeof value === 'string' && value.trim().length > 0;
20
- }
21
- function confirmed(input) {
22
- return (input.confirmed === true && nonEmpty(input.confirmed_by) && nonEmpty(input.confirmation_summary));
23
- }
24
- function readCase(adapter, caseId) {
25
- const row = adapter.prepare('SELECT * FROM case_truth WHERE case_id = ?').get(caseId);
26
- return row ?? null;
27
- }
28
- function resolveCanonicalChain(adapter, caseId) {
29
- const visited = new Set();
30
- const chain = [];
31
- let current = caseId;
32
- for (;;) {
33
- const depth = chain.length + 1;
34
- const cycleChain = [...chain, current];
35
- if (visited.has(current) || depth > 64) {
36
- return {
37
- kind: 'cycle',
38
- message: `Case merge chain cycle detected at depth ${depth} starting from case_id=${caseId}. Chain=${cycleChain.join(' -> ')}.`,
39
- };
40
- }
41
- visited.add(current);
42
- chain.push(current);
43
- const row = readCase(adapter, current);
44
- if (!row) {
45
- return { kind: 'precompile_gap', case_id: current };
46
- }
47
- if (!row.canonical_case_id) {
48
- return { kind: 'resolved', terminal_case_id: current, chain };
49
- }
50
- current = row.canonical_case_id;
51
- }
52
- }
53
- function insertMemoryEvent(input) {
54
- const eventId = `me_${(0, node_crypto_1.randomUUID)()}`;
55
- input.adapter
56
- .prepare(`
57
- INSERT INTO memory_events (
58
- event_id, event_type, actor, source_turn_id, memory_id, topic,
59
- scope_refs, evidence_refs, reason, created_at
60
- )
61
- VALUES (?, ?, 'user', NULL, NULL, ?, ?, ?, ?, ?)
62
- `)
63
- .run(eventId, input.event_type, input.topic, (0, canonicalize_js_1.canonicalizeJSON)(input.scope_refs), (0, canonicalize_js_1.canonicalizeJSON)(input.evidence_refs), (0, canonicalize_js_1.canonicalizeJSON)(input.reason), createdAtMs(input.now));
64
- return eventId;
65
- }
66
- function hasCallerChildCaseIds(children) {
67
- return children.some((child) => Object.prototype.hasOwnProperty.call(child, 'case_id'));
68
- }
69
- function trustedChildIdsAreValid(ids) {
70
- return ids.every((id) => CHILD_UUID_PATTERN.test(id) && !id.startsWith('case_'));
71
- }
72
- function childIdsAreUnique(ids) {
73
- return new Set(ids).size === ids.length;
74
- }
75
- function readParentMembership(adapter, parentCaseId, sourceType, sourceId) {
76
- const row = adapter
77
- .prepare(`
78
- SELECT role, confidence, reason, status
79
- FROM case_memberships
80
- WHERE case_id = ?
81
- AND source_type = ?
82
- AND source_id = ?
83
- `)
84
- .get(parentCaseId, sourceType, sourceId);
85
- return row ?? null;
86
- }
87
- function upsertChildMembership(input) {
88
- input.adapter
89
- .prepare(`
90
- INSERT INTO case_memberships (
91
- case_id, source_type, source_id, role, confidence, reason, status, added_by,
92
- added_at, updated_at, user_locked
93
- )
94
- VALUES (?, ?, ?, ?, ?, ?, 'active', 'user-correction', ?, ?, 1)
95
- ON CONFLICT(case_id, source_type, source_id) DO UPDATE SET
96
- role = excluded.role,
97
- confidence = excluded.confidence,
98
- reason = excluded.reason,
99
- status = 'active',
100
- added_by = 'user-correction',
101
- updated_at = excluded.updated_at,
102
- user_locked = 1
103
- `)
104
- .run(input.child_case_id, input.source_type, input.source_id, input.parent_membership?.role ?? null, input.parent_membership?.confidence ?? null, input.parent_membership?.reason ?? 'User assigned source during case split.', input.now, input.now);
105
- }
106
- function removeParentMembership(input) {
107
- input.adapter
108
- .prepare(`
109
- UPDATE case_memberships
110
- SET status = 'removed',
111
- user_locked = 1,
112
- updated_at = ?
113
- WHERE case_id = ?
114
- AND source_type = ?
115
- AND source_id = ?
116
- `)
117
- .run(input.now, input.parent_case_id, input.source_type, input.source_id);
118
- }
119
- function mergeCases(adapter, input) {
120
- const tx = adapter;
121
- if (!confirmed(input)) {
122
- return {
123
- kind: 'rejected',
124
- code: 'case.confirmation_required',
125
- message: 'confirmed=true, confirmed_by, and confirmation_summary are required.',
126
- };
127
- }
128
- return (0, sqlite_transaction_js_1.runImmediateTransaction)(tx, () => {
129
- const now = normalizeNow(input.now);
130
- if (input.loser_case_id === input.survivor_case_id) {
131
- return {
132
- kind: 'rejected',
133
- code: 'case.merge_self',
134
- message: 'loser_case_id and survivor_case_id must be different.',
135
- };
136
- }
137
- const loser = readCase(tx, input.loser_case_id);
138
- if (!loser) {
139
- return { kind: 'precompile_gap', code: 'case.precompile_gap', case_id: input.loser_case_id };
140
- }
141
- const survivor = readCase(tx, input.survivor_case_id);
142
- if (!survivor) {
143
- return {
144
- kind: 'precompile_gap',
145
- code: 'case.precompile_gap',
146
- case_id: input.survivor_case_id,
147
- };
148
- }
149
- const loserResolution = resolveCanonicalChain(tx, input.loser_case_id);
150
- if (loserResolution.kind === 'cycle') {
151
- return { kind: 'rejected', code: 'case.merge_chain_cycle', message: loserResolution.message };
152
- }
153
- if (loserResolution.kind === 'precompile_gap') {
154
- return {
155
- kind: 'precompile_gap',
156
- code: 'case.precompile_gap',
157
- case_id: loserResolution.case_id,
158
- };
159
- }
160
- const survivorResolution = resolveCanonicalChain(tx, input.survivor_case_id);
161
- if (survivorResolution.kind === 'cycle') {
162
- return {
163
- kind: 'rejected',
164
- code: 'case.merge_chain_cycle',
165
- message: survivorResolution.message,
166
- };
167
- }
168
- if (survivorResolution.kind === 'precompile_gap') {
169
- return {
170
- kind: 'precompile_gap',
171
- code: 'case.precompile_gap',
172
- case_id: survivorResolution.case_id,
173
- };
174
- }
175
- if (loserResolution.terminal_case_id === survivorResolution.terminal_case_id) {
176
- return {
177
- kind: 'rejected',
178
- code: 'case.merge_self',
179
- message: 'loser and survivor resolve to the same canonical case.',
180
- };
181
- }
182
- const canonicalLoserCaseId = loserResolution.terminal_case_id;
183
- const canonicalSurvivorCaseId = survivorResolution.terminal_case_id;
184
- if (TERMINAL_CASE_STATUSES.has(loser.status) || TERMINAL_CASE_STATUSES.has(survivor.status)) {
185
- return {
186
- kind: 'rejected',
187
- code: 'case.terminal_status',
188
- message: 'Merged, archived, and split cases cannot be merge endpoints.',
189
- };
190
- }
191
- (0, corrections_js_1.insertCaseCorrectionLock)(tx, {
192
- case_id: canonicalLoserCaseId,
193
- target_kind: 'case_field',
194
- target_ref: { kind: 'case_field', field: 'canonical_case_id' },
195
- field_name: null,
196
- old_value_json: (0, canonicalize_js_1.canonicalizeJSON)({
197
- status: loser.status,
198
- canonical_case_id: loser.canonical_case_id,
199
- }),
200
- new_value_json: (0, canonicalize_js_1.canonicalizeJSON)({
201
- status: 'merged',
202
- canonical_case_id: canonicalSurvivorCaseId,
203
- }),
204
- reason: input.reason,
205
- applied_by: input.confirmed_by,
206
- applied_at: now,
207
- is_lock_active: 0,
208
- });
209
- tx.prepare(`
210
- UPDATE case_truth
211
- SET status = 'merged',
212
- canonical_case_id = ?,
213
- updated_at = ?
214
- WHERE case_id = ?
215
- `).run(canonicalSurvivorCaseId, now, canonicalLoserCaseId);
216
- const auditEventId = insertMemoryEvent({
217
- adapter: tx,
218
- event_type: 'case.merged',
219
- topic: `case:${canonicalSurvivorCaseId}`,
220
- scope_refs: [
221
- { type: 'case', id: canonicalSurvivorCaseId },
222
- { type: 'case', id: canonicalLoserCaseId },
223
- ],
224
- evidence_refs: [canonicalLoserCaseId, canonicalSurvivorCaseId],
225
- reason: {
226
- reason: input.reason,
227
- confirmed_by: input.confirmed_by,
228
- confirmation_summary: input.confirmation_summary,
229
- },
230
- now,
231
- });
232
- return {
233
- kind: 'merged',
234
- loser_case_id: input.loser_case_id,
235
- survivor_case_id: input.survivor_case_id,
236
- audit_event_id: auditEventId,
237
- };
238
- });
239
- }
240
- function splitCase(adapter, input) {
241
- const tx = adapter;
242
- if (!confirmed(input)) {
243
- return {
244
- kind: 'rejected',
245
- code: 'case.confirmation_required',
246
- message: 'confirmed=true, confirmed_by, and confirmation_summary are required.',
247
- };
248
- }
249
- if (hasCallerChildCaseIds(input.children)) {
250
- return {
251
- kind: 'rejected',
252
- code: 'case.child_id_not_trusted',
253
- message: 'Child case IDs are runner-owned and must not be supplied in child payloads.',
254
- };
255
- }
256
- if (input.children.length < 2) {
257
- return {
258
- kind: 'rejected',
259
- code: 'case.split_requires_two_children',
260
- message: 'A split requires at least two children.',
261
- };
262
- }
263
- if (input.trusted_child_case_ids.length !== input.children.length) {
264
- return {
265
- kind: 'rejected',
266
- code: 'case.child_id_count_mismatch',
267
- message: 'trusted_child_case_ids length must match children length.',
268
- };
269
- }
270
- if (!childIdsAreUnique(input.trusted_child_case_ids) ||
271
- !trustedChildIdsAreValid(input.trusted_child_case_ids)) {
272
- return {
273
- kind: 'rejected',
274
- code: 'case.child_id_not_trusted',
275
- message: 'trusted_child_case_ids must be unique UUIDs minted by the standalone runner.',
276
- };
277
- }
278
- return (0, sqlite_transaction_js_1.runImmediateTransaction)(tx, () => {
279
- const now = normalizeNow(input.now);
280
- const parent = readCase(tx, input.parent_case_id);
281
- if (!parent) {
282
- return { kind: 'precompile_gap', code: 'case.precompile_gap', case_id: input.parent_case_id };
283
- }
284
- if (TERMINAL_CASE_STATUSES.has(parent.status)) {
285
- return {
286
- kind: 'rejected',
287
- code: 'case.terminal_status',
288
- message: `Cannot split terminal case status ${parent.status}.`,
289
- };
290
- }
291
- tx.prepare(`
292
- UPDATE case_truth
293
- SET status = 'split',
294
- updated_at = ?
295
- WHERE case_id = ?
296
- `).run(now, input.parent_case_id);
297
- for (const [index, child] of input.children.entries()) {
298
- const childCaseId = input.trusted_child_case_ids[index];
299
- tx.prepare(`
300
- INSERT INTO case_truth (
301
- case_id, current_wiki_path, title, status, split_from_case_id, wiki_path_history,
302
- scope_refs, confidence, created_at, updated_at
303
- )
304
- VALUES (?, ?, ?, 'active', ?, '[]', ?, ?, ?, ?)
305
- `).run(childCaseId, child.current_wiki_path ?? null, child.title, input.parent_case_id, parent.scope_refs ?? '[]', parent.confidence ?? null, now, now);
306
- for (const membership of child.membership_sources) {
307
- const sourceType = membership.source_type;
308
- const parentMembership = readParentMembership(tx, input.parent_case_id, sourceType, membership.source_id);
309
- upsertChildMembership({
310
- adapter: tx,
311
- child_case_id: childCaseId,
312
- source_type: sourceType,
313
- source_id: membership.source_id,
314
- parent_membership: parentMembership,
315
- now,
316
- });
317
- if (membership.remove_from_parent === true) {
318
- removeParentMembership({
319
- adapter: tx,
320
- parent_case_id: input.parent_case_id,
321
- source_type: sourceType,
322
- source_id: membership.source_id,
323
- now,
324
- });
325
- }
326
- }
327
- }
328
- (0, corrections_js_1.insertCaseCorrectionLock)(tx, {
329
- case_id: input.parent_case_id,
330
- target_kind: 'case_field',
331
- target_ref: { kind: 'case_field', field: 'status' },
332
- field_name: 'status',
333
- old_value_json: (0, canonicalize_js_1.canonicalizeJSON)(parent.status),
334
- new_value_json: (0, canonicalize_js_1.canonicalizeJSON)({
335
- status: 'split',
336
- child_case_ids: input.trusted_child_case_ids,
337
- }),
338
- reason: input.reason,
339
- applied_by: input.confirmed_by,
340
- applied_at: now,
341
- is_lock_active: 0,
342
- });
343
- const auditEventId = insertMemoryEvent({
344
- adapter: tx,
345
- event_type: 'case.split',
346
- topic: `case:${input.parent_case_id}`,
347
- scope_refs: [
348
- { type: 'case', id: input.parent_case_id },
349
- ...input.trusted_child_case_ids.map((id) => ({ type: 'case', id })),
350
- ],
351
- evidence_refs: input.trusted_child_case_ids,
352
- reason: {
353
- reason: input.reason,
354
- confirmed_by: input.confirmed_by,
355
- confirmation_summary: input.confirmation_summary,
356
- child_case_ids: input.trusted_child_case_ids,
357
- },
358
- now,
359
- });
360
- return {
361
- kind: 'split',
362
- parent_case_id: input.parent_case_id,
363
- child_case_ids: input.trusted_child_case_ids,
364
- audit_event_id: auditEventId,
365
- };
366
- });
367
- }
368
- //# sourceMappingURL=merge-split.js.map
@@ -1,10 +0,0 @@
1
- export type InferredCaseRole = 'requester' | 'implementer' | 'reviewer' | 'observer' | 'affected';
2
- interface InferTimelineEventRoleInput {
3
- userText: string;
4
- assistantText?: string;
5
- eventType?: string;
6
- actorHints?: string[];
7
- }
8
- export declare function inferTimelineEventRole(input: InferTimelineEventRoleInput): InferredCaseRole | null;
9
- export {};
10
- //# sourceMappingURL=role-inference.d.ts.map
@@ -1,85 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.inferTimelineEventRole = inferTimelineEventRole;
4
- function hasPattern(text, patterns) {
5
- return patterns.some((pattern) => pattern.test(text));
6
- }
7
- function joinText(parts) {
8
- return parts.filter((part) => Boolean(part?.trim())).join('\n');
9
- }
10
- function mentionsActor(text, actorHints) {
11
- return actorHints.some((hint) => {
12
- const trimmed = hint.trim();
13
- return trimmed.length > 0 && text.toLowerCase().includes(trimmed.toLowerCase());
14
- });
15
- }
16
- const REQUESTER_PATTERNS = [
17
- /\b(ask|asks|asked|request|requests|requested|please|can you|could you|would you|help me)\b/i,
18
- /요청|해줘|해주세요|부탁|해주시|해 줄래|해 주실/i, // Korean: keyword patterns
19
- ];
20
- const IMPLEMENTER_PATTERNS = [
21
- /\b(i|we)\s+(will\s+handle|can\s+handle|implemented|fixed|built|handled|completed|shipped|worked\s+on|am\s+working\s+on)\b/i,
22
- /\b(i'll|we'll)\s+handle\b/i,
23
- /\b(implemented|fixed|built|handled|completed|shipped)\b/i,
24
- /제가\s*(작업|수정|구현|처리|담당)|작업했습니다|수정했습니다|구현했습니다|담당합니다/i, // Korean: keyword patterns
25
- ];
26
- const ACTOR_IMPLEMENTER_PATTERNS = [
27
- /\b(will\s+handle|implemented|fixed|built|handled|completed|shipped|worked\s+on|owns\s+the\s+work)\b/i,
28
- /작업|수정|구현|처리|담당/i, // Korean: keyword patterns
29
- ];
30
- const REVIEWER_PATTERNS = [
31
- /\b(reviewed|reviewing|review|approved|approve|approval)\b/i,
32
- /검토|승인|리뷰/i, // Korean: keyword patterns
33
- ];
34
- const AFFECTED_PATTERNS = [
35
- /\b(blocked|waiting|held\s+up|impacted|affected|deferred|on\s+hold)\b/i,
36
- /막힘|막혔|보류|대기|영향/i, // Korean: keyword patterns
37
- ];
38
- const OBSERVER_PATTERNS = [
39
- /\b(fyi|for your information|status-only|status only|heads up|observing)\b/i,
40
- /참고|공유만|상태\s*공유|관찰/i, // Korean: keyword patterns
41
- ];
42
- const AMBIGUOUS_OWNER_BLOCKER_PATTERNS = [/\b(owner|blocker)\b/i, /오너|소유자|블로커/i]; // Korean: keyword patterns
43
- function inferTimelineEventRole(input) {
44
- const userText = input.userText.trim();
45
- const assistantText = input.assistantText?.trim() ?? '';
46
- const eventType = input.eventType?.trim() ?? '';
47
- const actorHints = input.actorHints ?? [];
48
- const combinedText = joinText([userText, assistantText, eventType, actorHints.join(' ')]);
49
- if (!combinedText) {
50
- return null;
51
- }
52
- const roles = new Set();
53
- if (hasPattern(userText, REQUESTER_PATTERNS)) {
54
- roles.add('requester');
55
- }
56
- const implementerText = joinText([assistantText, eventType]);
57
- if (hasPattern(implementerText, IMPLEMENTER_PATTERNS)) {
58
- roles.add('implementer');
59
- }
60
- if (mentionsActor(userText, actorHints) &&
61
- hasPattern(userText, ACTOR_IMPLEMENTER_PATTERNS) &&
62
- !hasPattern(userText, REQUESTER_PATTERNS)) {
63
- roles.add('implementer');
64
- }
65
- if (hasPattern(joinText([assistantText, eventType]), REVIEWER_PATTERNS)) {
66
- roles.add('reviewer');
67
- }
68
- if (mentionsActor(userText, actorHints) && hasPattern(userText, REVIEWER_PATTERNS)) {
69
- roles.add('reviewer');
70
- }
71
- if (hasPattern(combinedText, AFFECTED_PATTERNS)) {
72
- roles.add('affected');
73
- }
74
- if (hasPattern(combinedText, OBSERVER_PATTERNS)) {
75
- roles.add('observer');
76
- }
77
- if (roles.size === 0 && hasPattern(combinedText, AMBIGUOUS_OWNER_BLOCKER_PATTERNS)) {
78
- return null;
79
- }
80
- if (roles.size !== 1) {
81
- return null;
82
- }
83
- return [...roles][0] ?? null;
84
- }
85
- //# sourceMappingURL=role-inference.js.map
@@ -1,10 +0,0 @@
1
- export interface ImmediateTransactionAdapter {
2
- exec?: (sql: string) => void;
3
- transaction: <T>(fn: () => T) => T;
4
- }
5
- export interface ImmediateTransactionOptions {
6
- maxBusyRetries?: number;
7
- busyRetryDelayMs?: number;
8
- }
9
- export declare function runImmediateTransaction<T>(adapter: ImmediateTransactionAdapter, fn: () => T, options?: ImmediateTransactionOptions): T;
10
- //# sourceMappingURL=sqlite-transaction.d.ts.map
@@ -1,62 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runImmediateTransaction = runImmediateTransaction;
4
- function isThenable(value) {
5
- return (((typeof value === 'object' && value !== null) || typeof value === 'function') &&
6
- typeof value.then === 'function');
7
- }
8
- function isBusyError(error) {
9
- if (!(error instanceof Error)) {
10
- return false;
11
- }
12
- const code = error.code;
13
- return code === 'SQLITE_BUSY' || /SQLITE_BUSY|database is locked/i.test(error.message);
14
- }
15
- function requireSynchronousResult(result) {
16
- if (isThenable(result)) {
17
- throw new Error('runImmediateTransaction() callbacks must be synchronous');
18
- }
19
- return result;
20
- }
21
- function runImmediateTransaction(adapter, fn, options) {
22
- const maxBusyRetries = options?.maxBusyRetries ?? 3;
23
- const busyRetryDelayMs = Math.max(0, options?.busyRetryDelayMs ?? 20);
24
- if (!adapter.exec) {
25
- // Fake test adapters without exec can only provide deferred transaction
26
- // semantics; production SQLite adapters should expose exec for BEGIN IMMEDIATE.
27
- return adapter.transaction(() => requireSynchronousResult(fn()));
28
- }
29
- let attempt = 0;
30
- for (;;) {
31
- try {
32
- adapter.exec('BEGIN IMMEDIATE');
33
- try {
34
- const result = requireSynchronousResult(fn());
35
- adapter.exec('COMMIT');
36
- return result;
37
- }
38
- catch (error) {
39
- try {
40
- adapter.exec('ROLLBACK');
41
- }
42
- catch {
43
- // Preserve the original transaction failure when rollback also fails.
44
- }
45
- throw error;
46
- }
47
- }
48
- catch (error) {
49
- if (isBusyError(error) && attempt < maxBusyRetries) {
50
- attempt += 1;
51
- if (busyRetryDelayMs > 0) {
52
- // Preserve the retry budget contract without blocking the event loop
53
- // inside shared core code. Callers that need delayed retries should
54
- // wrap this synchronous helper at a higher async boundary.
55
- }
56
- continue;
57
- }
58
- throw error;
59
- }
60
- }
61
- }
62
- //# sourceMappingURL=sqlite-transaction.js.map
@@ -1,25 +0,0 @@
1
- import type { CaseMembershipSourceType } from './types.js';
2
- export type CaseFieldName = 'case_id' | 'canonical_case_id' | 'title' | 'status' | 'status_reason' | 'primary_actors' | 'blockers' | 'confidence' | 'last_activity_at';
3
- export interface CaseFieldTargetRef {
4
- kind: 'case_field';
5
- field: CaseFieldName;
6
- }
7
- export interface CaseMembershipTargetRef {
8
- kind: 'membership';
9
- source_type: CaseMembershipSourceType;
10
- source_id: string;
11
- }
12
- export interface CaseWikiSectionTargetRef {
13
- kind: 'wiki_section';
14
- section_heading: string;
15
- }
16
- export type CaseTargetRef = CaseFieldTargetRef | CaseMembershipTargetRef | CaseWikiSectionTargetRef;
17
- export interface CanonicalTargetRef {
18
- json: string;
19
- hash: Buffer;
20
- }
21
- export declare function buildCaseFieldTargetRef(fieldName: CaseFieldName): CaseFieldTargetRef;
22
- export declare function buildMembershipTargetRef(sourceType: CaseMembershipSourceType, sourceId: string): CaseMembershipTargetRef;
23
- export declare function buildWikiSectionTargetRef(sectionHeading: string): CaseWikiSectionTargetRef;
24
- export declare function canonicalTargetRef(targetRef: CaseTargetRef): CanonicalTargetRef;
25
- //# sourceMappingURL=target-ref.d.ts.map
@@ -1,22 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildCaseFieldTargetRef = buildCaseFieldTargetRef;
4
- exports.buildMembershipTargetRef = buildMembershipTargetRef;
5
- exports.buildWikiSectionTargetRef = buildWikiSectionTargetRef;
6
- exports.canonicalTargetRef = canonicalTargetRef;
7
- const canonicalize_js_1 = require("../canonicalize.js");
8
- function buildCaseFieldTargetRef(fieldName) {
9
- return { kind: 'case_field', field: fieldName };
10
- }
11
- function buildMembershipTargetRef(sourceType, sourceId) {
12
- return { kind: 'membership', source_type: sourceType, source_id: sourceId };
13
- }
14
- function buildWikiSectionTargetRef(sectionHeading) {
15
- return { kind: 'wiki_section', section_heading: sectionHeading };
16
- }
17
- function canonicalTargetRef(targetRef) {
18
- const json = (0, canonicalize_js_1.canonicalizeJSON)(targetRef);
19
- const hash = (0, canonicalize_js_1.targetRefHashCanonicalJSON)(json);
20
- return { json, hash };
21
- }
22
- //# sourceMappingURL=target-ref.js.map
@@ -1,13 +0,0 @@
1
- import type { DatabaseAdapter } from '../db-manager.js';
2
- export interface SweepStaleCaseMembershipsOptions {
3
- now?: string;
4
- limit?: number;
5
- }
6
- export interface SweepStaleCaseMembershipsResult {
7
- scanned_count: number;
8
- stale_count: number;
9
- locked_stale_count: number;
10
- audit_event_ids: string[];
11
- }
12
- export declare function sweepStaleCaseMemberships(adapter: DatabaseAdapter, options?: SweepStaleCaseMembershipsOptions): SweepStaleCaseMembershipsResult;
13
- //# sourceMappingURL=tombstone-sweeper.d.ts.map