@soederpop/luca 0.0.32 → 0.0.35
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/README.md +241 -36
- package/bun.lock +24 -6
- package/commands/build-python-bridge.ts +43 -0
- package/docs/README.md +1 -1
- package/docs/TABLE-OF-CONTENTS.md +0 -1
- package/docs/apis/clients/rest.md +7 -7
- package/docs/apis/clients/websocket.md +23 -10
- package/docs/apis/features/agi/assistant.md +155 -8
- package/docs/apis/features/agi/assistants-manager.md +90 -22
- package/docs/apis/features/agi/auto-assistant.md +377 -0
- package/docs/apis/features/agi/browser-use.md +802 -0
- package/docs/apis/features/agi/claude-code.md +6 -1
- package/docs/apis/features/agi/conversation-history.md +7 -6
- package/docs/apis/features/agi/conversation.md +111 -38
- package/docs/apis/features/agi/docs-reader.md +35 -57
- package/docs/apis/features/agi/file-tools.md +163 -0
- package/docs/apis/features/agi/openapi.md +2 -2
- package/docs/apis/features/agi/skills-library.md +227 -0
- package/docs/apis/features/node/content-db.md +125 -4
- package/docs/apis/features/node/disk-cache.md +11 -11
- package/docs/apis/features/node/downloader.md +1 -1
- package/docs/apis/features/node/file-manager.md +15 -15
- package/docs/apis/features/node/fs.md +78 -21
- package/docs/apis/features/node/git.md +50 -10
- package/docs/apis/features/node/google-calendar.md +3 -0
- package/docs/apis/features/node/google-docs.md +10 -1
- package/docs/apis/features/node/google-drive.md +3 -0
- package/docs/apis/features/node/google-mail.md +214 -0
- package/docs/apis/features/node/google-sheets.md +3 -0
- package/docs/apis/features/node/ink.md +10 -10
- package/docs/apis/features/node/ipc-socket.md +83 -93
- package/docs/apis/features/node/networking.md +5 -5
- package/docs/apis/features/node/os.md +7 -7
- package/docs/apis/features/node/package-finder.md +14 -14
- package/docs/apis/features/node/proc.md +2 -1
- package/docs/apis/features/node/process-manager.md +70 -3
- package/docs/apis/features/node/python.md +265 -9
- package/docs/apis/features/node/redis.md +380 -0
- package/docs/apis/features/node/ui.md +13 -13
- package/docs/apis/servers/express.md +35 -7
- package/docs/apis/servers/mcp.md +3 -3
- package/docs/apis/servers/websocket.md +51 -8
- package/docs/bootstrap/CLAUDE.md +1 -1
- package/docs/bootstrap/SKILL.md +93 -7
- package/docs/examples/feature-as-tool-provider.md +143 -0
- package/docs/examples/python.md +42 -1
- package/docs/introspection.md +15 -5
- package/docs/tutorials/00-bootstrap.md +3 -3
- package/docs/tutorials/02-container.md +2 -2
- package/docs/tutorials/10-creating-features.md +5 -0
- package/docs/tutorials/13-introspection.md +12 -2
- package/docs/tutorials/19-python-sessions.md +401 -0
- package/package.json +8 -5
- package/scripts/examples/using-assistant-with-mcp.ts +2 -7
- package/scripts/test-linux-binary.sh +80 -0
- package/src/agi/container.server.ts +8 -0
- package/src/agi/features/assistant.ts +18 -0
- package/src/agi/features/autonomous-assistant.ts +435 -0
- package/src/agi/features/conversation.ts +58 -6
- package/src/agi/features/file-tools.ts +286 -0
- package/src/agi/features/luca-coder.ts +643 -0
- package/src/bootstrap/generated.ts +705 -107
- package/src/cli/build-info.ts +2 -2
- package/src/cli/cli.ts +22 -13
- package/src/commands/bootstrap.ts +49 -6
- package/src/commands/code.ts +369 -0
- package/src/commands/describe.ts +7 -2
- package/src/commands/index.ts +1 -0
- package/src/commands/sandbox-mcp.ts +7 -7
- package/src/commands/save-api-docs.ts +1 -1
- package/src/container-describer.ts +4 -4
- package/src/container.ts +10 -19
- package/src/helper.ts +24 -33
- package/src/introspection/generated.agi.ts +3026 -849
- package/src/introspection/generated.node.ts +1690 -1012
- package/src/introspection/generated.web.ts +15 -57
- package/src/node/container.ts +5 -5
- package/src/node/features/figlet-fonts.ts +597 -0
- package/src/node/features/fs.ts +3 -9
- package/src/node/features/helpers.ts +20 -0
- package/src/node/features/python.ts +429 -16
- package/src/node/features/redis.ts +446 -0
- package/src/node/features/ui.ts +4 -11
- package/src/python/bridge.py +220 -0
- package/src/python/generated.ts +227 -0
- package/src/scaffolds/generated.ts +1 -1
- package/test/python-session.test.ts +105 -0
- package/assistants/lucaExpert/CORE.md +0 -37
- package/assistants/lucaExpert/hooks.ts +0 -9
- package/assistants/lucaExpert/tools.ts +0 -177
- package/docs/examples/port-exposer.md +0 -89
- package/src/node/features/port-exposer.ts +0 -351
package/README.md
CHANGED
|
@@ -1,48 +1,171 @@
|
|
|
1
|
-
# Luca
|
|
1
|
+
# Luca
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Lightweight Universal Conversational Architecture**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
A single binary CLI that ships 40+ self-documenting features, clients, and servers. No `npm install`, no setup — download it and start building.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Luca gives you a `container` object — think of it like a Docker container for your application runtime. It's a per-process singleton, event bus, state machine, and dependency injector all in one. Layer your own features, clients, servers, commands, and endpoints on top of the base `NodeContainer` (server) or `WebContainer` (browser), then bundle it into your own single-file executable or browser build.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
The `AGIContainer` extends the node stack with features, clients, and servers for building AI assistants — wrappers around major coding models, tool orchestration, and UIs to visualize them working.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
### Download the binary
|
|
14
|
+
|
|
15
|
+
Grab the latest release for your platform from [GitHub Releases](https://github.com/soederpop/luca/releases/latest):
|
|
16
|
+
|
|
17
|
+
| Platform | Binary |
|
|
18
|
+
|----------|--------|
|
|
19
|
+
| macOS (Apple Silicon) | `luca-darwin-arm64` |
|
|
20
|
+
| macOS (Intel) | `luca-darwin-x64` |
|
|
21
|
+
| Linux x64 | `luca-linux-x64` |
|
|
22
|
+
| Linux ARM64 | `luca-linux-arm64` |
|
|
23
|
+
| Windows x64 | `luca-windows-x64.exe` |
|
|
24
|
+
|
|
25
|
+
**Quick install (macOS/Linux):**
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
# Download (replace PLATFORM with your arch, e.g. darwin-arm64)
|
|
29
|
+
curl -L -o luca https://github.com/soederpop/luca/releases/latest/download/luca-PLATFORM
|
|
30
|
+
chmod +x luca
|
|
31
|
+
sudo mv luca /usr/local/bin/
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### macOS Gatekeeper warning
|
|
35
|
+
|
|
36
|
+
The binary is not yet code-signed (code signing is in progress). On first run macOS will block it with *"luca can't be opened because Apple cannot check it for malicious software."*
|
|
37
|
+
|
|
38
|
+
To allow it:
|
|
39
|
+
|
|
40
|
+
1. **System Settings** > **Privacy & Security** > scroll down to the Security section
|
|
41
|
+
2. You'll see a message about `luca` being blocked — click **Allow Anyway**
|
|
42
|
+
3. Run `luca` again and click **Open** in the confirmation dialog
|
|
43
|
+
|
|
44
|
+
Or from the terminal:
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
xattr -d com.apple.quarantine /usr/local/bin/luca
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
After that it runs without interruption.
|
|
51
|
+
|
|
52
|
+
### Verify
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
luca --version
|
|
56
|
+
# luca v0.0.34 (main@325a0ee) built 2026-03-25T06:10:28Z
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Quick Start
|
|
60
|
+
|
|
61
|
+
### Bootstrap a new project
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
luca bootstrap my-app
|
|
65
|
+
cd my-app
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Or just run `luca bootstrap` and it'll ask you for a project name. This scaffolds a project with `commands/`, `endpoints/`, `features/`, `docs/`, and AI assistant configuration — everything wired up and ready to extend.
|
|
69
|
+
|
|
70
|
+
### Explore
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
luca # list all commands
|
|
74
|
+
luca describe features # index of 40+ features
|
|
75
|
+
luca describe fs # full docs for any feature
|
|
76
|
+
luca describe fs.readFile # drill into a specific method
|
|
77
|
+
luca eval "container.features.available" # run code with the container in scope
|
|
78
|
+
luca console # full REPL
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Run scripts and markdown
|
|
82
|
+
|
|
83
|
+
`luca run` executes TypeScript, JavaScript, and markdown files. Markdown files have their code blocks executed in order, with `container` already in scope — no imports needed:
|
|
84
|
+
|
|
85
|
+
````md
|
|
86
|
+
# my-script.md
|
|
87
|
+
|
|
88
|
+
Grab some data and print it:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
const fs = container.feature('fs')
|
|
92
|
+
const files = await fs.readdir('.')
|
|
93
|
+
console.log(`Found ${files.length} files`)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Then do something with it:
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
const yaml = container.feature('yaml')
|
|
100
|
+
console.log(yaml.stringify({ files }))
|
|
101
|
+
```
|
|
102
|
+
````
|
|
103
|
+
|
|
104
|
+
```sh
|
|
105
|
+
luca run my-script.md
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Each block shares state with the previous ones, so variables defined in one block are available in the next. Use `--safe` to require approval before each block, or `--console` to drop into a REPL afterward with all the accumulated context. **Note:** if your block uses top-level awaits, we can't preserve context. You can use `container.addContext({ yourVariable })` and it will be available as a global variable in future blocks.
|
|
109
|
+
|
|
110
|
+
### Serve
|
|
111
|
+
|
|
112
|
+
```sh
|
|
113
|
+
luca serve # serves endpoints/ folder as HTTP routes
|
|
114
|
+
```
|
|
12
115
|
|
|
13
|
-
|
|
116
|
+
See [`docs/CLI.md`](./docs/CLI.md) for the full CLI reference.
|
|
14
117
|
|
|
15
|
-
|
|
118
|
+
## Importing the container into your own scripts / modules
|
|
16
119
|
|
|
17
120
|
```ts
|
|
18
121
|
import container from '@soederpop/luca'
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
That's it — you get one object with everything on it. No factory function, no setup. It's a singleton.
|
|
125
|
+
|
|
126
|
+
We do export the framework classes (`WebContainer`, `Feature`, `Client`, `Server`, etc.) if you want to extend them, but for using the system you only ever need the default export.
|
|
127
|
+
|
|
128
|
+
### In the browser via esm.sh
|
|
19
129
|
|
|
20
|
-
|
|
21
|
-
container.clients.available // ['rest','websocket']
|
|
22
|
-
container.servers.available // ['express','websocket','ipc','mcp']
|
|
130
|
+
**Static import:**
|
|
23
131
|
|
|
24
|
-
|
|
25
|
-
container.
|
|
132
|
+
```js
|
|
133
|
+
import container from 'https://esm.sh/@soederpop/luca/web'
|
|
26
134
|
|
|
27
|
-
container.
|
|
28
|
-
container.introspectAsText() // a markdown description of the same
|
|
135
|
+
container.features.available // ['fetch', 'state', 'ui', ...]
|
|
29
136
|
```
|
|
30
137
|
|
|
31
|
-
|
|
138
|
+
**Dynamic import:**
|
|
32
139
|
|
|
33
|
-
|
|
140
|
+
```js
|
|
141
|
+
const { default: container } = await import('https://esm.sh/@soederpop/luca/web')
|
|
34
142
|
|
|
143
|
+
container.features.available // same singleton
|
|
35
144
|
```
|
|
36
|
-
const fileManager = container.feature('fileManager')
|
|
37
145
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
146
|
+
With dynamic import you have to pick it off `default` yourself — there's no top-level default binding like the static form gives you. Either way, it's the same singleton container, and `window.luca` is set automatically so you can poke at it from the console.
|
|
147
|
+
|
|
148
|
+
## How It Works
|
|
149
|
+
|
|
150
|
+
### Self-documenting at runtime
|
|
151
|
+
|
|
152
|
+
Every helper (feature, client, server) carries its own introspection metadata — constructor options, observable state shape, events emitted, environment variables used, method signatures. This powers `luca describe`, works in the REPL, and enables metaprogramming.
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
import container from '@soederpop/luca'
|
|
156
|
+
|
|
157
|
+
container.features.available // ['fs','git','proc','vault',...]
|
|
158
|
+
container.clients.available // ['rest','websocket']
|
|
159
|
+
container.servers.available // ['express','websocket','ipc','mcp']
|
|
160
|
+
|
|
161
|
+
container.features.describe() // markdown summary of all features
|
|
162
|
+
container.feature('fs').introspect() // json
|
|
163
|
+
container.feature('fs').introspectAsText() // markdown
|
|
41
164
|
```
|
|
42
165
|
|
|
43
|
-
|
|
166
|
+
### Content-aware documentation
|
|
44
167
|
|
|
45
|
-
The node container
|
|
168
|
+
The node container includes `container.docs` powered by [Contentbase](https://github.com/soederpop/contentbase) — query your project's markdown documentation like a database:
|
|
46
169
|
|
|
47
170
|
```ts
|
|
48
171
|
await container.docs.load()
|
|
@@ -50,29 +173,111 @@ const { Tutorial } = container.docs.models
|
|
|
50
173
|
const tutorials = await container.docs.query(Tutorial).fetchAll()
|
|
51
174
|
```
|
|
52
175
|
|
|
53
|
-
|
|
176
|
+
### Project extensions
|
|
177
|
+
|
|
178
|
+
Drop files into convention-based folders and they're auto-discovered:
|
|
54
179
|
|
|
55
|
-
|
|
180
|
+
- `commands/` — custom CLI commands, run via `luca <name>`
|
|
181
|
+
- `endpoints/` — file-based HTTP routes, served via `luca serve`
|
|
182
|
+
- `features/` — custom container features
|
|
56
183
|
|
|
57
|
-
|
|
58
|
-
- The `luca describe` command lets you view docs, or just parts of docs, of any group of features, clients, etc, as a single markdown doc
|
|
59
|
-
- The `luca console` command will bring you into a full blown REPL
|
|
60
|
-
- The `luca chat` command will put you in touch with a tutor
|
|
61
|
-
- The `luca sandbox-mcp` provides a REPL for your coding assistant and a documentation browser
|
|
184
|
+
Generate boilerplate with `luca scaffold`:
|
|
62
185
|
|
|
63
|
-
|
|
186
|
+
```sh
|
|
187
|
+
luca scaffold command myTask --description "Automate something"
|
|
188
|
+
luca scaffold feature myCache --description "Custom caching layer"
|
|
189
|
+
luca scaffold endpoint users --description "User management API"
|
|
190
|
+
```
|
|
64
191
|
|
|
65
|
-
|
|
192
|
+
### Building an assistant
|
|
66
193
|
|
|
67
|
-
|
|
194
|
+
Features can inject their own tools into an assistant via `assistant.use()`. Here's an assistant that can browse the web:
|
|
68
195
|
|
|
69
|
-
|
|
196
|
+
```ts
|
|
197
|
+
import container from '@soederpop/luca'
|
|
198
|
+
|
|
199
|
+
const browser = container.feature('browserUse', { headed: true })
|
|
200
|
+
const assistant = container.feature('assistant', {
|
|
201
|
+
systemPrompt: 'You are a web research assistant. Use your browser tools to find information.',
|
|
202
|
+
model: 'gpt-4.1-mini',
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
// browserUse injects its tools — open, click, type, screenshot, extract, etc.
|
|
206
|
+
assistant.use(browser)
|
|
207
|
+
await assistant.start()
|
|
208
|
+
|
|
209
|
+
await assistant.ask('Go to hacker news and tell me what the top 3 stories are about')
|
|
210
|
+
```
|
|
70
211
|
|
|
71
|
-
|
|
212
|
+
### AI coding assistant integration
|
|
213
|
+
|
|
214
|
+
The CLI works great alongside Claude Code, Codex, and other coding assistants:
|
|
215
|
+
|
|
216
|
+
- `luca describe` gives assistants full API docs for any helper
|
|
217
|
+
- `luca eval` lets them test container expressions before committing code
|
|
218
|
+
- `luca sandbox-mcp` provides a REPL and doc browser as an MCP server
|
|
219
|
+
|
|
220
|
+
## Development
|
|
221
|
+
|
|
222
|
+
### Prerequisites
|
|
223
|
+
|
|
224
|
+
- [Bun](https://bun.sh) (runtime and test runner)
|
|
225
|
+
|
|
226
|
+
### Setup
|
|
227
|
+
|
|
228
|
+
```sh
|
|
229
|
+
git clone https://github.com/soederpop/luca.git
|
|
230
|
+
cd luca
|
|
231
|
+
bun install
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Running in dev
|
|
235
|
+
|
|
236
|
+
```sh
|
|
237
|
+
# Run the CLI from source (equivalent to the luca binary)
|
|
238
|
+
bun run src/cli/cli.ts
|
|
239
|
+
|
|
240
|
+
# Examples
|
|
241
|
+
bun run src/cli/cli.ts describe features
|
|
242
|
+
bun run src/cli/cli.ts eval "container.features.available"
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Testing
|
|
246
|
+
|
|
247
|
+
```sh
|
|
248
|
+
# Unit tests
|
|
249
|
+
bun test
|
|
250
|
+
|
|
251
|
+
# Integration tests (may require API keys / env vars)
|
|
252
|
+
bun run test:integration
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Building the binary
|
|
72
256
|
|
|
73
257
|
```sh
|
|
74
|
-
|
|
258
|
+
bun run compile
|
|
75
259
|
```
|
|
76
260
|
|
|
261
|
+
This runs the full pipeline: introspection generation, scaffold templates, bootstrap code, python bridge, build stamp, then compiles to `dist/luca` via Bun's native compiler.
|
|
262
|
+
|
|
263
|
+
### Project structure
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
src/
|
|
267
|
+
cli/ CLI entry point and commands
|
|
268
|
+
node/ NodeContainer and server-side features
|
|
269
|
+
web/ WebContainer and browser features
|
|
270
|
+
agi/ AGIContainer — AI assistant layer
|
|
271
|
+
schemas/ Shared Zod schemas
|
|
272
|
+
react/ React bindings
|
|
273
|
+
test/ Unit tests
|
|
274
|
+
test-integration/ Integration tests
|
|
275
|
+
docs/
|
|
276
|
+
apis/ Generated API docs
|
|
277
|
+
examples/ Runnable examples (luca run docs/examples/grep)
|
|
278
|
+
tutorials/ Longer-form guides
|
|
279
|
+
```
|
|
77
280
|
|
|
281
|
+
## License
|
|
78
282
|
|
|
283
|
+
MIT
|
package/bun.lock
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
"name": "@soederpop/luca",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
8
|
-
"@ngrok/ngrok": "^1.5.1",
|
|
9
8
|
"@openai/codex": "^0.99.0",
|
|
10
9
|
"@resvg/resvg-js": "^2.6.2",
|
|
11
10
|
"@supabase/supabase-js": "^2.95.3",
|
|
@@ -18,7 +17,7 @@
|
|
|
18
17
|
"chokidar": "^3.5.3",
|
|
19
18
|
"cli-markdown": "^3.5.0",
|
|
20
19
|
"compromise": "^14.14.5",
|
|
21
|
-
"contentbase": "^0.
|
|
20
|
+
"contentbase": "^0.1.7",
|
|
22
21
|
"cors": "^2.8.5",
|
|
23
22
|
"detect-port": "^1.5.1",
|
|
24
23
|
"dotenv": "^17.2.4",
|
|
@@ -33,6 +32,7 @@
|
|
|
33
32
|
"inflect": "^0.5.0",
|
|
34
33
|
"ink": "^6.7.0",
|
|
35
34
|
"inquirer": "^9.1.5",
|
|
35
|
+
"ioredis": "^5.10.1",
|
|
36
36
|
"isomorphic-vm": "^0.0.1",
|
|
37
37
|
"isomorphic-ws": "^5.0.0",
|
|
38
38
|
"js-tiktoken": "^1.0.21",
|
|
@@ -192,6 +192,8 @@
|
|
|
192
192
|
|
|
193
193
|
"@inquirer/figures": ["@inquirer/figures@1.0.12", "", {}, "sha512-MJttijd8rMFcKJC8NYmprWr6hD3r9Gd9qUC0XwPNwoEPWSMVJwA2MlXxF+nhZZNMY+HXsWa+o7KY2emWYIn0jQ=="],
|
|
194
194
|
|
|
195
|
+
"@ioredis/commands": ["@ioredis/commands@1.5.1", "", {}, "sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw=="],
|
|
196
|
+
|
|
195
197
|
"@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
|
|
196
198
|
|
|
197
199
|
"@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="],
|
|
@@ -334,7 +336,7 @@
|
|
|
334
336
|
|
|
335
337
|
"@sindresorhus/is": ["@sindresorhus/is@4.6.0", "", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="],
|
|
336
338
|
|
|
337
|
-
"@soederpop/luca": ["@soederpop/luca@0.0.
|
|
339
|
+
"@soederpop/luca": ["@soederpop/luca@0.0.32", "", { "dependencies": { "@modelcontextprotocol/sdk": "^1.12.1", "@ngrok/ngrok": "^1.5.1", "@openai/codex": "^0.99.0", "@resvg/resvg-js": "^2.6.2", "@supabase/supabase-js": "^2.95.3", "@types/marked": "^6.0.0", "@types/marked-terminal": "^6.1.1", "axios": "^1.3.5", "cacache": "^17.0.7", "chalk": "^5.2.0", "child-process-promise": "^2.2.1", "chokidar": "^3.5.3", "cli-markdown": "^3.5.0", "compromise": "^14.14.5", "contentbase": "^0.1.7", "cors": "^2.8.5", "detect-port": "^1.5.1", "dotenv": "^17.2.4", "endent": "^2.1.0", "esbuild-wasm": "0.17.18", "excalidraw-to-svg": "^3.1.0", "express": "^4.18.2", "figlet": "^1.6.0", "glob": "^11.0.2", "googleapis": "^171.4.0", "grammy": "^1.40.0", "inflect": "^0.5.0", "ink": "^6.7.0", "inquirer": "^9.1.5", "isomorphic-vm": "^0.0.1", "isomorphic-ws": "^5.0.0", "js-tiktoken": "^1.0.21", "js-yaml": "^4.1.0", "lodash-es": "^4.17.21", "marked": "^15.0.12", "marked-terminal": "^7.3.0", "mdast-util-to-markdown": "^1.5.0", "mdast-util-to-string": "^3.2.0", "micromatch": "^4.0.5", "minimist": "^1.2.8", "node-uuid": "^1.4.8", "object-hash": "^3.0.0", "openai": "^5.1.1", "opener": "^1.5.2", "react": "^19.2.4", "react-devtools-core": "^7.0.1", "react-dom": "^19.2.4", "react-reconciler": "^0.33.0", "remark-gfm": "^3.0.1", "rimraf": "^5.0.0", "typescript": "^5.9.3", "unist-util-find-after": "^4.0.1", "unist-util-find-all-after": "^4.0.1", "unist-util-find-all-before": "^4.0.1", "unist-util-find-before": "^3.0.1", "unist-util-select": "^4.0.3", "unist-util-visit": "^4.1.2", "wink-eng-lite-web-model": "^1.8.1", "wink-nlp": "^2.4.0", "ws": "^8.13.0", "zod": "^4.0.0" }, "optionalDependencies": { "node-llama-cpp": "^3.17.1" }, "bin": { "luca": "src/cli/cli.ts" } }, "sha512-JlIz18N0/J/dDfaFluJdwIvY1P6LkuV/gDBbrj3XGKAN1YaumMLThTcoQARE8CgEyfKVfM8bM9T9nNmygs1lCQ=="],
|
|
338
340
|
|
|
339
341
|
"@supabase/auth-js": ["@supabase/auth-js@2.95.3", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-vD2YoS8E2iKIX0F7EwXTmqhUpaNsmbU6X2R0/NdFcs02oEfnHyNP/3M716f3wVJ2E5XHGiTFXki6lRckhJ0Thg=="],
|
|
340
342
|
|
|
@@ -638,6 +640,8 @@
|
|
|
638
640
|
|
|
639
641
|
"clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="],
|
|
640
642
|
|
|
643
|
+
"cluster-key-slot": ["cluster-key-slot@1.1.2", "", {}, "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA=="],
|
|
644
|
+
|
|
641
645
|
"cmake-js": ["cmake-js@8.0.0", "", { "dependencies": { "debug": "^4.4.3", "fs-extra": "^11.3.3", "node-api-headers": "^1.8.0", "rc": "1.2.8", "semver": "^7.7.3", "tar": "^7.5.6", "url-join": "^4.0.1", "which": "^6.0.0", "yargs": "^17.7.2" }, "bin": { "cmake-js": "bin/cmake-js" } }, "sha512-YbUP88RDwCvoQkZhRtGURYm9RIpWdtvZuhT87fKNoLjk8kIFIFeARpKfuZQGdwfH99GZpUmqSfcDrK62X7lTgg=="],
|
|
642
646
|
|
|
643
647
|
"code-excerpt": ["code-excerpt@4.0.0", "", { "dependencies": { "convert-to-spaces": "^2.0.1" } }, "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA=="],
|
|
@@ -674,7 +678,7 @@
|
|
|
674
678
|
|
|
675
679
|
"content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
|
|
676
680
|
|
|
677
|
-
"contentbase": ["contentbase@0.
|
|
681
|
+
"contentbase": ["contentbase@0.1.8", "", { "dependencies": { "@soederpop/luca": ">=0.0.16", "gray-matter": "^4.0.3", "js-yaml": "^4.1.0", "mdast-util-mdxjs-esm": "^2.0.1", "mdast-util-to-markdown": "^2.1.2", "mdast-util-to-string": "^4.0.0", "picomatch": "^4.0.3", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-stringify": "^11.0.0", "unified": "^11.0.5", "unist-util-find-after": "^5.0.0", "unist-util-find-all-after": "^5.0.0", "unist-util-find-all-before": "^5.0.0", "unist-util-find-before": "^4.0.0", "unist-util-select": "^5.1.0", "unist-util-visit": "^5.0.0", "zod": "^4.3.6" }, "bin": { "cnotes": "src/cli/index.ts", "contentbase": "src/cli/index.ts" } }, "sha512-FcivPrOkmowDea2FobSCHPmNdudQz90ZF5xwp2aDF5ajRXu1lujvzOXEvmwAZ9AcJC37BQHVNR0Ifa1guZaODw=="],
|
|
678
682
|
|
|
679
683
|
"convert-to-spaces": ["convert-to-spaces@2.0.1", "", {}, "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ=="],
|
|
680
684
|
|
|
@@ -684,8 +688,6 @@
|
|
|
684
688
|
|
|
685
689
|
"cors": ["cors@2.8.5", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g=="],
|
|
686
690
|
|
|
687
|
-
"cross-fetch": ["cross-fetch@4.1.0", "", { "dependencies": { "node-fetch": "^2.7.0" } }, "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw=="],
|
|
688
|
-
|
|
689
691
|
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
|
690
692
|
|
|
691
693
|
"css-declaration-sorter": ["css-declaration-sorter@7.2.0", "", { "peerDependencies": { "postcss": "^8.0.9" } }, "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow=="],
|
|
@@ -738,6 +740,8 @@
|
|
|
738
740
|
|
|
739
741
|
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
|
|
740
742
|
|
|
743
|
+
"denque": ["denque@2.1.0", "", {}, "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="],
|
|
744
|
+
|
|
741
745
|
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
|
|
742
746
|
|
|
743
747
|
"dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="],
|
|
@@ -1032,6 +1036,8 @@
|
|
|
1032
1036
|
|
|
1033
1037
|
"inquirer": ["inquirer@9.3.7", "", { "dependencies": { "@inquirer/figures": "^1.0.3", "ansi-escapes": "^4.3.2", "cli-width": "^4.1.0", "external-editor": "^3.1.0", "mute-stream": "1.0.0", "ora": "^5.4.1", "run-async": "^3.0.0", "rxjs": "^7.8.1", "string-width": "^4.2.3", "strip-ansi": "^6.0.1", "wrap-ansi": "^6.2.0", "yoctocolors-cjs": "^2.1.2" } }, "sha512-LJKFHCSeIRq9hanN14IlOtPSTe3lNES7TYDTE2xxdAy1LS5rYphajK1qtwvj3YmQXvvk0U2Vbmcni8P9EIQW9w=="],
|
|
1034
1038
|
|
|
1039
|
+
"ioredis": ["ioredis@5.10.1", "", { "dependencies": { "@ioredis/commands": "1.5.1", "cluster-key-slot": "^1.1.0", "debug": "^4.3.4", "denque": "^2.1.0", "lodash.defaults": "^4.2.0", "lodash.isarguments": "^3.1.0", "redis-errors": "^1.2.0", "redis-parser": "^3.0.0", "standard-as-callback": "^2.1.0" } }, "sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA=="],
|
|
1040
|
+
|
|
1035
1041
|
"ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="],
|
|
1036
1042
|
|
|
1037
1043
|
"ipull": ["ipull@3.9.5", "", { "dependencies": { "@tinyhttp/content-disposition": "^2.2.0", "async-retry": "^1.3.3", "chalk": "^5.3.0", "ci-info": "^4.0.0", "cli-spinners": "^2.9.2", "commander": "^10.0.0", "eventemitter3": "^5.0.1", "filenamify": "^6.0.0", "fs-extra": "^11.1.1", "is-unicode-supported": "^2.0.0", "lifecycle-utils": "^2.0.1", "lodash.debounce": "^4.0.8", "lowdb": "^7.0.1", "pretty-bytes": "^6.1.0", "pretty-ms": "^8.0.0", "sleep-promise": "^9.1.0", "slice-ansi": "^7.1.0", "stdout-update": "^4.0.1", "strip-ansi": "^7.1.0" }, "optionalDependencies": { "@reflink/reflink": "^0.1.16" }, "bin": { "ipull": "dist/cli/cli.js" } }, "sha512-5w/yZB5lXmTfsvNawmvkCjYo4SJNuKQz/av8TC1UiOyfOHyaM+DReqbpU2XpWYfmY+NIUbRRH8PUAWsxaS+IfA=="],
|
|
@@ -1122,6 +1128,10 @@
|
|
|
1122
1128
|
|
|
1123
1129
|
"lodash.debounce": ["lodash.debounce@4.0.8", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="],
|
|
1124
1130
|
|
|
1131
|
+
"lodash.defaults": ["lodash.defaults@4.2.0", "", {}, "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="],
|
|
1132
|
+
|
|
1133
|
+
"lodash.isarguments": ["lodash.isarguments@3.1.0", "", {}, "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg=="],
|
|
1134
|
+
|
|
1125
1135
|
"lodash.memoize": ["lodash.memoize@4.1.2", "", {}, "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag=="],
|
|
1126
1136
|
|
|
1127
1137
|
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
|
|
@@ -1536,6 +1546,10 @@
|
|
|
1536
1546
|
|
|
1537
1547
|
"readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
|
|
1538
1548
|
|
|
1549
|
+
"redis-errors": ["redis-errors@1.2.0", "", {}, "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w=="],
|
|
1550
|
+
|
|
1551
|
+
"redis-parser": ["redis-parser@3.0.0", "", { "dependencies": { "redis-errors": "^1.0.0" } }, "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A=="],
|
|
1552
|
+
|
|
1539
1553
|
"rehype-stringify": ["rehype-stringify@10.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-to-html": "^9.0.0", "unified": "^11.0.0" } }, "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA=="],
|
|
1540
1554
|
|
|
1541
1555
|
"remark-gfm": ["remark-gfm@3.0.1", "", { "dependencies": { "@types/mdast": "^3.0.0", "mdast-util-gfm": "^2.0.0", "micromark-extension-gfm": "^2.0.0", "unified": "^10.0.0" } }, "sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig=="],
|
|
@@ -1634,6 +1648,8 @@
|
|
|
1634
1648
|
|
|
1635
1649
|
"stack-utils": ["stack-utils@2.0.6", "", { "dependencies": { "escape-string-regexp": "^2.0.0" } }, "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ=="],
|
|
1636
1650
|
|
|
1651
|
+
"standard-as-callback": ["standard-as-callback@2.1.0", "", {}, "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="],
|
|
1652
|
+
|
|
1637
1653
|
"statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
|
|
1638
1654
|
|
|
1639
1655
|
"stdin-discarder": ["stdin-discarder@0.3.1", "", {}, "sha512-reExS1kSGoElkextOcPkel4NE99S0BWxjUHQeDFnR8S993JxpPX7KU4MNmO19NXhlJp+8dmdCbKQVNgLJh2teA=="],
|
|
@@ -2030,6 +2046,8 @@
|
|
|
2030
2046
|
|
|
2031
2047
|
"inquirer/wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="],
|
|
2032
2048
|
|
|
2049
|
+
"ioredis/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
|
2050
|
+
|
|
2033
2051
|
"ipull/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
|
|
2034
2052
|
|
|
2035
2053
|
"ipull/lifecycle-utils": ["lifecycle-utils@2.1.0", "", {}, "sha512-AnrXnE2/OF9PHCyFg0RSqsnQTzV991XaZA/buhFDoc58xU7rhSCDgCz/09Lqpsn4MpoPHt7TRAXV1kWZypFVsA=="],
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import type { ContainerContext } from '@soederpop/luca'
|
|
3
|
+
import { CommandOptionsSchema } from '@soederpop/luca/schemas'
|
|
4
|
+
|
|
5
|
+
export const argsSchema = CommandOptionsSchema.extend({})
|
|
6
|
+
|
|
7
|
+
async function buildPythonBridge(options: z.infer<typeof argsSchema>, context: ContainerContext) {
|
|
8
|
+
const container = context.container as any
|
|
9
|
+
const fs = container.feature('fs')
|
|
10
|
+
|
|
11
|
+
const sourcePath = 'src/python/bridge.py'
|
|
12
|
+
const outputPath = 'src/python/generated.ts'
|
|
13
|
+
|
|
14
|
+
if (!fs.exists(sourcePath)) {
|
|
15
|
+
console.error(` ❌ ${sourcePath} not found`)
|
|
16
|
+
process.exit(1)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const content = fs.readFile(sourcePath)
|
|
20
|
+
console.log(` 📄 bridge.py: ${content.length} chars`)
|
|
21
|
+
|
|
22
|
+
const escapeForTemplate = (s: string) =>
|
|
23
|
+
s.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$\{/g, '\\${')
|
|
24
|
+
|
|
25
|
+
const output = `// Auto-generated Python bridge script
|
|
26
|
+
// Generated at: ${new Date().toISOString()}
|
|
27
|
+
// Source: src/python/bridge.py
|
|
28
|
+
//
|
|
29
|
+
// Do not edit manually. Run: luca build-python-bridge
|
|
30
|
+
|
|
31
|
+
export const bridgeScript = \`${escapeForTemplate(content)}\`
|
|
32
|
+
`
|
|
33
|
+
|
|
34
|
+
fs.ensureFolder('src/python')
|
|
35
|
+
await fs.writeFileAsync(outputPath, output)
|
|
36
|
+
console.log(`\n✨ Generated ${outputPath}`)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default {
|
|
40
|
+
description: 'Bundle the Python bridge script into src/python/generated.ts',
|
|
41
|
+
argsSchema,
|
|
42
|
+
handler: buildPythonBridge,
|
|
43
|
+
}
|
package/docs/README.md
CHANGED
|
@@ -25,7 +25,7 @@ Items: 169
|
|
|
25
25
|
Sections: (none)
|
|
26
26
|
Relationships: (none)
|
|
27
27
|
Documents: 43
|
|
28
|
-
IDs: examples/postgres, examples/yaml-tree, examples/grep, examples/ink, examples/git, examples/ink-renderer, examples/esbuild, examples/window-manager, examples/process-manager, examples/runpod, examples/google-auth, examples/
|
|
28
|
+
IDs: examples/postgres, examples/yaml-tree, examples/grep, examples/ink, examples/git, examples/ink-renderer, examples/esbuild, examples/window-manager, examples/process-manager, examples/runpod, examples/google-auth, examples/downloader, examples/secure-shell, examples/vault, examples/window-manager-layouts, examples/ipc-socket, examples/google-sheets, examples/fs, examples/networking, examples/ink-blocks, examples/ui, examples/opener, examples/nlp, examples/disk-cache, examples/assistant/CORE, examples/vm, examples/google-docs, examples/google-calendar, examples/content-db, examples/yaml, examples/package-finder, examples/os, examples/json-tree, examples/google-drive, examples/telegram, examples/file-manager, examples/repl, examples/python, examples/sqlite, examples/tts, examples/docker, examples/proc
|
|
29
29
|
|
|
30
30
|
Model: Idea
|
|
31
31
|
Prefix: ideas
|
|
@@ -43,7 +43,6 @@
|
|
|
43
43
|
- [Opener](./examples/opener.md)
|
|
44
44
|
- [os](./examples/os.md)
|
|
45
45
|
- [Package Finder](./examples/package-finder.md)
|
|
46
|
-
- [Port Exposer](./examples/port-exposer.md)
|
|
47
46
|
- [PostgreSQL](./examples/postgres.md)
|
|
48
47
|
- [proc](./examples/proc.md)
|
|
49
48
|
- [Process Manager](./examples/process-manager.md)
|
|
@@ -24,13 +24,13 @@ container.client('rest', {
|
|
|
24
24
|
|
|
25
25
|
### beforeRequest
|
|
26
26
|
|
|
27
|
-
**Returns:** `void
|
|
27
|
+
**Returns:** `Promise<void>`
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
### patch
|
|
32
32
|
|
|
33
|
-
Send a PATCH request.
|
|
33
|
+
Send a PATCH request. Returns the parsed response body directly (not an axios Response wrapper). On HTTP errors, returns the error as JSON instead of throwing.
|
|
34
34
|
|
|
35
35
|
**Parameters:**
|
|
36
36
|
|
|
@@ -46,7 +46,7 @@ Send a PATCH request.
|
|
|
46
46
|
|
|
47
47
|
### put
|
|
48
48
|
|
|
49
|
-
Send a PUT request.
|
|
49
|
+
Send a PUT request. Returns the parsed response body directly (not an axios Response wrapper). On HTTP errors, returns the error as JSON instead of throwing.
|
|
50
50
|
|
|
51
51
|
**Parameters:**
|
|
52
52
|
|
|
@@ -62,7 +62,7 @@ Send a PUT request.
|
|
|
62
62
|
|
|
63
63
|
### post
|
|
64
64
|
|
|
65
|
-
Send a POST request.
|
|
65
|
+
Send a POST request. Returns the parsed response body directly (not an axios Response wrapper). On HTTP errors, returns the error as JSON instead of throwing.
|
|
66
66
|
|
|
67
67
|
**Parameters:**
|
|
68
68
|
|
|
@@ -78,7 +78,7 @@ Send a POST request.
|
|
|
78
78
|
|
|
79
79
|
### delete
|
|
80
80
|
|
|
81
|
-
Send a DELETE request.
|
|
81
|
+
Send a DELETE request. Returns the parsed response body directly (not an axios Response wrapper). On HTTP errors, returns the error as JSON instead of throwing.
|
|
82
82
|
|
|
83
83
|
**Parameters:**
|
|
84
84
|
|
|
@@ -94,7 +94,7 @@ Send a DELETE request.
|
|
|
94
94
|
|
|
95
95
|
### get
|
|
96
96
|
|
|
97
|
-
Send a GET request.
|
|
97
|
+
Send a GET request. Returns the parsed response body directly (not an axios Response wrapper). On HTTP errors, returns the error as JSON instead of throwing.
|
|
98
98
|
|
|
99
99
|
**Parameters:**
|
|
100
100
|
|
|
@@ -118,7 +118,7 @@ Handle an axios error by emitting 'failure' and returning the error as JSON.
|
|
|
118
118
|
|------|------|----------|-------------|
|
|
119
119
|
| `error` | `AxiosError` | ✓ | Parameter error |
|
|
120
120
|
|
|
121
|
-
**Returns:** `
|
|
121
|
+
**Returns:** `Promise<object>`
|
|
122
122
|
|
|
123
123
|
|
|
124
124
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# WebSocketClient (clients.websocket)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
WebSocketClient helper
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
@@ -53,6 +53,26 @@ Send data over the WebSocket connection. Automatically JSON-serializes the paylo
|
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
|
|
56
|
+
### ask
|
|
57
|
+
|
|
58
|
+
Send a request and wait for a correlated response. The message is sent with a unique `requestId`; the remote side is expected to reply with a message containing `replyTo` set to that same ID.
|
|
59
|
+
|
|
60
|
+
**Parameters:**
|
|
61
|
+
|
|
62
|
+
| Name | Type | Required | Description |
|
|
63
|
+
|------|------|----------|-------------|
|
|
64
|
+
| `type` | `string` | ✓ | A string identifying the request type |
|
|
65
|
+
| `data` | `any` | | Optional payload to include with the request |
|
|
66
|
+
| `timeout` | `any` | | How long to wait for a response (default 10 000 ms) |
|
|
67
|
+
|
|
68
|
+
**Returns:** `Promise<R>`
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
const result = await ws.ask('getUser', { id: 42 })
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
56
76
|
### disconnect
|
|
57
77
|
|
|
58
78
|
Gracefully close the WebSocket connection. Suppresses auto-reconnect and updates connection state to disconnected.
|
|
@@ -146,16 +166,9 @@ Emitted when a request fails
|
|
|
146
166
|
|
|
147
167
|
## Examples
|
|
148
168
|
|
|
149
|
-
**
|
|
169
|
+
**ask**
|
|
150
170
|
|
|
151
171
|
```ts
|
|
152
|
-
const
|
|
153
|
-
baseURL: 'ws://localhost:8080',
|
|
154
|
-
reconnect: true,
|
|
155
|
-
maxReconnectAttempts: 5
|
|
156
|
-
})
|
|
157
|
-
ws.on('message', (data) => console.log('Received:', data))
|
|
158
|
-
await ws.connect()
|
|
159
|
-
await ws.send({ type: 'hello' })
|
|
172
|
+
const result = await ws.ask('getUser', { id: 42 })
|
|
160
173
|
```
|
|
161
174
|
|