lemma-sdk 0.2.28 → 0.2.31

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 (122) hide show
  1. package/README.md +241 -201
  2. package/bin/lemma-sdk.js +108 -0
  3. package/dist/browser/lemma-client.js +125 -4
  4. package/dist/client.d.ts +2 -0
  5. package/dist/client.js +3 -0
  6. package/dist/config.d.ts +2 -2
  7. package/dist/config.js +2 -2
  8. package/dist/datastore-query.d.ts +54 -0
  9. package/dist/datastore-query.js +157 -0
  10. package/dist/index.d.ts +7 -0
  11. package/dist/index.js +3 -0
  12. package/dist/namespaces/datastore.d.ts +9 -0
  13. package/dist/namespaces/datastore.js +13 -0
  14. package/dist/namespaces/records.d.ts +1 -1
  15. package/dist/openapi_client/index.d.ts +4 -0
  16. package/dist/openapi_client/index.js +1 -0
  17. package/dist/openapi_client/models/ConvertedArtifactResponse.d.ts +6 -0
  18. package/dist/openapi_client/models/ConvertedFileResponse.d.ts +10 -0
  19. package/dist/openapi_client/models/ConvertedFileResponse.js +1 -0
  20. package/dist/openapi_client/models/CreateFolderRequest.d.ts +3 -1
  21. package/dist/openapi_client/models/FlowRunEntity.d.ts +1 -0
  22. package/dist/openapi_client/models/ScheduledFlowStart.d.ts +3 -6
  23. package/dist/openapi_client/models/ScheduledFlowStartType.d.ts +4 -0
  24. package/dist/openapi_client/models/ScheduledFlowStartType.js +9 -0
  25. package/dist/openapi_client/models/WorkflowInstallRequest.d.ts +5 -0
  26. package/dist/openapi_client/models/WorkflowTimeInstallConfig.d.ts +19 -0
  27. package/dist/openapi_client/models/WorkflowTimeInstallConfig.js +1 -0
  28. package/dist/openapi_client/services/FilesService.d.ts +27 -1
  29. package/dist/openapi_client/services/FilesService.js +69 -1
  30. package/dist/openapi_client/services/WorkflowsService.d.ts +1 -1
  31. package/dist/openapi_client/services/WorkflowsService.js +1 -1
  32. package/dist/react/assistant-output.d.ts +6 -0
  33. package/dist/react/assistant-output.js +90 -0
  34. package/dist/react/index.d.ts +62 -8
  35. package/dist/react/index.js +31 -4
  36. package/dist/react/useAgentInputSchema.d.ts +19 -0
  37. package/dist/react/useAgentInputSchema.js +73 -0
  38. package/dist/react/useAgentRun.d.ts +17 -0
  39. package/dist/react/useAgentRun.js +56 -0
  40. package/dist/react/useAgentRuns.d.ts +33 -0
  41. package/dist/react/useAgentRuns.js +149 -0
  42. package/dist/react/useAssistantRun.d.ts +9 -0
  43. package/dist/react/useAssistantRun.js +28 -17
  44. package/dist/react/useAssistantSession.d.ts +5 -0
  45. package/dist/react/useAssistantSession.js +135 -86
  46. package/dist/react/useBulkRecords.d.ts +20 -0
  47. package/dist/react/useBulkRecords.js +65 -0
  48. package/dist/react/useConversation.d.ts +18 -0
  49. package/dist/react/useConversation.js +75 -0
  50. package/dist/react/useConversationMessages.d.ts +59 -0
  51. package/dist/react/useConversationMessages.js +167 -0
  52. package/dist/react/useConversations.d.ts +52 -0
  53. package/dist/react/useConversations.js +228 -0
  54. package/dist/react/useCreateRecord.d.ts +18 -0
  55. package/dist/react/useCreateRecord.js +51 -0
  56. package/dist/react/useCurrentUser.d.ts +14 -0
  57. package/dist/react/useCurrentUser.js +68 -0
  58. package/dist/react/useDeleteRecord.d.ts +21 -0
  59. package/dist/react/useDeleteRecord.js +52 -0
  60. package/dist/react/useFlowRunHistory.js +1 -5
  61. package/dist/react/useFlowSession.js +41 -33
  62. package/dist/react/useForeignKeyOptions.d.ts +31 -0
  63. package/dist/react/useForeignKeyOptions.js +161 -0
  64. package/dist/react/useFunctionRun.d.ts +19 -0
  65. package/dist/react/useFunctionRun.js +30 -0
  66. package/dist/react/useFunctionRuns.d.ts +33 -0
  67. package/dist/react/useFunctionRuns.js +149 -0
  68. package/dist/react/useFunctionSession.js +37 -29
  69. package/dist/react/useJoinedRecords.d.ts +18 -0
  70. package/dist/react/useJoinedRecords.js +80 -0
  71. package/dist/react/useMembers.d.ts +26 -0
  72. package/dist/react/useMembers.js +98 -0
  73. package/dist/react/useOrganizationMembers.d.ts +26 -0
  74. package/dist/react/useOrganizationMembers.js +113 -0
  75. package/dist/react/usePodAccess.d.ts +22 -0
  76. package/dist/react/usePodAccess.js +128 -0
  77. package/dist/react/useRecord.d.ts +18 -0
  78. package/dist/react/useRecord.js +75 -0
  79. package/dist/react/useRecordForm.d.ts +42 -0
  80. package/dist/react/useRecordForm.js +221 -0
  81. package/dist/react/useRecordSchema.d.ts +20 -0
  82. package/dist/react/useRecordSchema.js +24 -0
  83. package/dist/react/useRecords.d.ts +20 -0
  84. package/dist/react/useRecords.js +146 -0
  85. package/dist/react/useRelatedRecords.d.ts +43 -0
  86. package/dist/react/useRelatedRecords.js +239 -0
  87. package/dist/react/useReverseRelatedRecords.d.ts +47 -0
  88. package/dist/react/useReverseRelatedRecords.js +235 -0
  89. package/dist/react/useSchemaForm.d.ts +24 -0
  90. package/dist/react/useSchemaForm.js +104 -0
  91. package/dist/react/useTable.d.ts +16 -0
  92. package/dist/react/useTable.js +70 -0
  93. package/dist/react/useTables.d.ts +26 -0
  94. package/dist/react/useTables.js +113 -0
  95. package/dist/react/useTaskSession.js +11 -22
  96. package/dist/react/useUpdateRecord.d.ts +21 -0
  97. package/dist/react/useUpdateRecord.js +55 -0
  98. package/dist/react/useWorkflowResume.d.ts +18 -0
  99. package/dist/react/useWorkflowResume.js +45 -0
  100. package/dist/react/useWorkflowRun.d.ts +21 -0
  101. package/dist/react/useWorkflowRun.js +49 -0
  102. package/dist/react/useWorkflowRuns.d.ts +33 -0
  103. package/dist/react/useWorkflowRuns.js +149 -0
  104. package/dist/react/useWorkflowStart.d.ts +33 -0
  105. package/dist/react/useWorkflowStart.js +148 -0
  106. package/dist/react/utils.d.ts +5 -0
  107. package/dist/react/utils.js +25 -0
  108. package/dist/record-form.d.ts +30 -0
  109. package/dist/record-form.js +199 -0
  110. package/dist/schema-form.d.ts +41 -0
  111. package/dist/schema-form.js +200 -0
  112. package/dist/types.d.ts +6 -1
  113. package/package.json +11 -8
  114. package/dist/react/components/AssistantChrome.d.ts +0 -86
  115. package/dist/react/components/AssistantChrome.js +0 -48
  116. package/dist/react/components/AssistantEmbedded.d.ts +0 -10
  117. package/dist/react/components/AssistantEmbedded.js +0 -15
  118. package/dist/react/components/AssistantExperience.d.ts +0 -96
  119. package/dist/react/components/AssistantExperience.js +0 -1294
  120. package/dist/react/components/assistant-types.d.ts +0 -80
  121. package/dist/react/styles.css +0 -2407
  122. /package/dist/{react/components/assistant-types.js → openapi_client/models/ConvertedArtifactResponse.js} +0 -0
