@lumerahq/cli 0.7.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 (37) hide show
  1. package/README.md +118 -0
  2. package/dist/auth-7RGL7GXU.js +311 -0
  3. package/dist/chunk-2CR762KB.js +18 -0
  4. package/dist/chunk-AVKPM7C4.js +199 -0
  5. package/dist/chunk-D2BLSEGR.js +59 -0
  6. package/dist/chunk-NDLYGKS6.js +77 -0
  7. package/dist/chunk-V2XXMMEI.js +147 -0
  8. package/dist/dev-UTZC4ZJ7.js +87 -0
  9. package/dist/index.js +157 -0
  10. package/dist/init-OQCIET53.js +363 -0
  11. package/dist/migrate-2DZ6RQ5K.js +190 -0
  12. package/dist/resources-PNK3NESI.js +1350 -0
  13. package/dist/run-4NDI2CN4.js +257 -0
  14. package/dist/skills-56EUKHGY.js +414 -0
  15. package/dist/status-BEVUV6RY.js +131 -0
  16. package/package.json +37 -0
  17. package/templates/default/CLAUDE.md +245 -0
  18. package/templates/default/README.md +59 -0
  19. package/templates/default/biome.json +33 -0
  20. package/templates/default/index.html +13 -0
  21. package/templates/default/package.json.hbs +46 -0
  22. package/templates/default/platform/automations/.gitkeep +0 -0
  23. package/templates/default/platform/collections/example_items.json +28 -0
  24. package/templates/default/platform/hooks/.gitkeep +0 -0
  25. package/templates/default/pyproject.toml.hbs +14 -0
  26. package/templates/default/scripts/seed-demo.py +35 -0
  27. package/templates/default/src/components/Sidebar.tsx +84 -0
  28. package/templates/default/src/components/StatCard.tsx +31 -0
  29. package/templates/default/src/components/layout.tsx +13 -0
  30. package/templates/default/src/lib/queries.ts +27 -0
  31. package/templates/default/src/main.tsx +137 -0
  32. package/templates/default/src/routes/__root.tsx +10 -0
  33. package/templates/default/src/routes/index.tsx +90 -0
  34. package/templates/default/src/routes/settings.tsx +25 -0
  35. package/templates/default/src/styles.css +40 -0
  36. package/templates/default/tsconfig.json +23 -0
  37. package/templates/default/vite.config.ts +27 -0
