create-theokit 1.23.12 → 1.24.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-theokit",
3
- "version": "1.23.12",
3
+ "version": "1.24.0",
4
4
  "type": "module",
5
5
  "description": "Scaffold a new TheoKit project",
6
6
  "repository": {
@@ -79,6 +79,24 @@ your environment.
79
79
  Deeper detail lives in [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md);
80
80
  customization and environment variables have their own pages beside it.
81
81
 
82
+ ## What is already installed
83
+
84
+ Two component libraries come with this template, and the split is by **what a component is for**,
85
+ not by how generic it looks:
86
+
87
+ | You need | Import from | Examples |
88
+ | --- | --- | --- |
89
+ | Agent surfaces — chat, streaming, tool calls, approvals | **`@theokit/ui`** | `ChatThread`, `ChatMessage`, `ChatComposer`, `ToolCallCard`, `AgentStream` |
90
+ | App chrome — shell, navigation, tables, forms, feedback | **`@usetheo/ui`** | `Sidebar`, `PageShell`, `DataTable`, `Select`, `FormField`, `Badge`, `EmptyState`, `Alert`, `Dialog`, `CommandPalette` |
91
+
92
+ This template uses a handful of them. The rest are installed and waiting — **check before you write
93
+ markup by hand.** A real app built on this scaffold hand-wrote around 600 lines of navigation, rows,
94
+ filters, badges and empty states that already existed in these two packages
95
+ (usetheokit/theokit#471).
96
+
97
+ The catalogue is `node_modules/@theokit/ui/llms.txt` — written to be read by an agent, and it
98
+ carries the routing table above in full.
99
+
82
100
  ## Adding a screen
83
101
 
84
102
  Routing is file-based: a screen is a folder under `app/` with a `page.tsx`.
@@ -15,13 +15,23 @@ export default function RootLayout() {
15
15
  <div className="grid h-screen w-screen grid-rows-[auto_1fr] bg-background text-foreground">
16
16
  <Header />
17
17
  {/*
18
+ `<main>` SCROLLS. The shell pins itself to the viewport (`h-screen`), so the document never
19
+ scrolls and something inside has to — and the default is here, where an ordinary page gets
20
+ it for free. It used to be `overflow-hidden`, which is right for the chat and wrong for
21
+ every other page: content below the fold was simply unreachable, with nothing to explain it
22
+ (usetheokit/theokit#484). A page with the unusual requirement declares it; the common one
23
+ should not have to.
24
+
25
+ `min-h-0` is the non-obvious half. This is a grid child, and a grid/flex child defaults to
26
+ `min-height: auto` — it refuses to shrink below its content, so `overflow-y-auto` alone does
27
+ nothing at all. Whatever you scroll, it needs both.
28
+
18
29
  `data-theo-scroll` marks this as a scroll container, so its offset is restored on back
19
30
  navigation (usetheokit/theokit#421). Browsers and react-router only ever restore the
20
- DOCUMENT; in a shell like this one the document never scrolls, so without the marker there
21
- is nothing to restore. The value is the id — add the attribute to any other element you
22
- scroll, with a different value.
31
+ DOCUMENT, which here never scrolls, so without the marker there is nothing to restore. The
32
+ value is the id — add the attribute to any other element you scroll, with a different value.
23
33
  */}
24
- <main data-theo-scroll="main" className="flex h-full flex-col overflow-hidden">
34
+ <main data-theo-scroll="main" className="min-h-0 overflow-y-auto">
25
35
  <Outlet />
26
36
  </main>
27
37
  </div>
@@ -39,21 +39,31 @@ export default function Page() {
39
39
  return (
40
40
  <>
41
41
  <Metadata title="TheoKit agent" description="Chat with your TheoKit agent." />
42
- <ChatPanel
43
- thread={thread}
44
- isStreaming={isStreaming}
45
- onlyGreeting={onlyGreeting}
46
- onStarter={handleSubmit}
47
- />
48
- <Composer
49
- value={composerValue}
50
- onValueChange={setComposerValue}
51
- onSubmit={handleSubmit}
52
- running={isStreaming}
53
- hasError={hasError}
54
- error={error}
55
- onNewChat={newChat}
56
- />
42
+ {/*
43
+ The chat is the page that does NOT want the shell's scroll: the log scrolls inside itself
44
+ and the composer stays pinned to the bottom, which `overflow-hidden` is what produces. So it
45
+ declares that here rather than imposing it on every other page from the layout (#484).
46
+
47
+ `h-full` fills the routed slot; `min-h-0` lets this box shrink below its content so the
48
+ child's own scroll works — the same pair the layout comment describes.
49
+ */}
50
+ <div className="flex h-full min-h-0 flex-col overflow-hidden">
51
+ <ChatPanel
52
+ thread={thread}
53
+ isStreaming={isStreaming}
54
+ onlyGreeting={onlyGreeting}
55
+ onStarter={handleSubmit}
56
+ />
57
+ <Composer
58
+ value={composerValue}
59
+ onValueChange={setComposerValue}
60
+ onSubmit={handleSubmit}
61
+ running={isStreaming}
62
+ hasError={hasError}
63
+ error={error}
64
+ onNewChat={newChat}
65
+ />
66
+ </div>
57
67
  </>
58
68
  )
59
69
  }
@@ -25,17 +25,21 @@ paths:
25
25
  ```typescript
26
26
  import { theoFetch } from 'theokit/client'
27
27
 
28
- // Typed fetchparams and response inferred from server routes
28
+ // The URL is used literally build it yourself for a dynamic route.
29
29
  const tasks = await theoFetch('/api/tasks')
30
- const task = await theoFetch('/api/tasks/:id', { params: { id: 1 } })
30
+ const task = await theoFetch(`/api/tasks/${id}`)
31
31
 
32
- // POST with body
32
+ // POST with body. `method` is REQUIRED when the route declares one.
33
33
  const created = await theoFetch('/api/tasks', {
34
34
  method: 'POST',
35
35
  body: { title: 'New task' },
36
36
  })
37
37
  ```
38
38
 
39
+ `theoFetch` has **no `params` option.** Its options are `RequestInit` minus `body`/`method`, plus a
40
+ conditional `query` and `body` — nothing interpolates a `:id` segment for you. Reach for the
41
+ generated client below when you want that; it is the half that knows your route tree.
42
+
39
43
  ## App Client (proxy-based)
40
44
 
41
45
  ```typescript
@@ -43,11 +47,22 @@ import { createAppClient } from 'theokit/client'
43
47
 
44
48
  const client = createAppClient()
45
49
 
46
- const tasks = await client.tasks.GET()
47
- const task = await client.tasks[':id'].GET({ params: { id: 1 } })
48
- const created = await client.tasks.POST({ body: { title: 'New' } })
50
+ const tasks = await client.tasks.get()
51
+ const task = await client.tasks.id.get({ params: { id: '42' } }) // → GET /api/tasks/42
52
+ const created = await client.tasks.post({ body: { title: 'New' } })
49
53
  ```
50
54
 
55
+ Three details the generator decides for you, and each is easy to guess wrong:
56
+
57
+ - **methods are lowercase** — `get`, `post`; the export in your route file stays `GET`
58
+ - **a dynamic segment loses its colon** — `app/tasks/[id]` is reached as `client.tasks.id`, not
59
+ `client.tasks[':id']`
60
+ - **`params` values are strings** — `{ id: '42' }`; a URL segment has no other type
61
+
62
+ Segments are otherwise kept **literal**, so a hyphenated route needs bracket access:
63
+ `client['agents-config'].get()`. The client mirrors your URLs rather than prettifying them — a
64
+ camelCased key once produced a request to a path no route served.
65
+
51
66
  ## Agent Streaming
52
67
 
53
68
  Two client APIs from `theokit/client`:
@@ -16,9 +16,25 @@ paths:
16
16
 
17
17
  `@theokit/ui` is an optional peer dependency. If installed, it provides ready-made AI components for chat + coding-agent surfaces (chat thread, agent events, tool calls, diff viewer, build logs), plus theming. **Never build custom equivalents** of components it provides. Generic primitives (Button, Input, Card, CodeBlock, PageShell, Sidebar, Avatar, Alert, etc.) live in `@usetheo/ui`, which `@theokit/ui` depends on — import those from `@usetheo/ui`.
18
18
 
19
+ ## Read the catalogue before writing markup
20
+
21
+ `@theokit/ui` ships **`llms.txt`** — a file written for an agent to read, at
22
+ `node_modules/@theokit/ui/llms.txt`. It lists every component with its purpose and, in a
23
+ **"Which package has what"** table, routes each need to the right package. Read it before building a
24
+ sidebar, a table, a select, a badge or an empty state by hand.
25
+
26
+ That is not a style preference. A real app built on this scaffold hand-wrote ~600 lines of markup —
27
+ navigation, queue rows, filters, status badges, empty states, a composer — and **every one of them
28
+ already existed** in the two packages the scaffold had installed (usetheokit/theokit#471). The
29
+ components were there; nothing pointed at them.
30
+
31
+ `@usetheo/ui` has no `llms.txt`; its surface is in its own README and its type definitions.
32
+
19
33
  ## Package Identity
20
34
 
21
- `@theokit/ui` (AI-native, currently `1.0.0`) provides the AI-agent-surface components. Its generic foundation was split into `@usetheo/ui` in the 2026-07-03 AI-exclusive pivot; `@theokit/ui` depends on `@usetheo/ui`, so installing `@theokit/ui` pulls the foundation transitively.
35
+ `@theokit/ui` provides the AI-agent-surface components. (The version this project uses is in
36
+ `package.json`; a number written here goes stale the first time anyone upgrades, and this one
37
+ said `1.0.0` while npm served `1.5.1`.) Its generic foundation was split into `@usetheo/ui` in the 2026-07-03 AI-exclusive pivot; `@theokit/ui` depends on `@usetheo/ui`, so installing `@theokit/ui` pulls the foundation transitively.
22
38
 
23
39
  ```bash
24
40
  # Install from npm (preferred)
@@ -16,7 +16,7 @@
16
16
  "typecheck": "tsc --noEmit"
17
17
  },
18
18
  "dependencies": {
19
- "theokit": "^0.53.0",
19
+ "theokit": "^0.55.0",
20
20
  "@theokit/agents": "^10.1.0",
21
21
  "@theokit/sdk": "^4.52.1",
22
22
  "@theokit/ui": "^1.1.0",