package/README.md CHANGED
@@ -1,294 +1,334 @@
1
- # Lemma TypeScript SDK (`lemma-sdk`)
1
+ # Lemma TypeScript SDK
2
2
 
3
- Official TypeScript SDK for Lemma APIs with:
3
+ `lemma-sdk` is the headless TypeScript SDK for Lemma. Use `lemma-sdk` for the core client, `lemma-sdk/react` for hooks and auth primitives, and the Lemma shadcn registry for stock UI blocks.
4
4
 
5
- - Pod-scoped namespaces (`tables`, `records`, `files`, `assistants`,`agents` , `workflows`, `tasks`, .)
6
- - Built-in auth/session handling
7
- - SSE streaming helpers
8
- - React hooks and assistant UI components
5
+ `AuthGuard` intentionally stays in `lemma-sdk/react`. Stock assistant, table, workflow, agent, member, and function UI lives in the registry.
9
6
 
10
7
  ## Install
11
8
 
12
9
  ```bash
13
- npm i lemma-sdk
10
+ npm install lemma-sdk
14
11
  ```
15
12
 
16
- ## Quick Start
13
+ If your app uses shadcn/ui, configure the Lemma registry with:
14
+
15
+ ```bash
16
+ npx lemma-sdk init-shadcn
17
+ ```
18
+
19
+ That adds this namespace to your app's `components.json`:
20
+
21
+ ```json
22
+ {
23
+ "registries": {
24
+ "@lemma": "https://cdn.jsdelivr.net/gh/gappyai/lemma-typescript@main/public/r/{name}.json"
25
+ }
26
+ }
27
+ ```
28
+
29
+ If your app does not have `components.json` yet, run `npx shadcn@latest init` first or after the command above.
30
+
31
+ ## Core Client
17
32
 