@@ -0,0 +1,131 @@
1
+ import {
2
+ getToken,
3
+ getTokenSource
4
+ } from "./chunk-NDLYGKS6.js";
5
+ import {
6
+ detectProjectVersion,
7
+ findProjectRoot,
8
+ getAppName,
9
+ getAppTitle,
10
+ getBaseUrl,
11
+ readPackageJson
12
+ } from "./chunk-D2BLSEGR.js";
13
+
14
+ // src/commands/status.ts
15
+ import pc from "picocolors";
16
+ import { existsSync, readdirSync } from "fs";
17
+ import { join } from "path";
18
+ async function validateToken(token) {
19
+ const baseUrl = getBaseUrl();
20
+ try {
21
+ const response = await fetch(`${baseUrl}/api/me`, {
22
+ headers: { Authorization: `Bearer ${token}` }
23
+ });
24
+ if (!response.ok) {
25
+ return { valid: false, error: `${response.status} ${response.statusText}` };
26
+ }
27
+ const data = await response.json();
28
+ return {
29
+ valid: true,
30
+ user: data.user?.email,
31
+ company: data.user?.company?.name
32
+ };
33
+ } catch (err) {
34
+ return { valid: false, error: err instanceof Error ? err.message : "Unknown error" };
35
+ }
36
+ }
37
+ function countItems(dir) {
38
+ if (!existsSync(dir)) return 0;
39
+ return readdirSync(dir, { withFileTypes: true }).filter((d) => d.isFile() || d.isDirectory()).length;
40
+ }
41
+ async function status(args) {
42
+ if (args.includes("--help") || args.includes("-h")) {
43
+ console.log(`
44
+ ${pc.dim("Usage:")}
45
+ lumera status
46
+
47
+ ${pc.dim("Description:")}
48
+ Show project information and status.
49
+ `);
50
+ return;
51
+ }
52
+ let projectRoot;
53
+ try {
54
+ projectRoot = findProjectRoot();
55
+ } catch {
56
+ console.error(pc.red("Not in a Lumera project directory."));
57
+ console.error(pc.dim("Run this command from a project with a package.json."));
58
+ process.exit(1);
59
+ }
60
+ const pkg = readPackageJson(projectRoot);
61
+ const version = detectProjectVersion(projectRoot);
62
+ const appName = getAppName(projectRoot);
63
+ const appTitle = getAppTitle(projectRoot);
64
+ const tokenSource = getTokenSource(projectRoot);
65
+ console.log();
66
+ console.log(pc.bold(`Project: ${appTitle}`));
67
+ console.log(pc.dim(` Name: ${appName}`));
68
+ console.log(pc.dim(` Version: ${pkg.version || "0.0.0"}`));
69
+ console.log(pc.dim(` Structure: v${version}${version === 0 ? " (legacy)" : ""}`));
70
+ console.log();
71
+ const platformDir = version === 0 ? "lumera_platform" : "platform";
72
+ const collectionsDir = join(projectRoot, platformDir, "collections");
73
+ const automationsDir = join(projectRoot, platformDir, "automations");
74
+ const hooksDir = join(projectRoot, platformDir, "hooks");
75
+ const scriptsDir = version === 0 ? join(projectRoot, platformDir, "scripts") : join(projectRoot, "scripts");
76
+ const collections = countItems(collectionsDir);
77
+ const automations = countItems(automationsDir);
78
+ const hooks = countItems(hooksDir);
79
+ const scripts = countItems(scriptsDir);
80
+ console.log(pc.bold("Platform:"));
81
+ console.log(` ${collections} collection${collections !== 1 ? "s" : ""}`);
82
+ console.log(` ${automations} automation${automations !== 1 ? "s" : ""}`);
83
+ console.log(` ${hooks} hook${hooks !== 1 ? "s" : ""}`);
84
+ console.log();
85
+ if (scripts > 0) {
86
+ console.log(pc.bold("Scripts:"));
87
+ console.log(` ${scripts} script${scripts !== 1 ? "s" : ""}`);
88
+ console.log();
89
+ }
90
+ console.log(pc.bold("Auth:"));
91
+ const baseUrl = getBaseUrl();
92
+ console.log(pc.dim(` API: ${baseUrl}`));
93
+ if (tokenSource) {
94
+ let token;
95
+ try {
96
+ token = getToken(projectRoot);
97
+ } catch {
98
+ console.log(pc.yellow(` \u26A0 Token source found but could not read token`));
99
+ console.log(pc.dim(` Run \`lumera login\` to re-authenticate`));
100
+ console.log();
101
+ return;
102
+ }
103
+ const validation = await validateToken(token);
104
+ if (validation.valid) {
105
+ console.log(pc.green(` \u2713 Authenticated (${tokenSource})`));
106
+ if (validation.user) console.log(pc.dim(` User: ${validation.user}`));
107
+ if (validation.company) console.log(pc.dim(` Company: ${validation.company}`));
108
+ } else {
109
+ console.log(pc.red(` \u2717 Token invalid (${tokenSource})`));
110
+ console.log(pc.dim(` Error: ${validation.error}`));
111
+ console.log(pc.dim(` Run \`lumera login\` to re-authenticate`));
112
+ }
113
+ } else {
114
+ console.log(pc.yellow(` \u26A0 Not logged in`));
115
+ console.log(pc.dim(` Run \`lumera login\` to authenticate`));
116
+ }
117
+ console.log();
118
+ if (version === 0) {
119
+ console.log(pc.yellow("\u26A0 This project uses legacy structure (v0)."));
120
+ console.log(pc.dim(" Run `lumera project migrate` to upgrade to v1."));
121
+ console.log();
122
+ console.log(pc.dim(" Limited functionality in v0:"));
123
+ console.log(pc.dim(" - lumera app deploy: \u2713 supported"));
124
+ console.log(pc.dim(" - lumera platform apply: \u2717 requires v1"));
125
+ console.log(pc.dim(" - lumera run: \u2717 requires v1"));
126
+ console.log();
127
+ }
128
+ }
129
+ export {
130
+ status
131
+ };
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@lumerahq/cli",
3
+ "version": "0.7.0",
4
+ "description": "CLI for building and deploying Lumera apps",
5
+ "type": "module",
6
+ "engines": {
7
+ "node": ">=18.0.0"
8
+ },
9
+ "bin": {
10
+ "lumera": "./dist/index.js"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "templates"
15
+ ],
16
+ "dependencies": {
17
+ "archiver": "^7.0.1",
18
+ "dotenv": "^16.4.7",
19
+ "open": "^10.1.0",
20
+ "picocolors": "^1.1.1",
21
+ "prompts": "^2.4.2"
22
+ },
23
+ "devDependencies": {
24
+ "@types/archiver": "^6.0.3",
25
+ "@types/node": "^22.10.2",
26
+ "@types/prompts": "^2.4.9",
27
+ "tsup": "^8.5.0",
28
+ "typescript": "^5.7.2"
29
+ },
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "scripts": {
34
+ "build": "tsup src/index.ts --format esm --clean",
35
+ "dev": "tsup src/index.ts --format esm --watch"
36
+ }
37
+ }
@@ -0,0 +1,245 @@
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. Skills provide detailed documentation for building on the Lumera platform.
10
+
11
+ **Installed skills** (in `.claude/skills/`):
12
+ - **lumera-collections** - Collections and Records API
13
+ - **lumera-automations** - Python automation scripts
14
+ - **lumera-webhooks** - Receiving external webhooks
15
+ - **write-hooks** - Server-side JavaScript hooks
16
+ - **lumera-sdk** - Python SDK reference
17
+ - **using-lumera** - Platform overview and patterns
18
+
19
+ ### Installing/Updating Skills
20
+
21
+ Skills are auto-installed when creating the app. To manually install or update:
22
+
23
+ ```bash
24
+ npx skills add git@github.com:lumerahq/lumera-skills.git
25
+ ```
26
+
27
+ > **Note:** Requires SSH access to the lumerahq GitHub organization.
28
+
29
+ ---
30
+
31
+ ## Quick Reference
32
+
33
+ ### Lumera CLI
34
+
35
+ All `lumera` commands are run via `pnpm dlx`:
36
+
37
+ ```bash
38
+ # Shortcuts
39
+ pnpm dev # Start dev server
40
+ pnpm deploy # Deploy frontend
41
+
42
+ # All other commands
43
+ pnpm dlx @lumerahq/cli platform plan
44
+ pnpm dlx @lumerahq/cli platform apply
45
+ pnpm dlx @lumerahq/cli platform destroy
46
+ pnpm dlx @lumerahq/cli run scripts/seed-demo.py
47
+ pnpm dlx @lumerahq/cli status
48
+ ```
49
+
50
+ ### Running the Frontend
51
+
52
+ ```bash
53
+ # Login first (stores credentials in .lumera/credentials.json)
54
+ lumera login
55
+
56
+ # Start dev server
57
+ pnpm dev
58
+
59
+ # With custom port
60
+ lumera app dev --port 3000
61
+
62
+ # With ngrok tunnel
63
+ lumera app dev --url https://my-tunnel.ngrok.io
64
+
65
+ # Plain vite (no Lumera registration)
66
+ pnpm dev:vite
67
+ ```
68
+
69
+ ### Linting & Formatting
70
+
71
+ ```bash
72
+ # Type check without emitting
73
+ pnpm typecheck
74
+
75
+ # Lint and auto-fix
76
+ pnpm lint
77
+
78
+ # Format code
79
+ pnpm format
80
+
81
+ # Run all checks (lint + typecheck) - use in CI
82
+ pnpm check:ci
83
+ ```
84
+
85
+ ### Deploying
86
+
87
+ ```bash
88
+ # Deploy frontend to S3
89
+ lumera app deploy
90
+
91
+ # Apply platform resources (collections, automations, hooks)
92
+ lumera platform apply
93
+
94
+ # Preview platform changes first
95
+ lumera platform plan
96
+ ```
97
+
98
+ ### Running Scripts
99
+
100
+ All scripts are **idempotent** - safe to run multiple times during iterative development.
101
+
102
+ ```bash
103
+ # Run a script locally
104
+ lumera run scripts/seed-demo.py
105
+
106
+ # Dependencies can be declared inline (PEP 723)
107
+ ```
108
+
109
+ ### Running Automations via External ID
110
+
111
+ Always run automations using their `external_id` (not the internal Lumera ID which changes per tenant).
112
+
113
+ ```python
114
+ uv run python << 'EOF'
115
+ from lumera import automations
116
+
117
+ # Run automation by external_id (returns Run object immediately)
118
+ run = automations.run_by_external_id(
119
+ "{{projectName}}:my_automation",
120
+ inputs={"param": "value"}
121
+ )
122
+ print(f"Run ID: {run.id}")
123
+ print(f"Status: {run.status}")
124
+
125
+ # Wait for completion (blocks until done or timeout)
126
+ result = run.wait(timeout=600) # 10 min timeout
127
+ print(f"Result: {result}")
128
+ EOF
129
+ ```
130
+
131
+ **Run object properties**: `id`, `status`, `result`, `error`, `inputs`, `is_terminal`
132
+ **Run object methods**: `wait(timeout)`, `refresh()`, `cancel()`
133
+ **Status values**: `queued`, `running`, `succeeded`, `failed`, `cancelled`, `timeout`
134
+
135
+ ---
136
+
137
+ ## Important Rules
138
+
139
+ 1. **Authenticate first** - Before running any CLI or SDK commands, ensure the user has run `lumera login --local`. This stores credentials in `.lumera/credentials.json` which the SDK reads automatically.
140
+
141
+ 2. **Source of truth is code** - `platform/` contains all schemas, automations, hooks. Update local code first, then deploy.
142
+
143
+ 3. **Never edit Lumera directly** - Don't change data/schema in Lumera UI without explicit user approval.
144
+
145
+ 4. **Offer to deploy** - When schemas, hooks, or automations change, offer to deploy to Lumera.
146
+
147
+ 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:
148
+ - `lumera.pb` - Record and collection operations (search, get, create, update, delete)
149
+ - `lumera.storage` - File uploads and downloads
150
+ - `lumera.llm` - LLM completions
151
+ - `lumera.automations` - Running and managing automations
152
+ - `lumera.integrations` - Third-party integrations (Google, Slack, etc.)
153
+
154
+ 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`):
155
+ ```bash
156
+ uv run python -c "from lumera import pb; print(pb.search('collection_name'))"
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Key Directories
162
+
163
+ ```
164
+ platform/
165
+ ├── automations/ # Automation scripts (Python)
166
+ ├── collections/ # Collection schemas (JSON)
167
+ └── hooks/ # Server-side JavaScript hooks
168
+
169
+ scripts/ # Local scripts (seed, migrate, etc.)
170
+
171
+ src/ # React frontend
172
+ ├── routes/ # TanStack Router pages
173
+ ├── lib/ # queries.ts, api helpers
174
+ └── components/ # React components
175
+
176
+ .venv/ # Python venv with lumera SDK (for IDE autocomplete)
177
+ ```
178
+
179
+ ### Python Environment
180
+
181
+ A Python virtual environment is created at `.venv/` with the `lumera` SDK pre-installed. This provides IDE autocomplete when writing automations and scripts.
182
+
183
+ ```bash
184
+ # Activate venv (optional - for IDE integration)
185
+ source .venv/bin/activate
186
+
187
+ # SDK is available for import
188
+ python -c "from lumera import pb; print(pb)"
189
+ ```
190
+
191
+ > **Note:** You don't need to activate the venv to run scripts - `lumera run` handles this automatically.
192
+
193
+ ---
194
+
195
+ ## Frontend Patterns
196
+
197
+ ### Fetching Data
198
+
199
+ ```typescript
200
+ import { pbSql, pbList } from '@lumerahq/ui/lib';
201
+
202
+ const result = await pbSql<{ id: string; name: string }>({
203
+ sql: 'SELECT id, name FROM users WHERE active = true'
204
+ });
205
+
206
+ const items = await pbList<User>('users', {
207
+ filter: 'active = true',
208
+ sort: '-created',
209
+ perPage: 50,
210
+ });
211
+ ```
212
+
213
+ ### Running Automations from Frontend
214
+
215
+ ```typescript
216
+ import { createRun, pollRun } from '@lumerahq/ui/lib';
217
+
218
+ const run = await createRun({
219
+ automationId: '{{projectName}}:process_data',
220
+ inputs: { file_id: 'abc123' },
221
+ });
222
+
223
+ const result = await pollRun(run.id);
224
+ ```
225
+
226
+ ---
227
+
228
+ ## Debugging with Lumera SDK
229
+
230
+ ```python
231
+ uv run python << 'EOF'
232
+ from lumera import pb
233
+
234
+ # List collections
235
+ print(pb.list_collections())
236
+
237
+ # Search records
238
+ result = pb.search("my_collection", per_page=10)
239
+ print(result)
240
+
241
+ # Get single record
242
+ record = pb.get("my_collection", "record_id")
243
+ print(record)
244
+ EOF
245
+ ```
@@ -0,0 +1,59 @@
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 app dev # Start dev server
27
+ lumera app dev --port 3000 # Custom port
28
+
29
+ # Deployment
30
+ lumera app deploy # Build and deploy frontend
31
+ lumera platform apply # Apply collections, automations, hooks
32
+ lumera platform plan # Preview platform 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)
@@ -0,0 +1,33 @@
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
+ }
@@ -0,0 +1,13 @@
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>
@@ -0,0 +1,46 @@
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 app dev",
16
+ "deploy": "pnpm dlx @lumerahq/cli app deploy",
17
+ "dev:vite": "vite",
18
+ "build": "vite build && tsc",
19
+ "preview": "vite preview",
20
+ "typecheck": "tsc --noEmit",
21
+ "lint": "biome lint --write .",
22
+ "format": "biome format --write .",
23
+ "check": "biome check --write .",
24
+ "check:ci": "biome check . && tsc --noEmit"
25
+ },
26
+ "dependencies": {
27
+ "@lumerahq/ui": "^0.3.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
+ "@types/react": "^19.2.0",
41
+ "@types/react-dom": "^19.2.0",
42
+ "@vitejs/plugin-react": "^5.0.4",
43
+ "typescript": "^5.7.2",
44
+ "vite": "^7.1.7"
45
+ }
46
+ }
@@ -0,0 +1,28 @@
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": [
26
+ { "fields": ["source_id"], "unique": true }
27
+ ]
28
+ }
File without changes
@@ -0,0 +1,14 @@
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
+ ]
@@ -0,0 +1,35 @@
1
+ # /// script
2
+ # dependencies = ["lumera-sdk"]
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")