Merge branch 'main' into dev

Resolve 38 conflicts preserving both sides' work:
- Server: DB-based registries (dev) + WorkspaceGitService/DaemonConfigStore (main)
- App: script proxy/voice MCP (dev) + pin/hide tabs/bootstrap boundary (main)
- Shared: WorkspaceScriptPayload (dev) + git/GitHub runtime schemas (main)
- Deleted workspace-registry-bootstrap.ts (dev's DB approach supersedes)
This commit is contained in:
Mohamed Boudra
2026-04-14 03:05:45 +07:00
333 changed files with 13490 additions and 6317 deletions
+1 -1
View File
@@ -26,7 +26,7 @@ export const archiveSchema: OutputSchema<AgentArchiveResult> = {
export function addArchiveOptions(cmd: Command): Command {
return cmd
.description('Archive an agent (soft-delete)')
.description("Archive an agent (soft-delete)")
.argument("<id>", "Agent ID, prefix, or name")
.option("--force", "Force archive running agent (interrupts active run first)");
}
+29 -30
View File
@@ -10,6 +10,7 @@ import { addSendOptions, runSendCommand } from "./send.js";
import { addInspectOptions, runInspectCommand } from "./inspect.js";
import { addWaitOptions, runWaitCommand } from "./wait.js";
import { addAttachOptions, runAttachCommand } from "./attach.js";
import { addReloadOptions, runReloadCommand } from "./reload.js";
import { runUpdateCommand } from "./update.js";
import { withOutput } from "../../output/index.js";
import {
@@ -22,41 +23,35 @@ export function createAgentCommand(): Command {
const agent = new Command("agent").description("Manage agents (advanced operations)");
// Primary agent commands (same as top-level)
addJsonAndDaemonHostOptions(
addLsOptions(agent.command("ls")),
).action(withOutput(runLsCommand));
addJsonAndDaemonHostOptions(addLsOptions(agent.command("ls"))).action(withOutput(runLsCommand));
addJsonAndDaemonHostOptions(
addRunOptions(agent.command("run")),
).action(withOutput(runRunCommand));
addJsonAndDaemonHostOptions(addRunOptions(agent.command("run"))).action(
withOutput(runRunCommand),
);
addDaemonHostOption(
addAttachOptions(agent.command("attach")),
).action(runAttachCommand);
addDaemonHostOption(addAttachOptions(agent.command("attach"))).action(runAttachCommand);
addDaemonHostOption(
addLogsOptions(agent.command("logs")),
).action(runLogsCommand);
addDaemonHostOption(addLogsOptions(agent.command("logs"))).action(runLogsCommand);
addJsonAndDaemonHostOptions(
addStopOptions(agent.command("stop")),
).action(withOutput(runStopCommand));
addJsonAndDaemonHostOptions(addStopOptions(agent.command("stop"))).action(
withOutput(runStopCommand),
);
addJsonAndDaemonHostOptions(
addDeleteOptions(agent.command("delete")),
).action(withOutput(runDeleteCommand));
addJsonAndDaemonHostOptions(addDeleteOptions(agent.command("delete"))).action(
withOutput(runDeleteCommand),
);
addJsonAndDaemonHostOptions(
addSendOptions(agent.command("send")),
).action(withOutput(runSendCommand));
addJsonAndDaemonHostOptions(addSendOptions(agent.command("send"))).action(
withOutput(runSendCommand),
);
addJsonAndDaemonHostOptions(
addInspectOptions(agent.command("inspect")),
).action(withOutput(runInspectCommand));
addJsonAndDaemonHostOptions(addInspectOptions(agent.command("inspect"))).action(
withOutput(runInspectCommand),
);
addJsonAndDaemonHostOptions(
addWaitOptions(agent.command("wait")),
).action(withOutput(runWaitCommand));
addJsonAndDaemonHostOptions(addWaitOptions(agent.command("wait"))).action(
withOutput(runWaitCommand),
);
// Advanced agent commands (less common operations)
addJsonAndDaemonHostOptions(
@@ -68,9 +63,13 @@ export function createAgentCommand(): Command {
.option("--list", "List available modes for this agent"),
).action(withOutput(runModeCommand));
addJsonAndDaemonHostOptions(
addArchiveOptions(agent.command("archive")),
).action(withOutput(runArchiveCommand));
addJsonAndDaemonHostOptions(addArchiveOptions(agent.command("archive"))).action(
withOutput(runArchiveCommand),
);
addJsonAndDaemonHostOptions(addReloadOptions(agent.command("reload"))).action(
withOutput(runReloadCommand),
);
addJsonAndDaemonHostOptions(
agent
+106
View File
@@ -0,0 +1,106 @@
import { Command } from "commander";
import { connectToDaemon, getDaemonHost, resolveAgentId } from "../../utils/client.js";
import type {
CommandOptions,
SingleResult,
OutputSchema,
CommandError,
} from "../../output/index.js";
export interface AgentReloadResult {
agentId: string;
status: "reloaded";
timelineSize: number;
}
export const reloadSchema: OutputSchema<AgentReloadResult> = {
idField: "agentId",
columns: [
{ header: "AGENT ID", field: "agentId" },
{ header: "STATUS", field: "status" },
{ header: "TIMELINE", field: "timelineSize" },
],
};
export function addReloadOptions(cmd: Command): Command {
return cmd
.description("Reload an agent (restarts the underlying process)")
.argument("<id>", "Agent ID, prefix, or name");
}
export interface AgentReloadOptions extends CommandOptions {
host?: string;
}
export type AgentReloadCommandResult = SingleResult<AgentReloadResult>;
export async function runReloadCommand(
agentIdArg: string,
options: AgentReloadOptions,
_command: Command,
): Promise<AgentReloadCommandResult> {
const host = getDaemonHost({ host: options.host as string | undefined });
if (!agentIdArg || agentIdArg.trim().length === 0) {
const error: CommandError = {
code: "MISSING_AGENT_ID",
message: "Agent ID is required",
details: "Usage: paseo agent reload <id-or-name>",
};
throw error;
}
let client;
try {
client = await connectToDaemon({ host: options.host as string | undefined });
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
const error: CommandError = {
code: "DAEMON_NOT_RUNNING",
message: `Cannot connect to daemon at ${host}: ${message}`,
details: "Start the daemon with: paseo daemon start",
};
throw error;
}
try {
const agentsPayload = await client.fetchAgents({ filter: { includeArchived: true } });
const agents = agentsPayload.entries.map((entry) => entry.agent);
const agentId = resolveAgentId(agentIdArg, agents);
if (!agentId) {
const error: CommandError = {
code: "AGENT_NOT_FOUND",
message: `Agent not found: ${agentIdArg}`,
details: 'Use "paseo ls" to list available agents',
};
throw error;
}
const result = await client.refreshAgent(agentId);
await client.close();
return {
type: "single",
data: {
agentId: result.agentId,
status: "reloaded",
timelineSize: result.timelineSize ?? 0,
},
schema: reloadSchema,
};
} catch (err) {
await client.close().catch(() => {});
if (err && typeof err === "object" && "code" in err) {
throw err;
}
const message = err instanceof Error ? err.message : String(err);
const error: CommandError = {
code: "RELOAD_FAILED",
message: `Failed to reload agent: ${message}`,
};
throw error;
}
}
+7 -4
View File
@@ -1,4 +1,4 @@
import { Command } from "commander";
import { Command, Option } from "commander";
import {
getStructuredAgentResponse,
StructuredAgentResponseError,
@@ -22,7 +22,8 @@ export function addRunOptions(cmd: Command): Command {
.description("Create and start an agent with a task")
.argument("<prompt>", "The task/prompt for the agent")
.option("-d, --detach", "Run in background (detached)")
.option("--name <name>", "Assign a name/title to the agent")
.option("--title <title>", "Assign a title to the agent")
.addOption(new Option("--name <name>", "Hidden alias for --title").hideHelp())
.option(
"--provider <provider>",
"Agent provider, or provider/model (e.g. codex or codex/gpt-5.4)",
@@ -82,6 +83,7 @@ export const agentRunSchema: OutputSchema<AgentRunResult> = {
export interface AgentRunOptions extends CommandOptions {
detach?: boolean;
title?: string;
name?: string;
provider?: string;
model?: string;
@@ -324,6 +326,7 @@ export async function runRunCommand(
}
const resolvedProviderModel = resolveProviderAndModel(options);
const resolvedTitle = options.title ?? options.name;
let client;
try {
@@ -413,7 +416,7 @@ export async function runRunCommand(
structuredAgent = await client.createAgent({
provider: resolvedProviderModel.provider,
cwd,
title: options.name,
title: resolvedTitle,
modeId: options.mode,
model: resolvedProviderModel.model,
thinkingOptionId,
@@ -512,7 +515,7 @@ export async function runRunCommand(
const agent = await client.createAgent({
provider: resolvedProviderModel.provider,
cwd,
title: options.name,
title: resolvedTitle,
modeId: options.mode,
model: resolvedProviderModel.model,
thinkingOptionId,