@rubytech/taskmaster 1.2.0 → 1.3.0

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 (67) hide show
  1. package/dist/agents/auth-profiles/profiles.js +37 -0
  2. package/dist/agents/auth-profiles.js +1 -1
  3. package/dist/agents/pi-tools.policy.js +4 -1
  4. package/dist/agents/sandbox/constants.js +0 -1
  5. package/dist/agents/system-prompt.js +1 -4
  6. package/dist/agents/taskmaster-tools.js +14 -6
  7. package/dist/agents/tool-policy.js +5 -5
  8. package/dist/agents/tools/apikeys-tool.js +16 -5
  9. package/dist/agents/tools/contact-create-tool.js +59 -0
  10. package/dist/agents/tools/contact-delete-tool.js +48 -0
  11. package/dist/agents/tools/contact-update-tool.js +17 -2
  12. package/dist/agents/tools/file-delete-tool.js +137 -0
  13. package/dist/agents/tools/file-list-tool.js +127 -0
  14. package/dist/auto-reply/reply/commands-tts.js +7 -2
  15. package/dist/build-info.json +3 -3
  16. package/dist/cli/provision-seed.js +1 -3
  17. package/dist/commands/doctor-config-flow.js +13 -0
  18. package/dist/config/agent-tools-reconcile.js +53 -0
  19. package/dist/config/defaults.js +10 -1
  20. package/dist/config/legacy.migrations.part-3.js +26 -0
  21. package/dist/config/zod-schema.core.js +9 -1
  22. package/dist/config/zod-schema.js +1 -0
  23. package/dist/control-ui/assets/index-CPawOl_z.css +1 -0
  24. package/dist/control-ui/assets/{index-DwMopZij.js → index-DQ1kxYd4.js} +693 -598
  25. package/dist/control-ui/assets/index-DQ1kxYd4.js.map +1 -0
  26. package/dist/control-ui/index.html +2 -2
  27. package/dist/gateway/chat-sanitize.js +16 -2
  28. package/dist/gateway/config-reload.js +1 -0
  29. package/dist/gateway/media-http.js +32 -1
  30. package/dist/gateway/server-methods/apikeys.js +56 -4
  31. package/dist/gateway/server-methods/tts.js +11 -2
  32. package/dist/gateway/server.impl.js +15 -0
  33. package/dist/media-understanding/apply.js +35 -0
  34. package/dist/media-understanding/providers/deepgram/audio.js +1 -1
  35. package/dist/media-understanding/providers/google/audio.js +1 -1
  36. package/dist/media-understanding/providers/google/video.js +1 -1
  37. package/dist/media-understanding/providers/index.js +2 -0
  38. package/dist/media-understanding/providers/openai/audio.js +1 -1
  39. package/dist/media-understanding/providers/sherpa-onnx/index.js +10 -0
  40. package/dist/media-understanding/runner.js +61 -72
  41. package/dist/media-understanding/sherpa-onnx-local.js +223 -0
  42. package/dist/records/records-manager.js +10 -0
  43. package/dist/tts/tts.js +98 -10
  44. package/dist/web/auto-reply/monitor/process-message.js +1 -0
  45. package/dist/web/inbound/monitor.js +9 -1
  46. package/extensions/googlechat/node_modules/.bin/taskmaster +2 -2
  47. package/extensions/googlechat/package.json +2 -2
  48. package/extensions/line/node_modules/.bin/taskmaster +2 -2
  49. package/extensions/line/package.json +1 -1
  50. package/extensions/matrix/node_modules/.bin/taskmaster +2 -2
  51. package/extensions/matrix/package.json +1 -1
  52. package/extensions/msteams/node_modules/.bin/taskmaster +2 -2
  53. package/extensions/msteams/package.json +1 -1
  54. package/extensions/nostr/node_modules/.bin/taskmaster +2 -2
  55. package/extensions/nostr/package.json +1 -1
  56. package/extensions/zalo/node_modules/.bin/taskmaster +2 -2
  57. package/extensions/zalo/package.json +1 -1
  58. package/extensions/zalouser/node_modules/.bin/taskmaster +2 -2
  59. package/extensions/zalouser/package.json +1 -1
  60. package/package.json +3 -2
  61. package/scripts/postinstall.js +76 -0
  62. package/skills/business-assistant/references/crm.md +32 -8
  63. package/taskmaster-docs/USER-GUIDE.md +84 -5
  64. package/templates/beagle/agents/admin/AGENTS.md +4 -2
  65. package/templates/taskmaster/agents/admin/AGENTS.md +1 -0
  66. package/dist/control-ui/assets/index-DvB85yTz.css +0 -1
  67. package/dist/control-ui/assets/index-DwMopZij.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/taskmaster",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "AI-powered business assistant for small businesses",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -195,7 +195,8 @@
