From 52c3e600e79c608bb49b72368a6e91625a0ae788 Mon Sep 17 00:00:00 2001 From: Chaim Marcus Date: Sun, 17 May 2026 10:18:33 +0000 Subject: [PATCH] style: biome auto-fix (const, import order, formatter) Co-Authored-By: Claude Sonnet 4.6 --- src/manifest.ts | 3 +- src/worker.ts | 110 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 76 insertions(+), 37 deletions(-) diff --git a/src/manifest.ts b/src/manifest.ts index e490d4e..b8e1228 100644 --- a/src/manifest.ts +++ b/src/manifest.ts @@ -167,7 +167,8 @@ export default { { jobKey: "weekly-feedback-analysis", displayName: "ניתוח פידבק שבועי", - description: 'מסכם פידבק יו"ר מהשבוע האחרון ומעדכן את decision-lessons.md', + description: + 'מסכם פידבק יו"ר מהשבוע האחרון ומעדכן את decision-lessons.md', schedule: "0 19 * * 0", }, ], diff --git a/src/worker.ts b/src/worker.ts index 5f2701a..5ac952b 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -1,5 +1,8 @@ +import type { + PluginContext, + PluginWebhookInput, +} from "@paperclipai/plugin-sdk"; import { definePlugin, runWorker } from "@paperclipai/plugin-sdk"; -import type { PluginContext, PluginWebhookInput } from "@paperclipai/plugin-sdk"; import { LegalApi } from "./legal-api.js"; // Hoisted so onWebhook can access the context after setup() completes. @@ -7,8 +10,10 @@ let pluginCtx: PluginContext | null = null; // Per-company CEO agent IDs (shared between setup and onWebhook). const CEO_AGENT_IDS: Record = { - "42a7acd0-30c5-4cbd-ac97-7424f65df294": "752cebdd-6748-4a04-aacd-c7ab0294ef33", // CMP (רישוי ובניה) - "8639e837-4c9d-47fa-a76b-95788d651896": "cdbfa8bc-3d61-41a4-a2e7-677ec7d34562", // CMPA (היטלי השבחה) + "42a7acd0-30c5-4cbd-ac97-7424f65df294": + "752cebdd-6748-4a04-aacd-c7ab0294ef33", // CMP (רישוי ובניה) + "8639e837-4c9d-47fa-a76b-95788d651896": + "cdbfa8bc-3d61-41a4-a2e7-677ec7d34562", // CMPA (היטלי השבחה) }; const plugin = definePlugin({ @@ -545,7 +550,7 @@ const plugin = definePlugin({ body?: string; } | null; - let issueId = payload?.issueId; + const issueId = payload?.issueId; let commentBody = payload?.body; // If issueId is not in payload, try to find it from the comment entity @@ -590,21 +595,17 @@ const plugin = definePlugin({ } try { - const { runId } = await ctx.agents.invoke( - ceoAgentId, - event.companyId, - { - prompt: [ - `תגובה חדשה מחיים על issue "${issue.title}" (${issue.identifier || issueId}):`, - "", - commentBody, - "", - `קרא את ה-comments האחרונים על ה-issue, הבן מה חיים מבקש, והחלט מה לעשות.`, - `אם ההוראה ברורה — נתב לסוכן המתאים. אם לא ברור — שאל את חיים.`, - ].join("\n"), - reason: `user_commented_on_${issue.identifier || issueId}`, - }, - ); + const { runId } = await ctx.agents.invoke(ceoAgentId, event.companyId, { + prompt: [ + `תגובה חדשה מחיים על issue "${issue.title}" (${issue.identifier || issueId}):`, + "", + commentBody, + "", + `קרא את ה-comments האחרונים על ה-issue, הבן מה חיים מבקש, והחלט מה לעשות.`, + `אם ההוראה ברורה — נתב לסוכן המתאים. אם לא ברור — שאל את חיים.`, + ].join("\n"), + reason: `user_commented_on_${issue.identifier || issueId}`, + }); ctx.logger.info("Routed user comment to CEO agent", { issueId, commentId: entityId, @@ -709,7 +710,8 @@ const plugin = definePlugin({ ctx.jobs.register("stale-case-reminder", async (_job) => { ctx.logger.info("stale-case-reminder: starting"); const config = await ctx.config.get(); - const apiBase = (config.legalApiBaseUrl as string) ?? "http://localhost:8085"; + const apiBase = + (config.legalApiBaseUrl as string) ?? "http://localhost:8085"; const resp = await ctx.http.fetch(`${apiBase}/api/cases/stale?days=3`); if (!resp.ok) { @@ -718,13 +720,21 @@ const plugin = definePlugin({ } const data = (await resp.json()) as { - cases: Array<{ case_number: string; title: string; status: string; days_stale: number }>; + cases: Array<{ + case_number: string; + title: string; + status: string; + days_stale: number; + }>; total: number; }; // Build case→issue map once (O(companies × issues)) to avoid N×M RPCs per stale case const companies = await ctx.companies.list(); - const caseIssueMap = new Map(); + const caseIssueMap = new Map< + string, + { issueId: string; companyId: string } + >(); for (const company of companies) { const issues = await ctx.issues.list({ companyId: company.id }); for (const issue of issues) { @@ -734,7 +744,10 @@ const plugin = definePlugin({ stateKey: "legal-case-number", }); if (linkedCase && typeof linkedCase === "string") { - caseIssueMap.set(linkedCase, { issueId: issue.id, companyId: company.id }); + caseIssueMap.set(linkedCase, { + issueId: issue.id, + companyId: company.id, + }); } } } @@ -750,27 +763,39 @@ const plugin = definePlugin({ linked.companyId, ); reminded++; - ctx.logger.info(`stale-case-reminder: reminded case ${staleCase.case_number} (${staleCase.days_stale}d)`); + ctx.logger.info( + `stale-case-reminder: reminded case ${staleCase.case_number} (${staleCase.days_stale}d)`, + ); } - ctx.logger.info(`stale-case-reminder: done. ${reminded}/${data.total} cases reminded`); + ctx.logger.info( + `stale-case-reminder: done. ${reminded}/${data.total} cases reminded`, + ); }); ctx.jobs.register("weekly-feedback-analysis", async (_job) => { ctx.logger.info("weekly-feedback-analysis: starting"); const config = await ctx.config.get(); - const apiBase = (config.legalApiBaseUrl as string) ?? "http://localhost:8085"; + const apiBase = + (config.legalApiBaseUrl as string) ?? "http://localhost:8085"; - const resp = await ctx.http.fetch(`${apiBase}/api/chair-feedback/weekly-summary`); + const resp = await ctx.http.fetch( + `${apiBase}/api/chair-feedback/weekly-summary`, + ); if (!resp.ok) { ctx.logger.error(`weekly-feedback-analysis: API error ${resp.status}`); return; } - const data = (await resp.json()) as { summary: string; entry_count: number }; + const data = (await resp.json()) as { + summary: string; + entry_count: number; + }; if (data.entry_count === 0) { - ctx.logger.info("weekly-feedback-analysis: no feedback this week, skipping"); + ctx.logger.info( + "weekly-feedback-analysis: no feedback this week, skipping", + ); return; } @@ -780,7 +805,9 @@ const plugin = definePlugin({ const ceoId = CEO_AGENT_IDS[company.id]; if (!ceoId) { - ctx.logger.warn(`weekly-feedback-analysis: no CEO agent for company ${company.id}`); + ctx.logger.warn( + `weekly-feedback-analysis: no CEO agent for company ${company.id}`, + ); return; } @@ -789,7 +816,9 @@ const plugin = definePlugin({ reason: "weekly-feedback-analysis scheduled job", }); - ctx.logger.info(`weekly-feedback-analysis: invoked CEO ${ceoId} with ${data.entry_count} feedback entries`); + ctx.logger.info( + `weekly-feedback-analysis: invoked CEO ${ceoId} with ${data.entry_count} feedback entries`, + ); }); ctx.logger.info("Legal AI plugin ready"); @@ -820,13 +849,20 @@ const plugin = definePlugin({ const { caseNumber, oldStatus, newStatus, companyId } = payload; if (!caseNumber || !newStatus || !companyId) { - pluginCtx.logger.warn("onWebhook: malformed payload", { caseNumber, newStatus, companyId }); + pluginCtx.logger.warn("onWebhook: malformed payload", { + caseNumber, + newStatus, + companyId, + }); return; } - pluginCtx.logger.info(`Webhook: case ${caseNumber} ${oldStatus} → ${newStatus}`, { - companyId, - }); + pluginCtx.logger.info( + `Webhook: case ${caseNumber} ${oldStatus} → ${newStatus}`, + { + companyId, + }, + ); // Find the Paperclip issue linked to this case number by scanning plugin state. // State stores: issue.id → case_number (scopeKind=issue, stateKey=legal-case-number) @@ -845,7 +881,9 @@ const plugin = definePlugin({ } if (!linkedIssueId) { - pluginCtx.logger.warn(`onWebhook: no Paperclip issue linked to case ${caseNumber}`); + pluginCtx.logger.warn( + `onWebhook: no Paperclip issue linked to case ${caseNumber}`, + ); return; }