@lumerahq/cli 0.10.0 → 0.11.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.
Files changed (35) hide show
  1. package/dist/chunk-CHRKCAIZ.js +155 -0
  2. package/dist/{chunk-WRAZC6SJ.js → chunk-HIYM7EM2.js} +17 -1
  3. package/dist/dev-2HVDP3NX.js +155 -0
  4. package/dist/index.js +166 -14
  5. package/dist/init-VNJNSU4Q.js +440 -0
  6. package/dist/{resources-PGBVCS2K.js → resources-GTG3QMVV.js} +2 -4
  7. package/dist/{run-WIRQDYYX.js → run-47GF5VVS.js} +2 -4
  8. package/dist/templates-6KMZWOYH.js +194 -0
  9. package/package.json +1 -1
  10. package/dist/chunk-2CR762KB.js +0 -18
  11. package/dist/dev-BHBF4ECH.js +0 -87
  12. package/dist/init-EDSRR3YM.js +0 -360
  13. package/templates/default/ARCHITECTURE.md +0 -80
  14. package/templates/default/CLAUDE.md +0 -238
  15. package/templates/default/README.md +0 -59
  16. package/templates/default/biome.json +0 -38
  17. package/templates/default/gitignore +0 -9
  18. package/templates/default/index.html +0 -13
  19. package/templates/default/package.json.hbs +0 -47
  20. package/templates/default/platform/automations/.gitkeep +0 -0
  21. package/templates/default/platform/collections/example_items.json +0 -26
  22. package/templates/default/platform/hooks/.gitkeep +0 -0
  23. package/templates/default/pyproject.toml.hbs +0 -14
  24. package/templates/default/scripts/seed-demo.py +0 -35
  25. package/templates/default/src/components/Sidebar.tsx +0 -82
  26. package/templates/default/src/components/StatCard.tsx +0 -25
  27. package/templates/default/src/components/layout.tsx +0 -13
  28. package/templates/default/src/lib/queries.ts +0 -27
  29. package/templates/default/src/main.tsx +0 -131
  30. package/templates/default/src/routes/__root.tsx +0 -10
  31. package/templates/default/src/routes/index.tsx +0 -88
  32. package/templates/default/src/routes/settings.tsx +0 -21
  33. package/templates/default/src/styles.css +0 -44
  34. package/templates/default/tsconfig.json +0 -23
  35. package/templates/default/vite.config.ts +0 -28