18
33
  ```ts
19
34
  import { LemmaClient } from "lemma-sdk";
20
35
 
21
36
  const client = new LemmaClient({
22
- apiUrl: "https://api.lemma.work",
23
- authUrl: "https://auth.lemma.work/auth",
24
37
  podId: "<pod-id>",
25
38
  });
26
39
 
27
40
  await client.initialize();
28
41
 
29
42
  const tables = await client.tables.list();
30
- const assistants = await client.assistants.list({ limit: 20 });
31
- const supportAssistant = await client.assistants.get("support_assistant");
43
+ const records = await client.records.list("tickets");
32
44
  ```
33
45
 
34
- ## Configuration
46
+ Pod-scoped namespaces include `tables`, `records`, `assistants`, `agents`, `tasks`, `workflows`, `functions`, `files`, `desks`, `integrations`, `resources`, and `datastore`.
47
+
48
+ Org and user surfaces include `users`, `organizations`, `pods`, `podMembers`, `podJoinRequests`, and `podSurfaces`.
35
49
 
36
- `LemmaClient` config resolution order:
50
+ ## React Package
37
51
 
38
- 1. Constructor overrides
39
- 2. `window.__LEMMA_CONFIG__`
40
- 3. Environment variables
41
- 4. Defaults
52
+ Install React if your app needs hooks:
42
53
 
43
- Supported env keys:
54
+ ```bash
55
+ npm install react react-dom
56
+ ```
44
57
 
45
- - `VITE_LEMMA_API_URL`, `REACT_APP_LEMMA_API_URL`, `LEMMA_API_URL`
46
- - `VITE_LEMMA_AUTH_URL`, `REACT_APP_LEMMA_AUTH_URL`, `LEMMA_AUTH_URL`
47
- - `VITE_LEMMA_POD_ID`, `REACT_APP_LEMMA_POD_ID`, `LEMMA_POD_ID`
58
+ `lemma-sdk/react` is headless-first. It exports hooks plus `AuthGuard`; it does not export stock UI components or CSS.
48
59
 
49
- Defaults when unset:
60
+ ```tsx
61
+ import {
62
+ AuthGuard,
63
+ useAgentRun,
64
+ useConversationMessages,
65
+ useConversations,
66
+ useRecords,
67
+ useSchemaForm,
68
+ useWorkflowStart,
69
+ } from "lemma-sdk/react";
70
+ ```
50
71
 
51
- - `apiUrl`: `http://localhost:8000`
52
- - `authUrl`: `http://localhost:3000`
72
+ ### Hook Matrix
53
73
 
