capacitor-mobile-claw 1.6.3 → 1.6.5

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.
Files changed (2) hide show
  1. package/README.md +141 -40
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  **On-device AI agent engine for mobile apps** — run Claude directly on your phone with file tools, code execution, git, and extensible MCP tool support.
8
8
 
9
- Mobile Claw is a [Capacitor](https://capacitorjs.com/) plugin that embeds a full AI agent runtime on Android and iOS via an embedded Node.js worker. No cloud relay, no proxy the agent runs locally on the device and talks directly to the Anthropic API.
9
+ Mobile Claw is a [Capacitor](https://capacitorjs.com/) plugin that embeds a full AI agent runtime on Android and iOS. Two execution modes: a **WebView agent** for instant cold start (agent loop runs in-process) or a **Node.js worker** for full sandboxed tooling. Both talk directly to the Anthropic API — no cloud relay, no proxy. Includes **on-device vector memory** via [LanceDB](https://www.npmjs.com/package/capacitor-lancedb), **background scheduling** via [MobileCron](https://www.npmjs.com/package/capacitor-mobilecron) (WorkManager / BGTaskScheduler), cron jobs with reusable skills, and native streaming HTTP for WebView CORS bypass.
10
10
 
11
11
  > Built on [OpenClaw](https://github.com/openclaw/openclaw) and the [Pi framework](https://www.npmjs.com/package/@mariozechner/pi-ai) by [Mario Zechner](https://github.com/badlogic). Pi's philosophy of *"what you leave out matters more than what you put in"* — just 4 core tools and a system prompt under 1,000 tokens — is what makes running a capable AI agent on a phone possible at all.
12
12
 
@@ -79,13 +79,16 @@ npx cap open ios
79
79
  ### Running Tests
80
80
 
81
81
  ```bash
82
- # Android E2E (100 tests, requires ADB device)
82
+ # Unit tests (64 tests)
83
+ npm test
84
+
85
+ # Android E2E (111 tests, requires ADB device)
83
86
  npm run test:android
84
87
 
85
- # iOS E2E (104 tests, requires booted Simulator)
88
+ # iOS E2E (111 tests, requires booted Simulator)
86
89
  npm run test:ios
87
90
 
88
- # Full suite: node + Android + iOS (skips unavailable platforms)
91
+ # Full suite: unit + Android + iOS (skips unavailable platforms)
89
92
  npm run test:full
90
93
  ```
91
94
 
@@ -93,29 +96,23 @@ Once the app launches, enter your Anthropic API key in settings and start chatti
93
96
 
94
97
  ## How It Works
95
98
 
99
+ The agent loop runs directly in the WebView for instant cold start — no waiting for Node.js worker boot. LLM API calls are routed through native HTTP (OkHttp / URLSession) to bypass WebView CORS, with full SSE streaming. Worker tools (file I/O, git, code exec) are transparently proxied via the bridge.
100
+
96
101
  ```
97
- ┌─────────────────────────────────────────────────────┐
98
- │ Your App (Vue, React, Svelte, vanilla JS)
99
- ┌───────────────────────────────────────────────┐
100
- │ │ MobileClawEngine (framework-agnostic) │ │
101
- │ │ - sendMessage() / stopTurn() / steerAgent() │ │
102
- │ │ - readFile() / writeFile() │ │
103
- │ │ - listSessions() / resumeSession() │ │
104
- │ │ - invokeTool() │ │
105
- └──────────────────┬────────────────────────────┘
106
- Bridge Protocol (IPC)
107
- ┌──────────────────▼────────────────────────────┐
108
- │ │ Embedded Node.js Worker (Capacitor-NodeJS) │ │
109
- ┌──────────────┐ ┌──────────────────────┐
110
- │ │ │ Pi Agent │ │ MCP Server │ │ │
111
- │ │ │ (@mariozechner│ │ - Bridge transport │ │ │
112
- │ │ │ /pi-ai) │ │ - STOMP transport │ │ │
113
- │ │ │ │ │ - Custom tools (BYO) │ │ │
114
- │ │ └──────┬───────┘ └──────────────────────┘ │ │
115
- │ │ │ │ │
116
- │ │ ▼ Anthropic Messages API │ │
117
- │ └────────────────────────────────────────────────┘ │
118
- └─────────────────────────────────────────────────────┘
102
+ ┌──────────────────────────────────────────────────────────┐
103
+ │ Your App (Vue, React, Svelte, vanilla JS)
104
+ ┌────────────────────────────────────────────────────┐
105
+ │ │ MobileClawEngine (useWebViewAgent: true) │ │
106
+ │ │ ┌──────────────┐ │ │
107
+ │ │ Pi Agent │──── Anthropic API (native HTTP) │ │
108
+ │ │ (in WebView) │
109
+ │ │ └──────┬───────┘ │ │
110
+ │ │ ToolProxy (bridge IPC) │
111
+ ┌──────▼───────────────────────────────────────┐
112
+ Node.js Worker (file tools, git, code exec) │ │ │
113
+ │ │ └──────────────────────────────────────────────┘ │ │
114
+ └────────────────────────────────────────────────────┘
115
+ └──────────────────────────────────────────────────────────┘
119
116
  ```
120
117
 
121
118
  ## Install in Your Own App
@@ -124,6 +121,16 @@ Once the app launches, enter your Anthropic API key in settings and start chatti
124
121
  npm install capacitor-mobile-claw @capacitor/core @capacitor/device @choreruiz/capacitor-node-js @capacitor-community/sqlite
125
122
  ```
126
123
 
124
+ If using Vite, add the bundler plugin to `vite.config.js` (stubs Node.js-only transitive deps):
125
+
126
+ ```javascript
127
+ import { mobileClawVitePlugin } from 'capacitor-mobile-claw/vite-plugin'
128
+
129
+ export default defineConfig({
130
+ plugins: [mobileClawVitePlugin(), vue()],
131
+ })
132
+ ```
133
+
127
134
  Then add these scripts to your `package.json`:
128
135
 
129
136
  ```json
@@ -156,13 +163,13 @@ import { MobileClawEngine } from 'capacitor-mobile-claw'
156
163
 
157
164
  const engine = new MobileClawEngine()
158
165
 
159
- // Initialize the embedded Node.js worker
160
- await engine.init()
166
+ // WebView agent instant cold start, streaming via native HTTP
167
+ await engine.init({ useWebViewAgent: true })
161
168
 
162
169
  // Listen for streaming text
163
170
  engine.addListener('agentEvent', (event) => {
164
171
  if (event.eventType === 'text_delta') {
165
- process.stdout.write(event.data.text)
172
+ console.log(event.data.text)
166
173
  }
167
174
  })
168
175
 
@@ -189,12 +196,77 @@ const engine = new MobileClawEngine()
189
196
 
190
197
  await engine.init({
191
198
  tools: myTools,
192
- enableBridge: true,
199
+ useWebViewAgent: true,
200
+ })
201
+ ```
202
+
203
+ ### With On-Device Memory
204
+
205
+ The agent remembers across sessions using [capacitor-lancedb](https://www.npmjs.com/package/capacitor-lancedb) — a Rust-powered vector database running entirely on-device. Memories are stored, deduplicated, and recalled via semantic search. Five built-in tools (`memory_store`, `memory_recall`, `memory_search`, `memory_forget`, `memory_get`) are passed to the agent automatically.
206
+
207
+ ```typescript
208
+ import { MemoryManager } from 'capacitor-lancedb'
209
+
210
+ const memory = new MemoryManager({ dbPath: 'files://agent-memory' })
211
+ await memory.init()
212
+
213
+ const engine = new MobileClawEngine()
214
+ const memoryTools = memory.getTools()
215
+ await engine.init({ tools: memoryTools, useWebViewAgent: true })
216
+
217
+ // Agent can now store/recall memories across sessions.
218
+ // Auto-recall injects relevant context at turn start.
219
+ // Auto-capture extracts facts from agent responses.
220
+ ```
221
+
222
+ ### With Background Scheduling
223
+
224
+ [capacitor-mobilecron](https://www.npmjs.com/package/capacitor-mobilecron) enables the agent to wake and run in the background via Android WorkManager and iOS BGTaskScheduler. The engine's scheduler manages heartbeats (periodic check-ins) and cron jobs (recurring tasks).
225
+
226
+ ```typescript
227
+ import { MobileCron } from 'capacitor-mobilecron'
228
+
229
+ const engine = new MobileClawEngine()
230
+ await engine.init({ useWebViewAgent: true, mobileCron: MobileCron })
231
+
232
+ // Enable scheduler + heartbeat (runs every 30 minutes)
233
+ await engine.setSchedulerConfig({ enabled: true, schedulingMode: 'balanced' })
234
+ await engine.setHeartbeat({ enabled: true, everyMs: 1800000 })
235
+
236
+ // Listen for heartbeat results
237
+ engine.addListener('heartbeatCompleted', (event) => {
238
+ console.log(`Heartbeat: ${event.status} (${event.durationMs}ms)`)
239
+ })
240
+ ```
241
+
242
+ ### With Cron Jobs
243
+
244
+ ```typescript
245
+ // Create a skill (reusable prompt + tool constraints)
246
+ const skill = await engine.addSkill({
247
+ name: 'daily-summary',
248
+ maxTurns: 3,
249
+ timeoutMs: 60000,
250
+ })
251
+
252
+ // Schedule a recurring cron job
253
+ await engine.addCronJob({
254
+ name: 'morning-briefing',
255
+ enabled: true,
256
+ sessionTarget: 'isolated',
257
+ schedule: { kind: 'every', everyMs: 86400000 }, // 24h
258
+ skillId: skill.id,
259
+ prompt: 'Summarize my workspace changes since yesterday',
260
+ deliveryMode: 'notification',
193
261
  })
194
262
  ```
195
263
 
196
264
  ## Features
197
265
 
266
+ - **Instant cold start** — agent loop runs in the WebView, worker tools proxied transparently
267
+ - **On-device vector memory** — store, recall, and search memories via [LanceDB](https://www.npmjs.com/package/capacitor-lancedb) with auto-recall context injection and deduplication
268
+ - **Background scheduling** — heartbeat check-ins and cron jobs via [MobileCron](https://www.npmjs.com/package/capacitor-mobilecron) (Android WorkManager / iOS BGTaskScheduler)
269
+ - **Cron jobs & skills** — recurring agent tasks with reusable skill definitions, run history, and delivery modes
198
270
  - **Real-time streaming** — text deltas, tool use, and thinking events
199
271
  - **Multi-turn conversations** — session persistence via native SQLite
200
272
  - **OAuth PKCE + API key** — sign in with Claude Max or use a direct API key
@@ -202,8 +274,9 @@ await engine.init({
202
274
  - **Code execution** — JavaScript (sandbox) + Python (Pyodide/WebAssembly)
203
275
  - **Git** — clone, commit, push, diff via isomorphic-git
204
276
  - **MCP device tools** — extensible via Model Context Protocol
205
- - **Tool approval gate** — approve/deny tool executions before they run
277
+ - **Tool approval gate** — approve/deny tool executions before they run (120s TTL)
206
278
  - **Agent steering** — inject follow-up instructions into a running turn
279
+ - **Vite plugin** — stubs Node.js-only transitive deps for browser bundling
207
280
 
208
281
  ## API Reference
209
282
 
@@ -211,18 +284,38 @@ await engine.init({
211
284
 
212
285
  | Method | Description |
213
286
  |--------|-------------|
214
- | `init(options?)` | Start the Node.js worker and MCP bridge |
287
+ | `init(options?)` | Start engine. Options: `useWebViewAgent`, `tools`, `mobileCron`, `enableBridge`, `enableStomp` |
215
288
  | `sendMessage(prompt, agentId?)` | Send a prompt to the agent |
216
289
  | `stopTurn()` | Cancel the running agent turn |
217
- | `approveTool(toolCallId, approved)` | Approve/deny a tool execution |
290
+ | `respondToPreExecute(toolCallId, args, deny?)` | Approve/deny a tool execution |
218
291
  | `steerAgent(text)` | Inject a follow-up instruction |
219
- | `updateConfig(config)` | Update worker config (auth, model, etc.) |
220
- | `getAuthStatus()` | Get current auth profile status |
221
- | `getModels()` | List available models |
292
+ | `updateConfig(config)` | Update config (auth, model, provider) |
293
+ | `exchangeOAuthCode(tokenUrl, body)` | OAuth token exchange via native HTTP |
294
+ | `getAuthStatus(provider?)` | Get current auth profile status |
295
+ | `getModels(provider?)` | List available models |
222
296
  | `readFile(path)` / `writeFile(path, content)` | Workspace file operations |
223
297
  | `listSessions()` / `resumeSession(key)` | Session management |
224
298
  | `invokeTool(toolName, args?)` | Call a tool directly |
225
- | `addListener(eventName, handler)` | Subscribe to agent events |
299
+ | `addListener(eventName, handler)` | Subscribe to events |
300
+
301
+ #### Scheduler & Heartbeat
302
+
303
+ | Method | Description |
304
+ |--------|-------------|
305
+ | `setSchedulerConfig(config)` | Set scheduler state (enabled, mode, runOnCharging, activeHours) |
306
+ | `getSchedulerConfig()` | Read scheduler + heartbeat config |
307
+ | `setHeartbeat(config)` | Configure heartbeat (enabled, interval, skillId, prompt) |
308
+ | `triggerHeartbeatWake(source?)` | Trigger immediate heartbeat (`manual` bypasses scheduler gate) |
309
+
310
+ #### Cron Jobs & Skills
311
+
312
+ | Method | Description |
313
+ |--------|-------------|
314
+ | `addCronJob(job)` / `updateCronJob(id, patch)` / `removeCronJob(id)` | CRUD for cron jobs |
315
+ | `listCronJobs()` / `runCronJob(id)` | List or manually trigger a job |
316
+ | `getCronRunHistory(jobId?, limit?)` | Get historical run records |
317
+ | `addSkill(skill)` / `updateSkill(id, patch)` / `removeSkill(id)` | CRUD for skills |
318
+ | `listSkills()` | List all defined skills |
226
319
 
227
320
  ### Events
228
321
 
@@ -231,8 +324,11 @@ await engine.init({
231
324
  | `agentEvent` | Text delta, tool use, tool result, or thinking update |
232
325
  | `agentCompleted` | Agent turn finished (includes token usage) |
233
326
  | `agentError` | Agent execution failed |
234
- | `toolApprovalRequest` | Agent wants to run a tool (approval gate) |
327
+ | `toolPreExecute` | Agent wants to run a tool (approval gate) |
235
328
  | `workerReady` | Node.js worker initialized |
329
+ | `heartbeatStarted` / `heartbeatCompleted` / `heartbeatSkipped` | Heartbeat lifecycle |
330
+ | `cronJobStarted` / `cronJobCompleted` / `cronJobError` | Cron job lifecycle |
331
+ | `schedulerStatus` | Scheduler state changed (next run times) |
236
332
 
237
333
  ## Documentation
238
334
 
@@ -243,6 +339,8 @@ await engine.init({
243
339
  ## Related Packages
244
340
 
245
341
  - [capacitor-mobile-claw-device-tools](https://www.npmjs.com/package/capacitor-mobile-claw-device-tools) — 64+ pre-built device tools (camera, clipboard, sensors, SSH, etc.)
342
+ - [capacitor-lancedb](https://www.npmjs.com/package/capacitor-lancedb) — on-device vector database for agent memory
343
+ - [capacitor-mobilecron](https://www.npmjs.com/package/capacitor-mobilecron) — native background scheduling (WorkManager / BGTaskScheduler)
246
344
 
247
345
  ## Contributing
248
346
 
@@ -257,11 +355,14 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, workflow, and guid
257
355
  | Embedded runtime | [@choreruiz/capacitor-node-js](https://github.com/rogelioRuiz/capacitor-node-js) |
258
356
  | Tool protocol | [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) |
259
357
  | LLM provider | [Anthropic Claude](https://anthropic.com/) |
358
+ | Vector memory | [LanceDB](https://lancedb.com/) via [capacitor-lancedb](https://www.npmjs.com/package/capacitor-lancedb) (Rust FFI, on-device) |
359
+ | Background scheduling | [capacitor-mobilecron](https://www.npmjs.com/package/capacitor-mobilecron) (WorkManager / BGTaskScheduler) |
260
360
  | Git | [isomorphic-git](https://isomorphic-git.org/) |
261
- | Database | [@capacitor-community/sqlite](https://github.com/nicepkg/capacitor-community-sqlite) (native SQLite via JSON-RPC bridge) |
361
+ | Database | [@capacitor-community/sqlite](https://github.com/nicepkg/capacitor-community-sqlite) (native SQLite) |
262
362
  | Python | [Pyodide](https://pyodide.org/) (CPython via WebAssembly) |
263
363
  | Type system | TypeScript (strict mode) |
264
- | Tests | [Vitest](https://vitest.dev/) |
364
+ | Lint | [Biome](https://biomejs.dev/) |
365
+ | Tests | [Vitest](https://vitest.dev/) (64 unit) + Sentinel E2E (111 on-device) |
265
366
 
266
367
  ## Acknowledgments
267
368
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-mobile-claw",
3
- "version": "1.6.3",
3
+ "version": "1.6.5",
4
4
  "description": "On-device AI agent engine for Capacitor apps — embedded Node.js worker with LLM, file tools, code execution, git, and extensible MCP server",
5
5
  "main": "dist/esm/index.js",
6
6
  "types": "dist/esm/index.d.ts",