Commit Graph

23 Commits

Author SHA1 Message Date
83b6ff51b7 feat: fix wizard step-skip bug + extend case edit with all fields + Paperclip title sync
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m38s
- Fix keyboard navigation bug: React was reusing the submit button DOM element
  when transitioning "הבא" → "צור תיק", retaining focus and causing Enter to
  auto-submit step 3. Added key props to force element replacement.

- CaseEditDialog now covers all wizard fields: appellants, respondents,
  property_address, permit_number (in addition to existing title, subject,
  hearing_date, expected_outcome, notes).

- When case title changes, Paperclip project name is updated in background
  via new update_project_name() in paperclip_client.py.

- Extended CaseUpdateRequest, case_update MCP tool, and caseUpdateSchema
  to carry the new fields end-to-end.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 10:55:45 +00:00
799b950961 feat(curator): trigger Knowledge Curator from api_mark_final, drop CEO F2
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 8s
The previous F2 stage in legal-ceo.md fired after the first DOCX export
— too early, since the user often iterates with עריכה-* uploads after
the first export. The true "this is dafna's chosen final" signal is the
"סמן כסופי" button in the UI, which calls api_mark_final.

This commit moves the curator wakeup from CEO's instructions to a
direct hook in api_mark_final:

- web/paperclip_client.py: add CURATOR_AGENTS dict (CMP + CMPA UUIDs)
  and wake_curator_for_final() helper. Looks up main case issue,
  creates a child issue assigned to the curator, tags plugin_state for
  case visibility, and triggers wakeup via Paperclip API.
- web/app.py: api_mark_final now calls workflow_tools.ingest_final_version
  (so case_law table finally gets populated for search_decisions) and
  pc_wake_curator_for_final. Both are best-effort — failure does not
  block marking final.
- legal-ceo.md: remove F2 stage, leave only the agents-table reference
  noting the curator runs from api_mark_final.
- hermes-curator.md: update activation description to reflect the new
  flow.

Result: curator runs only when chaim deliberately clicks "סמן כסופי",
on the actual final file, with no risk of analyzing a draft that will
later change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 14:47:03 +00:00
d0994704cf feat(agents): mirror Paperclip interactions in case page
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 47s
Surface issue_thread_interactions (ask_user_questions / request_confirmation /
suggest_tasks) directly inside legal-ai's case detail feed so the user can
answer agent prompts without switching to Paperclip's UI.

Backend (FastAPI):
- paperclip_client.py: 4 new helpers — get_issue_interactions (DB),
  respond_to_interaction / accept_interaction / reject_interaction (REST).
- app.py: extends GET /api/cases/{case_number}/agents to include
  `interactions`, and adds POST /api/cases/{case_number}/agents/interaction-response
  routing to /respond, /accept, /reject in Paperclip.
- paperclip_client.py: also pulls existing httpx calls onto the centralized
  pc_request helper (paperclip_api.py) for consistent auth + run-id headers.

Frontend (web-ui, Next.js 16 + TanStack Query):
- agents.ts: Interaction / InteractionPayload / InteractionStatus types,
  useSubmitInteraction mutation hook (invalidates the activity query).
- agent-activity-feed.tsx: InteractionCard renders radio (single) /
  checkbox (multi) for ask_user_questions, accept/reject + reason for
  request_confirmation, task selection for suggest_tasks. Resolved
  interactions show a read-only summary. Cards are interleaved with
  comments by created_at, so the feed reads chronologically.

Paperclip auto-wakes the issue assignee on a successful response
(queueResolvedInteractionContinuationWakeup) — no explicit wakeup needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 16:40:45 +00:00
923903217c feat(precedents): auto-trigger Claude extraction via Paperclip wakeup
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 7s
When a precedent is uploaded to the library, the FastAPI container now
fires a Paperclip wakeup so Claude (running locally as the CEO agent)
picks up the new row and runs `precedent_process_pending` for both
metadata and halacha extraction. The user no longer has to remember to
trigger it manually.

Mechanics:
- New `wake_for_precedent_extraction()` in paperclip_client.py creates
  (or reuses) a per-company "ספריית פסיקה — תור חילוץ" project, opens
  a fresh issue assigned to the company CEO with the case_law_id +
  citation in the description, and pings the Board API wakeup endpoint
  with `triggerDetail=precedent_library_upload`.
- ingest_precedent's _run() in app.py captures the returned case_law_id
  and best-effort calls the wake function (failures are logged, not
  surfaced — the upload itself stays clean).
- legal-ceo.md adds the precedent_process_pending tool family and a
  new "חילוץ פסיקה אוטומטי" section that tells the CEO to short-circuit
  past the heartbeat scan when woken with this trigger.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 16:49:25 +00:00
5deb38f5cf paperclip: assign CEO on issue creation so wakeup gate accepts run
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 9s
Paperclip heartbeat staleness gate (heartbeat.js evaluateQueuedRunStaleness)
cancels queued runs when issue.assigneeAgentId !== run.agentId, with error
"issue assignee changed before the queued run could start". Older Paperclip
versions auto-assigned on wakeup; the current version does not, so issues
created with NULL assignee silently never run.

