@soederpop/luca 0.0.34 → 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/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",
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/port-exposer, 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
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)
@@ -275,7 +275,7 @@ A table of contents for the container. **Run `luca describe <name>` for full doc
275
275
  | **AI Assistants** | `assistant`, `assistantsManager`, `conversation`, `conversationHistory`, `fileTools` | Build AI assistants, manage conversations, tool calling. `fileTools` composes lower-level features (`fs`, `grep`) into an assistant-ready tool surface — a good example of how features can define tools for assistants (see `references/examples/feature-as-tool-provider.md`). |
276
276
  | **AI Agent Wrappers** | `claudeCode`, `openaiCodex`, `lucaCoder` | Spawn and manage external AI agent CLIs as subprocesses |
277
277
  | **Data & Storage** | `sqlite`, `postgres`, `diskCache`, `contentDb`, `redis` | Databases, caching, document management |
278
- | **Networking** | `networking`, `dns`, `portExposer` | Network utilities, DNS, tunneling |
278
+ | **Networking** | `networking`, `dns` | Network utilities, DNS |
279
279
  | **Google Workspace** | `googleAuth`, `googleDrive`, `googleDocs`, `googleSheets`, `googleCalendar`, `googleMail` | OAuth and Google service wrappers |
280
280
  | **Dev Tools** | `git`, `docker`, `esbuild`, `vm`, `python`, `packageFinder` | Version control, containers, bundling, sandboxed execution |
281
281
  | **Content & NLP** | `docsReader`, `nlp`, `semanticSearch`, `skillsLibrary`, `jsonTree`, `yamlTree` | Document Q&A, text analysis, semantic search, skills, structured file ingestion |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soederpop/luca",
3
- "version": "0.0.34",
3
+ "version": "0.0.35",
4
4
  "website": "https://luca.soederpop.com",
5
5
  "description": "lightweight universal conversational architecture AKA Le Ultimate Component Architecture AKA Last Universal Common Ancestor, part AI part Human",
6
6
  "author": "jon soeder aka the people's champ <jon@soederpop.com>",
@@ -92,7 +92,6 @@
92
92
  },
93
93
  "dependencies": {
94
94
  "@modelcontextprotocol/sdk": "^1.12.1",
95
- "@ngrok/ngrok": "^1.5.1",
96
95
  "@openai/codex": "^0.99.0",
97
96
  "@resvg/resvg-js": "^2.6.2",
98
97
  "@supabase/supabase-js": "^2.95.3",
@@ -129,19 +129,16 @@ async function main() {
129
129
  }
130
130
  }
131
131
 
132
- // ── Phase 1b: Expose MCP Servers via ngrok ─────────────────────────────
132
+ // ── Phase 1b: Build local MCP Server URLs ──────────────────────────────
133
133
 
134
134
  const publicUrls: Record<string, string> = {}
135
- const exposers: Array<{ close(): Promise<void> }> = []
136
135
 
137
136
  for (const def of MCP_SERVERS) {
138
137
  const entry = serverMap[def.tag]!
139
138
  if (entry.status === 'running' || entry.status === 'external') {
140
- const exposer = container.feature('portExposer', { port: def.port, enable: true })
141
- const url = await exposer.expose()
139
+ const url = `http://localhost:${def.port}`
142
140
  publicUrls[def.tag] = `${url}/mcp`
143
141
  entry.publicUrl = url
144
- exposers.push(exposer)
145
142
  }
146
143
  }
147
144
 
