fix: setup registration — use initDatabase/setRegisteredGroup, .ts imports, correct CLI commands

- setup/register.ts: replace inline DB logic with initDatabase() + setRegisteredGroup()
  (fixes missing is_main column on existing DBs, .js MODULE_NOT_FOUND with tsx)
- SKILL.md (telegram, slack, discord): replace broken registerGroup() pseudo-code
  with actual `npx tsx setup/index.ts --step register` commands
- docs/SPEC.md: fix registerGroup → setRegisteredGroup in example

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
gavrielc
2026-03-10 22:51:40 +02:00
parent d8a1ee8c3c
commit 04fb44e417
5 changed files with 31 additions and 94 deletions

View File

@@ -126,31 +126,18 @@ Wait for the user to provide the channel ID (format: `dc:1234567890123456`).
### Register the channel
Use the IPC register flow or register directly. The channel ID, name, and folder name are needed.
The channel ID, name, and folder name are needed. Use `npx tsx setup/index.ts --step register` with the appropriate flags.
For a main channel (responds to all messages):
```typescript
registerGroup("dc:<channel-id>", {
name: "<server-name> #<channel-name>",
folder: "discord_main",
trigger: `@${ASSISTANT_NAME}`,
added_at: new Date().toISOString(),
requiresTrigger: false,
isMain: true,
});
```bash
npx tsx setup/index.ts --step register -- --jid "dc:<channel-id>" --name "<server-name> #<channel-name>" --folder "discord_main" --trigger "@${ASSISTANT_NAME}" --channel discord --no-trigger-required --is-main
```
For additional channels (trigger-only):
```typescript
registerGroup("dc:<channel-id>", {
name: "<server-name> #<channel-name>",
folder: "discord_<channel-name>",
trigger: `@${ASSISTANT_NAME}`,
added_at: new Date().toISOString(),
requiresTrigger: true,
});
```bash
npx tsx setup/index.ts --step register -- --jid "dc:<channel-id>" --name "<server-name> #<channel-name>" --folder "discord_<channel-name>" --trigger "@${ASSISTANT_NAME}" --channel discord
```
## Phase 5: Verify

View File

@@ -114,31 +114,18 @@ Wait for the user to provide the channel ID.
### Register the channel
Use the IPC register flow or register directly. The channel ID, name, and folder name are needed.
The channel ID, name, and folder name are needed. Use `npx tsx setup/index.ts --step register` with the appropriate flags.
For a main channel (responds to all messages):
```typescript
registerGroup("slack:<channel-id>", {
name: "<channel-name>",
folder: "slack_main",
trigger: `@${ASSISTANT_NAME}`,
added_at: new Date().toISOString(),
requiresTrigger: false,
isMain: true,
});
```bash
npx tsx setup/index.ts --step register -- --jid "slack:<channel-id>" --name "<channel-name>" --folder "slack_main" --trigger "@${ASSISTANT_NAME}" --channel slack --no-trigger-required --is-main
```
For additional channels (trigger-only):
```typescript
registerGroup("slack:<channel-id>", {
name: "<channel-name>",
folder: "slack_<channel-name>",
trigger: `@${ASSISTANT_NAME}`,
added_at: new Date().toISOString(),
requiresTrigger: true,
});
```bash
npx tsx setup/index.ts --step register -- --jid "slack:<channel-id>" --name "<channel-name>" --folder "slack_<channel-name>" --trigger "@${ASSISTANT_NAME}" --channel slack
```
## Phase 5: Verify

View File