@@ -1,238 +0,0 @@
1
- # {{projectTitle}} - Claude Code Instructions
2
-
3
- **Full Architecture**: See `ARCHITECTURE.md`
4
-
5
- ---
6
-
7
- ## AI Agent Skills
8
-
9
- This project includes Lumera skills for AI coding agents in `.claude/skills/`. Read the relevant skill file when you need detailed API docs and usage patterns for that capability.
10
-
11
- <!-- LUMERA_SKILLS_START -->
12
- _Run `lumera skills install` to populate skill descriptions._
13
- <!-- LUMERA_SKILLS_END -->
14
-
15
- ### Managing Skills
16
-
17
- ```bash
18
- lumera skills update # Update all skills to latest
19
- lumera skills install --force # Re-install from scratch
20
- ```
21
-
22
- ---
23
-
24
- ## Quick Reference
25
-
26
- ### Lumera CLI
27
-
28
- All `lumera` commands are run via `pnpm dlx`:
29
-
30
- ```bash
31
- # Shortcuts
32
- pnpm dev # Start dev server
33
- pnpm deploy # Deploy frontend
34
-
35
- # All other commands
36
- pnpm dlx @lumerahq/cli plan
37
- pnpm dlx @lumerahq/cli apply
38
- pnpm dlx @lumerahq/cli destroy
39
- pnpm dlx @lumerahq/cli run scripts/seed-demo.py
40
- pnpm dlx @lumerahq/cli status
41
- ```
42
-
43
- ### Running the Frontend
44
-
45
- ```bash
46
- # Login first (stores credentials in .lumera/credentials.json)
47
- lumera login
48
-
49
- # Start dev server
50
- pnpm dev
51
-
52
- # With custom port
53
- lumera dev --port 3000
54
-
55
- # With ngrok tunnel
56
- lumera dev --url https://my-tunnel.ngrok.io
57
-
58
- # Plain vite (no Lumera registration)
59
- pnpm dev:vite
60
- ```
61
-
62
- ### Linting & Formatting
63
-
64
- ```bash
65
- # Type check without emitting
66
- pnpm typecheck
67
-
68
- # Lint and auto-fix
69
- pnpm lint
70
-
71
- # Format code
72
- pnpm format
73
-
74
- # Run all checks (lint + format + typecheck) - use in CI
75
- pnpm check:ci
76
- ```
77
-
78
- ### Deploying
79
-
80
- ```bash
81
- # Deploy frontend
82
- lumera apply app
83
-
84
- # Apply all resources (collections, automations, hooks, app)
85
- lumera apply
86
-
87
- # Preview changes first
88
- lumera plan
89
- ```
90
-
91
- ### Running Scripts
92
-
93
- All scripts are **idempotent** - safe to run multiple times during iterative development.
94
-
95
- ```bash
96
- # Run a script locally
97
- lumera run scripts/seed-demo.py
98
-
99
- # Dependencies can be declared inline (PEP 723)
100
- ```
101
-
102
- ### Running Automations via External ID
103
-
104
- Always run automations using their `external_id` (not the internal Lumera ID which changes per tenant).
105
-
106
- ```python
107
- uv run python << 'EOF'
108
- from lumera import automations
109
-
110
- # Run automation by external_id (returns Run object immediately)
111
- run = automations.run_by_external_id(
112
- "{{projectName}}:my_automation",
113
- inputs={"param": "value"}
114
- )
115
- print(f"Run ID: {run.id}")
116
- print(f"Status: {run.status}")
117
-
118
- # Wait for completion (blocks until done or timeout)
119
- result = run.wait(timeout=600) # 10 min timeout
120
- print(f"Result: {result}")
121
- EOF
122
- ```
123
-
124
- **Run object properties**: `id`, `status`, `result`, `error`, `inputs`, `is_terminal`
125
- **Run object methods**: `wait(timeout)`, `refresh()`, `cancel()`
126
- **Status values**: `queued`, `running`, `succeeded`, `failed`, `cancelled`, `timeout`
127
-
128
- ---
129
-
130
- ## Important Rules
131
-
132
- 1. **Authenticate first** - Before running any CLI or SDK commands, ensure the user has run `lumera login`. This stores credentials in `.lumera/credentials.json` which the SDK reads automatically.
133
-
134
- 2. **Source of truth is code** - `platform/` contains all schemas, automations, hooks. Update local code first, then deploy.
135
-
136
- 3. **Never edit Lumera directly** - Don't change data/schema in Lumera UI without explicit user approval.
137
-
138
- 4. **Offer to deploy** - When schemas, hooks, or automations change, offer to deploy to Lumera.
139
-
140
- 5. **Use lumera-sdk skill for Python** - When writing scripts or automations, refer to the **lumera-sdk** skill (`.claude/skills/lumera-sdk.md`) for available SDK functions and usage patterns. The SDK source code is also available in `.venv/lib/python*/site-packages/lumera/` for detailed implementation reference. Key modules:
141
- - `lumera.pb` - Record and collection operations (search, get, create, update, delete)
142
- - `lumera.storage` - File uploads and downloads
143
- - `lumera.llm` - LLM completions
144
- - `lumera.automations` - Running and managing automations
145
- - `lumera.integrations` - Third-party integrations (Google, Slack, etc.)
146
-
147
- 6. **Use Python SDK for ad-hoc investigation** - When you need to quickly query data, inspect records, or debug issues, use the Python SDK with `uv run python` (uses `.venv` automatically via `pyproject.toml`):
148
- ```bash
149
- uv run python -c "from lumera import pb; print(pb.search('collection_name'))"
150
- ```
151
-
152
- ---
153
-
154
- ## Key Directories
155
-
156
- ```
157
- platform/
158
- ├── automations/ # Automation scripts (Python)
159
- ├── collections/ # Collection schemas (JSON)
160
- └── hooks/ # Server-side JavaScript hooks
161
-
162
- scripts/ # Local scripts (seed, migrate, etc.)
163
-
164
- src/ # React frontend
165
- ├── routes/ # TanStack Router pages
166
- ├── lib/ # queries.ts, api helpers
167
- └── components/ # React components
168
-
169
- .venv/ # Python venv with lumera SDK (for IDE autocomplete)
170
- ```
171
-
172
- ### Python Environment
173
-
174
- A Python virtual environment is created at `.venv/` with the `lumera` SDK pre-installed. This provides IDE autocomplete when writing automations and scripts.
175
-
176
- ```bash
177
- # Activate venv (optional - for IDE integration)
178
- source .venv/bin/activate
179
-
180
- # SDK is available for import
181
- python -c "from lumera import pb; print(pb)"
182
- ```
183
-
184
- > **Note:** You don't need to activate the venv to run scripts - `lumera run` handles this automatically.
185
-
186
- ---
187
-
188
- ## Frontend Patterns
189
-
190
- ### Fetching Data
191
-
192
- ```typescript
193
- import { pbSql, pbList } from '@lumerahq/ui/lib';
194
-
195
- const result = await pbSql<{ id: string; name: string }>({
196
- sql: 'SELECT id, name FROM users WHERE active = true'
197
- });
198
-
199
- const items = await pbList<User>('users', {
200
- filter: JSON.stringify({ status: "active" }),
201
- sort: '-created',
202
- perPage: 50,
203
- });
204
- ```
205
-
206
- ### Running Automations from Frontend
207
-
208
- ```typescript
209
- import { createRun, pollRun } from '@lumerahq/ui/lib';
210
-
211
- const run = await createRun({
212
- automationId: '{{projectName}}:process_data',
213
- inputs: { file_id: 'abc123' },
214
- });
215
-
216
- const result = await pollRun(run.id);
217
- ```
218
-
219
- ---
220
-
221
- ## Debugging with Lumera SDK
222
-
223
- ```python
224
- uv run python << 'EOF'
225
- from lumera import pb
226
-
227
- # List collections
228
- print(pb.list_collections())
229
-
230
- # Search records
231
- result = pb.search("my_collection", per_page=10)
232
- print(result)
233
-
234
- # Get single record
235
- record = pb.get("my_collection", "record_id")
236
- print(record)
237
- EOF
238
- ```
@@ -1,59 +0,0 @@
1
- # {{projectTitle}}
2
-
3
- Lumera custom embedded app.
4
-
5
- ## Getting Started
6
-
7
- 1. Install dependencies:
8
- ```bash
9
- pnpm install
10
- ```
11
-
12
- 2. Login to Lumera:
13
- ```bash
14
- lumera login
15
- ```
16
-
17
- 3. Start development server:
18
- ```bash
19
- pnpm dev
20
- ```
21
-
22
- ## CLI Commands
23
-
24
- ```bash
25
- # Development
26
- lumera dev # Start dev server
27
- lumera dev --port 3000 # Custom port
28
-
29
- # Deployment
30
- lumera apply app # Build and deploy frontend
31
- lumera apply # Apply all resources
32
- lumera plan # Preview changes
33
-
34
- # Scripts
35
- lumera run scripts/seed-demo.py # Run seed script
36
-
37
- # Project info
38
- lumera status # Show project info
39
- ```
40
-
41
- ## Project Structure
42
-
43
- ```
44
- ├── src/ # Frontend (React + TanStack)
45
- │ ├── routes/ # TanStack Router pages
46
- │ ├── components/ # React components
47
- │ └── lib/ # API utilities
48
- ├── platform/ # Backend resources
49
- │ ├── collections/ # Collection schemas (JSON)
50
- │ ├── automations/ # Automation scripts (Python)
51
- │ └── hooks/ # Server-side hooks (JS)
52
- ├── scripts/ # Local scripts
53
- └── CLAUDE.md # AI assistant instructions
54
- ```
55
-
56
- ## Documentation
57
-
58
- - `CLAUDE.md` - AI coding assistant instructions
59
- - `ARCHITECTURE.md` - System architecture (customize for your app)
@@ -1,38 +0,0 @@
1
- {
2
- "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
3
- "vcs": {
4
- "enabled": true,
5
- "clientKind": "git",
6
- "useIgnoreFile": true
7
- },
8
- "files": {
9
- "ignoreUnknown": false,
10
- "includes": ["**", "!!**/node_modules", "!!**/dist", "!!**/*routeTree.gen.ts"]
11
- },
12
- "formatter": {
13
- "enabled": true,
14
- "indentStyle": "space",
15
- "indentWidth": 2,
16
- "lineWidth": 100
17
- },
18
- "linter": {
19
- "enabled": true,
20
- "rules": {
21
- "recommended": true,
22
- "suspicious": { "noExplicitAny": "off" },
23
- "style": { "noNonNullAssertion": "off" }
24
- }
25
- },
26
- "javascript": {
27
- "formatter": {
28
- "quoteStyle": "single",
29
- "semicolons": "always",
30
- "trailingCommas": "es5"
31
- }
32
- },
33
- "css": {
34
- "parser": {
35
- "tailwindDirectives": true
36
- }
37
- }
38
- }
@@ -1,9 +0,0 @@
1
- node_modules
2
- dist
3
- .env
4
- .env.local
5
- *.local
6
- __pycache__
7
- *.pyc
8
- .venv/
9
- .lumera/
@@ -1,13 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <meta name="theme-color" content="#000000" />
7
- <title>{{projectTitle}}</title>
8
- </head>
9
- <body>
10
- <div id="app"></div>
11
- <script type="module" src="/src/main.tsx"></script>
12
- </body>
13
- </html>
@@ -1,47 +0,0 @@
1
- {
2
- "name": "{{projectName}}",
3
- "private": true,
4
- "type": "module",
5
- "pnpm": {
6
- "overrides": {
7
- "@tanstack/router-core": "1.155.0"
8
- }
9
- },
10
- "lumera": {
11
- "version": 1,
12
- "name": "{{projectTitle}}"
13
- },
14
- "scripts": {
15
- "dev": "pnpm dlx @lumerahq/cli dev",
16
- "deploy": "pnpm dlx @lumerahq/cli apply app",
17
- "dev:vite": "vite",
18
- "build": "vite build && tsc",
19
- "preview": "vite preview",
20
- "typecheck": "tsr generate && tsc --noEmit",
21
- "lint": "biome lint --write .",
22
- "format": "biome format --write .",
23
- "check": "biome check --write .",
24
- "check:ci": "biome check . && tsr generate && tsc --noEmit"
25
- },
26
- "dependencies": {
27
- "@lumerahq/ui": "^0.5.0",
28
- "@tanstack/react-query": "^5.90.11",
29
- "@tanstack/react-router": "1.155.0",
30
- "@tanstack/router-plugin": "1.155.0",
31
- "lucide-react": "^0.469.0",
32
- "react": "^19.2.0",
33
- "react-dom": "^19.2.0",
34
- "sonner": "^2.0.7",
35
- "tailwindcss": "^4.0.6"
36
- },
37
- "devDependencies": {
38
- "@biomejs/biome": "^2.0.0",
39
- "@tailwindcss/vite": "^4.0.6",
40
- "@tanstack/router-cli": "1.155.0",
41
- "@types/react": "^19.2.0",
42
- "@types/react-dom": "^19.2.0",
43
- "@vitejs/plugin-react": "^5.0.4",
44
- "typescript": "^5.7.2",
45
- "vite": "^7.1.7"
46
- }
47
- }
File without changes
@@ -1,26 +0,0 @@
1
- {
2
- "id": "example_items",
3
- "name": "example_items",
4
- "fields": [
5
- {
6
- "name": "name",
7
- "type": "text",
8
- "required": true
9
- },
10
- {
11
- "name": "status",
12
- "type": "select",
13
- "values": ["pending", "processing", "completed"],
14
- "default": "pending"
15
- },
16
- {
17
- "name": "description",
18
- "type": "text"
19
- },
20
- {
21
- "name": "source_id",
22
- "type": "text"
23
- }
24
- ],
25
- "indexes": [{ "fields": ["source_id"], "unique": true }]
26
- }
File without changes
@@ -1,14 +0,0 @@
1
- [project]
2
- name = "{{projectName}}"
3
- version = "0.1.0"
4
- description = "{{projectTitle}} - Lumera custom app"
5
- requires-python = ">=3.11"
6
- dependencies = [
7
- "lumera",
8
- ]
9
-
10
- [project.optional-dependencies]
11
- dev = [
12
- "ruff",
13
- "pytest",
14
- ]
@@ -1,35 +0,0 @@
1
- # /// script
2
- # dependencies = ["lumera"]
3
- # ///
4
- """
5
- Seed demo data into Lumera (idempotent - safe to run multiple times).
6
-
7
- Usage:
8
- lumera run scripts/seed-demo.py
9
- """
10
-
11
- from lumera import pb
12
-
13
- # Seed demo items
14
- demo_items = [
15
- {
16
- "external_id": "demo:item_1",
17
- "name": "Example Item 1",
18
- "status": "pending",
19
- "description": "This is an example item",
20
- },
21
- {
22
- "external_id": "demo:item_2",
23
- "name": "Example Item 2",
24
- "status": "pending",
25
- "description": "Another example item",
26
- },
27
- ]
28
-
29
- print("Seeding demo data...")
30
-
31
- for item in demo_items:
32
- pb.upsert("example_items", item)
33
- print(f" ✓ {item['name']}")
34
-
35
- print(f"\nSeeded {len(demo_items)} items")
@@ -1,82 +0,0 @@
1
- import { cn } from '@lumerahq/ui/lib';
2
- import { Link, useRouterState } from '@tanstack/react-router';
3
- import { ChevronLeft, ChevronRight, LayoutDashboard, Settings } from 'lucide-react';
4
- import { useState } from 'react';
5
-
6
- type NavItem = {
7
- to: string;
8
- label: string;
9
- icon: React.ElementType;
10
- };
11
-
12
- const navItems: NavItem[] = [
13
- { to: '/', label: 'Dashboard', icon: LayoutDashboard },
14
- { to: '/settings', label: 'Settings', icon: Settings },
15
- ];
16
-
17
- export function Sidebar() {
18
- const [collapsed, setCollapsed] = useState(false);
19
- const routerState = useRouterState();
20
- const currentPath = routerState.location.pathname;
21
-
22
- const isActive = (path: string) => {
23
- if (path === '/') return currentPath === '/';
24
- return currentPath.startsWith(path);
25
- };
26
-
27
- return (
28
- <aside
29
- className={cn(
30
- 'flex flex-col bg-slate-900 text-white border-r border-slate-800 transition-all duration-200',
31
- collapsed ? 'w-16' : 'w-56'
32
- )}
33
- >
34
- {/* Logo */}
35
- <div className="flex items-center h-14 px-4 border-b border-slate-800">
36
- <Link to="/" className="flex items-center gap-2">
37
- <div className="size-8 rounded-lg bg-primary flex items-center justify-center text-primary-foreground font-bold text-sm">
38
- {{projectInitial}}
39
- </div>
40
- {!collapsed && <span className="font-semibold text-sm">{{projectTitle}}</span>}
41
- </Link>
42
- </div>
43
-
44
- {/* Navigation */}
45
- <nav className="flex-1 p-2 space-y-1">
46
- {navItems.map((item) => {
47
- const active = isActive(item.to);
48
- return (
49
- <Link
50
- key={item.to}
51
- to={item.to}
52
- className={cn(
53
- 'flex items-center gap-3 px-3 py-2 rounded-md text-sm font-medium transition-colors',
54
- active
55
- ? 'bg-slate-800 text-white'
56
- : 'text-slate-400 hover:bg-slate-800/50 hover:text-white'
57
- )}
58
- >
59
- <item.icon className="size-4 shrink-0" />
60
- {!collapsed && <span>{item.label}</span>}
61
- </Link>
62
- );
63
- })}
64
- </nav>
65
-
66
- {/* Collapse toggle */}
67
- <div className="p-2 border-t border-slate-800">
68
- <button
69
- type="button"
70
- onClick={() => setCollapsed(!collapsed)}
71
- className={cn(
72
- 'flex items-center gap-2 w-full px-3 py-2 rounded-md text-sm text-slate-400 hover:text-white hover:bg-slate-800/50 transition-colors',
73
- collapsed && 'justify-center'
74
- )}
75
- >
76
- {collapsed ? <ChevronRight className="size-4" /> : <ChevronLeft className="size-4" />}
77
- {!collapsed && <span>Collapse</span>}
78
- </button>
79
- </div>
80
- </aside>
81
- );
82
- }
@@ -1,25 +0,0 @@
1
- import { cn } from '@lumerahq/ui/lib';
2
- import type { ReactNode } from 'react';
3
-
4
- interface StatCardProps {
5
- title: string;
6
- value: string | number;
7
- subtitle?: string;
8
- icon?: ReactNode;
9
- className?: string;
10
- }
11
-
12
- export function StatCard({ title, value, subtitle, icon, className }: StatCardProps) {
13
- return (
14
- <div className={cn('rounded-xl border bg-card p-5', className)}>
15
- <div className="flex items-start justify-between">
16
- <div className="space-y-1">
17
- <p className="text-sm font-medium text-muted-foreground">{title}</p>
18
- <p className="text-2xl font-semibold tracking-tight">{value}</p>
19
- {subtitle && <p className="text-sm text-muted-foreground">{subtitle}</p>}
20
- </div>
21
- {icon && <div className="rounded-lg bg-muted p-2.5 text-muted-foreground">{icon}</div>}
22
- </div>
23
- </div>
24
- );
25
- }
@@ -1,13 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import { Sidebar } from './Sidebar';
3
-
4
- export function AppLayout({ children }: { children: ReactNode }) {
5
- return (
6
- <div className="flex h-screen bg-background">
7
- <Sidebar />
8
- <main className="flex-1 overflow-auto">
9
- <div className="p-6">{children}</div>
10
- </main>
11
- </div>
12
- );
13
- }
@@ -1,27 +0,0 @@
1
- import { type PbRecord, pbList } from '@lumerahq/ui/lib';
2
-
3
- export type ExampleRecord = PbRecord & {
4
- name: string;
5
- status: string;
6
- };
7
-
8
- export async function getExampleData() {
9
- // Replace with your actual data fetching logic
10
- return {
11
- message: 'Replace this with your data fetching logic',
12
- timestamp: new Date().toISOString(),
13
- instructions: [
14
- '1. Edit src/lib/queries.ts',
15
- '2. Use pbSql or pbList from @lumerahq/ui/lib',
16
- '3. Create query functions for your data',
17
- ],
18
- };
19
- }
20
-
21
- export async function listExampleRecords(page = 1) {
22
- return pbList<ExampleRecord>('your_collection', {
23
- page,
24
- perPage: 20,
25
- sort: '-created',
26
- });
27
- }