feat: mount store rw for main agent and add requiresTrigger to register_group

- Mount store/ separately as read-write so the main agent can access
  the SQLite database directly.
- Add requiresTrigger parameter to the register_group MCP tool
  (host IPC already supported it, but the tool never exposed it).
  Defaults to false (no trigger).
- Update group registration instructions to ask user about trigger.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
gavrielc
2026-04-03 16:17:57 +03:00
parent e9db4d461d
commit 032ba77a7f
4 changed files with 27 additions and 8 deletions

View File

@@ -460,6 +460,12 @@ Use available_groups.json to find the JID for a group. The folder name must be c
'Channel-prefixed folder name (e.g., "whatsapp_family-chat", "telegram_dev-team")',
),
trigger: z.string().describe('Trigger word (e.g., "@Andy")'),
requiresTrigger: z
.boolean()
.optional()
.describe(
'Whether messages must start with the trigger word. Default: false (respond to all messages). Set to true for busy groups with many participants where you only want the agent to respond when explicitly mentioned.',
),
},
async (args) => {
if (!isMain) {
@@ -480,6 +486,7 @@ Use available_groups.json to find the JID for a group. The folder name must be c
name: args.name,
folder: args.folder,
trigger: args.trigger,
requiresTrigger: args.requiresTrigger ?? false,
timestamp: new Date().toISOString(),
};

View File

@@ -42,7 +42,7 @@ private_key, .secret
**Read-Only Project Root:**
The main group's project root is mounted read-only. Writable paths the agent needs (group folder, IPC, `.claude/`) are mounted separately. This prevents the agent from modifying host application code (`src/`, `dist/`, `package.json`, etc.) which would bypass the sandbox entirely on next restart.
The main group's project root is mounted read-only. Writable paths the agent needs (store, group folder, IPC, `.claude/`) are mounted separately. This prevents the agent from modifying host application code (`src/`, `dist/`, `package.json`, etc.) which would bypass the sandbox entirely on next restart. The `store/` directory is mounted read-write so the main agent can access the SQLite database directly.
### 3. Session Isolation
@@ -88,6 +88,7 @@ Each NanoClaw group gets its own OneCLI agent identity. This allows different cr
| Capability | Main Group | Non-Main Group |
|------------|------------|----------------|
| Project root access | `/workspace/project` (ro) | None |
| Store (SQLite DB) | `/workspace/project/store` (rw) | None |
| Group folder | `/workspace/group` (rw) | `/workspace/group` (rw) |
| Global memory | Implicit via project | `/workspace/global` (ro) |
| Additional mounts | Configurable | Read-only unless allowed |

View File

@@ -83,15 +83,16 @@ Anthropic credentials must be either an API key from console.anthropic.com (`ANT
## Container Mounts
Main has read-only access to the project and read-write access to its group folder:
Main has read-only access to the project, read-write access to the store (SQLite DB), and read-write access to its group folder:
| Container Path | Host Path | Access |
|----------------|-----------|--------|
| `/workspace/project` | Project root | read-only |
| `/workspace/project/store` | `store/` | read-write |
| `/workspace/group` | `groups/main/` | read-write |
Key paths inside the container:
- `/workspace/project/store/messages.db` - SQLite database
- `/workspace/project/store/messages.db` - SQLite database (read-write)
- `/workspace/project/store/messages.db` (registered_groups table) - Group config
- `/workspace/project/groups/` - All group folders
@@ -172,10 +173,11 @@ Fields:
### Adding a Group
1. Query the database to find the group's JID
2. Use the `register_group` MCP tool with the JID, name, folder, and trigger
3. Optionally include `containerConfig` for additional mounts
4. The group folder is created automatically: `/workspace/project/groups/{folder-name}/`
5. Optionally create an initial `CLAUDE.md` for the group
2. Ask the user whether the group should require a trigger word before registering
3. Use the `register_group` MCP tool with the JID, name, folder, trigger, and the chosen `requiresTrigger` setting
4. Optionally include `containerConfig` for additional mounts
5. The group folder is created automatically: `/workspace/project/groups/{folder-name}/`
6. Optionally create an initial `CLAUDE.md` for the group
Folder naming convention — channel prefix with underscore separator:
- WhatsApp "Family Chat" → `whatsapp_family-chat`

View File

@@ -68,7 +68,7 @@ function buildVolumeMounts(
if (isMain) {
// Main gets the project root read-only. Writable paths the agent needs
// (group folder, IPC, .claude/) are mounted separately below.
// (store, group folder, IPC, .claude/) are mounted separately below.
// Read-only prevents the agent from modifying host application code
// (src/, dist/, package.json, etc.) which would bypass the sandbox
// entirely on next restart.
@@ -89,6 +89,15 @@ function buildVolumeMounts(
});
}
// Main gets writable access to the store (SQLite DB) so it can
// query and write to the database directly.
const storeDir = path.join(projectRoot, 'store');
mounts.push({
hostPath: storeDir,
containerPath: '/workspace/project/store',
readonly: false,
});
// Main also gets its group folder as the working directory
mounts.push({
hostPath: groupDir,