refactor: replace agent-control MCP with labels system and Paseo MCP
This commit is contained in:
@@ -55,7 +55,7 @@ Notes:
|
||||
|
||||
### `packages/cli/src/commands/agent/inspect.ts`
|
||||
Inline types:
|
||||
- `AgentSnapshotLike` (snapshot fields + `lastUsage`, `capabilities`, `availableModes`, `pendingPermissions`, `parentAgentId`)
|
||||
- `AgentSnapshotLike` (snapshot fields + `lastUsage`, `capabilities`, `availableModes`, `pendingPermissions`)
|
||||
|
||||
Recommended server types:
|
||||
- `AgentSnapshotPayload` (overall snapshot shape). **Not exported**.
|
||||
|
||||
@@ -37,9 +37,11 @@ export function createCli(): Command {
|
||||
// Primary agent commands (top-level)
|
||||
program
|
||||
.command('ls')
|
||||
.description('List agents. By default shows running agents in current directory.')
|
||||
.description('List agents. By default shows background agents (without ui=true) in current directory.')
|
||||
.option('-a, --all', 'Include all statuses (not just running)')
|
||||
.option('-g, --global', 'Show agents from all directories (not just current)')
|
||||
.option('--label <key=value>', 'Filter by label (can be used multiple times)', collectMultiple, [])
|
||||
.option('--ui', 'Show only UI agents (equivalent to --label ui=true)')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host:port (default: localhost:6767)')
|
||||
.action((options, command) => {
|
||||
@@ -62,6 +64,8 @@ export function createCli(): Command {
|
||||
.option('--base <branch>', 'Base branch for worktree (default: current branch)')
|
||||
.option('--image <path>', 'Attach image(s) to the initial prompt (can be used multiple times)', collectMultiple, [])
|
||||
.option('--cwd <path>', 'Working directory (default: current)')
|
||||
.option('--label <key=value>', 'Add label(s) to the agent (can be used multiple times)', collectMultiple, [])
|
||||
.option('--ui', 'Mark as UI agent (equivalent to --label ui=true)')
|
||||
.option('--host <host>', 'Daemon host:port (default: localhost:6767)')
|
||||
.action(withOutput(runRunCommand))
|
||||
|
||||
|
||||
@@ -14,12 +14,19 @@ import { withOutput } from '../../output/index.js'
|
||||
export function createAgentCommand(): Command {
|
||||
const agent = new Command('agent').description('Manage agents (advanced operations)')
|
||||
|
||||
// Helper function to collect multiple option values into an array
|
||||
const collectMultiple = (value: string, previous: string[]): string[] => {
|
||||
return previous.concat([value])
|
||||
}
|
||||
|
||||
// Primary agent commands (same as top-level)
|
||||
agent
|
||||
.command('ls')
|
||||
.description('List agents. By default shows running agents in current directory.')
|
||||
.description('List agents. By default shows background agents (without ui=true) in current directory.')
|
||||
.option('-a, --all', 'Include all statuses (not just running)')
|
||||
.option('-g, --global', 'Show agents from all directories (not just current)')
|
||||
.option('--label <key=value>', 'Filter by label (can be used multiple times)', collectMultiple, [])
|
||||
.option('--ui', 'Show only UI agents (equivalent to --label ui=true)')
|
||||
.option('--json', 'Output in JSON format')
|
||||
.option('--host <host>', 'Daemon host:port (default: localhost:6767)')
|
||||
.action((options, command) => {
|
||||
@@ -39,6 +46,8 @@ export function createAgentCommand(): Command {
|
||||
.option('--model <model>', 'Model to use (e.g., claude-sonnet-4-20250514, claude-3-5-haiku-20241022)')
|
||||
.option('--mode <mode>', 'Provider-specific mode (e.g., plan, default, bypass)')
|
||||
.option('--cwd <path>', 'Working directory (default: current)')
|
||||
.option('--label <key=value>', 'Add label(s) to the agent (can be used multiple times)', collectMultiple, [])
|
||||
.option('--ui', 'Mark as UI agent (equivalent to --label ui=true)')
|
||||
.option('--host <host>', 'Daemon host:port (default: localhost:6767)')
|
||||
.action(withOutput(runRunCommand))
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ interface AgentInspect {
|
||||
id: string
|
||||
tool: string
|
||||
}>
|
||||
parentAgentId: string | null
|
||||
}
|
||||
|
||||
/** Key-value row for table display */
|
||||
@@ -122,7 +121,6 @@ function toInspectData(snapshot: AgentSnapshotPayload): AgentInspect {
|
||||
id: p.id,
|
||||
tool: p.name ?? 'unknown',
|
||||
})),
|
||||
parentAgentId: snapshot.parentAgentId ?? null,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,11 +175,6 @@ function toInspectRows(agent: AgentInspect): InspectRow[] {
|
||||
rows.push({ key: 'PendingPermissions', value: '[]' })
|
||||
}
|
||||
|
||||
rows.push({
|
||||
key: 'ParentAgentId',
|
||||
value: agent.parentAgentId ?? 'null',
|
||||
})
|
||||
|
||||
return rows
|
||||
}
|
||||
|
||||
|
||||
@@ -82,6 +82,10 @@ export interface AgentLsOptions extends CommandOptions {
|
||||
status?: string
|
||||
/** Filter by specific cwd (overrides default cwd filtering) */
|
||||
cwd?: string
|
||||
/** Filter by labels (key=value format) */
|
||||
label?: string[]
|
||||
/** Filter to UI agents only (equivalent to --label ui=true) */
|
||||
ui?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,6 +149,46 @@ export async function runLsCommand(
|
||||
})
|
||||
}
|
||||
|
||||
// Label filtering:
|
||||
// Parse --label flags and --ui flag
|
||||
// --ui is equivalent to --label ui=true
|
||||
// By default (no --ui flag), show background agents (those WITHOUT ui=true)
|
||||
const labelFilters: Record<string, string> = {}
|
||||
if (options.label) {
|
||||
for (const labelStr of options.label) {
|
||||
const eqIndex = labelStr.indexOf('=')
|
||||
if (eqIndex !== -1) {
|
||||
const key = labelStr.slice(0, eqIndex)
|
||||
const value = labelStr.slice(eqIndex + 1)
|
||||
labelFilters[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add ui=true filter if --ui flag is set
|
||||
if (options.ui) {
|
||||
labelFilters['ui'] = 'true'
|
||||
}
|
||||
|
||||
// Apply label filtering
|
||||
if (Object.keys(labelFilters).length > 0) {
|
||||
// Filter to agents that have ALL specified labels (AND semantics)
|
||||
agents = agents.filter((a) => {
|
||||
const agentLabels = (a as any).labels as Record<string, string> | undefined
|
||||
for (const [key, value] of Object.entries(labelFilters)) {
|
||||
if (!agentLabels || agentLabels[key] !== value) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
} else {
|
||||
// Default: show background agents only (those without ui=true)
|
||||
agents = agents.filter((a) => {
|
||||
const agentLabels = (a as any).labels as Record<string, string> | undefined
|
||||
return !agentLabels || agentLabels['ui'] !== 'true'
|
||||
})
|
||||
}
|
||||
|
||||
await client.close()
|
||||
|
||||
// Sort agents: running first, then idle, then others; within each group, most recent first
|
||||
|
||||
@@ -37,6 +37,8 @@ export interface AgentRunOptions extends CommandOptions {
|
||||
base?: string
|
||||
image?: string[]
|
||||
cwd?: string
|
||||
label?: string[]
|
||||
ui?: boolean
|
||||
}
|
||||
|
||||
function toRunResult(agent: AgentSnapshotPayload): AgentRunResult {
|
||||
@@ -127,6 +129,31 @@ export async function runRunCommand(
|
||||
}
|
||||
: undefined
|
||||
|
||||
// Build labels from --label and --ui flags
|
||||
// --ui is syntactic sugar for --label ui=true
|
||||
// If explicit --label ui=... is provided, it takes precedence over --ui
|
||||
const labels: Record<string, string> = {}
|
||||
if (options.label) {
|
||||
for (const labelStr of options.label) {
|
||||
const eqIndex = labelStr.indexOf('=')
|
||||
if (eqIndex === -1) {
|
||||
const error: CommandError = {
|
||||
code: 'INVALID_LABEL',
|
||||
message: `Invalid label format: ${labelStr}`,
|
||||
details: 'Labels must be in key=value format',
|
||||
}
|
||||
throw error
|
||||
}
|
||||
const key = labelStr.slice(0, eqIndex)
|
||||
const value = labelStr.slice(eqIndex + 1)
|
||||
labels[key] = value
|
||||
}
|
||||
}
|
||||
// Add ui=true if --ui flag is set and ui label not already set
|
||||
if (options.ui && !('ui' in labels)) {
|
||||
labels['ui'] = 'true'
|
||||
}
|
||||
|
||||
// Create the agent
|
||||
const agent = await client.createAgent({
|
||||
provider: (options.provider as 'claude' | 'codex' | 'opencode') ?? 'claude',
|
||||
@@ -138,6 +165,7 @@ export async function runRunCommand(
|
||||
images,
|
||||
git,
|
||||
worktreeName: options.worktree,
|
||||
labels: Object.keys(labels).length > 0 ? labels : undefined,
|
||||
})
|
||||
|
||||
await client.close()
|
||||
|
||||
Reference in New Issue
Block a user