@lucern/sdk 0.3.0-alpha.16 → 0.3.0-alpha.2

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 (227) hide show
  1. package/CHANGELOG.md +0 -8
  2. package/README.md +4 -110
  3. package/dist/adminClient.d.ts +8 -10
  4. package/dist/adminClient.js +39 -260
  5. package/dist/adminClient.js.map +1 -1
  6. package/dist/answersClient.d.ts +0 -2
  7. package/dist/answersClient.js +11 -239
  8. package/dist/answersClient.js.map +1 -1
  9. package/dist/audience/index.d.ts +1 -2
  10. package/dist/audience/index.js +3 -1
  11. package/dist/audience/index.js.map +1 -1
  12. package/dist/audiencesClient.d.ts +16 -18
  13. package/dist/audiencesClient.js +90 -315
  14. package/dist/audiencesClient.js.map +1 -1
  15. package/dist/auditClient.d.ts +0 -2
  16. package/dist/auditClient.js +15 -245
  17. package/dist/auditClient.js.map +1 -1
  18. package/dist/beliefs/index.d.ts +5 -27
  19. package/dist/beliefs/index.js +1177 -3842
  20. package/dist/beliefs/index.js.map +1 -1
  21. package/dist/beliefsClient.d.ts +2 -4
  22. package/dist/beliefsClient.js +26 -248
  23. package/dist/beliefsClient.js.map +1 -1
  24. package/dist/client-B6aWUUwp.d.ts +2552 -0
  25. package/dist/client.d.ts +27 -3041
  26. package/dist/client.js +1177 -3842
  27. package/dist/client.js.map +1 -1
  28. package/dist/contextClient.d.ts +3 -6
  29. package/dist/contextClient.js +30 -270
  30. package/dist/contextClient.js.map +1 -1
  31. package/dist/contextFacade.js +16 -25
  32. package/dist/contextFacade.js.map +1 -1
  33. package/dist/contextPackCompiler.js +30 -19
  34. package/dist/contextPackCompiler.js.map +1 -1
  35. package/dist/contextPackPolicy.js +17 -7
  36. package/dist/contextPackPolicy.js.map +1 -1
  37. package/dist/contextTypes.d.ts +0 -2
  38. package/dist/contracts/api-enums.contract.d.ts +2 -2
  39. package/dist/contracts/api-enums.contract.js +1 -6
  40. package/dist/contracts/api-enums.contract.js.map +1 -1
  41. package/dist/contracts/auth-session.contract.d.ts +1 -1
  42. package/dist/contracts/auth-session.contract.js +1 -13
  43. package/dist/contracts/auth-session.contract.js.map +1 -1
  44. package/dist/contracts/index.d.ts +0 -1
  45. package/dist/contracts/index.js +6 -133
  46. package/dist/contracts/index.js.map +1 -1
  47. package/dist/contracts/lens-filter.contract.js +3 -4
  48. package/dist/contracts/lens-filter.contract.js.map +1 -1
  49. package/dist/contracts/lens-workflow.contract.js +3 -4
  50. package/dist/contracts/lens-workflow.contract.js.map +1 -1
  51. package/dist/contracts/lensFilter.js +3 -4
  52. package/dist/contracts/lensFilter.js.map +1 -1
  53. package/dist/contracts/lensWorkflow.js +3 -4
  54. package/dist/contracts/lensWorkflow.js.map +1 -1
  55. package/dist/contracts/mcpTools.d.ts +1 -46
  56. package/dist/contracts/mcpTools.js +0 -108
  57. package/dist/contracts/mcpTools.js.map +1 -1
  58. package/dist/contradictions/index.d.ts +4 -26
  59. package/dist/contradictions/index.js +1177 -3842
  60. package/dist/contradictions/index.js.map +1 -1
  61. package/dist/coreClient.d.ts +2 -28
  62. package/dist/coreClient.js +14 -240
  63. package/dist/coreClient.js.map +1 -1
  64. package/dist/decisions/index.d.ts +14 -36
  65. package/dist/decisions/index.js +1177 -3842
  66. package/dist/decisions/index.js.map +1 -1
  67. package/dist/decisionsClient.d.ts +12 -6
  68. package/dist/decisionsClient.js +37 -253
  69. package/dist/decisionsClient.js.map +1 -1
  70. package/dist/edges/index.d.ts +87 -49
  71. package/dist/edges/index.js +1177 -3842
  72. package/dist/edges/index.js.map +1 -1
  73. package/dist/events.js +3 -6
  74. package/dist/events.js.map +1 -1
  75. package/dist/eventsCore.d.ts +1 -3
  76. package/dist/eventsCore.js +14 -240
  77. package/dist/eventsCore.js.map +1 -1
  78. package/dist/evidence/index.d.ts +4 -26
  79. package/dist/evidence/index.js +1177 -3842
  80. package/dist/evidence/index.js.map +1 -1
  81. package/dist/evidenceClient.d.ts +0 -2
  82. package/dist/evidenceClient.js +14 -240
  83. package/dist/evidenceClient.js.map +1 -1
  84. package/dist/facade/context.d.ts +1 -2
  85. package/dist/facade/context.js +16 -25
  86. package/dist/facade/context.js.map +1 -1
  87. package/dist/gatewayFacades.d.ts +46 -90
  88. package/dist/gatewayFacades.js +128 -609
  89. package/dist/gatewayFacades.js.map +1 -1
  90. package/dist/graphClient.d.ts +13 -8
  91. package/dist/graphClient.js +45 -262
  92. package/dist/graphClient.js.map +1 -1
  93. package/dist/harnessClient.d.ts +24 -15
  94. package/dist/harnessClient.js +42 -253
  95. package/dist/harnessClient.js.map +1 -1
  96. package/dist/identityClient.d.ts +11 -115
  97. package/dist/identityClient.js +33 -555
  98. package/dist/identityClient.js.map +1 -1
  99. package/dist/index.d.ts +6 -32
  100. package/dist/index.js +2580 -5825
  101. package/dist/index.js.map +1 -1
  102. package/dist/learningClient.d.ts +6 -8
  103. package/dist/learningClient.js +44 -270
  104. package/dist/learningClient.js.map +1 -1
  105. package/dist/lenses/index.d.ts +38 -78
  106. package/dist/lenses/index.js +1177 -3842
  107. package/dist/lenses/index.js.map +1 -1
  108. package/dist/nodes/index.d.ts +21 -65
  109. package/dist/nodes/index.js +1177 -3842
  110. package/dist/nodes/index.js.map +1 -1
  111. package/dist/ontologies/index.d.ts +32 -55
  112. package/dist/ontologies/index.js +1177 -3842
  113. package/dist/ontologies/index.js.map +1 -1
  114. package/dist/ontologyClient.d.ts +25 -19
  115. package/dist/ontologyClient.js +40 -276
  116. package/dist/ontologyClient.js.map +1 -1
  117. package/dist/packsClient.d.ts +23 -11
  118. package/dist/packsClient.js +46 -252
  119. package/dist/packsClient.js.map +1 -1
  120. package/dist/policyClient.d.ts +10 -13
  121. package/dist/policyClient.js +25 -261
  122. package/dist/policyClient.js.map +1 -1
  123. package/dist/questions/index.d.ts +4 -26
  124. package/dist/questions/index.js +1177 -3842
  125. package/dist/questions/index.js.map +1 -1
  126. package/dist/realtime/index.d.ts +1 -1
  127. package/dist/reportsClient.d.ts +7 -9
  128. package/dist/reportsClient.js +53 -299
  129. package/dist/reportsClient.js.map +1 -1
  130. package/dist/schemaClient.d.ts +3 -5
  131. package/dist/schemaClient.js +29 -253
  132. package/dist/schemaClient.js.map +1 -1
  133. package/dist/sdkSurface.d.ts +3 -8
  134. package/dist/sdkSurface.js +6 -10
  135. package/dist/sdkSurface.js.map +1 -1
  136. package/dist/sourcesClient.d.ts +0 -2
  137. package/dist/sourcesClient.js +14 -240
  138. package/dist/sourcesClient.js.map +1 -1
  139. package/dist/topics/index.d.ts +9 -37
  140. package/dist/topics/index.js +1177 -3844
  141. package/dist/topics/index.js.map +1 -1
  142. package/dist/topicsClient.d.ts +0 -4
  143. package/dist/topicsClient.js +24 -255
  144. package/dist/topicsClient.js.map +1 -1
  145. package/dist/types.d.ts +0 -17
  146. package/dist/version.d.ts +1 -1
  147. package/dist/version.js +1 -1
  148. package/dist/version.js.map +1 -1
  149. package/dist/workflowClient.d.ts +40 -60
  150. package/dist/workflowClient.js +58 -261
  151. package/dist/workflowClient.js.map +1 -1
  152. package/dist/worktrees/index.d.ts +33 -71
  153. package/dist/worktrees/index.js +1177 -3842
  154. package/dist/worktrees/index.js.map +1 -1
  155. package/package.json +3 -17
  156. package/dist/accessControl.d.ts +0 -79
  157. package/dist/accessControl.js +0 -1270
  158. package/dist/accessControl.js.map +0 -1
  159. package/dist/authContext.d.ts +0 -56
  160. package/dist/authContext.js +0 -170
  161. package/dist/authContext.js.map +0 -1
  162. package/dist/authDeviceClient.d.ts +0 -49
  163. package/dist/authDeviceClient.js +0 -121
  164. package/dist/authDeviceClient.js.map +0 -1
  165. package/dist/boundaryClientSurface.d.ts +0 -20
  166. package/dist/boundaryClientSurface.js +0 -73
  167. package/dist/boundaryClientSurface.js.map +0 -1
  168. package/dist/clientHelpers.d.ts +0 -48
  169. package/dist/clientHelpers.js +0 -137
  170. package/dist/clientHelpers.js.map +0 -1
  171. package/dist/control-plane.d.ts +0 -69
  172. package/dist/control-plane.js +0 -674
  173. package/dist/control-plane.js.map +0 -1
  174. package/dist/embeddingsClient.d.ts +0 -106
  175. package/dist/embeddingsClient.js +0 -749
  176. package/dist/embeddingsClient.js.map +0 -1
  177. package/dist/eventingClient.d.ts +0 -96
  178. package/dist/eventingClient.js +0 -746
  179. package/dist/eventingClient.js.map +0 -1
  180. package/dist/functionSurface.d.ts +0 -144
  181. package/dist/functionSurface.js +0 -1227
  182. package/dist/functionSurface.js.map +0 -1
  183. package/dist/functionSurfaceClient.d.ts +0 -8
  184. package/dist/functionSurfaceClient.js +0 -1227
  185. package/dist/functionSurfaceClient.js.map +0 -1
  186. package/dist/graphAnalysisClient.d.ts +0 -192
  187. package/dist/graphAnalysisClient.js +0 -817
  188. package/dist/graphAnalysisClient.js.map +0 -1
  189. package/dist/graphIntel.d.ts +0 -4
  190. package/dist/graphIntel.js +0 -3
  191. package/dist/graphIntel.js.map +0 -1
  192. package/dist/graphIntelligence.d.ts +0 -2
  193. package/dist/graphIntelligence.js +0 -47
  194. package/dist/graphIntelligence.js.map +0 -1
  195. package/dist/graphRecommendationsClient.d.ts +0 -56
  196. package/dist/graphRecommendationsClient.js +0 -682
  197. package/dist/graphRecommendationsClient.js.map +0 -1
  198. package/dist/graphStateClassifierClient.d.ts +0 -73
  199. package/dist/graphStateClassifierClient.js +0 -734
  200. package/dist/graphStateClassifierClient.js.map +0 -1
  201. package/dist/infisicalRuntime.d.ts +0 -43
  202. package/dist/infisicalRuntime.js +0 -346
  203. package/dist/infisicalRuntime.js.map +0 -1
  204. package/dist/jobsClient.d.ts +0 -98
  205. package/dist/jobsClient.js +0 -744
  206. package/dist/jobsClient.js.map +0 -1
  207. package/dist/mcpClient.d.ts +0 -28
  208. package/dist/mcpClient.js +0 -687
  209. package/dist/mcpClient.js.map +0 -1
  210. package/dist/modelRuntimeClient.d.ts +0 -72
  211. package/dist/modelRuntimeClient.js +0 -722
  212. package/dist/modelRuntimeClient.js.map +0 -1
  213. package/dist/ontologyLinksClient.d.ts +0 -71
  214. package/dist/ontologyLinksClient.js +0 -715
  215. package/dist/ontologyLinksClient.js.map +0 -1
  216. package/dist/orgGraphSearchClient.d.ts +0 -85
  217. package/dist/orgGraphSearchClient.js +0 -690
  218. package/dist/orgGraphSearchClient.js.map +0 -1
  219. package/dist/secrets.d.ts +0 -1
  220. package/dist/secrets.js +0 -3
  221. package/dist/secrets.js.map +0 -1
  222. package/dist/telemetryClient.d.ts +0 -94
  223. package/dist/telemetryClient.js +0 -759
  224. package/dist/telemetryClient.js.map +0 -1
  225. package/dist/toolRegistryClient.d.ts +0 -115
  226. package/dist/toolRegistryClient.js +0 -785
  227. package/dist/toolRegistryClient.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -5,14 +5,6 @@ All notable changes to `@lucern/sdk` will be documented in this file.
