diff --git a/.plans/create-bead-ui-convoy.md b/.plans/create-bead-ui-convoy.md new file mode 100644 index 0000000000..647da82190 --- /dev/null +++ b/.plans/create-bead-ui-convoy.md @@ -0,0 +1,62 @@ +# Create Bead UI Convoy — Shared Context + +## Bead 1: Backend (createBead tRPC + Workers AI enrichment) + +### Status: completed + +### Deviations from plan + +- `HELD_LABEL` and `HELD_LABEL_LIKE` constants are exported from `patrol.ts` (not alongside `TRIAGE_LABEL_LIKE` in reconciler.ts — that's just the consumer). This matches the existing pattern where `TRIAGE_LABEL_LIKE` is defined in `patrol.ts` and imported in `reconciler.ts`. +- Labels in the database are stored as JSON arrays (e.g. `'["gt:held","bug"]'`), so `HELD_LABEL_LIKE` uses the pattern `%"gt:held"%` (with quotes), matching the same pattern used by `TRIAGE_LABEL_LIKE = '%"gt:triage-request"%'`. +- `slingBead()` already supports `labels?: string[]` in its input type — no change needed there. The `sling` tRPC procedure needed updating to accept `labels` and pass it through. +- The `enrichBead` procedure uses `ctx.env.AI.run(...)`. The AI binding is typed as `Ai` (Cloudflare Workers AI SDK) in `worker-configuration.d.ts`. The `run()` call for text generation models returns `{ response?: string }`. +- `createHeldBead` and `notifyMayorOfNewBead` are added as public RPC methods on `TownDO` (not private helpers), since they need to be called from the tRPC router via `townStub`. +- For `startBead`, the labels are updated via `beadOps.updateBeadFields()` — filtering out `gt:held`. Then `escalateToActiveCadence()` is called to arm the alarm. + +### Notes for future implementors + +- The `createBead` tRPC procedure creates an `open` bead with `gt:held` label (unless `startImmediately=true`). The reconciler's Rule 1 excludes beads with `gt:held` label from dispatch. +- The `startBead` tRPC procedure removes `gt:held` from labels and arms the reconciler alarm via `townStub.startHeldBead()`. +- The `enrichBead` procedure calls Workers AI (`@cf/meta/llama-3.1-8b-instruct`) to suggest title + labels. It returns `null` if the AI response is unparseable. +- All three new tRPC procedures follow the `gastownProcedure` pattern with `verifyRigOwnership` (createBead, startBead) or `verifyTownOwnership` (enrichBead) for authorization. +- The mayor is notified via `townStub.notifyMayorOfNewBead()` when `startImmediately=false`. + +--- + +## Bead 2: UI (CreateBeadDrawer + MDXEditor) + +### Status: in progress + +### Deviations from plan + +- The `createBead`, `startBead`, and `enrichBead` procedures from bead 0/1 were NOT yet reflected in `apps/web/src/lib/gastown/types/router.d.ts`. Added them manually to the declaration file (both the top-level `gastawnRouter` section and the nested `wrappedGastawnRouter` section). +- Used `@mdxeditor/editor` with a dynamic import wrapper. The MDXEditor CSS import must be in the non-SSR wrapper file (not the parent component) to avoid Next.js SSR issues. +- MDXEditor dark theme: overriding via CSS variables on the container element is the cleanest approach since the library doesn't natively support dark mode out of the box. +- Debounce for AI enrichment is implemented with `useEffect` + `setTimeout`/`clearTimeout` rather than a library like `use-debounce`, since that would be a new dependency. + +### Notes for future implementors + +- MDXEditor requires `ssr: false` dynamic import in Next.js. The `MarkdownEditor.tsx` wrapper imports the CSS and renders MDXEditor directly; the parent uses `dynamic(() => import('./MarkdownEditor'), { ssr: false })`. +- The `CreateBeadDrawer` uses `vaul` `Drawer.Root` (same pattern as `BeadDetailDrawer`) for the right-side slide-in. +- AI enrichment fires on body text > 20 chars after a 1500ms debounce. `userEditedTitle` state prevents AI overwriting manual title changes. +- Labels from `enrichBead` are shown as `✨` chips. The user can remove them. Custom label entry via a text input "+ add" pattern. +- `startImmediately=false` (default): bead gets `gt:held` label and mayor is notified. `startImmediately=true`: bead is created and dispatched immediately. + +--- + +## Bead 3: Mayor system prompt + +### Status: completed + +### Deviations from plan + +- `notifyMayorOfNewBead()` was already partially implemented by bead 1 (with a slightly different message). Updated the message to match the spec exactly (adding the `To start the bead immediately, remove the gt:held label via gt_bead_update.` line and the `When you reply, create a message bead` instruction using the exact wording from the bead spec). +- The mayor system prompt lives in `services/gastown/src/prompts/mayor-system.prompt.ts` — a standalone file exporting `buildMayorSystemPrompt()`. Added the new `## User-Created Beads` section at the end, before the closing backtick. +- `gt_bead_update` in `mayor-tools.ts` already exposed both `labels: string[]` and `body: string` — no changes needed there. + +### Notes for future implementors + +- The mayor system prompt is in `services/gastown/src/prompts/mayor-system.prompt.ts`, NOT inline in `Town.do.ts`. It's called via `dispatch.systemPromptForRole()` which calls `buildMayorSystemPrompt()` from `container-dispatch.ts`. +- `sendMayorMessage()` in `Town.do.ts` sends a message to the mayor's running container via the kilo API. It's called from `notifyMayorOfNewBead()` after a user creates a held bead. +- `gt_bead_update` (mayor-tools.ts:294) already has both `labels` and `body` parameters — no changes needed. +- The mayor sees the notification message as a user turn. It should respond by calling `gt_sling({ type: 'message', parent_bead_id: beadId, body: '...' })` to post its response back to the bead drawer. diff --git a/apps/web/package.json b/apps/web/package.json index 02f6875c16..0d32b68958 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -38,7 +38,6 @@ "@chat-adapter/slack": "^4.20.1", "@chat-adapter/state-memory": "^4.20.1", "@chat-adapter/state-redis": "^4.20.1", - "google-auth-library": "^10.4.1", "@kilocode/db": "workspace:*", "@kilocode/encryption": "workspace:*", "@kilocode/kiloclaw-secret-catalog": "workspace:*", @@ -46,6 +45,7 @@ "@lottiefiles/dotlottie-react": "^0.17.15", "@mdx-js/loader": "^3.1.1", "@mdx-js/react": "^3.1.1", + "@mdxeditor/editor": "^3.55.0", "@mistralai/mistralai": "^1.15.1", "@monaco-editor/react": "^4.7.0", "@next/bundle-analyzer": "^16.1.6", @@ -111,6 +111,7 @@ "eventsource-parser": "^3.0.6", "fflate": "^0.8.2", "form-data": "^4.0.5", + "google-auth-library": "^10.4.1", "jotai": "^2.18.1", "jotai-minidb": "^0.0.8", "js-cookie": "^3.0.5", diff --git a/apps/web/src/app/(app)/gastown/[townId]/rigs/[rigId]/RigDetailPageClient.tsx b/apps/web/src/app/(app)/gastown/[townId]/rigs/[rigId]/RigDetailPageClient.tsx index a76515f924..c9385f2efc 100644 --- a/apps/web/src/app/(app)/gastown/[townId]/rigs/[rigId]/RigDetailPageClient.tsx +++ b/apps/web/src/app/(app)/gastown/[townId]/rigs/[rigId]/RigDetailPageClient.tsx @@ -10,7 +10,7 @@ import { Skeleton } from '@/components/ui/skeleton'; import { BeadBoard } from '@/components/gastown/BeadBoard'; import { AgentCard } from '@/components/gastown/AgentCard'; import { ConvoyTimeline } from '@/components/gastown/ConvoyTimeline'; -import { SlingDialog } from '@/components/gastown/SlingDialog'; +import { CreateBeadDrawer } from '@/components/gastown/CreateBeadDrawer'; import { useDrawerStack } from '@/components/gastown/DrawerStack'; import { Plus, @@ -39,7 +39,7 @@ export function RigDetailPageClient({ }: RigDetailPageClientProps) { const townBasePath = basePathOverride ?? `/gastown/${townId}`; const trpc = useGastownTRPC(); - const [isSlingOpen, setIsSlingOpen] = useState(false); + const [isCreateBeadOpen, setIsCreateBeadOpen] = useState(false); const [convoysCollapsed, setConvoysCollapsed] = useState(false); const { open: openDrawer } = useDrawerStack(); @@ -71,6 +71,16 @@ export function RigDetailPageClient({ }) ); + const startBead = useMutation( + trpc.gastown.startBead.mutationOptions({ + onSuccess: () => { + void queryClient.invalidateQueries({ queryKey: trpc.gastown.listBeads.queryKey() }); + toast.success('Bead started'); + }, + onError: err => toast.error(err.message), + }) + ); + const deleteAgent = useMutation( trpc.gastown.deleteAgent.mutationOptions({ onSuccess: () => { @@ -156,11 +166,11 @@ export function RigDetailPageClient({ @@ -228,6 +238,7 @@ export function RigDetailPageClient({ } }} onSelectBead={bead => openDrawer({ type: 'bead', beadId: bead.bead_id, rigId })} + onStartBead={beadId => startBead.mutate({ rigId, beadId })} agentNameById={agentNameById} /> @@ -285,7 +296,12 @@ export function RigDetailPageClient({ - setIsSlingOpen(false)} /> + setIsCreateBeadOpen(false)} + /> ); } diff --git a/apps/web/src/components/gastown/BeadBoard.tsx b/apps/web/src/components/gastown/BeadBoard.tsx index eb2316f619..b4d18cb295 100644 --- a/apps/web/src/components/gastown/BeadBoard.tsx +++ b/apps/web/src/components/gastown/BeadBoard.tsx @@ -4,7 +4,7 @@ import { Card, CardContent } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Skeleton } from '@/components/ui/skeleton'; import { cn } from '@/lib/utils'; -import { Trash2 } from 'lucide-react'; +import { Trash2, Clock, Play } from 'lucide-react'; import { formatDistanceToNow } from 'date-fns'; import { motion, AnimatePresence } from 'motion/react'; @@ -26,6 +26,7 @@ type BeadBoardProps = { isLoading: boolean; onDeleteBead?: (beadId: string) => void; onSelectBead?: (bead: Bead) => void; + onStartBead?: (beadId: string) => void; selectedBeadId?: string | null; agentNameById?: Record; }; @@ -53,22 +54,31 @@ const priorityColors: Record = { critical: 'text-red-300', }; +const HELD_LABEL = 'gt:held'; + +function isHeld(bead: Bead) { + return bead.labels.includes(HELD_LABEL); +} + function BeadCard({ bead, onDelete, onSelect, + onStart, isSelected, agentNameById, }: { bead: Bead; onDelete?: () => void; onSelect?: () => void; + onStart?: () => void; isSelected?: boolean; agentNameById?: Record; }) { const assigneeName = bead.assignee_agent_bead_id ? agentNameById?.[bead.assignee_agent_bead_id] : null; + const held = isHeld(bead); const handleKeyDown = (e: React.KeyboardEvent) => { if (!onSelect) return; @@ -81,8 +91,9 @@ function BeadCard({ return (
-

{bead.title}

+
+ {held && ( + + + + )} +

{bead.title}