@@ -129,31 +129,18 @@ Wait for the user to provide the chat ID (format: `tg:123456789` or `tg:-1001234
### Register the chat
Use the IPC register flow or register directly. The chat ID, name, and folder name are needed.
The chat ID, name, and folder name are needed. Use `npx tsx setup/index.ts --step register` with the appropriate flags.
For a main chat (responds to all messages):
```typescript
registerGroup("tg:<chat-id>", {
name: "<chat-name>",
folder: "telegram_main",
trigger: `@${ASSISTANT_NAME}`,
added_at: new Date().toISOString(),
requiresTrigger: false,
isMain: true,
});
```bash
npx tsx setup/index.ts --step register -- --jid "tg:<chat-id>" --name "<chat-name>" --folder "telegram_main" --trigger "@${ASSISTANT_NAME}" --channel telegram --no-trigger-required --is-main
```
For additional chats (trigger-only):
```typescript
registerGroup("tg:<chat-id>", {
name: "<chat-name>",
folder: "telegram_<group-name>",
trigger: `@${ASSISTANT_NAME}`,
added_at: new Date().toISOString(),
requiresTrigger: true,
});
```bash
npx tsx setup/index.ts --step register -- --jid "tg:<chat-id>" --name "<chat-name>" --folder "telegram_<group-name>" --trigger "@${ASSISTANT_NAME}" --channel telegram
```
## Phase 5: Verify

View File

@@ -358,7 +358,7 @@ export const TRIGGER_PATTERN = new RegExp(`^@${ASSISTANT_NAME}\\b`, 'i');
Groups can have additional directories mounted via `containerConfig` in the SQLite `registered_groups` table (stored as JSON in the `container_config` column). Example registration:
```typescript
registerGroup("1234567890@g.us", {
setRegisteredGroup("1234567890@g.us", {
name: "Dev Team",
folder: "whatsapp_dev-team",
trigger: "@Andy",

View File

@@ -7,12 +7,11 @@
import fs from 'fs';
import path from 'path';
import Database from 'better-sqlite3';
import { STORE_DIR } from '../src/config.js';
import { isValidGroupFolder } from '../src/group-folder.js';
import { logger } from '../src/logger.js';
import { emitStatus } from './status.js';
import { STORE_DIR } from '../src/config.ts';
import { initDatabase, setRegisteredGroup } from '../src/db.ts';
import { isValidGroupFolder } from '../src/group-folder.ts';
import { logger } from '../src/logger.ts';
import { emitStatus } from './status.ts';
interface RegisterArgs {
jid: string;
@@ -98,41 +97,18 @@ export async function run(args: string[]): Promise<void> {
fs.mkdirSync(path.join(projectRoot, 'data'), { recursive: true });
fs.mkdirSync(STORE_DIR, { recursive: true });
// Write to SQLite using parameterized queries (no SQL injection)
const dbPath = path.join(STORE_DIR, 'messages.db');
const timestamp = new Date().toISOString();
const requiresTriggerInt = parsed.requiresTrigger ? 1 : 0;
// Initialize database (creates schema + runs migrations)
initDatabase();
const db = new Database(dbPath);
// Ensure schema exists
db.exec(`CREATE TABLE IF NOT EXISTS registered_groups (
jid TEXT PRIMARY KEY,
name TEXT NOT NULL,
folder TEXT NOT NULL UNIQUE,
trigger_pattern TEXT NOT NULL,
added_at TEXT NOT NULL,
container_config TEXT,
requires_trigger INTEGER DEFAULT 1,
is_main INTEGER DEFAULT 0
)`);
setRegisteredGroup(parsed.jid, {
name: parsed.name,
folder: parsed.folder,
trigger: parsed.trigger,
added_at: new Date().toISOString(),
requiresTrigger: parsed.requiresTrigger,
isMain: parsed.isMain,
});
const isMainInt = parsed.isMain ? 1 : 0;
db.prepare(
`INSERT OR REPLACE INTO registered_groups
(jid, name, folder, trigger_pattern, added_at, container_config, requires_trigger, is_main)
VALUES (?, ?, ?, ?, ?, NULL, ?, ?)`,
).run(
parsed.jid,
parsed.name,
parsed.folder,
parsed.trigger,
timestamp,
requiresTriggerInt,
isMainInt,
);
db.close();
logger.info('Wrote registration to SQLite');
// Create group folders