fix: setup skill reliability, requiresTrigger option, agent-browser visibility

Setup skill fixes:
- Run QR auth in foreground with long timeout, not background
- Replace fragile message-based registration with DB group sync lookup
- Personal chats: ask for phone number instead of querying empty DB
- Consolidate trigger word + security model + channel selection into one step
- Remove `timeout` shell command (unavailable on macOS), use Bash tool timeout
- Query 40 groups, display 10 at a time, support name lookup

requiresTrigger support:
- Add requiresTrigger field to RegisteredGroup type and DB schema
- Skip trigger check when requiresTrigger is false (for solo/personal chats)
- Main group still always processes all messages (unchanged)

Agent-browser visibility:
- Append global CLAUDE.md to non-main agent system prompts via SDK
- Add browser tool docs to global and main CLAUDE.md
- Update skill description to be broader (not just "web testing")
- Reference agent-browser.md in root CLAUDE.md key files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
gavrielc
2026-02-07 01:39:31 +02:00
parent 675ed30ba0
commit f26468c9b0
9 changed files with 114 additions and 52 deletions

View File

@@ -78,6 +78,15 @@ export function initDatabase(): void {
/* column already exists */
}
// Add requires_trigger column if it doesn't exist (migration for existing DBs)
try {
db.exec(
`ALTER TABLE registered_groups ADD COLUMN requires_trigger INTEGER DEFAULT 1`,
);
} catch {
/* column already exists */
}
// State tables (replacing JSON files)
db.exec(`
CREATE TABLE IF NOT EXISTS router_state (
@@ -94,7 +103,8 @@ export function initDatabase(): void {
folder TEXT NOT NULL UNIQUE,
trigger_pattern TEXT NOT NULL,
added_at TEXT NOT NULL,
container_config TEXT
container_config TEXT,
requires_trigger INTEGER DEFAULT 1
);
`);
@@ -460,6 +470,7 @@ export function getRegisteredGroup(
trigger_pattern: string;
added_at: string;
container_config: string | null;
requires_trigger: number | null;
}
| undefined;
if (!row) return undefined;
@@ -472,6 +483,7 @@ export function getRegisteredGroup(
containerConfig: row.container_config
? JSON.parse(row.container_config)
: undefined,
requiresTrigger: row.requires_trigger === null ? undefined : row.requires_trigger === 1,
};
}
@@ -480,8 +492,8 @@ export function setRegisteredGroup(
group: RegisteredGroup,
): void {
db.prepare(
`INSERT OR REPLACE INTO registered_groups (jid, name, folder, trigger_pattern, added_at, container_config)
VALUES (?, ?, ?, ?, ?, ?)`,
`INSERT OR REPLACE INTO registered_groups (jid, name, folder, trigger_pattern, added_at, container_config, requires_trigger)
VALUES (?, ?, ?, ?, ?, ?, ?)`,
).run(
jid,
group.name,
@@ -489,6 +501,7 @@ export function setRegisteredGroup(
group.trigger,
group.added_at,
group.containerConfig ? JSON.stringify(group.containerConfig) : null,
group.requiresTrigger === undefined ? 1 : group.requiresTrigger ? 1 : 0,
);
}
@@ -502,6 +515,7 @@ export function getAllRegisteredGroups(): Record<string, RegisteredGroup> {
trigger_pattern: string;
added_at: string;
container_config: string | null;
requires_trigger: number | null;
}>;
const result: Record<string, RegisteredGroup> = {};
for (const row of rows) {
@@ -513,6 +527,7 @@ export function getAllRegisteredGroups(): Record<string, RegisteredGroup> {
containerConfig: row.container_config
? JSON.parse(row.container_config)
: undefined,
requiresTrigger: row.requires_trigger === null ? undefined : row.requires_trigger === 1,
};
}
return result;

View File

@@ -209,8 +209,8 @@ async function processGroupMessages(chatJid: string): Promise<boolean> {
if (missedMessages.length === 0) return true;
// For non-main groups, check if any message has the trigger
if (!isMainGroup) {
// For non-main groups, check if trigger is required and present
if (!isMainGroup && group.requiresTrigger !== false) {
const hasTrigger = missedMessages.some((m) =>
TRIGGER_PATTERN.test(m.content.trim()),
);

View File

@@ -38,6 +38,7 @@ export interface RegisteredGroup {
trigger: string;
added_at: string;
containerConfig?: ContainerConfig;
requiresTrigger?: boolean; // Default: true for groups, false for solo chats
}
export interface NewMessage {