luca 3.0.0 → 3.0.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.
- package/.github/workflows/release.yaml +1 -0
- package/CLAUDE.md +10 -2
- package/README.md +130 -112
- package/assistants/codingAssistant/CORE.md +6 -1
- package/assistants/codingAssistant/hooks.ts +1 -1
- package/assistants/inkbot/hooks.ts +1 -1
- package/assistants/inkbot/tools.ts +1 -1
- package/bun.lock +220 -322
- package/commands/audit-docs.ts +2 -2
- package/commands/build-bootstrap.ts +2 -3
- package/commands/build-python-bridge.ts +2 -3
- package/commands/build-scaffolds.ts +2 -3
- package/commands/bundle-consumer-project.ts +521 -0
- package/commands/generate-api-docs.ts +2 -2
- package/commands/inkbot.ts +2 -2
- package/commands/release.ts +2 -2
- package/commands/try-all-challenges.ts +3 -3
- package/commands/try-challenge.ts +3 -3
- package/dist/agi/container.server.d.ts +2 -2
- package/dist/agi/features/assistant.d.ts +2 -2
- package/dist/agi/features/assistants-manager.d.ts +1 -1
- package/dist/agi/features/autonomous-assistant.d.ts +1 -1
- package/dist/agi/features/browser-use.d.ts +1 -1
- package/dist/agi/features/claude-code.d.ts +1 -1
- package/dist/agi/features/conversation-history.d.ts +2 -2
- package/dist/agi/features/conversation.d.ts +1 -1
- package/dist/agi/features/docs-reader.d.ts +1 -1
- package/dist/agi/features/file-tools.d.ts +1 -1
- package/dist/agi/features/luca-coder.d.ts +1 -1
- package/dist/agi/features/openai-codex.d.ts +1 -1
- package/dist/agi/features/skills-library.d.ts +1 -1
- package/dist/clients/civitai/index.d.ts +4 -4
- package/dist/clients/client-template.d.ts +4 -4
- package/dist/clients/comfyui/index.d.ts +2 -2
- package/dist/clients/elevenlabs/index.d.ts +2 -2
- package/dist/clients/openai/index.d.ts +2 -2
- package/dist/clients/supabase/index.d.ts +3 -3
- package/dist/command.d.ts +1 -1
- package/dist/node/container.d.ts +1 -1
- package/dist/node/features/helpers.d.ts +3 -3
- package/dist/node/features/semantic-search.d.ts +1 -1
- package/dist/node/features/vm.d.ts +3 -3
- package/dist/node.d.ts +1 -1
- package/dist/scaffolds/generated.d.ts +1 -1
- package/dist/selector.d.ts +1 -1
- package/index.html +217 -190
- package/luca.console.ts +1 -1
- package/package.json +2 -2
- package/public/index.html +217 -190
- package/public/slides-ai-native.html +1 -1
- package/public/slides-intro.html +2 -2
- package/scripts/examples/ask-luca-expert.ts +1 -1
- package/scripts/examples/assistant-questions.ts +1 -1
- package/scripts/examples/excalidraw-expert.ts +1 -1
- package/scripts/examples/file-manager.ts +1 -1
- package/scripts/examples/ideas.ts +1 -1
- package/scripts/examples/interactive-chat.ts +1 -1
- package/scripts/examples/opening-a-web-browser.ts +1 -1
- package/scripts/examples/telegram-bot.ts +1 -1
- package/scripts/examples/using-assistant-with-mcp.ts +1 -1
- package/scripts/examples/using-claude-code.ts +1 -1
- package/scripts/examples/using-contentdb.ts +2 -2
- package/scripts/examples/using-conversations.ts +1 -1
- package/scripts/examples/using-disk-cache.ts +1 -1
- package/scripts/examples/using-docker-shell.ts +1 -1
- package/scripts/examples/using-elevenlabs.ts +1 -1
- package/scripts/examples/using-google-calendar.ts +1 -1
- package/scripts/examples/using-google-docs.ts +1 -1
- package/scripts/examples/using-google-drive.ts +1 -1
- package/scripts/examples/using-google-sheets.ts +1 -1
- package/scripts/examples/using-nlp.ts +1 -1
- package/scripts/examples/using-ollama.ts +1 -1
- package/scripts/examples/using-postgres.ts +1 -1
- package/scripts/examples/using-runpod.ts +1 -1
- package/scripts/examples/using-tts.ts +1 -1
- package/scripts/scaffold.ts +5 -5
- package/scripts/scratch.ts +1 -1
- package/scripts/test-assistant-hooks.ts +1 -1
- package/scripts/test-docs-reader.ts +1 -1
- package/src/agi/container.server.ts +6 -2
- package/src/agi/features/agent-memory.ts +25 -25
- package/src/agi/features/assistant.ts +34 -5
- package/src/agi/features/assistants-manager.ts +122 -6
- package/src/agi/features/autonomous-assistant.ts +1 -1
- package/src/agi/features/browser-use.ts +20 -1
- package/src/agi/features/claude-code.ts +51 -5
- package/src/agi/features/coding-tools.ts +1 -1
- package/src/agi/features/conversation-history.ts +181 -4
- package/src/agi/features/conversation.ts +186 -15
- package/src/agi/features/docs-reader.ts +2 -2
- package/src/agi/features/file-tools.ts +49 -2
- package/src/agi/features/luca-coder.ts +7 -5
- package/src/agi/features/mcp-bridge.ts +532 -0
- package/src/agi/features/openai-codex.ts +2 -2
- package/src/agi/features/skills-library.ts +131 -52
- package/src/agi/lib/token-counter.ts +80 -0
- package/src/bootstrap/generated.ts +56 -57
- package/src/browser.ts +1 -1
- package/src/cli/build-info.ts +2 -2
- package/src/cli/cli.ts +2 -2
- package/src/clients/civitai/index.ts +5 -5
- package/src/clients/client-template.ts +4 -4
- package/src/clients/comfyui/index.ts +4 -4
- package/src/clients/elevenlabs/index.ts +4 -4
- package/src/clients/openai/index.ts +7 -7
- package/src/clients/supabase/index.ts +4 -4
- package/src/clients/voicebox/index.ts +4 -4
- package/src/command.ts +2 -1
- package/src/commands/chat.ts +1 -0
- package/src/commands/eval.ts +2 -56
- package/src/commands/introspect.ts +1 -1
- package/src/commands/prompt.ts +41 -9
- package/src/container-describer.ts +8 -1
- package/src/container.ts +13 -0
- package/src/entity.ts +2 -2
- package/src/helper.ts +1 -1
- package/src/introspection/generated.agi.ts +28563 -27571
- package/src/introspection/generated.node.ts +20281 -20194
- package/src/introspection/generated.web.ts +605 -584
- package/src/introspection/scan.ts +11 -6
- package/src/node/container.ts +1 -1
- package/src/node/features/content-db.ts +39 -2
- package/src/node/features/display-result.ts +57 -0
- package/src/node/features/helpers.ts +42 -15
- package/src/node/features/python.ts +25 -19
- package/src/node/features/repl.ts +1 -1
- package/src/node/features/secure-shell.ts +11 -17
- package/src/node/features/semantic-search.ts +2 -2
- package/src/node/features/transpiler.ts +2 -3
- package/src/node/features/ui.ts +5 -0
- package/src/node/features/vm.ts +3 -3
- package/src/node.ts +3 -3
- package/src/python/generated.ts +0 -1
- package/src/scaffolds/generated.ts +82 -83
- package/src/selector.ts +1 -1
- package/src/servers/express.ts +1 -1
- package/src/web/features/helpers.ts +22 -0
- package/tsconfig.json +12 -12
- package/docs/CLI.md +0 -335
- package/docs/CNAME +0 -1
- package/docs/README.md +0 -60
- package/docs/TABLE-OF-CONTENTS.md +0 -183
- package/docs/apis/clients/elevenlabs.md +0 -308
- package/docs/apis/clients/graph.md +0 -107
- package/docs/apis/clients/openai.md +0 -429
- package/docs/apis/clients/rest.md +0 -161
- package/docs/apis/clients/websocket.md +0 -174
- package/docs/apis/features/agi/assistant.md +0 -625
- package/docs/apis/features/agi/assistants-manager.md +0 -282
- package/docs/apis/features/agi/auto-assistant.md +0 -279
- package/docs/apis/features/agi/browser-use.md +0 -802
- package/docs/apis/features/agi/claude-code.md +0 -884
- package/docs/apis/features/agi/conversation-history.md +0 -364
- package/docs/apis/features/agi/conversation.md +0 -548
- package/docs/apis/features/agi/docs-reader.md +0 -99
- package/docs/apis/features/agi/file-tools.md +0 -163
- package/docs/apis/features/agi/luca-coder.md +0 -407
- package/docs/apis/features/agi/openai-codex.md +0 -396
- package/docs/apis/features/agi/openapi.md +0 -138
- package/docs/apis/features/agi/semantic-search.md +0 -387
- package/docs/apis/features/agi/skills-library.md +0 -239
- package/docs/apis/features/node/container-link.md +0 -192
- package/docs/apis/features/node/content-db.md +0 -450
- package/docs/apis/features/node/disk-cache.md +0 -379
- package/docs/apis/features/node/dns.md +0 -652
- package/docs/apis/features/node/docker.md +0 -706
- package/docs/apis/features/node/downloader.md +0 -81
- package/docs/apis/features/node/esbuild.md +0 -60
- package/docs/apis/features/node/file-manager.md +0 -191
- package/docs/apis/features/node/fs.md +0 -1217
- package/docs/apis/features/node/git.md +0 -371
- package/docs/apis/features/node/google-auth.md +0 -193
- package/docs/apis/features/node/google-calendar.md +0 -202
- package/docs/apis/features/node/google-docs.md +0 -173
- package/docs/apis/features/node/google-drive.md +0 -246
- package/docs/apis/features/node/google-mail.md +0 -214
- package/docs/apis/features/node/google-sheets.md +0 -194
- package/docs/apis/features/node/grep.md +0 -292
- package/docs/apis/features/node/helpers.md +0 -164
- package/docs/apis/features/node/ink.md +0 -334
- package/docs/apis/features/node/ipc-socket.md +0 -249
- package/docs/apis/features/node/json-tree.md +0 -86
- package/docs/apis/features/node/networking.md +0 -316
- package/docs/apis/features/node/nlp.md +0 -133
- package/docs/apis/features/node/opener.md +0 -97
- package/docs/apis/features/node/os.md +0 -146
- package/docs/apis/features/node/package-finder.md +0 -392
- package/docs/apis/features/node/postgres.md +0 -234
- package/docs/apis/features/node/proc.md +0 -399
- package/docs/apis/features/node/process-manager.md +0 -305
- package/docs/apis/features/node/python.md +0 -604
- package/docs/apis/features/node/redis.md +0 -380
- package/docs/apis/features/node/repl.md +0 -88
- package/docs/apis/features/node/runpod.md +0 -674
- package/docs/apis/features/node/secure-shell.md +0 -176
- package/docs/apis/features/node/semantic-search.md +0 -408
- package/docs/apis/features/node/sqlite.md +0 -233
- package/docs/apis/features/node/telegram.md +0 -279
- package/docs/apis/features/node/transpiler.md +0 -74
- package/docs/apis/features/node/tts.md +0 -133
- package/docs/apis/features/node/ui.md +0 -701
- package/docs/apis/features/node/vault.md +0 -59
- package/docs/apis/features/node/vm.md +0 -75
- package/docs/apis/features/node/yaml-tree.md +0 -85
- package/docs/apis/features/node/yaml.md +0 -176
- package/docs/apis/features/web/asset-loader.md +0 -59
- package/docs/apis/features/web/container-link.md +0 -192
- package/docs/apis/features/web/esbuild.md +0 -54
- package/docs/apis/features/web/helpers.md +0 -164
- package/docs/apis/features/web/network.md +0 -44
- package/docs/apis/features/web/speech.md +0 -69
- package/docs/apis/features/web/vault.md +0 -59
- package/docs/apis/features/web/vm.md +0 -75
- package/docs/apis/features/web/voice.md +0 -84
- package/docs/apis/servers/express.md +0 -171
- package/docs/apis/servers/mcp.md +0 -238
- package/docs/apis/servers/websocket.md +0 -170
- package/docs/bootstrap/CLAUDE.md +0 -101
- package/docs/bootstrap/SKILL.md +0 -341
- package/docs/bootstrap/templates/about-command.ts +0 -41
- package/docs/bootstrap/templates/docs-models.ts +0 -22
- package/docs/bootstrap/templates/docs-readme.md +0 -43
- package/docs/bootstrap/templates/example-feature.ts +0 -53
- package/docs/bootstrap/templates/health-endpoint.ts +0 -15
- package/docs/bootstrap/templates/luca-cli.ts +0 -30
- package/docs/bootstrap/templates/runme.md +0 -54
- package/docs/challenges/caching-proxy.md +0 -16
- package/docs/challenges/content-db-round-trip.md +0 -14
- package/docs/challenges/custom-command.md +0 -9
- package/docs/challenges/file-watcher-pipeline.md +0 -11
- package/docs/challenges/grep-audit-report.md +0 -15
- package/docs/challenges/multi-feature-dashboard.md +0 -14
- package/docs/challenges/process-orchestrator.md +0 -17
- package/docs/challenges/rest-api-server-with-client.md +0 -12
- package/docs/challenges/script-runner-with-vm.md +0 -11
- package/docs/challenges/simple-rest-api.md +0 -15
- package/docs/challenges/websocket-serve-and-client.md +0 -11
- package/docs/challenges/yaml-config-system.md +0 -14
- package/docs/command-system-overhaul.md +0 -94
- package/docs/documentation-audit.md +0 -134
- package/docs/examples/assistant/CORE.md +0 -18
- package/docs/examples/assistant/hooks.ts +0 -3
- package/docs/examples/assistant/tools.ts +0 -10
- package/docs/examples/assistant-hooks-reference.ts +0 -171
- package/docs/examples/assistant-with-process-manager.md +0 -84
- package/docs/examples/content-db.md +0 -77
- package/docs/examples/disk-cache.md +0 -83
- package/docs/examples/docker.md +0 -101
- package/docs/examples/downloader.md +0 -70
- package/docs/examples/entity.md +0 -124
- package/docs/examples/esbuild.md +0 -80
- package/docs/examples/feature-as-tool-provider.md +0 -143
- package/docs/examples/file-manager.md +0 -82
- package/docs/examples/fs.md +0 -83
- package/docs/examples/git.md +0 -85
- package/docs/examples/google-auth.md +0 -88
- package/docs/examples/google-calendar.md +0 -94
- package/docs/examples/google-docs.md +0 -82
- package/docs/examples/google-drive.md +0 -96
- package/docs/examples/google-sheets.md +0 -95
- package/docs/examples/grep.md +0 -85
- package/docs/examples/ink-blocks.md +0 -75
- package/docs/examples/ink-renderer.md +0 -41
- package/docs/examples/ink.md +0 -103
- package/docs/examples/ipc-socket.md +0 -103
- package/docs/examples/json-tree.md +0 -91
- package/docs/examples/networking.md +0 -58
- package/docs/examples/nlp.md +0 -91
- package/docs/examples/opener.md +0 -78
- package/docs/examples/os.md +0 -72
- package/docs/examples/package-finder.md +0 -89
- package/docs/examples/postgres.md +0 -91
- package/docs/examples/proc.md +0 -81
- package/docs/examples/process-manager.md +0 -79
- package/docs/examples/python.md +0 -132
- package/docs/examples/repl.md +0 -93
- package/docs/examples/runpod.md +0 -119
- package/docs/examples/secure-shell.md +0 -92
- package/docs/examples/sqlite.md +0 -86
- package/docs/examples/structured-output-with-assistants.md +0 -144
- package/docs/examples/telegram.md +0 -77
- package/docs/examples/tts.md +0 -86
- package/docs/examples/ui.md +0 -80
- package/docs/examples/vault.md +0 -70
- package/docs/examples/vm.md +0 -86
- package/docs/examples/websocket-ask-and-reply-example.md +0 -128
- package/docs/examples/yaml-tree.md +0 -93
- package/docs/examples/yaml.md +0 -104
- package/docs/ideas/assistant-factory-pattern.md +0 -142
- package/docs/in-memory-fs.md +0 -4
- package/docs/introspection-audit.md +0 -49
- package/docs/introspection.md +0 -164
- package/docs/mcp/readme.md +0 -162
- package/docs/models.ts +0 -41
- package/docs/philosophy.md +0 -86
- package/docs/principles.md +0 -7
- package/docs/prompts/audit-codebase-for-failures-to-use-the-container.md +0 -34
- package/docs/prompts/check-for-undocumented-features.md +0 -27
- package/docs/prompts/mcp-test-easy-command.md +0 -27
- package/docs/scaffolds/client.md +0 -149
- package/docs/scaffolds/command.md +0 -120
- package/docs/scaffolds/endpoint.md +0 -171
- package/docs/scaffolds/feature.md +0 -158
- package/docs/scaffolds/selector.md +0 -91
- package/docs/scaffolds/server.md +0 -196
- package/docs/selectors.md +0 -115
- package/docs/sessions/custom-command/attempt-log-2.md +0 -195
- package/docs/sessions/file-watcher-pipeline/attempt-log-1.md +0 -728
- package/docs/sessions/file-watcher-pipeline/attempt-log-2.md +0 -555
- package/docs/sessions/grep-audit-report/attempt-log-1.md +0 -289
- package/docs/sessions/multi-feature-dashboard/attempt-log-2.md +0 -679
- package/docs/sessions/rest-api-server-with-client/attempt-log-1.md +0 -1
- package/docs/sessions/rest-api-server-with-client/attempt-log-3.md +0 -920
- package/docs/sessions/simple-rest-api/attempt-log-1.md +0 -593
- package/docs/sessions/websocket-serve-and-client/attempt-log-2.md +0 -995
- package/docs/tutorials/00-bootstrap.md +0 -166
- package/docs/tutorials/01-getting-started.md +0 -106
- package/docs/tutorials/02-container.md +0 -210
- package/docs/tutorials/03-scripts.md +0 -194
- package/docs/tutorials/04-features-overview.md +0 -196
- package/docs/tutorials/05-state-and-events.md +0 -171
- package/docs/tutorials/06-servers.md +0 -157
- package/docs/tutorials/07-endpoints.md +0 -198
- package/docs/tutorials/08-commands.md +0 -252
- package/docs/tutorials/09-clients.md +0 -162
- package/docs/tutorials/10-creating-features.md +0 -203
- package/docs/tutorials/11-contentbase.md +0 -191
- package/docs/tutorials/12-assistants.md +0 -215
- package/docs/tutorials/13-introspection.md +0 -157
- package/docs/tutorials/14-type-system.md +0 -174
- package/docs/tutorials/15-project-patterns.md +0 -222
- package/docs/tutorials/16-google-features.md +0 -534
- package/docs/tutorials/17-tui-blocks.md +0 -530
- package/docs/tutorials/18-semantic-search.md +0 -334
- package/docs/tutorials/19-python-sessions.md +0 -401
- package/docs/tutorials/20-browser-esm.md +0 -234
- package/src/agi/endpoints/ask.ts +0 -60
- package/src/agi/endpoints/conversations/[id].ts +0 -45
- package/src/agi/endpoints/conversations.ts +0 -31
- package/src/agi/endpoints/experts.ts +0 -37
- package/test/assistant-hooks.test.ts +0 -306
- package/test/assistant.test.ts +0 -81
- package/test/bus.test.ts +0 -134
- package/test/clients-servers.test.ts +0 -217
- package/test/command.test.ts +0 -267
- package/test/container-link.test.ts +0 -274
- package/test/conversation.test.ts +0 -220
- package/test/features.test.ts +0 -160
- package/test/fork-and-research.test.ts +0 -450
- package/test/integration.test.ts +0 -787
- package/test/interceptor-chain.test.ts +0 -61
- package/test/node-container.test.ts +0 -121
- package/test/python-session.test.ts +0 -105
- package/test/rate-limit.test.ts +0 -272
- package/test/semantic-search.test.ts +0 -550
- package/test/state.test.ts +0 -121
- package/test/vm-context.test.ts +0 -146
- package/test/vm-loadmodule.test.ts +0 -213
- package/test/websocket-ask.test.ts +0 -101
- package/test-integration/assistant.test.ts +0 -138
- package/test-integration/assistants-manager.test.ts +0 -113
- package/test-integration/claude-code.test.ts +0 -98
- package/test-integration/conversation-history.test.ts +0 -205
- package/test-integration/conversation.test.ts +0 -137
- package/test-integration/elevenlabs.test.ts +0 -55
- package/test-integration/google-services.test.ts +0 -80
- package/test-integration/helpers.ts +0 -89
- package/test-integration/memory.test.ts +0 -204
- package/test-integration/openai-codex.test.ts +0 -93
- package/test-integration/runpod.test.ts +0 -58
- package/test-integration/server-endpoints.test.ts +0 -97
- package/test-integration/telegram.test.ts +0 -46
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Type System and Module Augmentation
|
|
3
|
-
tags: [types, typescript, zod, module-augmentation, schemas, type-safety]
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Type System and Module Augmentation
|
|
7
|
-
|
|
8
|
-
Luca's type system ensures that as you add features, clients, servers, and commands, the container's factory methods stay fully typed. This is powered by Zod schemas and TypeScript module augmentation.
|
|
9
|
-
|
|
10
|
-
## The Pattern
|
|
11
|
-
|
|
12
|
-
When you register a new helper, you augment the corresponding interface so TypeScript knows about it:
|
|
13
|
-
|
|
14
|
-
```typescript
|
|
15
|
-
import { Feature, features, FeatureStateSchema, FeatureOptionsSchema } from '@soederpop/luca'
|
|
16
|
-
import { z } from 'zod'
|
|
17
|
-
|
|
18
|
-
// 1. Define your feature
|
|
19
|
-
export class MyCache extends Feature<MyCacheState, MyCacheOptions> {
|
|
20
|
-
// ...
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// 2. Register it
|
|
24
|
-
features.register('myCache', MyCache)
|
|
25
|
-
|
|
26
|
-
// 3. Augment the interface
|
|
27
|
-
declare module '@soederpop/luca' {
|
|
28
|
-
interface AvailableFeatures {
|
|
29
|
-
myCache: typeof MyCache
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// 4. Now fully typed everywhere:
|
|
34
|
-
const cache = container.feature('myCache', { ttl: 3600 })
|
|
35
|
-
// ^-- TypeScript knows this is MyCache
|
|
36
|
-
// ^-- autocomplete for MyCache options
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Zod Schemas = Types + Runtime Validation
|
|
40
|
-
|
|
41
|
-
Every schema you define gives you both compile-time types and runtime validation:
|
|
42
|
-
|
|
43
|
-
```typescript
|
|
44
|
-
// Define once with Zod
|
|
45
|
-
export const UserOptionsSchema = FeatureOptionsSchema.extend({
|
|
46
|
-
apiKey: z.string().describe('API key for authentication'),
|
|
47
|
-
timeout: z.number().default(5000).describe('Request timeout in ms'),
|
|
48
|
-
retries: z.number().default(3).describe('Max retry attempts'),
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
// Extract the type
|
|
52
|
-
export type UserOptions = z.infer<typeof UserOptionsSchema>
|
|
53
|
-
|
|
54
|
-
// Use for static typing
|
|
55
|
-
export class UserService extends Feature<UserState, UserOptions> {
|
|
56
|
-
static override optionsSchema = UserOptionsSchema
|
|
57
|
-
|
|
58
|
-
connect() {
|
|
59
|
-
// this.options is typed: { apiKey: string, timeout: number, retries: number }
|
|
60
|
-
const { apiKey, timeout } = this.options
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
The schema also powers:
|
|
66
|
-
- **Runtime validation** when options are passed to the factory
|
|
67
|
-
- **Introspection** -- `.describe()` text appears in `helper.introspect()`
|
|
68
|
-
- **Documentation** -- field descriptions appear in `container.features.describe('userService')`
|
|
69
|
-
|
|
70
|
-
## State Typing
|
|
71
|
-
|
|
72
|
-
```typescript
|
|
73
|
-
const TaskStateSchema = FeatureStateSchema.extend({
|
|
74
|
-
tasks: z.array(z.object({
|
|
75
|
-
id: z.string(),
|
|
76
|
-
title: z.string(),
|
|
77
|
-
done: z.boolean(),
|
|
78
|
-
})).default([]),
|
|
79
|
-
filter: z.enum(['all', 'active', 'done']).default('all'),
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
type TaskState = z.infer<typeof TaskStateSchema>
|
|
83
|
-
|
|
84
|
-
class TaskManager extends Feature<TaskState> {
|
|
85
|
-
static override stateSchema = TaskStateSchema
|
|
86
|
-
|
|
87
|
-
addTask(title: string) {
|
|
88
|
-
const tasks = this.state.get('tasks')
|
|
89
|
-
// ^-- typed as Array<{ id: string, title: string, done: boolean }>
|
|
90
|
-
|
|
91
|
-
this.state.set('tasks', [...(tasks || []), { id: '1', title, done: false }])
|
|
92
|
-
// ^-- TypeScript validates the shape
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
## Module Augmentation for All Helper Types
|
|
98
|
-
|
|
99
|
-
The pattern is the same for features, clients, servers, and commands:
|
|
100
|
-
|
|
101
|
-
```typescript
|
|
102
|
-
// Features
|
|
103
|
-
declare module '@soederpop/luca' {
|
|
104
|
-
interface AvailableFeatures {
|
|
105
|
-
myFeature: typeof MyFeature
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Clients
|
|
110
|
-
declare module '@soederpop/luca' {
|
|
111
|
-
interface AvailableClients {
|
|
112
|
-
myClient: typeof MyClient
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Servers
|
|
117
|
-
declare module '@soederpop/luca' {
|
|
118
|
-
interface AvailableServers {
|
|
119
|
-
myServer: typeof MyServer
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Commands
|
|
124
|
-
declare module '@soederpop/luca' {
|
|
125
|
-
interface AvailableCommands {
|
|
126
|
-
myCommand: typeof MyCommand
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
## Using .describe() Effectively
|
|
132
|
-
|
|
133
|
-
```typescript
|
|
134
|
-
const ConfigSchema = z.object({
|
|
135
|
-
host: z.string().describe('Database hostname or IP address'),
|
|
136
|
-
port: z.number().default(5432).describe('Database port'),
|
|
137
|
-
database: z.string().describe('Database name to connect to'),
|
|
138
|
-
ssl: z.boolean().default(false).describe('Whether to use SSL/TLS for the connection'),
|
|
139
|
-
pool: z.object({
|
|
140
|
-
min: z.number().default(2).describe('Minimum connections to keep open'),
|
|
141
|
-
max: z.number().default(10).describe('Maximum connections allowed'),
|
|
142
|
-
}).describe('Connection pool configuration'),
|
|
143
|
-
})
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
These descriptions are not just for humans reading the code -- they show up in:
|
|
147
|
-
- `container.features.describe('db')` output
|
|
148
|
-
- `container.features.introspect('db')` data
|
|
149
|
-
- OpenAPI specs when used in endpoint schemas
|
|
150
|
-
- AI agent tool descriptions
|
|
151
|
-
|
|
152
|
-
## The Full Typed Flow
|
|
153
|
-
|
|
154
|
-
```typescript
|
|
155
|
-
// 1. You define a feature with schemas
|
|
156
|
-
export class Analytics extends Feature<AnalyticsState, AnalyticsOptions> { ... }
|
|
157
|
-
|
|
158
|
-
// 2. You register + augment
|
|
159
|
-
features.register('analytics', Analytics)
|
|
160
|
-
declare module '@soederpop/luca' {
|
|
161
|
-
interface AvailableFeatures { analytics: typeof Analytics }
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// 3. Now every interaction is typed:
|
|
165
|
-
const a = container.feature('analytics', { trackingId: 'UA-123' })
|
|
166
|
-
// ^-- Analytics instance ^-- autocomplete: 'analytics'
|
|
167
|
-
// ^-- type error if wrong options
|
|
168
|
-
|
|
169
|
-
a.state.get('pageViews') // typed by AnalyticsState
|
|
170
|
-
a.on('pageView', ...) // typed by event definitions
|
|
171
|
-
a.track('click', { ... }) // typed by Analytics methods
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
This is the core principle: **never break the type system.** Every step of `container.feature('name', options)` should give you autocomplete, type checking, and documentation.
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Project Patterns and Recipes
|
|
3
|
-
tags: [patterns, recipes, examples, architecture, full-stack, best-practices]
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Project Patterns and Recipes
|
|
7
|
-
|
|
8
|
-
Common patterns for building applications with Luca.
|
|
9
|
-
|
|
10
|
-
## Pattern: REST API with File-Based Routing
|
|
11
|
-
|
|
12
|
-
The most common Luca project -- a JSON API with automatic OpenAPI docs.
|
|
13
|
-
|
|
14
|
-
```
|
|
15
|
-
my-api/
|
|
16
|
-
├── package.json
|
|
17
|
-
├── endpoints/
|
|
18
|
-
│ ├── health.ts
|
|
19
|
-
│ ├── users.ts
|
|
20
|
-
│ └── users/[id].ts
|
|
21
|
-
├── commands/
|
|
22
|
-
│ └── seed.ts
|
|
23
|
-
└── public/
|
|
24
|
-
└── index.html
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
```json
|
|
28
|
-
// package.json
|
|
29
|
-
{
|
|
30
|
-
"name": "my-api",
|
|
31
|
-
"scripts": {
|
|
32
|
-
"dev": "luca serve",
|
|
33
|
-
"seed": "luca seed"
|
|
34
|
-
},
|
|
35
|
-
"dependencies": {
|
|
36
|
-
"@soederpop/luca": "latest",
|
|
37
|
-
"zod": "^3.24.0"
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
Start with `bun run dev`. OpenAPI spec auto-generated at `/openapi.json`.
|
|
43
|
-
|
|
44
|
-
## Pattern: CLI Tool
|
|
45
|
-
|
|
46
|
-
A project that's primarily a set of CLI commands.
|
|
47
|
-
|
|
48
|
-
```
|
|
49
|
-
my-tool/
|
|
50
|
-
├── package.json
|
|
51
|
-
├── commands/
|
|
52
|
-
│ ├── init.ts
|
|
53
|
-
│ ├── build.ts
|
|
54
|
-
│ ├── deploy.ts
|
|
55
|
-
│ └── status.ts
|
|
56
|
-
└── lib/
|
|
57
|
-
└── helpers.ts
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
luca init --template react
|
|
62
|
-
luca build --minify
|
|
63
|
-
luca deploy --env production
|
|
64
|
-
luca status
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## Pattern: AI-Powered App
|
|
68
|
-
|
|
69
|
-
An API with an AI assistant behind it.
|
|
70
|
-
|
|
71
|
-
```
|
|
72
|
-
ai-app/
|
|
73
|
-
├── package.json
|
|
74
|
-
├── endpoints/
|
|
75
|
-
│ ├── health.ts
|
|
76
|
-
│ ├── ask.ts # Proxies to the assistant
|
|
77
|
-
│ └── conversations.ts # List/manage conversations
|
|
78
|
-
├── assistants/
|
|
79
|
-
│ └── helper/
|
|
80
|
-
│ ├── CORE.md
|
|
81
|
-
│ ├── tools.ts
|
|
82
|
-
│ ├── hooks.ts
|
|
83
|
-
│ └── docs/
|
|
84
|
-
│ ├── product-info.md
|
|
85
|
-
│ ├── faq.md
|
|
86
|
-
│ └── policies.md
|
|
87
|
-
└── public/
|
|
88
|
-
└── index.html # Chat UI
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
The endpoint creates the assistant and forwards questions:
|
|
92
|
-
|
|
93
|
-
```typescript
|
|
94
|
-
// endpoints/ask.ts
|
|
95
|
-
import { z } from 'zod'
|
|
96
|
-
import type { EndpointContext } from '@soederpop/luca'
|
|
97
|
-
|
|
98
|
-
export const path = '/api/ask'
|
|
99
|
-
export const postSchema = z.object({
|
|
100
|
-
question: z.string(),
|
|
101
|
-
conversationId: z.string().optional(),
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
export async function post(params: z.infer<typeof postSchema>, ctx: EndpointContext) {
|
|
105
|
-
const assistant = ctx.container.feature('assistant', {
|
|
106
|
-
folder: 'assistants/helper',
|
|
107
|
-
model: 'gpt-4o',
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
const answer = await assistant.ask(params.question)
|
|
111
|
-
return { answer }
|
|
112
|
-
}
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## Pattern: Content-Driven Site
|
|
116
|
-
|
|
117
|
-
Using contentbase to power a documentation site or blog.
|
|
118
|
-
|
|
119
|
-
```
|
|
120
|
-
docs-site/
|
|
121
|
-
├── package.json
|
|
122
|
-
├── content/
|
|
123
|
-
│ ├── guides/
|
|
124
|
-
│ │ ├── getting-started.md
|
|
125
|
-
│ │ ├── configuration.md
|
|
126
|
-
│ │ └── deployment.md
|
|
127
|
-
│ └── reference/
|
|
128
|
-
│ ├── api.md
|
|
129
|
-
│ └── cli.md
|
|
130
|
-
├── endpoints/
|
|
131
|
-
│ ├── docs.ts # Query and serve content
|
|
132
|
-
│ └── search.ts # Full-text search over content
|
|
133
|
-
└── public/
|
|
134
|
-
└── index.html
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
// endpoints/docs.ts
|
|
139
|
-
import { z } from 'zod'
|
|
140
|
-
import type { EndpointContext } from '@soederpop/luca'
|
|
141
|
-
|
|
142
|
-
export const path = '/api/docs'
|
|
143
|
-
export const getSchema = z.object({
|
|
144
|
-
section: z.string().optional(),
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
export async function get(params: z.infer<typeof getSchema>, ctx: EndpointContext) {
|
|
148
|
-
const db = ctx.container.feature('contentDb', { rootPath: './content' })
|
|
149
|
-
await db.load()
|
|
150
|
-
// ... query and return content
|
|
151
|
-
}
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
## Pattern: Automation Script Suite
|
|
155
|
-
|
|
156
|
-
A collection of scripts for DevOps or data tasks.
|
|
157
|
-
|
|
158
|
-
```
|
|
159
|
-
automation/
|
|
160
|
-
├── package.json
|
|
161
|
-
├── scripts/
|
|
162
|
-
│ ├── backup-db.ts
|
|
163
|
-
│ ├── sync-data.ts
|
|
164
|
-
│ ├── generate-report.ts
|
|
165
|
-
│ └── cleanup-old-files.ts
|
|
166
|
-
└── config.json
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
```bash
|
|
170
|
-
luca run scripts/backup-db.ts
|
|
171
|
-
luca run scripts/sync-data.ts --since 2024-01-01
|
|
172
|
-
luca run scripts/generate-report.ts --format pdf
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
## Pattern: Feature Composition
|
|
176
|
-
|
|
177
|
-
Build complex features by composing simpler ones:
|
|
178
|
-
|
|
179
|
-
```typescript
|
|
180
|
-
class NotificationService extends Feature<NotifState, NotifOptions> {
|
|
181
|
-
private cache: any
|
|
182
|
-
private api: any
|
|
183
|
-
|
|
184
|
-
async initialize() {
|
|
185
|
-
// Compose other features
|
|
186
|
-
this.cache = this.container.feature('diskCache', { path: './.notif-cache' })
|
|
187
|
-
this.api = this.container.client('rest', {
|
|
188
|
-
baseURL: this.options.webhookUrl,
|
|
189
|
-
})
|
|
190
|
-
await this.api.connect()
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
async send(channel: string, message: string) {
|
|
194
|
-
// Check rate limiting via cache
|
|
195
|
-
const key = `ratelimit:${channel}`
|
|
196
|
-
if (await this.cache.has(key)) {
|
|
197
|
-
this.emit('rateLimited', { channel })
|
|
198
|
-
return
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// Send via API client
|
|
202
|
-
await this.api.post('/send', { channel, message })
|
|
203
|
-
await this.cache.set(key, true, { ttl: 60 })
|
|
204
|
-
|
|
205
|
-
this.emit('sent', { channel, message })
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
## Best Practices
|
|
211
|
-
|
|
212
|
-
1. **Use file-based conventions** -- endpoints in `endpoints/`, commands in `commands/`, assistants in `assistants/`. This is the Luca way.
|
|
213
|
-
|
|
214
|
-
2. **Let the container own your dependencies** -- instead of importing libraries directly, use features and clients. This gives you introspection, state management, and events for free.
|
|
215
|
-
|
|
216
|
-
3. **Keep endpoints thin** -- endpoints should validate input and delegate to features. Business logic belongs in features, not route handlers.
|
|
217
|
-
|
|
218
|
-
4. **Compose features** -- build complex behavior by combining simpler features. Each feature should do one thing well.
|
|
219
|
-
|
|
220
|
-
5. **Use Zod everywhere** -- for endpoint schemas, feature options, state definitions. It gives you types, validation, and documentation in one place.
|
|
221
|
-
|
|
222
|
-
6. **Document with JSDoc** -- Luca's introspection system extracts it. Your documentation IS your code.
|