54
- ## Pod Scoping
74
+ | Area | Hooks | Stability | Use when |
75
+ | --- | --- | --- | --- |
76
+ | Auth | `AuthGuard`, `useAuth`, `useCurrentUser`, `usePodAccess` | Stable | Gate an app, read signed-in user state, or request pod access. |
77
+ | Tables | `useTables`, `useTable`, `useRecords`, `useRecord`, `useJoinedRecords`, `useRelatedRecords`, `useReverseRelatedRecords` | Stable | Build custom table browsers, details views, related-record views, and relational reads. |
78
+ | Record mutations | `useCreateRecord`, `useUpdateRecord`, `useDeleteRecord`, `useBulkRecords` | Stable | Create, update, delete, or bulk-delete rows from headless UI. |
79
+ | Record forms | `useRecordSchema`, `useRecordForm`, `useForeignKeyOptions`, `useSchemaForm` | Stable | Render schema-driven forms, enum fields, and foreign-key selectors. |
80
+ | Assistant | `useConversations`, `useConversation`, `useConversationMessages`, `useAssistantRun`, `useAssistantSession`, `useAssistantRuntime`, `useAssistantController` | Stable except controller/runtime | Build custom chat, conversation lists, streaming output, and final-output views. |
81
+ | Agents | `useAgentRun`, `useAgentRuns`, `useAgentInputSchema`, `useTaskSession` | Stable except raw session | Start agent tasks, submit follow-up input, read task history, and inspect input/output schemas. |
82
+ | Workflows | `useWorkflowStart`, `useWorkflowRun`, `useWorkflowRuns`, `useWorkflowResume` | Stable | Start, poll, resume, cancel, retry, and inspect workflow runs. |
83
+ | Workflow compatibility | `useFlowSession`, `useFlowRunHistory` | Deprecated naming | Kept for existing callers; prefer workflow-named hooks for new code. |
84
+ | Functions | `useFunctionRun`, `useFunctionRuns`, `useFunctionSession` | Stable except raw session | Run functions, poll function runs, and list function history. |
85
+ | Members and org | `useMembers`, `useOrganizationMembers` | Stable | Read pod and organization member lists. `useMembers` is intentionally read-only. |
55
86
 
56
- Most namespaces are pod-scoped. You can set pod scope in three ways:
87
+ ### Common Hook Shapes
57
88
 
58
- ```ts
59
- client.setPodId("pod_a");
89
+ List hooks generally expose:
60
90
 
61
- const podBClient = client.withPod("pod_b");
91
+ - `items` named for the resource, such as `records`, `runs`, or `members`
92
+ - `isLoading`
93
+ - `error`
94
+ - `nextPageToken`
95
+ - `refresh(...)`
96
+ - `loadMore(...)` where pagination is useful
62
97
 
63
- const conversations = await client.conversations.list({ pod_id: "pod_c" });
64
- ```
98
+ Run hooks generally expose:
65
99
 
66
- ## Namespace Overview
100
+ - `run` or `task`
101
+ - `status`
102
+ - `isPolling`, `isStreaming`, or `isRunning`
103
+ - `output`
104
+ - `finalOutput`
105
+ - `start(...)`
106
+ - `refresh(...)`
107
+ - follow-up helpers such as `resume(...)`, `submitInput(...)`, `cancel(...)`, or `retry(...)`
67
108
 
68
- Common pod-scoped namespaces:
109
+ ### Headless Examples
69
110
 
70
- - `client.tables`
71
- - `client.records`
72
- - `client.files`
73
- - `client.functions`
74
- - `client.agents`
75
- - `client.tasks`
76
- - `client.assistants`
77
- - `client.workflows`
78
- - `client.desks`
79
- - `client.integrations`
80
- - `client.resources`
111
+ Records:
81
112
 
82
- Org/user-level namespaces:
113
+ ```tsx
114
+ import { LemmaClient } from "lemma-sdk";
115
+ import { useRecords } from "lemma-sdk/react";
83
116
 
84
- - `client.users`
85
- - `client.icons`
86
- - `client.pods`
87
- - `client.podMembers`
88
- - `client.podJoinRequests`
89
- - `client.organizations`
90
- - `client.podSurfaces`
117
+ const client = new LemmaClient({ podId: "<pod-id>" });
91
118
 
92
- Escape hatch for unmapped endpoints:
119
+ function TicketList() {
120
+ const tickets = useRecords({
121
+ client,
122
+ tableName: "tickets",
123
+ limit: 25,
124
+ sortBy: "created_at",
125
+ order: "desc",
126
+ });
93
127
 
94
- ```ts
95
- const result = await client.request("GET", "/models");
128
+ if (tickets.error) return <p>{tickets.error.message}</p>;
129
+
130
+ return (
131
+ <ul>
132
+ {tickets.records.map((ticket) => (
133
+ <li key={String(ticket.id)}>{String(ticket.title ?? ticket.id)}</li>
134
+ ))}
135
+ </ul>
136
+ );
137
+ }
96
138
  ```
97
139
 
98
- ## CRUD Examples
140
+ Assistant final output:
99
141
 
100
- ### Tables + Records
142
+ ```tsx
143
+ import { useConversationMessages, useConversations } from "lemma-sdk/react";
101
144
 