5
5
  ## [Unreleased]
6
6
  - No unreleased changes yet.
7
7
 
8
- ## [0.3.0-alpha.16] - 2026-05-14
9
- - Adds the exact-row reasoning-kernel migration surface required for tenant identity/scope repairs.
10
- - Keeps the coherent Lucern package line aligned for StackOS and reasoning-environment adoption.
11
-
12
-
13
- ## [0.3.0-alpha.7] - 2026-05-03
14
- - Rebuild the coherent Lucern package line after Campaign 1 SDK hardening fixes.
15
-
16
8
  ## [0.2.0-alpha.5] - 2026-04-18
17
9
  - Refresh publish from current stackos source under EK-16 T4.
18
10
  - Version-numbering note: 0.2.0-alpha.2 through 0.2.0-alpha.5 were published from earlier stackos source on 2026-04-12 by pete_c. This release (alpha.5) is the first to ship the current April 18 source — 56 commits of accumulated changes from the code-separation track.
package/README.md CHANGED
@@ -10,31 +10,6 @@ Lucern gives your agents a reasoning graph that accumulates understanding across
10
10
  npm install @lucern/sdk
11
11
  ```
12
12
 
13
- ## Install Model
14
-
15
- `@lucern/sdk` is the primary TypeScript app dependency. Installing it also
16
- installs its internal runtime dependencies, including Lucern contracts and
17
- reasoning-kernel helpers, but a tenant should still list any `@lucern/*`
18
- package that its own code or scripts import or execute.
19
-
20
- Common direct installs:
21
-
22
- | Need | Install |
23
- | --- | --- |
24
- | Programmatic Lucern API calls | `@lucern/sdk` |
25
- | Tool access checks | `@lucern/access-control` |
26
- | React hooks/components | `@lucern/react @lucern/sdk` |
27
- | Convex component binding | `@lucern/control-plane @lucern/reasoning-kernel` |
28
- | Bootstrap, auth, doctor, and operator commands | `@lucern/cli` |
29
- | Agent-facing MCP server/runtime | `@lucern/mcp` |
30
- | Full design-partner/package-suite pin | all packages from `TENANT_CLIENT_INSTALLABLE_PACKAGES` in `@lucern/contracts` |
31
-
32
- The difference matters: `@lucern/cli` is a direct install because it provides
33
- the `lucern` binary, but tenant app source should not import it. The Convex
34
- component packages are direct installs for `convex.config.ts`, while application
35
- code should stay on `@lucern/sdk`, `@lucern/react`, `@lucern/mcp`,
36
- `@lucern/access-control`, `@lucern/contracts`, and `@lucern/types`.
37
-
38
13
  ## Canonical Interface
39
14
 
40
15
  `@lucern/sdk` is the canonical public interface for Lucern.
@@ -42,9 +17,6 @@ code should stay on `@lucern/sdk`, `@lucern/react`, `@lucern/mcp`,
42
17
  - Build applications, automations, and backend integrations against the SDK first.
43
18
  - Treat `/api/platform/v1/*` as the transport mirror of the SDK surface.
44
19
  - Treat MCP as an agent-facing client of the same surface, not as a privileged bypass around SDK or HTTP semantics.
45
- - Treat REST, SDK, CLI, and MCP as projections of the same manifest. New
46
- control-plane operations must be added to the manifest first, then exposed
47
- through the generated surfaces.
48
20
 
49
21
  IA-7 closes the remaining SDK surface gaps needed for SDK-first clients:
50
22
 
@@ -70,62 +42,6 @@ const identity = await lucern.identity.whoami();
70
42
  const principal: SdkPrincipalContext = identity.data;
71
43
  ```
72
44
 
73
- ### Control-Plane Tenant Bootstrap
74
-
75
- Interactive tenant applications should resolve Clerk users through the Lucern
76
- control-plane identity surface before making workspace-scoped graph calls. Clerk
77
- proves the browser user's identity; Lucern authorization comes from the
78
- Permit-backed control-plane projection.
79
-
80
- ```typescript
81
- import { createLucernClient } from "@lucern/sdk";
82
-
83
- async function createLucernForClerkUser(args: {
84
- clerkUserId: string;
85
- getClerkToken: () => Promise<string | null>;
86
- tenantId: string;
87
- workspaceId: string;
88
- clerkProjectId?: string;
89
- }) {
90
- const token = await args.getClerkToken();
91
- if (!token) {
92
- throw new Error("Clerk session token is required.");
93
- }
94
-
95
- const getAuthHeaders = () => ({ Authorization: `Bearer ${token}` });
96
- const lucern = createLucernClient({
97
- baseUrl: "https://api.lucern.ai",
98
- getAuthHeaders,
99
- });
100
-
101
- const principal =
102
- await lucern.controlPlane.identity.resolveInteractivePrincipal({
103
- clerkId: args.clerkUserId,
104
- tenantId: args.tenantId,
105
- workspaceId: args.workspaceId,
106
- providerProjectId: args.clerkProjectId,
107
- });
108
-
109
- return createLucernClient({
110
- baseUrl: "https://api.lucern.ai",
111
- getAuthHeaders,
112
- authContext: principal.data,
113
- });
114
- }
115
- ```
116
-
117
- Use `authContext.principalId`, roles, scopes, groups, permitted tools, and
118
- Permit subject data as the runtime Lucern principal context. Tenant apps must
119
- not read legacy `users.mcRole` / `defaultTenantId` fields as authorization, and
120
- they must not call `components.controlPlane.migration` from application code.
121
- Provisioning and backfills can use migration APIs; runtime bootstrapping uses
122
- `controlPlane.identity.resolveInteractivePrincipal(...)`.
123
-
124
- StackOS, Lucern Graph, and Stack Engineering should use this bootstrap path
125
- before calling morning brief, graph session, MCP, or CLI-backed runtime flows.
126
- `/api/platform/v1/users/:clerkId` may be a profile facade, but it is not an
127
- authorization source.
128
-
129
45
  ## The Full Developer Journey
130
46
 
131
47
  This walkthrough mirrors what a developer building an AI-powered code review system would experience in a real coding session. Every API call is something you would actually use.
@@ -385,7 +301,7 @@ await lucern.graph.createEdge({
385
301
  Before your agent starts its next session, it reads the graph:
386
302
 
387
303
  ```typescript
388
- const context = await lucern.context.compile({
304
+ const context = await lucern.context.compile(topicId, {
389
305
  query: "code review strategy and static analysis coverage",
390
306
  ranking: "weighted_v1",
391
307
  tokenBudget: 2000,
@@ -447,28 +363,6 @@ lucern.identity // API keys and sessions
447
363
 
448
364
  The graph doesn't just store knowledge — it analyzes itself.
449
365
 
450
- ### Query Suite
451
-
452
- ```typescript
453
- // Discover the prompt-backed Graph Intelligence recipes tenants can expose in
454
- // their own UI or model workflows.
455
- const catalog = await lucern.graphAnalysis.listGraphIntelligenceQueries();
456
-
457
- // Run a named recipe. Lucern returns the resolved prompt, deterministic graph
458
- // analysis bundle, sampled graph context, and public tool plan for LLM synthesis.
459
- const preMortem = await lucern.graphAnalysis.runGraphIntelligenceQuery({
460
- topicId,
461
- queryId: "pre-mortem",
462
- limit: 25,
463
- });
464
-
465
- await modelMachine.run({
466
- prompt: preMortem.data.prompt,
467
- context: preMortem.data.analysis,
468
- tools: preMortem.data.toolPlan,
469
- });
470
- ```
471
-
472
366
  ### Structural Analysis
473
367
 
474
368
  ```typescript
@@ -551,7 +445,7 @@ traversal.data.nodes.forEach(node => {
551
445
  ### Inject Reasoning Context Into Any LLM Call
552
446
 
553
447
  ```typescript
554
- const context = await lucern.context.compile({
448
+ const context = await lucern.context.compile(topicId, {
555
449
  query: "security review priorities",
556
450
  ranking: "weighted_v1",
557
451
  tokenBudget: 3000,
@@ -662,7 +556,7 @@ architectural decisions, check the reasoning graph:
662
556
 
663
557
  - Read current beliefs: `lucern.beliefs.list({ topicId: "..." })`
664
558
  - Check for contradictions: `lucern.contradictions.list({ topicId: "..." })`
665
- - Compile context before analysis: `lucern.context.compile({ query: "..." })`
559
+ - Compile context before analysis: `lucern.context.compile(topicId, { query: "..." })`
666
560
 
667
561
  After making decisions, write them back:
668
562
  - Create beliefs for architectural decisions
@@ -693,7 +587,7 @@ contradictions, or knowledge state.
693
587
  Compile the current context to understand what the graph knows:
694
588
 
695
589
  \`\`\`typescript
696
- const context = await lucern.context.compile({
590
+ const context = await lucern.context.compile(topicId, {
697
591
  query: "<what you're working on>",
698
592
  tokenBudget: 2000,
699
593
  });
@@ -2,8 +2,6 @@ import { GatewayClientConfig, PlatformGatewaySuccess, GatewayScope } from './cor
2
2
  export { LucernApiError } from './coreClient.js';
3
3
  import { ListResult, JsonObject } from './types.js';
4
4
  import { ControlObjectOwnershipContract } from './controlObjectOwnership.js';
5
- import './authContext.js';
6
- import './contracts/auth-session.contract.js';
7
5
  import './contracts/workflow-runtime.contract.js';
8
6
  import './contracts/lens-workflow.contract.js';
9
7
  import './contracts/lens-filter.contract.js';
@@ -153,11 +151,11 @@ declare function createAdminClient(config?: AdminClientConfig): {
153
151
  /**
154
152
  * Get the control-object ownership contract.
155
153
  */
