@softr/sdk 0.0.90-alpha.1 → 0.0.90-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.
@@ -1,4 +1,4 @@
1
- import * as react6 from "react";
1
+ import * as react4 from "react";
2
2
 
3
3
  //#region src/default-error-overlay.d.ts
4
4
  type Props = {
@@ -8,6 +8,6 @@ type Props = {
8
8
  declare function DefaultErrorOverlay({
9
9
  error,
10
10
  reset
11
- }: Props): react6.JSX.Element;
11
+ }: Props): react4.JSX.Element;
12
12
  //#endregion
13
13
  export { DefaultErrorOverlay };
package/dist/mcp.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { DatasourceAction } from "./action.js";
2
- import * as _tanstack_react_start6 from "@tanstack/react-start";
2
+ import * as _tanstack_react_start0 from "@tanstack/react-start";
3
3
 
4
4
  //#region src/mcp.d.ts
5
5
 
@@ -31,6 +31,6 @@ type SoftrMcpOptions = {
31
31
  * ],
32
32
  * }))
33
33
  */
34
- declare function softrMcpMiddleware(options?: SoftrMcpOptions): _tanstack_react_start6.RequestMiddlewareAfterServer<{}, undefined, undefined>;
34
+ declare function softrMcpMiddleware(options?: SoftrMcpOptions): _tanstack_react_start0.RequestMiddlewareAfterServer<{}, undefined, undefined>;
35
35
  //#endregion
36
36
  export { softrMcpMiddleware };
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.0.90-alpha.1";
2
+ var version = "0.0.90-alpha.2";
3
3
 
4
4
  //#endregion
5
5
  export { version };
package/dist/pwa.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import * as react4 from "react";
1
+ import * as react5 from "react";
2
2
  import "@tanstack/react-start";
3
3
 
4
4
  //#region src/pwa.d.ts
@@ -23,7 +23,7 @@ import "@tanstack/react-start";
23
23
  * )
24
24
  * }
25
25
  */
26
- declare function SoftrPwaHead(): react4.FunctionComponentElement<react4.FragmentProps>;
26
+ declare function SoftrPwaHead(): react5.FunctionComponentElement<react5.FragmentProps>;
27
27
  type PwaPlatform = "ios" | "android" | "desktop";
28
28
  type PwaInstall = {
29
29
  available: false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softr/sdk",
3
- "version": "0.0.90-alpha.1",
3
+ "version": "0.0.90-alpha.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" },
@@ -9,7 +9,7 @@ description: >-
9
9
  metadata:
10
10
  type: core
11
11
  library: softr-sdk
12
- library_version: 0.0.90-alpha.1
12
+ library_version: 0.0.90-alpha.2
13
13
  ---
14
14
 
15
15
  # Softr SDK core
@@ -12,7 +12,7 @@ description: >-
12
12
  metadata:
13
13
  type: sub-skill
14
14
  library: softr-sdk
15
- library_version: 0.0.90-alpha.1
15
+ library_version: 0.0.90-alpha.2
16
16
  ---
17
17
 
18
18
  **Boundary.** `listAgents` and `useAgentChat` live on `@softr/sdk`. `listAgents` runs in a route loader, `useAgentChat` in a component. Neither needs a route, server function or registration of its own. It chats as the signed-in visitor, or anonymously when no one is signed in.
@@ -85,38 +85,30 @@ A `tool` with status `awaiting-connection` needs the visitor's own `integration`
85
85
 
86
86
  ## The chat panel
87
87
 
88
- Classic Softr apps ship a chat panel. Visitors expect the same from yours:
88
+ Visitors expect the panel classic Softr apps ship:
89
89
 
