// Action registry — defines all available actions, their parameters, and policies. // policy: "auto-accept" | "auto-deny" | "queue" import { resolve_path, exec } from './helpers.mjs'; import { check_can_approve } from './auth.mjs'; export const actions = { "list-actions": { description: "List all available actions and their definitions", params: [], policy: "auto-accept", handler: () => { return Object.entries(actions).map(([name, def]) => ({ action: name, description: def.description, params: def.params, policy: def.policy, })); }, }, "edit-file": { description: "Open a file in the editor", params: [{ name: "filename", required: true, type: "path" }], policy: "auto-accept", handler: ({ filename }) => { const resolved = resolve_path(filename); exec('subl3', [resolved]); return { opened: resolved }; }, }, /* "open-directory": { description: "Open a directory in the file manager", params: [{ name: "path", required: true, type: "path" }], policy: 'queue', handler: ({ path }) => { const resolved = resolve_path(path); // exec( ... ); return { opened: resolved }; }, }, */ "open-browser": { description: "Open a URL in the web browser", params: [{ name: "url", required: true, type: "string" }], policy: "queue", handler: ({ url }) => { const parsed = new URL(url); if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') { throw new Error(`Disallowed protocol: ${parsed.protocol}`); } exec('xdg-open', [parsed.href]); return { opened: parsed.href }; }, }, "open-terminal": { description: "Open a terminal in a given directory", params: [{ name: "path", required: false, type: "path" }], policy: 'queue', handler: ({ path }) => { const resolved = resolve_path(path ?? 'workspace'); exec('konsole', ['--workdir', resolved, '-e', 'bash']); return { opened: resolved }; }, }, 'send-email': { description: 'Send an email to a permitted recipient', params: [ { name: 'to', required: true, type: 'string' }, { name: 'subject', required: true, type: 'string' }, { name: 'body', required: true, type: 'string' }, { name: 'topic', required: true, type: 'string' }, ], policy: 'auto-accept', handler: async ({ to, subject, body, topic }, { caller, mail_perm_store, mailer_send }) => { if (!mail_perm_store.check(caller, to, topic)) { throw new Error(`Mail permission denied: ${caller} → ${to} [${topic}]`); } await mailer_send(to, subject, body); return { sent: true, to, topic }; }, }, 'set-mail-permission': { description: 'Grant or revoke permission for a user to send email to a recipient/topic', params: [ { name: 'target_user', required: true, type: 'string' }, { name: 'to', required: true, type: 'string' }, { name: 'topic', required: true, type: 'string' }, { name: 'allow', required: true, type: 'boolean' }, ], policy: 'auto-accept', handler: ({ target_user, to, topic, allow }, { caller, users, mail_perm_store }) => { if (!check_can_approve(users, caller, target_user)) { throw new Error(`Not authorized to set mail permissions for '${target_user}'`); } if (allow) { mail_perm_store.add(target_user, to, topic); } else { mail_perm_store.remove(target_user, to, topic); } return { target_user, to, topic, allow, permissions: mail_perm_store.list() }; }, }, 'get-mail-permissions': { description: 'List current mail permissions, optionally filtered by user', params: [ { name: 'target_user', required: false, type: 'string' }, ], policy: 'auto-accept', handler: ({ target_user }, { mail_perm_store }) => { const all = mail_perm_store.list(); return { permissions: target_user ? all.filter(e => e.user === target_user) : all }; }, }, };