+
{bead.priority} @@ -124,9 +142,16 @@ function BeadCard({
- - {bead.type} - + {held ? ( + + + Held + + ) : ( + + {bead.type} + + )} {formatDistanceToNow(new Date(bead.created_at), { addSuffix: true })} @@ -137,17 +162,34 @@ function BeadCard({ )}
- {bead.labels.length > 0 && ( + {bead.labels.filter(l => l !== HELD_LABEL).length > 0 && (
- {bead.labels.map(label => ( - - {label} - - ))} + {bead.labels + .filter(l => l !== HELD_LABEL) + .map(label => ( + + {label} + + ))}
)}
+ + {/* Hover quick action for held beads */} + {held && onStart && ( + + )}
); } @@ -157,6 +199,7 @@ export function BeadBoard({ isLoading, onDeleteBead, onSelectBead, + onStartBead, selectedBeadId, agentNameById, }: BeadBoardProps) { @@ -235,6 +278,7 @@ export function BeadBoard({ bead={bead} onDelete={onDeleteBead ? () => onDeleteBead(bead.bead_id) : undefined} onSelect={onSelectBead ? () => onSelectBead(bead) : undefined} + onStart={onStartBead ? () => onStartBead(bead.bead_id) : undefined} isSelected={selectedBeadId === bead.bead_id} agentNameById={agentNameById} /> diff --git a/apps/web/src/components/gastown/CreateBeadDrawer.tsx b/apps/web/src/components/gastown/CreateBeadDrawer.tsx new file mode 100644 index 0000000000..e1da4110c6 --- /dev/null +++ b/apps/web/src/components/gastown/CreateBeadDrawer.tsx @@ -0,0 +1,350 @@ +'use client'; + +import { useState, useEffect, useRef } from 'react'; +import dynamic from 'next/dynamic'; +import { Drawer } from 'vaul'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { useGastownTRPC } from '@/lib/gastown/trpc'; +import { toast } from 'sonner'; +import { Button } from '@/components/Button'; +import { Input } from '@/components/ui/input'; +import { X, Plus, Sparkles, Loader2 } from 'lucide-react'; + +const MDXEditorComponent = dynamic( + () => import('@/components/gastown/MarkdownEditor').then(m => ({ default: m.MarkdownEditor })), + { ssr: false } +); + +type CreateBeadDrawerProps = { + rigId: string; + townId: string; + isOpen: boolean; + onClose: () => void; +}; + +export function CreateBeadDrawer({ rigId, townId, isOpen, onClose }: CreateBeadDrawerProps) { + const trpc = useGastownTRPC(); + const queryClient = useQueryClient(); + + const [title, setTitle] = useState(''); + const [body, setBody] = useState(''); + const [labels, setLabels] = useState([]); + const [aiLabels, setAiLabels] = useState([]); + const [labelInput, setLabelInput] = useState(''); + const [showLabelInput, setShowLabelInput] = useState(false); + const [startImmediately, setStartImmediately] = useState(false); + const [userEditedTitle, setUserEditedTitle] = useState(false); + const [isEnriching, setIsEnriching] = useState(false); + + const debounceRef = useRef | null>(null); + // Tracks the sequence number of the most recently fired enrichment request. + // When a response arrives we compare against this to discard stale results. + const enrichSeqRef = useRef(0); + // Mirror of userEditedTitle read inside async callbacks so the response + // handler sees edits that happened after the request started. + const userEditedTitleRef = useRef(false); + + useEffect(() => { + userEditedTitleRef.current = userEditedTitle; + }, [userEditedTitle]); + + const createBead = useMutation( + trpc.gastown.createBead.mutationOptions({ + onSuccess: () => { + void queryClient.invalidateQueries({ queryKey: trpc.gastown.listBeads.queryKey() }); + toast.success(startImmediately ? 'Work dispatched' : 'Bead created — notifying mayor'); + handleClose(); + }, + onError: err => toast.error(err.message), + }) + ); + + const enrichBead = useMutation(trpc.gastown.enrichBead.mutationOptions()); + + // Reset state when drawer opens/closes + useEffect(() => { + if (!isOpen) { + setTitle(''); + setBody(''); + setLabels([]); + setAiLabels([]); + setLabelInput(''); + setShowLabelInput(false); + setStartImmediately(false); + setUserEditedTitle(false); + userEditedTitleRef.current = false; + setIsEnriching(false); + if (debounceRef.current) { + clearTimeout(debounceRef.current); + } + // Advance the sequence so any in-flight enrichment response is discarded + enrichSeqRef.current++; + } + }, [isOpen]); + + // Debounced AI enrichment + useEffect(() => { + if (debounceRef.current) { + clearTimeout(debounceRef.current); + } + + if (body.length > 20) { + debounceRef.current = setTimeout(() => { + const seq = ++enrichSeqRef.current; + setIsEnriching(true); + enrichBead.mutate( + { body, townId }, + { + onSuccess: result => { + // Discard the response if a newer request has since been fired + // or if the drawer has been closed and state has been reset. + if (seq !== enrichSeqRef.current) return; + setIsEnriching(false); + if (result) { + if (!userEditedTitleRef.current) { + setTitle(result.title); + } + setAiLabels(result.labels); + } + }, + onError: () => { + if (seq !== enrichSeqRef.current) return; + setIsEnriching(false); + }, + } + ); + }, 1500); + } + + return () => { + if (debounceRef.current) { + clearTimeout(debounceRef.current); + } + }; + }, [body, townId]); // eslint-disable-line react-hooks/exhaustive-deps + + const handleClose = () => { + onClose(); + }; + + const handleTitleChange = (e: React.ChangeEvent) => { + setTitle(e.target.value); + setUserEditedTitle(true); + }; + + const handleAddLabel = () => { + const trimmed = labelInput.trim(); + if (trimmed && !labels.includes(trimmed) && !aiLabels.includes(trimmed)) { + setLabels(prev => [...prev, trimmed]); + setLabelInput(''); + setShowLabelInput(false); + } + }; + + const handleLabelKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + e.preventDefault(); + handleAddLabel(); + } else if (e.key === 'Escape') { + setLabelInput(''); + setShowLabelInput(false); + } + }; + + const removeLabel = (label: string) => { + setLabels(prev => prev.filter(l => l !== label)); + }; + + const removeAiLabel = (label: string) => { + setAiLabels(prev => prev.filter(l => l !== label)); + }; + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + if (!title.trim()) return; + const allLabels = [...labels, ...aiLabels]; + createBead.mutate({ + rigId, + townId, + title: title.trim(), + body: body.trim() || undefined, + labels: allLabels.length > 0 ? allLabels : undefined, + startImmediately, + }); + }; + + const allLabels = [...labels, ...aiLabels]; + + return ( + !open && handleClose()} direction="right"> + + + +
+ {/* Header */} +
+ + New Bead + + +
+ + {/* Form */} +
+
+ {/* Title */} +
+
+ + {isEnriching && } +
+ +
+ + {/* Labels */} +
+
+ + {isEnriching && } +
+
+ {/* AI-suggested labels */} + {aiLabels.map(label => ( + + + {label} + + + ))} + {/* Manually added labels */} + {labels.map(label => ( + + {label} + + + ))} + {/* Add label input */} + {showLabelInput ? ( + setLabelInput(e.target.value)} + onKeyDown={handleLabelKeyDown} + onBlur={handleAddLabel} + placeholder="label name" + className="rounded-md border border-white/[0.12] bg-white/[0.04] px-2 py-0.5 text-[11px] text-white/70 placeholder:text-white/25 outline-none focus:border-white/20" + style={{ width: '80px' }} + /> + ) : ( + + )} + {allLabels.length === 0 && !showLabelInput && ( + No labels yet + )} +
+
+ + {/* Body / MDXEditor */} +
+ + +
+
+ + {/* Footer */} +
+ {/* Start immediately toggle */} +
+ +
+ + {/* Action buttons */} +
+ + +
+
+
+
+
+
+
+ ); +} diff --git a/apps/web/src/components/gastown/MarkdownEditor.tsx b/apps/web/src/components/gastown/MarkdownEditor.tsx new file mode 100644 index 0000000000..f24f4ce874 --- /dev/null +++ b/apps/web/src/components/gastown/MarkdownEditor.tsx @@ -0,0 +1,57 @@ +'use client'; + +import { + MDXEditor, + headingsPlugin, + listsPlugin, + quotePlugin, + markdownShortcutPlugin, + toolbarPlugin, + BoldItalicUnderlineToggles, + UndoRedo, +} from '@mdxeditor/editor'; +import '@mdxeditor/editor/style.css'; + +type MarkdownEditorProps = { + value: string; + onChange: (value: string) => void; + placeholder?: string; +}; + +export function MarkdownEditor({ value, onChange, placeholder }: MarkdownEditorProps) { + return ( +
+ + ( + <> + + + + ), + }), + ]} + /> +
+ ); +} diff --git a/apps/web/src/components/gastown/drawer-panels/BeadPanel.tsx b/apps/web/src/components/gastown/drawer-panels/BeadPanel.tsx index 35f4644ae8..26ac50ff0a 100644 --- a/apps/web/src/components/gastown/drawer-panels/BeadPanel.tsx +++ b/apps/web/src/components/gastown/drawer-panels/BeadPanel.tsx @@ -10,7 +10,7 @@ import { Textarea } from '@/components/ui/textarea'; import { BeadEventTimeline, extractPrUrl } from '@/components/gastown/ActivityFeed'; import type { ResourceRef } from '@/components/gastown/DrawerStack'; -import { format } from 'date-fns'; +import { format, formatDistanceToNow } from 'date-fns'; import { Clock, ExternalLink, @@ -33,6 +33,8 @@ import { X, Save, Loader2, + Play, + MessageCircle, } from 'lucide-react'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; @@ -151,6 +153,16 @@ export function BeadPanel({ }) ); + const { mutate: doStartBead, isPending: isStartPending } = useMutation( + trpc.gastown.startBead.mutationOptions({ + onSuccess: () => { + void queryClient.invalidateQueries({ + queryKey: trpc.gastown.listBeads.queryKey({ rigId }), + }); + }, + }) + ); + const handleSave = useCallback(() => { if (!bead) return; @@ -232,6 +244,14 @@ export function BeadPanel({ c => c.id === beadConvoyId || c.beads.some(b => b.bead_id === bead.bead_id) ); + // Held bead detection + const isHeld = bead.labels.includes('gt:held'); + + // Mayor responses: message-type child beads + const mayorResponses = allBeads.filter( + b => b.type === 'message' && b.parent_bead_id === bead.bead_id + ); + return (
{/* Title area */} @@ -291,11 +311,18 @@ export function BeadPanel({
) : (
- - {bead.status.replace('_', ' ')} - + {isHeld ? ( + + + Held + + ) : ( + + {bead.status.replace('_', ' ')} + + )} {bead.type} @@ -305,6 +332,21 @@ export function BeadPanel({ {bead.priority} + {isHeld && ( + + )}
)} @@ -527,6 +569,45 @@ export function BeadPanel({ )} + {/* Mayor responses thread */} + {mayorResponses.length > 0 && ( +
+
+ + + Mayor Responses + +
+
+ {mayorResponses.map(msg => ( +
+
+ M +
+
+
+ Mayor + + {formatDistanceToNow(new Date(msg.created_at), { addSuffix: true })} + +
+ {msg.body ? ( +
+ {msg.body} +
+ ) : ( + No content + )} +
+
+ ))} +
+
+ )} + {/* Event Timeline */}
diff --git a/apps/web/src/lib/gastown/types/router.d.ts b/apps/web/src/lib/gastown/types/router.d.ts index da9eff6d5f..99e9e3e5c0 100644 --- a/apps/web/src/lib/gastown/types/router.d.ts +++ b/apps/web/src/lib/gastown/types/router.d.ts @@ -1386,6 +1386,84 @@ export declare const gastownRouter: import('@trpc/server').TRPCBuiltRouter< output: never; meta: object; }>; + createBead: import('@trpc/server').TRPCMutationProcedure<{ + input: { + rigId: string; + title: string; + body?: string | undefined; + labels?: string[] | undefined; + startImmediately?: boolean | undefined; + townId?: string | undefined; + }; + output: { + bead_id: string; + type: + | 'agent' + | 'convoy' + | 'escalation' + | 'issue' + | 'merge_request' + | 'message' + | 'molecule'; + status: 'closed' | 'failed' | 'in_progress' | 'in_review' | 'open'; + title: string; + body: string | null; + rig_id: string | null; + parent_bead_id: string | null; + assignee_agent_bead_id: string | null; + priority: 'critical' | 'high' | 'low' | 'medium'; + labels: string[]; + metadata: Record; + created_by: string | null; + created_at: string; + updated_at: string; + closed_at: string | null; + }; + meta: object; + }>; + startBead: import('@trpc/server').TRPCMutationProcedure<{ + input: { + rigId: string; + beadId: string; + townId?: string | undefined; + }; + output: { + bead_id: string; + type: + | 'agent' + | 'convoy' + | 'escalation' + | 'issue' + | 'merge_request' + | 'message' + | 'molecule'; + status: 'closed' | 'failed' | 'in_progress' | 'in_review' | 'open'; + title: string; + body: string | null; + rig_id: string | null; + parent_bead_id: string | null; + assignee_agent_bead_id: string | null; + priority: 'critical' | 'high' | 'low' | 'medium'; + labels: string[]; + metadata: Record; + created_by: string | null; + created_at: string; + updated_at: string; + closed_at: string | null; + }; + meta: object; + }>; + enrichBead: import('@trpc/server').TRPCMutationProcedure<{ + input: { + body: string; + townId: string; + }; + output: { + title: string; + labels: string[]; + } | null; + meta: object; + }>; }> >; export type GastownRouter = typeof gastownRouter; @@ -2790,6 +2868,84 @@ export declare const wrappedGastownRouter: import('@trpc/server').TRPCBuiltRoute output: never; meta: object; }>; + createBead: import('@trpc/server').TRPCMutationProcedure<{ + input: { + rigId: string; + title: string; + body?: string | undefined; + labels?: string[] | undefined; + startImmediately?: boolean | undefined; + townId?: string | undefined; + }; + output: { + bead_id: string; + type: + | 'agent' + | 'convoy' + | 'escalation' + | 'issue' + | 'merge_request' + | 'message' + | 'molecule'; + status: 'closed' | 'failed' | 'in_progress' | 'in_review' | 'open'; + title: string; + body: string | null; + rig_id: string | null; + parent_bead_id: string | null; + assignee_agent_bead_id: string | null; + priority: 'critical' | 'high' | 'low' | 'medium'; + labels: string[]; + metadata: Record; + created_by: string | null; + created_at: string; + updated_at: string; + closed_at: string | null; + }; + meta: object; + }>; + startBead: import('@trpc/server').TRPCMutationProcedure<{ + input: { + rigId: string; + beadId: string; + townId?: string | undefined; + }; + output: { + bead_id: string; + type: + | 'agent' + | 'convoy' + | 'escalation' + | 'issue' + | 'merge_request' + | 'message' + | 'molecule'; + status: 'closed' | 'failed' | 'in_progress' | 'in_review' | 'open'; + title: string; + body: string | null; + rig_id: string | null; + parent_bead_id: string | null; + assignee_agent_bead_id: string | null; + priority: 'critical' | 'high' | 'low' | 'medium'; + labels: string[]; + metadata: Record; + created_by: string | null; + created_at: string; + updated_at: string; + closed_at: string | null; + }; + meta: object; + }>; + enrichBead: import('@trpc/server').TRPCMutationProcedure<{ + input: { + body: string; + townId: string; + }; + output: { + title: string; + labels: string[]; + } | null; + meta: object; + }>; }> >; }> diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 04df5eba8d..d16777a212 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -487,6 +487,9 @@ importers: '@mdx-js/react': specifier: ^3.1.1 version: 3.1.1(@types/react@19.2.14)(react@19.2.4) + '@mdxeditor/editor': + specifier: ^3.55.0 + version: 3.55.0(@codemirror/language@6.12.3)(@lezer/highlight@1.2.3)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@mistralai/mistralai': specifier: ^1.15.1 version: 1.15.1 @@ -3216,6 +3219,111 @@ packages: '@cloudflare/workers-types@4.20260313.1': resolution: {integrity: sha512-jMEeX3RKfOSVqqXRKr/ulgglcTloeMzSH3FdzIfqJHtvc12/ELKd5Ldsg8ZHahKX/4eRxYdw3kbzb8jLXbq/jQ==} + '@codemirror/autocomplete@6.20.1': + resolution: {integrity: sha512-1cvg3Vz1dSSToCNlJfRA2WSI4ht3K+WplO0UMOgmUYPivCyy2oueZY6Lx7M9wThm7SDUBViRmuT+OG/i8+ON9A==} + + '@codemirror/commands@6.10.3': + resolution: {integrity: sha512-JFRiqhKu+bvSkDLI+rUhJwSxQxYb759W5GBezE8Uc8mHLqC9aV/9aTC7yJSqCtB3F00pylrLCwnyS91Ap5ej4Q==} + + '@codemirror/lang-angular@0.1.4': + resolution: {integrity: sha512-oap+gsltb/fzdlTQWD6BFF4bSLKcDnlxDsLdePiJpCVNKWXSTAbiiQeYI3UmES+BLAdkmIC1WjyztC1pi/bX4g==} + + '@codemirror/lang-cpp@6.0.3': + resolution: {integrity: sha512-URM26M3vunFFn9/sm6rzqrBzDgfWuDixp85uTY49wKudToc2jTHUrKIGGKs+QWND+YLofNNZpxcNGRynFJfvgA==} + + '@codemirror/lang-css@6.3.1': + resolution: {integrity: sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==} + + '@codemirror/lang-go@6.0.1': + resolution: {integrity: sha512-7fNvbyNylvqCphW9HD6WFnRpcDjr+KXX/FgqXy5H5ZS0eC5edDljukm/yNgYkwTsgp2busdod50AOTIy6Jikfg==} + + '@codemirror/lang-html@6.4.11': + resolution: {integrity: sha512-9NsXp7Nwp891pQchI7gPdTwBuSuT3K65NGTHWHNJ55HjYcHLllr0rbIZNdOzas9ztc1EUVBlHou85FFZS4BNnw==} + + '@codemirror/lang-java@6.0.2': + resolution: {integrity: sha512-m5Nt1mQ/cznJY7tMfQTJchmrjdjQ71IDs+55d1GAa8DGaB8JXWsVCkVT284C3RTASaY43YknrK2X3hPO/J3MOQ==} + + '@codemirror/lang-javascript@6.2.5': + resolution: {integrity: sha512-zD4e5mS+50htS7F+TYjBPsiIFGanfVqg4HyUz6WNFikgOPf2BgKlx+TQedI1w6n/IqRBVBbBWmGFdLB/7uxO4A==} + + '@codemirror/lang-jinja@6.0.1': + resolution: {integrity: sha512-P5kyHLObzjtbGj16h+hyvZTxJhSjBEeSx4wMjbnAf3b0uwTy2+F0zGjMZL4PQOm/mh2eGZ5xUDVZXgwP783Nsw==} + + '@codemirror/lang-json@6.0.2': + resolution: {integrity: sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==} + + '@codemirror/lang-less@6.0.2': + resolution: {integrity: sha512-EYdQTG22V+KUUk8Qq582g7FMnCZeEHsyuOJisHRft/mQ+ZSZ2w51NupvDUHiqtsOy7It5cHLPGfHQLpMh9bqpQ==} + + '@codemirror/lang-liquid@6.3.2': + resolution: {integrity: sha512-6PDVU3ZnfeYyz1at1E/ttorErZvZFXXt1OPhtfe1EZJ2V2iDFa0CwPqPgG5F7NXN0yONGoBogKmFAafKTqlwIw==} + + '@codemirror/lang-markdown@6.5.0': + resolution: {integrity: sha512-0K40bZ35jpHya6FriukbgaleaqzBLZfOh7HuzqbMxBXkbYMJDxfF39c23xOgxFezR+3G+tR2/Mup+Xk865OMvw==} + + '@codemirror/lang-php@6.0.2': + resolution: {integrity: sha512-ZKy2v1n8Fc8oEXj0Th0PUMXzQJ0AIR6TaZU+PbDHExFwdu+guzOA4jmCHS1Nz4vbFezwD7LyBdDnddSJeScMCA==} + + '@codemirror/lang-python@6.2.1': + resolution: {integrity: sha512-IRjC8RUBhn9mGR9ywecNhB51yePWCGgvHfY1lWN/Mrp3cKuHr0isDKia+9HnvhiWNnMpbGhWrkhuWOc09exRyw==} + + '@codemirror/lang-rust@6.0.2': + resolution: {integrity: sha512-EZaGjCUegtiU7kSMvOfEZpaCReowEf3yNidYu7+vfuGTm9ow4mthAparY5hisJqOHmJowVH3Upu+eJlUji6qqA==} + + '@codemirror/lang-sass@6.0.2': + resolution: {integrity: sha512-l/bdzIABvnTo1nzdY6U+kPAC51czYQcOErfzQ9zSm9D8GmNPD0WTW8st/CJwBTPLO8jlrbyvlSEcN20dc4iL0Q==} + + '@codemirror/lang-sql@6.10.0': + resolution: {integrity: sha512-6ayPkEd/yRw0XKBx5uAiToSgGECo/GY2NoJIHXIIQh1EVwLuKoU8BP/qK0qH5NLXAbtJRLuT73hx7P9X34iO4w==} + + '@codemirror/lang-vue@0.1.3': + resolution: {integrity: sha512-QSKdtYTDRhEHCfo5zOShzxCmqKJvgGrZwDQSdbvCRJ5pRLWBS7pD/8e/tH44aVQT6FKm0t6RVNoSUWHOI5vNug==} + + '@codemirror/lang-wast@6.0.2': + resolution: {integrity: sha512-Imi2KTpVGm7TKuUkqyJ5NRmeFWF7aMpNiwHnLQe0x9kmrxElndyH0K6H/gXtWwY6UshMRAhpENsgfpSwsgmC6Q==} + + '@codemirror/lang-xml@6.1.0': + resolution: {integrity: sha512-3z0blhicHLfwi2UgkZYRPioSgVTo9PV5GP5ducFH6FaHy0IAJRg+ixj5gTR1gnT/glAIC8xv4w2VL1LoZfs+Jg==} + + '@codemirror/lang-yaml@6.1.3': + resolution: {integrity: sha512-AZ8DJBuXGVHybpBQhmZtgew5//4hv3tdkXnr3vDmOUMJRuB6vn/uuwtmTOTlqEaQFg3hQSVeA90NmvIQyUV6FQ==} + + '@codemirror/language-data@6.5.2': + resolution: {integrity: sha512-CPkWBKrNS8stYbEU5kwBwTf3JB1kghlbh4FSAwzGW2TEscdeHHH4FGysREW86Mqnj3Qn09s0/6Ea/TutmoTobg==} + + '@codemirror/language@6.12.3': + resolution: {integrity: sha512-QwCZW6Tt1siP37Jet9Tb02Zs81TQt6qQrZR2H+eGMcFsL1zMrk2/b9CLC7/9ieP1fjIUMgviLWMmgiHoJrj+ZA==} + + '@codemirror/legacy-modes@6.5.2': + resolution: {integrity: sha512-/jJbwSTazlQEDOQw2FJ8LEEKVS72pU0lx6oM54kGpL8t/NJ2Jda3CZ4pcltiKTdqYSRk3ug1B3pil1gsjA6+8Q==} + + '@codemirror/lint@6.9.5': + resolution: {integrity: sha512-GElsbU9G7QT9xXhpUg1zWGmftA/7jamh+7+ydKRuT0ORpWS3wOSP0yT1FOlIZa7mIJjpVPipErsyvVqB9cfTFA==} + + '@codemirror/merge@6.12.1': + resolution: {integrity: sha512-GA8hBq2T+IFM0sb5fk8CunTrqOulA3zurJmHtzcU15EMnL8aYpVINfJ5bkfd53M4ikwoew4Y1ydtSaAlk6+B1w==} + + '@codemirror/search@6.6.0': + resolution: {integrity: sha512-koFuNXcDvyyotWcgOnZGmY7LZqEOXZaaxD/j6n18TCLx2/9HieZJ5H6hs1g8FiRxBD0DNfs0nXn17g872RmYdw==} + + '@codemirror/state@6.6.0': + resolution: {integrity: sha512-4nbvra5R5EtiCzr9BTHiTLc+MLXK2QGiAVYMyi8PkQd3SR+6ixar/Q/01Fa21TBIDOZXgeWV4WppsQolSreAPQ==} + + '@codemirror/view@6.41.1': + resolution: {integrity: sha512-ToDnWKbBnke+ZLrP6vgTTDScGi5H37YYuZGniQaBzxMVdtCxMrslsmtnOvbPZk4RX9bvkQqnWR/WS/35tJA0qg==} + + '@codesandbox/nodebox@0.1.8': + resolution: {integrity: sha512-2VRS6JDSk+M+pg56GA6CryyUSGPjBEe8Pnae0QL3jJF1mJZJVMDKr93gJRtBbLkfZN6LD/DwMtf+2L0bpWrjqg==} + + '@codesandbox/sandpack-client@2.19.8': + resolution: {integrity: sha512-CMV4nr1zgKzVpx4I3FYvGRM5YT0VaQhALMW9vy4wZRhEyWAtJITQIqZzrTGWqB1JvV7V72dVEUCUPLfYz5hgJQ==} + + '@codesandbox/sandpack-react@2.20.0': + resolution: {integrity: sha512-takd1YpW/PMQ6KPQfvseWLHWklJovGY8QYj8MtWnskGKbjOGJ6uZfyZbcJ6aCFLQMpNyjTqz9AKNbvhCOZ1TUQ==} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + react-dom: ^16.8.0 || ^17 || ^18 || ^19 + '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -4175,6 +4283,128 @@ packages: '@kilocode/sdk@7.2.14': resolution: {integrity: sha512-Naz83lFrsbavuDp6UwxRuglOaSNvRBsZfcRNvb7RpWYAwbuJP0dBdhpXj6uO3ta5qxeQ2JzxKNC9Ffz+LCLLDg==} + '@lexical/clipboard@0.35.0': + resolution: {integrity: sha512-ko7xSIIiayvDiqjNDX6fgH9RlcM6r9vrrvJYTcfGVBor5httx16lhIi0QJZ4+RNPvGtTjyFv4bwRmsixRRwImg==} + + '@lexical/code@0.35.0': + resolution: {integrity: sha512-ox4DZwETQ9IA7+DS6PN8RJNwSAF7RMjL7YTVODIqFZ5tUFIf+5xoCHbz7Fll0Bvixlp12hVH90xnLwTLRGpkKw==} + + '@lexical/devtools-core@0.35.0': + resolution: {integrity: sha512-C2wwtsMCR6ZTfO0TqpSM17RLJWyfHmifAfCTjFtOJu15p3M6NO/nHYK5Mt7YMQteuS89mOjB4ng8iwoLEZ6QpQ==} + peerDependencies: + react: '>=17.x' + react-dom: '>=17.x' + + '@lexical/dragon@0.35.0': + resolution: {integrity: sha512-SL6mT5pcqrt6hEbJ16vWxip5+r3uvMd0bQV5UUxuk+cxIeuP86iTgRh0HFR7SM2dRTYovL6/tM/O+8QLAUGTIg==} + + '@lexical/hashtag@0.35.0': + resolution: {integrity: sha512-LYJWzXuO2ZjKsvQwrLkNZiS2TsjwYkKjlDgtugzejquTBQ/o/nfSn/MmVx6EkYLOYizaJemmZbz3IBh+u732FA==} + + '@lexical/history@0.35.0': + resolution: {integrity: sha512-onjDRLLxGbCfHexSxxrQaDaieIHyV28zCDrbxR5dxTfW8F8PxjuNyuaG0z6o468AXYECmclxkP+P4aT6poHEpQ==} + + '@lexical/html@0.35.0': + resolution: {integrity: sha512-rXGFE5S5rKsg3tVnr1s4iEgOfCApNXGpIFI3T2jGEShaCZ5HLaBY9NVBXnE9Nb49e9bkDkpZ8FZd1qokCbQXbw==} + + '@lexical/link@0.35.0': + resolution: {integrity: sha512-+0Wx6cBwO8TfdMzpkYFacsmgFh8X1rkiYbq3xoLvk3qV8upYxaMzK1s8Q1cpKmWyI0aZrU6z7fiK4vUqB7+69w==} + + '@lexical/list@0.35.0': + resolution: {integrity: sha512-owsmc8iwgExBX8sFe8fKTiwJVhYULt9hD1RZ/HwfaiEtRZZkINijqReOBnW2mJfRxBzhFSWc4NG3ISB+fHYzqw==} + + '@lexical/mark@0.35.0': + resolution: {integrity: sha512-W0hwMTAVeexvpk9/+J6n1G/sNkpI/Meq1yeDazahFLLAwXLHtvhIAq2P/klgFknDy1hr8X7rcsQuN/bqKcKHYg==} + + '@lexical/markdown@0.35.0': + resolution: {integrity: sha512-BlNyXZAt4gWidMw0SRWrhBETY1BpPglFBZI7yzfqukFqgXRh7HUQA28OYeI/nsx9pgNob8TiUduUwShqqvOdEA==} + + '@lexical/offset@0.35.0': + resolution: {integrity: sha512-DRE4Df6qYf2XiV6foh6KpGNmGAv2ANqt3oVXpyS6W8hTx3+cUuAA1APhCZmLNuU107um4zmHym7taCu6uXW5Yg==} + + '@lexical/overflow@0.35.0': + resolution: {integrity: sha512-B25YvnJQTGlZcrNv7b0PJBLWq3tl8sql497OHfYYLem7EOMPKKDGJScJAKM/91D4H/mMAsx5gnA/XgKobriuTg==} + + '@lexical/plain-text@0.35.0': + resolution: {integrity: sha512-lwBCUNMJf7Gujp2syVWMpKRahfbTv5Wq+H3HK1Q1gKH1P2IytPRxssCHvexw9iGwprSyghkKBlbF3fGpEdIJvQ==} + + '@lexical/react@0.35.0': + resolution: {integrity: sha512-uYAZSqumH8tRymMef+A0f2hQvMwplKK9DXamcefnk3vSNDHHqRWQXpiUo6kD+rKWuQmMbVa5RW4xRQebXEW+1A==} + peerDependencies: + react: '>=17.x' + react-dom: '>=17.x' + + '@lexical/rich-text@0.35.0': + resolution: {integrity: sha512-qEHu8g7vOEzz9GUz1VIUxZBndZRJPh9iJUFI+qTDHj+tQqnd5LCs+G9yz6jgNfiuWWpezTp0i1Vz/udNEuDPKQ==} + + '@lexical/selection@0.35.0': + resolution: {integrity: sha512-mMtDE7Q0nycXdFTTH/+ta6EBrBwxBB4Tg8QwsGntzQ1Cq//d838dpXpFjJOqHEeVHUqXpiuj+cBG8+bvz/rPRw==} + + '@lexical/table@0.35.0': + resolution: {integrity: sha512-9jlTlkVideBKwsEnEkqkdg7A3mije1SvmfiqoYnkl1kKJCLA5iH90ywx327PU0p+bdnURAytWUeZPXaEuEl2OA==} + + '@lexical/text@0.35.0': + resolution: {integrity: sha512-uaMh46BkysV8hK8wQwp5g/ByZW+2hPDt8ahAErxtf8NuzQem1FHG/f5RTchmFqqUDVHO3qLNTv4AehEGmXv8MA==} + + '@lexical/utils@0.35.0': + resolution: {integrity: sha512-2H393EYDnFznYCDFOW3MHiRzwEO5M/UBhtUjvTT+9kc+qhX4U3zc8ixQalo5UmZ5B2nh7L/inXdTFzvSRXtsRA==} + + '@lexical/yjs@0.35.0': + resolution: {integrity: sha512-3DSP7QpmTGYU9bN/yljP0PIao4tNIQtsR4ycauWNSawxs/GQCZtSmAPcLRnCm6qpqsDDjUtKjO/1Ej8FRp0m0w==} + peerDependencies: + yjs: '>=13.5.22' + + '@lezer/common@1.5.2': + resolution: {integrity: sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==} + + '@lezer/cpp@1.1.5': + resolution: {integrity: sha512-DIhSXmYtJKLehrjzDFN+2cPt547ySQ41nA8yqcDf/GxMc+YM736xqltFkvADL2M0VebU5I+3+4ks2Vv+Kyq3Aw==} + + '@lezer/css@1.3.3': + resolution: {integrity: sha512-RzBo8r+/6QJeow7aPHIpGVIH59xTcJXp399820gZoMo9noQDRVpJLheIBUicYwKcsbOYoBRoLZlf2720dG/4Tg==} + + '@lezer/go@1.0.1': + resolution: {integrity: sha512-xToRsYxwsgJNHTgNdStpcvmbVuKxTapV0dM0wey1geMMRc9aggoVyKgzYp41D2/vVOx+Ii4hmE206kvxIXBVXQ==} + + '@lezer/highlight@1.2.3': + resolution: {integrity: sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==} + + '@lezer/html@1.3.13': + resolution: {integrity: sha512-oI7n6NJml729m7pjm9lvLvmXbdoMoi2f+1pwSDJkl9d68zGr7a9Btz8NdHTGQZtW2DA25ybeuv/SyDb9D5tseg==} + + '@lezer/java@1.1.3': + resolution: {integrity: sha512-yHquUfujwg6Yu4Fd1GNHCvidIvJwi/1Xu2DaKl/pfWIA2c1oXkVvawH3NyXhCaFx4OdlYBVX5wvz2f7Aoa/4Xw==} + + '@lezer/javascript@1.5.4': + resolution: {integrity: sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA==} + + '@lezer/json@1.0.3': + resolution: {integrity: sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==} + + '@lezer/lr@1.4.10': + resolution: {integrity: sha512-rnCpTIBafOx4mRp43xOxDJbFipJm/c0cia/V5TiGlhmMa+wsSdoGmUN3w5Bqrks/09Q/D4tNAmWaT8p6NRi77A==} + + '@lezer/markdown@1.6.3': + resolution: {integrity: sha512-jpGm5Ps+XErS+xA4urw7ogEGkeZOahVQF21Z6oECF0sj+2liwZopd2+I8uH5I/vZsRuuze3OxBREIANLf6KKUw==} + + '@lezer/php@1.0.5': + resolution: {integrity: sha512-W7asp9DhM6q0W6DYNwIkLSKOvxlXRrif+UXBMxzsJUuqmhE7oVU+gS3THO4S/Puh7Xzgm858UNaFi6dxTP8dJA==} + + '@lezer/python@1.1.18': + resolution: {integrity: sha512-31FiUrU7z9+d/ElGQLJFXl+dKOdx0jALlP3KEOsGTex8mvj+SoE1FgItcHWK/axkxCHGUSpqIHt6JAWfWu9Rhg==} + + '@lezer/rust@1.0.2': + resolution: {integrity: sha512-Lz5sIPBdF2FUXcWeCu1//ojFAZqzTQNRga0aYv6dYXqJqPfMdCAI0NzajWUd4Xijj1IKJLtjoXRPMvTKWBcqKg==} + + '@lezer/sass@1.1.0': + resolution: {integrity: sha512-3mMGdCTUZ/84ArHOuXWQr37pnf7f+Nw9ycPUeKX+wu19b7pSMcZGLbaXwvD2APMBDOGxPmpK/O6S1v1EvLoqgQ==} + + '@lezer/xml@1.0.6': + resolution: {integrity: sha512-CdDwirL0OEaStFue/66ZmFSeppuL6Dwjlk8qk153mSQwiSH/Dlri4GNymrNWnUmPl2Um7QfV1FO9KFUyX3Twww==} + + '@lezer/yaml@1.0.4': + resolution: {integrity: sha512-2lrrHqxalACEbxIbsjhqGpSW8kWpUKuY6RHgnSAFZa6qK62wvnPxA8hGOwOoDbwHcOFs5M4o27mjGu+P7TvBmw==} + '@lottiefiles/dotlottie-react@0.17.15': resolution: {integrity: sha512-4wYAjsJhM28eUvJ/gT3KRM6fcyT7EM9n7PDrP71LaBTacc6bSN43qFTSJc1Li3QxUiraz23p0Q8EJBzXo8DsRw==} peerDependencies: @@ -4191,6 +4421,9 @@ packages: resolution: {integrity: sha512-qC72D4+CDdjGqJvkFMMEAtancHUQ7/d/tAiHf64z8MopFDmcrtbcJuerDtFceuAfQJ2pDSfCKCtbqoGBNnwg0w==} engines: {node: '>=8'} + '@marijn/find-cluster-break@1.0.2': + resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==} + '@mdx-js/loader@3.1.1': resolution: {integrity: sha512-0TTacJyZ9mDmY+VefuthVshaNIyCGZHJG2fMnGaDttCt8HmjUF7SizlHJpaCDoGnN635nK1wpzfpx/Xx5S4WnQ==} peerDependencies: @@ -4208,6 +4441,20 @@ packages: '@types/react': '>=16' react: '>=16' + '@mdxeditor/editor@3.55.0': + resolution: {integrity: sha512-ziJY12OQVrrdAcWAwG8njV7gPy8orEIodGdFTXpQVlIOjdV/FOIHMcETMc5XXfON3hw3uO1CcHDb3TZQQSgfqg==} + engines: {node: '>=16'} + peerDependencies: + react: '>= 18 || >= 19' + react-dom: '>= 18 || >= 19' + + '@mdxeditor/gurx@1.2.4': + resolution: {integrity: sha512-9ZykIFYhKaXaaSPCs1cuI+FvYDegJjbKwmA4ASE/zY+hJY6EYqvoye4esiO85CjhOw9aoD/izD/CU78/egVqmg==} + engines: {node: '>=16'} + peerDependencies: + react: '>= 18 || >= 19' + react-dom: '>= 18 || >= 19' + '@mistralai/mistralai@1.15.1': resolution: {integrity: sha512-fb995eiz3r0KsBGtRjFV+/iLbX+UpfalxpF+YitT3R6ukrPD4PN+FGwwmYcRFhNAzVzDUtTVxQYnjQWEnwV5nw==} @@ -4403,6 +4650,9 @@ packages: '@octokit/types@16.0.0': resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==} + '@open-draft/deferred-promise@2.2.0': + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + '@opentelemetry/api-logs@0.207.0': resolution: {integrity: sha512-lAb0jQRVyleQQGiuuvCOTDVspc14nx6XJjP4FspJ1sNARo3Regq4ZZbrc3rN4b1TYSuUCvgH+UXUPug4SLOqEQ==} engines: {node: '>=8.0.0'} @@ -5316,6 +5566,9 @@ packages: resolution: {integrity: sha512-oQG/FejNpItrxRHoyctYvT3rwGZOnK4jr3JdppO/c78ktDvkWiPXPHNsrDf33K9sZdRb6PR7gi4noIapu5q4HA==} engines: {node: '>=18.0.0', pnpm: '>=8'} + '@radix-ui/colors@3.0.0': + resolution: {integrity: sha512-FUOsGBkHrYJwCSEtWRCIfQbZG7q1e6DgxCIOe1SUQzDe/7rXXeA47s8yCn6fuTNQAj1Zq4oTFi9Yjp3wzElcxg==} + '@radix-ui/number@1.1.1': resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} @@ -5484,6 +5737,11 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-icons@1.3.2': + resolution: {integrity: sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==} + peerDependencies: + react: ^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc + '@radix-ui/react-id@1.1.1': resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} peerDependencies: @@ -5636,6 +5894,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-separator@1.1.7': + resolution: {integrity: sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-separator@1.1.8': resolution: {integrity: sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g==} peerDependencies: @@ -5693,6 +5964,45 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-toggle-group@1.1.11': + resolution: {integrity: sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-toggle@1.1.10': + resolution: {integrity: sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-toolbar@1.1.11': + resolution: {integrity: sha512-4ol06/1bLoFu1nwUqzdD4Y5RZ9oDdKeiHIsntug54Hcr1pgaHiPqHFEaXI1IFP/EsOfROQZ8Mig9VTIRza6Tjg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-tooltip@1.2.8': resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==} peerDependencies: @@ -5827,6 +6137,16 @@ packages: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + '@react-hook/intersection-observer@3.1.2': + resolution: {integrity: sha512-mWU3BMkmmzyYMSuhO9wu3eJVP21N8TcgYm9bZnTrMwuM818bEk+0NRM3hP+c/TqA9Ln5C7qE53p1H0QMtzYdvQ==} + peerDependencies: + react: '>=16.8' + + '@react-hook/passive-layout-effect@1.2.1': + resolution: {integrity: sha512-IwEphTD75liO8g+6taS+4oqz+nnroocNfWVHWz7j+N+ZO2vYrc6PV1q7GQhuahL0IOR7JccFTsFKQ/mb6iZWAg==} + peerDependencies: + react: '>=16.8' + '@react-native-community/netinfo@11.5.2': resolution: {integrity: sha512-/g0m65BtX9HU+bPiCH2517bOHpEIUsGrWFXDzi1a5nNKn5KujQgm04WhL7/OSXWKHyrT8VVtUoJA0XKRxueBpQ==} peerDependencies: @@ -6787,6 +7107,9 @@ packages: '@standard-schema/utils@0.3.0': resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} + '@stitches/core@1.2.8': + resolution: {integrity: sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg==} + '@storybook/addon-actions@8.5.8': resolution: {integrity: sha512-7J0NAz+WDw1NmvmKIh0Qr5cxgVRDPFC5fmngbDNxedk147TkwrgmqOypgEi/SAksHbTWxJclbimoqdcsNtWffA==} peerDependencies: @@ -7999,6 +8322,9 @@ packages: anser@1.4.10: resolution: {integrity: sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==} + anser@2.3.5: + resolution: {integrity: sha512-vcZjxvvVoxTeR5XBNJB38oTu/7eDCZlwdz32N1eNgpyPF7j/Z7Idf+CUwQOkKKpJ7RJyjxgLHCM7vdIK0iCNMQ==} + ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} @@ -8607,6 +8933,9 @@ packages: class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + classnames@2.5.1: + resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + clean-css@5.3.3: resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} engines: {node: '>= 10.0'} @@ -8614,6 +8943,9 @@ packages: clean-git-ref@2.0.1: resolution: {integrity: sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==} + clean-set@1.1.2: + resolution: {integrity: sha512-cA8uCj0qSoG9e0kevyOWXwPaELRPVg5Pxp6WskLMwerx257Zfnh8Nl0JBH59d7wQzij2CK7qEfJQK3RjuKKIug==} + clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} @@ -8664,6 +8996,14 @@ packages: resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} engines: {node: '>=0.10.0'} + cm6-theme-basic-light@0.2.0: + resolution: {integrity: sha512-1prg2gv44sYfpHscP26uLT/ePrh0mlmVwMSoSd3zYKQ92Ab3jPRLzyCnpyOCQLJbK+YdNs4HvMRqMNYdy4pMhA==} + peerDependencies: + '@codemirror/language': ^6.0.0 + '@codemirror/state': ^6.0.0 + '@codemirror/view': ^6.0.0 + '@lezer/highlight': ^1.0.0 + cmdk@1.1.1: resolution: {integrity: sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==} peerDependencies: @@ -8678,6 +9018,9 @@ packages: resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + codemirror@6.0.2: + resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==} + collapse-white-space@2.1.0: resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} @@ -8761,6 +9104,9 @@ packages: resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} engines: {node: '>= 0.8.0'} + compute-scroll-into-view@2.0.4: + resolution: {integrity: sha512-y/ZA3BGnxoM/QHHQ2Uy49CLtnWPbt4tTPpEEZiEmmiWBFKjej7nEyH8Ryz54jH0MLXflUYA3Er2zUxPSJu5R+g==} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -8859,6 +9205,9 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true + crelt@1.0.6: + resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} + croner@10.0.1: resolution: {integrity: sha512-ixNtAJndqh173VQ4KodSdJEI6nuioBWI0V1ITNKhZZsO0pEMoDxz539T4FTTbSZ/xIOSuDnzxLVRqBVSvPNE2g==} engines: {node: '>=18.0'} @@ -8959,6 +9308,10 @@ packages: resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} engines: {node: '>=12'} + d@1.0.2: + resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} + engines: {node: '>=0.12'} + data-uri-to-buffer@4.0.1: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} @@ -9253,6 +9606,11 @@ packages: resolution: {integrity: sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==} engines: {node: '>=12'} + downshift@7.6.2: + resolution: {integrity: sha512-iOv+E1Hyt3JDdL9yYcOgW7nZ7GQ2Uz6YbggwXvKUSleetYhU2nXD482Rz6CzvM4lvI1At34BYruKAL4swRGxaA==} + peerDependencies: + react: '>=16.12.0' + drange@1.1.1: resolution: {integrity: sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==} engines: {node: '>=4'} @@ -9467,9 +9825,20 @@ packages: es-toolkit@1.45.1: resolution: {integrity: sha512-/jhoOj/Fx+A+IIyDNOvO3TItGmlMKhtX8ISAHKE90c4b/k1tqaqEZ+uUqfpU8DMnW5cgNJv606zS55jGvza0Xw==} + es5-ext@0.10.64: + resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==} + engines: {node: '>=0.10'} + es6-error@4.1.1: resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} + es6-iterator@2.0.3: + resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} + + es6-symbol@3.1.4: + resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==} + engines: {node: '>=0.12'} + esast-util-from-estree@2.0.0: resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} @@ -9490,6 +9859,9 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-carriage@1.3.1: + resolution: {integrity: sha512-GwBr6yViW3ttx1kb7/Oh+gKQ1/TrhYwxKqVmg5gS+BK+Qe2KrOa/Vh7w3HPBvgGf0LfcDGoY9I6NHKoA5Hozhw==} + escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} @@ -9527,6 +9899,10 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} + esniff@2.0.1: + resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==} + engines: {node: '>=0.10'} + esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} @@ -9576,6 +9952,9 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} + event-emitter@0.3.5: + resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + event-source-polyfill@1.0.31: resolution: {integrity: sha512-4IJSItgS/41IxN5UVAVuAyczwZF7ZIEsM1XAoUzIHA6A+xzusEZUutdXz2Nr+MQPLxfTiCvqE79/C8HT8fKFvA==} @@ -9943,6 +10322,9 @@ packages: exsolve@1.0.8: resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} + ext@1.7.0: + resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} + extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} @@ -9978,6 +10360,9 @@ packages: fastq@1.20.1: resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + fault@2.0.1: + resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} + fb-dotslash@0.5.8: resolution: {integrity: sha512-XHYLKk9J4BupDxi9bSEhkfss0m+Vr9ChTrjhf9l2iw3jB5C7BnY4GVPoMcqbrTutsKJso6yj2nAB6BI/F2oZaA==} engines: {node: '>=20'} @@ -10127,6 +10512,10 @@ packages: resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} + format@0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} + formatly@0.3.0: resolution: {integrity: sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==} engines: {node: '>=18.3.0'} @@ -10578,6 +10967,10 @@ packages: resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==} engines: {node: '>=10.13.0'} + intersection-observer@0.10.0: + resolution: {integrity: sha512-fn4bQ0Xq8FTej09YC/jqKZwtijpvARlRp6wxL5WTA6yPe2YWSJ5RJh7Nm79rK2qB0wr6iDQzH60XGq5V/7u8YQ==} + deprecated: The Intersection Observer polyfill is no longer needed and can safely be removed. Intersection Observer has been Baseline since 2019. + intl-pluralrules@2.0.1: resolution: {integrity: sha512-astxTLzIdXPeN0K9Rumi6LfMpm3rvNO0iJE+h/k8Kr/is+wPbRe4ikyDjlLr6VTh/mEfNv8RjN+gu3KwDiuhqg==} @@ -11245,6 +11638,9 @@ packages: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} + lexical@0.35.0: + resolution: {integrity: sha512-3VuV8xXhh5xJA6tzvfDvE0YBCMkIZUmxtRilJQDDdCgJCc+eut6qAv2qbN+pbqvarqcQqPN1UF+8YvsjmyOZpw==} + lighthouse-logger@1.4.2: resolution: {integrity: sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==} @@ -11460,6 +11856,10 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + madge@8.0.0: resolution: {integrity: sha512-9sSsi3TBPhmkTCIpVQF0SPiChj1L7Rq9kU2KDG1o6v2XH9cCw086MopjVCD+vuoL5v8S77DTbVopTO8OUiQpIw==} engines: {node: '>=18'} @@ -11527,12 +11927,18 @@ packages: md5.js@1.3.5: resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + mdast-util-directive@3.1.0: + resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} + mdast-util-find-and-replace@3.0.2: resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} mdast-util-from-markdown@2.0.3: resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} + mdast-util-frontmatter@2.0.1: + resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==} + mdast-util-gfm-autolink-literal@2.0.1: resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} @@ -11551,6 +11957,9 @@ packages: mdast-util-gfm@3.1.0: resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + mdast-util-highlight-mark@1.2.2: + resolution: {integrity: sha512-OYumVoytj+B9YgwzBhBcYUCLYHIPvJtAvwnMyKhUXbfUFuER5S+FDZyu9fadUxm2TCT5fRYK3jQXh2ioWAxrMw==} + mdast-util-mdx-expression@2.0.1: resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} @@ -11664,6 +12073,12 @@ packages: micromark-core-commonmark@2.0.3: resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + micromark-extension-directive@3.0.2: + resolution: {integrity: sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==} + + micromark-extension-frontmatter@2.0.0: + resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==} + micromark-extension-gfm-autolink-literal@2.1.0: resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} @@ -11685,6 +12100,9 @@ packages: micromark-extension-gfm@3.0.0: resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + micromark-extension-highlight-mark@1.2.0: + resolution: {integrity: sha512-huGtbd/9kQsMk8u7nrVMaS5qH/47yDG6ZADggo5Owz5JoY8wdfQjfuy118/QiYNCvdFuFDbzT0A7K7Hp2cBsXA==} + micromark-extension-mdx-expression@3.0.1: resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} @@ -11904,6 +12322,10 @@ packages: react-dom: optional: true + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + mrmime@2.0.1: resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} @@ -11966,6 +12388,9 @@ packages: nodemailer: optional: true + next-tick@1.1.0: + resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} + next@16.1.6: resolution: {integrity: sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw==} engines: {node: '>=20.9.0'} @@ -12174,6 +12599,9 @@ packages: resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} engines: {node: '>=0.10.0'} + outvariant@1.4.0: + resolution: {integrity: sha512-AlWY719RF02ujitly7Kk/0QlV+pXGFDHrHf9O2OKqyqgBieaPOIeuSkL8sRK6j2WK+/ZAURq2kZsY0d8JapUiw==} + oxc-parser@0.120.0: resolution: {integrity: sha512-WyPWZlcIm+Fkte63FGfgFB8mAAk33aH9h5N9lphXVOHSXEBFFsmYdOBedVKly363aWABjZdaj/m9lBfEY4wt+w==} engines: {node: ^20.19.0 || >=22.12.0} @@ -12576,6 +13004,10 @@ packages: resolution: {integrity: sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==} engines: {node: '>=10'} + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + proc-log@4.2.0: resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -12700,6 +13132,9 @@ packages: react-devtools-core@6.1.5: resolution: {integrity: sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==} + react-devtools-inline@4.4.0: + resolution: {integrity: sha512-ES0GolSrKO8wsKbsEkVeiR/ZAaHQTY4zDh1UW8DImVmm8oaGLl3ijJDvSGe+qDRKPZdPRnDtWWnSvvrgxXdThQ==} + react-docgen-typescript@2.4.0: resolution: {integrity: sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==} peerDependencies: @@ -12720,6 +13155,12 @@ packages: peerDependencies: react: '>= 16.8 || 18.0.0' + react-error-boundary@3.1.4: + resolution: {integrity: sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==} + engines: {node: '>=10', npm: '>=6'} + peerDependencies: + react: '>=16.13.1' + react-fast-compare@3.2.2: resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} @@ -12729,6 +13170,12 @@ packages: peerDependencies: react: '>=17.0.0' + react-hook-form@7.72.1: + resolution: {integrity: sha512-RhwBoy2ygeVZje+C+bwJ8g0NjTdBmDlJvAUHTxRjTmSUKPYsKfMphkS2sgEMotsY03bP358yEYlnUeZy//D9Ig==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + react-image-gallery@1.2.12: resolution: {integrity: sha512-JIh85lh0Av/yewseGJb/ycg00Y/weQiZEC/BQueC2Z5jnYILGB6mkxnrOevNhsM2NdZJpvcDekCluhy6uzEoTA==} peerDependencies: @@ -12737,6 +13184,9 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} @@ -13203,6 +13653,10 @@ packages: rxjs@7.8.2: resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -13506,6 +13960,9 @@ packages: state-local@1.0.7: resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==} + static-browser-server@1.0.3: + resolution: {integrity: sha512-ZUyfgGDdFRbZGGJQ1YhiM930Yczz5VlbJObrQLlk24+qNHVQx4OlLcYswEUo3bIyNAbQUIUR9Yr5/Hqjzqb4zA==} + statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} @@ -13633,6 +14090,9 @@ packages: streamx@2.23.0: resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==} + strict-event-emitter@0.4.6: + resolution: {integrity: sha512-12KWeb+wixJohmnwNFerbyiBrAlq5qJLwIt38etRtKtmmHyDSoGlIqFE9wx+4IwG0aDjI7GV8tc8ZccjWZZtTg==} + strict-uri-encode@2.0.0: resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} engines: {node: '>=4'} @@ -13738,6 +14198,9 @@ packages: peerDependencies: webpack: ^5.0.0 + style-mod@4.1.3: + resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==} + style-to-js@1.1.21: resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} @@ -14074,6 +14537,9 @@ packages: resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} + type@2.7.3: + resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==} + typed-array-buffer@1.0.3: resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} @@ -14152,6 +14618,9 @@ packages: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} engines: {node: '>=18'} + unidiff@1.0.4: + resolution: {integrity: sha512-ynU0vsAXw0ir8roa+xPCUHmnJ5goc5BTM2Kuc3IJd8UwgaeRs7VSD5+eeaQL+xp1JtB92hu/Zy/Lgy7RZcr1pQ==} + unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} @@ -14302,6 +14771,11 @@ packages: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true + uvu@0.5.6: + resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} + engines: {node: '>=8'} + hasBin: true + v8-to-istanbul@9.3.0: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} @@ -14445,6 +14919,9 @@ packages: vm-browserify@1.1.2: resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} + w3c-keyname@2.2.8: + resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + wait-on@7.2.0: resolution: {integrity: sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==} engines: {node: '>=12.0.0'} @@ -16507,6 +16984,303 @@ snapshots: '@cloudflare/workers-types@4.20260313.1': {} + '@codemirror/autocomplete@6.20.1': + dependencies: + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.1 + '@lezer/common': 1.5.2 + + '@codemirror/commands@6.10.3': + dependencies: + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.1 + '@lezer/common': 1.5.2 + + '@codemirror/lang-angular@0.1.4': + dependencies: + '@codemirror/lang-html': 6.4.11 + '@codemirror/lang-javascript': 6.2.5 + '@codemirror/language': 6.12.3 + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@codemirror/lang-cpp@6.0.3': + dependencies: + '@codemirror/language': 6.12.3 + '@lezer/cpp': 1.1.5 + + '@codemirror/lang-css@6.3.1': + dependencies: + '@codemirror/autocomplete': 6.20.1 + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@lezer/common': 1.5.2 + '@lezer/css': 1.3.3 + + '@codemirror/lang-go@6.0.1': + dependencies: + '@codemirror/autocomplete': 6.20.1 + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@lezer/common': 1.5.2 + '@lezer/go': 1.0.1 + + '@codemirror/lang-html@6.4.11': + dependencies: + '@codemirror/autocomplete': 6.20.1 + '@codemirror/lang-css': 6.3.1 + '@codemirror/lang-javascript': 6.2.5 + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.1 + '@lezer/common': 1.5.2 + '@lezer/css': 1.3.3 + '@lezer/html': 1.3.13 + + '@codemirror/lang-java@6.0.2': + dependencies: + '@codemirror/language': 6.12.3 + '@lezer/java': 1.1.3 + + '@codemirror/lang-javascript@6.2.5': + dependencies: + '@codemirror/autocomplete': 6.20.1 + '@codemirror/language': 6.12.3 + '@codemirror/lint': 6.9.5 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.1 + '@lezer/common': 1.5.2 + '@lezer/javascript': 1.5.4 + + '@codemirror/lang-jinja@6.0.1': + dependencies: + '@codemirror/autocomplete': 6.20.1 + '@codemirror/lang-html': 6.4.11 + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.1 + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@codemirror/lang-json@6.0.2': + dependencies: + '@codemirror/language': 6.12.3 + '@lezer/json': 1.0.3 + + '@codemirror/lang-less@6.0.2': + dependencies: + '@codemirror/lang-css': 6.3.1 + '@codemirror/language': 6.12.3 + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@codemirror/lang-liquid@6.3.2': + dependencies: + '@codemirror/autocomplete': 6.20.1 + '@codemirror/lang-html': 6.4.11 + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.1 + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@codemirror/lang-markdown@6.5.0': + dependencies: + '@codemirror/autocomplete': 6.20.1 + '@codemirror/lang-html': 6.4.11 + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.1 + '@lezer/common': 1.5.2 + '@lezer/markdown': 1.6.3 + + '@codemirror/lang-php@6.0.2': + dependencies: + '@codemirror/lang-html': 6.4.11 + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@lezer/common': 1.5.2 + '@lezer/php': 1.0.5 + + '@codemirror/lang-python@6.2.1': + dependencies: + '@codemirror/autocomplete': 6.20.1 + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@lezer/common': 1.5.2 + '@lezer/python': 1.1.18 + + '@codemirror/lang-rust@6.0.2': + dependencies: + '@codemirror/language': 6.12.3 + '@lezer/rust': 1.0.2 + + '@codemirror/lang-sass@6.0.2': + dependencies: + '@codemirror/lang-css': 6.3.1 + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@lezer/common': 1.5.2 + '@lezer/sass': 1.1.0 + + '@codemirror/lang-sql@6.10.0': + dependencies: + '@codemirror/autocomplete': 6.20.1 + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@codemirror/lang-vue@0.1.3': + dependencies: + '@codemirror/lang-html': 6.4.11 + '@codemirror/lang-javascript': 6.2.5 + '@codemirror/language': 6.12.3 + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@codemirror/lang-wast@6.0.2': + dependencies: + '@codemirror/language': 6.12.3 + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@codemirror/lang-xml@6.1.0': + dependencies: + '@codemirror/autocomplete': 6.20.1 + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.1 + '@lezer/common': 1.5.2 + '@lezer/xml': 1.0.6 + + '@codemirror/lang-yaml@6.1.3': + dependencies: + '@codemirror/autocomplete': 6.20.1 + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + '@lezer/yaml': 1.0.4 + + '@codemirror/language-data@6.5.2': + dependencies: + '@codemirror/lang-angular': 0.1.4 + '@codemirror/lang-cpp': 6.0.3 + '@codemirror/lang-css': 6.3.1 + '@codemirror/lang-go': 6.0.1 + '@codemirror/lang-html': 6.4.11 + '@codemirror/lang-java': 6.0.2 + '@codemirror/lang-javascript': 6.2.5 + '@codemirror/lang-jinja': 6.0.1 + '@codemirror/lang-json': 6.0.2 + '@codemirror/lang-less': 6.0.2 + '@codemirror/lang-liquid': 6.3.2 + '@codemirror/lang-markdown': 6.5.0 + '@codemirror/lang-php': 6.0.2 + '@codemirror/lang-python': 6.2.1 + '@codemirror/lang-rust': 6.0.2 + '@codemirror/lang-sass': 6.0.2 + '@codemirror/lang-sql': 6.10.0 + '@codemirror/lang-vue': 0.1.3 + '@codemirror/lang-wast': 6.0.2 + '@codemirror/lang-xml': 6.1.0 + '@codemirror/lang-yaml': 6.1.3 + '@codemirror/language': 6.12.3 + '@codemirror/legacy-modes': 6.5.2 + + '@codemirror/language@6.12.3': + dependencies: + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.1 + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + style-mod: 4.1.3 + + '@codemirror/legacy-modes@6.5.2': + dependencies: + '@codemirror/language': 6.12.3 + + '@codemirror/lint@6.9.5': + dependencies: + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.1 + crelt: 1.0.6 + + '@codemirror/merge@6.12.1': + dependencies: + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.1 + '@lezer/highlight': 1.2.3 + style-mod: 4.1.3 + + '@codemirror/search@6.6.0': + dependencies: + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.1 + crelt: 1.0.6 + + '@codemirror/state@6.6.0': + dependencies: + '@marijn/find-cluster-break': 1.0.2 + + '@codemirror/view@6.41.1': + dependencies: + '@codemirror/state': 6.6.0 + crelt: 1.0.6 + style-mod: 4.1.3 + w3c-keyname: 2.2.8 + + '@codesandbox/nodebox@0.1.8': + dependencies: + outvariant: 1.4.0 + strict-event-emitter: 0.4.6 + + '@codesandbox/sandpack-client@2.19.8': + dependencies: + '@codesandbox/nodebox': 0.1.8 + buffer: 6.0.3 + dequal: 2.0.3 + mime-db: 1.54.0 + outvariant: 1.4.0 + static-browser-server: 1.0.3 + + '@codesandbox/sandpack-react@2.20.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@codemirror/autocomplete': 6.20.1 + '@codemirror/commands': 6.10.3 + '@codemirror/lang-css': 6.3.1 + '@codemirror/lang-html': 6.4.11 + '@codemirror/lang-javascript': 6.2.5 + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.1 + '@codesandbox/sandpack-client': 2.19.8 + '@lezer/highlight': 1.2.3 + '@react-hook/intersection-observer': 3.1.2(react@19.2.4) + '@stitches/core': 1.2.8 + anser: 2.3.5 + clean-set: 1.1.2 + dequal: 2.0.3 + escape-carriage: 1.3.1 + lz-string: 1.5.0 + react: 19.2.4 + react-devtools-inline: 4.4.0 + react-dom: 19.2.4(react@19.2.4) + react-is: 17.0.2 + '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 @@ -17682,31 +18456,271 @@ snapshots: dependencies: cross-spawn: 7.0.6 - '@lottiefiles/dotlottie-react@0.17.15(react@19.2.4)': + '@lexical/clipboard@0.35.0': dependencies: - '@lottiefiles/dotlottie-web': 0.63.0 + '@lexical/html': 0.35.0 + '@lexical/list': 0.35.0 + '@lexical/selection': 0.35.0 + '@lexical/utils': 0.35.0 + lexical: 0.35.0 + + '@lexical/code@0.35.0': + dependencies: + '@lexical/utils': 0.35.0 + lexical: 0.35.0 + prismjs: 1.30.0 + + '@lexical/devtools-core@0.35.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@lexical/html': 0.35.0 + '@lexical/link': 0.35.0 + '@lexical/mark': 0.35.0 + '@lexical/table': 0.35.0 + '@lexical/utils': 0.35.0 + lexical: 0.35.0 react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - '@lottiefiles/dotlottie-web@0.63.0': {} + '@lexical/dragon@0.35.0': + dependencies: + lexical: 0.35.0 - '@lukeed/csprng@1.1.0': {} + '@lexical/hashtag@0.35.0': + dependencies: + '@lexical/utils': 0.35.0 + lexical: 0.35.0 - '@lukeed/uuid@2.0.1': + '@lexical/history@0.35.0': dependencies: - '@lukeed/csprng': 1.1.0 + '@lexical/utils': 0.35.0 + lexical: 0.35.0 - '@mdx-js/loader@3.1.1(webpack@5.105.4(@swc/core@1.15.18)(esbuild@0.27.4))': + '@lexical/html@0.35.0': dependencies: - '@mdx-js/mdx': 3.1.1 - source-map: 0.7.6 - optionalDependencies: - webpack: 5.105.4(@swc/core@1.15.18)(esbuild@0.27.4) - transitivePeerDependencies: - - supports-color + '@lexical/selection': 0.35.0 + '@lexical/utils': 0.35.0 + lexical: 0.35.0 - '@mdx-js/mdx@3.1.1': + '@lexical/link@0.35.0': dependencies: - '@types/estree': 1.0.8 + '@lexical/utils': 0.35.0 + lexical: 0.35.0 + + '@lexical/list@0.35.0': + dependencies: + '@lexical/selection': 0.35.0 + '@lexical/utils': 0.35.0 + lexical: 0.35.0 + + '@lexical/mark@0.35.0': + dependencies: + '@lexical/utils': 0.35.0 + lexical: 0.35.0 + + '@lexical/markdown@0.35.0': + dependencies: + '@lexical/code': 0.35.0 + '@lexical/link': 0.35.0 + '@lexical/list': 0.35.0 + '@lexical/rich-text': 0.35.0 + '@lexical/text': 0.35.0 + '@lexical/utils': 0.35.0 + lexical: 0.35.0 + + '@lexical/offset@0.35.0': + dependencies: + lexical: 0.35.0 + + '@lexical/overflow@0.35.0': + dependencies: + lexical: 0.35.0 + + '@lexical/plain-text@0.35.0': + dependencies: + '@lexical/clipboard': 0.35.0 + '@lexical/selection': 0.35.0 + '@lexical/utils': 0.35.0 + lexical: 0.35.0 + + '@lexical/react@0.35.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@floating-ui/react': 0.27.19(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@lexical/devtools-core': 0.35.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@lexical/dragon': 0.35.0 + '@lexical/hashtag': 0.35.0 + '@lexical/history': 0.35.0 + '@lexical/link': 0.35.0 + '@lexical/list': 0.35.0 + '@lexical/mark': 0.35.0 + '@lexical/markdown': 0.35.0 + '@lexical/overflow': 0.35.0 + '@lexical/plain-text': 0.35.0 + '@lexical/rich-text': 0.35.0 + '@lexical/table': 0.35.0 + '@lexical/text': 0.35.0 + '@lexical/utils': 0.35.0 + '@lexical/yjs': 0.35.0 + lexical: 0.35.0 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-error-boundary: 3.1.4(react@19.2.4) + transitivePeerDependencies: + - yjs + + '@lexical/rich-text@0.35.0': + dependencies: + '@lexical/clipboard': 0.35.0 + '@lexical/selection': 0.35.0 + '@lexical/utils': 0.35.0 + lexical: 0.35.0 + + '@lexical/selection@0.35.0': + dependencies: + lexical: 0.35.0 + + '@lexical/table@0.35.0': + dependencies: + '@lexical/clipboard': 0.35.0 + '@lexical/utils': 0.35.0 + lexical: 0.35.0 + + '@lexical/text@0.35.0': + dependencies: + lexical: 0.35.0 + + '@lexical/utils@0.35.0': + dependencies: + '@lexical/list': 0.35.0 + '@lexical/selection': 0.35.0 + '@lexical/table': 0.35.0 + lexical: 0.35.0 + + '@lexical/yjs@0.35.0': + dependencies: + '@lexical/offset': 0.35.0 + '@lexical/selection': 0.35.0 + lexical: 0.35.0 + + '@lezer/common@1.5.2': {} + + '@lezer/cpp@1.1.5': + dependencies: + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@lezer/css@1.3.3': + dependencies: + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@lezer/go@1.0.1': + dependencies: + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@lezer/highlight@1.2.3': + dependencies: + '@lezer/common': 1.5.2 + + '@lezer/html@1.3.13': + dependencies: + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@lezer/java@1.1.3': + dependencies: + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@lezer/javascript@1.5.4': + dependencies: + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@lezer/json@1.0.3': + dependencies: + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@lezer/lr@1.4.10': + dependencies: + '@lezer/common': 1.5.2 + + '@lezer/markdown@1.6.3': + dependencies: + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + + '@lezer/php@1.0.5': + dependencies: + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@lezer/python@1.1.18': + dependencies: + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@lezer/rust@1.0.2': + dependencies: + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@lezer/sass@1.1.0': + dependencies: + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@lezer/xml@1.0.6': + dependencies: + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@lezer/yaml@1.0.4': + dependencies: + '@lezer/common': 1.5.2 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.10 + + '@lottiefiles/dotlottie-react@0.17.15(react@19.2.4)': + dependencies: + '@lottiefiles/dotlottie-web': 0.63.0 + react: 19.2.4 + + '@lottiefiles/dotlottie-web@0.63.0': {} + + '@lukeed/csprng@1.1.0': {} + + '@lukeed/uuid@2.0.1': + dependencies: + '@lukeed/csprng': 1.1.0 + + '@marijn/find-cluster-break@1.0.2': {} + + '@mdx-js/loader@3.1.1(webpack@5.105.4(@swc/core@1.15.18)(esbuild@0.27.4))': + dependencies: + '@mdx-js/mdx': 3.1.1 + source-map: 0.7.6 + optionalDependencies: + webpack: 5.105.4(@swc/core@1.15.18)(esbuild@0.27.4) + transitivePeerDependencies: + - supports-color + + '@mdx-js/mdx@3.1.1': + dependencies: + '@types/estree': 1.0.8 '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.4 '@types/mdx': 2.0.13 @@ -17740,6 +18754,79 @@ snapshots: '@types/react': 19.2.14 react: 19.2.4 + '@mdxeditor/editor@3.55.0(@codemirror/language@6.12.3)(@lezer/highlight@1.2.3)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@codemirror/commands': 6.10.3 + '@codemirror/lang-markdown': 6.5.0 + '@codemirror/language-data': 6.5.2 + '@codemirror/merge': 6.12.1 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.1 + '@codesandbox/sandpack-react': 2.20.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@lexical/clipboard': 0.35.0 + '@lexical/link': 0.35.0 + '@lexical/list': 0.35.0 + '@lexical/markdown': 0.35.0 + '@lexical/plain-text': 0.35.0 + '@lexical/react': 0.35.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@lexical/rich-text': 0.35.0 + '@lexical/selection': 0.35.0 + '@lexical/utils': 0.35.0 + '@mdxeditor/gurx': 1.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/colors': 3.0.0 + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-icons': 1.3.2(react@19.2.4) + '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-select': 2.2.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-toolbar': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-tooltip': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + classnames: 2.5.1 + cm6-theme-basic-light: 0.2.0(@codemirror/language@6.12.3)(@codemirror/state@6.6.0)(@codemirror/view@6.41.1)(@lezer/highlight@1.2.3) + codemirror: 6.0.2 + downshift: 7.6.2(react@19.2.4) + js-yaml: 4.1.1 + lexical: 0.35.0 + mdast-util-directive: 3.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-frontmatter: 2.0.1 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-highlight-mark: 1.2.2 + mdast-util-mdx: 3.0.0 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-to-markdown: 2.1.2 + micromark-extension-directive: 3.0.2 + micromark-extension-frontmatter: 2.0.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-extension-highlight-mark: 1.2.0 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs: 3.0.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-hook-form: 7.72.1(react@19.2.4) + unidiff: 1.0.4 + transitivePeerDependencies: + - '@codemirror/language' + - '@lezer/highlight' + - '@types/react' + - '@types/react-dom' + - supports-color + - yjs + + '@mdxeditor/gurx@1.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + '@mistralai/mistralai@1.15.1': dependencies: ws: 8.19.0 @@ -17962,6 +19049,8 @@ snapshots: dependencies: '@octokit/openapi-types': 27.0.0 + '@open-draft/deferred-promise@2.2.0': {} + '@opentelemetry/api-logs@0.207.0': dependencies: '@opentelemetry/api': 1.9.0 @@ -18662,6 +19751,8 @@ snapshots: '@qdrant/openapi-typescript-fetch@1.2.6': {} + '@radix-ui/colors@3.0.0': {} + '@radix-ui/number@1.1.1': {} '@radix-ui/primitive@1.1.3': {} @@ -18906,6 +19997,10 @@ snapshots: '@types/react': 19.2.14 '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@radix-ui/react-icons@1.3.2(react@19.2.4)': + dependencies: + react: 19.2.4 + '@radix-ui/react-id@1.1.1(@types/react@19.2.14)(react@19.2.0)': dependencies: '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.0) @@ -19136,6 +20231,15 @@ snapshots: '@types/react': 19.2.14 '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@radix-ui/react-separator@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@radix-ui/react-separator@1.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -19220,6 +20324,47 @@ snapshots: '@types/react': 19.2.14 '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@radix-ui/react-toggle-group@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-toggle@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-toolbar@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-separator': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 @@ -19382,6 +20527,16 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) + '@react-hook/intersection-observer@3.1.2(react@19.2.4)': + dependencies: + '@react-hook/passive-layout-effect': 1.2.1(react@19.2.4) + intersection-observer: 0.10.0 + react: 19.2.4 + + '@react-hook/passive-layout-effect@1.2.1(react@19.2.4)': + dependencies: + react: 19.2.4 + '@react-native-community/netinfo@11.5.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': dependencies: react: 19.2.0 @@ -20510,6 +21665,8 @@ snapshots: '@standard-schema/utils@0.3.0': {} + '@stitches/core@1.2.8': {} + '@storybook/addon-actions@8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: '@storybook/global': 5.0.0 @@ -22116,6 +23273,8 @@ snapshots: anser@1.4.10: {} + anser@2.3.5: {} + ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 @@ -22807,12 +23966,16 @@ snapshots: dependencies: clsx: 2.1.1 + classnames@2.5.1: {} + clean-css@5.3.3: dependencies: source-map: 0.6.1 clean-git-ref@2.0.1: {} + clean-set@1.1.2: {} + clean-stack@2.2.0: {} cli-boxes@3.0.0: {} @@ -22856,6 +24019,13 @@ snapshots: cluster-key-slot@1.1.2: {} + cm6-theme-basic-light@0.2.0(@codemirror/language@6.12.3)(@codemirror/state@6.6.0)(@codemirror/view@6.41.1)(@lezer/highlight@1.2.3): + dependencies: + '@codemirror/language': 6.12.3 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.1 + '@lezer/highlight': 1.2.3 + cmdk@1.1.1(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) @@ -22874,6 +24044,16 @@ snapshots: dependencies: convert-to-spaces: 2.0.1 + codemirror@6.0.2: + dependencies: + '@codemirror/autocomplete': 6.20.1 + '@codemirror/commands': 6.10.3 + '@codemirror/language': 6.12.3 + '@codemirror/lint': 6.9.5 + '@codemirror/search': 6.6.0 + '@codemirror/state': 6.6.0 + '@codemirror/view': 6.41.1 + collapse-white-space@2.1.0: {} collect-v8-coverage@1.0.3: {} @@ -22955,6 +24135,8 @@ snapshots: transitivePeerDependencies: - supports-color + compute-scroll-into-view@2.0.4: {} + concat-map@0.0.1: {} connect@3.7.0: @@ -23079,6 +24261,8 @@ snapshots: - supports-color - ts-node + crelt@1.0.6: {} + croner@10.0.1: {} cross-spawn@7.0.6: @@ -23202,6 +24386,11 @@ snapshots: d3-timer@3.0.1: {} + d@1.0.2: + dependencies: + es5-ext: 0.10.64 + type: 2.7.3 + data-uri-to-buffer@4.0.1: {} date-fns@4.1.0: {} @@ -23507,6 +24696,15 @@ snapshots: dotenv@17.3.1: {} + downshift@7.6.2(react@19.2.4): + dependencies: + '@babel/runtime': 7.29.2 + compute-scroll-into-view: 2.0.4 + prop-types: 15.8.1 + react: 19.2.4 + react-is: 17.0.2 + tslib: 2.8.1 + drange@1.1.1: {} drizzle-kit@0.31.9: @@ -23624,8 +24822,26 @@ snapshots: es-toolkit@1.45.1: {} + es5-ext@0.10.64: + dependencies: + es6-iterator: 2.0.3 + es6-symbol: 3.1.4 + esniff: 2.0.1 + next-tick: 1.1.0 + es6-error@4.1.1: {} + es6-iterator@2.0.3: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-symbol: 3.1.4 + + es6-symbol@3.1.4: + dependencies: + d: 1.0.2 + ext: 1.7.0 + esast-util-from-estree@2.0.0: dependencies: '@types/estree-jsx': 1.0.5 @@ -23678,6 +24894,8 @@ snapshots: escalade@3.2.0: {} + escape-carriage@1.3.1: {} + escape-html@1.0.3: {} escape-string-regexp@1.0.5: {} @@ -23718,6 +24936,13 @@ snapshots: eslint-visitor-keys@5.0.1: {} + esniff@2.0.1: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + event-emitter: 0.3.5 + type: 2.7.3 + esprima@4.0.1: {} esrecurse@4.3.0: @@ -23767,6 +24992,11 @@ snapshots: etag@1.8.1: {} + event-emitter@0.3.5: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + event-source-polyfill@1.0.31: {} event-target-shim@5.0.1: {} @@ -24229,6 +25459,10 @@ snapshots: exsolve@1.0.8: {} + ext@1.7.0: + dependencies: + type: 2.7.3 + extend@3.0.2: {} fast-content-type-parse@3.0.0: {} @@ -24265,6 +25499,10 @@ snapshots: dependencies: reusify: 1.1.0 + fault@2.0.1: + dependencies: + format: 0.2.2 + fb-dotslash@0.5.8: {} fb-watchman@2.0.2: @@ -24457,6 +25695,8 @@ snapshots: hasown: 2.0.2 mime-types: 2.1.35 + format@0.2.2: {} + formatly@0.3.0: dependencies: fd-package-json: 2.0.0 @@ -24951,6 +26191,8 @@ snapshots: interpret@3.1.1: {} + intersection-observer@0.10.0: {} + intl-pluralrules@2.0.1: {} invariant@2.2.4: @@ -26107,6 +27349,8 @@ snapshots: leven@3.1.0: {} + lexical@0.35.0: {} + lighthouse-logger@1.4.2: dependencies: debug: 2.6.9 @@ -26275,6 +27519,8 @@ snapshots: dependencies: react: 19.2.4 + lz-string@1.5.0: {} + madge@8.0.0(typescript@5.9.3): dependencies: chalk: 4.1.2 @@ -26348,6 +27594,20 @@ snapshots: inherits: 2.0.4 safe-buffer: 5.2.1 + mdast-util-directive@3.1.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-visit-parents: 6.0.2 + transitivePeerDependencies: + - supports-color + mdast-util-find-and-replace@3.0.2: dependencies: '@types/mdast': 4.0.4 @@ -26372,6 +27632,17 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-frontmatter@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + escape-string-regexp: 5.0.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + micromark-extension-frontmatter: 2.0.0 + transitivePeerDependencies: + - supports-color + mdast-util-gfm-autolink-literal@2.0.1: dependencies: '@types/mdast': 4.0.4 @@ -26429,6 +27700,10 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-highlight-mark@1.2.2: + dependencies: + micromark-extension-highlight-mark: 1.2.0 + mdast-util-mdx-expression@2.0.1: dependencies: '@types/estree-jsx': 1.0.5 @@ -26724,6 +27999,23 @@ snapshots: micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 + micromark-extension-directive@3.0.2: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + parse-entities: 4.0.2 + + micromark-extension-frontmatter@2.0.0: + dependencies: + fault: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-extension-gfm-autolink-literal@2.1.0: dependencies: micromark-util-character: 2.1.1 @@ -26782,6 +28074,15 @@ snapshots: micromark-util-combine-extensions: 2.0.1 micromark-util-types: 2.0.2 + micromark-extension-highlight-mark@1.2.0: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + uvu: 0.5.6 + micromark-extension-mdx-expression@3.0.1: dependencies: '@types/estree': 1.0.8 @@ -27106,6 +28407,8 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) + mri@1.2.0: {} + mrmime@2.0.1: {} ms@2.0.0: {} @@ -27149,6 +28452,8 @@ snapshots: react-dom: 19.2.4(react@19.2.4) uuid: 8.3.2 + next-tick@1.1.0: {} + next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@next/env': 16.1.6 @@ -27406,6 +28711,8 @@ snapshots: os-homedir@1.0.2: {} + outvariant@1.4.0: {} + oxc-parser@0.120.0: dependencies: '@oxc-project/types': 0.120.0 @@ -27898,6 +29205,8 @@ snapshots: dependencies: parse-ms: 2.1.0 + prismjs@1.30.0: {} + proc-log@4.2.0: {} process-nextick-args@2.0.1: {} @@ -28041,6 +29350,10 @@ snapshots: - bufferutil - utf-8-validate + react-devtools-inline@4.4.0: + dependencies: + es6-symbol: 3.1.4 + react-docgen-typescript@2.4.0(typescript@5.9.3): dependencies: typescript: 5.9.3 @@ -28077,18 +29390,29 @@ snapshots: prop-types: 15.8.1 react: 19.2.4 + react-error-boundary@3.1.4(react@19.2.4): + dependencies: + '@babel/runtime': 7.29.2 + react: 19.2.4 + react-fast-compare@3.2.2: {} react-freeze@1.0.4(react@19.2.0): dependencies: react: 19.2.0 + react-hook-form@7.72.1(react@19.2.4): + dependencies: + react: 19.2.4 + react-image-gallery@1.2.12(react@19.2.4): dependencies: react: 19.2.4 react-is@16.13.1: {} + react-is@17.0.2: {} + react-is@18.3.1: {} react-is@19.2.4: {} @@ -28785,6 +30109,10 @@ snapshots: dependencies: tslib: 2.8.1 + sade@1.8.1: + dependencies: + mri: 1.2.0 + safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} @@ -29149,6 +30477,13 @@ snapshots: state-local@1.0.7: {} + static-browser-server@1.0.3: + dependencies: + '@open-draft/deferred-promise': 2.2.0 + dotenv: 16.6.1 + mime-db: 1.54.0 + outvariant: 1.4.0 + statuses@1.5.0: {} statuses@2.0.2: {} @@ -29350,6 +30685,8 @@ snapshots: - bare-abort-controller - react-native-b4a + strict-event-emitter@0.4.6: {} + strict-uri-encode@2.0.0: {} string-length@4.0.2: @@ -29456,6 +30793,8 @@ snapshots: dependencies: webpack: 5.105.4(esbuild@0.27.4) + style-mod@4.1.3: {} + style-to-js@1.1.21: dependencies: style-to-object: 1.0.14 @@ -29776,6 +31115,8 @@ snapshots: media-typer: 1.1.0 mime-types: 3.0.2 + type@2.7.3: {} + typed-array-buffer@1.0.3: dependencies: call-bound: 1.0.4 @@ -29836,6 +31177,10 @@ snapshots: unicorn-magic@0.1.0: {} + unidiff@1.0.4: + dependencies: + diff: 8.0.3 + unified@11.0.5: dependencies: '@types/unist': 3.0.3 @@ -30018,6 +31363,13 @@ snapshots: uuid@9.0.1: {} + uvu@0.5.6: + dependencies: + dequal: 2.0.3 + diff: 8.0.3 + kleur: 4.1.5 + sade: 1.8.1 + v8-to-istanbul@9.3.0: dependencies: '@jridgewell/trace-mapping': 0.3.31 @@ -30321,6 +31673,8 @@ snapshots: vm-browserify@1.1.2: {} + w3c-keyname@2.2.8: {} + wait-on@7.2.0: dependencies: axios: 1.15.0 diff --git a/services/gastown/src/dos/Town.do.ts b/services/gastown/src/dos/Town.do.ts index 8461a7ae48..264fa77210 100644 --- a/services/gastown/src/dos/Town.do.ts +++ b/services/gastown/src/dos/Town.do.ts @@ -2399,6 +2399,79 @@ export class TownDO extends DurableObject { return { bead, agent: hookedAgent }; } + /** + * Create an open bead with the given labels, without arming the reconciler alarm. + * The caller is responsible for including `gt:held` in the labels if the bead + * should not be dispatched immediately. + */ + async createHeldBead(input: { + rigId: string; + title: string; + body?: string; + labels?: string[]; + }): Promise { + const bead = beadOps.createBead(this.sql, { + type: 'issue', + title: input.title, + body: input.body, + rig_id: input.rigId, + labels: input.labels, + }); + + events.insertEvent(this.sql, 'bead_created', { + bead_id: bead.bead_id, + payload: { bead_type: 'issue', rig_id: input.rigId, has_blockers: false }, + }); + + return bead; + } + + /** + * Notify the mayor about a newly created held bead. + * The mayor can then explore the codebase, plan, decompose into a convoy, or start it. + */ + async notifyMayorOfNewBead( + beadId: string, + rigId: string, + title: string, + body?: string + ): Promise { + const message = [ + `A user just created a new bead in rig ${rigId}:`, + `ID: ${beadId}`, + `Title: "${title}"`, + body ? `Description: ${body.slice(0, 500)}${body.length > 500 ? '...' : ''}` : '', + ``, + `The bead is currently held (tagged gt:held) and will not be dispatched until started.`, + `Would you like to explore the codebase and flesh out a detailed plan, decompose it into a staged convoy, or start it immediately?`, + `Your chat reply is already visible to the user — no extra tool call is needed to surface your response.`, + `To start the bead immediately, remove the gt:held label via gt_bead_update.`, + ] + .filter(Boolean) + .join('\n'); + await this.sendMayorMessage(message); + } + + /** + * Remove the `gt:held` label from a bead and arm the reconciler alarm so the + * bead is picked up on the next tick. + * + * @param rigId - The rig the caller has verified ownership of. The bead must + * belong to this rig to prevent cross-rig label removal within the same town. + */ + async startHeldBead(beadId: string, rigId: string): Promise { + const bead = beadOps.getBead(this.sql, beadId); + if (!bead) throw new Error(`Bead ${beadId} not found`); + if (bead.rig_id !== rigId) { + throw new Error(`Bead ${beadId} does not belong to rig ${rigId}`); + } + + const updatedLabels = (bead.labels ?? []).filter(l => l !== patrol.HELD_LABEL); + const updated = beadOps.updateBeadFields(this.sql, beadId, { labels: updatedLabels }, 'system'); + await this.escalateToActiveCadence(); + return updated; + } + /** Build the rig list for mayor agent startup (browse worktree setup on fresh containers). */ private async rigListForMayor(): Promise< Array<{ diff --git a/services/gastown/src/dos/town/patrol.ts b/services/gastown/src/dos/town/patrol.ts index 2172623233..d8a7ffb539 100644 --- a/services/gastown/src/dos/town/patrol.ts +++ b/services/gastown/src/dos/town/patrol.ts @@ -59,6 +59,12 @@ export const TRIAGE_BATCH_LABEL = 'gt:triage'; /** SQL LIKE pattern for querying triage request beads by label. */ export const TRIAGE_LABEL_LIKE = `%"${TRIAGE_REQUEST_LABEL}"%`; +/** Label used to mark beads that should not yet be dispatched by the reconciler. */ +export const HELD_LABEL = 'gt:held'; + +/** SQL LIKE pattern for querying held beads by label. */ +export const HELD_LABEL_LIKE = `%"${HELD_LABEL}"%`; + /** Create a triage request bead for the LLM triage agent to resolve. */ export function createTriageRequest( sql: SqlStorage, diff --git a/services/gastown/src/dos/town/reconciler.ts b/services/gastown/src/dos/town/reconciler.ts index 2422477e5f..9bfdb9d15f 100644 --- a/services/gastown/src/dos/town/reconciler.ts +++ b/services/gastown/src/dos/town/reconciler.ts @@ -25,6 +25,7 @@ import { GUPP_FORCE_STOP_MS, AGENT_GC_RETENTION_MS, TRIAGE_LABEL_LIKE, + HELD_LABEL_LIKE, createTriageRequest, } from './patrol'; import { MAX_DISPATCH_ATTEMPTS } from './scheduling'; @@ -880,6 +881,7 @@ export function reconcileBeads( AND b.${beads.columns.assignee_agent_bead_id} IS NULL AND b.${beads.columns.rig_id} IS NOT NULL AND b.${beads.columns.labels} NOT LIKE ? + AND b.${beads.columns.labels} NOT LIKE ? AND NOT EXISTS ( SELECT 1 FROM ${bead_dependencies} bd INNER JOIN ${beads} blocker ON blocker.${beads.columns.bead_id} = bd.${bead_dependencies.columns.depends_on_bead_id} @@ -895,7 +897,7 @@ export function reconcileBeads( AND cm.${convoy_metadata.columns.staged} = 1 ) `, - [TRIAGE_LABEL_LIKE] + [TRIAGE_LABEL_LIKE, HELD_LABEL_LIKE] ), ]); diff --git a/services/gastown/src/gastown.worker.ts b/services/gastown/src/gastown.worker.ts index 14546cf07f..4c429c4982 100644 --- a/services/gastown/src/gastown.worker.ts +++ b/services/gastown/src/gastown.worker.ts @@ -1043,6 +1043,7 @@ app.use( endpoint: '/trpc', createContext: (_opts: unknown, c: Context) => ({ env: c.env, + executionCtx: c.executionCtx, userId: c.get('kiloUserId') ?? '', isAdmin: c.get('kiloIsAdmin') ?? false, apiTokenPepper: c.get('kiloApiTokenPepper') ?? null, diff --git a/services/gastown/src/prompts/mayor-system.prompt.ts b/services/gastown/src/prompts/mayor-system.prompt.ts index 2ec1f379f2..054ef037a8 100644 --- a/services/gastown/src/prompts/mayor-system.prompt.ts +++ b/services/gastown/src/prompts/mayor-system.prompt.ts @@ -322,5 +322,23 @@ The UI has a "Report a Bug" dropdown in the terminal bar with two options: If a user prefers to discuss a problem rather than file a formal issue, point them to the Discord channel. For reproducible bugs with clear steps, prefer filing a GitHub issue via -gt_report_bug so it's tracked.`; +gt_report_bug so it's tracked. + +## User-Created Beads + +When a user creates a bead manually, you will receive a notification with the bead ID, title, and description. +The bead is tagged \`gt:held\` and will not be dispatched until you or the user starts it. + +Your response should: +1. Briefly acknowledge the bead (1 sentence) +2. Offer 2-3 concrete options: + - "I can explore the codebase and flesh out a detailed implementation plan, then update the bead body" + - "I can decompose this into a staged convoy of smaller tasks for your review" + - "I can start it immediately — just say the word" +3. Keep it concise — 3-5 sentences max. +4. Your chat reply is already visible to the user — no extra tool call is needed to surface the response. +5. To start the bead: first read its current labels (from the notification or via gt_list_beads), then call + gt_bead_update({ rig_id, bead_id, labels: currentLabels.filter(l => l !== 'gt:held') }) + — this removes only gt:held without dropping other labels, releasing the bead to the reconciler. +6. To plan: use gt_list_rigs and your file reading tools, then gt_bead_update to enrich the body, or gt_sling_batch with staged=true for a convoy.`; } diff --git a/services/gastown/src/trpc/init.ts b/services/gastown/src/trpc/init.ts index 18d32987e8..bea8bb9b6d 100644 --- a/services/gastown/src/trpc/init.ts +++ b/services/gastown/src/trpc/init.ts @@ -5,6 +5,7 @@ import type { JwtOrgMembership } from '../middleware/auth.middleware'; export type TRPCContext = { env: Env; + executionCtx: ExecutionContext; userId: string; isAdmin: boolean; apiTokenPepper: string | null; diff --git a/services/gastown/src/trpc/router.ts b/services/gastown/src/trpc/router.ts index 801d5b629e..9568dfe922 100644 --- a/services/gastown/src/trpc/router.ts +++ b/services/gastown/src/trpc/router.ts @@ -817,6 +817,7 @@ export const gastownRouter = router({ title: z.string().min(1), body: z.string().optional(), model: z.string().default('kilo/kilo-auto/frontier'), + labels: z.array(z.string()).optional(), }) ) .output(RpcSlingResultOutput) @@ -844,10 +845,118 @@ export const gastownRouter = router({ rigId: rig.id, title: input.title, body: input.body, + labels: input.labels, metadata: { model: input.model, slung_by: user.id }, }); }), + createBead: gastownProcedure + .input( + z.object({ + rigId: z.string().uuid(), + title: z.string().min(1), + body: z.string().optional(), + labels: z.array(z.string()).optional(), + startImmediately: z.boolean().default(false), + townId: z.string().uuid().optional(), + }) + ) + .output(RpcBeadOutput) + .mutation(async ({ ctx, input }) => { + const rig = await verifyRigOwnership(ctx.env, ctx, input.rigId, input.townId); + const townStub = getTownDOStub(ctx.env, rig.town_id); + + const labels = input.startImmediately + ? (input.labels ?? []) + : ['gt:held', ...(input.labels ?? [])]; + + const bead = await townStub.createHeldBead({ + rigId: rig.id, + title: input.title, + body: input.body, + labels, + }); + + if (input.startImmediately) { + // Return the post-start bead so callers see the removed gt:held label + // and any status changes from dispatch. + return townStub.startHeldBead(bead.bead_id, rig.id); + } + + // Mayor notification can start a container — use waitUntil so the Worker + // stays alive until the RPC completes without blocking the HTTP response. + ctx.executionCtx.waitUntil( + townStub + .notifyMayorOfNewBead(bead.bead_id, rig.id, input.title, input.body) + .catch(err => console.warn('[gastown-trpc] createBead: mayor notification failed', err)) + ); + + return bead; + }), + + startBead: gastownProcedure + .input( + z.object({ + rigId: z.string().uuid(), + beadId: z.string().uuid(), + townId: z.string().uuid().optional(), + }) + ) + .output(RpcBeadOutput) + .mutation(async ({ ctx, input }) => { + const rig = await verifyRigOwnership(ctx.env, ctx, input.rigId, input.townId); + const townStub = getTownDOStub(ctx.env, rig.town_id); + return townStub.startHeldBead(input.beadId, rig.id); + }), + + enrichBead: gastownProcedure + .input( + z.object({ + body: z.string().min(10), + townId: z.string().uuid(), + }) + ) + .output( + z + .object({ + title: z.string(), + labels: z.array(z.string()), + }) + .nullable() + ) + .mutation(async ({ ctx, input }) => { + await verifyTownOwnership(ctx.env, ctx, input.townId); + + const result = await ctx.env.AI.run('@cf/meta/llama-3.1-8b-instruct', { + prompt: `You are a software project assistant. Given this task description, suggest a concise title (max 8 words) and 1-3 relevant labels from: [bug, feature, refactor, docs, test, chore, performance, security, ui, backend, infrastructure].\n\nTask description:\n${input.body}\n\nRespond with JSON only: { "title": "...", "labels": ["..."] }`, + max_tokens: 100, + }); + + const responseValue = + result && typeof result === 'object' && 'response' in result + ? (result as Record<'response', unknown>).response + : undefined; + const responseText = typeof responseValue === 'string' ? responseValue : null; + + if (!responseText) return null; + + try { + // Strip markdown code fences if present + const cleaned = responseText + .replace(/^```(?:json)?\s*/i, '') + .replace(/\s*```\s*$/, '') + .trim(); + const parsed = JSON.parse(cleaned) as unknown; + const schema = z.object({ + title: z.string(), + labels: z.array(z.string()), + }); + return schema.parse(parsed); + } catch { + return null; + } + }), + // ── Mayor ─────────────────────────────────────────────────────────── sendMessage: gastownProcedure