@lucern/sdk 0.2.0-alpha.4 → 0.2.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/README.md +31 -0
  2. package/dist/.generated +2 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.js +3 -8894
  5. package/dist/lib/platform/auth/credentials.d.ts +5 -0
  6. package/dist/lib/platform/auth/credentials.js +40 -0
  7. package/dist/lib/platform/sdk/adminClient.d.ts +404 -0
  8. package/dist/lib/platform/sdk/adminClient.js +384 -0
  9. package/dist/lib/platform/sdk/answersClient.d.ts +16 -0
  10. package/dist/lib/platform/sdk/answersClient.js +21 -0
  11. package/dist/{packages/sdk/src → lib/platform/sdk}/audiencesClient.d.ts +6 -0
  12. package/dist/lib/platform/sdk/audiencesClient.js +111 -0
  13. package/dist/{packages/sdk/src → lib/platform/sdk}/auditClient.d.ts +3 -0
  14. package/dist/lib/platform/sdk/auditClient.js +21 -0
  15. package/dist/lib/platform/sdk/beliefsClient.d.ts +157 -0
  16. package/dist/lib/platform/sdk/beliefsClient.js +124 -0
  17. package/dist/{packages/sdk/src → lib/platform/sdk}/client.d.ts +957 -146
  18. package/dist/lib/platform/sdk/client.js +1831 -0
  19. package/dist/lib/platform/sdk/contextClient.d.ts +21 -0
  20. package/dist/lib/platform/sdk/contextClient.js +86 -0
  21. package/dist/lib/platform/sdk/contextFacade.d.ts +10 -0
  22. package/dist/lib/platform/sdk/contextFacade.js +10 -0
  23. package/dist/{lucern/packages/domain-context/src/context-pack-compiler.d.ts → lib/platform/sdk/contextPackCompiler.d.ts} +2 -3
  24. package/dist/lib/platform/sdk/contextPackCompiler.js +534 -0
  25. package/dist/lib/platform/sdk/contextTypes.d.ts +133 -0
  26. package/dist/lib/platform/sdk/contextTypes.js +1 -0
  27. package/dist/{packages/sdk/src → lib/platform/sdk}/controlObjectOwnership.d.ts +15 -0
  28. package/dist/lib/platform/sdk/controlObjectOwnership.js +220 -0
  29. package/dist/{packages/sdk/src → lib/platform/sdk}/coreClient.d.ts +19 -0
  30. package/dist/lib/platform/sdk/coreClient.js +366 -0
  31. package/dist/{packages/sdk/src → lib/platform/sdk}/customTools.d.ts +21 -3
  32. package/dist/lib/platform/sdk/customTools.js +247 -0
  33. package/dist/{packages/sdk/src → lib/platform/sdk}/decisionsClient.d.ts +9 -0
  34. package/dist/lib/platform/sdk/decisionsClient.js +129 -0
  35. package/dist/lib/platform/sdk/domainContext.d.ts +1 -0
  36. package/dist/lib/platform/sdk/domainContext.js +1 -0
  37. package/dist/lib/platform/sdk/events.d.ts +176 -0
  38. package/dist/lib/platform/sdk/events.js +261 -0
  39. package/dist/lib/platform/sdk/eventsCore.d.ts +13 -0
  40. package/dist/lib/platform/sdk/eventsCore.js +13 -0
  41. package/dist/lib/platform/sdk/gatewayFacades.d.ts +586 -0
  42. package/dist/lib/platform/sdk/gatewayFacades.js +845 -0
  43. package/dist/{packages/sdk/src → lib/platform/sdk}/graphClient.d.ts +75 -0
  44. package/dist/lib/platform/sdk/graphClient.js +235 -0
  45. package/dist/{packages/sdk/src → lib/platform/sdk}/harnessClient.d.ts +90 -1
  46. package/dist/lib/platform/sdk/harnessClient.js +219 -0
  47. package/dist/{packages/sdk/src → lib/platform/sdk}/identityClient.d.ts +45 -15
  48. package/dist/lib/platform/sdk/identityClient.js +131 -0
  49. package/dist/{packages/sdk/src → lib/platform/sdk}/index.d.ts +24 -3
  50. package/dist/lib/platform/sdk/index.js +49 -0
  51. package/dist/{packages/sdk/src → lib/platform/sdk}/learningClient.d.ts +3 -0
  52. package/dist/lib/platform/sdk/learningClient.js +53 -0
  53. package/dist/{packages/sdk/src → lib/platform/sdk}/mcpParityClient.d.ts +1 -0
  54. package/dist/lib/platform/sdk/mcpParityClient.js +196 -0
  55. package/dist/{packages/sdk/src → lib/platform/sdk}/mcpParitySurface.d.ts +2 -0
  56. package/dist/lib/platform/sdk/mcpParitySurface.js +57 -0
  57. package/dist/{packages/sdk/src → lib/platform/sdk}/ontologyClient.d.ts +16 -0
  58. package/dist/lib/platform/sdk/ontologyClient.js +161 -0
  59. package/dist/lib/platform/sdk/packRuntime.d.ts +1 -0
  60. package/dist/lib/platform/sdk/packRuntime.js +1 -0
  61. package/dist/{packages/sdk/src → lib/platform/sdk}/packsClient.d.ts +25 -0
  62. package/dist/lib/platform/sdk/packsClient.js +157 -0
  63. package/dist/{packages/sdk/src → lib/platform/sdk}/policyClient.d.ts +90 -1
  64. package/dist/lib/platform/sdk/policyClient.js +277 -0
  65. package/dist/lib/platform/sdk/promptCatalog.d.ts +1 -0
  66. package/dist/lib/platform/sdk/promptCatalog.js +1 -0
  67. package/dist/{packages/sdk/src → lib/platform/sdk}/reportsClient.d.ts +3 -0
  68. package/dist/lib/platform/sdk/reportsClient.js +64 -0
  69. package/dist/{packages/sdk/src → lib/platform/sdk}/schemaClient.d.ts +5 -0
  70. package/dist/lib/platform/sdk/schemaClient.js +71 -0
  71. package/dist/{packages/sdk/src → lib/platform/sdk}/sdkSurface.d.ts +1 -0
  72. package/dist/lib/platform/sdk/sdkSurface.js +140 -0
  73. package/dist/{packages/sdk/src → lib/platform/sdk}/topicsClient.d.ts +33 -0
  74. package/dist/lib/platform/sdk/topicsClient.js +118 -0
  75. package/dist/{packages/sdk/src → lib/platform/sdk}/types.d.ts +224 -2
  76. package/dist/lib/platform/sdk/types.js +1 -0
  77. package/dist/lib/platform/sdk/version.js +2 -0
  78. package/dist/{packages/sdk/src → lib/platform/sdk}/workflowClient.d.ts +63 -2
  79. package/dist/lib/platform/sdk/workflowClient.js +366 -0
  80. package/dist/lucern/contracts/src/api-enums.contract.d.ts +58 -0
  81. package/dist/lucern/contracts/src/api-enums.contract.js +147 -0
  82. package/dist/lucern/contracts/src/auth-context.contract.d.ts +8 -0
  83. package/dist/lucern/contracts/src/auth-context.contract.js +8 -0
  84. package/dist/lucern/contracts/src/auth-session.contract.d.ts +5 -50
  85. package/dist/lucern/contracts/src/auth-session.contract.js +8 -0
  86. package/dist/lucern/contracts/src/auth.contract.d.ts +88 -0
  87. package/dist/lucern/contracts/src/auth.contract.js +57 -0
  88. package/dist/lucern/contracts/src/context-pack.contract.js +169 -0
  89. package/dist/lucern/contracts/src/convex-admin.contract.d.ts +5 -0
  90. package/dist/lucern/contracts/src/convex-admin.contract.js +1 -0
  91. package/dist/lucern/contracts/src/events-types.contract.d.ts +8 -0
  92. package/dist/lucern/contracts/src/events-types.contract.js +8 -0
  93. package/dist/lucern/{packages/events/src/types.d.ts → contracts/src/events.contract.d.ts} +25 -0
  94. package/dist/lucern/contracts/src/events.contract.js +159 -0
  95. package/dist/lucern/contracts/src/gateway.contract.d.ts +74 -0
  96. package/dist/lucern/contracts/src/gateway.contract.js +19 -0
  97. package/dist/lucern/contracts/src/ids.contract.js +24 -0
  98. package/dist/lucern/contracts/src/index.d.ts +29 -0
  99. package/dist/lucern/contracts/src/index.js +29 -0
  100. package/dist/lucern/contracts/src/lens-filter.contract.js +95 -0
  101. package/dist/lucern/contracts/src/lens-workflow.contract.js +54 -0
  102. package/dist/lucern/contracts/src/mcp-tools.contract.js +3281 -0
  103. package/dist/lucern/contracts/src/ontology-matching.contract.d.ts +8 -0
  104. package/dist/lucern/contracts/src/ontology-matching.contract.js +8 -0
  105. package/dist/lucern/contracts/src/prompt.contract.d.ts +24 -0
  106. package/dist/lucern/contracts/src/prompt.contract.js +24 -0
  107. package/dist/lucern/contracts/src/sdk-methods.contract.d.ts +358 -0
  108. package/dist/lucern/contracts/src/sdk-methods.contract.js +19 -0
  109. package/dist/lucern/contracts/src/sdk-tools.contract.d.ts +92 -0
  110. package/dist/lucern/contracts/src/sdk-tools.contract.js +1398 -0
  111. package/dist/lucern/contracts/src/text-matching.contract.js +277 -0
  112. package/dist/lucern/contracts/src/topic-scope.contract.d.ts +8 -0
  113. package/dist/lucern/contracts/src/topic-scope.contract.js +8 -0
  114. package/dist/lucern/contracts/src/workflow-runtime.contract.js +257 -0
  115. package/dist/realtime-refs.d.ts +1 -0
  116. package/dist/realtime-refs.js +1 -0
  117. package/dist/realtime.d.ts +1 -0
  118. package/dist/realtime.js +1 -0
  119. package/package.json +18 -5
  120. package/dist/index.js.map +0 -1
  121. package/dist/lucern/mcp-server/src/context-pack-policy.d.ts +0 -119
  122. package/dist/lucern/mcp-server/src/context-pack-schema.d.ts +0 -18
  123. package/dist/lucern/modules/graph-primitives/src/ontology-matching.d.ts +0 -78
  124. package/dist/lucern/packages/client-core/src/beliefs.d.ts +0 -30
  125. package/dist/lucern/packages/client-core/src/context.d.ts +0 -29
  126. package/dist/lucern/packages/client-core/src/contradictions.d.ts +0 -11
  127. package/dist/lucern/packages/client-core/src/edges.d.ts +0 -11
  128. package/dist/lucern/packages/client-core/src/events.d.ts +0 -9
  129. package/dist/lucern/packages/client-core/src/evidence.d.ts +0 -21
  130. package/dist/lucern/packages/client-core/src/graph.d.ts +0 -17
  131. package/dist/lucern/packages/client-core/src/identity.d.ts +0 -7
  132. package/dist/lucern/packages/client-core/src/ontologies.d.ts +0 -13
  133. package/dist/lucern/packages/client-core/src/questions.d.ts +0 -39
  134. package/dist/lucern/packages/client-core/src/search.d.ts +0 -7
  135. package/dist/lucern/packages/client-core/src/tasks.d.ts +0 -13
  136. package/dist/lucern/packages/client-core/src/topics.d.ts +0 -17
  137. package/dist/lucern/packages/client-core/src/webhooks.d.ts +0 -35
  138. package/dist/lucern/packages/client-core/src/worktrees.d.ts +0 -17
  139. package/dist/lucern/packages/domain-beliefs/src/beliefs.d.ts +0 -283
  140. package/dist/lucern/packages/domain-beliefs/src/index.d.ts +0 -1
  141. package/dist/lucern/packages/domain-context/src/compile.d.ts +0 -11
  142. package/dist/lucern/packages/domain-context/src/index.d.ts +0 -4
  143. package/dist/lucern/packages/domain-context/src/ports.d.ts +0 -58
  144. package/dist/lucern/packages/domain-context/src/public-types.d.ts +0 -1
  145. package/dist/lucern/packages/domain-edges/src/contradictions.d.ts +0 -59
  146. package/dist/lucern/packages/domain-edges/src/edges.d.ts +0 -91
  147. package/dist/lucern/packages/domain-edges/src/index.d.ts +0 -2
  148. package/dist/lucern/packages/domain-evidence/src/evidence.d.ts +0 -115
  149. package/dist/lucern/packages/domain-evidence/src/index.d.ts +0 -1
  150. package/dist/lucern/packages/domain-graph/src/graph.d.ts +0 -150
  151. package/dist/lucern/packages/domain-identity/src/index.d.ts +0 -1
  152. package/dist/lucern/packages/domain-identity/src/whoami.d.ts +0 -13
  153. package/dist/lucern/packages/domain-ontologies/src/ontologies.d.ts +0 -123
  154. package/dist/lucern/packages/domain-questions/src/index.d.ts +0 -1
  155. package/dist/lucern/packages/domain-questions/src/questions.d.ts +0 -147
  156. package/dist/lucern/packages/domain-search/src/search.d.ts +0 -97
  157. package/dist/lucern/packages/domain-tasks/src/index.d.ts +0 -1
  158. package/dist/lucern/packages/domain-tasks/src/tasks.d.ts +0 -102
  159. package/dist/lucern/packages/domain-topics/src/index.d.ts +0 -1
  160. package/dist/lucern/packages/domain-topics/src/topics.d.ts +0 -147
  161. package/dist/lucern/packages/domain-worktrees/src/index.d.ts +0 -1
  162. package/dist/lucern/packages/domain-worktrees/src/worktrees.d.ts +0 -185
  163. package/dist/lucern/packages/events/src/index.d.ts +0 -4
  164. package/dist/lucern/packages/events/src/matching.d.ts +0 -3
  165. package/dist/lucern/packages/events/src/outbox.d.ts +0 -15
  166. package/dist/lucern/packages/events/src/webhooks.d.ts +0 -9
  167. package/dist/lucern/packages/sdk-typescript/src/facade/beliefs.d.ts +0 -15
  168. package/dist/lucern/packages/sdk-typescript/src/facade/context.d.ts +0 -12
  169. package/dist/lucern/packages/sdk-typescript/src/facade/contradictions.d.ts +0 -7
  170. package/dist/lucern/packages/sdk-typescript/src/facade/edges.d.ts +0 -7
  171. package/dist/lucern/packages/sdk-typescript/src/facade/events.d.ts +0 -6
  172. package/dist/lucern/packages/sdk-typescript/src/facade/evidence.d.ts +0 -21
  173. package/dist/lucern/packages/sdk-typescript/src/facade/graph.d.ts +0 -10
  174. package/dist/lucern/packages/sdk-typescript/src/facade/identity.d.ts +0 -5
  175. package/dist/lucern/packages/sdk-typescript/src/facade/ontologies.d.ts +0 -8
  176. package/dist/lucern/packages/sdk-typescript/src/facade/questions.d.ts +0 -39
  177. package/dist/lucern/packages/sdk-typescript/src/facade/search.d.ts +0 -5
  178. package/dist/lucern/packages/sdk-typescript/src/facade/tasks.d.ts +0 -8
  179. package/dist/lucern/packages/sdk-typescript/src/facade/topics.d.ts +0 -10
  180. package/dist/lucern/packages/sdk-typescript/src/facade/webhooks.d.ts +0 -16
  181. package/dist/lucern/packages/sdk-typescript/src/facade/worktrees.d.ts +0 -10
  182. package/dist/lucern/packages/sdk-typescript/src/index.d.ts +0 -28
  183. package/dist/packages/sdk/src/adminClient.d.ts +0 -89
  184. package/dist/packages/sdk/src/answersClient.d.ts +0 -5
  185. package/dist/packages/sdk/src/beliefsClient.d.ts +0 -52
  186. package/dist/packages/sdk/src/contextClient.d.ts +0 -9
  187. package/dist/packages/sdk/src/contracts/api-enums.contract.d.ts +0 -79
  188. /package/dist/{packages/sdk/src → lib/platform/sdk}/version.d.ts +0 -0
  189. /package/dist/lucern/{packages/client-core/src/ids.d.ts → contracts/src/ids.contract.d.ts} +0 -0
  190. /package/dist/lucern/{modules/graph-primitives/src/text-matching.d.ts → contracts/src/text-matching.contract.d.ts} +0 -0