102
- ```ts
103
- await client.tables.create({ name: "todos" });
145
+ function SupportThread({ client }: { client: LemmaClient }) {
146
+ const conversations = useConversations({
147
+ client,
148
+ assistantName: "support_assistant",
149
+ });
104
150
 
105
- await client.records.create("todos", {
106
- title: "Ship docs rewrite",
107
- status: "todo",
108
- });
151
+ const messages = useConversationMessages({
152
+ client,
153
+ conversationId: conversations.effectiveSelectedConversationId,
154
+ autoResume: true,
155
+ });
109
156
 
110
- const page = await client.records.list("todos", {
111
- limit: 20,
112
- sort: [{ field: "created_at", direction: "desc" }],
113
- });
157
+ return <pre>{messages.finalOutputText || messages.outputText || "No output yet."}</pre>;
158
+ }
114
159
  ```
115
160
 
116
- ### Files (Datastore)
161
+ Agent run:
117
162
 
118
- ```ts
119
- await client.files.folder.create("reports", { directoryPath: "/" });
120
- await client.files.upload(fileBlob, { directoryPath: "/reports", name: "q1.pdf" });
163
+ ```tsx
164
+ import { useAgentRun } from "lemma-sdk/react";
165
+
166
+ function AgentButton({ client }: { client: LemmaClient }) {
167
+ const agent = useAgentRun({
168
+ client,
169
+ agentName: "triage_agent",
170
+ });
121
171
 
122
- const listing = await client.files.list({ directoryPath: "/reports" });
123
- const downloaded = await client.files.download("/reports/q1.pdf");
172
+ return (
173
+ <button
174
+ disabled={agent.isStreaming}
175
+ onClick={() => {
176
+ void agent.start({ ticket_id: "ticket_123" });
177
+ }}
178
+ >
179
+ {agent.status ?? "Run agent"}
180
+ </button>
181
+ );
182
+ }
124
183
  ```
125
184
 
126
- ### Assistants + Conversations
185
+ Workflow run:
127
186
 
128
- ```ts
129
- await client.assistants.create({
130
- name: "support_assistant",
131
- instruction: "Help with support triage.",
132
- });
187
+ ```tsx
188
+ import { useWorkflowRun } from "lemma-sdk/react";
133
189
 
134
- const conversation = await client.conversations.createForAssistant("support_assistant", {
135
- title: "Ticket review",
136
- });
190
+ function WorkflowButton({ client }: { client: LemmaClient }) {
191
+ const workflow = useWorkflowRun({
192
+ client,
193
+ workflowName: "approve_ticket",
194
+ });
137
195
 
138
- await client.conversations.messages.send(conversation.id, {
139
- content: "Summarize unresolved issues from today.",
140
- });
196
+ return (
197
+ <button
198
+ disabled={workflow.isPolling}
199
+ onClick={() => {
200
+ void workflow.start({ ticket_id: "ticket_123" });
201
+ }}
202
+ >
203
+ {workflow.status ?? "Start workflow"}
204
+ </button>
205
+ );
206
+ }
141
207
  ```
142
208
 
143
- ### Pod Join Requests
209
+ ## Shadcn Registry
144
210
 
145
- ```ts
146
- // Current user requests access to a pod
147
- await client.podJoinRequests.create("pod_123");
211
+ Lemma UI lives in the registry, not in `lemma-sdk/react`.
148
212
 
149
- // Current user's pending request (or null)
150
- const mine = await client.podJoinRequests.me("pod_123");
213
+ After running `npx lemma-sdk init-shadcn`, install blocks like:
151
214
 
152
- // Admin view of requests for a pod
153
- const requests = await client.podJoinRequests.list("pod_123", {
154
- status: "PENDING",
155
- limit: 50,
156
- });
157
-
158
- // Admin approval (defaults: ORG_MEMBER + POD_USER)
159
- await client.podJoinRequests.approve("pod_123", "join_req_abc", {
160
- org_role: "ORG_MEMBER",
161
- pod_role: "POD_USER",
162
- });
215
+ ```bash
216
+ npx shadcn@latest add @lemma/lemma-records-page
217
+ npx shadcn@latest add @lemma/lemma-agent-runner-page
218
+ npx shadcn@latest add @lemma/lemma-workflow-launcher-page
219
+ npx shadcn@latest add @lemma/lemma-function-runner-page
163
220
  ```
164
221
 
165
- ## Streaming (SSE)
222
+ Current registry items:
166
223
 
167
- Use `readSSE` + `parseSSEJson` for incremental events.
224
+ | Area | Items |
225
+ | --- | --- |
226
+ | Assistant | `lemma-assistant-experience`, `lemma-assistant-embedded` |
227
+ | Schema | `lemma-schema-form` |
228
+ | Tables | `lemma-table-picker`, `lemma-record-picker`, `lemma-record-filters-bar`, `lemma-records-table`, `lemma-record-details-card`, `lemma-record-form`, `lemma-related-records-table`, `lemma-reverse-related-records-table`, `lemma-bulk-actions-bar`, `lemma-records-page` |
229
+ | Agents | `lemma-agent-run-panel`, `lemma-agent-output-card`, `lemma-agent-messages`, `lemma-agent-runner-page` |
230
+ | Workflows | `lemma-workflow-start-form`, `lemma-workflow-history`, `lemma-workflow-run-status`, `lemma-workflow-run-details`, `lemma-workflow-launcher-page` |
231
+ | Members and access | `lemma-members-table`, `lemma-member-picker`, `lemma-org-member-picker`, `lemma-pod-access-card` |
232
+ | Functions | `lemma-function-run-panel`, `lemma-function-run-history`, `lemma-function-runner-page` |
168
233
 
169
- ```ts
170
- import { readSSE, parseSSEJson } from "lemma-sdk";
234
+ The registry is currently served from jsDelivr against this public repo:
171
235
 
