feat(cli): add multica issue take <id> for local agent takeover#1880
feat(cli): add multica issue take <id> for local agent takeover#1880james-heidi wants to merge 10 commits intomultica-ai:mainfrom
multica issue take <id> for local agent takeover#1880Conversation
Adds a one-liner command that resumes the agent's most recent completed run for an issue: spawns the right CLI in the worktree by default, with `--print` and `--copy` modes for shell wrappers and clipboard. `--provider` overrides the runtime auto-detection. Mapping covers claude, codex, cursor, gemini, opencode, and copilot. Workdir-gone falls back to the user's cwd; unsupported providers surface session_id + workdir for manual assembly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
feat(cli): add `multica issue take <id>` for local agent takeover
|
@james-heidi is attempting to deploy a commit to the IndexLabs Team on Vercel. A member of the Team first needs to authorize it. |
Commit 55b7e2e dropped the only consumer of `defaultModel` (the `triggerLabel` expression) but left the `useMemo` declaration in place, which fails `tsc --noEmit` with TS6133 and red-CI's any downstream branch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…t-model fix(views): remove unused defaultModel declaration in model-picker
# Conflicts: # packages/views/agents/components/inspector/model-picker.tsx
Cloud-runtime tasks don't persist a local session_id + work_dir (`PinTaskSession` is daemon-only), so `take` quietly skips them and exits with "no completed run found". Make that explicit in the command's long help so users assigning a cloud agent understand why nothing happens, instead of treating it as a bug. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
docs(cli): note that issue take only handles local-runtime sessions
Surfaces the existing `multica issue take --print` command as a desktop overflow menu item so users don't have to drop into a terminal to pick up where an agent left off. Clicking the entry runs the bundled CLI in the main process, copies the resolved shell command to the clipboard, and shows a toast with the workdir. Visibility: desktop builds only, gated on at least one resumable run (completed task with a session_id whose runtime provider is in the supported list — claude/codex/cursor/gemini/opencode/copilot). Web builds skip the data-fetch and never render the row. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The desktop CLI profile only stores `server_url` + `token`; it never pins a workspace because the renderer is the source of truth (the user can switch workspaces inside the app without ever touching the CLI). Without --workspace-id, `multica issue take <id> --print` issued the `/api/issues/<id>/task-runs` request with no `X-Workspace-*` header and the API returned 400 "workspace_id or workspace_slug is required". Plumb the active workspace id from the renderer through the IPC channel and into the CLI invocation so the headers are populated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
feat(desktop): add 'Take Over Locally' issue action
|
Hi @james-heidi — thanks for putting this together. Before diving into the implementation details, I'd like to step back and discuss the product framing, because I'm not sure this is a direction Multica wants to encourage as a first-class user-facing feature. What this PR offers, in product terms: when a cloud / daemon agent finishes a run on an issue, the user can take that session and resume it locally — either via The concern: if the user's goal is "I want to talk to the agent some more" or "I want to push it to do one more thing," the most natural path on Multica is to keep the conversation on the issue itself — comment, mention the agent, the next run picks up the resume pointer we already store. That's the affordance the product is built around: issue-as-thread, agent runs as part of that thread, everything visible to collaborators. A local takeover sits awkwardly next to that:
So my suggestion is to split the PR's value:
Curious what use cases you had in mind that aren't well served by just continuing the conversation on the issue — that would help calibrate whether the desktop entry is solving a real problem I'm underweighting, or whether the CLI alone covers it. Happy to dig into the implementation details (a few were noted earlier) once we're aligned on the product shape. |
|
Appreciated @Bohan-J for your comprehensive review. Let me bring the case first: when I chat with agent in a issue, I found it's hard to use local agent mcp,
so I need to `tap` into the original session to do a deep dive
and use the tools I have already configured in local agent environment (claude code or codex)
for example, I need to read/write context from/to notion page.Reason 1: The core direction here is to enjoy the local agent native experience that I have already configured. Reason 2: same as you mentioned, need to to deep-dive, trace back after a incident. Then my thought start jumping into this each issue becomes an agent-agnostic session that could be extended by any agent at any time. then the issue become a recoverable story. |
What does this PR do?
Adds a new
multica issue take <issue-id>CLI subcommand that resumes the agent's most recent completed run for an issue locally. By default it spawns the matching agent CLI inside the worktree the agent used (with stdin/stdout/stderr passthrough);--printemits the equivalent shell command forevalwrappers,--copydrops it on the system clipboard, and--provider <name>overrides the auto-detected provider.Local runtimes only. Cloud-runtime tasks don't persist a local
session_id+work_dir(PinTaskSessioninserver/internal/daemon/client.gois daemon-only), so they're skipped withno completed run foundrather than producing a broken resume command. The constraint is documented in the command's--help. A future remote-takeover feature would need its own attach/exec transport (out of scope here).Related Issue
N/A
Type of Change
Changes Made
server/cmd/multica/cmd_issue.go— newissueTakeCmdcobra command with--provider,--print,--copyflags. Auto-detects provider from/api/issues/<id>/task-runs[0].runtime_id→/api/runtimes. Builds a quoting-safecd <wd> && <bin> <args>shell line and either spawns the agent (default), prints, or pipes intopbcopy/xclip/xsel. Long help text spells out the local-only constraint.claude,codex,cursor,gemini,opencode,copilot. Unsupported providers exit non-zero after surfacing thesession_id+work_dirfor manual assembly.$PWD; no completed run → exit withno completed run found;codexthread expired → propagate codex's stderr verbatim (no retry, since stdio is pass-through). Cloud-runtime tasks fall into the "no completed run found" path because the daemon's session pin never runs.server/cmd/multica/cmd_issue_test.go— 6 newTestIssueTake*end-to-end cases (auto-detect, --print, --copy mutex, unsupported provider, runtime-not-found, --provider override) plus unit tests for the provider map, POSIX shell quoter, and run picker.How to Test
Checklist
go test ./...→ 872 passed across 25 packages;go vet ./cmd/multica/clean)--helplong text now states the local-only constraint)AI Disclosure
AI tool used: Claude Code (Opus 4.7).
Prompt / approach: Diagnosed CI failure on the original PR, traced the unused-variable error to commit 55b7e2e which removed the consumer (
triggerLabel) but left the declaration. Removed the declaration and refreshed the surrounding comment. Subsequent reviewer question about cloud runtime support produced an audit confirmingtakeis local-only and a doc tweak in--helpto say so.Screenshots (optional)
N/A.