@soederpop/luca 0.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/CLAUDE.md +71 -0
- package/README.md +78 -0
- package/bun.lock +2928 -0
- package/bunfig.toml +3 -0
- package/commands/audit-docs.ts +740 -0
- package/commands/build-scaffolds.ts +154 -0
- package/commands/generate-api-docs.ts +114 -0
- package/commands/update-introspection.ts +67 -0
- package/docs/CLI.md +335 -0
- package/docs/README.md +88 -0
- package/docs/TABLE-OF-CONTENTS.md +157 -0
- package/docs/apis/clients/elevenlabs.md +84 -0
- package/docs/apis/clients/graph.md +56 -0
- package/docs/apis/clients/openai.md +69 -0
- package/docs/apis/clients/rest.md +41 -0
- package/docs/apis/clients/websocket.md +107 -0
- package/docs/apis/features/agi/assistant.md +471 -0
- package/docs/apis/features/agi/assistants-manager.md +154 -0
- package/docs/apis/features/agi/claude-code.md +602 -0
- package/docs/apis/features/agi/conversation-history.md +352 -0
- package/docs/apis/features/agi/conversation.md +333 -0
- package/docs/apis/features/agi/docs-reader.md +121 -0
- package/docs/apis/features/agi/openai-codex.md +318 -0
- package/docs/apis/features/agi/openapi.md +138 -0
- package/docs/apis/features/agi/semantic-search.md +387 -0
- package/docs/apis/features/agi/skills-library.md +216 -0
- package/docs/apis/features/node/container-link.md +133 -0
- package/docs/apis/features/node/content-db.md +313 -0
- package/docs/apis/features/node/disk-cache.md +379 -0
- package/docs/apis/features/node/dns.md +651 -0
- package/docs/apis/features/node/docker.md +705 -0
- package/docs/apis/features/node/downloader.md +81 -0
- package/docs/apis/features/node/esbuild.md +59 -0
- package/docs/apis/features/node/file-manager.md +182 -0
- package/docs/apis/features/node/fs.md +581 -0
- package/docs/apis/features/node/git.md +330 -0
- package/docs/apis/features/node/google-auth.md +174 -0
- package/docs/apis/features/node/google-calendar.md +187 -0
- package/docs/apis/features/node/google-docs.md +151 -0
- package/docs/apis/features/node/google-drive.md +225 -0
- package/docs/apis/features/node/google-sheets.md +179 -0
- package/docs/apis/features/node/grep.md +290 -0
- package/docs/apis/features/node/helpers.md +135 -0
- package/docs/apis/features/node/ink.md +334 -0
- package/docs/apis/features/node/ipc-socket.md +260 -0
- package/docs/apis/features/node/json-tree.md +86 -0
- package/docs/apis/features/node/launcher-app-command-listener.md +145 -0
- package/docs/apis/features/node/networking.md +281 -0
- package/docs/apis/features/node/nlp.md +133 -0
- package/docs/apis/features/node/opener.md +97 -0
- package/docs/apis/features/node/os.md +118 -0
- package/docs/apis/features/node/package-finder.md +402 -0
- package/docs/apis/features/node/postgres.md +212 -0
- package/docs/apis/features/node/proc.md +430 -0
- package/docs/apis/features/node/process-manager.md +210 -0
- package/docs/apis/features/node/python.md +278 -0
- package/docs/apis/features/node/repl.md +88 -0
- package/docs/apis/features/node/runpod.md +673 -0
- package/docs/apis/features/node/secure-shell.md +169 -0
- package/docs/apis/features/node/semantic-search.md +401 -0
- package/docs/apis/features/node/sqlite.md +211 -0
- package/docs/apis/features/node/telegram.md +254 -0
- package/docs/apis/features/node/tts.md +118 -0
- package/docs/apis/features/node/ui.md +703 -0
- package/docs/apis/features/node/vault.md +64 -0
- package/docs/apis/features/node/vm.md +84 -0
- package/docs/apis/features/node/window-manager.md +337 -0
- package/docs/apis/features/node/yaml-tree.md +85 -0
- package/docs/apis/features/node/yaml.md +176 -0
- package/docs/apis/features/web/asset-loader.md +47 -0
- package/docs/apis/features/web/container-link.md +133 -0
- package/docs/apis/features/web/esbuild.md +59 -0
- package/docs/apis/features/web/helpers.md +135 -0
- package/docs/apis/features/web/network.md +30 -0
- package/docs/apis/features/web/speech.md +55 -0
- package/docs/apis/features/web/vault.md +64 -0
- package/docs/apis/features/web/vm.md +84 -0
- package/docs/apis/features/web/voice.md +67 -0
- package/docs/apis/servers/express.md +127 -0
- package/docs/apis/servers/mcp.md +213 -0
- package/docs/apis/servers/websocket.md +99 -0
- package/docs/documentation-audit.md +134 -0
- package/docs/examples/content-db.md +77 -0
- package/docs/examples/disk-cache.md +83 -0
- package/docs/examples/docker.md +101 -0
- package/docs/examples/downloader.md +70 -0
- package/docs/examples/esbuild.md +80 -0
- package/docs/examples/file-manager.md +82 -0
- package/docs/examples/fs.md +83 -0
- package/docs/examples/git.md +85 -0
- package/docs/examples/google-auth.md +88 -0
- package/docs/examples/google-calendar.md +94 -0
- package/docs/examples/google-docs.md +82 -0
- package/docs/examples/google-drive.md +96 -0
- package/docs/examples/google-sheets.md +95 -0
- package/docs/examples/grep.md +85 -0
- package/docs/examples/ink-blocks.md +75 -0
- package/docs/examples/ink-renderer.md +41 -0
- package/docs/examples/ink.md +103 -0
- package/docs/examples/ipc-socket.md +103 -0
- package/docs/examples/json-tree.md +91 -0
- package/docs/examples/launcher-app-command-listener.md +120 -0
- package/docs/examples/networking.md +58 -0
- package/docs/examples/nlp.md +91 -0
- package/docs/examples/opener.md +78 -0
- package/docs/examples/os.md +72 -0
- package/docs/examples/package-finder.md +89 -0
- package/docs/examples/port-exposer.md +89 -0
- package/docs/examples/postgres.md +91 -0
- package/docs/examples/proc.md +81 -0
- package/docs/examples/process-manager.md +79 -0
- package/docs/examples/python.md +91 -0
- package/docs/examples/repl.md +93 -0
- package/docs/examples/runpod.md +119 -0
- package/docs/examples/secure-shell.md +92 -0
- package/docs/examples/sqlite.md +86 -0
- package/docs/examples/telegram.md +77 -0
- package/docs/examples/tts.md +86 -0
- package/docs/examples/ui.md +80 -0
- package/docs/examples/vault.md +70 -0
- package/docs/examples/vm.md +86 -0
- package/docs/examples/window-manager.md +125 -0
- package/docs/examples/yaml-tree.md +93 -0
- package/docs/examples/yaml.md +104 -0
- package/docs/ideas/class-registration-refactor-possibilities.md +197 -0
- package/docs/ideas/container-use-api.md +9 -0
- package/docs/ideas/easy-auth-for-express-servers-and-luca-serve.md +0 -0
- package/docs/ideas/feature-stacks.md +22 -0
- package/docs/ideas/luca-cli-self-sufficiency-demo.md +23 -0
- package/docs/ideas/mcp-design.md +9 -0
- package/docs/ideas/web-container-debugging-feature.md +13 -0
- package/docs/introspection-audit.md +49 -0
- package/docs/introspection.md +154 -0
- package/docs/mcp/readme.md +162 -0
- package/docs/models.ts +38 -0
- package/docs/philosophy.md +85 -0
- package/docs/principles.md +7 -0
- package/docs/prompts/audit-codebase-for-failures-to-use-the-container.md +34 -0
- package/docs/prompts/mcp-test-easy-command.md +27 -0
- package/docs/reports/assistant-bugs.md +38 -0
- package/docs/reports/attach-pattern-usage.md +18 -0
- package/docs/reports/code-audit-results.md +391 -0
- package/docs/reports/introspection-audit-tasks.md +378 -0
- package/docs/reports/luca-mcp-improvements.md +128 -0
- package/docs/scaffolds/client.md +140 -0
- package/docs/scaffolds/command.md +106 -0
- package/docs/scaffolds/endpoint.md +176 -0
- package/docs/scaffolds/feature.md +148 -0
- package/docs/scaffolds/server.md +187 -0
- package/docs/tasks/web-container-helper-discovery.md +71 -0
- package/docs/todos.md +1 -0
- package/docs/tutorials/01-getting-started.md +106 -0
- package/docs/tutorials/02-container.md +210 -0
- package/docs/tutorials/03-scripts.md +194 -0
- package/docs/tutorials/04-features-overview.md +196 -0
- package/docs/tutorials/05-state-and-events.md +171 -0
- package/docs/tutorials/06-servers.md +157 -0
- package/docs/tutorials/07-endpoints.md +198 -0
- package/docs/tutorials/08-commands.md +171 -0
- package/docs/tutorials/09-clients.md +162 -0
- package/docs/tutorials/10-creating-features.md +198 -0
- package/docs/tutorials/11-contentbase.md +191 -0
- package/docs/tutorials/12-assistants.md +215 -0
- package/docs/tutorials/13-introspection.md +147 -0
- package/docs/tutorials/14-type-system.md +174 -0
- package/docs/tutorials/15-project-patterns.md +222 -0
- package/docs/tutorials/16-google-features.md +534 -0
- package/docs/tutorials/17-tui-blocks.md +530 -0
- package/docs/tutorials/18-semantic-search.md +334 -0
- package/index.ts +1 -0
- package/luca.console.ts +9 -0
- package/main.py +6 -0
- package/package.json +154 -0
- package/pyproject.toml +7 -0
- package/scripts/animations/chrome-glitch.ts +55 -0
- package/scripts/animations/index.ts +16 -0
- package/scripts/animations/neon-pulse.ts +64 -0
- package/scripts/animations/types.ts +6 -0
- package/scripts/build-web.ts +28 -0
- package/scripts/examples/ask-luca-expert.ts +42 -0
- package/scripts/examples/assistant-questions.ts +12 -0
- package/scripts/examples/excalidraw-expert.ts +75 -0
- package/scripts/examples/expert-chat.ts +0 -0
- package/scripts/examples/file-manager.ts +14 -0
- package/scripts/examples/ideas.ts +12 -0
- package/scripts/examples/interactive-chat.ts +20 -0
- package/scripts/examples/openai-tool-calls.ts +113 -0
- package/scripts/examples/opening-a-web-browser.ts +5 -0
- package/scripts/examples/telegram-bot.ts +79 -0
- package/scripts/examples/telegram-ink-ui.ts +302 -0
- package/scripts/examples/using-assistant-with-mcp.ts +560 -0
- package/scripts/examples/using-claude-code.ts +10 -0
- package/scripts/examples/using-contentdb.ts +35 -0
- package/scripts/examples/using-conversations.ts +35 -0
- package/scripts/examples/using-disk-cache.ts +10 -0
- package/scripts/examples/using-docker-shell.ts +75 -0
- package/scripts/examples/using-elevenlabs.ts +25 -0
- package/scripts/examples/using-google-calendar.ts +57 -0
- package/scripts/examples/using-google-docs.ts +74 -0
- package/scripts/examples/using-google-drive.ts +74 -0
- package/scripts/examples/using-google-sheets.ts +89 -0
- package/scripts/examples/using-nlp.ts +55 -0
- package/scripts/examples/using-ollama.ts +10 -0
- package/scripts/examples/using-openai-codex.ts +23 -0
- package/scripts/examples/using-postgres.ts +55 -0
- package/scripts/examples/using-runpod.ts +32 -0
- package/scripts/examples/using-tts.ts +40 -0
- package/scripts/examples/vm-loading-esm-modules.ts +16 -0
- package/scripts/scaffold.ts +391 -0
- package/scripts/scratch.ts +15 -0
- package/scripts/test-command-listener.ts +123 -0
- package/scripts/test-window-manager-lifecycle.ts +86 -0
- package/scripts/test-window-manager.ts +43 -0
- package/scripts/update-introspection-data.ts +58 -0
- package/src/agi/README.md +14 -0
- package/src/agi/container.server.ts +114 -0
- package/src/agi/endpoints/ask.ts +60 -0
- package/src/agi/endpoints/conversations/[id].ts +45 -0
- package/src/agi/endpoints/conversations.ts +31 -0
- package/src/agi/endpoints/experts.ts +37 -0
- package/src/agi/features/assistant.ts +767 -0
- package/src/agi/features/assistants-manager.ts +260 -0
- package/src/agi/features/claude-code.ts +1111 -0
- package/src/agi/features/conversation-history.ts +497 -0
- package/src/agi/features/conversation.ts +799 -0
- package/src/agi/features/openai-codex.ts +631 -0
- package/src/agi/features/openapi.ts +438 -0
- package/src/agi/features/skills-library.ts +425 -0
- package/src/agi/index.ts +6 -0
- package/src/agi/lib/token-counter.ts +122 -0
- package/src/browser.ts +25 -0
- package/src/bus.ts +100 -0
- package/src/cli/cli.ts +70 -0
- package/src/client.ts +461 -0
- package/src/clients/civitai/index.ts +541 -0
- package/src/clients/client-template.ts +41 -0
- package/src/clients/comfyui/index.ts +597 -0
- package/src/clients/elevenlabs/index.ts +291 -0
- package/src/clients/openai/index.ts +451 -0
- package/src/clients/supabase/index.ts +366 -0
- package/src/command.ts +164 -0
- package/src/commands/chat.ts +182 -0
- package/src/commands/console.ts +192 -0
- package/src/commands/describe.ts +433 -0
- package/src/commands/eval.ts +116 -0
- package/src/commands/help.ts +214 -0
- package/src/commands/index.ts +14 -0
- package/src/commands/mcp.ts +64 -0
- package/src/commands/prompt.ts +807 -0
- package/src/commands/run.ts +257 -0
- package/src/commands/sandbox-mcp.ts +439 -0
- package/src/commands/scaffold.ts +79 -0
- package/src/commands/serve.ts +172 -0
- package/src/container.ts +781 -0
- package/src/endpoint.ts +340 -0
- package/src/feature.ts +75 -0
- package/src/hash-object.ts +97 -0
- package/src/helper.ts +543 -0
- package/src/introspection/generated.agi.ts +23388 -0
- package/src/introspection/generated.node.ts +18899 -0
- package/src/introspection/generated.web.ts +2021 -0
- package/src/introspection/index.ts +256 -0
- package/src/introspection/scan.ts +912 -0
- package/src/node/container.ts +354 -0
- package/src/node/feature.ts +13 -0
- package/src/node/features/container-link.ts +558 -0
- package/src/node/features/content-db.ts +475 -0
- package/src/node/features/disk-cache.ts +382 -0
- package/src/node/features/dns.ts +655 -0
- package/src/node/features/docker.ts +912 -0
- package/src/node/features/downloader.ts +92 -0
- package/src/node/features/esbuild.ts +68 -0
- package/src/node/features/file-manager.ts +357 -0
- package/src/node/features/fs.ts +534 -0
- package/src/node/features/git.ts +492 -0
- package/src/node/features/google-auth.ts +502 -0
- package/src/node/features/google-calendar.ts +300 -0
- package/src/node/features/google-docs.ts +404 -0
- package/src/node/features/google-drive.ts +339 -0
- package/src/node/features/google-sheets.ts +279 -0
- package/src/node/features/grep.ts +406 -0
- package/src/node/features/helpers.ts +374 -0
- package/src/node/features/ink.ts +490 -0
- package/src/node/features/ipc-socket.ts +459 -0
- package/src/node/features/json-tree.ts +188 -0
- package/src/node/features/launcher-app-command-listener.ts +388 -0
- package/src/node/features/networking.ts +925 -0
- package/src/node/features/nlp.ts +211 -0
- package/src/node/features/opener.ts +166 -0
- package/src/node/features/os.ts +157 -0
- package/src/node/features/package-finder.ts +539 -0
- package/src/node/features/port-exposer.ts +342 -0
- package/src/node/features/postgres.ts +273 -0
- package/src/node/features/proc.ts +502 -0
- package/src/node/features/process-manager.ts +542 -0
- package/src/node/features/python.ts +444 -0
- package/src/node/features/repl.ts +194 -0
- package/src/node/features/runpod.ts +802 -0
- package/src/node/features/secure-shell.ts +248 -0
- package/src/node/features/semantic-search.ts +924 -0
- package/src/node/features/sqlite.ts +289 -0
- package/src/node/features/telegram.ts +342 -0
- package/src/node/features/tts.ts +184 -0
- package/src/node/features/ui.ts +857 -0
- package/src/node/features/vault.ts +164 -0
- package/src/node/features/vm.ts +312 -0
- package/src/node/features/window-manager.ts +804 -0
- package/src/node/features/yaml-tree.ts +149 -0
- package/src/node/features/yaml.ts +132 -0
- package/src/node.ts +70 -0
- package/src/react/index.ts +175 -0
- package/src/registry.ts +199 -0
- package/src/scaffolds/generated.ts +1613 -0
- package/src/scaffolds/template.ts +37 -0
- package/src/schemas/base.ts +255 -0
- package/src/server.ts +135 -0
- package/src/servers/express.ts +209 -0
- package/src/servers/mcp.ts +805 -0
- package/src/servers/socket.ts +120 -0
- package/src/state.ts +101 -0
- package/src/web/clients/socket.ts +82 -0
- package/src/web/container.ts +74 -0
- package/src/web/extension.ts +30 -0
- package/src/web/feature.ts +12 -0
- package/src/web/features/asset-loader.ts +64 -0
- package/src/web/features/container-link.ts +385 -0
- package/src/web/features/esbuild.ts +79 -0
- package/src/web/features/helpers.ts +267 -0
- package/src/web/features/network.ts +61 -0
- package/src/web/features/speech.ts +87 -0
- package/src/web/features/vault.ts +189 -0
- package/src/web/features/vm.ts +78 -0
- package/src/web/features/voice-recognition.ts +129 -0
- package/src/web/shims/isomorphic-vm.ts +149 -0
- package/test/bus.test.ts +134 -0
- package/test/clients-servers.test.ts +216 -0
- package/test/container-link.test.ts +274 -0
- package/test/features.test.ts +160 -0
- package/test/integration.test.ts +787 -0
- package/test/node-container.test.ts +121 -0
- package/test/rate-limit.test.ts +272 -0
- package/test/semantic-search.test.ts +550 -0
- package/test/state.test.ts +121 -0
- package/test-integration/assistant.test.ts +138 -0
- package/test-integration/assistants-manager.test.ts +123 -0
- package/test-integration/claude-code.test.ts +98 -0
- package/test-integration/conversation-history.test.ts +205 -0
- package/test-integration/conversation.test.ts +137 -0
- package/test-integration/elevenlabs.test.ts +55 -0
- package/test-integration/google-services.test.ts +80 -0
- package/test-integration/helpers.ts +89 -0
- package/test-integration/openai-codex.test.ts +93 -0
- package/test-integration/runpod.test.ts +58 -0
- package/test-integration/server-endpoints.test.ts +97 -0
- package/test-integration/skills-library.test.ts +157 -0
- package/test-integration/telegram.test.ts +46 -0
- package/tsconfig.json +58 -0
- package/uv.lock +8 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Natural Language Processing"
|
|
3
|
+
tags: [nlp, parsing, text-analysis]
|
|
4
|
+
lastTested: null
|
|
5
|
+
lastTestPassed: null
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# nlp
|
|
9
|
+
|
|
10
|
+
Natural language processing utilities for parsing utterances into structured data, POS tagging, and entity extraction.
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
The `nlp` feature is an on-demand feature that combines two complementary NLP libraries: **compromise** for verb normalization and quick structural parsing, and **wink-nlp** for high-accuracy part-of-speech tagging and named entity recognition. Use it when you need to extract intent from voice commands, classify sentence structure, or identify entities in text.
|
|
15
|
+
|
|
16
|
+
## Enabling the Feature
|
|
17
|
+
|
|
18
|
+
The nlp feature is on-demand, so we enable it explicitly.
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
const nlp = container.feature('nlp', { enable: true })
|
|
22
|
+
console.log('NLP feature enabled:', nlp.state.enabled)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Parsing Voice Commands
|
|
26
|
+
|
|
27
|
+
The `parse()` method uses compromise to extract structured command data: an intent (normalized verb), a target noun, an optional prepositional subject, and any modifiers.
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
const cmd1 = nlp.parse("open the terminal")
|
|
31
|
+
console.log('Command:', JSON.stringify(cmd1, null, 2))
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Prepositional phrases with "of" are extracted as the subject.
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
const cmd2 = nlp.parse("draw a diagram of the auth flow")
|
|
38
|
+
console.log('Command with subject:', JSON.stringify(cmd2, null, 2))
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Notice how `intent` is the normalized verb form ("draw"), `target` is the direct object ("diagram"), and `subject` captures the prepositional phrase ("auth flow").
|
|
42
|
+
|
|
43
|
+
## POS Tagging and Entity Recognition
|
|
44
|
+
|
|
45
|
+
The `analyze()` method uses wink-nlp for high-accuracy part-of-speech tagging and named entity recognition.
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
const analysis = nlp.analyze("meet john at 3pm about the deployment")
|
|
49
|
+
console.log('Tokens:')
|
|
50
|
+
for (const tok of analysis.tokens) {
|
|
51
|
+
console.log(` ${tok.value.padEnd(15)} ${tok.pos}`)
|
|
52
|
+
}
|
|
53
|
+
console.log('Entities:', JSON.stringify(analysis.entities))
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Each token is tagged with its part of speech (VERB, NOUN, ADP, DET, etc.) and named entities like times and proper nouns are extracted separately.
|
|
57
|
+
|
|
58
|
+
## Full Understanding
|
|
59
|
+
|
|
60
|
+
The `understand()` method combines both `parse()` and `analyze()` into a single result, giving you structured command data alongside detailed POS tags and entities.
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
const full = nlp.understand("send an email to sarah about the quarterly report")
|
|
64
|
+
console.log('Intent:', full.intent)
|
|
65
|
+
console.log('Target:', full.target)
|
|
66
|
+
console.log('Modifiers:', full.modifiers)
|
|
67
|
+
console.log('Token count:', full.tokens.length)
|
|
68
|
+
console.log('Entities:', JSON.stringify(full.entities))
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
This is the most complete method when you need both the high-level command structure and the detailed linguistic analysis in one call.
|
|
72
|
+
|
|
73
|
+
## Comparing Multiple Commands
|
|
74
|
+
|
|
75
|
+
Parse is fast and lightweight, making it suitable for batch processing of voice commands.
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
const commands = [
|
|
79
|
+
"deploy the app to production",
|
|
80
|
+
"restart the database server",
|
|
81
|
+
"show logs for the api gateway",
|
|
82
|
+
]
|
|
83
|
+
for (const raw of commands) {
|
|
84
|
+
const parsed = nlp.parse(raw)
|
|
85
|
+
console.log(`"${raw}" => intent: ${parsed.intent}, target: ${parsed.target}`)
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Summary
|
|
90
|
+
|
|
91
|
+
This demo covered the three main methods of the `nlp` feature: `parse()` for quick structural extraction from voice commands, `analyze()` for detailed POS tagging and entity recognition, and `understand()` for a combined view of both. The feature is well suited for building voice command interpreters, chatbot intent classifiers, and text analysis pipelines.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Opener"
|
|
3
|
+
tags: [opener, files, urls, apps, editor]
|
|
4
|
+
lastTested: null
|
|
5
|
+
lastTestPassed: null
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# opener
|
|
9
|
+
|
|
10
|
+
Opens files, URLs, desktop applications, and code editors from scripts. HTTP/HTTPS URLs open in Chrome, files open with the system default handler, and VS Code / Cursor can be targeted directly.
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
The `opener` feature provides a simple interface for opening things on the host system. It delegates to platform-appropriate commands (`open` on macOS, `start` on Windows, direct invocation on Linux). Because every method triggers a side effect (launching an application or browser), all operational examples use skip blocks.
|
|
15
|
+
|
|
16
|
+
## Enabling the Feature
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
const opener = container.feature('opener', { enable: true })
|
|
20
|
+
console.log('Opener enabled:', opener.state.get('enabled'))
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Exploring the API
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
const docs = container.features.describe('opener')
|
|
27
|
+
console.log(docs)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Opening a URL
|
|
31
|
+
|
|
32
|
+
Open a URL in Google Chrome (the default browser for HTTP/HTTPS targets).
|
|
33
|
+
|
|
34
|
+
```ts skip
|
|
35
|
+
await opener.open('https://github.com/soederpop/luca')
|
|
36
|
+
console.log('URL opened in Chrome')
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Non-HTTP paths are opened with the platform default handler. For example, opening a `.png` file would launch Preview on macOS.
|
|
40
|
+
|
|
41
|
+
```ts skip
|
|
42
|
+
await opener.open('/Users/jon/screenshots/diagram.png')
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Opening a Desktop App
|
|
46
|
+
|
|
47
|
+
Launch any desktop application by name.
|
|
48
|
+
|
|
49
|
+
```ts skip
|
|
50
|
+
await opener.app('Slack')
|
|
51
|
+
console.log('Slack launched')
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```ts skip
|
|
55
|
+
await opener.app('Finder')
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
On macOS this uses `open -a`. The application name should match what appears in `/Applications`.
|
|
59
|
+
|
|
60
|
+
## Opening in VS Code or Cursor
|
|
61
|
+
|
|
62
|
+
Open a file or folder directly in VS Code or Cursor.
|
|
63
|
+
|
|
64
|
+
```ts skip
|
|
65
|
+
await opener.code('/Users/jon/projects/my-app')
|
|
66
|
+
console.log('VS Code opened')
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```ts skip
|
|
70
|
+
await opener.cursor('/Users/jon/projects/my-app/src/index.ts')
|
|
71
|
+
console.log('Cursor opened')
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Both methods fall back to `open -a` on macOS if the CLI command is not found in PATH.
|
|
75
|
+
|
|
76
|
+
## Summary
|
|
77
|
+
|
|
78
|
+
The `opener` feature provides `open`, `app`, `code`, and `cursor` methods for launching URLs, files, desktop applications, and code editors from Luca scripts. All operations produce side effects on the host system.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "os"
|
|
3
|
+
tags: [os, system, platform, core]
|
|
4
|
+
lastTested: null
|
|
5
|
+
lastTestPassed: null
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# os
|
|
9
|
+
|
|
10
|
+
Operating system information including platform, architecture, CPU, and network details.
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
The `os` feature is a core feature, auto-enabled on every container. You can access it directly as a global or via `container.feature('os')`. It exposes system metadata through simple getters -- no method calls needed. Use it to detect the runtime environment, adapt behavior per platform, or gather machine info for diagnostics.
|
|
15
|
+
|
|
16
|
+
## Platform and Architecture
|
|
17
|
+
|
|
18
|
+
The `platform` and `arch` getters tell you what operating system and CPU architecture the code is running on.
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
console.log('Platform:', os.platform)
|
|
22
|
+
console.log('Architecture:', os.arch)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Platform returns values like `darwin`, `linux`, or `win32`. Architecture returns values like `arm64` or `x64`.
|
|
26
|
+
|
|
27
|
+
## CPU Information
|
|
28
|
+
|
|
29
|
+
The `cpuCount` getter reports the number of logical CPU cores available.
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
console.log('CPU cores:', os.cpuCount)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Use this to size worker pools or decide how many parallel tasks to run.
|
|
36
|
+
|
|
37
|
+
## System Paths
|
|
38
|
+
|
|
39
|
+
The `tmpdir` and `homedir` getters return commonly needed system directories.
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
console.log('Temp directory:', os.tmpdir)
|
|
43
|
+
console.log('Home directory:', os.homedir)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
These are the OS defaults -- `tmpdir` for throwaway files and `homedir` for the current user's home.
|
|
47
|
+
|
|
48
|
+
## Hostname
|
|
49
|
+
|
|
50
|
+
The `hostname` getter returns the machine's network hostname.
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
console.log('Hostname:', os.hostname)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This can be useful for logging, multi-machine coordination, or display purposes.
|
|
57
|
+
|
|
58
|
+
## Network Interfaces
|
|
59
|
+
|
|
60
|
+
The `macAddresses` getter returns MAC addresses for non-internal IPv4 network interfaces.
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
const macs = os.macAddresses
|
|
64
|
+
console.log('MAC addresses:', macs.length, 'found')
|
|
65
|
+
macs.slice(0, 3).forEach(mac => console.log(' ', mac))
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
MAC addresses are useful for machine fingerprinting or license management.
|
|
69
|
+
|
|
70
|
+
## Summary
|
|
71
|
+
|
|
72
|
+
This demo covered querying the platform and architecture, checking CPU core count, retrieving system directory paths, reading the hostname, and listing network MAC addresses. The `os` feature gives scripts everything they need to adapt to and report on the runtime environment.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Package Finder"
|
|
3
|
+
tags: [packageFinder, packages, dependencies, npm]
|
|
4
|
+
lastTested: null
|
|
5
|
+
lastTestPassed: null
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# packageFinder
|
|
9
|
+
|
|
10
|
+
Scans your workspace's node_modules and builds a queryable index of every installed package. Find duplicates, inspect versions, and map dependency relationships.
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
The `packageFinder` feature is on-demand. After enabling and starting it, it recursively walks all node_modules directories, reads every package.json, and indexes the results. Use it for dependency auditing, duplicate detection, or understanding what is actually installed in your project.
|
|
15
|
+
|
|
16
|
+
## Starting the Finder
|
|
17
|
+
|
|
18
|
+
Enable the feature and run the initial scan.
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
const finder = container.feature('packageFinder')
|
|
22
|
+
await finder.start()
|
|
23
|
+
console.log('Scan complete:', finder.isStarted)
|
|
24
|
+
console.log('Unique packages:', finder.packageNames.length)
|
|
25
|
+
console.log('Total manifests:', finder.manifests.length)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The difference between unique package names and total manifests reveals how many packages exist in multiple copies (different versions in different locations).
|
|
29
|
+
|
|
30
|
+
## Listing Packages
|
|
31
|
+
|
|
32
|
+
Browse the discovered package names.
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
const names = finder.packageNames
|
|
36
|
+
console.log('First 10 packages:')
|
|
37
|
+
names.slice(0, 10).forEach(n => console.log(' ', n))
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Package names include both scoped and unscoped packages from every node_modules tree in the workspace.
|
|
41
|
+
|
|
42
|
+
## Finding a Package by Name
|
|
43
|
+
|
|
44
|
+
Look up a specific package to see its version and location.
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
const zod = finder.findByName('zod')
|
|
48
|
+
if (zod) {
|
|
49
|
+
console.log('Found:', zod.name)
|
|
50
|
+
console.log('Version:', zod.version)
|
|
51
|
+
console.log('Description:', zod.description)
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
If multiple versions exist, `findByName` returns the first match. Use `filter()` to find all instances.
|
|
56
|
+
|
|
57
|
+
## Scoped Packages
|
|
58
|
+
|
|
59
|
+
The finder tracks which npm scopes are present in your dependencies.
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
const scopes = finder.scopes
|
|
63
|
+
console.log('Scopes found:', scopes.length)
|
|
64
|
+
scopes.slice(0, 8).forEach(s => {
|
|
65
|
+
const count = finder.packageNames.filter(n => n.startsWith(s)).length
|
|
66
|
+
console.log(` ${s}: ${count} packages`)
|
|
67
|
+
})
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
This is useful for auditing which organizations and ecosystems your project depends on.
|
|
71
|
+
|
|
72
|
+
## Detecting Duplicates
|
|
73
|
+
|
|
74
|
+
Packages that appear in multiple locations (often at different versions) show up in the duplicates list.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
const dupes = finder.duplicates
|
|
78
|
+
console.log('Duplicate packages:', dupes.length)
|
|
79
|
+
dupes.slice(0, 5).forEach(name => {
|
|
80
|
+
const count = finder.counts[name]
|
|
81
|
+
console.log(` ${name}: ${count} copies`)
|
|
82
|
+
})
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Duplicates increase install size and can cause subtle bugs when multiple versions of the same library coexist.
|
|
86
|
+
|
|
87
|
+
## Summary
|
|
88
|
+
|
|
89
|
+
This demo covered scanning the workspace for packages, listing and looking up packages, inspecting scopes, and detecting duplicates. The `packageFinder` feature gives you a complete inventory of your installed dependencies for auditing and analysis.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Port Exposer"
|
|
3
|
+
tags: [portExposer, ngrok, networking, tunnel]
|
|
4
|
+
lastTested: null
|
|
5
|
+
lastTestPassed: null
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# portExposer
|
|
9
|
+
|
|
10
|
+
Exposes local HTTP services via ngrok with SSL-enabled public URLs. Useful for development, testing webhooks, and sharing local services with external consumers.
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
The `portExposer` feature creates an ngrok tunnel from a local port to a public HTTPS URL. It supports custom subdomains, regional endpoints, basic auth, and OAuth (features that require a paid ngrok plan). Requires ngrok to be installed or available as a dependency, and optionally an auth token for premium features.
|
|
15
|
+
|
|
16
|
+
## Enabling the Feature
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
const exposer = container.feature('portExposer', {
|
|
20
|
+
port: 3000,
|
|
21
|
+
enable: true
|
|
22
|
+
})
|
|
23
|
+
console.log('Port Exposer enabled:', exposer.state.get('enabled'))
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Exploring the API
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
const docs = container.features.describe('portExposer')
|
|
30
|
+
console.log(docs)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Checking Connection State
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
const exposer = container.feature('portExposer', { port: 3000 })
|
|
37
|
+
console.log('Connected:', exposer.isConnected())
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Exposing a Port
|
|
41
|
+
|
|
42
|
+
Create a tunnel and get the public URL.
|
|
43
|
+
|
|
44
|
+
```ts skip
|
|
45
|
+
const url = await exposer.expose()
|
|
46
|
+
console.log('Public URL:', url)
|
|
47
|
+
console.log('Connected:', exposer.isConnected())
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The returned URL is an HTTPS endpoint that forwards traffic to `localhost:3000`. The tunnel remains active until `close()` is called or the process exits.
|
|
51
|
+
|
|
52
|
+
## Getting Connection Info
|
|
53
|
+
|
|
54
|
+
Retrieve a snapshot of the current tunnel state.
|
|
55
|
+
|
|
56
|
+
```ts skip
|
|
57
|
+
await exposer.expose()
|
|
58
|
+
const info = exposer.getConnectionInfo()
|
|
59
|
+
console.log('Public URL:', info.publicUrl)
|
|
60
|
+
console.log('Local port:', info.localPort)
|
|
61
|
+
console.log('Connected at:', info.connectedAt)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Reconnecting with New Options
|
|
65
|
+
|
|
66
|
+
Close the existing tunnel and re-expose with different settings.
|
|
67
|
+
|
|
68
|
+
```ts skip
|
|
69
|
+
const url1 = await exposer.expose()
|
|
70
|
+
console.log('First URL:', url1)
|
|
71
|
+
|
|
72
|
+
const url2 = await exposer.reconnect({ port: 8080 })
|
|
73
|
+
console.log('New URL (port 8080):', url2)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The `reconnect` method calls `close()` internally, merges the new options, then calls `expose()` again.
|
|
77
|
+
|
|
78
|
+
## Closing the Tunnel
|
|
79
|
+
|
|
80
|
+
```ts skip
|
|
81
|
+
await exposer.close()
|
|
82
|
+
console.log('Tunnel closed:', !exposer.isConnected())
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Calling `close()` when no tunnel is active is a safe no-op. The `disable()` method also closes the tunnel before disabling the feature.
|
|
86
|
+
|
|
87
|
+
## Summary
|
|
88
|
+
|
|
89
|
+
The `portExposer` feature wraps ngrok to expose local ports as public HTTPS endpoints. It supports connection lifecycle management, reconnection with new options, and event-driven notifications for tunnel state changes. Requires ngrok to be installed.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "PostgreSQL"
|
|
3
|
+
tags: [postgres, database, sql, storage]
|
|
4
|
+
lastTested: null
|
|
5
|
+
lastTestPassed: null
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# postgres
|
|
9
|
+
|
|
10
|
+
PostgreSQL feature for safe SQL execution through Bun's native SQL client. Supports parameterized queries, tagged-template literals, and write operations.
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
Use the `postgres` feature when you need to interact with a PostgreSQL database. It provides three query interfaces: parameterized `query()` for reads, `execute()` for writes, and the `sql` tagged template for injection-safe inline SQL.
|
|
15
|
+
|
|
16
|
+
Requires a running PostgreSQL instance and a connection URL.
|
|
17
|
+
|
|
18
|
+
## Enabling the Feature
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
const pg = container.feature('postgres', {
|
|
22
|
+
url: 'postgres://user:pass@localhost:5432/mydb'
|
|
23
|
+
})
|
|
24
|
+
console.log('Postgres feature created')
|
|
25
|
+
console.log('Connection URL configured:', !!pg.state.url)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Pass your connection URL via the `url` option. In production, read from an environment variable.
|
|
29
|
+
|
|
30
|
+
## API Documentation
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
const info = await container.features.describe('postgres')
|
|
34
|
+
console.log(info)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Parameterized Queries
|
|
38
|
+
|
|
39
|
+
Use `query()` for SELECT statements with `$N` placeholders to prevent SQL injection.
|
|
40
|
+
|
|
41
|
+
```ts skip
|
|
42
|
+
const users = await pg.query(
|
|
43
|
+
'SELECT id, email FROM users WHERE active = $1 LIMIT $2',
|
|
44
|
+
[true, 10]
|
|
45
|
+
)
|
|
46
|
+
console.log(`Found ${users.length} active users`)
|
|
47
|
+
users.forEach(u => console.log(` ${u.id}: ${u.email}`))
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
With a running database, this would return an array of row objects matching the query. The `query` event fires on each execution.
|
|
51
|
+
|
|
52
|
+
## Tagged Template SQL
|
|
53
|
+
|
|
54
|
+
The `sql` tagged template automatically converts interpolated values into bound parameters.
|
|
55
|
+
|
|
56
|
+
```ts skip
|
|
57
|
+
const email = 'hello@example.com'
|
|
58
|
+
const rows = await pg.sql`
|
|
59
|
+
SELECT id, name FROM users WHERE email = ${email}
|
|
60
|
+
`
|
|
61
|
+
console.log('Found:', rows)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
This is the most ergonomic way to write queries. Each interpolated value becomes a `$N` parameter automatically, preventing SQL injection without manual placeholder numbering.
|
|
65
|
+
|
|
66
|
+
## Write Operations
|
|
67
|
+
|
|
68
|
+
Use `execute()` for INSERT, UPDATE, and DELETE statements that return affected row counts.
|
|
69
|
+
|
|
70
|
+
```ts skip
|
|
71
|
+
const { rowCount } = await pg.execute(
|
|
72
|
+
'UPDATE users SET active = $1 WHERE last_login < $2',
|
|
73
|
+
[false, '2024-01-01']
|
|
74
|
+
)
|
|
75
|
+
console.log(`Deactivated ${rowCount} users`)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The `execute` event fires with the row count after each write operation.
|
|
79
|
+
|
|
80
|
+
## Closing the Connection
|
|
81
|
+
|
|
82
|
+
```ts skip
|
|
83
|
+
await pg.close()
|
|
84
|
+
console.log('Connection closed:', !pg.state.connected)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Always close the connection when done. The `closed` event fires after teardown.
|
|
88
|
+
|
|
89
|
+
## Summary
|
|
90
|
+
|
|
91
|
+
The `postgres` feature wraps Bun's native SQL client with three query methods: `query()` for parameterized reads, `execute()` for writes, and the `sql` tagged template for ergonomic injection-safe queries. Events fire for each operation. Key methods: `query()`, `execute()`, `sql`, `close()`.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "proc"
|
|
3
|
+
tags: [proc, process, shell, core]
|
|
4
|
+
lastTested: null
|
|
5
|
+
lastTestPassed: null
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# proc
|
|
9
|
+
|
|
10
|
+
Process execution utilities for running shell commands and capturing their output.
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
The `proc` feature is a core feature, auto-enabled on every container. You can access it directly as a global or via `container.feature('proc')`. It provides synchronous and asynchronous methods for executing shell commands. Use `exec()` for quick synchronous calls and `execAndCapture()` when you need structured output with exit codes.
|
|
15
|
+
|
|
16
|
+
## Simple Command Execution
|
|
17
|
+
|
|
18
|
+
Use `exec()` to run a command synchronously and get its stdout as a string.
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
const result = proc.exec('echo hello from luca')
|
|
22
|
+
console.log('Output:', result.trim())
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The output is returned directly as a string, with no wrapper object.
|
|
26
|
+
|
|
27
|
+
## Listing Files
|
|
28
|
+
|
|
29
|
+
Commands that produce multi-line output work naturally. Each line comes through as part of the string.
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
const listing = proc.exec('ls src')
|
|
33
|
+
const entries = listing.trim().split('\n')
|
|
34
|
+
console.log('Entries in src/:', entries.length)
|
|
35
|
+
entries.slice(0, 5).forEach(e => console.log(' ', e))
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
You can split and process the output like any other string.
|
|
39
|
+
|
|
40
|
+
## Working Directory Option
|
|
41
|
+
|
|
42
|
+
Pass a `cwd` option to run a command in a different directory without changing the container's working directory.
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
const rootFiles = proc.exec('ls -1', { cwd: '.' })
|
|
46
|
+
console.log('Files in project root:')
|
|
47
|
+
rootFiles.trim().split('\n').slice(0, 5).forEach(f => console.log(' ', f))
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
This is useful when you need to operate on files in a subdirectory or sibling project.
|
|
51
|
+
|
|
52
|
+
## Getting System Info
|
|
53
|
+
|
|
54
|
+
Shell commands work for gathering system information that might not be available through other features.
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
const date = proc.exec('date')
|
|
58
|
+
console.log('Current date:', date.trim())
|
|
59
|
+
|
|
60
|
+
const whoami = proc.exec('whoami')
|
|
61
|
+
console.log('Current user:', whoami.trim())
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Any command available on the system PATH can be called through `exec()`.
|
|
65
|
+
|
|
66
|
+
## Async Execution with Capture
|
|
67
|
+
|
|
68
|
+
Use `execAndCapture()` for async execution with structured output including exit code and stderr.
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
const result = await proc.execAndCapture('ls src')
|
|
72
|
+
console.log('Exit code:', result.exitCode)
|
|
73
|
+
console.log('Stdout lines:', result.stdout.trim().split('\n').length)
|
|
74
|
+
console.log('Stderr:', result.stderr || '(empty)')
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The returned object gives you `stdout`, `stderr`, `exitCode`, and `pid` for full control over the result.
|
|
78
|
+
|
|
79
|
+
## Summary
|
|
80
|
+
|
|
81
|
+
This demo covered synchronous command execution, processing multi-line output, running commands in different directories, gathering system info, and async execution with structured results. The `proc` feature is the escape hatch for anything the other features do not cover directly.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Process Manager"
|
|
3
|
+
tags: [processManager, processes, spawn, lifecycle]
|
|
4
|
+
lastTested: null
|
|
5
|
+
lastTestPassed: null
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# processManager
|
|
9
|
+
|
|
10
|
+
Manage long-running child processes with tracking, events, and automatic cleanup.
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
The `processManager` feature is an on-demand feature for spawning and supervising child processes. Unlike `proc.spawn` which blocks until a process exits, processManager returns a `SpawnHandler` immediately -- a handle object with its own state, events, and lifecycle methods. The feature tracks all spawned processes and can kill them all on parent exit. Use it when you need to orchestrate multiple background services, dev servers, or worker processes.
|
|
15
|
+
|
|
16
|
+
## Enabling the Feature
|
|
17
|
+
|
|
18
|
+
Enable the processManager with auto-cleanup so tracked processes are killed when the parent exits.
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
const pm = container.feature('processManager', { enable: true, autoCleanup: true })
|
|
22
|
+
console.log('ProcessManager enabled:', pm.state.enabled)
|
|
23
|
+
console.log('Total spawned so far:', pm.state.totalSpawned)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Spawning a Process
|
|
27
|
+
|
|
28
|
+
Spawn a short-lived process and capture its output. The `spawn` method returns a `SpawnHandler` immediately.
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
const handle = pm.spawn('echo', ['hello from process manager'], { tag: 'greeter' })
|
|
32
|
+
console.log('Spawned process tag:', 'greeter')
|
|
33
|
+
console.log('Handle has kill method:', typeof handle.kill === 'function')
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The handle provides methods like `kill()` and events like `stdout`, `stderr`, `exited`, and `crashed`.
|
|
37
|
+
|
|
38
|
+
## Listing Tracked Processes
|
|
39
|
+
|
|
40
|
+
The processManager keeps track of every process it has spawned, whether running or finished.
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
const all = pm.list()
|
|
44
|
+
console.log('Tracked processes:', all.length)
|
|
45
|
+
console.log('Total spawned:', pm.state.totalSpawned)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
You can also look up a specific process by its tag.
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
const found = pm.getByTag('greeter')
|
|
52
|
+
console.log('Found by tag:', found ? 'yes' : 'no')
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Spawning and Killing
|
|
56
|
+
|
|
57
|
+
You can spawn a longer process and then kill it. Here we spawn `sleep` and immediately terminate it.
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
const sleeper = pm.spawn('sleep', ['10'], { tag: 'sleeper' })
|
|
61
|
+
console.log('Sleeper spawned')
|
|
62
|
+
sleeper.kill()
|
|
63
|
+
console.log('Sleeper killed')
|
|
64
|
+
console.log('Total spawned now:', pm.state.totalSpawned)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Cleaning Up
|
|
68
|
+
|
|
69
|
+
The `killAll` method terminates every tracked process, and `stop` does a full teardown including removing exit handlers.
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
pm.killAll()
|
|
73
|
+
const remaining = pm.list().filter(h => h.state?.status === 'running')
|
|
74
|
+
console.log('Running after killAll:', remaining.length)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Summary
|
|
78
|
+
|
|
79
|
+
This demo covered the `processManager` feature: spawning processes that return handles immediately, tracking them by ID or tag, listing all tracked processes, and killing them individually or all at once. It is the right tool for orchestrating background services, dev servers, and any scenario where you need non-blocking process management with lifecycle events.
|