172
- const stream = await client.conversations.sendMessageStream(conversationId, {
173
- content: "Analyze recent incidents",
174
- });
236
+ - registry root: `https://cdn.jsdelivr.net/gh/gappyai/lemma-typescript@main/public/r/registry.json`
237
+ - item shape: `https://cdn.jsdelivr.net/gh/gappyai/lemma-typescript@main/public/r/{name}.json`
175
238
 
176
- for await (const event of readSSE(stream)) {
177
- const payload = parseSSEJson(event);
178
- if (!payload) continue;
179
- console.log(event.event, payload);
180
- }
181
- ```
239
+ For more stable installs, pin the registry URL to a tag or commit SHA instead of `@main`.
182
240
 
183
- Task stream example:
241
+ ### Records Workspace Customization
184
242
 
185
- ```ts
186
- const task = await client.tasks.create({
187
- agent_name: "triage_agent",
188
- input_data: { ticketId: "TCK-1042" },
189
- });
243
+ The records blocks are meant to be configured with props before you reach for a fork.
190
244
 
191
- const taskStream = await client.tasks.stream(task.id);
192
- ```
245
+ `lemma-records-page` supports:
193
246
 
194
- ## Access Grants (`accessible_tables`)
247
+ - capability toggles such as `allowCreate`, `allowEdit`, `allowSelection`, `allowBulkDelete`, `allowSearch`, `allowFilters`, `allowSorting`, `allowPageSizeSelect`, and `allowColumnVisibility`
248
+ - layout toggles such as `showTablePicker`, `showRecordPicker`, and `showRecordDetails`
249
+ - column control through `columns`, `hiddenColumnNames`, `defaultHiddenColumnNames`, and `onHiddenColumnNamesChange`
250
+ - non-`id` primary keys through `recordIdField` or `getRecordId`
251
+ - record-form overrides through `recordFormHiddenFields`, `recordFormFieldOrder`, `recordFormFieldLabels`, `recordFormFieldDescriptions`, `createFormTitle`, `editFormTitle`, `createSubmitLabel`, and `editSubmitLabel`
195
252
 
196
- When creating agents/functions/assistants, `accessible_tables` must use object entries:
253
+ `lemma-records-table` supports richer column definitions:
197
254
 
198
- ```ts
199
- import { TableAccessMode } from "lemma-sdk";
255
+ - `label`, `description`, `type`, `width`, `minWidth`, `align`
256
+ - `searchable`, `hideable`, `hidden`
257
+ - `renderCell(...)` for custom cell output
258
+ - per-row buttons through `rowActions`
200
259
 
