Files
plugin-legal-ai/src/manifest.ts
Chaim Marcus 237d829844 feat(sync): מוני-ריצה מובחנים ל-sync-case-status (legal-ai #617)
הג'וב סיים עד כה בשורה אחת — `casesChecked` — שאינה מבחינה בין "אין מה
לעשות", "נדחה בכוונה" ו"נפל". 13,872 ריצות דיווחו בריאות ירוקה, ובפועל
היו בהן 389 כתיבות בלבד; האבחנה ב-#604 נבנתה על היעדר-ראיה.

כל ריצה פולטת מעתה: scanned · matched · written · declined{no_linked_issues,
no_writable_root, ambiguous_writable_roots, unknown_status, already_matching}.
הפליטה יושבת ב-`finally` וזורקת את השגיאה המקורית הלאה, כך שריצה שנפלה
נשארת `failed` ב-`plugin_job_runs` **וגם** נושאת את המונים שהספיקה לצבור.

שני משטחים קיימים וצורכים, שנמדדו:
- `ctx.logger.info` → stdout של pm2 — שם בוצע בפועל האבחון של #626/#637.
- `ctx.metrics.write` → `plugin_logs` (level='metric') — הטבלה שפאנל
  "Recent Logs" בדף-הפלאגין מרנדר, וניתנת לשאילתת-SQL (AC4).

המונים בתוך מחרוזת-ההודעה ולא רק ב-meta, כי שני המשטחים מתעלמים מ-meta
בפועל (הפאנל מרנדר createdAt/level/message בלבד; ומ-pino נמדד ששדה
`{error:…}` נופל). נדרשה הרשאת `metrics.write` ב-manifest — זו הדרך
היחידה לכתוב ל-`plugin_logs`.

אפס שינוי בהתנהגות-הכתיבה: `sync-target.ts` לא נגע כלל, ובכלל זה
`NON_WRITABLE_STATUSES` (הכרעת-יו"ר, #626).

Closes ezer-mishpati/legal-ai#617

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 16:51:48 +03:00

236 lines
6.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
export default {
id: "marcusgroup.legal-ai",
apiVersion: 1,
version: "0.1.0",
displayName: "Ezer Mishpati - Legal AI",
description:
"Integration with legal decision drafting system — case management, semantic search, and workflow tracking",
author: "Marcus Group",
categories: ["connector"] as const,
capabilities: [
"events.subscribe",
"issues.read",
"issues.create",
"issues.update",
"issue.comments.read",
"issue.comments.create",
"issue.interactions.create",
"issue.documents.write",
"agent.tools.register",
"agents.invoke",
"http.outbound",
"plugin.state.read",
"plugin.state.write",
"jobs.schedule",
"activity.log.write",
// נדרש ל-`ctx.metrics.write` — סיכום-ריצת הג'וב `sync-case-status`
// (legal-ai issue #617). זו הדרך היחידה לכתוב ל-`plugin_logs`
// (level='metric'), הטבלה שפאנל "Recent Logs" בדף-הפלאגין מרנדר.
"metrics.write",
"companies.read",
"projects.read",
"webhooks.receive",
"ui.detailTab.register",
"ui.dashboardWidget.register",
] as const,
entrypoints: {
worker: "dist/worker.js",
ui: "dist/ui",
},
instanceConfigSchema: {
type: "object" as const,
properties: {
legalApiBaseUrl: {
type: "string" as const,
default: "http://localhost:8085",
description: "Base URL for the Ezer Mishpati API",
},
},
},
tools: [
{
toolKey: "legal_case_list",
name: "legal_case_list",
displayName: "List Legal Cases",
description: "List all appeal cases in the legal system",
parametersSchema: { type: "object" as const, properties: {} },
},
{
toolKey: "legal_case_get",
name: "legal_case_get",
displayName: "Get Legal Case Details",
description: "Get full details of a legal case including documents",
parametersSchema: {
type: "object" as const,
properties: {
case_number: { type: "string" as const, description: "Case number" },
},
required: ["case_number"],
},
},
{
toolKey: "legal_case_create",
name: "legal_case_create",
displayName: "Create Legal Case",
description: "Create a new appeal case with linked Paperclip issue",
parametersSchema: {
type: "object" as const,
properties: {
case_number: { type: "string" as const },
title: { type: "string" as const },
appellants: {
type: "array" as const,
items: { type: "string" as const },
},
respondents: {
type: "array" as const,
items: { type: "string" as const },
},
subject: { type: "string" as const },
property_address: { type: "string" as const },
expected_outcome: { type: "string" as const },
},
required: ["case_number", "title"],
},
},
{
toolKey: "legal_case_update",
name: "legal_case_update",
displayName: "Update Legal Case",
description: "Update a legal case status, title, or outcome",
parametersSchema: {
type: "object" as const,
properties: {
case_number: { type: "string" as const },
status: { type: "string" as const },
title: { type: "string" as const },
expected_outcome: { type: "string" as const },
},
required: ["case_number"],
},
},
{
toolKey: "legal_case_status",
name: "legal_case_status",
displayName: "Get Case Workflow Status",
description: "Get full workflow status: documents, drafts, next steps",
parametersSchema: {
type: "object" as const,
properties: {
case_number: { type: "string" as const },
},
required: ["case_number"],
},
},
{
toolKey: "legal_search",
name: "legal_search",
displayName: "Search Legal Precedents",
description: "Semantic RAG search across previous decisions",
parametersSchema: {
type: "object" as const,
properties: {
query: {
type: "string" as const,
description: "Search query in Hebrew",
},
limit: { type: "number" as const },
section_type: { type: "string" as const },
},
required: ["query"],
},
},
{
toolKey: "legal_case_template",
name: "legal_case_template",
displayName: "Get Decision Template",
description: "Get outcome-aware decision template for 12-block structure",
parametersSchema: {
type: "object" as const,
properties: {
case_number: { type: "string" as const },
},
required: ["case_number"],
},
},
{
toolKey: "legal_processing_status",
name: "legal_processing_status",
displayName: "Get Processing Status",
description: "Get overall system processing status",
parametersSchema: { type: "object" as const, properties: {} },
},
{
toolKey: "legal_predecessor_context",
name: "legal_predecessor_context",
displayName: "הקשר מריצות קודמות",
description:
"Recent conclusions from prior heartbeat runs on this case (the 'summary' each run left). Call this when RESUMING work on a case to see what earlier sessions already did/decided — instead of re-deriving context from scratch.",
parametersSchema: {
type: "object" as const,
properties: {
case_number: {
type: "string" as const,
description: "Case number (e.g. 1043-02-26)",
},
},
required: ["case_number"],
},
},
],
jobs: [
{
jobKey: "sync-case-status",
displayName: "Sync Legal Case Status",
description:
"Polls legal-ai for case status changes and updates Paperclip issues",
schedule: "*/15 * * * *",
},
{
jobKey: "stale-case-reminder",
displayName: "תזכורת תיקים תקועים",
description: "מזהה תיקים שלא עודכנו 30+ ימים ומוסיף תגובה ל-issue",
schedule: "0 8 * * *",
},
{
jobKey: "weekly-feedback-analysis",
displayName: "ניתוח פידבק שבועי",
description:
'מסכם פידבק יו"ר מהשבוע האחרון ומעדכן את decision-lessons.md',
schedule: "0 19 * * 0",
},
{
jobKey: "route-pending-comments",
displayName: "ערובת מסירת-הערות (sweep)",
description:
"sweep פיוס: מנתב כל הערת-משתמש שטרם נותבה ל-CEO (at-least-once), כדי שהערה לא תיפול גם אם ה-wakeup התבטל/התלכד",
schedule: "*/2 * * * *",
},
],
webhooks: [
{
endpointKey: "case-status",
displayName: "עדכון סטטוס תיק",
description:
"מקבל עדכוני סטטוס מ-legal-ai ומפרסם תגובה על ה-issue המקושר",
},
],
ui: {
slots: [
{
type: "detailTab" as const,
id: "legal-case-tab",
displayName: "ערר",
exportName: "LegalCaseTab",
entityTypes: ["issue" as const],
},
{
type: "dashboardWidget" as const,
id: "legal-cases-widget",
displayName: "תיקי ערר",
exportName: "LegalCasesWidget",
},
],
},
};