From 0d996cf7590e3e52f424859c7d6f0e68640f119e Mon Sep 17 00:00:00 2001
From: soryu <soryu@soryu.co>
Date: Sun, 17 May 2026 21:23:20 +0100
Subject: chore: remove LLM module + all dependent surfaces (#135)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Wholesale removal of the LLM integration layer. ~14,200 LOC deleted
across backend and frontend. All chat-driven UIs go with it.

## Backend
- Delete `src/llm/` (7,400 LOC): claude/groq clients, contract_tools,
  contract_evaluator, discuss_tools, mesh_tools, phase_guidance,
  task_output, templates, markdown round-trip, tools, transcript_analyzer.
- Delete handlers wholly dependent on LLM:
  - `chat.rs` (file-level LLM chat at /files/{id}/chat)
  - `mesh_chat.rs` (mesh & task LLM chat + history)
  - `templates.rs` (/contract-types listing)
- Strip LLM uses from `mesh_daemon.rs`:
  - `compute_action_directive` (used phase_guidance::check_deliverables_met
    to nudge supervisors with "all tasks done" messages). The auto-PR
    path below still fires when all tasks finish, so no behaviour lost.
  - `crate::llm::markdown_to_body` → inline 1-line replacement that
    wraps markdown content in a single BodyElement::Markdown. The
    editor re-parses on display, so round-trip is preserved.
- Drop routes: /files/{id}/chat, /mesh/chat, /mesh/chat/history,
  /mesh/tasks/{id}/chat, /contract-types.
- Drop the matching openapi registrations.

## Frontend
- Delete components that were LLM-only:
  - `mesh/UnifiedMeshChatInput.tsx`
  - `listen/DiscussContractModal.tsx`
  - `listen/TranscriptAnalysisPanel.tsx`
  - `listen/ContractPickerModal.tsx`
  - `files/CliInput.tsx`
- Delete the entire /listen page (its primary value-add was
  voice → LLM analysis → contract creation; without LLM the page is
  just a transcript display with no obvious user purpose).
- Delete `hooks/useMeshChatHistory.ts` and `lib/listenApi.ts`
  (transcript-analysis API client to the already-Phase-5-removed
  listen handlers).
- Strip api.ts of LLM exports: LlmModel, ChatMessage/Request/Response,
  UserQuestion/Answer, chatWithFile, MeshChat* types & functions,
  getMeshChatHistory, clearMeshChatHistory, chatWithMeshContext,
  ContractTypeTemplate, listContractTypes, chatWithContract,
  getContractChatHistory, clearContractChatHistory, discussContract,
  PhaseDefinition, DeliverableDefinition.
- mesh.tsx: drop UnifiedMeshChatInput render + the chatContext memo +
  handleTaskUpdatedFromCli (only consumer was the input).
- files.tsx: drop CliInput render + handleGenerateFromElement +
  handleBodyUpdate + handleClearFocus + suggestedPrompt state (all
  CliInput-only).
- NavStrip: drop the /listen link.
- main.tsx: drop the /listen route.

## Net diff: 37 files changed, 58 insertions, 14,281 deletions.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
 makima/frontend/src/routes/files.tsx | 88 +++++-------------------------------
 1 file changed, 11 insertions(+), 77 deletions(-)

(limited to 'makima/frontend/src/routes/files.tsx')

diff --git a/makima/frontend/src/routes/files.tsx b/makima/frontend/src/routes/files.tsx
index b232aa0..5d757a4 100644
--- a/makima/frontend/src/routes/files.tsx
+++ b/makima/frontend/src/routes/files.tsx
@@ -3,7 +3,6 @@ import { useParams, useNavigate } from "react-router";
 import { Masthead } from "../components/Masthead";
 import { FileList } from "../components/files/FileList";
 import { FileDetail, type FocusedElement } from "../components/files/FileDetail";
-import { CliInput } from "../components/files/CliInput";
 import { ConflictNotification } from "../components/files/ConflictNotification";
 import { UpdateNotification } from "../components/files/UpdateNotification";
 import { useFiles } from "../hooks/useFiles";
@@ -57,7 +56,6 @@ function FilesPageContent() {
   const [remoteUpdate, setRemoteUpdate] = useState<FileUpdateEvent | null>(null);
   const [remoteFileData, setRemoteFileData] = useState<FileDetailType | null>(null);
   const [focusedElement, setFocusedElement] = useState<FocusedElement | null>(null);
-  const [suggestedPrompt, setSuggestedPrompt] = useState<string | null>(null);
   const [createdTask, setCreatedTask] = useState<Task | null>(null);
   // Contract selection modal state for task creation
   const [showContractModal, setShowContractModal] = useState(false);
@@ -246,18 +244,8 @@ function FilesPageContent() {
     [editFile, fileDetail, updateHasLocalChanges]
   );
 
-  const handleBodyUpdate = useCallback(
-    (body: BodyElement[], summary: string | null) => {
-      if (fileDetail) {
-        setFileDetail({
-          ...fileDetail,
-          body,
-          summary,
-        });
-      }
-    },
-    [fileDetail]
-  );
+  // handleBodyUpdate was the CliInput callback for AI-driven body
+  // rewrites. CliInput is gone with the LLM module.
 
   const handleBodyElementUpdate = useCallback(
     async (index: number, element: BodyElement) => {
@@ -423,9 +411,7 @@ function FilesPageContent() {
     setFocusedElement(element);
   }, []);
 
-  const handleClearFocus = useCallback(() => {
-    setFocusedElement(null);
-  }, []);
+  // handleClearFocus was passed to CliInput; both gone now.
 
   // Convert element to a different type
   const handleConvertElement = useCallback(
@@ -506,55 +492,10 @@ function FilesPageContent() {
     [fileDetail, id, editFile, updateHasLocalChanges, focusedElement]
   );
 
-  // Generate from element - focus on it and pre-fill a prompt
-  const handleGenerateFromElement = useCallback(
-    (index: number, action: string) => {
-      if (!fileDetail) return;
-
-      const element = fileDetail.body[index];
-      if (!element) return;
-
-      // Get preview text
-      let preview = "";
-      switch (element.type) {
-        case "heading":
-        case "paragraph":
-          preview = element.text.slice(0, 50);
-          break;
-        case "code":
-          preview = element.content.slice(0, 50);
-          break;
-        case "list":
-          preview = element.items[0]?.slice(0, 40) || "";
-          break;
-        default:
-          preview = "Element";
-      }
-
-      // Focus on the element
-      setFocusedElement({
-        index,
-        type: element.type,
-        preview: preview + (preview.length >= 50 ? "..." : ""),
-      });
-
-      // Set suggested prompt based on action
-      let prompt = "";
-      switch (action) {
-        case "elaborate":
-          prompt = "Elaborate and expand on this content";
-          break;
-        case "summarize":
-          prompt = "Summarize this content";
-          break;
-        case "extract_actions":
-          prompt = "Extract action items from this content";
-          break;
-      }
-      setSuggestedPrompt(prompt);
-    },
-    [fileDetail]
-  );
+  // handleGenerateFromElement was an LLM elaborate/summarise/extract
+  // affordance that piped a suggested prompt into CliInput. Both
+  // CliInput and the LLM module are gone; the handler + its prop on
+  // FileDetail are removed.
 
   // Create a mesh task from an element - shows contract selection modal
   const handleCreateTaskFromElement = useCallback(
@@ -762,7 +703,6 @@ function FilesPageContent() {
                 onBodyElementDelete={handleBodyElementDelete}
                 onBodyElementDuplicate={handleBodyElementDuplicate}
                 onConvertElement={handleConvertElement}
-                onGenerateFromElement={handleGenerateFromElement}
                 onCreateTaskFromElement={handleCreateTaskFromElement}
                 onEditingChange={updateIsActivelyEditing}
                 hasPendingRemoteUpdate={!!remoteUpdate}
@@ -779,16 +719,10 @@ function FilesPageContent() {
                 onClearVersionSelection={clearSelectedVersion}
               />
             </div>
-            <div className="shrink-0">
-              <CliInput
-                fileId={id}
-                onUpdate={handleBodyUpdate}
-                focusedElement={focusedElement}
-                onClearFocus={handleClearFocus}
-                suggestedPrompt={suggestedPrompt}
-                onClearSuggestedPrompt={() => setSuggestedPrompt(null)}
-              />
-            </div>
+            {/* CliInput (file-level LLM chat) removed alongside the LLM
+                module. The file detail view is now a pure read/edit
+                surface; AI-driven file editing was the primary value of
+                this composer and went with the LLM removal. */}
           </div>
         ) : id && detailLoading ? (
           <div className="panel h-full flex items-center justify-center">
-- 
cgit v1.2.3