201
- accessible_tables: [
202
- { table_name: "expenses", mode: TableAccessMode.READ },
203
- { table_name: "expense_notes", mode: TableAccessMode.WRITE },
260
+ ```tsx
261
+ import { LemmaRecordsPage } from "@/components/lemma/lemma-records-page";
262
+ import type { LemmaRecordsTableColumn } from "@/components/lemma/lemma-records-table";
263
+
264
+ const columns: LemmaRecordsTableColumn[] = [
265
+ { name: "item_id", label: "Item ID", hideable: false, width: 180 },
266
+ { name: "group_id", label: "Group", width: 160 },
267
+ { name: "name", label: "Name", minWidth: 320, searchable: true },
268
+ {
269
+ name: "sellable",
270
+ label: "Sellable",
271
+ type: "boolean",
272
+ width: 120,
273
+ align: "center",
274
+ renderCell: ({ value }) => (value ? "Yes" : "No"),
275
+ },
204
276
  ];
205
- ```
206
277
 
207
- `["expenses"]` is not valid.
278
+ <LemmaRecordsPage
279
+ allowColumnVisibility
280
+ allowCreate
281
+ allowEdit
282
+ columns={columns}
283
+ createButtonLabel="New SKU"
284
+ defaultHiddenColumnNames={["group_id"]}
285
+ editSubmitLabel="Save SKU"
286
+ recordFormFieldLabels={{ item_id: "Item ID" }}
287
+ recordIdField="item_id"
288
+ tableName="catalog_items"
289
+ />;
290
+ ```
208
291
 
209
292
  ## Auth
210
293
 
211
- Default mode is cookie/session auth (`credentials: "include"`).
294
+ The SDK uses cookie or session auth by default.
212
295
 
213
- For local browser testing, token injection is supported via local storage key `lemma_token`:
214
-
215
- ```ts
216
- import { setTestingToken, clearTestingToken } from "lemma-sdk";
217
-
218
- setTestingToken("<access-token>");
219
- clearTestingToken();
220
- ```
221
-
222
- Auth helpers:
296
+ Useful helpers:
223
297
 
224
298
  - `buildAuthUrl(...)`
225
299
  - `buildFederatedLogoutUrl(...)`
226
300
  - `resolveSafeRedirectUri(...)`
227
- - `client.auth.redirectToAuth(...)`
228
- - `client.auth.redirectToFederatedLogout(...)`
229
-
230
- ## React Package (`lemma-sdk/react`)
301
+ - `setTestingToken(...)`
302
+ - `clearTestingToken()`
231
303
 
232
- Includes auth helpers, run hooks, and assistant UI primitives.
304
+ When `client.podId` is set and the signed-in user is not a pod member, `AuthGuard` can render the request-access flow and create or show pod join requests.
233
305
 
234
- Install React peer dependency in your app if not already installed:
235
-
236
- ```bash
237
- npm i react react-dom
238
- ```
306
+ `usePodAccess` exposes the same membership/request-access state as a hook for custom UI.
239
307
 
240
- Import stylesheet once:
308
+ ## Migration Notes
241
309
 
242
- ```tsx
243
- import "lemma-sdk/react/styles.css";
244
- ```
310
+ From `0.2.30` onward:
245
311
 
246
- Fastest assistant integration:
312
+ - `lemma-sdk/react` should be treated as hooks plus auth primitives.
313
+ - `AuthGuard` remains in `lemma-sdk/react`.
314
+ - Stock UI should be installed from the shadcn registry.
315
+ - Assistant UI source and CSS are no longer part of the React SDK internals.
316
+ - `react-markdown` and `remark-gfm` are registry-block dependencies for assistant UI, not core SDK dependencies.
317
+ - New workflow code should prefer `useWorkflowRun`, `useWorkflowRuns`, and `useWorkflowResume` over the older `flow`-named hooks.
247
318
 
248
- ```tsx
249
- import { AssistantEmbedded } from "lemma-sdk/react";
250
-
251
- <div style={{ height: 720, minHeight: 0 }}>
252
- <AssistantEmbedded
253
- client={client}
254
- podId="<pod-id>"
255
- assistantName="support_assistant"
256
- title="Support Assistant"
257
- placeholder="Message Support Assistant"
258
- showConversationList
259
- />
260
- </div>;
261
- ```
319
+ ## Local Development
262
320
 
263
- Auth guard example:
321
+ From the root of this repository:
264
322
 
265
- ```tsx
266
- import { AuthGuard } from "lemma-sdk/react";
267
-
268
- <AuthGuard client={client}>
269
- <App />
270
- </AuthGuard>;
323
+ ```bash
324
+ npm install
325
+ npm run build
326
+ npm run registry:build
271
327
  ```
272
328
 
273
- When `client.podId` is set and the signed-in user is not a pod member, `AuthGuard` automatically renders a request-access state and can create/view pod join requests.
274
-
275
- ## Browser Bundle
276
-
277
- The package also ships a standalone browser bundle:
329
+ This repo includes:
278
330
 
279
- - npm artifact path: `dist/browser/lemma-client.js`
280
- - export path: `lemma-sdk/browser-bundle`
281
- - global: `window.LemmaClient.LemmaClient`
282
-
283
- Example:
284
-
285
- ```html
286
- <script src="https://unpkg.com/lemma-sdk@latest/dist/browser/lemma-client.js"></script>
287
- <script>
288
- const client = new window.LemmaClient.LemmaClient({
289
- apiUrl: "https://api.lemma.work",
290
- authUrl: "https://auth.lemma.work/auth",
291
- podId: "<pod-id>"
292
- });
293
- </script>
294
- ```
331
+ - `registry.json` for registry source definitions
332
+ - `public/r` for the generated flat registry output
333
+ - `.github/workflows/deploy-registry-pages.yml` for GitHub Pages deployment
334
+ - `.github/workflows/publish-npm.yml` for npm publishing
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
4
+ import { resolve } from "node:path";
5
+
6
+ const SHADCN_SCHEMA_URL = "https://ui.shadcn.com/schema.json";
7
+ const LEMMA_REGISTRY_URL =
8
+ "https://cdn.jsdelivr.net/gh/gappyai/lemma-typescript@main/public/r/{name}.json";
9
+
10
+ function printUsage() {
11
+ console.log(`Usage:
12
+ lemma-sdk init-shadcn
13
+
14
+ Commands:
15
+ init-shadcn Add the @lemma shadcn registry to components.json in the current directory.`);
16
+ }
17
+
18
+ function fail(message) {
19
+ console.error(`lemma-sdk: ${message}`);
20
+ process.exit(1);
21
+ }
22
+
23
+ function ensureObject(value, label) {
24
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
25
+ fail(`${label} must be a JSON object.`);
26
+ }
27
+
28
+ return value;
29
+ }
30
+
31
+ function loadComponentsConfig(configPath) {
32
+ if (!existsSync(configPath)) {
33
+ return {
34
+ config: {
35
+ $schema: SHADCN_SCHEMA_URL,
36
+ registries: {},
37
+ },
38
+ existed: false,
39
+ };
40
+ }
41
+
42
+ let parsed;
43
+ try {
44
+ parsed = JSON.parse(readFileSync(configPath, "utf8"));
45
+ } catch (error) {
46
+ const message = error instanceof Error ? error.message : String(error);
47
+ fail(`Could not parse ${configPath}: ${message}`);
48
+ }
49
+
50
+ const config = ensureObject(parsed, "components.json");
51
+
52
+ if (config.$schema == null) {
53
+ config.$schema = SHADCN_SCHEMA_URL;
54
+ }
55
+
56
+ if (config.registries == null) {
57
+ config.registries = {};
58
+ }
59
+
60
+ ensureObject(config.registries, "components.json registries");
61
+
62
+ return {
63
+ config,
64
+ existed: true,
65
+ };
66
+ }
67
+
68
+ function writeComponentsConfig(configPath, config) {
69
+ writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, "utf8");
70
+ }
71
+
72
+ function initShadcn() {
73
+ const configPath = resolve(process.cwd(), "components.json");
74
+ const { config, existed } = loadComponentsConfig(configPath);
75
+
76
+ const currentUrl = config.registries["@lemma"];
77
+ const alreadyConfigured = currentUrl === LEMMA_REGISTRY_URL;
78
+
79
+ config.registries["@lemma"] = LEMMA_REGISTRY_URL;
80
+ writeComponentsConfig(configPath, config);
81
+
82
+ if (alreadyConfigured) {
83
+ console.log(`@lemma is already configured in ${configPath}`);
84
+ } else if (existed) {
85
+ console.log(`Added @lemma registry to ${configPath}`);
86
+ } else {
87
+ console.log(`Created ${configPath} with the @lemma registry`);
88
+ console.log("If you have not initialized shadcn yet, run: npx shadcn@latest init");
89
+ }
90
+
91
+ console.log(`Registry URL: ${LEMMA_REGISTRY_URL}`);
92
+ }
93
+
94
+ const command = process.argv[2];
95
+
96
+ switch (command) {
97
+ case "init-shadcn":
98
+ initShadcn();
99
+ break;
100
+ case "-h":
101
+ case "--help":
102
+ case "help":
103
+ case undefined:
104
+ printUsage();
105
+ break;
106
+ default:
107
+ fail(`Unknown command "${command}". Run "lemma-sdk --help" for usage.`);
108
+ }