90
- - A round `primary` button in a corner opens it: about 56px, a soft shadow, the agent's avatar or a chat icon. It hides while the panel is open.
91
- - The panel opens on the right on desktop, about 420px wide with a left border and a large shadow, and full screen on mobile.
92
- - The header shows the agent's avatar and name, a picker when there are several agents, new chat, past chats and close.
93
- - An empty chat greets the visitor with the agent's avatar.
94
- - The list scrolls to the newest message as the reply streams, until the visitor scrolls up. Then a button takes them back down.
90
+ - A round `primary` button in a corner opens it, with the agent's avatar or a chat icon. It hides while the panel is open.
91
+ - A right-side panel, about 420px, full screen on mobile.
92
+ - Header: avatar, name, agent picker when there are several, new chat, past chats, close.
93
+ - The list follows the streaming reply until the visitor scrolls up, then offers a jump back down.
95
94
  - Text renders as Markdown, tables included.
96
- - The input says "Ask {agent title}…". Enter sends. Shift+Enter adds a line.
97
- - A line under the input: "AI can make mistakes. Please double-check responses."
95
+ - The input says "Ask {agent title}…". Enter sends, Shift+Enter adds a line. Under it: "AI can make mistakes. Please double-check responses."
98
96
  - An answered question stays locked.
99
- - A tool's `input` is JSON. Show it readable: one `Label: value` line per field, with line breaks kept, never the raw JSON. Leave out `thought`, `input`, `error` or the duration when it's empty.
100
- - A tool that needs the visitor's account shows a Connect button.
97
+ - A tool's `input` shows as `Label: value` lines, never raw JSON. Empty `thought`, `input`, `error` or duration are left out.
101
98
 
102
99
  ## How it looks
103
100
 
104
- The chat is the visitor's first impression of the agent. These are defaults for the first build. When the builder asks for a different look, follow them instead.
105
-
106
- - **The app's own look.** Build it from the app's own primitives and match its pages, so it never reads as a third-party widget.
107
- - **One loud thing at a time.** The answer is the content. Tool lines stay quiet. Only a block that waits for the visitor (approve, connect, question) stands out.
108
- - **Layout.** Three zones: a fixed header, the scrolling messages, a fixed composer. Use `text-sm` throughout.
109
- - **Header.** A small round avatar, the agent's name, and a muted line under it (the agent picker, when there are several). Actions are ghost icon buttons with tooltips.
110
- - **Visitor messages.** Right-aligned bubbles in `primary`, generously rounded, at most 85% wide.
111
- - **Agent replies.** No bubble. Full width on the background, with a small avatar at the start of each reply, so long answers and tables read like a page.
112
- - **Markdown.** Comfortable paragraph and list spacing. Inline code on `muted`. Tables bordered, in a horizontal scroll wrapper, never wider than the panel. Links in `primary`.
113
- - **Tools.** One `text-xs` muted line with a status icon: a spinner while running, a check when done, an alert on error. Click to expand.
114
- - **Blocks that wait for the visitor.** A `card` with a border, a rounded corner and padding: a one-line title, a short explanation, buttons on the right. The main action is `primary`, the other `outline`.
115
- - **Thinking.** Where the reply will appear, a muted "Thinking…" with a gentle pulse or shimmer.
116
- - **Empty chat.** Centred: a large avatar, "Hi, I'm {agent title}", one muted line inviting a question. Add two to four suggestion chips only when the builder said what the agent does; they send on click.
117
- - **Composer.** One rounded, bordered box that holds the textarea and an icon send button in its corner, with the focus ring on the box. The textarea grows to about six lines, then scrolls. The disclaimer sits under it in `text-xs` muted, centred.
118
- - **Spacing.** Clear space between turns, tight space inside a turn.
119
- - **Motion.** The panel slides in and new messages fade in, both short, and they respect reduced motion. Nothing bounces.
101
+ Defaults for the first build. The builder's prompt overrides them.
102
+
103
+ - Reuse the app's own components and styles: its Markdown renderer, cards, buttons, avatars. Add no copies and no new colours.
104
+ - One loud thing at a time. Tool lines stay quiet; only a block waiting for the visitor stands out.
105
+ - Visitor messages are right-aligned `primary` bubbles. Agent replies have no bubble and run full width, so tables read like a page.
106
+ - A tool is one muted `text-xs` line with a status icon, expandable.
107
+ - Approve, connect and questions sit in a `card`: a title, a short line, the main action `primary`.
108
+ - While `thinking`, a muted pulsing "Thinking…" where the reply will appear.
109
+ - An empty chat shows a large avatar and "Hi, I'm {agent title}". Add suggestion chips only when the builder said what the agent does.
110
+ - The composer is one rounded box holding the textarea and send button. It grows to about six lines.
111
+ - Short slide and fade motion that respects reduced motion.
120
112
 