@@ -0,0 +1,277 @@
1
+ /**
2
+ * Shared lexical matching primitives used across MCP handlers and graph utilities.
3
+ *
4
+ * The goal is not to replace downstream LLM scoring. It provides a fast,
5
+ * deterministic substrate for candidate generation, reranking, and light
6
+ * classification across belief/question/evidence/entity surfaces.
7
+ */
8
+ const TOKEN_SPLIT_REGEX = /[^a-z0-9]+/;
9
+ const NON_ALPHANUMERIC_REGEX = /[^a-z0-9]/g;
10
+ /** Stop words that add noise to scoring. */
11
+ const STOP_WORDS = new Set([
12
+ "the",
13
+ "a",
14
+ "an",
15
+ "and",
16
+ "or",
17
+ "but",
18
+ "in",
19
+ "on",
20
+ "at",
21
+ "to",
22
+ "for",
23
+ "of",
24
+ "with",
25
+ "by",
26
+ "from",
27
+ "is",
28
+ "it",
29
+ "as",
30
+ "be",
31
+ "was",
32
+ "are",
33
+ "this",
34
+ "that",
35
+ "has",
36
+ "had",
37
+ "have",
38
+ "not",
39
+ "all",
40
+ "can",
41
+ "do",
42
+ "its",
43
+ "may",
44
+ "will",
45
+ "how",
46
+ "what",
47
+ "which",
48
+ "who",
49
+ "when",
50
+ "where",
51
+ "than",
52
+ "then",
53
+ "each",
54
+ "into",
55
+ "such",
56
+ "any",
57
+ "been",
58
+ "if",
59
+ "would",
60
+ "about",
61
+ "should",
62
+ "these",
63
+ "those",
64
+ "their",
65
+ "we",
66
+ "our",
67
+ "so",
68
+ ]);
69
+ /** Tokenize a string into lowercase words, removing stop words. */
70
+ export function tokenizeSearchText(text) {
71
+ return text
72
+ .toLowerCase()
73
+ .split(TOKEN_SPLIT_REGEX)
74
+ .filter((token) => token.length >= 2 && !STOP_WORDS.has(token));
75
+ }
76
+ /** Simple stemmer: strip common English suffixes for fuzzy matching. */
77
+ export function stemToken(word) {
78
+ if (word.length <= 4) {
79
+ return word;
80
+ }
81
+ if (word.endsWith("ation")) {
82
+ return word.slice(0, -5);
83
+ }
84
+ if (word.endsWith("ment")) {
85
+ return word.slice(0, -4);
86
+ }
87
+ if (word.endsWith("ness")) {
88
+ return word.slice(0, -4);
89
+ }
90
+ if (word.endsWith("ical")) {
91
+ return word.slice(0, -4);
92
+ }
93
+ if (word.endsWith("tion")) {
94
+ return word.slice(0, -4);
95
+ }
96
+ if (word.endsWith("sion")) {
97
+ return word.slice(0, -4);
98
+ }
99
+ if (word.endsWith("ing")) {
100
+ return word.slice(0, -3);
101
+ }
102
+ if (word.endsWith("ous")) {
103
+ return word.slice(0, -3);
104
+ }
105
+ if (word.endsWith("ive")) {
106
+ return word.slice(0, -3);
107
+ }
108
+ if (word.endsWith("ity")) {
109
+ return word.slice(0, -3);
110
+ }
111
+ if (word.endsWith("ics")) {
112
+ return word.slice(0, -3);
113
+ }
114
+ if (word.endsWith("ly")) {
115
+ return word.slice(0, -2);
116
+ }
117
+ if (word.endsWith("ed")) {
118
+ return word.slice(0, -2);
119
+ }
120
+ if (word.endsWith("er")) {
121
+ return word.slice(0, -2);
122
+ }
123
+ if (word.endsWith("es")) {
124
+ return word.slice(0, -2);
125
+ }
126
+ if (word.endsWith("al")) {
127
+ return word.slice(0, -2);
128
+ }
129
+ if (word.endsWith("ic")) {
130
+ return word.slice(0, -2);
131
+ }
132
+ if (word.endsWith("s") && !word.endsWith("ss")) {
133
+ return word.slice(0, -1);
134
+ }
135
+ return word;
136
+ }
137
+ /** Compute token overlap score between query tokens and text tokens. */
138
+ export function tokenOverlapScore(queryTokens, textTokens) {
139
+ if (queryTokens.length === 0 || textTokens.length === 0) {
140
+ return 0;
141
+ }
142
+ const stemmedText = new Set(textTokens.map(stemToken));
143
+ let matchCount = 0;
144
+ for (const queryToken of queryTokens) {
145
+ const stemmedQuery = stemToken(queryToken);
146
+ if (stemmedText.has(stemmedQuery)) {
147
+ matchCount += 1;
148
+ continue;
149
+ }
150
+ for (const textToken of stemmedText) {
151
+ if (textToken.startsWith(stemmedQuery) ||
152
+ stemmedQuery.startsWith(textToken)) {
153
+ matchCount += 0.5;
154
+ break;
155
+ }
156
+ }
157
+ }
158
+ return matchCount / queryTokens.length;
159
+ }
160
+ /**
161
+ * Extract character bigrams from text. Normalizes to lowercase, removes
162
+ * non-alphanumeric characters, and generates overlapping pairs.
163
+ */
164
+ export function bigramTokenize(text) {
165
+ const normalized = text.toLowerCase().replace(NON_ALPHANUMERIC_REGEX, "");
166
+ const bigrams = new Set();
167
+ for (let i = 0; i < normalized.length - 1; i++) {
168
+ bigrams.add(normalized.slice(i, i + 2));
169
+ }
170
+ return bigrams;
171
+ }
172
+ /**
173
+ * Extract word-level tokens from text (for coarser matching).
174
+ * Normalizes to lowercase, splits on non-alphanumeric.
175
+ */
176
+ export function wordTokenize(text) {
177
+ return text
178
+ .toLowerCase()
179
+ .split(TOKEN_SPLIT_REGEX)
180
+ .filter((token) => token.length > 1);
181
+ }
182
+ /** Jaccard similarity between two sets: |A ∩ B| / |A ∪ B|. */
183
+ export function jaccardSimilarity(setA, setB) {
184
+ if (setA.size === 0 && setB.size === 0) {
185
+ return 0;
186
+ }
187
+ let intersectionSize = 0;
188
+ const smaller = setA.size <= setB.size ? setA : setB;
189
+ const larger = setA.size <= setB.size ? setB : setA;
190
+ for (const item of smaller) {
191
+ if (larger.has(item)) {
192
+ intersectionSize++;
193
+ }
194
+ }
195
+ const unionSize = setA.size + setB.size - intersectionSize;
196
+ return unionSize === 0 ? 0 : intersectionSize / unionSize;
197
+ }
198
+ /** Exact word overlap score: fraction of type words found in input text. */
199
+ export function wordOverlapScore(inputWords, typeWords) {
200
+ if (typeWords.length === 0) {
201
+ return 0;
202
+ }
203
+ let matches = 0;
204
+ for (const word of typeWords) {
205
+ if (inputWords.includes(word)) {
206
+ matches++;
207
+ }
208
+ }
209
+ return matches / typeWords.length;
210
+ }
211
+ /** Pre-compute reusable lexical structures for a query. */
212
+ export function prepareLexicalQuery(query) {
213
+ return {
214
+ raw: query,
215
+ tokens: tokenizeSearchText(query),
216
+ words: wordTokenize(query),
217
+ bigrams: bigramTokenize(query),
218
+ };
219
+ }
220
+ /** Score a single lexical signal against a prepared query. */
221
+ export function scoreLexicalSignal(query, signal) {
222
+ const text = signal.text?.trim();
223
+ if (!text) {
224
+ return 0;
225
+ }
226
+ switch (signal.strategy ?? "tokenOverlap") {
227
+ case "bigramJaccard":
228
+ return jaccardSimilarity(query.bigrams, bigramTokenize(text));
229
+ case "wordOverlap":
230
+ return wordOverlapScore(query.words, wordTokenize(text));
231
+ default:
232
+ return tokenOverlapScore(query.tokens, tokenizeSearchText(text));
233
+ }
234
+ }
235
+ /** Weighted lexical score across multiple textual signals. */
236
+ export function scoreLexicalSignals(query, signals) {
237
+ let weightedScore = 0;
238
+ let totalWeight = 0;
239
+ for (const signal of signals) {
240
+ if (!signal.text?.trim() || signal.weight <= 0) {
241
+ continue;
242
+ }
243
+ weightedScore += scoreLexicalSignal(query, signal) * signal.weight;
244
+ totalWeight += signal.weight;
245
+ }
246
+ return totalWeight === 0 ? 0 : weightedScore / totalWeight;
247
+ }
248
+ /** Map a candidate's original rank position into a 0..1 prior. */
249
+ export function rankWindowScore(index, total) {
250
+ if (total <= 1) {
251
+ return 1;
252
+ }
253
+ const clampedIndex = Math.max(0, Math.min(index, total - 1));
254
+ return 1 - clampedIndex / (total - 1);
255
+ }
256
+ /** Rerank a candidate window by lexical overlap while preserving original-rank prior. */
257
+ export function rerankLexicalWindow(query, items, getText, options) {
258
+ const preparedQuery = prepareLexicalQuery(query);
259
+ if (preparedQuery.tokens.length === 0 || items.length <= 1) {
260
+ return items;
261
+ }
262
+ const lexicalWeight = options?.lexicalWeight ?? 0.65;
263
+ const rankWeight = options?.rankWeight ?? 0.35;
264
+ return items
265
+ .map((item, index) => {
266
+ const lexicalScore = scoreLexicalSignals(preparedQuery, [
267
+ { text: getText(item) ?? "", weight: 1, strategy: "tokenOverlap" },
268
+ ]);
269
+ const rankScore = rankWindowScore(index, items.length);
270
+ return {
271
+ item,
272
+ combinedScore: lexicalScore * lexicalWeight + rankScore * rankWeight,
273
+ };
274
+ })
275
+ .sort((left, right) => right.combinedScore - left.combinedScore)
276
+ .map(({ item }) => item);
277
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @lucern/contracts — topic-scope compat shim
3
+ *
4
+ * This file moved to ./v1/topics/v1.ts during EK-16 T1 PR 2.
5
+ * Retained here until the Lucern 1.0.0 barrel-sunset cut (D12).
6
+ * New code should import from "@lucern/contracts/v1/topics" directly.
7
+ */
8
+ export * from "./v1/topics/v1";
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @lucern/contracts — topic-scope compat shim
3
+ *
4
+ * This file moved to ./v1/topics/v1.ts during EK-16 T1 PR 2.
5
+ * Retained here until the Lucern 1.0.0 barrel-sunset cut (D12).
6
+ * New code should import from "@lucern/contracts/v1/topics" directly.
7
+ */
8
+ export * from "./v1/topics/v1.js";
@@ -0,0 +1,257 @@
1
+ /**
2
+ * Workflow Runtime Contract v1
3
+ *
4
+ * Canonical TypeScript contract for Lucern's graph-local workflow runtime.
5
+ * WF-1 defines the typed substrate for:
6
+ * - workflow definitions and run receipts
7
+ * - action mutation tiering and approval expectations
8
+ * - hooks over worktree/question/evidence/inbox events
9
+ * - output unions for domain-specific artifacts
10
+ * - deterministic integrity checks and operational metadata
11
+ *
12
+ * BREAKING CHANGE RULES:
13
+ * - Adding optional fields is NON-breaking
14
+ * - Removing fields or renaming enum values is BREAKING
15
+ * - Reclassifying a mutation tier is BREAKING
16
+ * - Changing canonical workflow IDs is BREAKING
17
+ */
18
+ export const WORKFLOW_RUNTIME_SCHEMA_VERSION = "1.0.0";
19
+ export const WORKFLOW_MUTATION_TIERS = [
20
+ "read_only",
21
+ "low_risk_write",
22
+ "high_risk_write",
23
+ ];
24
+ export const WORKFLOW_APPROVAL_MODES = [
25
+ "none",
26
+ "audit_only",
27
+ "human_required",
28
+ "auto_approve",
29
+ ];
30
+ export const DEFAULT_TIER_APPROVAL_MODE = {
31
+ read_only: "none",
32
+ low_risk_write: "audit_only",
33
+ high_risk_write: "human_required",
34
+ };
35
+ export const WORKFLOW_ACTION_KINDS = [
36
+ "context_pack",
37
+ "integrity_check",
38
+ "lucern_tool",
39
+ "report_compile",
40
+ "brief_publish",
41
+ "notification",
42
+ "custom",
43
+ ];
44
+ export const WORKFLOW_HOOK_EVENTS = [
45
+ "schedule.tick",
46
+ "worktree.activated",
47
+ "worktree.completed",
48
+ "question.created",
49
+ "question.answered",
50
+ "evidence.appended",
51
+ "inbox.item_created",
52
+ ];
53
+ export const WORKFLOW_OUTPUT_KINDS = [
54
+ "engineering_brief",
55
+ "research_memo",
56
+ "strategy_artifact",
57
+ "inbox_summary",
58
+ "pipeline_brief",
59
+ "structured_payload",
60
+ ];
61
+ export const WORKFLOW_RUN_STATUSES = [
62
+ "queued",
63
+ "running",
64
+ "awaiting_approval",
65
+ "completed",
66
+ "failed",
67
+ "cancelled",
68
+ ];
69
+ export const WORKFLOW_TRIGGER_KINDS = [
70
+ "manual",
71
+ "schedule",
72
+ "hook",
73
+ ];
74
+ export const WORKFLOW_PROOF_ARTIFACT_KINDS = [
75
+ "report",
76
+ "brief",
77
+ "artifact",
78
+ "dashboard",
79
+ "test_evidence",
80
+ ];
81
+ export const WORKFLOW_STAFFING_HINTS = [
82
+ "solo",
83
+ "backend+tests",
84
+ "fullstack",
85
+ "mcp+tests",
86
+ ];
87
+ export const WORKFLOW_AUTO_FIX_MODES = [
88
+ "disabled",
89
+ "dry_run",
90
+ "safe",
91
+ "aggressive",
92
+ ];
93
+ export const WORKFLOW_INTEGRITY_CHECKS = [
94
+ "null_dependency_refs",
95
+ "superseded_blockers",
96
+ "band_order_inconsistency",
97
+ "sparse_shaping",
98
+ "failed_completed_gate",
99
+ ];
100
+ export const DEFAULT_WORKFLOW_AUTO_FIX_POLICY = {
101
+ mode: "disabled",
102
+ permittedMutationTiers: ["read_only"],
103
+ requireAuditTrail: true,
104
+ };
105
+ export const NIGHTLY_RECONCILIATION_WORKFLOW_ID = "workflow.pipeline_reconciliation.v1";
106
+ export const MORNING_BRIEF_WORKFLOW_ID = "workflow.morning_brief.v1";
107
+ export const CANONICAL_WORKFLOW_DEFINITIONS = [
108
+ {
109
+ workflowId: NIGHTLY_RECONCILIATION_WORKFLOW_ID,
110
+ version: WORKFLOW_RUNTIME_SCHEMA_VERSION,
111
+ title: "Nightly Pipeline Reconciliation",
112
+ description: "Runs deterministic integrity checks, compiles pipeline state, and emits an operator-facing reconciliation brief.",
113
+ trigger: {
114
+ kind: "schedule",
115
+ cadence: "daily",
116
+ timezone: "America/New_York",
117
+ },
118
+ staffingHint: "backend+tests",
119
+ proofArtifacts: [
120
+ {
121
+ kind: "report",
122
+ label: "Pipeline reconciliation report",
123
+ required: true,
124
+ },
125
+ {
126
+ kind: "test_evidence",
127
+ label: "Integrity check receipt",
128
+ required: true,
129
+ },
130
+ ],
131
+ autoFixPolicy: {
132
+ mode: "safe",
133
+ maxActionsPerRun: 5,
134
+ permittedMutationTiers: ["read_only", "low_risk_write"],
135
+ requireAuditTrail: true,
136
+ escalationGate: "gate:workflow-runtime-contract-live",
137
+ },
138
+ actions: [
139
+ {
140
+ actionId: "compile_context_pack",
141
+ kind: "context_pack",
142
+ title: "Compile pipeline context",
143
+ description: "Build the ranked context needed for deterministic checks.",
144
+ mutationTier: "read_only",
145
+ produces: ["structured_payload"],
146
+ idempotent: true,
147
+ approval: { mode: "none" },
148
+ },
149
+ {
150
+ actionId: "run_integrity_checks",
151
+ kind: "integrity_check",
152
+ title: "Run integrity checks",
153
+ description: "Evaluate dependency references, blockers, execution bands, shaping coverage, and completed gates.",
154
+ mutationTier: "read_only",
155
+ produces: ["structured_payload"],
156
+ idempotent: true,
157
+ approval: { mode: "none" },
158
+ },
159
+ {
160
+ actionId: "record_followup_questions",
161
+ kind: "lucern_tool",
162
+ title: "Record follow-up questions",
163
+ description: "Create or reopen operator-facing questions for integrity failures that require human review.",
164
+ mutationTier: "low_risk_write",
165
+ toolName: "create_question",
166
+ produces: ["pipeline_brief"],
167
+ approval: { mode: "audit_only", rationaleRequired: true },
168
+ },
169
+ {
170
+ actionId: "publish_reconciliation_brief",
171
+ kind: "brief_publish",
172
+ title: "Publish reconciliation brief",
173
+ description: "Emit an inbox-routed brief summarizing the nightly pipeline state and grouped blockers.",
174
+ mutationTier: "low_risk_write",
175
+ produces: ["pipeline_brief", "inbox_summary"],
176
+ approval: { mode: "audit_only" },
177
+ },
178
+ ],
179
+ hooks: [
180
+ {
181
+ hookId: "nightly-schedule",
182
+ event: "schedule.tick",
183
+ description: "Run once per nightly cadence.",
184
+ actionIds: [
185
+ "compile_context_pack",
186
+ "run_integrity_checks",
187
+ "record_followup_questions",
188
+ "publish_reconciliation_brief",
189
+ ],
190
+ },
191
+ ],
192
+ outputs: ["pipeline_brief", "inbox_summary", "structured_payload"],
193
+ integrityChecks: WORKFLOW_INTEGRITY_CHECKS,
194
+ },
195
+ {
196
+ workflowId: MORNING_BRIEF_WORKFLOW_ID,
197
+ version: WORKFLOW_RUNTIME_SCHEMA_VERSION,
198
+ title: "Morning Brief",
199
+ description: "Compiles a developer-facing morning brief from graph state, overnight workflow outputs, and inbox routing preferences.",
200
+ trigger: {
201
+ kind: "schedule",
202
+ cadence: "daily",
203
+ timezone: "America/New_York",
204
+ },
205
+ staffingHint: "solo",
206
+ proofArtifacts: [
207
+ {
208
+ kind: "brief",
209
+ label: "Morning brief",
210
+ required: true,
211
+ },
212
+ ],
213
+ autoFixPolicy: {
214
+ mode: "dry_run",
215
+ maxActionsPerRun: 1,
216
+ permittedMutationTiers: ["read_only", "low_risk_write"],
217
+ requireAuditTrail: true,
218
+ },
219
+ actions: [
220
+ {
221
+ actionId: "compile_brief_inputs",
222
+ kind: "context_pack",
223
+ title: "Compile brief inputs",
224
+ description: "Read graph state, worktree state, and overnight workflow receipts.",
225
+ mutationTier: "read_only",
226
+ produces: ["structured_payload"],
227
+ idempotent: true,
228
+ approval: { mode: "none" },
229
+ },
230
+ {
231
+ actionId: "publish_morning_brief",
232
+ kind: "brief_publish",
233
+ title: "Publish morning brief",
234
+ description: "Publish a typed inbox summary with prioritized worktree and question context.",
235
+ mutationTier: "low_risk_write",
236
+ produces: ["engineering_brief", "inbox_summary"],
237
+ approval: { mode: "audit_only" },
238
+ },
239
+ ],
240
+ hooks: [
241
+ {
242
+ hookId: "morning-schedule",
243
+ event: "schedule.tick",
244
+ description: "Run once per morning cadence.",
245
+ actionIds: ["compile_brief_inputs", "publish_morning_brief"],
246
+ },
247
+ {
248
+ hookId: "worktree-complete-refresh",
249
+ event: "worktree.completed",
250
+ description: "Refresh the queued morning brief inputs when worktree outcomes land overnight.",
251
+ actionIds: ["compile_brief_inputs"],
252
+ },
253
+ ],
254
+ outputs: ["engineering_brief", "inbox_summary", "structured_payload"],
255
+ integrityChecks: ["sparse_shaping"],
256
+ },
257
+ ];
@@ -0,0 +1 @@
1
+ export * from "./lib/platform/sdk/realtime/refs";
@@ -0,0 +1 @@
1
+ export * from "./lib/platform/sdk/realtime/refs.js";
@@ -0,0 +1 @@
1
+ export * from "./lib/platform/sdk/realtime/index";
@@ -0,0 +1 @@
1
+ export * from "./lib/platform/sdk/realtime/index.js";
package/package.json CHANGED
@@ -1,20 +1,28 @@
1
1
  {
2
2
  "name": "@lucern/sdk",
3
- "version": "0.2.0-alpha.4",
3
+ "version": "0.2.0-alpha.6",
4
4
  "description": "Lucern reasoning platform SDK. Install this one package, provide your API key, and start building in 10 minutes.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
8
8
  "module": "./dist/index.js",
9
- "types": "./dist/packages/sdk/src/index.d.ts",
9
+ "types": "./dist/index.d.ts",
10
10
  "files": [
11
11
  "dist",
12
12
  "README.md"
13
13
  ],
14
14
  "exports": {
15
15
  ".": {
16
- "types": "./dist/packages/sdk/src/index.d.ts",
16
+ "types": "./dist/index.d.ts",
17
17
  "import": "./dist/index.js"
18
+ },
19
+ "./realtime": {
20
+ "types": "./dist/realtime.d.ts",
21
+ "import": "./dist/realtime.js"
22
+ },
23
+ "./realtime/refs": {
24
+ "types": "./dist/realtime-refs.d.ts",
25
+ "import": "./dist/realtime-refs.js"
18
26
  }
19
27
  },
20
28
  "sideEffects": false,
@@ -22,18 +30,23 @@
22
30
  "node": ">=18.0.0"
23
31
  },
24
32
  "scripts": {
25
- "build": "tsup && tsc --project tsconfig.bundle.json --declaration --emitDeclarationOnly --outDir dist",
33
+ "build": "bash -lc 'cd ../../.. && npx tsx scripts/build-sdk-package.ts'",
26
34
  "build:js": "tsup",
27
35
  "build:dts": "tsc --project tsconfig.bundle.json --declaration --emitDeclarationOnly --outDir dist",
28
36
  "pack:dry-run": "npm pack --dry-run",
37
+ "prepack": "npm run build",
29
38
  "typecheck": "tsc --project tsconfig.json --noEmit"
30
39
  },
31
40
  "peerDependencies": {
32
- "convex": ">=1.0.0"
41
+ "convex": ">=1.0.0",
42
+ "react": "^18.0.0 || ^19.0.0-0 || ^19.0.0"
33
43
  },
34
44
  "peerDependenciesMeta": {
35
45
  "convex": {
36
46
  "optional": true
47
+ },
48
+ "react": {
49
+ "optional": true
37
50
  }
38
51
  },
39
52
  "devDependencies": {