195
195
  },
196
196
  "optionalDependencies": {
197
197
  "@napi-rs/canvas": "^0.1.88",
198
- "node-llama-cpp": "3.15.0"
198
+ "node-llama-cpp": "3.15.0",
199
+ "sherpa-onnx-node": "^1.12.26"
199
200
  },
200
201
  "devDependencies": {
201
202
  "@grammyjs/types": "^3.23.0",
@@ -311,6 +311,81 @@ function ensurePlatformDeps() {
311
311
  }
312
312
  }
313
313
 
314
+ /**
315
+ * Download the sherpa-onnx speech recognition model for offline voice note
316
+ * transcription. Runs on global installs (deployed devices) and dev setups
317
+ * where sherpa-onnx-node is available. The model is platform-independent;
318
+ * only the native bindings (installed via npm optionalDeps) are platform-specific.
319
+ */
320
+ function ensureSherpaOnnxModel() {
321
+ const homeDir = process.env.HOME || process.env.USERPROFILE || "";
322
+ if (!homeDir) return;
323
+
324
+ const libDir = path.join(homeDir, ".taskmaster", "lib", "sherpa-onnx");
325
+ const modelDir = path.join(libDir, "nemo-ctc-en-conformer-small");
326
+ const modelFile = path.join(modelDir, "model.int8.onnx");
327
+ const tokensFile = path.join(modelDir, "tokens.txt");
328
+
329
+ // Already downloaded — nothing to do
330
+ if (fs.existsSync(modelFile) && fs.existsSync(tokensFile)) return;
331
+
332
+ // Only download if sherpa-onnx-node is installed (optional dep)
333
+ try {
334
+ const repoRoot = getRepoRoot();
335
+ const sherpaEntry = path.join(repoRoot, "node_modules", "sherpa-onnx-node");
336
+ if (!fs.existsSync(sherpaEntry)) return;
337
+ } catch {
338
+ return;
339
+ }
340
+
341
+ // Check that curl and tar are available (always true on macOS/Linux)
342
+ const hasCurl = spawnSync("curl", ["--version"], { stdio: "ignore" }).status === 0;
343
+ const hasTar = spawnSync("tar", ["--version"], { stdio: "ignore" }).status === 0;
344
+ if (!hasCurl || !hasTar) return;
345
+
346
+ const archiveUrl =
347
+ "https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-nemo-ctc-en-conformer-small.tar.bz2";
348
+ const archiveName = "nemo-ctc-en-conformer-small.tar.bz2";
349
+ const archivePath = path.join(libDir, archiveName);
350
+ const extractedDir = path.join(libDir, "sherpa-onnx-nemo-ctc-en-conformer-small");
351
+
352
+ console.log("[postinstall] Downloading sherpa-onnx speech recognition model…");
353
+ fs.mkdirSync(libDir, { recursive: true });
354
+
355
+ const curl = spawnSync("curl", ["-fsSL", "-o", archivePath, archiveUrl], {
356
+ stdio: "inherit",
357
+ timeout: 300_000,
358
+ });
359
+ if (curl.status !== 0) {
360
+ console.warn("[postinstall] sherpa-onnx model download failed (voice notes will use cloud STT)");
361
+ try { fs.unlinkSync(archivePath); } catch {}
362
+ return;
363
+ }
364
+
365
+ const tar = spawnSync("tar", ["-xjf", archivePath, "-C", libDir], {
366
+ stdio: "inherit",
367
+ timeout: 120_000,
368
+ });
369
+ if (tar.status !== 0) {
370
+ console.warn("[postinstall] sherpa-onnx model extraction failed (voice notes will use cloud STT)");
371
+ try { fs.unlinkSync(archivePath); } catch {}
372
+ return;
373
+ }
374
+
375
+ // Rename extracted directory (strip sherpa-onnx- prefix)
376
+ if (fs.existsSync(extractedDir) && extractedDir !== modelDir) {
377
+ try { fs.rmSync(modelDir, { recursive: true, force: true }); } catch {}
378
+ fs.renameSync(extractedDir, modelDir);
379
+ }
380
+
381
+ // Clean up: archive, full-precision model (keep int8), test wavs
382
+ try { fs.unlinkSync(archivePath); } catch {}
383
+ try { fs.unlinkSync(path.join(modelDir, "model.onnx")); } catch {}
384
+ try { fs.rmSync(path.join(modelDir, "test_wavs"), { recursive: true, force: true }); } catch {}
385
+
386
+ console.log("[postinstall] sherpa-onnx model installed (offline voice note transcription)");
387
+ }
388
+
314
389
  function main() {
315
390
  const repoRoot = getRepoRoot();
316
391
  process.chdir(repoRoot);
@@ -318,6 +393,7 @@ function main() {
318
393
  ensureExecutable(path.join(repoRoot, "dist", "entry.js"));
319
394
  setupGitHooks({ repoRoot });
320
395
  ensurePlatformDeps();
396
+ ensureSherpaOnnxModel();
321
397
 
322
398
  if (!shouldApplyPnpmPatchedDependenciesFallback()) {
323
399
  return;
@@ -1,9 +1,33 @@
1
1
  # Customer Records (CRM)
2
2
 
3
+ ## Contacts as Source of Truth
4
+
5
+ The **contact record** is the highest-level directory for every customer relationship. Its phone number and name are the canonical identifiers — all user-scoped data (memory profiles, conversations, documents, events) hangs off the contact via the phone number.
6
+
7
+ | Concept | What it is | Storage |
8
+ |---------|-----------|---------|
9
+ | **Contact record** | Structured directory entry (phone, name, pipeline status, address) | `~/.taskmaster/records.json` via `contact_*` tools |
10
+ | **User memory** | Freeform narrative, conversation history, media, documents | `memory/users/{phone}/` via `memory_*` tools |
11
+
12
+ The contact record determines the relationship. User memory provides the detail. A memory profile without a contact record is orphaned data. A contact record without memory is a directory entry awaiting context.
13
+
3
14
  ## Tools
4
15
 
5
- - `contact_lookup` Search by phone number or name. Use before every customer interaction.
6
- - `contact_update` — Update record fields. Use after every meaningful event.
16
+ | Tool | Access | Purpose |
17
+ |------|--------|---------|
18
+ | `contact_create` | Admin only | Create a new contact record (phone + name + optional fields) |
19
+ | `contact_lookup` | All agents | Search by phone number or name. Use before every customer interaction |
20
+ | `contact_update` | Admin only | Update record fields or rename a contact. Use after every meaningful event |
21
+ | `contact_delete` | Admin only | Remove a contact record. Does not delete user memory |
22
+
23
+ ### Creating a Contact Record vs Creating User Memory
24
+
25
+ These are distinct operations:
26
+
27
+ - **`contact_create`** — Creates a structured directory entry in the secure records store. Use when you have a name and phone number for a new customer.
28
+ - **`memory_write` to `memory/users/{phone}/profile.md`** — Creates or updates the freeform narrative profile. Use to store context, personality, preferences, and history.
29
+
30
+ On first meaningful interaction, do **both**: create the contact record, then write an initial memory profile.
7
31
 
8
32
  ## When to Create a Record
9
33
 
@@ -26,7 +50,7 @@ Update the contact record after every event that changes the customer's status o
26
50
 
27
51
  | Field | Description | Example |
28
52
  |-------|-------------|---------|
29
- | `name` | Full name | `Mrs Sarah Jenkins` |
53
+ | `name` | Full name (set via `contact_create`, update via `contact_update` with field `name`) | `Mrs Sarah Jenkins` |
30
54
  | `status` | Pipeline stage | `enquiry`, `quoted`, `booked`, `completed`, `invoiced`, `paid`, `archived` |
31
55
  | `address` | Full postal address | `42 Oak Lane, Stansted, CM23 4AB` |
32
56
  | `postcode` | Extracted postcode (for geographic clustering) | `CM23 4AB` |
@@ -53,15 +77,15 @@ enquiry → quoted → booked → completed → invoiced → paid
53
77
 
54
78
  Update the status at each transition. This enables the business owner to see their pipeline at a glance.
55
79
 
56
- ## Memory vs Records
80
+ ## Contact Records vs User Memory
57
81
 
58
82
  Contact records and memory serve different purposes. Use both.
59
83
 
60
- | | Contact Records | Memory |
84
+ | | Contact Records | User Memory |
61
85
  |---|---|---|
62
- | **Store** | `contact_lookup` / `contact_update` | `memory/users/{phone}/profile.md` |
86
+ | **Store** | `contact_create` / `contact_update` / `contact_lookup` | `memory/users/{phone}/profile.md` |
63
87
  | **Structure** | Key-value fields (name, status, address, etc.) | Freeform narrative |
64
- | **Purpose** | Pipeline tracking, structured queries | Context, personality, history |
88
+ | **Purpose** | Directory entry, pipeline tracking, structured queries | Context, personality, history |
65
89
  | **Example** | `status: invoiced`, `postcode: CM23 4AB` | "Mrs Jenkins is elderly, lives alone, prefers morning appointments. She had a boiler service last month and was very happy with the work." |
66
90
 
67
91
  When searching for a customer, check **both**: `contact_lookup` for structured data, `memory_search` for context.
@@ -72,6 +96,6 @@ Customer documents are filed at `memory/users/{phone}/documents/`. The phone num
72
96
 
73
97
  When creating documents for a customer, always:
74
98
  1. Verify the contact record exists (`contact_lookup`)
75
- 2. Create or update the record if needed (`contact_update`)
99
+ 2. Create the record if needed (`contact_create`) or update it (`contact_update`)
76
100
  3. File the document in the correct path
77
101
  4. Update the contact record status
@@ -171,6 +171,8 @@ The very first time you open the dashboard, you'll be asked to **set a PIN** (4-
171
171
 
172
172
  When you return, a login screen asks for your PIN. If you have multiple accounts, pick the account you want to operate on from the dropdown and enter the account PIN (this is different to the admin PIN). If you log into the admin account, you have access to all the other registered accounts.
173
173
 
174
+ Each PIN field has an **eye icon** on the right — tap it to reveal the PIN digits so you can check what you've typed. Tap again to hide them.
175
+
174
176
  ### Account PINs
175
177
 
176
178
  If you share your device with other people (e.g. a business partner who manages a different account), each account can have its own PIN:
@@ -238,6 +240,15 @@ You can send files to your assistant by dragging and dropping them onto the chat
238
240
 
239
241
  **Via WhatsApp** you can also send **voice notes** and **videos** — these are automatically transcribed or analysed before your assistant sees them (see "Voice Notes & Video" below).
240
242
 
243
+ ### Voice Notes (Chat Page)
244
+
245
+ You can record and send voice notes directly from the Chat page. When the message box is empty, a microphone button appears in place of the send button.
246
+
247
+ - **Tap** the microphone to start recording. A recording indicator with a timer appears. Tap the **send button** to send, or the **trash button** to discard.
248
+ - **Press and hold** the microphone to record hands-free. Release to send automatically, or slide left to cancel.
249
+
250
+ Your assistant transcribes the voice note and responds to the content, the same as a WhatsApp voice note.
251
+
241
252
  ### Sending Messages While the Assistant is Working
242
253
 
243
254
  If your assistant is busy thinking, you can still type and send more messages. They appear immediately in the chat as normal messages and are delivered to your assistant in order once it finishes its current task.
@@ -289,12 +300,16 @@ The Files page shows a **status indicator** next to the Re-index button — a gr
289
300
  | Search knowledge | Find information across all your business files and notes |
290
301
  | Read files | Open and read any file in your workspace |
291
302
  | Write and update files | Create new notes, update existing files, or reorganise content |
303
+ | List files and folders | Browse what's in any workspace directory |
304
+ | Delete files and folders | Remove files or folders you no longer need (protected paths like agents/ cannot be deleted) |
292
305
  | Save photos | Store images to customer folders or your workspace |
293
306
 
294
307
  **Try asking:**
295
308
  - "What's our pricing for a full bathroom refit?"
296
309
  - "Save a note that Mrs. Jones prefers morning appointments"
297
310
  - "What do we know about the customer on +44 7700 900123?"
311
+ - "List what's in memory/users"
312
+ - "Delete the file memory/public/old-pricelist.md"
298
313
 
299
314
  ### Web Search
300
315
 
@@ -310,6 +325,21 @@ Your assistant can search the web and read web pages to find information for you
310
325
  - "What are the opening hours for Travis Perkins in Bromley?"
311
326
  - "Read this page and summarise it: https://example.com/article"
312
327
 
328
+ ### Weather
329
+
330
+ Your assistant can check the weather for any location — current conditions, forecasts, humidity, wind, and more. No API key is needed.
331
+
332
+ | Capability | Description |
333
+ |------------|-------------|
334
+ | Current conditions | Temperature, weather conditions, humidity, and wind speed for any city |
335
+ | Forecasts | Multi-day weather forecasts for planning ahead |
336
+ | Any location | Look up weather by city name, airport code, or coordinates |
337
+
338
+ **Try asking:**
339
+ - "What's the weather like in London?"
340
+ - "Will it rain tomorrow in Manchester?"
341
+ - "What's the forecast for this week?"
342
+
313
343
  ### Images & Documents
314
344
 
315
345
  Your assistant can analyse photos you send it and read common document formats.
@@ -354,7 +384,7 @@ When someone sends a voice note, image, or video, your assistant processes it au
354
384
  | Images | Automatically described — your assistant sees what's in the picture |
355
385
  | Video | Key frames extracted and described — your assistant understands the content |
356
386
 
357
- Voice note transcription and video analysis require a Google AI (Gemini) API key (see API Keys below). Image analysis uses your Claude connection directly — no extra key needed.
387
+ Voice note transcription works out of the box — Taskmaster includes a built-in offline speech recognition model that runs locally on your device with no API key required. For higher accuracy or video analysis, add a Google AI (Gemini) API key (see API Keys below). Image analysis uses your Claude connection directly — no extra key needed.
358
388
 
359
389
  ### Customer Records
360
390
 
@@ -466,6 +496,23 @@ Your assistant can open and interact with websites in a built-in browser — fil
466
496
 
467
497
  > **Tip:** Keep the Browser page open while your assistant browses — you can see exactly what it's doing and step in if a site asks for a CAPTCHA or login.
468
498
 
499
+ ### Business Idea Validation
500
+
501
+ Thinking about a new product, service, or direction for your business? Your assistant can walk you through the process of validating the idea before you invest time and money — from initial concept through customer discovery and assumption testing to a clear product brief.
502
+
503
+ | Phase | What happens |
504
+ |-------|-------------|
505
+ | Discovery | Clarify your idea, define your target customer, plan customer conversations, and assess the market |
506
+ | Validation | Identify the riskiest assumptions in your idea and design quick tests to check them |
507
+ | Product brief | Turn the validated concept into a clear document — problem, audience, features, success metrics, and next steps |
508
+
509
+ Your assistant guides you through each phase conversationally — you don't need to know any frameworks or jargon. Just describe your idea and it will ask the right questions.
510
+
511
+ **Try asking:**
512
+ - "I have an idea for a new service — can you help me think it through?"
513
+ - "Help me validate whether this product idea is worth pursuing"
514
+ - "I want to write a product brief for a new offering"
515
+
469
516
  ---
470
517
 
471
518
  ### API Keys
@@ -496,16 +543,17 @@ Additional keys for advanced use cases:
496
543
  |----------|----------------|------------|
497
544
  | **Brave** | Web search — alternative to Tavily | Yes (free plan available) |
498
545
  | **OpenAI** | Voice note transcription, alternative AI models | No |
499
- | **ElevenLabs** | Text-to-speech (for future voice features) | Yes (limited free tier) |
546
+ | **ElevenLabs** | Text-to-speech voice replies | Yes (limited free tier) |
500
547
  | **Replicate** | Image and media AI models | No |
501
- | **Hume** | Voice and emotion AI | No |
548
+ | **Hume** | Text-to-speech voice replies (expressive voice) | Yes |
502
549
 
503
550
  #### Managing Keys
504
551
 
505
552
  1. Go to the **Setup** page
506
553
  2. Click on the **API Keys** row in the status dashboard
507
554
  3. Enter a key next to any provider and click **Save**
508
- 4. To remove a key, click **Remove** next to it
555
+ 4. To temporarily turn off a key without losing it, click the **power icon** next to it — the row dims and the key stops being used. Click the power icon again to re-enable it.
556
+ 5. To permanently remove a key, click the **trash icon** next to it
509
557
 
510
558
  #### Recommended Free Keys
511
559
 
@@ -533,7 +581,7 @@ You get 1,000 free search credits per month — more than enough for daily busin
533
581
  4. **Copy the key** (it starts with `AIza`)
534
582
  5. Go to your Taskmaster **Setup** page, click the **API Keys** row, find **Google**, paste the key, and click **Save**
535
583
 
536
- The free tier works for low-volume use (a handful of voice notes or images per day). For higher volumes, you'll need to enable billing in your Google Cloud account — see [Google AI pricing](https://ai.google.dev/pricing) for details.
584
+ Voice notes work without this key (using the built-in offline model), but adding a Google key enables higher-accuracy cloud transcription and video analysis. The free tier works for low-volume use (a handful of voice notes or images per day). For higher volumes, you'll need to enable billing in your Google Cloud account — see [Google AI pricing](https://ai.google.dev/pricing) for details.
537
585
 
538
586
  ---
539
587
 
@@ -1381,6 +1429,31 @@ You can control your assistant's behaviour by typing slash commands in any conve
1381
1429
  | `/activation always` | Make the assistant respond to every group message (not just @mentions) |
1382
1430
  | `/activation mention` | Make the assistant only respond when @mentioned in groups |
1383
1431
 
1432
+ ### Voice replies (Text-to-Speech)
1433
+
1434
+ Your assistant can reply with voice notes instead of text. Two providers are available out of the box:
1435
+
1436
+ | Provider | Requires API key? | Notes |
1437
+ |----------|------------------|-------|
1438
+ | **Edge** (Microsoft) | No — free, works immediately | Good quality neural voices, many languages |
1439
+ | **Hume** | Yes — add in Setup > API Keys | Expressive, emotionally-aware voice (Octave TTS) |
1440
+
1441
+ Voice replies are controlled with the `/tts` command:
1442
+
1443
+ | Command | What it does |
1444
+ |---------|-------------|
1445
+ | `/tts` | Show current TTS status and available providers |
1446
+ | `/tts always` | Every reply is sent as a voice note |
1447
+ | `/tts inbound` | Reply with voice only when you send a voice note |
1448
+ | `/tts off` | Turn off voice replies |
1449
+ | `/tts provider edge` | Use Microsoft Edge TTS (free, no key needed) |
1450
+ | `/tts provider hume` | Use Hume Octave TTS (requires Hume API key) |
1451
+ | `/tts status` | Show current mode, provider, and fallback chain |
1452
+
1453
+ **How it works:** When TTS is enabled, the assistant writes its reply as normal text, and the system automatically converts it to a voice note before sending. If the selected provider fails (e.g. missing API key), it falls back to the next available provider. Emojis are automatically stripped so they don't get read aloud.
1454
+
1455
+ **Quick start:** Just type `/tts always` — Edge TTS will work immediately with no setup. To upgrade to Hume's expressive voice, add a Hume API key in the Control Panel and type `/tts provider hume`.
1456
+
1384
1457
  ### Examples
1385
1458
 
1386
1459
  > **You:** `/filler`
@@ -1392,6 +1465,12 @@ You can control your assistant's behaviour by typing slash commands in any conve
1392
1465
  > **You:** `/think high`
1393
1466
  > **System:** Thinking level set to high.
1394
1467
 
1468
+ > **You:** `/tts always`
1469
+ > **System:** TTS mode set to always.
1470
+
1471
+ > **You:** `/tts provider hume`
1472
+ > **System:** TTS provider set to hume (fallbacks: edge).
1473
+
1395
1474
  ---
1396
1475
 
1397
1476
  ## Groups
@@ -80,11 +80,13 @@ stripe refunds create --payment-intent {pi_id}
80
80
 
81
81
  ## Customer Record Management
82
82
 
83
- You have write access to customer records (`contact_update`). Use this for:
83
+ You have full access to customer records (`contact_create`, `contact_update`, `contact_delete`). Use this for:
84
+ - Creating contact records on first meaningful interaction
84
85
  - Updating trust scores after job completion
85
86
  - Setting blacklist status after fee escalation
86
87
  - Reinstating customers after payment
87
88
  - Recording provider opt-out/opt-in
89
+ - Deleting records for data erasure requests
88
90
 
89
91
  The public agent (Beagle) can read records but cannot modify them — this prevents prompt injection from changing payment status.
90
92
 
@@ -93,7 +95,7 @@ The public agent (Beagle) can read records but cannot modify them — this preve
93
95
  ## Data Compliance (Admin-Side Execution)
94
96
 
95
97
  When the Beagle agent receives a data erasure request, you execute the deletion sequence:
96
- 1. Delete the customer record (`contact_update` with DELETE)
98
+ 1. Delete the customer record (`contact_delete`)
97
99
  2. Clear the memory profile
98
100
  3. Redact booking files (replace customer phone/name with [REDACTED])
99
101
  4. Delete member files from booking groups
@@ -106,6 +106,7 @@ You have tool access within your workspace:
106
106
  - Session management
107
107
  - Config commands
108
108
  - File system access (within workspace)
109
+ - **Contact management** — `contact_create`, `contact_lookup`, `contact_update`, `contact_delete` (see skill reference `references/crm.md`)
109
110
  - **Document reading** — use `document_read` to extract text from PDFs, DOCX, XLSX, PPTX files
110
111
  - **Message relay** — use `relay_message` to inject a missed WhatsApp message into the public agent's session (see below)
111
112