@soederpop/luca 0.0.32 → 0.0.34
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 -5
- package/commands/build-python-bridge.ts +43 -0
- 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 -4
- 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 -17
- 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 -590
- package/src/introspection/generated.node.ts +1625 -688
- package/src/introspection/generated.web.ts +15 -57
- package/src/node/container.ts +5 -0
- 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
|
@@ -32,7 +32,7 @@ container.feature('ink', {
|
|
|
32
32
|
|
|
33
33
|
Pre-load ink + react modules so the sync getters work. Called automatically by render(), but you can call it early.
|
|
34
34
|
|
|
35
|
-
**Returns:** `
|
|
35
|
+
**Returns:** `Promise<this>`
|
|
36
36
|
|
|
37
37
|
```ts
|
|
38
38
|
const ink = container.feature('ink', { enable: true })
|
|
@@ -54,7 +54,7 @@ Mount a React element to the terminal. Wraps `ink.render()` — automatically lo
|
|
|
54
54
|
| `node` | `any` | ✓ | A React element (JSX or React.createElement) |
|
|
55
55
|
| `options` | `Record<string, any>` | | Ink render options (stdout, stdin, debug, etc.) |
|
|
56
56
|
|
|
57
|
-
**Returns:** `
|
|
57
|
+
**Returns:** `Promise<any>`
|
|
58
58
|
|
|
59
59
|
|
|
60
60
|
|
|
@@ -138,7 +138,7 @@ Register a named React function component as a renderable block.
|
|
|
138
138
|
| `name` | `string` | ✓ | Unique block name |
|
|
139
139
|
| `component` | `Function` | ✓ | A React function component |
|
|
140
140
|
|
|
141
|
-
**Returns:** `
|
|
141
|
+
**Returns:** `this`
|
|
142
142
|
|
|
143
143
|
```ts
|
|
144
144
|
ink.registerBlock('Greeting', ({ name }) =>
|
|
@@ -159,7 +159,7 @@ Render a registered block by name with optional props. Looks up the component, c
|
|
|
159
159
|
| `name` | `string` | ✓ | The registered block name |
|
|
160
160
|
| `data` | `Record<string, any>` | | Props to pass to the component |
|
|
161
161
|
|
|
162
|
-
**Returns:** `void
|
|
162
|
+
**Returns:** `Promise<void>`
|
|
163
163
|
|
|
164
164
|
```ts
|
|
165
165
|
await ink.renderBlock('Greeting', { name: 'Jon' })
|
|
@@ -179,7 +179,7 @@ Render a registered block that needs to stay mounted for async work. The compone
|
|
|
179
179
|
| `data` | `Record<string, any>` | | Props to pass to the component (a `done` prop is added automatically) |
|
|
180
180
|
| `options` | `{ timeout?: number }` | | `timeout` in ms before force-unmounting (default 30 000) |
|
|
181
181
|
|
|
182
|
-
**Returns:** `void
|
|
182
|
+
**Returns:** `Promise<void>`
|
|
183
183
|
|
|
184
184
|
```tsx
|
|
185
185
|
// In a ## Blocks section:
|
|
@@ -205,12 +205,12 @@ await renderAsync('AsyncChart', { url: 'https://api.example.com/data' })
|
|
|
205
205
|
|
|
206
206
|
| Property | Type | Description |
|
|
207
207
|
|----------|------|-------------|
|
|
208
|
-
| `React` | `
|
|
209
|
-
| `components` | `
|
|
210
|
-
| `hooks` | `
|
|
211
|
-
| `measureElement` | `
|
|
208
|
+
| `React` | `typeof import('react')` | The React module (createElement, useState, useEffect, etc.) Exposed so consumers don't need a separate react import. Lazy-loaded — first access triggers the import. |
|
|
209
|
+
| `components` | `{ Box: typeof import('ink').Box; Text: typeof import('ink').Text; Static: typeof import('ink').Static; Transform: typeof import('ink').Transform; Newline: typeof import('ink').Newline; Spacer: typeof import('ink').Spacer }` | All Ink components as a single object for destructuring. ```ts const { Box, Text, Static, Spacer } = ink.components ``` |
|
|
210
|
+
| `hooks` | `{ useInput: typeof import('ink').useInput; useApp: typeof import('ink').useApp; useStdin: typeof import('ink').useStdin; useStdout: typeof import('ink').useStdout; useStderr: typeof import('ink').useStderr; useFocus: typeof import('ink').useFocus; useFocusManager: typeof import('ink').useFocusManager; useCursor: typeof import('ink').useCursor }` | All Ink hooks as a single object for destructuring. ```ts const { useInput, useApp, useFocus } = ink.hooks ``` |
|
|
211
|
+
| `measureElement` | `typeof import('ink').measureElement` | The Ink measureElement utility. |
|
|
212
212
|
| `isMounted` | `boolean` | Whether an ink app is currently mounted. |
|
|
213
|
-
| `instance` | `any` | The raw ink render instance if you need low-level access. |
|
|
213
|
+
| `instance` | `any | null` | The raw ink render instance if you need low-level access. |
|
|
214
214
|
| `blocks` | `string[]` | List all registered block names. |
|
|
215
215
|
|
|
216
216
|
## Events (Zod v4 schema)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# IpcSocket (features.ipcSocket)
|
|
2
2
|
|
|
3
|
-
IpcSocket Feature - Inter-Process Communication via Unix Domain Sockets This feature provides robust IPC (Inter-Process Communication) capabilities using Unix domain sockets. It supports both server and client modes, allowing processes to communicate efficiently through file system-based socket connections. **Key Features:** -
|
|
3
|
+
IpcSocket Feature - Inter-Process Communication via Unix Domain Sockets This feature provides robust IPC (Inter-Process Communication) capabilities using Unix domain sockets. It supports both server and client modes, allowing processes to communicate efficiently through file system-based socket connections. **Key Features:** - Hub-and-spoke: one server, many named clients with identity tracking - Targeted messaging: sendTo(clientId), broadcast(msg, excludeId) - Request/reply: ask() + reply() with timeout-based correlation - Auto-reconnect: clients reconnect with exponential backoff - Stale socket detection: probeSocket() before listen() - Clean shutdown: stopServer() removes socket file **Server (Hub):** ```typescript const ipc = container.feature('ipcSocket'); await ipc.listen('/tmp/hub.sock', true); ipc.on('connection', (clientId, socket) => { console.log('Client joined:', clientId); }); ipc.on('message', (data, clientId) => { console.log(`From ${clientId}:`, data); // Reply to sender, or ask and wait ipc.sendTo(clientId, { ack: true }); }); ``` **Client (Spoke):** ```typescript const ipc = container.feature('ipcSocket'); await ipc.connect('/tmp/hub.sock', { reconnect: true, name: 'worker-1' }); // Fire and forget await ipc.send({ type: 'status', ready: true }); // Request/reply ipc.on('message', (data) => { if (data.requestId) ipc.reply(data.requestId, { result: 42 }); }); ```
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
@@ -64,81 +64,113 @@ try {
|
|
|
64
64
|
|
|
65
65
|
### broadcast
|
|
66
66
|
|
|
67
|
-
Broadcasts a message to all connected clients (server mode only).
|
|
67
|
+
Broadcasts a message to all connected clients (server mode only).
|
|
68
68
|
|
|
69
69
|
**Parameters:**
|
|
70
70
|
|
|
71
71
|
| Name | Type | Required | Description |
|
|
72
72
|
|------|------|----------|-------------|
|
|
73
|
-
| `message` | `any` | ✓ | The message object to broadcast
|
|
73
|
+
| `message` | `any` | ✓ | The message object to broadcast |
|
|
74
|
+
| `exclude` | `string` | | Optional client ID to exclude from broadcast |
|
|
74
75
|
|
|
75
|
-
**Returns:** `
|
|
76
|
+
**Returns:** `this`
|
|
76
77
|
|
|
77
|
-
```ts
|
|
78
|
-
// Broadcast to all connected clients
|
|
79
|
-
ipc.broadcast({
|
|
80
|
-
type: 'notification',
|
|
81
|
-
message: 'Server is shutting down in 30 seconds',
|
|
82
|
-
timestamp: Date.now()
|
|
83
|
-
});
|
|
84
78
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
79
|
+
|
|
80
|
+
### sendTo
|
|
81
|
+
|
|
82
|
+
Sends a message to a specific client by ID (server mode only).
|
|
83
|
+
|
|
84
|
+
**Parameters:**
|
|
85
|
+
|
|
86
|
+
| Name | Type | Required | Description |
|
|
87
|
+
|------|------|----------|-------------|
|
|
88
|
+
| `clientId` | `string` | ✓ | The target client ID |
|
|
89
|
+
| `message` | `any` | ✓ | The message to send |
|
|
90
|
+
|
|
91
|
+
**Returns:** `boolean`
|
|
89
92
|
|
|
90
93
|
|
|
91
94
|
|
|
92
95
|
### send
|
|
93
96
|
|
|
94
|
-
|
|
97
|
+
Fire-and-forget: sends a message to the server (client mode only). For server→client, use sendTo() or broadcast().
|
|
95
98
|
|
|
96
99
|
**Parameters:**
|
|
97
100
|
|
|
98
101
|
| Name | Type | Required | Description |
|
|
99
102
|
|------|------|----------|-------------|
|
|
100
|
-
| `message` | `any` | ✓ | The message
|
|
103
|
+
| `message` | `any` | ✓ | The message to send |
|
|
101
104
|
|
|
102
|
-
**Returns:** `void
|
|
105
|
+
**Returns:** `Promise<void>`
|
|
103
106
|
|
|
104
|
-
```ts
|
|
105
|
-
// Send a simple message
|
|
106
|
-
await ipc.send({ type: 'ping' });
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
108
|
+
|
|
109
|
+
### ask
|
|
110
|
+
|
|
111
|
+
Sends a message and waits for a correlated reply. Works in both client and server mode. The recipient should call `reply(requestId, response)` to respond.
|
|
112
|
+
|
|
113
|
+
**Parameters:**
|
|
114
|
+
|
|
115
|
+
| Name | Type | Required | Description |
|
|
116
|
+
|------|------|----------|-------------|
|
|
117
|
+
| `message` | `any` | ✓ | The message to send |
|
|
118
|
+
| `options` | `{ clientId?: string; timeoutMs?: number }` | | Optional: clientId (server mode target), timeoutMs |
|
|
119
|
+
|
|
120
|
+
**Returns:** `Promise<any>`
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
### reply
|
|
125
|
+
|
|
126
|
+
Sends a reply to a previous ask() call, correlated by requestId.
|
|
127
|
+
|
|
128
|
+
**Parameters:**
|
|
129
|
+
|
|
130
|
+
| Name | Type | Required | Description |
|
|
131
|
+
|------|------|----------|-------------|
|
|
132
|
+
| `requestId` | `string` | ✓ | The requestId from the incoming message |
|
|
133
|
+
| `data` | `any` | ✓ | The reply payload |
|
|
134
|
+
| `clientId` | `string` | | Target client (server mode; for client mode, omit) |
|
|
135
|
+
|
|
136
|
+
**Returns:** `void`
|
|
114
137
|
|
|
115
138
|
|
|
116
139
|
|
|
117
140
|
### connect
|
|
118
141
|
|
|
119
|
-
Connects to an IPC server at the specified socket path (client mode).
|
|
142
|
+
Connects to an IPC server at the specified socket path (client mode).
|
|
120
143
|
|
|
121
144
|
**Parameters:**
|
|
122
145
|
|
|
123
146
|
| Name | Type | Required | Description |
|
|
124
147
|
|------|------|----------|-------------|
|
|
125
|
-
| `socketPath` | `string` | ✓ |
|
|
148
|
+
| `socketPath` | `string` | ✓ | Path to the server's Unix domain socket |
|
|
149
|
+
| `options` | `{ reconnect?: boolean; name?: string }` | | Optional: reconnect (enable auto-reconnect), name (identify this client) |
|
|
126
150
|
|
|
127
151
|
**Returns:** `Promise<Socket>`
|
|
128
152
|
|
|
129
|
-
```ts
|
|
130
|
-
// Connect to server
|
|
131
|
-
const socket = await ipc.connect('/tmp/myapp.sock');
|
|
132
|
-
console.log('Connected to IPC server');
|
|
133
153
|
|
|
134
|
-
// Handle incoming messages
|
|
135
|
-
ipc.on('message', (data) => {
|
|
136
|
-
console.log('Server message:', data);
|
|
137
|
-
});
|
|
138
154
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
155
|
+
### disconnect
|
|
156
|
+
|
|
157
|
+
Disconnects the client and stops any reconnection attempts.
|
|
158
|
+
|
|
159
|
+
**Returns:** `void`
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
### probeSocket
|
|
164
|
+
|
|
165
|
+
Probe an existing socket to see if a live listener is behind it. Attempts a quick connect — if it succeeds, someone is listening.
|
|
166
|
+
|
|
167
|
+
**Parameters:**
|
|
168
|
+
|
|
169
|
+
| Name | Type | Required | Description |
|
|
170
|
+
|------|------|----------|-------------|
|
|
171
|
+
| `socketPath` | `string` | ✓ | Parameter socketPath |
|
|
172
|
+
|
|
173
|
+
**Returns:** `Promise<boolean>`
|
|
142
174
|
|
|
143
175
|
|
|
144
176
|
|
|
@@ -146,12 +178,20 @@ await ipc.send({ type: 'hello', client_id: 'client_001' });
|
|
|
146
178
|
|
|
147
179
|
| Property | Type | Description |
|
|
148
180
|
|----------|------|-------------|
|
|
149
|
-
| `isClient` | `
|
|
150
|
-
| `isServer` | `
|
|
151
|
-
| `
|
|
181
|
+
| `isClient` | `boolean` | Checks if the IPC socket is operating in client mode. |
|
|
182
|
+
| `isServer` | `boolean` | Checks if the IPC socket is operating in server mode. |
|
|
183
|
+
| `clientCount` | `number` | Returns the number of currently connected clients (server mode). |
|
|
184
|
+
| `connectedClients` | `Array<{ id: string; name?: string; connectedAt: number }>` | Returns info about all connected clients (server mode). |
|
|
185
|
+
| `connection` | `Socket | undefined` | Gets the current client connection socket. |
|
|
152
186
|
|
|
153
187
|
## Events (Zod v4 schema)
|
|
154
188
|
|
|
189
|
+
### disconnection
|
|
190
|
+
|
|
191
|
+
Event emitted by IpcSocket
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
155
195
|
### connection
|
|
156
196
|
|
|
157
197
|
Event emitted by IpcSocket
|
|
@@ -207,53 +247,3 @@ try {
|
|
|
207
247
|
}
|
|
208
248
|
```
|
|
209
249
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
**broadcast**
|
|
213
|
-
|
|
214
|
-
```ts
|
|
215
|
-
// Broadcast to all connected clients
|
|
216
|
-
ipc.broadcast({
|
|
217
|
-
type: 'notification',
|
|
218
|
-
message: 'Server is shutting down in 30 seconds',
|
|
219
|
-
timestamp: Date.now()
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
// Chain multiple operations
|
|
223
|
-
ipc.broadcast({ status: 'ready' })
|
|
224
|
-
.broadcast({ time: new Date().toISOString() });
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
**send**
|
|
230
|
-
|
|
231
|
-
```ts
|
|
232
|
-
// Send a simple message
|
|
233
|
-
await ipc.send({ type: 'ping' });
|
|
234
|
-
|
|
235
|
-
// Send complex data
|
|
236
|
-
await ipc.send({
|
|
237
|
-
type: 'data_update',
|
|
238
|
-
payload: { users: [...], timestamp: Date.now() }
|
|
239
|
-
});
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
**connect**
|
|
245
|
-
|
|
246
|
-
```ts
|
|
247
|
-
// Connect to server
|
|
248
|
-
const socket = await ipc.connect('/tmp/myapp.sock');
|
|
249
|
-
console.log('Connected to IPC server');
|
|
250
|
-
|
|
251
|
-
// Handle incoming messages
|
|
252
|
-
ipc.on('message', (data) => {
|
|
253
|
-
console.log('Server message:', data);
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
// Send messages
|
|
257
|
-
await ipc.send({ type: 'hello', client_id: 'client_001' });
|
|
258
|
-
```
|
|
259
|
-
|
|
@@ -32,7 +32,7 @@ Finds the next available port starting from the specified port number. This meth
|
|
|
32
32
|
|------|------|----------|-------------|
|
|
33
33
|
| `startAt` | `any` | | The port number to start searching from (0 means system will choose) |
|
|
34
34
|
|
|
35
|
-
**Returns:** `
|
|
35
|
+
**Returns:** `Promise<number>`
|
|
36
36
|
|
|
37
37
|
```ts
|
|
38
38
|
// Find any available port
|
|
@@ -55,7 +55,7 @@ Checks if a specific port is available for use. This method attempts to detect i
|
|
|
55
55
|
|------|------|----------|-------------|
|
|
56
56
|
| `checkPort` | `any` | | The port number to check for availability |
|
|
57
57
|
|
|
58
|
-
**Returns:** `
|
|
58
|
+
**Returns:** `Promise<boolean>`
|
|
59
59
|
|
|
60
60
|
```ts
|
|
61
61
|
// Check if port 8080 is available
|
|
@@ -197,9 +197,9 @@ Convenience method: discover and port-scan hosts across all local networks.
|
|
|
197
197
|
|
|
198
198
|
| Property | Type | Description |
|
|
199
199
|
|----------|------|-------------|
|
|
200
|
-
| `proc` | `
|
|
201
|
-
| `os` | `
|
|
202
|
-
| `nmap` | `
|
|
200
|
+
| `proc` | `ReturnType<typeof this.container.feature<'proc'>>` | |
|
|
201
|
+
| `os` | `ReturnType<typeof this.container.feature<'os'>>` | |
|
|
202
|
+
| `nmap` | `{ isAvailable: () => Promise<boolean>; scan: (target: string, args?: string[]) => Promise<{ hosts: NmapHost[]; raw: string }>; quickScan: (cidr: string) => Promise<{ hosts: NmapHost[]; raw: string }>; fullScan: (target: string) => Promise<{ hosts: NmapHost[]; raw: string }> }` | Optional nmap wrapper for users that already have nmap installed. |
|
|
203
203
|
|
|
204
204
|
## Events (Zod v4 schema)
|
|
205
205
|
|
|
@@ -29,13 +29,13 @@ displays.forEach(d => {
|
|
|
29
29
|
|
|
30
30
|
| Property | Type | Description |
|
|
31
31
|
|----------|------|-------------|
|
|
32
|
-
| `arch` | `
|
|
33
|
-
| `tmpdir` | `
|
|
34
|
-
| `homedir` | `
|
|
35
|
-
| `cpuCount` | `
|
|
36
|
-
| `hostname` | `
|
|
37
|
-
| `platform` | `
|
|
38
|
-
| `networkInterfaces` | `
|
|
32
|
+
| `arch` | `string` | Gets the operating system CPU architecture. |
|
|
33
|
+
| `tmpdir` | `string` | Gets the operating system's default directory for temporary files. |
|
|
34
|
+
| `homedir` | `string` | Gets the current user's home directory path. |
|
|
35
|
+
| `cpuCount` | `number` | Gets the number of logical CPU cores available on the system. |
|
|
36
|
+
| `hostname` | `string` | Gets the hostname of the operating system. |
|
|
37
|
+
| `platform` | `string` | Gets the operating system platform. |
|
|
38
|
+
| `networkInterfaces` | `NodeJS.Dict<os.NetworkInterfaceInfo[]>` | Gets information about the system's network interfaces. |
|
|
39
39
|
| `macAddresses` | `string[]` | Gets an array of MAC addresses for non-internal IPv4 network interfaces. This filters the network interfaces to only include external IPv4 interfaces and returns their MAC addresses, which can be useful for system identification. |
|
|
40
40
|
|
|
41
41
|
## State (Zod v4 schema)
|
|
@@ -57,7 +57,7 @@ finder.addPackage({
|
|
|
57
57
|
|
|
58
58
|
Starts the package finder and performs the initial workspace scan. This method is idempotent - calling it multiple times will not re-scan if already started. It triggers the complete workspace scanning process.
|
|
59
59
|
|
|
60
|
-
**Returns:** `
|
|
60
|
+
**Returns:** `Promise<this | undefined>`
|
|
61
61
|
|
|
62
62
|
```ts
|
|
63
63
|
await finder.start();
|
|
@@ -82,7 +82,7 @@ Performs a comprehensive scan of all node_modules directories in the workspace.
|
|
|
82
82
|
|----------|------|-------------|
|
|
83
83
|
| `exclude` | `any` | Optional exclusion patterns (not implemented) |
|
|
84
84
|
|
|
85
|
-
**Returns:** `
|
|
85
|
+
**Returns:** `Promise<this>`
|
|
86
86
|
|
|
87
87
|
```ts
|
|
88
88
|
// Manual scan (usually called automatically by start())
|
|
@@ -104,7 +104,7 @@ Finds the first package manifest matching the given name. If multiple versions o
|
|
|
104
104
|
|------|------|----------|-------------|
|
|
105
105
|
| `name` | `string` | ✓ | The exact package name to search for |
|
|
106
106
|
|
|
107
|
-
**Returns:** `
|
|
107
|
+
**Returns:** `PartialManifest | undefined`
|
|
108
108
|
|
|
109
109
|
```ts
|
|
110
110
|
const lodash = finder.findByName('lodash');
|
|
@@ -125,7 +125,7 @@ Finds all packages that declare the specified package as a dependency. Searches
|
|
|
125
125
|
|------|------|----------|-------------|
|
|
126
126
|
| `packageName` | `string` | ✓ | The name of the package to find dependents for |
|
|
127
127
|
|
|
128
|
-
**Returns:** `
|
|
128
|
+
**Returns:** `PartialManifest[]`
|
|
129
129
|
|
|
130
130
|
```ts
|
|
131
131
|
const reactDependents = finder.findDependentsOf('react');
|
|
@@ -147,7 +147,7 @@ Finds the first package manifest matching the provided filter function.
|
|
|
147
147
|
|------|------|----------|-------------|
|
|
148
148
|
| `filter` | `(manifest: PartialManifest) => boolean` | ✓ | Function that returns true for matching packages |
|
|
149
149
|
|
|
150
|
-
**Returns:** `
|
|
150
|
+
**Returns:** `PartialManifest | undefined`
|
|
151
151
|
|
|
152
152
|
```ts
|
|
153
153
|
// Find a package with specific version
|
|
@@ -169,7 +169,7 @@ Finds all package manifests matching the provided filter function.
|
|
|
169
169
|
|------|------|----------|-------------|
|
|
170
170
|
| `filter` | `(manifest: PartialManifest) => boolean` | ✓ | Function that returns true for matching packages |
|
|
171
171
|
|
|
172
|
-
**Returns:** `
|
|
172
|
+
**Returns:** `PartialManifest[]`
|
|
173
173
|
|
|
174
174
|
```ts
|
|
175
175
|
// Find all packages with 'babel' in the name
|
|
@@ -194,7 +194,7 @@ Returns all packages that do NOT match the provided filter function. This is the
|
|
|
194
194
|
|------|------|----------|-------------|
|
|
195
195
|
| `filter` | `(manifest: PartialManifest) => boolean` | ✓ | Function that returns true for packages to exclude |
|
|
196
196
|
|
|
197
|
-
**Returns:** `
|
|
197
|
+
**Returns:** `PartialManifest[]`
|
|
198
198
|
|
|
199
199
|
```ts
|
|
200
200
|
// Get all non-development packages (those not in devDependencies)
|
|
@@ -208,7 +208,7 @@ const unscoped = finder.exclude(pkg => pkg.name.startsWith('@'));
|
|
|
208
208
|
|
|
209
209
|
### findLocalPackageFolders
|
|
210
210
|
|
|
211
|
-
**Returns:** `
|
|
211
|
+
**Returns:** `Promise<string[]>`
|
|
212
212
|
|
|
213
213
|
|
|
214
214
|
|
|
@@ -216,12 +216,12 @@ const unscoped = finder.exclude(pkg => pkg.name.startsWith('@'));
|
|
|
216
216
|
|
|
217
217
|
| Property | Type | Description |
|
|
218
218
|
|----------|------|-------------|
|
|
219
|
-
| `duplicates` | `
|
|
220
|
-
| `isStarted` | `
|
|
221
|
-
| `packageNames` | `
|
|
222
|
-
| `scopes` | `
|
|
223
|
-
| `manifests` | `
|
|
224
|
-
| `counts` | `
|
|
219
|
+
| `duplicates` | `string[]` | Gets a list of package names that have multiple versions/instances installed. This is useful for identifying potential dependency conflicts or opportunities for deduplication in the project. |
|
|
220
|
+
| `isStarted` | `boolean` | Checks if the package finder has completed its initial scan. |
|
|
221
|
+
| `packageNames` | `string[]` | Gets an array of all unique package names discovered in the workspace. |
|
|
222
|
+
| `scopes` | `string[]` | Gets an array of all scoped package prefixes found in the workspace. Scoped packages are those starting with '@' (e.g., @types/node, @babel/core). This returns just the scope part (e.g., '@types', '@babel'). |
|
|
223
|
+
| `manifests` | `(PartialManifest & { __path: string })[]` | Gets a flat array of all package manifests found in the workspace. This includes all versions/instances of packages, unlike packageNames which returns unique names only. |
|
|
224
|
+
| `counts` | `Record<string, number>` | Gets a count of instances for each package name. Useful for quickly identifying which packages have multiple versions and how many instances of each exist. |
|
|
225
225
|
|
|
226
226
|
## State (Zod v4 schema)
|
|
227
227
|
|
|
@@ -70,6 +70,7 @@ Spawns a process and captures its output with real-time monitoring capabilities.
|
|
|
70
70
|
| `onError` | `(data: string) => void` | Callback invoked when stderr data is received |
|
|
71
71
|
| `onOutput` | `(data: string) => void` | Callback invoked when stdout data is received |
|
|
72
72
|
| `onExit` | `(code: number) => void` | Callback invoked when the process exits |
|
|
73
|
+
| `onStart` | `(childProcess: ChildProcess) => void` | Callback invoked when the process starts |
|
|
73
74
|
|
|
74
75
|
**Returns:** `Promise<{
|
|
75
76
|
stderr: string;
|
|
@@ -126,7 +127,7 @@ Spawn a raw child process and return the handle immediately. Useful when callers
|
|
|
126
127
|
| `stdout` | `"pipe" | "inherit" | "ignore"` | Stdout mode for the child process |
|
|
127
128
|
| `stderr` | `"pipe" | "inherit" | "ignore"` | Stderr mode for the child process |
|
|
128
129
|
|
|
129
|
-
**Returns:** `
|
|
130
|
+
**Returns:** `import('child_process').ChildProcess`
|
|
130
131
|
|
|
131
132
|
|
|
132
133
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ProcessManager (features.processManager)
|
|
2
2
|
|
|
3
|
-
Manages long-running child processes with tracking, events, and automatic cleanup. Unlike the `proc` feature whose spawn methods block until the child exits, ProcessManager returns a SpawnHandler immediately — a handle object with its own state, events, and lifecycle methods. The feature tracks all spawned processes, maintains observable state, and can automatically kill them on parent exit.
|
|
3
|
+
Manages long-running child processes with tracking, events, and automatic cleanup. Unlike the `proc` feature whose spawn methods block until the child exits, ProcessManager returns a SpawnHandler immediately — a handle object with its own state, events, and lifecycle methods. The feature tracks all spawned processes, maintains observable state, and can automatically kill them on parent exit. Each handler maintains a memory-efficient output buffer: the first 20 lines (head) and last 50 lines (tail) of stdout/stderr are kept, everything in between is discarded.
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
@@ -19,6 +19,70 @@ container.feature('processManager', {
|
|
|
19
19
|
|
|
20
20
|
## Methods
|
|
21
21
|
|
|
22
|
+
### spawnProcess
|
|
23
|
+
|
|
24
|
+
Tool handler: spawn a long-running background process.
|
|
25
|
+
|
|
26
|
+
**Parameters:**
|
|
27
|
+
|
|
28
|
+
| Name | Type | Required | Description |
|
|
29
|
+
|------|------|----------|-------------|
|
|
30
|
+
| `args` | `{ command: string; args?: string; tag?: string; cwd?: string }` | ✓ | Parameter args |
|
|
31
|
+
|
|
32
|
+
**Returns:** `void`
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### runCommand
|
|
37
|
+
|
|
38
|
+
Tool handler: run a command to completion and return its output.
|
|
39
|
+
|
|
40
|
+
**Parameters:**
|
|
41
|
+
|
|
42
|
+
| Name | Type | Required | Description |
|
|
43
|
+
|------|------|----------|-------------|
|
|
44
|
+
| `args` | `{ command: string; cwd?: string }` | ✓ | Parameter args |
|
|
45
|
+
|
|
46
|
+
**Returns:** `void`
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### listProcesses
|
|
51
|
+
|
|
52
|
+
Tool handler: list all tracked processes.
|
|
53
|
+
|
|
54
|
+
**Returns:** `void`
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
### getProcessOutput
|
|
59
|
+
|
|
60
|
+
Tool handler: peek at a process's buffered output.
|
|
61
|
+
|
|
62
|
+
**Parameters:**
|
|
63
|
+
|
|
64
|
+
| Name | Type | Required | Description |
|
|
65
|
+
|------|------|----------|-------------|
|
|
66
|
+
| `args` | `{ id?: string; tag?: string; stream?: string }` | ✓ | Parameter args |
|
|
67
|
+
|
|
68
|
+
**Returns:** `void`
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
### killProcess
|
|
73
|
+
|
|
74
|
+
Tool handler: kill a process by ID or tag.
|
|
75
|
+
|
|
76
|
+
**Parameters:**
|
|
77
|
+
|
|
78
|
+
| Name | Type | Required | Description |
|
|
79
|
+
|------|------|----------|-------------|
|
|
80
|
+
| `args` | `{ id?: string; tag?: string; signal?: string }` | ✓ | Parameter args |
|
|
81
|
+
|
|
82
|
+
**Returns:** `void`
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
22
86
|
### spawn
|
|
23
87
|
|
|
24
88
|
Spawn a long-running process and return a handle immediately. The returned SpawnHandler provides events for stdout/stderr streaming, exit/crash notifications, and methods to kill or await the process.
|
|
@@ -157,7 +221,7 @@ Emitted when a new process is spawned
|
|
|
157
221
|
| Name | Type | Description |
|
|
158
222
|
|------|------|-------------|
|
|
159
223
|
| `arg0` | `string` | process ID |
|
|
160
|
-
| `arg1` | `
|
|
224
|
+
| `arg1` | `string` | process metadata |
|
|
161
225
|
|
|
162
226
|
|
|
163
227
|
|
|
@@ -184,7 +248,7 @@ Emitted when a process exits with non-zero code
|
|
|
184
248
|
|------|------|-------------|
|
|
185
249
|
| `arg0` | `string` | process ID |
|
|
186
250
|
| `arg1` | `number` | exit code |
|
|
187
|
-
| `arg2` | `
|
|
251
|
+
| `arg2` | `string` | error info |
|
|
188
252
|
|
|
189
253
|
|
|
190
254
|
|
|
@@ -225,6 +289,9 @@ const server = pm.spawn('node', ['server.js'], { tag: 'api', cwd: '/app' })
|
|
|
225
289
|
server.on('stdout', (data) => console.log('[api]', data))
|
|
226
290
|
server.on('crash', (code) => console.error('API crashed:', code))
|
|
227
291
|
|
|
292
|
+
// Peek at buffered output
|
|
293
|
+
const { head, tail } = server.peek()
|
|
294
|
+
|
|
228
295
|
// Kill one
|
|
229
296
|
server.kill()
|
|
230
297
|
|