Set assignee_agent_id to the company's CEO at INSERT time. Affects both the
project setup issue and the "התחל תהליך ניסוח" workflow issue.
2026-05-01 15:32:22 +00:00
1fbcdd0d16 paperclip: auto-attach default workspace on project creation
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 8s
Without a primary workspace on a project, the "סביבות עבודה" tab in
Paperclip stays hidden (gate: enableIsolatedWorkspaces && S0t list
non-empty), and agents wake with cwd=`/home/chaim` instead of the
legal-ai source tree. New helper inserts a primary workspace pointing at
LEGAL_AI_WORKSPACE_CWD (default /home/chaim/legal-ai) on both new and
legacy/existing-project paths. Idempotent — skips if any workspace row
already exists.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 15:17:04 +00:00
6a47320b9c get_case_issues: also match issues by [ערר X] title prefix
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 8s
The original implementation only returned issues with a plugin_state
linkage (legal-case-number key), which was set just on the initial
setup issue. Sub-agents that created follow-up issues during the case
workflow tagged them in the title ("[ערר 1130-25] כתיבת החלטה" etc.)
but didn't write a plugin_state row, so 23 of 24 historical issues
for case 1130-25 were invisible to the agent activity feed.

Widened the lookup to UNION two paths:
  (a) plugin_state.scope_id matches via the legal-case-number key
  (b) issues.title LIKE '%[ערר {case_number}]%' OR '%ערר {case_number}%'

Used DISTINCT ON (i.id) + post-sort by created_at to dedupe and keep
chronological order. The widget on https://legal-ai.../cases/1130-25
will now show the full history (was 1 issue → now 16).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:53:20 +00:00
7d86ed4a62 Archive: also cancel open Paperclip issues to clear agent widget
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 32s
When a case is archived, the legal-ai UI's AgentStatusWidget kept showing
"agents started working, waiting for first report" because related
Paperclip issues remained in 'todo' / 'in_progress' status. Concrete
example: case 1130-25 had two open issues (CMP-15 ניתוח תכנוני, CMP-21
כתיבת החלטה) that lingered after the case was finalized; 1194-25 had
two more (CMP-37, CMP-44).

Extended pc_archive_project to also UPDATE issues SET status='cancelled',
cancelled_at=now() WHERE project_id matches AND status IN
('backlog','todo','in_progress','blocked','in_review'). Returns the list
of cancelled issues so the toast can announce the count.

Updated cases.ts ArchiveResult.paperclip.issues_cancelled type and the
toast message in case-archive-action to surface "(N משימות פתוחות בוטלו)"
when relevant.

Restore is intentionally unchanged — we don't auto-recreate cancelled
issues; if work needs to resume, a fresh issue should be created.

Stale issues for 1130-25 / 1194-25 cancelled directly in DB as a one-off
cleanup (CMP-15, CMP-21, CMP-37, CMP-44).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:14:12 +00:00
2b7f291928 Case archive/restore with Paperclip sync
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m27s
Adds a comprehensive archive flow for closed cases — separate /archive
screen in the UI, archive/restore actions on the case detail page, and
automatic two-way sync with Paperclip.

Backend (web/app.py + mcp-server/services/db.py):
- New SCHEMA_V6 migration: cases.archived_at TIMESTAMPTZ + partial index
- list_cases gains include_archived/archived_only flags; default excludes
  archived rows so the main /api/cases list hides closed cases
- archive_case / restore_case helpers in db.py
- POST /api/cases/{n}/archive sets archived_at and calls
  pc_archive_project (sets Paperclip projects.archived_at via direct DB)
- POST /api/cases/{n}/restore clears archived_at and calls
  pc_restore_project (clears Paperclip archived_at)
- archive_project / restore_project in paperclip_client.py — name-based
  match consistent with create_project's lookup

Frontend (web-ui):
- cases.ts: scope param ("active"|"archived"|"all") on useCases;
  useArchiveCase / useRestoreCase mutations
- /archive page (new): table of archived cases with restore button +
  search, sort, empty state matching the editorial aesthetic of /
- case-archive-action.tsx: button on case detail header. Active case →
  confirm dialog → archive. Archived case → restore (no confirm).
  Toast announces both legal-ai and Paperclip outcomes (synced, not
  found in pc, error)
- case-header shows "בארכיון" badge when archived_at is set
- Nav: ארכיון link added to AppShell after בית

Tested end-to-end against the live DB:
- 1130-25 archive → list_cases(include_archived=False) excludes it,
  list_cases(archived_only=True) includes it, restore reverses
- pc archive/restore on 1194-25 verified via direct DB lookup
- TypeScript compiles clean

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 18:54:52 +00:00
d7a79cf5ec Show per-case agent status instead of global — fix Hebrew translation of "running"
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 3m41s
Agent status widget now checks heartbeat_runs + wakeup_requests to determine
if an agent is running on *this* case. Agents running on other cases show as idle.
Added "running" to STATUS_DOT/STATUS_LABEL maps so it displays in Hebrew.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 14:47:42 +00:00
c9a8cca35f Link agents to CMPA company, route CEO wakeup per-company
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 8s
Created 7 agents in CMPA (betterment levy) company, mirroring
the CMP agents with same config and hierarchy. CEO_AGENTS dict
maps company_id to the correct CEO for wakeup routing.