121
113
  ## Context
122
114
 
@@ -128,6 +120,13 @@ The page title and URL go along on their own. Nothing else about the page does,
128
120
 
129
121
  The agent reads and changes data through the app's own MCP, as the visitor who is chatting. Their groups and each action's `permissions` apply. The actions it may use are the ones listed in `softrMcpMiddleware`. With no MCP wired, the agent can only talk. Load [mcp/SKILL.md](../mcp/SKILL.md) to wire it.
130
122
 
123
+ **The agent calls a listed action directly, with any input.** Pages and server functions are skipped, so the action's `permissions` are its only guard: a read returns every row those groups may see, an update or delete takes any id.
124
+
125
+ - List the app's existing actions. Don't define copies for the agent.
126
+ - Narrow `permissions` to who may really run it. When roles differ, split the action: each writes only that role's fields, with `customGroups` for that role.
127
+ - Don't list an action that is only safe for a visitor's own records. Nothing scopes it to them.
128
+ - Tell the builder which actions the agent can use and who may run each one.
129
+
131
130
  ## Failure modes
132
131
 
133
132
  **Building a chat without the hook.** Calling the agents service from the browser fails: only the app's server can sign the request in as the visitor. Use `useAgentChat`.
@@ -136,6 +135,8 @@ The agent reads and changes data through the app's own MCP, as the visitor who i
136
135
 
137
136
  **The hook inside a panel that unmounts when it closes.** Closing it stops a reply that is still coming. Call `useAgentChat` in the component that owns the open state, such as `AppLayout` in `src/routes/_app.tsx`, and pass `chat` into the panel. Keep the selected agent there too, or closing the panel resets it.
138
137
 
138
+ **One action for every role.** An update any signed-in visitor may run, writing the status, lets an employee have the agent approve their own vacation request. Give approve its own action, limited to managers.
139
+
139
140
  **An agent id written by hand.** The chat fails on the first message, and an agent hidden from the visitor still shows. Take the id from `listAgents`.
140
141
 
141
142
  ## References
@@ -9,7 +9,7 @@ description: >-
9
9
  metadata:
10
10
  type: sub-skill
11
11
  library: softr-sdk
12
- library_version: 0.0.90-alpha.1
12
+ library_version: 0.0.90-alpha.2
13
13
  ---
14
14
 
15
15
  **Boundary.** `auth` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler — importing it into a component fails the build.
@@ -9,7 +9,7 @@ description: >-
9
9
  metadata:
10
10
  type: sub-skill
11
11
  library: softr-sdk
12
- library_version: 0.0.90-alpha.1
12
+ library_version: 0.0.90-alpha.2
13
13
  ---
14
14
 
15
15
  **Boundary.** `ds` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler or a server-side route hook — importing it into a component fails the build. `defineQuery` and every type come from `@softr/sdk` and can be imported anywhere.
@@ -9,7 +9,7 @@ description: >-
9
9
  metadata:
10
10
  type: sub-skill
11
11
  library: softr-sdk
12
- library_version: 0.0.90-alpha.1
12
+ library_version: 0.0.90-alpha.2
13
13
  ---
14
14
 
15
15
  # The current user
@@ -7,7 +7,7 @@ description: >-
7
7
  metadata:
8
8
  type: sub-skill
9
9
  library: softr-sdk
10
- library_version: 0.0.90-alpha.1
10
+ library_version: 0.0.90-alpha.2
11
11
  ---
12
12
 
13
13
  **Boundary.** `upload` lives on `@softr/sdk/server` and runs inside server functions. `useFileUpload` and `FileItem` live on `@softr/sdk` and run in components. `FileAttachment` comes from `@softr/sdk` and can be imported anywhere.