@@ -496,7 +493,6 @@ async function main() {
496
493
  useInput(
497
494
  (input, key) => {
498
495
  if (key.ctrl && input === 'c') {
499
- for (const e of exposers) e.close().catch(() => {})
500
496
  pm.killAll()
501
497
  exit()
502
498
  }
@@ -553,7 +549,6 @@ async function main() {
553
549
  await ink.render(h(App))
554
550
  await ink.waitUntilExit()
555
551
 
556
- for (const e of exposers) await e.close().catch(() => {})
557
552
  pm.killAll()
558
553
  }
559
554
 
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # CI-style test: cross-compile luca for Linux and verify it runs in a Docker container
5
+ # Usage: bash scripts/test-linux-binary.sh
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8
+ PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
9
+ DIST_DIR="$PROJECT_DIR/dist"
10
+ LINUX_BINARY="$DIST_DIR/luca-linux"
11
+
12
+ echo "=== Cross-compiling luca for linux-arm64 ==="
13
+ cd "$PROJECT_DIR"
14
+
15
+ # Run the pre-compile build steps (introspection, scaffolds, etc.)
16
+ bun run build:introspection
17
+ bun run build:scaffolds
18
+ bun run build:bootstrap
19
+ bun run build:python-bridge
20
+ bash scripts/stamp-build.sh
21
+
22
+ # Cross-compile for linux arm64 (matches Docker on Apple Silicon)
23
+ bun build ./src/cli/cli.ts --compile --target=bun-linux-arm64 --outfile "$LINUX_BINARY" --external node-llama-cpp
24
+
25
+ echo ""
26
+ echo "=== Built linux binary: $(file "$LINUX_BINARY") ==="
27
+ echo ""
28
+
29
+ # Create a minimal Dockerfile inline
30
+ DOCKER_TAG="luca-linux-test"
31
+
32
+ docker build -t "$DOCKER_TAG" -f - "$DIST_DIR" <<'DOCKERFILE'
33
+ FROM debian:bookworm-slim
34
+ RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && rm -rf /var/lib/apt/lists/*
35
+ WORKDIR /app
36
+ COPY luca-linux /usr/local/bin/luca
37
+ RUN chmod +x /usr/local/bin/luca
38
+ DOCKERFILE
39
+
40
+ echo ""
41
+ echo "=== Running smoke tests in Docker container ==="
42
+ echo ""
43
+
44
+ PASS=0
45
+ FAIL=0
46
+
47
+ run_test() {
48
+ local description="$1"
49
+ shift
50
+ echo -n " TEST: $description ... "
51
+ if output=$(docker run --rm "$DOCKER_TAG" "$@" 2>&1); then
52
+ echo "PASS"
53
+ PASS=$((PASS + 1))
54
+ else
55
+ echo "FAIL"
56
+ echo " Output: $output"
57
+ FAIL=$((FAIL + 1))
58
+ fi
59
+ }
60
+
61
+ # Basic smoke tests
62
+ run_test "binary executes" luca --version
63
+ run_test "help flag works" luca --help
64
+ run_test "eval runs JS expression" luca eval "1 + 1"
65
+ run_test "describe features" luca describe features
66
+ run_test "container basics via eval" luca eval "container.uuid"
67
+
68
+ echo ""
69
+ echo "=== Results: $PASS passed, $FAIL failed ==="
70
+
71
+ # Cleanup
72
+ docker rmi "$DOCKER_TAG" > /dev/null 2>&1 || true
73
+ rm -f "$LINUX_BINARY"
74
+
75
+ if [ "$FAIL" -gt 0 ]; then
76
+ echo "FAILED"
77
+ exit 1
78
+ fi
79
+
80
+ echo "ALL TESTS PASSED"
@@ -1,5 +1,5 @@
1
1
  // Auto-generated bootstrap content
2
- // Generated at: 2026-03-26T03:30:22.249Z
2
+ // Generated at: 2026-03-27T03:29:28.307Z
3
3
  // Source: docs/bootstrap/*.md, docs/bootstrap/templates/*, docs/examples/*.md, docs/tutorials/*.md
4
4
  //
5
5
  // Do not edit manually. Run: luca build-bootstrap
@@ -282,7 +282,7 @@ A table of contents for the container. **Run \`luca describe <name>\` for full d
282
282
  | **AI Assistants** | \`assistant\`, \`assistantsManager\`, \`conversation\`, \`conversationHistory\`, \`fileTools\` | Build AI assistants, manage conversations, tool calling. \`fileTools\` composes lower-level features (\`fs\`, \`grep\`) into an assistant-ready tool surface — a good example of how features can define tools for assistants (see \`references/examples/feature-as-tool-provider.md\`). |
283
283
  | **AI Agent Wrappers** | \`claudeCode\`, \`openaiCodex\`, \`lucaCoder\` | Spawn and manage external AI agent CLIs as subprocesses |
284
284
  | **Data & Storage** | \`sqlite\`, \`postgres\`, \`diskCache\`, \`contentDb\`, \`redis\` | Databases, caching, document management |
285
- | **Networking** | \`networking\`, \`dns\`, \`portExposer\` | Network utilities, DNS, tunneling |
285
+ | **Networking** | \`networking\`, \`dns\` | Network utilities, DNS |
286
286
  | **Google Workspace** | \`googleAuth\`, \`googleDrive\`, \`googleDocs\`, \`googleSheets\`, \`googleCalendar\`, \`googleMail\` | OAuth and Google service wrappers |
287
287
  | **Dev Tools** | \`git\`, \`docker\`, \`esbuild\`, \`vm\`, \`python\`, \`packageFinder\` | Version control, containers, bundling, sandboxed execution |
288
288
  | **Content & NLP** | \`docsReader\`, \`nlp\`, \`semanticSearch\`, \`skillsLibrary\`, \`jsonTree\`, \`yamlTree\` | Document Q&A, text analysis, semantic search, skills, structured file ingestion |
@@ -2684,96 +2684,6 @@ console.log('Done')
2684
2684
  ## Summary
2685
2685
 
2686
2686
  The ask/reply protocol gives you awaitable request/response over WebSocket without leaving the Luca helper API. The client calls \`ask(type, data)\` and gets back a promise. The server's message handler gets \`reply()\` and \`replyError()\` injected on any message that carries a \`requestId\`. The server can also \`ask()\` a specific client. Timeouts, error propagation, and cleanup of pending requests on disconnect are all handled automatically.
2687
- `,
2688
- "port-exposer.md": `---
2689
- title: "Port Exposer"
2690
- tags: [portExposer, ngrok, networking, tunnel]
2691
- lastTested: null
2692
- lastTestPassed: null
2693
- ---
2694
-
2695
- # portExposer
2696
-
2697
- Exposes local HTTP services via ngrok with SSL-enabled public URLs. Useful for development, testing webhooks, and sharing local services with external consumers.
2698
-
2699
- ## Overview
2700
-
2701
- 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.
2702
-
2703
- ## Enabling the Feature
2704
-
2705
- \`\`\`ts
2706
- const exposer = container.feature('portExposer', {
2707
- port: 3000,
2708
- enable: true
2709
- })
2710
- console.log('Port Exposer enabled:', exposer.state.get('enabled'))
2711
- \`\`\`
2712
-
2713
- ## Exploring the API
2714
-
2715
- \`\`\`ts
2716
- const docs = container.features.describe('portExposer')
2717
- console.log(docs)
2718
- \`\`\`
2719
-
2720
- ## Checking Connection State
2721
-
2722
- \`\`\`ts
2723
- const exposer = container.feature('portExposer', { port: 3000 })
2724
- console.log('Connected:', exposer.isConnected())
2725
- \`\`\`
2726
-
2727
- ## Exposing a Port
2728
-
2729
- Create a tunnel and get the public URL.
2730
-
2731
- \`\`\`ts skip
2732
- const url = await exposer.expose()
2733
- console.log('Public URL:', url)
2734
- console.log('Connected:', exposer.isConnected())
2735
- \`\`\`
2736
-
2737
- 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.
2738
-
2739
- ## Getting Connection Info
2740
-
2741
- Retrieve a snapshot of the current tunnel state.
2742
-
2743
- \`\`\`ts skip
2744
- await exposer.expose()
2745
- const info = exposer.getConnectionInfo()
2746
- console.log('Public URL:', info.publicUrl)
2747
- console.log('Local port:', info.localPort)
2748
- console.log('Connected at:', info.connectedAt)
2749
- \`\`\`
2750
-
2751
- ## Reconnecting with New Options
2752
-
2753
- Close the existing tunnel and re-expose with different settings.
2754
-
2755
- \`\`\`ts skip
2756
- const url1 = await exposer.expose()
2757
- console.log('First URL:', url1)
2758
-
2759
- const url2 = await exposer.reconnect({ port: 8080 })
2760
- console.log('New URL (port 8080):', url2)
2761
- \`\`\`
2762
-
2763
- The \`reconnect\` method calls \`close()\` internally, merges the new options, then calls \`expose()\` again.
2764
-
2765
- ## Closing the Tunnel
2766
-
2767
- \`\`\`ts skip
2768
- await exposer.close()
2769
- console.log('Tunnel closed:', !exposer.isConnected())
2770
- \`\`\`
2771
-
2772
- Calling \`close()\` when no tunnel is active is a safe no-op. The \`disable()\` method also closes the tunnel before disabling the feature.
2773
-
2774
- ## Summary
2775
-
2776
- 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.
2777
2687
  `,
2778
2688
  "secure-shell.md": `---
2779
2689
  title: "Secure Shell"
@@ -1,4 +1,4 @@
1
1
  // Generated at compile time — do not edit manually
2
- export const BUILD_SHA = 'd3e8b52'
2
+ export const BUILD_SHA = 'd0aa900'
3
3
  export const BUILD_BRANCH = 'main'
4
- export const BUILD_DATE = '2026-03-26T03:30:23Z'
4
+ export const BUILD_DATE = '2026-03-27T03:29:29Z'