build: add direct cleanup command

This commit is contained in:
2026-03-19 19:41:25 +05:30
parent 5593bc8cc9
commit bfd55e0f9f
5 changed files with 31 additions and 16 deletions
+16 -13
View File
@@ -34,8 +34,8 @@ If you installed it via bun and want to use it as a project tool, import it from
```typescript ```typescript
// .opencode/tools/multi-model.ts // .opencode/tools/multi-model.ts
import { openTool, closeTool } from "@username/opencode-multi-model" import { openTool as open, closeTool as close } from "@username/opencode-multi-model"
export { openTool, closeTool } export { open, close }
``` ```
If you are developing this package locally and want to test it in a project without publishing, import via relative paths: If you are developing this package locally and want to test it in a project without publishing, import via relative paths:
@@ -44,7 +44,7 @@ If you are developing this package locally and want to test it in a project with
// .opencode/tools/multi-model.ts // .opencode/tools/multi-model.ts
import { openTool } from "../../src/tools/open" import { openTool } from "../../src/tools/open"
import { closeTool } from "../../src/tools/close" import { closeTool } from "../../src/tools/close"
export { openTool, closeTool } export { openTool as open, closeTool as close }
``` ```
## Usage ## Usage
@@ -57,10 +57,14 @@ Use multi-model-open tool:
sessionName: my-session, models: ["openai/gpt-4o", "anthropic/claude-3-5-sonnet"] sessionName: my-session, models: ["openai/gpt-4o", "anthropic/claude-3-5-sonnet"]
``` ```
**Close a session:** **Close a session (using tool):**
``` ```
Use multi-model-close tool: call tool multi-model-close with sessionName: my-session
sessionName: my-session, cleanupWorktrees: true ```
**Close a session (using manual command):**
```bash
tmux kill-session -t my-session && rm -rf ~/.local/share/opencode/multi-model/my-session && git worktree prune && git branch -D $(git branch --format='%(refname:short)' --list 'opencode/my-session/*')
``` ```
### CLI Usage ### CLI Usage
@@ -78,16 +82,15 @@ export OPENCODE_MULTI_MODEL_BINARY=kilo
opencode-multi-model open my-session -m openai/gpt-4o opencode-multi-model open my-session -m openai/gpt-4o
``` ```
**Close a session:** **Close a session (CLI command):**
```bash ```bash
# Just close the tmux session
opencode-multi-model close my-session
# Close and cleanup worktrees # Close and cleanup worktrees
opencode-multi-model close my-session --cleanup-worktrees opencode-multi-model close my-session
```
# Force cleanup without confirmation **Close a session (manual command):**
opencode-multi-model close my-session --cleanup-worktrees --force ```bash
tmux kill-session -t my-session && rm -rf ~/.local/share/opencode/multi-model/my-session && git worktree prune && git branch -D $(git branch --format='%(refname:short)' --list 'opencode/my-session/*')
``` ```
**Help:** **Help:**
+1
View File
@@ -25,6 +25,7 @@ program
sessionName, sessionName,
models: options.models, models: options.models,
binaryName, binaryName,
mode: "cli",
}); });
if (result.success) { if (result.success) {
+11 -3
View File
@@ -39,6 +39,7 @@ export async function launchMultiModel(options: MultiModelOptions): Promise<Mult
const safeSessionName = sanitizeName(sessionName); const safeSessionName = sanitizeName(sessionName);
const models = normalizeModels(options.models); const models = normalizeModels(options.models);
const binaryName = options.binaryName || "opencode"; const binaryName = options.binaryName || "opencode";
const mode = options.mode || "cli";
if (!sessionName) { if (!sessionName) {
return { success: false, sessionName: "", error: "Error: `sessionName` must not be empty." }; return { success: false, sessionName: "", error: "Error: `sessionName` must not be empty." };
@@ -189,6 +190,10 @@ export async function launchMultiModel(options: MultiModelOptions): Promise<Mult
const windowNames = windowPlans.map((p) => p.windowName); const windowNames = windowPlans.map((p) => p.windowName);
const attachCommand = `tmux attach -t ${sessionName}`; const attachCommand = `tmux attach -t ${sessionName}`;
const cleanupCommand = `tmux kill-session -t ${sessionName} && rm -rf ~/.local/share/opencode/multi-model/${safeSessionName} && git worktree prune && git branch -D $(git branch --format='%(refname:short)' --list 'opencode/${safeSessionName}/*')`; const cleanupCommand = `tmux kill-session -t ${sessionName} && rm -rf ~/.local/share/opencode/multi-model/${safeSessionName} && git worktree prune && git branch -D $(git branch --format='%(refname:short)' --list 'opencode/${safeSessionName}/*')`;
const primaryCleanup =
mode === "tool"
? `call tool multi-model-close with sessionName: ${sessionName}`
: `opencode-multi-model close ${sessionName}`;
if (failedModels.length > 0) { if (failedModels.length > 0) {
return { return {
@@ -200,7 +205,9 @@ export async function launchMultiModel(options: MultiModelOptions): Promise<Mult
`Succeeded: ${succeededModels.length > 0 ? succeededModels.join(", ") : "none"}.`, `Succeeded: ${succeededModels.length > 0 ? succeededModels.join(", ") : "none"}.`,
`Failed: ${failedModels.join(", ")}.`, `Failed: ${failedModels.join(", ")}.`,
`Attach with \`${attachCommand}\` to inspect the session.`, `Attach with \`${attachCommand}\` to inspect the session.`,
`Cleanup with \n\`${cleanupCommand}\`\nwhen done.`, `Cleanup when done using either:`,
`1. ${primaryCleanup}`,
`2. Or run manually: \`${cleanupCommand}\``,
].join("\n"), ].join("\n"),
}; };
} }
@@ -211,8 +218,9 @@ export async function launchMultiModel(options: MultiModelOptions): Promise<Mult
windows: windowNames, windows: windowNames,
instructions: [ instructions: [
`Use \`${attachCommand}\` to join session.`, `Use \`${attachCommand}\` to join session.`,
`When finished, clean up worktrees with:`, `When finished, clean up using either:`,
`\`${cleanupCommand}\``, `1. ${primaryCleanup}`,
`2. Or run manually: \`${cleanupCommand}\``,
].join("\n"), ].join("\n"),
}; };
} }
+1
View File
@@ -24,6 +24,7 @@ export const openTool = tool({
sessionName: args.sessionName, sessionName: args.sessionName,
models: args.models, models: args.models,
binaryName, binaryName,
mode: "tool",
}); });
context.metadata({ context.metadata({
+2
View File
@@ -8,6 +8,8 @@ export interface MultiModelOptions {
models: string[]; models: string[];
/** Binary name to use ('opencode' or 'kilo'). Defaults to 'opencode'. */ /** Binary name to use ('opencode' or 'kilo'). Defaults to 'opencode'. */
binaryName?: string; binaryName?: string;
/** Caller context: 'cli' shows shell commands, 'tool' shows tool instructions. */
mode?: "cli" | "tool";
} }
/** /**