wake_ceo_agent and post_comment now resolve the correct CEO
based on company_id. create_workflow_issue returns company_id.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 12:09:37 +00:00
1e4c5c1518 Add Paperclip agent activity mirror to case detail page
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 3m16s
New "Agents" tab in case detail shows all Paperclip agent comments,
issue status, and agent status for each case — eliminating the need
to switch between Legal-AI and Paperclip UIs.

Backend: 4 new DB query functions in paperclip_client.py (issues,
comments, agents, post_comment) + 2 new API endpoints (GET/POST
/api/cases/{case_number}/agents). Comment posting uses Board API
with DB+wakeup fallback to ensure CEO routing.

Frontend: agents.ts hooks (10s polling), AgentActivityFeed component
(markdown timeline + comment input), AgentStatusWidget (sidebar),
4th tab in case detail page.

Also includes new-company-setup-guide.md documenting the process
for setting up the betterment levy (CMPA) company.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 10:44:42 +00:00
43b8106f55 Fix wakeup API source/triggerDetail enum values
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 10s
Paperclip expects source ∈ {timer, assignment, on_demand, automation}
and triggerDetail ∈ {manual, ping, callback, system}.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 16:08:07 +00:00
6228846223 Add "Start Workflow" button to trigger CEO agent from web UI
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 49s
New endpoint POST /api/cases/{case_number}/start-workflow creates a
Paperclip issue, wakes the CEO agent via wakeup API, and transitions
case status to "processing". Button appears on case page only when
status is "new" or "documents_ready".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 15:51:23 +00:00
1133272e34 Fix Paperclip integration (identifier→issue_prefix) + add settings page
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 34s
- Fix column name mismatch in paperclip_client.py and app.py: Paperclip's
  companies table uses `issue_prefix`, not `identifier`
- Fix _LEGAL_DB_URL to read from POSTGRES_URL env var (used in container)
- Add settings page (/settings) for managing tag → Paperclip company mappings
- Replace "תיק חדש" nav item with "הגדרות" (new case is on home page)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 14:09:08 +00:00
2faae002e7 Add settings page for tag-to-company mappings and auto-create Paperclip projects
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m22s
When a case is created, a Paperclip project is now automatically created in
the correct company based on the appeal_subtype tag. Tag-to-company mappings
are managed via a new Settings page that pulls companies from Paperclip DB.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 06:24:23 +00:00
3f759d3610 Improve document processing pipeline and agent workflows
- Add delete_document_chunks for reprocessing, save extracted text to disk
- Expand case directory structure (original/extracted/proofread/backup)
- Update classifier patterns (תגובה, הודעת עמדה)
- Fix proofreader agent paths for new directory layout
- Update HEARTBEAT to notify on every task completion
- Improve bidi_table with LRE/PDF directional embedding
- Add Paperclip project verification and auto-close setup issue
- Add auto-sync-cases.sh for Gitea synchronization

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 16:45:49 +00:00
85880c482e Revert Paperclip DB URL to host embedded-postgres (localhost:54329)
Paperclip moved back from Docker to pm2 on host.
Reverts c83dcd6 (Docker migration URL change).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 12:03:08 +00:00
c83dcd660e Update Paperclip DB URL for Docker migration
Paperclip moved from embedded PG (localhost:54329) to Coolify-managed
PostgreSQL container (10.0.2.13:5432).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 11:17:57 +00:00
e5dc037088 Create Paperclip issue + plugin state link when opening new case
Wizard now creates: project + issue (CMP-N) + plugin_state entry
linking the issue to the legal-ai case number. This enables the
sync job in the marcusgroup.legal-ai plugin to track case status.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 13:44:49 +00:00
10071d7f18 Prevent duplicate Paperclip projects: check existing before creating
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 11:21:06 +00:00
0dfb42ab00 Fix env var loading for Docker: support GITEA_TOKEN fallback, configurable Paperclip DB URL
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 10:18:24 +00:00
0593fe9b01 Add interactive case creation wizard + document upload with auto-rename
New SPA UI with 4 views:
- Case list (#/) with status cards and document counts
- New case wizard (#/new) with 4-step form: details, parties, schedule, review+create
- Case view (#/case/:id) with grouped documents and drag-drop upload with tagging
- Legacy upload (#/upload) for backwards compatibility

Auto-creation pipeline in wizard step 4:
1. Creates case in legal-ai DB with local git repo
2. Creates Gitea repo in 'cases' org and pushes initial commit
3. Creates Paperclip project via direct DB insert

Document upload with smart rename:
- scan_001.pdf -> כתב-ערר-קובר-1130-25.pdf
- Based on doc_type + party_name + case_number

New files:
- web/gitea_client.py: Gitea REST API client
- web/paperclip_client.py: Paperclip embedded DB client

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 10:17:24 +00:00