156
- getControlObjectOwnership: () => Promise<PlatformGatewaySuccess<ControlObjectOwnershipContract>>;
154
+ getControlObjectOwnership(): Promise<PlatformGatewaySuccess<ControlObjectOwnershipContract>>;
157
155
  /**
158
156
  * @deprecated Use getControlObjectOwnership.
159
157
  */
160
- getControlObjectOwnershipContract: () => Promise<PlatformGatewaySuccess<ControlObjectOwnershipContract>>;
158
+ getControlObjectOwnershipContract(): Promise<PlatformGatewaySuccess<ControlObjectOwnershipContract>>;
161
159
  /**
162
160
  * List workspaces for the current admin scope.
163
161
  */
@@ -190,33 +188,33 @@ declare function createAdminClient(config?: AdminClientConfig): {
190
188
  /**
191
189
  * Create a membership.
192
190
  */
193
- createMembership: (input: GatewayScope & {
191
+ createMembership(input: GatewayScope & {
194
192
  membershipId?: string;
195
193
  principalId: string;
196
194
  role: "platform_admin" | "tenant_admin" | "workspace_admin" | "editor" | "viewer" | "auditor" | "service_agent";
197
195
  status?: "active" | "invited" | "revoked" | "expired";
198
196
  source?: "bootstrap" | "manual" | "sync" | "sso" | "api" | "scim" | "invitation";
199
- }, idempotencyKey?: string) => Promise<PlatformGatewaySuccess<unknown>>;
197
+ }, idempotencyKey?: string): Promise<PlatformGatewaySuccess<unknown>>;
200
198
  /**
201
199
  * Update a membership.
202
200
  */
203
- updateMembership: (input: GatewayScope & {
201
+ updateMembership(input: GatewayScope & {
204
202
  membershipId?: string;
205
203
  principalId: string;
206
204
  role: "platform_admin" | "tenant_admin" | "workspace_admin" | "editor" | "viewer" | "auditor" | "service_agent";
207
205
  status?: "active" | "invited" | "revoked" | "expired";
208
206
  source?: "bootstrap" | "manual" | "sync" | "sso" | "api" | "scim" | "invitation";
209
- }, idempotencyKey?: string) => Promise<PlatformGatewaySuccess<unknown>>;
207
+ }, idempotencyKey?: string): Promise<PlatformGatewaySuccess<unknown>>;
210
208
  /**
211
209
  * @deprecated Use createMembership or updateMembership.
212
210
  */
213
- upsertMembership: (input: GatewayScope & {
211
+ upsertMembership(input: GatewayScope & {
214
212
  membershipId?: string;
215
213
  principalId: string;
216
214
  role: "platform_admin" | "tenant_admin" | "workspace_admin" | "editor" | "viewer" | "auditor" | "service_agent";
217
215
  status?: "active" | "invited" | "revoked" | "expired";
218
216
  source?: "bootstrap" | "manual" | "sync" | "sso" | "api" | "scim" | "invitation";
219
- }, idempotencyKey?: string) => Promise<PlatformGatewaySuccess<unknown>>;
217
+ }, idempotencyKey?: string): Promise<PlatformGatewaySuccess<unknown>>;
220
218
  /**
221
219
  * List tenant API keys in the current admin scope.
222
220
  */
@@ -1,170 +1,3 @@
1
- // src/authContext.ts
2
- var LucernSdkAuthContextError = class extends Error {
3
- reason;
4
- constructor(reason, message) {
5
- super(message);
6
- this.name = "LucernSdkAuthContextError";
7
- this.reason = reason;
8
- }
9
- };
10
- function cleanString(value) {
11
- const normalized = value?.trim();
12
- return normalized ? normalized : void 0;
13
- }
14
- function cleanStringList(values) {
15
- if (!values) {
16
- return [];
17
- }
18
- return values.map((value) => value.trim()).filter(
19
- (value, index, list) => value.length > 0 && list.indexOf(value) === index
20
- );
21
- }
22
- function requireString(value, reason, label) {
23
- const normalized = cleanString(value);
24
- if (!normalized) {
25
- throw new LucernSdkAuthContextError(
26
- reason,
27
- `Canonical Lucern SDK auth context is missing ${label}.`
28
- );
29
- }
30
- return normalized;
31
- }
32
- function requirePrincipalType(principalType) {
33
- if (!principalType) {
34
- throw new LucernSdkAuthContextError(
35
- "principal_missing",
36
- "Canonical Lucern SDK auth context is missing principalType."
37
- );
38
- }
39
- return principalType;
40
- }
41
- function requireAuthMode(authMode) {
42
- if (!authMode) {
43
- throw new LucernSdkAuthContextError(
44
- "principal_missing",
45
- "Canonical Lucern SDK auth context is missing authMode."
46
- );
47
- }
48
- return authMode;
49
- }
50
- function ensurePermitMatch(args) {
51
- const actual = cleanString(args.actual);
52
- if (actual && actual !== args.expected) {
53
- throw new LucernSdkAuthContextError(
54
- "policy_denied",
55
- `Canonical Lucern SDK auth context has conflicting Permit ${args.field}.`
56
- );
57
- }
58
- }
59
- function normalizeCanonicalLucernAuthContext(input) {
60
- if (!input) {
61
- throw new LucernSdkAuthContextError(
62
- "principal_missing",
63
- "Canonical Lucern SDK auth context is required."
64
- );
65
- }
66
- if (input.policyDecision === "deny") {
67
- throw new LucernSdkAuthContextError(
68
- "policy_denied",
69
- "Canonical Lucern SDK auth context carries a denied policy decision."
70
- );
71
- }
72
- const principalId = requireString(
73
- input.principalId,
74
- "principal_missing",
75
- "principalId"
76
- );
77
- const tenantId = requireString(input.tenantId, "tenant_missing", "tenantId");
78
- const workspaceId = requireString(
79
- input.workspaceId,
80
- "workspace_missing",
81
- "workspaceId"
82
- );
83
- const roles = cleanStringList(input.roles);
84
- const scopes = cleanStringList(input.scopes);
85
- const principalType = requirePrincipalType(input.principalType);
86
- const authMode = requireAuthMode(input.authMode);
87
- const roleBasedInteractiveAuth = authMode === "interactive_user" && roles.length > 0;
88
- if (roles.length === 0 || scopes.length === 0 && !roleBasedInteractiveAuth) {
89
- throw new LucernSdkAuthContextError(
90
- "membership_missing",
91
- "Canonical Lucern SDK auth context requires non-empty roles and scopes."
92
- );
93
- }
94
- const subject = cleanString(input.permit?.subject) ?? principalId;
95
- const tenant = cleanString(input.permit?.tenant) ?? tenantId;
96
- const workspace = cleanString(input.permit?.workspace) ?? workspaceId;
97
- ensurePermitMatch({
98
- field: "subject",
99
- expected: principalId,
100
- actual: subject
101
- });
102
- ensurePermitMatch({ field: "tenant", expected: tenantId, actual: tenant });
103
- ensurePermitMatch({
104
- field: "workspace",
105
- expected: workspaceId,
106
- actual: workspace
107
- });
108
- const context = input.permit?.context ? { ...input.permit.context } : void 0;
109
- return {
110
- clerkId: cleanString(input.clerkId),
111
- principalId,
112
- tenantId,
113
- workspaceId,
114
- principalType,
115
- authMode,
116
- roles,
117
- scopes,
118
- delegationChain: input.delegationChain ? [...input.delegationChain] : [],
119
- policyTraceId: cleanString(input.policyTraceId),
120
- correlationId: cleanString(input.correlationId),
121
- membershipId: cleanString(input.membershipId),
122
- permit: {
123
- subject,
124
- tenant,
125
- workspace,
126
- resource: cleanString(input.permit?.resource),
127
- action: cleanString(input.permit?.action),
128
- relation: cleanString(input.permit?.relation),
129
- context
130
- }
131
- };
132
- }
133
- function createCanonicalAuthHeaders(authContext) {
134
- const headers = {
135
- "x-lucern-principal-id": authContext.principalId,
136
- "x-lucern-principal-type": authContext.principalType,
137
- "x-lucern-tenant": authContext.tenantId,
138
- "x-lucern-tenant-id": authContext.tenantId,
139
- "x-lucern-workspace": authContext.workspaceId,
140
- "x-lucern-workspace-id": authContext.workspaceId,
141
- "x-lucern-auth-mode": authContext.authMode,
142
- "x-lucern-roles": authContext.roles.join(","),
143
- "x-lucern-scopes": authContext.scopes.join(","),
144
- "x-lucern-permit-context": JSON.stringify(authContext.permit)
145
- };
146
- if (authContext.clerkId) {
147
- headers["x-lucern-clerk-id"] = authContext.clerkId;
148
- headers["x-lucern-user-id"] = authContext.clerkId;
149
- }
150
- if (authContext.delegationChain.length > 0) {
151
- headers["x-lucern-delegation-chain"] = JSON.stringify(
152
- authContext.delegationChain
153
- );
154
- }
155
- if (authContext.policyTraceId) {
156
- headers["x-lucern-policy-trace-id"] = authContext.policyTraceId;
157
- }
158
- if (authContext.correlationId) {
159
- headers["x-correlation-id"] = authContext.correlationId;
160
- headers["x-lucern-correlation-id"] = authContext.correlationId;
161
- }
162
- if (authContext.membershipId) {
163
- headers["x-lucern-membership-id"] = authContext.membershipId;
164
- }
165
- return headers;
166
- }
167
-
168
1
  // src/coreClient.ts
169
2
  var LucernApiError = class extends Error {
170
3
  code;
@@ -232,7 +65,9 @@ function generatePortableRequestId() {
232
65
  8
233
66
  ).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10).join("")}`;
234
67
  }
235
- var randomIdempotencyKey = generatePortableRequestId;
68
+ function randomIdempotencyKey() {
69
+ return generatePortableRequestId();
70
+ }
236
71
  function isRetryableStatus(status) {
237
72
  return status >= 500 || status === 408 || status === 429;
238
73
  }
@@ -297,11 +132,8 @@ function timeoutError(timeoutMs) {
297
132
  error.name = "AbortError";
298
133
  return error;
299
134
  }
300
- function isRecord(value) {
301
- return value !== null && typeof value === "object" && !Array.isArray(value);
302
- }
303
135
  function readPolicySummaryFromDetails(details) {
304
- if (!isRecord(details)) {
136
+ if (!details || typeof details !== "object" || Array.isArray(details)) {
305
137
  return null;
306
138
  }
307
139
  const directSummary = details.summary;
@@ -309,11 +141,11 @@ function readPolicySummaryFromDetails(details) {
309
141
  return directSummary.trim();
310
142
  }
311
143
  const policy = details.policy;
312
- if (!isRecord(policy)) {
144
+ if (!policy || typeof policy !== "object" || Array.isArray(policy)) {
313
145
  return null;
314
146
  }
315
147
  const explanation = policy.explanation;
316
- if (!isRecord(explanation)) {
148
+ if (!explanation || typeof explanation !== "object" || Array.isArray(explanation)) {
317
149
  return null;
318
150
  }
319
151
  const nestedSummary = explanation.summary;
@@ -322,59 +154,16 @@ function readPolicySummaryFromDetails(details) {
322
154
  }
323
155
  return null;
324
156
  }
325
- async function resolveConfiguredAuthContext(authContext) {
326
- if (typeof authContext === "function") {
327
- return await authContext();
328
- }
329
- return authContext;
330
- }
331
- function mergeHeaderRecord(base, addition) {
332
- const headers = new Headers(base);
333
- for (const [key, value] of Object.entries(addition)) {
334
- const existing = headers.get(key);
335
- if (existing !== null && existing !== value) {
336
- throw new LucernSdkAuthContextError(
337
- "policy_denied",
338
- `Canonical Lucern SDK auth context conflicts with existing ${key} header.`
339
- );
340
- }
341
- headers.set(key, value);
342
- }
343
- return Object.fromEntries(headers.entries());
344
- }
345
- function cleanHeaderValue(value) {
346
- const normalized = value?.trim();
347
- return normalized ? normalized : void 0;
348
- }
349
157
  function createGatewayRequestClient(config = {}) {
350
158
  const fetchImpl = config.fetchImpl ?? fetch;
351
159
  const baseUrl = config.baseUrl?.replace(/\/+$/, "") ?? "";
352
160
  const maxRetries = config.maxRetries ?? 2;
353
161
  const requestIdFactory = config.requestIdFactory ?? (() => generatePortableRequestId());
354
162
  async function resolveAuthHeaders() {
355
- const provided = config.getAuthHeaders ? await config.getAuthHeaders() : {};
356
- const headers = new Headers(provided);
357
- const setIfAbsent = (name, value) => {
358
- const normalized = cleanHeaderValue(value);
359
- if (normalized && !headers.has(name)) {
360
- headers.set(name, normalized);
361
- }
362
- };
363
- setIfAbsent("x-lucern-key", config.apiKey);
364
- setIfAbsent("x-lucern-session-token", config.userToken);
365
- setIfAbsent("x-lucern-environment", config.environment);
366
- setIfAbsent("x-lucern-clerk-id", config.clerkId);
367
- setIfAbsent("x-lucern-user-id", config.userId ?? config.clerkId);
368
- setIfAbsent("x-lucern-deployment-host", config.deploymentHost);
369
- const base = Object.fromEntries(headers.entries());
370
- const authContextInput = await resolveConfiguredAuthContext(
371
- config.authContext
372
- );
373
- if (!authContextInput && !config.requireCanonicalAuthContext) {
374
- return base;
163
+ if (!config.getAuthHeaders) {
164
+ return {};
375
165
  }
376
- const authContext = normalizeCanonicalLucernAuthContext(authContextInput);
377
- return mergeHeaderRecord(base, createCanonicalAuthHeaders(authContext));
166
+ return await config.getAuthHeaders();
378
167
  }
379
168
  async function fetchWithTimeout(url, init, timeoutMs) {
380
169
  const controller = new AbortController();
@@ -395,11 +184,11 @@ function createGatewayRequestClient(config = {}) {
395
184
  if (!text) {
396
185
  return null;
397
186
  }
398
- const parsed = tryParseGatewayEnvelopeJson(text);
399
- if (!parsed.ok) {
187
+ try {
188
+ return JSON.parse(text);
189
+ } catch {
400
190
  return null;
401
191
  }
402
- return isRecord(parsed.value) ? parsed.value : null;
403
192
  }
404
193
  function resolveTimeoutMs(method, requestTimeoutMs) {
405
194
  if (typeof requestTimeoutMs === "number") {
@@ -411,31 +200,16 @@ function createGatewayRequestClient(config = {}) {
411
200
  }
412
201
  return config.timeoutMs ?? 15e3;
413
202
  }
414
- function tryParseGatewayEnvelopeJson(text) {
415
- const trimmed = text.trim();
416
- if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
417
- return { ok: false, reason: "non-json" };
418
- }
419
- try {
420
- return { ok: true, value: JSON.parse(trimmed) };
421
- } catch (error) {
422
- if (error instanceof SyntaxError) {
423
- return { ok: false, reason: "invalid-json", error };
424
- }
425
- throw error;
426
- }
427
- }
428
203
  function buildApiError(args) {
429
204
  const failure = args.failure;
430
- const legacyError = failure && isRecord(failure.error) ? failure.error : failure?.legacyError;
205
+ const legacyError = failure && typeof failure.error === "object" && failure.error !== null ? failure.error : failure?.legacyError;
431
206
  const correlationId = failure?.correlationId ?? args.response.headers.get("x-lucern-correlation-id")?.trim() ?? args.requestId;
432
207
  const policyTraceId = failure?.policyTraceId ?? args.response.headers.get("x-lucern-policy-trace-id")?.trim() ?? null;
433
208
  const details = failure?.details ?? legacyError?.details;
434
209
  const policySummary = readPolicySummaryFromDetails(details);
435
- const failureMessage = typeof failure?.error === "string" ? failure.error : legacyError?.message;
436
210
  return new LucernApiError({
437
211
  code: failure?.code ?? legacyError?.code ?? fallbackErrorCode(args.response.status),
438
- message: policySummary ?? failureMessage ?? (args.response.ok ? "Platform API returned an invalid success payload." : "Platform API request failed."),
212
+ message: policySummary ?? (typeof failure?.error === "string" ? failure.error : legacyError?.message ?? (args.response.ok ? "Platform API returned an invalid success payload." : "Platform API request failed.")),
439
213
  status: args.response.status,
440
214
  invariant: failure?.invariant,
441
215
  suggestion: failure?.suggestion,
@@ -567,10 +341,7 @@ function createListResult(items, legacyKey) {
567
341
  total: items.length
568
342
  };
569
343
  if (legacyKey) {
570
- return {
571
- ...result,
572
- [legacyKey]: items
573
- };
344
+ result[legacyKey] = items;
574
345
  }
575
346
  return result;
576
347
  }
@@ -608,17 +379,6 @@ function asTenantVaultSecretArray(data) {
608
379
  }
609
380
  function createAdminClient(config = {}) {
610
381
  const gateway = createGatewayRequestClient(config);
611
- const getControlObjectOwnership = async () => gateway.request({
612
- path: "/api/platform/v1/admin/control-ownership"
613
- });
614
- const createMembership = async (input, idempotencyKey) => gateway.request({
615
- path: "/api/platform/v1/memberships",
616
- method: "POST",
617
- body: input,
618
- idempotencyKey: idempotencyKey ?? randomIdempotencyKey()
619
- });
620
- const updateMembership = createMembership;
621
- const upsertMembership = createMembership;
622
382
  return {
623
383
  /**
624
384
  * List tenants visible to the current principal.
@@ -650,11 +410,19 @@ function createAdminClient(config = {}) {
650
410
  /**
651
411
  * Get the control-object ownership contract.
652
412
  */
653
- getControlObjectOwnership,
413
+ async getControlObjectOwnership() {
414
+ return gateway.request({
415
+ path: "/api/platform/v1/admin/control-ownership"
416
+ });
417
+ },
654
418
  /**
655
419
  * @deprecated Use getControlObjectOwnership.
656
420
  */
657
- getControlObjectOwnershipContract: getControlObjectOwnership,
421
+ async getControlObjectOwnershipContract() {
422
+ return gateway.request({
423
+ path: "/api/platform/v1/admin/control-ownership"
424
+ });
425
+ },
658
426
  /**
659
427
  * List workspaces for the current admin scope.
660
428
  */
@@ -701,15 +469,26 @@ function createAdminClient(config = {}) {
701
469
  /**
702
470
  * Create a membership.
703
471
  */
704
- createMembership,
472
+ async createMembership(input, idempotencyKey) {
473
+ return gateway.request({
474
+ path: "/api/platform/v1/memberships",
475
+ method: "POST",
476
+ body: input,
477
+ idempotencyKey: idempotencyKey ?? randomIdempotencyKey()
478
+ });
479
+ },
705
480
  /**
706
481
  * Update a membership.
707
482
  */
708
- updateMembership,
483
+ async updateMembership(input, idempotencyKey) {
484
+ return this.createMembership(input, idempotencyKey);
485
+ },
709
486
  /**
710
487
  * @deprecated Use createMembership or updateMembership.
711
488
  */
712
- upsertMembership,
489
+ async upsertMembership(input, idempotencyKey) {
490
+ return this.createMembership(input, idempotencyKey);
491
+ },
713
492
  /**
714
493
  * List tenant API keys in the current admin scope.
715
494
  */