Add POST /api/upload-file endpoint that uploads files to S3 and returns
CDN URLs protected by CloudFront signed cookies (same pattern as Linear).
Infrastructure:
- Two private S3 buckets (static.multica.ai, static-staging.multica.ai)
- Two CloudFront distributions with OAC and Trusted Key Groups
- ACM wildcard cert in us-east-1, DNS records in Route 53
- RSA signing key stored in AWS Secrets Manager
Backend:
- S3 storage service with CloudFront CDN domain support
- CloudFront signed cookie generation (RSA-SHA1)
- Private key loaded from Secrets Manager (env var fallback for local dev)
- Cookies set on login (VerifyCode) with 72h expiry matching JWT
- Upload handler: multipart form → S3 → CloudFront URL response
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(agents): reply as thread instead of top-level comment
When an agent responds to a user comment, the reply is now nested under
the triggering comment (parent_id) instead of appearing as a separate
top-level comment. Also enables on_comment trigger by default for newly
created agents.
- Add trigger_comment_id column to agent_task_queue (migration 028)
- Pass triggering comment ID through EnqueueTaskForIssue → task → createAgentComment
- Include parent_id in WebSocket broadcast for agent comments
- Default agent creation includes both on_assign and on_comment triggers
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(cli): add --parent flag to comment add for threaded replies
The agent posts comments via the CLI, so the correct fix is giving it a
--parent flag rather than wiring trigger_comment_id through the task
infrastructure. The agent reads the comment list, decides which comment
to reply to, and passes --parent <comment-id>.
- Add --parent flag to `multica issue comment add`
- Update agent runtime instructions to explain --parent usage
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(daemon): pass trigger_comment_id to agent execution context
The agent now knows which comment triggered its task and gets an explicit
instruction to reply to it using --parent. The trigger_comment_id flows
from the DB through the claim response, daemon Task struct, and into
issue_context.md where the agent sees it.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(comments): agent replies to thread root, matching frontend behavior
When the triggering comment is itself a reply (has parent_id), resolve
to the thread root so the agent's reply stays in the same flat thread.
This matches the frontend where all replies share the top-level parent.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(cli): show parent_id and full IDs in comment list
The table output now includes a PARENT column and shows full comment IDs
(not truncated) so agents can see thread structure and use --parent.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(daemon): instruct agents to always use --output json
Agents now see explicit guidance to use --output json for all read
commands, ensuring they get structured data with full IDs and parent_id
for proper threading.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(daemon): differentiate comment-trigger vs assign-trigger context
When triggered by a comment, the agent now gets clear instructions:
- Primary goal is to read and respond to the comment
- Do NOT change issue status just because you replied
- Only change status if explicitly requested
This prevents the agent from seeing "In Review" and stopping, since
it now understands the task is to reply, not to re-evaluate the issue.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(daemon): split workflow by trigger type in CLAUDE.md/AGENTS.md
The Workflow section in the agent's runtime config now shows a
comment-reply workflow when triggered by a comment (read comments,
find trigger, reply, don't change status) vs the full assignment
workflow (set in_progress, do work, set in_review).
Previously the agent always saw the assignment workflow, causing it
to check the issue status, see "In Review", and stop without reading
or replying to the triggering comment.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor(daemon): remove duplicate workflow from issue_context.md
Workflow instructions now live only in CLAUDE.md/AGENTS.md (runtime_config.go).
issue_context.md keeps just the task data: issue ID, trigger type, and
triggering comment ID.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(task): skip duplicate comment on completion for comment-triggered tasks
When triggered by a comment, the agent posts its own reply via CLI
with --parent. The task completion path was also creating a comment
from the agent's stdout output, resulting in duplicates. Now only
assignment-triggered tasks auto-post output as a comment. Error
messages from FailTask are still posted regardless of trigger type.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Server-side (primary): Apply redact.Text/InputMap on task message
content, output, and input fields before DB persistence and WebSocket
broadcast. Extended redact package with GitLab tokens, JWTs, connection
strings, and PASSWORD/SECRET/TOKEN env var patterns.
Frontend (fallback): redactSecrets utility mirrors server patterns,
applied in buildTimeline and ToolCallRow render as a safety net.
- Fix duplicate icons in tool call rows (use chevron only for expand/collapse)
- Show detailed tool information (WebSearch queries, Agent prompts, Skill names)
- Add thinking/reasoning rows with Brain icon and expandable content
- Show tool results as separate chronological entries with previews
- Add TaskRunHistory component for viewing past agent execution logs
- Add listTasksByIssue API endpoint and task-runs route
- Support thinking content blocks in agent SDK (MessageThinking type)
- Improve callID→toolName mapping in daemon message forwarding
When an agent is working on an issue, users can now see real-time output
in the issue detail page instead of waiting for completion.
Backend:
- Add task_message table and migration for persisting agent messages
- Add POST /api/daemon/tasks/{id}/messages endpoint for daemon to report
structured messages (tool_use, tool_result, text, error) in batches
- Add GET /api/daemon/tasks/{id}/messages for catch-up after reconnect
- Add GET /api/issues/{id}/active-task to check for running tasks
- Broadcast task:message events via WebSocket
- Daemon forwards agent session messages with 500ms text throttling
Frontend:
- Add AgentLiveCard component showing live tool calls, text output,
and progress indicators with auto-scroll
- Wire into issue detail timeline with WS subscription and HTTP catch-up
- Card appears when agent is working, disappears on completion/failure
Add Slack-style emoji reactions to comments and issue descriptions with
full-stack support: database tables, REST API endpoints, real-time
WebSocket sync, optimistic UI updates, and inbox notifications.
- New `comment_reaction` and `issue_reaction` tables with migrations
- POST/DELETE endpoints for adding/removing reactions on both comments
and issue descriptions
- Real-time WS events (reaction:added/removed, issue_reaction:added/removed)
- Shared ReactionBar component with quick emoji picker and full emoji-mart
picker (lazy-loaded)
- Optimistic add/remove with rollback on failure
- Inbox notifications for comment author and issue creator when reacted to
- Reactions included in timeline, comment list, and issue detail responses
Replace blanket owner/admin role check in UpdateAgent and DeleteAgent
with canManageAgent, which requires the requesting user to be the
agent's owner (or a workspace owner/admin) for private agents.
- Add redact package to detect and mask secrets (AWS keys, private keys,
API tokens, bearer tokens, credentials, home paths) in agent output
before posting as comments in TaskService
- Enforce agent visibility on issue assignment: private agents can only
be assigned by their owner or workspace admins
- Add visibility picker (workspace/private) to CreateAgentDialog,
default to private
- Grey out unassignable private agents in the assignee picker with
lock icon indicator
Enforce workspace isolation at every layer:
- Router: move RequireWorkspaceMember middleware to group level so ALL
workspace-scoped routes (issues, agents, skills, runtimes, inbox,
comments) require workspace context
- SQL: add GetXxxInWorkspace queries that filter by workspace_id,
eliminating cross-workspace data access at the query level
- Handlers: loadXForUser functions use workspace-scoped queries,
no fallback to unscoped queries
- Migration 025: add workspace_id column to comment table with backfill
- ListComments: add workspace_id filter for defense-in-depth
Fix daemon workspace mapping:
- Server returns workspace_id in task claim response (from issue)
- Daemon uses task.WorkspaceID directly instead of unreliable
workspaceIDForRuntime() local map lookup
- Remove workspaceIDForRuntime function
Fix agent/human parity:
- Comment update/delete: use resolveActor for isAuthor check so agents
can edit/delete their own comments
- Event attribution: replace hardcoded "member" with resolveActor in
agent, skill, and subscriber publish calls
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add multi-select with batch update/delete support in the list view.
Users can select issues via checkboxes (per-row or per-status-group)
and apply bulk status, priority, assignee changes or delete via a
floating toolbar.
ensureUserWorkspace in auth.go omitted the IssuePrefix field when
creating a default workspace during first login. This caused the
workspace's issue_prefix to be empty, producing identifiers like "-16"
instead of "JIA-16".
- Pass generateIssuePrefix(wsName) when creating the default workspace
- Add fallback in getIssuePrefix to regenerate from workspace name if
the stored prefix is empty
- Add migration 024 to backfill empty prefixes on existing workspaces
* feat(server): distinguish agent vs human CLI actions via X-Agent-ID/X-Task-ID headers
Extract resolveActor helper in handler to centralize agent identity resolution
from X-Agent-ID header with X-Task-ID cross-validation. Fix DeleteComment,
DeleteIssue, and UpdateComment handlers that previously hardcoded "member" as
actor type. Forward MULTICA_TASK_ID as X-Task-ID header from CLI client.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(server): add debug logging and test coverage for resolveActor
Add slog.Debug on agent/task validation failures for easier debugging.
Add TestResolveActor with 5 cases covering member fallback, valid agent,
non-existent agent, valid task, and mismatched task.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move workspace membership and role validation from individual handlers
into dedicated Chi middleware. The new middleware resolves workspace ID
(from query param, X-Workspace-ID header, or URL param), validates
membership via DB, and injects the member into request context.
Handlers now read workspace ID and member from context instead of
calling requireWorkspaceMember/requireWorkspaceRole directly. This
eliminates ~17 duplicated permission checks across handlers and makes
it harder to accidentally omit access control on new routes.
When agents use the multica CLI during task execution, their comments,
issue updates, and issue creations were attributed to the daemon's user
(via JWT) instead of the agent. Pass MULTICA_AGENT_ID env var from the
daemon, send X-Agent-ID header from the CLI client, and use it in
handlers to set the correct author/actor identity.
Main added execenv.Reuse() for workdir reuse across tasks on the same
issue. Our branch removed Type/BranchName/gitRoot from Environment
(repos are now checked out on demand). Resolution: keep Reuse() but
simplify it to work with the new Environment struct (no workspace type
tracking). Keep the "reused" log field from main, drop removed fields.
Agents now decide which repo to use based on issue context and check out
repos on demand via `multica repo checkout <url>`. Workspace repos are
cached locally as bare clones for fast worktree creation.
Key changes:
- Add repocache package for bare clone management (clone, fetch, worktree)
- Add `multica repo checkout` CLI command that talks to local daemon
- Add POST /repo/checkout endpoint on daemon health server
- Pass workspace repos metadata through register + task claim responses
- Remove pre-created worktrees from execenv (workdir starts empty)
- Update CLAUDE.md template to instruct agents to use `multica repo checkout`
- Pass MULTICA_DAEMON_PORT, WORKSPACE_ID, AGENT_NAME, TASK_ID env vars to agent
Previously each task created a fresh workdir via execenv.Prepare(), even
when resuming work on the same (agent, issue). This caused the agent's
session context to be out of sync with a blank code state.
Now the server returns prior_work_dir in the claim response, and the
daemon tries execenv.Reuse() first — which wraps the existing directory,
detects git worktree state, and refreshes context files. Falls back to
Prepare() if the prior workdir no longer exists. Workdirs are no longer
cleaned up after task completion so they remain available for reuse.
- Coalescing queue: use HasPendingTaskForIssue (queued/dispatched only)
instead of HasActiveTaskForIssue so comments during a running task
enqueue exactly one follow-up task that picks up all new comments.
- Stale task cleanup: runtime sweeper now fails orphaned tasks when
their runtime goes offline (daemon crash/network partition).
- Cancel-aware daemon: handleTask checks task status after execution
and discards results if the task was cancelled mid-run (e.g. reassign).
- Terminal issue guard: ClaimTaskForRuntime auto-cancels pending tasks
for done/cancelled issues instead of executing them.
- Race condition safety net: unique partial index ensures at most one
pending task per issue at the DB level.
member:added event now includes workspace_name. Frontend shows a toast
notification when the current user is invited. Also clears stale member
list on workspace switch.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Inbox items were previously queried only by recipient, which leaked data
across workspaces. All list/count/batch operations now filter by
workspace_id from the X-Workspace-ID header.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a member comments on an issue assigned to an agent, automatically
enqueue a new task if the agent has on_comment trigger enabled (or no
triggers configured). Combined with session persistence, the agent
resumes its prior conversation context and sees the new feedback.
- Add HasActiveTaskForIssue query to prevent duplicate task enqueue
- Refactor shouldEnqueueAgentTask into reusable isAgentTriggerEnabled
- Add shouldEnqueueOnComment with active-task and status guards
- Call trigger logic from CreateComment handler
Add an `instructions` text field to the agent model, allowing users to
define each agent's role, expertise, and working style. Instructions are
injected into CLAUDE.md as an "Agent Identity" section so the agent
knows who it is on every task execution.
- Migration 021: add instructions column to agent table
- Backend: create/update/get agent handlers support instructions
- ClaimTask response includes instructions for daemon injection
- execenv: inject instructions into CLAUDE.md meta-skill
- Frontend: add Instructions tab to agent detail panel
Store the Claude Code session ID and working directory when a task
completes. On the next task for the same (agent, issue) pair, look up
the prior session and pass --resume <session_id> to Claude Code so
the agent retains conversation context across multiple tasks on the
same issue.
Changes:
- Migration 020: add session_id and work_dir columns to agent_task_queue
- CompleteAgentTask stores session_id and work_dir on completion
- GetLastTaskSession query retrieves prior session for (agent, issue)
- ClaimTaskByRuntime handler populates prior_session_id in response
- Daemon passes ResumeSessionID through to Claude backend Execute()
- Claude backend adds --resume flag when ResumeSessionID is set
Add per-workspace auto-incrementing issue numbers with a configurable
prefix, producing identifiers like "JIA-1" instead of truncated UUIDs.
Database:
- Add issue_prefix and issue_counter to workspace table
- Add number column to issue table with UNIQUE(workspace_id, number)
- Backfill existing issues with sequential numbers
Backend:
- Issue creation atomically increments counter in a transaction
- API responses include number and identifier fields
- Support issue lookup by identifier format (KEY-N)
- Workspace prefix auto-generated from name, customizable via API
Frontend:
- Display identifier in list rows and issue detail breadcrumb
- Add issue_prefix to Workspace type, number/identifier to Issue type
Add comprehensive data visualization to the runtime detail page:
- Daily token usage stacked area chart and daily cost bar chart
- Model distribution donut chart with cost breakdown
- GitHub-style activity heatmap (13 weeks of daily token usage)
- Hourly task distribution bar chart with new backend endpoint
- Responsive 2-column grid layout for charts on wide screens
Backend: new GET /api/runtimes/{runtimeId}/activity endpoint
returning hourly task counts from agent_task_queue.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The createAgentInitIssue flow created a boilerplate "Initialize environment"
issue every time an agent was created, polluting the issue list with low-value
tasks. Agents naturally learn the project context when executing real work.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Refactor real-time sync from per-event precise mutations to WS-as-invalidation-signal + debounced refetch.
Backend:
- Add SubscribeAll to Event Bus — auto-broadcasts ALL events, eliminates manual 25-item allEvents list
- Add skill event constants to protocol, fix skill handler string literals
- Add title_changed activity tracking
Frontend:
- WSClient: add onAny() method for wildcard event subscription
- useRealtimeSync: rewrite to refreshMap + prefix routing + 100ms debounce
- Precise handlers only for side effects: workspace:deleted, member:removed, member:added (self-check)
- Reconnect now refetches all stores (fixes missing members/skills/workspace refresh)
- Stale-while-revalidate: fetch() only shows loading spinner on initial load, not on refetch
- Remove redundant useWSEvent in agents/page.tsx and skills-page.tsx
- WSClient.disconnect() now clears all handler registrations
Inbox bugfixes:
- Unify sidebar badge count with page count via dedupedItems + unreadCount in store
- Sort by time DESC (removed severity-first ordering)
- Ellipsis on truncated detail labels
UI:
- Status/Priority pickers: replace RadioGroup with MenuItem for auto-close on selection
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add missing notifications for priority_changed and due_date_changed events
- Publish priority_changed and due_date_changed flags from UpdateIssue handler
- Add details JSONB column to inbox_item (migration 019) for structured change data
- Store from/to values in details for status, priority, assignee, and due_date changes
- Notification titles now use plain issue title; details carry structured context
- Add human-readable label maps (statusLabels, priorityLabels) in notification listeners
- Update inbox handler responses to include details field
- Frontend: InboxDetailLabel renders rich subtitles per notification type
- Status: "Set status to ● In Progress" with StatusIcon
- Priority: "Set priority to ◆ High" with PriorityIcon
- Assigned: "Assigned to Bob" with resolved actor name
- Due date: "Set due date to Apr 20"
- Comment: truncated comment body preview
- Frontend: HoverCard on inbox items shows issue title + description context
- Add due_date_changed to InboxItemType and typeLabels
- Add tests for priority_changed and due_date_changed notifications
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Extract shared timeAgo utility, remove duplicates from comment-card and issue-detail
- Remove unused replies prop from CommentCard
- Fix recursive delete to remove all descendant replies, not just direct children
- Improve formatActivity with human-readable status/priority labels and actor names
- Validate parent comment exists and belongs to same issue before creating reply
- Add priority_changed activity recording in activity listeners
- Fix activity SQL query to sort ASC (was DESC, then re-sorted in handler)
- Fix reply-input layout alignment and test submit button selector
- Minor: .gitignore additions, button dark mode aria-expanded fix
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Activity entries now show ActorAvatar instead of a small dot (consistent with comments)
- Remove All/Comments/Activity filter toggle (comments are just a type of activity)
- Remove one-level reply restriction in backend (allow nested threading)
- Remove unused Circle import
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix activity:created WS payload to match frontend expectations
(issue_id at top level, entry as TimelineEntry object)
- Promote child comments to top-level when parent is deleted
(both in handleDeleteComment and WS comment:deleted handler)
- Enforce one-level reply nesting: reject replies to replies with 400
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the comment-only list with a Linear-style unified timeline that
interleaves field changes and comments chronologically.
Backend:
- activity_listeners.go: records field changes (status, assignee, description,
task completed/failed) to activity_log table on domain events
- Timeline API: GET /api/issues/{id}/timeline merges activity_log + comments
sorted by created_at
- Comment reply: parent_id column + handler support for threading
Frontend:
- Unified timeline replaces comment list: activity entries as compact muted
lines, comments as Card components with reply threading
- Filter toggle (All / Comments / Activity)
- Reply UI: inline editor under comments with Cancel/Reply buttons
- Real-time sync for activity:created + comment events
- 10 new Go tests, all passing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause: backend hardcoded UserType="member" in subscribe/unsubscribe handlers,
so unsubscribing an agent actually tried to delete a member record (no-op), and
the WS event broadcast wrong user_type causing other subscribers' UI to break.
- Backend: accept optional user_type in subscribe/unsubscribe request body
- Frontend: pass userType through API client to backend
- Fixes: clicking agent checkbox no longer affects member subscriptions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Backend: subscribe/unsubscribe API now accepts optional user_id to manage other users
- Frontend: replace manual avatar stacking with shadcn AvatarGroup component
- Frontend: replace disabled-checkbox Popover with Command+Popover combo (Linear-style)
- Search/filter workspace members
- Click to toggle subscription (checkbox)
- Shows reason badge (Assignee, Creator, etc.) for auto-subscribed users
- Clean up duplicate status_change type (keep only status_changed)
- All tests pass (Go + TypeScript)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace inbox_listeners.go with a subscriber-driven notification system:
- Add issue_subscriber table with auto-subscribe on create/assign/comment
- New subscriber_listeners.go: maintains subscriber data on domain events
- New notification_listeners.go: notifySubscribers (fanout to all subscribers
minus actor) and notifyDirect (targeted, punches through unsubscribe)
- Subscriber API: list/subscribe/unsubscribe endpoints
- Frontend: subscribers section in issue detail sidebar with real-time sync
- Frontend: inbox notification grouping by (issue_id, type, actor_id)
- Remove createInboxForIssueCreator from task.go (unified through event bus)
- 21 new Go tests, all passing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: decouple task lifecycle from issue status, add daemon health server
- Remove automatic issue status changes from StartTask (in_progress),
CompleteTask (in_review), and FailTask (blocked) in task service.
Issue status is now fully managed by the agent via `multica issue status`.
- Update agent prompt and meta skill to instruct agents to manage issue
status themselves (in_progress → done/in_review/blocked).
- Add daemon health HTTP server on 127.0.0.1:19514 with /health endpoint
exposing pid, uptime, agents, and workspaces. Fail fast if port is taken
(another daemon already running).
- Update `multica status` to check both server and daemon health.
- Add Save button to repos section in workspace settings UI.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor(daemon): simplify prompt, fix runtime config path, improve task error logging
- Slim down BuildPrompt to a minimal hint; detailed workflow now lives in CLAUDE.md/AGENTS.md
- Write CLAUDE.md to workDir root instead of .claude/CLAUDE.md
- Fix git-exclude pattern (.claude → CLAUDE.md)
- Decouple task queue reconciliation from issue status changes (agents manage status via CLI)
- Add diagnostic logging when CompleteTask/FailTask fail due to unexpected task state
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(task): use task_completed/task_failed inbox notification types
FailTask was sending "agent_blocked" which conflates agent crash with
issue-level blocked status. Align notification types with the new
decoupled model: task_completed and task_failed. Update frontend types
and labels accordingly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a `repos` JSONB column to the workspace table for storing
associated repository URLs and descriptions. This enables the daemon
to clone repos and set up git worktrees for agent task execution.
Structure: [{"url": "https://github.com/org/repo", "description": "..."}]
- Migration 014: adds repos column with default '[]'
- UpdateWorkspace query: supports updating repos
- Workspace API: returns repos in GET, accepts in PUT
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the frozen context snapshot pattern with a CLI-driven approach:
agents now use `multica` CLI commands to fetch issue details, comments,
and workspace context on demand, always getting the latest data.
- Remove buildContextSnapshot and snapshot generation from enqueue
- Claim endpoint now returns fresh agent name + skills from DB
- Daemon resolves provider from local runtimeIndex, not snapshot
- Prompt instructs agent to use `multica issue get` / `comment list`
- Meta skill (CLAUDE.md/AGENTS.md) documents all available CLI commands
- Skills still injected as filesystem files (static agent config)
- Simplify daemon types: remove TaskContext/IssueContext/RuntimeContext
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>