apify tool, tools API + automation UI, integrations config, super admin restrictions

- apify tool: TOOL.md definition, index.ts implementation with auto-auth via OFFICER_APIFY_TOKEN, output_path for large datasets
- tools API: /tools routes (list, detail, chat, create, delete) mirroring tasks pattern
- automation UI: tools tab in sidebar, NewTool component, tool detail view
- apify integration: settings page for enterprise API key config, pi-bridge passes env var to containers
- tiktok-trends task: rewritten as agent instructions using apify tool with output_path, scripted report generation for 50KB read limit
- restrict edit/delete of native/global capabilities to Super Admin only (backend + frontend)
- tools authoring guide: TOOLS.md with full spec for TOOL.md frontmatter, index.ts execute signature, patterns

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-02 20:00:45 +00:00
co-authored by Claude Opus 4.6
parent 776738a983
commit bd362dc586
19 changed files with 1059 additions and 149 deletions
@@ -33,6 +33,40 @@ integrationsRouter.get('/', async (ctx) => {
return ctx.json([]);
});
// --- Enterprise: Apify config (Super Admin only) ---
type ApifyConfig = { apiToken: string };
export const readApifyConfig = async (): Promise<ApifyConfig | null> => {
const integration = await getServerIntegration('apify');
if (!integration) return null;
const config = integration.config as Record<string, unknown>;
if (!config.apiToken) return null;
return config as unknown as ApifyConfig;
};
integrationsRouter.get('/apify/config', async (ctx) => {
const user = ctx.get('user');
if (user.role !== 'Super Admin') throw FORBIDDEN();
return ctx.json(await readApifyConfig());
});
integrationsRouter.put('/apify/config', async (ctx) => {
const user = ctx.get('user');
if (user.role !== 'Super Admin') throw FORBIDDEN();
const body = ctx.get('body') as { apiToken?: string };
const config = { apiToken: body.apiToken ?? '' };
await upsertServerIntegration('apify', config);
return ctx.json(config);
});
integrationsRouter.get('/apify/status', async (ctx) => {
const config = await readApifyConfig();
return ctx.json({ configured: !!config?.apiToken });
});
// --- Enterprise: Google OAuth config (Super Admin only) ---
integrationsRouter.get('/google/config', async (ctx) => {