@@ -8,7 +8,7 @@ description: >-
8
8
  metadata:
9
9
  type: sub-skill
10
10
  library: softr-sdk
11
- library_version: 0.0.90-alpha.1
11
+ library_version: 0.0.90-alpha.2
12
12
  ---
13
13
 
14
14
  # Dates, times and numbers
@@ -7,7 +7,7 @@ description: >-
7
7
  metadata:
8
8
  type: sub-skill
9
9
  library: softr-sdk
10
- library_version: 0.0.90-alpha.1
10
+ library_version: 0.0.90-alpha.2
11
11
  ---
12
12
 
13
13
  **Boundary.** `integration` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler — importing it into a component fails the build. `defineIntegration` and every type come from `@softr/sdk` and can be imported anywhere.
@@ -9,7 +9,7 @@ description: >-
9
9
  metadata:
10
10
  type: sub-skill
11
11
  library: softr-sdk
12
- library_version: 0.0.90-alpha.1
12
+ library_version: 0.0.90-alpha.2
13
13
  ---
14
14
 
15
15
  **Boundary.** `softrMcpMiddleware` lives on `@softr/sdk` and is registered once, in `src/start.ts`. The actions you hand it are the same `defineQuery` / `defineMutation` values the app's own pages use — declared wherever they already live, not duplicated for MCP.
@@ -9,7 +9,7 @@ description: >-
9
9
  metadata:
10
10
  type: sub-skill
11
11
  library: softr-sdk
12
- library_version: 0.0.90-alpha.1
12
+ library_version: 0.0.90-alpha.2
13
13
  ---
14
14
 
15
15
  # Installing the app
@@ -8,7 +8,7 @@ description: >-
8
8
  metadata:
9
9
  type: sub-skill
10
10
  library: softr-sdk
11
- library_version: 0.0.90-alpha.1
11
+ library_version: 0.0.90-alpha.2
12
12
  ---
13
13
 
14
14
  **Boundary.** `ds` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler — importing it into a component fails the build. `defineMutation` and every type come from `@softr/sdk` and can be imported anywhere.
@@ -9,7 +9,7 @@ description: >-
9
9
  metadata:
10
10
  type: sub-skill
11
11
  library: softr-sdk
12
- library_version: 0.0.90-alpha.1
12
+ library_version: 0.0.90-alpha.2
13
13
  ---
14
14
 
15
15
  **Boundary.** `ds` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler or a server-side route hook — importing it into a component fails the build. The same holds for any helper that calls `ds`: declare it inside the handler. A function at module level that calls `ds` keeps the server-only import in the browser bundle, and every page stops loading until it moves. `defineQuery` and every type come from `@softr/sdk` and can be imported anywhere.
@@ -9,7 +9,7 @@ description: >-
9
9
  metadata:
10
10
  type: sub-skill
11
11
  library: softr-sdk
12
- library_version: 0.0.90-alpha.1
12
+ library_version: 0.0.90-alpha.2
13
13
  ---
14
14
 
15
15
  **Boundary.** `Audience` and `defineVisibility` come from `@softr/sdk` and work anywhere.
@@ -9,7 +9,7 @@ description: >-
9
9
  metadata:
10
10
  type: sub-skill
11
11
  library: softr-sdk
12
- library_version: 0.0.90-alpha.1
12
+ library_version: 0.0.90-alpha.2
13
13
  ---
14
14
 
15
15
  **Boundary.** `definePage`, `pageHead`, the access functions and the error predicates come from `@softr/sdk` and work anywhere.
@@ -9,7 +9,7 @@ description: >-
9
9
  metadata:
10
10
  type: sub-skill
11
11
  library: softr-sdk
12
- library_version: 0.0.90-alpha.1
12
+ library_version: 0.0.90-alpha.2
13
13
  ---
14
14
 
15
15
  **Boundary.** `workflow` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler — importing it into a component fails the build. `defineWorkflow` and every type come from `@softr/sdk` and can be imported anywhere.