@lucern/sdk 0.3.0-alpha.17 → 0.3.0-alpha.3
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.
- package/CHANGELOG.md +0 -12
- package/README.md +4 -110
- package/dist/adminClient.d.ts +8 -8
- package/dist/adminClient.js +40 -70
- package/dist/adminClient.js.map +1 -1
- package/dist/answersClient.js +12 -49
- package/dist/answersClient.js.map +1 -1
- package/dist/audience/index.d.ts +1 -2
- package/dist/audience/index.js +3 -1
- package/dist/audience/index.js.map +1 -1
- package/dist/audiencesClient.d.ts +16 -16
- package/dist/audiencesClient.js +91 -125
- package/dist/audiencesClient.js.map +1 -1
- package/dist/auditClient.js +14 -53
- package/dist/auditClient.js.map +1 -1
- package/dist/authContext.d.ts +2 -2
- package/dist/authContext.js +3 -4
- package/dist/authContext.js.map +1 -1
- package/dist/authDeviceClient.js +3 -16
- package/dist/authDeviceClient.js.map +1 -1
- package/dist/beliefs/index.d.ts +4 -9
- package/dist/beliefs/index.js +1305 -1943
- package/dist/beliefs/index.js.map +1 -1
- package/dist/beliefsClient.d.ts +2 -2
- package/dist/beliefsClient.js +23 -54
- package/dist/beliefsClient.js.map +1 -1
- package/dist/boundaryClientSurface.js +3 -10
- package/dist/boundaryClientSurface.js.map +1 -1
- package/dist/client-EiG9nJOY.d.ts +2911 -0
- package/dist/client.d.ts +41 -3038
- package/dist/client.js +1305 -1943
- package/dist/client.js.map +1 -1
- package/dist/contextClient.d.ts +3 -4
- package/dist/contextClient.js +30 -79
- package/dist/contextClient.js.map +1 -1
- package/dist/contextFacade.js +16 -25
- package/dist/contextFacade.js.map +1 -1
- package/dist/contextPackCompiler.js +30 -19
- package/dist/contextPackCompiler.js.map +1 -1
- package/dist/contextPackPolicy.js +17 -7
- package/dist/contextPackPolicy.js.map +1 -1
- package/dist/contextTypes.d.ts +0 -2
- package/dist/contracts/api-enums.contract.d.ts +2 -2
- package/dist/contracts/api-enums.contract.js +1 -6
- package/dist/contracts/api-enums.contract.js.map +1 -1
- package/dist/contracts/auth-session.contract.d.ts +1 -1
- package/dist/contracts/auth-session.contract.js +2 -14
- package/dist/contracts/auth-session.contract.js.map +1 -1
- package/dist/contracts/index.js +6 -30
- package/dist/contracts/index.js.map +1 -1
- package/dist/contracts/lens-filter.contract.js +3 -4
- package/dist/contracts/lens-filter.contract.js.map +1 -1
- package/dist/contracts/lens-workflow.contract.js +3 -4
- package/dist/contracts/lens-workflow.contract.js.map +1 -1
- package/dist/contracts/lensFilter.js +3 -4
- package/dist/contracts/lensFilter.js.map +1 -1
- package/dist/contracts/lensWorkflow.js +3 -4
- package/dist/contracts/lensWorkflow.js.map +1 -1
- package/dist/contracts/mcpTools.js +0 -6
- package/dist/contracts/mcpTools.js.map +1 -1
- package/dist/contradictions/index.d.ts +3 -8
- package/dist/contradictions/index.js +1305 -1943
- package/dist/contradictions/index.js.map +1 -1
- package/dist/coreClient.d.ts +2 -19
- package/dist/coreClient.js +15 -50
- package/dist/coreClient.js.map +1 -1
- package/dist/decisions/index.d.ts +13 -18
- package/dist/decisions/index.js +1305 -1943
- package/dist/decisions/index.js.map +1 -1
- package/dist/decisionsClient.d.ts +12 -4
- package/dist/decisionsClient.js +35 -60
- package/dist/decisionsClient.js.map +1 -1
- package/dist/edges/index.d.ts +86 -31
- package/dist/edges/index.js +1305 -1943
- package/dist/edges/index.js.map +1 -1
- package/dist/embeddingsClient.js +18 -60
- package/dist/embeddingsClient.js.map +1 -1
- package/dist/eventingClient.js +18 -60
- package/dist/eventingClient.js.map +1 -1
- package/dist/events.js +3 -6
- package/dist/events.js.map +1 -1
- package/dist/eventsCore.d.ts +1 -1
- package/dist/eventsCore.js +15 -50
- package/dist/eventsCore.js.map +1 -1
- package/dist/evidence/index.d.ts +3 -8
- package/dist/evidence/index.js +1305 -1943
- package/dist/evidence/index.js.map +1 -1
- package/dist/evidenceClient.js +15 -50
- package/dist/evidenceClient.js.map +1 -1
- package/dist/facade/context.d.ts +1 -2
- package/dist/facade/context.js +16 -25
- package/dist/facade/context.js.map +1 -1
- package/dist/gatewayFacades.d.ts +48 -90
- package/dist/gatewayFacades.js +128 -251
- package/dist/gatewayFacades.js.map +1 -1
- package/dist/graphAnalysisClient.d.ts +1 -53
- package/dist/graphAnalysisClient.js +17 -81
- package/dist/graphAnalysisClient.js.map +1 -1
- package/dist/graphClient.d.ts +13 -6
- package/dist/graphClient.js +39 -65
- package/dist/graphClient.js.map +1 -1
- package/dist/graphRecommendationsClient.js +17 -54
- package/dist/graphRecommendationsClient.js.map +1 -1
- package/dist/graphStateClassifierClient.js +19 -60
- package/dist/graphStateClassifierClient.js.map +1 -1
- package/dist/harnessClient.d.ts +24 -13
- package/dist/harnessClient.js +41 -61
- package/dist/harnessClient.js.map +1 -1
- package/dist/identityClient.d.ts +9 -27
- package/dist/identityClient.js +39 -203
- package/dist/identityClient.js.map +1 -1
- package/dist/index.d.ts +6 -15
- package/dist/index.js +1171 -2256
- package/dist/index.js.map +1 -1
- package/dist/jobsClient.js +19 -60
- package/dist/jobsClient.js.map +1 -1
- package/dist/learningClient.d.ts +6 -6
- package/dist/learningClient.js +43 -78
- package/dist/learningClient.js.map +1 -1
- package/dist/lenses/index.d.ts +37 -60
- package/dist/lenses/index.js +1305 -1943
- package/dist/lenses/index.js.map +1 -1
- package/dist/mcpClient.js +13 -51
- package/dist/mcpClient.js.map +1 -1
- package/dist/modelRuntimeClient.js +18 -60
- package/dist/modelRuntimeClient.js.map +1 -1
- package/dist/nodes/index.d.ts +22 -49
- package/dist/nodes/index.js +1305 -1943
- package/dist/nodes/index.js.map +1 -1
- package/dist/ontologies/index.d.ts +31 -37
- package/dist/ontologies/index.js +1305 -1943
- package/dist/ontologies/index.js.map +1 -1
- package/dist/ontologyClient.d.ts +25 -17
- package/dist/ontologyClient.js +41 -86
- package/dist/ontologyClient.js.map +1 -1
- package/dist/ontologyLinksClient.js +19 -60
- package/dist/ontologyLinksClient.js.map +1 -1
- package/dist/orgGraphSearchClient.js +14 -53
- package/dist/orgGraphSearchClient.js.map +1 -1
- package/dist/packRuntime.d.ts +1 -2
- package/dist/packsClient.d.ts +23 -9
- package/dist/packsClient.js +47 -62
- package/dist/packsClient.js.map +1 -1
- package/dist/policyClient.d.ts +10 -11
- package/dist/policyClient.js +26 -71
- package/dist/policyClient.js.map +1 -1
- package/dist/questions/index.d.ts +3 -8
- package/dist/questions/index.js +1305 -1943
- package/dist/questions/index.js.map +1 -1
- package/dist/realtime/index.d.ts +1 -1
- package/dist/reportsClient.d.ts +7 -7
- package/dist/reportsClient.js +52 -107
- package/dist/reportsClient.js.map +1 -1
- package/dist/schemaClient.d.ts +3 -3
- package/dist/schemaClient.js +30 -63
- package/dist/schemaClient.js.map +1 -1
- package/dist/sdkSurface.d.ts +3 -6
- package/dist/sdkSurface.js +6 -10
- package/dist/sdkSurface.js.map +1 -1
- package/dist/sourcesClient.js +15 -50
- package/dist/sourcesClient.js.map +1 -1
- package/dist/telemetryClient.js +19 -60
- package/dist/telemetryClient.js.map +1 -1
- package/dist/toolRegistryClient.d.ts +2 -10
- package/dist/toolRegistryClient.js +20 -73
- package/dist/toolRegistryClient.js.map +1 -1
- package/dist/topics/index.d.ts +8 -19
- package/dist/topics/index.js +1305 -1945
- package/dist/topics/index.js.map +1 -1
- package/dist/topicsClient.d.ts +0 -2
- package/dist/topicsClient.js +20 -60
- package/dist/topicsClient.js.map +1 -1
- package/dist/types.d.ts +0 -17
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/workflowClient.d.ts +40 -58
- package/dist/workflowClient.js +54 -66
- package/dist/workflowClient.js.map +1 -1
- package/dist/worktrees/index.d.ts +33 -54
- package/dist/worktrees/index.js +1305 -1943
- package/dist/worktrees/index.js.map +1 -1
- package/package.json +3 -17
- package/dist/accessControl.d.ts +0 -79
- package/dist/accessControl.js +0 -1270
- package/dist/accessControl.js.map +0 -1
- package/dist/clientHelpers.d.ts +0 -48
- package/dist/clientHelpers.js +0 -137
- package/dist/clientHelpers.js.map +0 -1
- package/dist/control-plane.d.ts +0 -69
- package/dist/control-plane.js +0 -674
- package/dist/control-plane.js.map +0 -1
- package/dist/functionSurface.d.ts +0 -144
- package/dist/functionSurface.js +0 -1227
- package/dist/functionSurface.js.map +0 -1
- package/dist/functionSurfaceClient.d.ts +0 -8
- package/dist/functionSurfaceClient.js +0 -1227
- package/dist/functionSurfaceClient.js.map +0 -1
- package/dist/graphIntel.d.ts +0 -4
- package/dist/graphIntel.js +0 -3
- package/dist/graphIntel.js.map +0 -1
- package/dist/graphIntelligence.d.ts +0 -2
- package/dist/graphIntelligence.js +0 -47
- package/dist/graphIntelligence.js.map +0 -1
- package/dist/infisicalRuntime.d.ts +0 -43
- package/dist/infisicalRuntime.js +0 -346
- package/dist/infisicalRuntime.js.map +0 -1
- package/dist/secrets.d.ts +0 -1
- package/dist/secrets.js +0 -3
- package/dist/secrets.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,18 +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.17] - 2026-05-19
|
|
9
|
-
- Release notes pending.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
## [0.3.0-alpha.16] - 2026-05-14
|
|
13
|
-
- Adds the exact-row reasoning-kernel migration surface required for tenant identity/scope repairs.
|
|
14
|
-
- Keeps the coherent Lucern package line aligned for StackOS and reasoning-environment adoption.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
## [0.3.0-alpha.7] - 2026-05-03
|
|
18
|
-
- Rebuild the coherent Lucern package line after Campaign 1 SDK hardening fixes.
|
|
19
|
-
|
|
20
8
|
## [0.2.0-alpha.5] - 2026-04-18
|
|
21
9
|
- Refresh publish from current stackos source under EK-16 T4.
|
|
22
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
|
});
|
package/dist/adminClient.d.ts
CHANGED
|
@@ -153,11 +153,11 @@ declare function createAdminClient(config?: AdminClientConfig): {
|
|
|
153
153
|
/**
|
|
154
154
|
* Get the control-object ownership contract.
|
|
155
155
|
*/
|
|
156
|
-
getControlObjectOwnership
|
|
156
|
+
getControlObjectOwnership(): Promise<PlatformGatewaySuccess<ControlObjectOwnershipContract>>;
|
|
157
157
|
/**
|
|
158
158
|
* @deprecated Use getControlObjectOwnership.
|
|
159
159
|
*/
|
|
160
|
-
getControlObjectOwnershipContract
|
|
160
|
+
getControlObjectOwnershipContract(): Promise<PlatformGatewaySuccess<ControlObjectOwnershipContract>>;
|
|
161
161
|
/**
|
|
162
162
|
* List workspaces for the current admin scope.
|
|
163
163
|
*/
|
|
@@ -190,33 +190,33 @@ declare function createAdminClient(config?: AdminClientConfig): {
|
|
|
190
190
|
/**
|
|
191
191
|
* Create a membership.
|
|
192
192
|
*/
|
|
193
|
-
createMembership
|
|
193
|
+
createMembership(input: GatewayScope & {
|
|
194
194
|
membershipId?: string;
|
|
195
195
|
principalId: string;
|
|
196
196
|
role: "platform_admin" | "tenant_admin" | "workspace_admin" | "editor" | "viewer" | "auditor" | "service_agent";
|
|
197
197
|
status?: "active" | "invited" | "revoked" | "expired";
|
|
198
198
|
source?: "bootstrap" | "manual" | "sync" | "sso" | "api" | "scim" | "invitation";
|
|
199
|
-
}, idempotencyKey?: string)
|
|
199
|
+
}, idempotencyKey?: string): Promise<PlatformGatewaySuccess<unknown>>;
|
|
200
200
|
/**
|
|
201
201
|
* Update a membership.
|
|
202
202
|
*/
|
|
203
|
-
updateMembership
|
|
203
|
+
updateMembership(input: GatewayScope & {
|
|
204
204
|
membershipId?: string;
|
|
205
205
|
principalId: string;
|
|
206
206
|
role: "platform_admin" | "tenant_admin" | "workspace_admin" | "editor" | "viewer" | "auditor" | "service_agent";
|
|
207
207
|
status?: "active" | "invited" | "revoked" | "expired";
|
|
208
208
|
source?: "bootstrap" | "manual" | "sync" | "sso" | "api" | "scim" | "invitation";
|
|
209
|
-
}, idempotencyKey?: string)
|
|
209
|
+
}, idempotencyKey?: string): Promise<PlatformGatewaySuccess<unknown>>;
|
|
210
210
|
/**
|
|
211
211
|
* @deprecated Use createMembership or updateMembership.
|
|
212
212
|
*/
|
|
213
|
-
upsertMembership
|
|
213
|
+
upsertMembership(input: GatewayScope & {
|
|
214
214
|
membershipId?: string;
|
|
215
215
|
principalId: string;
|
|
216
216
|
role: "platform_admin" | "tenant_admin" | "workspace_admin" | "editor" | "viewer" | "auditor" | "service_agent";
|
|
217
217
|
status?: "active" | "invited" | "revoked" | "expired";
|
|
218
218
|
source?: "bootstrap" | "manual" | "sync" | "sso" | "api" | "scim" | "invitation";
|
|
219
|
-
}, idempotencyKey?: string)
|
|
219
|
+
}, idempotencyKey?: string): Promise<PlatformGatewaySuccess<unknown>>;
|
|
220
220
|
/**
|
|
221
221
|
* List tenant API keys in the current admin scope.
|
|
222
222
|
*/
|
package/dist/adminClient.js
CHANGED
|
@@ -82,15 +82,14 @@ function normalizeCanonicalLucernAuthContext(input) {
|
|
|
82
82
|
);
|
|
83
83
|
const roles = cleanStringList(input.roles);
|
|
84
84
|
const scopes = cleanStringList(input.scopes);
|
|
85
|
-
|
|
86
|
-
const authMode = requireAuthMode(input.authMode);
|
|
87
|
-
const roleBasedInteractiveAuth = authMode === "interactive_user" && roles.length > 0;
|
|
88
|
-
if (roles.length === 0 || scopes.length === 0 && !roleBasedInteractiveAuth) {
|
|
85
|
+
if (roles.length === 0 || scopes.length === 0) {
|
|
89
86
|
throw new LucernSdkAuthContextError(
|
|
90
87
|
"membership_missing",
|
|
91
88
|
"Canonical Lucern SDK auth context requires non-empty roles and scopes."
|
|
92
89
|
);
|
|
93
90
|
}
|
|
91
|
+
const principalType = requirePrincipalType(input.principalType);
|
|
92
|
+
const authMode = requireAuthMode(input.authMode);
|
|
94
93
|
const subject = cleanString(input.permit?.subject) ?? principalId;
|
|
95
94
|
const tenant = cleanString(input.permit?.tenant) ?? tenantId;
|
|
96
95
|
const workspace = cleanString(input.permit?.workspace) ?? workspaceId;
|
|
@@ -232,7 +231,9 @@ function generatePortableRequestId() {
|
|
|
232
231
|
8
|
|
233
232
|
).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10).join("")}`;
|
|
234
233
|
}
|
|
235
|
-
|
|
234
|
+
function randomIdempotencyKey() {
|
|
235
|
+
return generatePortableRequestId();
|
|
236
|
+
}
|
|
236
237
|
function isRetryableStatus(status) {
|
|
237
238
|
return status >= 500 || status === 408 || status === 429;
|
|
238
239
|
}
|
|
@@ -297,11 +298,8 @@ function timeoutError(timeoutMs) {
|
|
|
297
298
|
error.name = "AbortError";
|
|
298
299
|
return error;
|
|
299
300
|
}
|
|
300
|
-
function isRecord(value) {
|
|
301
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
302
|
-
}
|
|
303
301
|
function readPolicySummaryFromDetails(details) {
|
|
304
|
-
if (!
|
|
302
|
+
if (!details || typeof details !== "object" || Array.isArray(details)) {
|
|
305
303
|
return null;
|
|
306
304
|
}
|
|
307
305
|
const directSummary = details.summary;
|
|
@@ -309,11 +307,11 @@ function readPolicySummaryFromDetails(details) {
|
|
|
309
307
|
return directSummary.trim();
|
|
310
308
|
}
|
|
311
309
|
const policy = details.policy;
|
|
312
|
-
if (!
|
|
310
|
+
if (!policy || typeof policy !== "object" || Array.isArray(policy)) {
|
|
313
311
|
return null;
|
|
314
312
|
}
|
|
315
313
|
const explanation = policy.explanation;
|
|
316
|
-
if (!
|
|
314
|
+
if (!explanation || typeof explanation !== "object" || Array.isArray(explanation)) {
|
|
317
315
|
return null;
|
|
318
316
|
}
|
|
319
317
|
const nestedSummary = explanation.summary;
|
|
@@ -342,31 +340,13 @@ function mergeHeaderRecord(base, addition) {
|
|
|
342
340
|
}
|
|
343
341
|
return Object.fromEntries(headers.entries());
|
|
344
342
|
}
|
|
345
|
-
function cleanHeaderValue(value) {
|
|
346
|
-
const normalized = value?.trim();
|
|
347
|
-
return normalized ? normalized : void 0;
|
|
348
|
-
}
|
|
349
343
|
function createGatewayRequestClient(config = {}) {
|
|
350
344
|
const fetchImpl = config.fetchImpl ?? fetch;
|
|
351
345
|
const baseUrl = config.baseUrl?.replace(/\/+$/, "") ?? "";
|
|
352
346
|
const maxRetries = config.maxRetries ?? 2;
|
|
353
347
|
const requestIdFactory = config.requestIdFactory ?? (() => generatePortableRequestId());
|
|
354
348
|
async function resolveAuthHeaders() {
|
|
355
|
-
const
|
|
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());
|
|
349
|
+
const base = config.getAuthHeaders ? await config.getAuthHeaders() : {};
|
|
370
350
|
const authContextInput = await resolveConfiguredAuthContext(
|
|
371
351
|
config.authContext
|
|
372
352
|
);
|
|
@@ -395,11 +375,11 @@ function createGatewayRequestClient(config = {}) {
|
|
|
395
375
|
if (!text) {
|
|
396
376
|
return null;
|
|
397
377
|
}
|
|
398
|
-
|
|
399
|
-
|
|
378
|
+
try {
|
|
379
|
+
return JSON.parse(text);
|
|
380
|
+
} catch {
|
|
400
381
|
return null;
|
|
401
382
|
}
|
|
402
|
-
return isRecord(parsed.value) ? parsed.value : null;
|
|
403
383
|
}
|
|
404
384
|
function resolveTimeoutMs(method, requestTimeoutMs) {
|
|
405
385
|
if (typeof requestTimeoutMs === "number") {
|
|
@@ -411,31 +391,16 @@ function createGatewayRequestClient(config = {}) {
|
|
|
411
391
|
}
|
|
412
392
|
return config.timeoutMs ?? 15e3;
|
|
413
393
|
}
|
|
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
394
|
function buildApiError(args) {
|
|
429
395
|
const failure = args.failure;
|
|
430
|
-
const legacyError = failure &&
|
|
396
|
+
const legacyError = failure && typeof failure.error === "object" && failure.error !== null ? failure.error : failure?.legacyError;
|
|
431
397
|
const correlationId = failure?.correlationId ?? args.response.headers.get("x-lucern-correlation-id")?.trim() ?? args.requestId;
|
|
432
398
|
const policyTraceId = failure?.policyTraceId ?? args.response.headers.get("x-lucern-policy-trace-id")?.trim() ?? null;
|
|
433
399
|
const details = failure?.details ?? legacyError?.details;
|
|
434
400
|
const policySummary = readPolicySummaryFromDetails(details);
|
|
435
|
-
const failureMessage = typeof failure?.error === "string" ? failure.error : legacyError?.message;
|
|
436
401
|
return new LucernApiError({
|
|
437
402
|
code: failure?.code ?? legacyError?.code ?? fallbackErrorCode(args.response.status),
|
|
438
|
-
message: policySummary ??
|
|
403
|
+
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
404
|
status: args.response.status,
|
|
440
405
|
invariant: failure?.invariant,
|
|
441
406
|
suggestion: failure?.suggestion,
|
|
@@ -567,10 +532,7 @@ function createListResult(items, legacyKey) {
|
|
|
567
532
|
total: items.length
|
|
568
533
|
};
|
|
569
534
|
if (legacyKey) {
|
|
570
|
-
|
|
571
|
-
...result,
|
|
572
|
-
[legacyKey]: items
|
|
573
|
-
};
|
|
535
|
+
result[legacyKey] = items;
|
|
574
536
|
}
|
|
575
537
|
return result;
|
|
576
538
|
}
|
|
@@ -608,17 +570,6 @@ function asTenantVaultSecretArray(data) {
|
|
|
608
570
|
}
|
|
609
571
|
function createAdminClient(config = {}) {
|
|
610
572
|
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
573
|
return {
|
|
623
574
|
/**
|
|
624
575
|
* List tenants visible to the current principal.
|
|
@@ -650,11 +601,19 @@ function createAdminClient(config = {}) {
|
|
|
650
601
|
/**
|
|
651
602
|
* Get the control-object ownership contract.
|
|
652
603
|
*/
|
|
653
|
-
getControlObjectOwnership
|
|
604
|
+
async getControlObjectOwnership() {
|
|
605
|
+
return gateway.request({
|
|
606
|
+
path: "/api/platform/v1/admin/control-ownership"
|
|
607
|
+
});
|
|
608
|
+
},
|
|
654
609
|
/**
|
|
655
610
|
* @deprecated Use getControlObjectOwnership.
|
|
656
611
|
*/
|
|
657
|
-
getControlObjectOwnershipContract
|
|
612
|
+
async getControlObjectOwnershipContract() {
|
|
613
|
+
return gateway.request({
|
|
614
|
+
path: "/api/platform/v1/admin/control-ownership"
|
|
615
|
+
});
|
|
616
|
+
},
|
|
658
617
|
/**
|
|
659
618
|
* List workspaces for the current admin scope.
|
|
660
619
|
*/
|
|
@@ -701,15 +660,26 @@ function createAdminClient(config = {}) {
|
|
|
701
660
|
/**
|
|
702
661
|
* Create a membership.
|
|
703
662
|
*/
|
|
704
|
-
createMembership,
|
|
663
|
+
async createMembership(input, idempotencyKey) {
|
|
664
|
+
return gateway.request({
|
|
665
|
+
path: "/api/platform/v1/memberships",
|
|
666
|
+
method: "POST",
|
|
667
|
+
body: input,
|
|
668
|
+
idempotencyKey: idempotencyKey ?? randomIdempotencyKey()
|
|
669
|
+
});
|
|
670
|
+
},
|
|
705
671
|
/**
|
|
706
672
|
* Update a membership.
|
|
707
673
|
*/
|
|
708
|
-
updateMembership,
|
|
674
|
+
async updateMembership(input, idempotencyKey) {
|
|
675
|
+
return this.createMembership(input, idempotencyKey);
|
|
676
|
+
},
|
|
709
677
|
/**
|
|
710
678
|
* @deprecated Use createMembership or updateMembership.
|
|
711
679
|
*/
|
|
712
|
-
upsertMembership,
|
|
680
|
+
async upsertMembership(input, idempotencyKey) {
|
|
681
|
+
return this.createMembership(input, idempotencyKey);
|
|
682
|
+
},
|
|
713
683
|
/**
|
|
714
684
|
* List tenant API keys in the current admin scope.
|
|
715
685
|
*/
|