mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
chore: remove packages/cli/docs
This commit is contained in:
@@ -1,544 +0,0 @@
|
||||
# Output Architecture Design
|
||||
|
||||
This document describes the output abstraction layer for the Paseo CLI, enabling structured data output with multiple format options.
|
||||
|
||||
## Overview
|
||||
|
||||
Commands should return **structured data objects**, not formatted strings. A separate rendering layer transforms this data into the requested output format. This separation enables:
|
||||
|
||||
1. **Testability** - Tests verify structured data without parsing strings
|
||||
2. **Flexibility** - Easy to add new output formats
|
||||
3. **Consistency** - Uniform formatting across all commands
|
||||
|
||||
### Inspiration from Existing CLIs
|
||||
|
||||
This design draws from patterns in established CLIs:
|
||||
|
||||
- **Docker CLI** - Uses Go templates with `--format` flag, provides `table` and `json` directives
|
||||
- **kubectl** - Supports `-o json`, `-o yaml`, `-o wide`, and custom columns
|
||||
- **GitHub CLI** - Uses `--json` with field selection, plus `--jq` and `--template` post-processors
|
||||
|
||||
Sources:
|
||||
- [Docker CLI Formatting](https://docs.docker.com/engine/cli/formatting/)
|
||||
- [kubectl Output Formatting](https://www.baeldung.com/ops/kubectl-output-format)
|
||||
- [GitHub CLI Formatting](https://cli.github.com/manual/gh_help_formatting)
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Command Execution │
|
||||
│ │
|
||||
│ parseArgs() → executeCommand() → CommandResult<T> │
|
||||
└─────────────────────────────────┬───────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Output Renderer │
|
||||
│ │
|
||||
│ CommandResult<T> + OutputOptions → formatted string │
|
||||
│ │
|
||||
│ Renderers: │
|
||||
│ - TableRenderer (default, human-readable) │
|
||||
│ - JsonRenderer (machine-readable) │
|
||||
│ - YamlRenderer (machine-readable) │
|
||||
│ - QuietRenderer (minimal, IDs only) │
|
||||
└─────────────────────────────────┬───────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ stdout/stderr │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Type Definitions
|
||||
|
||||
### Output Options
|
||||
|
||||
```typescript
|
||||
type OutputFormat = 'table' | 'json' | 'yaml'
|
||||
|
||||
interface OutputOptions {
|
||||
format: OutputFormat
|
||||
quiet: boolean // Minimal output (IDs only)
|
||||
noHeaders: boolean // Omit table headers
|
||||
noColor: boolean // Disable color output
|
||||
}
|
||||
```
|
||||
|
||||
### Command Result
|
||||
|
||||
Commands return a `CommandResult<T>` that contains structured data plus metadata for formatting:
|
||||
|
||||
```typescript
|
||||
interface CommandResult<T> {
|
||||
/** The structured data to render */
|
||||
data: T
|
||||
|
||||
/** Schema describing how to render this data */
|
||||
schema: OutputSchema<T>
|
||||
}
|
||||
|
||||
interface OutputSchema<T> {
|
||||
/** Field to use for quiet mode (--quiet outputs just this) */
|
||||
idField: keyof T | ((item: T) => string)
|
||||
|
||||
/** Column definitions for table output */
|
||||
columns: ColumnDef<T>[]
|
||||
|
||||
/** Optional: transform data before JSON/YAML output */
|
||||
serialize?: (data: T) => unknown
|
||||
}
|
||||
|
||||
interface ColumnDef<T> {
|
||||
/** Header text for the column */
|
||||
header: string
|
||||
|
||||
/** Field key or accessor function */
|
||||
field: keyof T | ((item: T) => unknown)
|
||||
|
||||
/** Optional width hint (characters) */
|
||||
width?: number
|
||||
|
||||
/** Optional alignment */
|
||||
align?: 'left' | 'right' | 'center'
|
||||
|
||||
/** Optional color function */
|
||||
color?: (value: unknown, item: T) => string | undefined
|
||||
}
|
||||
```
|
||||
|
||||
### Single vs List Results
|
||||
|
||||
Commands may return either a single item or a list:
|
||||
|
||||
```typescript
|
||||
// For commands returning a single item (e.g., `agent show <id>`)
|
||||
interface SingleResult<T> extends CommandResult<T> {
|
||||
type: 'single'
|
||||
data: T
|
||||
}
|
||||
|
||||
// For commands returning a list (e.g., `agent list`)
|
||||
interface ListResult<T> extends CommandResult<T[]> {
|
||||
type: 'list'
|
||||
data: T[]
|
||||
}
|
||||
|
||||
// Union type for command handlers
|
||||
type AnyCommandResult<T> = SingleResult<T> | ListResult<T>
|
||||
```
|
||||
|
||||
## Example: Agent List Command
|
||||
|
||||
### Data Type
|
||||
|
||||
```typescript
|
||||
interface AgentListItem {
|
||||
id: string
|
||||
title: string
|
||||
status: 'running' | 'idle' | 'error'
|
||||
provider: string
|
||||
cwd: string
|
||||
createdAt: string
|
||||
}
|
||||
```
|
||||
|
||||
### Schema Definition
|
||||
|
||||
```typescript
|
||||
const agentListSchema: OutputSchema<AgentListItem> = {
|
||||
idField: 'id',
|
||||
|
||||
columns: [
|
||||
{
|
||||
header: 'ID',
|
||||
field: 'id',
|
||||
width: 8,
|
||||
},
|
||||
{
|
||||
header: 'TITLE',
|
||||
field: 'title',
|
||||
width: 30,
|
||||
},
|
||||
{
|
||||
header: 'STATUS',
|
||||
field: 'status',
|
||||
color: (value) => {
|
||||
switch (value) {
|
||||
case 'running': return 'green'
|
||||
case 'idle': return 'dim'
|
||||
case 'error': return 'red'
|
||||
default: return undefined
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
header: 'PROVIDER',
|
||||
field: 'provider',
|
||||
},
|
||||
{
|
||||
header: 'CWD',
|
||||
field: 'cwd',
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### Command Implementation
|
||||
|
||||
```typescript
|
||||
async function agentListCommand(options: CommandOptions): Promise<ListResult<AgentListItem>> {
|
||||
const client = await connectToDaemon(options)
|
||||
const agents = client.listAgents()
|
||||
|
||||
const data = agents.map(agent => ({
|
||||
id: agent.agentId,
|
||||
title: agent.title ?? '(untitled)',
|
||||
status: mapLifecycleStatus(agent.lifecycle),
|
||||
provider: agent.agentType,
|
||||
cwd: agent.cwd,
|
||||
createdAt: agent.createdAt,
|
||||
}))
|
||||
|
||||
return {
|
||||
type: 'list',
|
||||
data,
|
||||
schema: agentListSchema,
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Renderer Implementations
|
||||
|
||||
### Table Renderer
|
||||
|
||||
The default renderer for human-readable output:
|
||||
|
||||
```typescript
|
||||
function renderTable<T>(result: ListResult<T>, options: OutputOptions): string {
|
||||
const { data, schema } = result
|
||||
|
||||
if (data.length === 0) {
|
||||
return '' // Or a "no items" message
|
||||
}
|
||||
|
||||
const rows: string[][] = []
|
||||
|
||||
// Add header row (unless noHeaders)
|
||||
if (!options.noHeaders) {
|
||||
rows.push(schema.columns.map(col => col.header))
|
||||
}
|
||||
|
||||
// Add data rows
|
||||
for (const item of data) {
|
||||
const row = schema.columns.map(col => {
|
||||
const value = typeof col.field === 'function'
|
||||
? col.field(item)
|
||||
: item[col.field]
|
||||
return String(value ?? '')
|
||||
})
|
||||
rows.push(row)
|
||||
}
|
||||
|
||||
// Calculate column widths
|
||||
const widths = schema.columns.map((col, i) => {
|
||||
const maxContent = Math.max(...rows.map(row => stripAnsi(row[i]).length))
|
||||
return col.width ? Math.max(col.width, maxContent) : maxContent
|
||||
})
|
||||
|
||||
// Format and join
|
||||
return rows.map((row, rowIndex) => {
|
||||
return row.map((cell, colIndex) => {
|
||||
const col = schema.columns[colIndex]
|
||||
const width = widths[colIndex]
|
||||
let formatted = padCell(cell, width, col.align ?? 'left')
|
||||
|
||||
// Apply color (skip header row)
|
||||
if (rowIndex > 0 && col.color && !options.noColor) {
|
||||
const colorName = col.color(cell, data[rowIndex - 1])
|
||||
if (colorName) {
|
||||
formatted = applyColor(formatted, colorName)
|
||||
}
|
||||
}
|
||||
|
||||
return formatted
|
||||
}).join(' ')
|
||||
}).join('\n')
|
||||
}
|
||||
```
|
||||
|
||||
### JSON Renderer
|
||||
|
||||
```typescript
|
||||
function renderJson<T>(result: AnyCommandResult<T>, options: OutputOptions): string {
|
||||
const { data, schema } = result
|
||||
const output = schema.serialize ? schema.serialize(data) : data
|
||||
return JSON.stringify(output, null, 2)
|
||||
}
|
||||
```
|
||||
|
||||
### YAML Renderer
|
||||
|
||||
```typescript
|
||||
import YAML from 'yaml'
|
||||
|
||||
function renderYaml<T>(result: AnyCommandResult<T>, options: OutputOptions): string {
|
||||
const { data, schema } = result
|
||||
const output = schema.serialize ? schema.serialize(data) : data
|
||||
return YAML.stringify(output)
|
||||
}
|
||||
```
|
||||
|
||||
### Quiet Renderer
|
||||
|
||||
Returns only the ID field(s):
|
||||
|
||||
```typescript
|
||||
function renderQuiet<T>(result: AnyCommandResult<T>, options: OutputOptions): string {
|
||||
const { data, schema } = result
|
||||
const getId = typeof schema.idField === 'function'
|
||||
? schema.idField
|
||||
: (item: T) => String(item[schema.idField as keyof T])
|
||||
|
||||
if (result.type === 'single') {
|
||||
return getId(data as T)
|
||||
}
|
||||
|
||||
return (data as T[]).map(getId).join('\n')
|
||||
}
|
||||
```
|
||||
|
||||
## Error Output
|
||||
|
||||
Errors are handled separately from success output and always go to stderr:
|
||||
|
||||
```typescript
|
||||
interface CommandError {
|
||||
code: string // Machine-readable error code
|
||||
message: string // Human-readable message
|
||||
details?: unknown // Additional context
|
||||
}
|
||||
|
||||
function renderError(error: CommandError, options: OutputOptions): string {
|
||||
if (options.format === 'json') {
|
||||
return JSON.stringify({ error }, null, 2)
|
||||
}
|
||||
|
||||
if (options.format === 'yaml') {
|
||||
return YAML.stringify({ error })
|
||||
}
|
||||
|
||||
// Table/default format
|
||||
return chalk.red(`Error: ${error.message}`)
|
||||
}
|
||||
```
|
||||
|
||||
## Streaming Output
|
||||
|
||||
For commands like `logs -f` and `attach`, streaming requires a different approach:
|
||||
|
||||
```typescript
|
||||
interface StreamingResult<T> {
|
||||
type: 'stream'
|
||||
schema: OutputSchema<T>
|
||||
|
||||
/** Async iterator yielding items as they arrive */
|
||||
stream: AsyncIterable<T>
|
||||
}
|
||||
```
|
||||
|
||||
### Streaming Renderer
|
||||
|
||||
```typescript
|
||||
async function renderStream<T>(
|
||||
result: StreamingResult<T>,
|
||||
options: OutputOptions,
|
||||
write: (chunk: string) => void
|
||||
): Promise<void> {
|
||||
const { stream, schema } = result
|
||||
|
||||
// For JSON, output newline-delimited JSON (NDJSON)
|
||||
if (options.format === 'json') {
|
||||
for await (const item of stream) {
|
||||
write(JSON.stringify(item) + '\n')
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// For table format, render each item as a row
|
||||
let headerWritten = false
|
||||
for await (const item of stream) {
|
||||
if (!headerWritten && !options.noHeaders) {
|
||||
write(renderTableHeader(schema) + '\n')
|
||||
headerWritten = true
|
||||
}
|
||||
write(renderTableRow(item, schema, options) + '\n')
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### NDJSON for Streaming
|
||||
|
||||
When `--json` (or `--format json`) is used with streaming commands, output is newline-delimited JSON (NDJSON) for easy parsing:
|
||||
|
||||
```
|
||||
{"timestamp":"2024-01-15T10:30:00Z","type":"stdout","content":"Hello"}
|
||||
{"timestamp":"2024-01-15T10:30:01Z","type":"stdout","content":"World"}
|
||||
```
|
||||
|
||||
This allows consumers to process output line-by-line without buffering the entire stream.
|
||||
|
||||
## Testing
|
||||
|
||||
### Testing Structured Data
|
||||
|
||||
Tests can directly verify the structured data without parsing formatted output:
|
||||
|
||||
```typescript
|
||||
describe('agent list', () => {
|
||||
it('returns agents with correct structure', async () => {
|
||||
const result = await agentListCommand({ host: testHost })
|
||||
|
||||
expect(result.type).toBe('list')
|
||||
expect(result.data).toHaveLength(2)
|
||||
expect(result.data[0]).toMatchObject({
|
||||
id: expect.any(String),
|
||||
title: 'Test Agent',
|
||||
status: 'running',
|
||||
})
|
||||
})
|
||||
|
||||
it('uses correct schema for table output', async () => {
|
||||
const result = await agentListCommand({ host: testHost })
|
||||
|
||||
expect(result.schema.idField).toBe('id')
|
||||
expect(result.schema.columns.map(c => c.header)).toEqual([
|
||||
'ID', 'TITLE', 'STATUS', 'PROVIDER', 'CWD'
|
||||
])
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### Testing Renderers
|
||||
|
||||
Renderer tests verify formatting independently:
|
||||
|
||||
```typescript
|
||||
describe('table renderer', () => {
|
||||
it('formats data as aligned table', () => {
|
||||
const result: ListResult<AgentListItem> = {
|
||||
type: 'list',
|
||||
data: [
|
||||
{ id: 'abc123', title: 'Agent 1', status: 'running', ... },
|
||||
{ id: 'def456', title: 'Agent 2', status: 'idle', ... },
|
||||
],
|
||||
schema: agentListSchema,
|
||||
}
|
||||
|
||||
const output = renderTable(result, { format: 'table', quiet: false, ... })
|
||||
|
||||
expect(output).toContain('ID')
|
||||
expect(output).toContain('abc123')
|
||||
expect(output).toContain('Agent 1')
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### E2E Tests
|
||||
|
||||
E2E tests can verify both structured data (for correctness) and formatted output (for UX):
|
||||
|
||||
```typescript
|
||||
// Verify JSON output is valid and contains expected data
|
||||
test('agent list --json', async () => {
|
||||
const output = await ctx.paseo('agent list --json')
|
||||
const data = JSON.parse(output.stdout)
|
||||
|
||||
expect(data).toBeInstanceOf(Array)
|
||||
expect(data[0]).toHaveProperty('id')
|
||||
})
|
||||
|
||||
// Verify table output looks correct
|
||||
test('agent list shows table headers', async () => {
|
||||
const output = await ctx.paseo('agent list')
|
||||
|
||||
expect(output.stdout).toMatch(/ID\s+TITLE\s+STATUS/)
|
||||
})
|
||||
```
|
||||
|
||||
## Integration with Command Framework
|
||||
|
||||
### Global Options
|
||||
|
||||
Add output options to the root command:
|
||||
|
||||
```typescript
|
||||
program
|
||||
.option('-o, --format <format>', 'Output format: table, json, yaml', 'table')
|
||||
.option('--json', 'Output in JSON format (alias for --format json)')
|
||||
.option('-q, --quiet', 'Minimal output (IDs only)')
|
||||
.option('--no-headers', 'Omit table headers')
|
||||
.option('--no-color', 'Disable colored output')
|
||||
```
|
||||
|
||||
### Command Handler Wrapper
|
||||
|
||||
A wrapper function handles the rendering:
|
||||
|
||||
```typescript
|
||||
function withOutput<T>(
|
||||
handler: (options: CommandOptions) => Promise<AnyCommandResult<T>>
|
||||
) {
|
||||
return async (options: CommandOptions) => {
|
||||
try {
|
||||
const result = await handler(options)
|
||||
const output = render(result, options)
|
||||
process.stdout.write(output + '\n')
|
||||
} catch (error) {
|
||||
const errorOutput = renderError(toCommandError(error), options)
|
||||
process.stderr.write(errorOutput + '\n')
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Usage
|
||||
program
|
||||
.command('list')
|
||||
.description('List agents')
|
||||
.action(withOutput(agentListCommand))
|
||||
```
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
1. **Phase 1: Core Types**
|
||||
- Define `CommandResult`, `OutputSchema`, `ColumnDef` types
|
||||
- Implement basic table renderer
|
||||
- Implement JSON renderer
|
||||
|
||||
2. **Phase 2: Integration**
|
||||
- Add global output options to CLI
|
||||
- Create `withOutput` wrapper
|
||||
- Migrate `daemon status` command as proof of concept
|
||||
|
||||
3. **Phase 3: Full Coverage**
|
||||
- Add YAML renderer
|
||||
- Add quiet renderer
|
||||
- Migrate all existing commands
|
||||
|
||||
4. **Phase 4: Streaming**
|
||||
- Implement `StreamingResult` type
|
||||
- Add streaming renderers
|
||||
- Apply to `logs` and `attach` commands
|
||||
|
||||
## Open Questions
|
||||
|
||||
1. **Should we support Go templates like Docker/gh?** This adds flexibility but also complexity. For v1, predefined formats are likely sufficient.
|
||||
|
||||
2. **How to handle nested data in tables?** Options:
|
||||
- Flatten (e.g., `config.timeout` becomes `TIMEOUT` column)
|
||||
- Skip in table, include in JSON/YAML
|
||||
- Use nested tables for detail views
|
||||
|
||||
3. **Should quiet mode support custom fields?** e.g., `--quiet=title` to output titles instead of IDs.
|
||||
@@ -1,155 +0,0 @@
|
||||
# CLI Type Audit (commands)
|
||||
|
||||
## Scope
|
||||
- Audited `packages/cli/src/commands/**` for inline type/interface definitions.
|
||||
- Checked `@getpaseo/server` exports from `packages/server/src/server/exports.ts`.
|
||||
- Note: `packages/server/src/index.ts` does **not** exist in this repo; the package export entrypoint is `./src/server/exports.ts` per `packages/server/package.json`.
|
||||
|
||||
## Server Exports (current)
|
||||
`packages/server/src/server/exports.ts` exports:
|
||||
- `createPaseoDaemon`, `PaseoDaemon`, `PaseoDaemonConfig`
|
||||
- `loadConfig`, `resolvePaseoHome`
|
||||
- `createRootLogger`, `LogLevel`, `LogFormat`
|
||||
- `loadPersistedConfig`, `PersistedConfig`
|
||||
- `DaemonClient`, `DaemonClientConfig`, `ConnectionState`, `DaemonEvent`
|
||||
|
||||
No agent snapshot/timeline/permission/message types are exported.
|
||||
|
||||
## Findings by File
|
||||
|
||||
### `packages/cli/src/commands/agent/run.ts`
|
||||
Inline types:
|
||||
- `AgentSnapshot` (id/provider/cwd/createdAt/status/title)
|
||||
|
||||
Recommended server type:
|
||||
- `AgentSnapshotPayload` from `packages/server/src/shared/messages.ts` (daemon client returns this shape). **Not exported** from `@getpaseo/server` today.
|
||||
|
||||
Notes:
|
||||
- `AgentRunResult` is CLI output; no server type expected.
|
||||
|
||||
---
|
||||
|
||||
### `packages/cli/src/commands/agent/ps.ts`
|
||||
Inline types:
|
||||
- `AgentSnapshot` (id/provider/cwd/createdAt/status/title/archivedAt?)
|
||||
|
||||
Recommended server type:
|
||||
- `AgentSnapshotPayload` (includes `archivedAt` and full snapshot fields). **Not exported**.
|
||||
|
||||
Notes:
|
||||
- `AgentListItem` is CLI output; no server type expected.
|
||||
|
||||
---
|
||||
|
||||
### `packages/cli/src/commands/agent/send.ts`
|
||||
Inline types:
|
||||
- `AgentSnapshot` (id/provider/cwd/createdAt/status/title)
|
||||
|
||||
Recommended server type:
|
||||
- `AgentSnapshotPayload`. **Not exported**.
|
||||
|
||||
Notes:
|
||||
- `AgentSendResult` is CLI output; no server type expected.
|
||||
|
||||
---
|
||||
|
||||
### `packages/cli/src/commands/agent/inspect.ts`
|
||||
Inline types:
|
||||
- `AgentSnapshotLike` (snapshot fields + `lastUsage`, `capabilities`, `availableModes`, `pendingPermissions`)
|
||||
|
||||
Recommended server types:
|
||||
- `AgentSnapshotPayload` (overall snapshot shape). **Not exported**.
|
||||
- `AgentUsage` for `lastUsage`. **Not exported** (in `packages/server/src/server/agent/agent-sdk-types.ts`).
|
||||
- `AgentCapabilityFlags` for `capabilities`. **Not exported**.
|
||||
- `AgentMode` for `availableModes`. **Not exported**.
|
||||
- `AgentPermissionRequest` for `pendingPermissions`. **Not exported**.
|
||||
|
||||
Notes:
|
||||
- `pendingPermissions` uses `{ id, tool?: string }` but server type is `AgentPermissionRequest` with `{ name, kind, ... }`; current CLI projection is lossy and field names don’t match (`tool` vs `name`).
|
||||
- `AgentInspect` and `InspectRow` are CLI output types.
|
||||
|
||||
---
|
||||
|
||||
### `packages/cli/src/commands/agent/logs.ts`
|
||||
Inline types:
|
||||
- `AgentStreamSnapshotMessage`
|
||||
- `AgentStreamMessage`
|
||||
- Timeline item shape in `formatTimelineItem` and `extractTimelineFrom*` helpers (`{ type: string; ... }`)
|
||||
|
||||
Recommended server types:
|
||||
- `AgentStreamSnapshotMessage` from `packages/server/src/shared/messages.ts`. **Not exported**.
|
||||
- `AgentStreamMessage` from `packages/server/src/shared/messages.ts`. **Not exported**.
|
||||
- `AgentStreamEventPayload` from `packages/server/src/shared/messages.ts` (for `event` typing). **Not exported**.
|
||||
- `AgentTimelineItem` from `packages/server/src/server/agent/agent-sdk-types.ts` (for timeline item shape). **Not exported**.
|
||||
|
||||
Notes:
|
||||
- These are WebSocket message types; they should come from shared message definitions to avoid drift.
|
||||
- `LogEntry` is CLI output.
|
||||
|
||||
---
|
||||
|
||||
### `packages/cli/src/commands/agent/mode.ts`
|
||||
Inline types:
|
||||
- `ModeListItem` (id/label/description)
|
||||
- `SetModeResult` (agentId/mode)
|
||||
|
||||
Recommended server type:
|
||||
- `ModeListItem` duplicates the shape of `AgentMode` (id/label/description) from `packages/server/src/server/agent/agent-sdk-types.ts`. **Not exported**.
|
||||
|
||||
Notes:
|
||||
- `SetModeResult` is CLI output.
|
||||
|
||||
---
|
||||
|
||||
### `packages/cli/src/commands/daemon/start.ts`
|
||||
Inline types:
|
||||
- `StartOptions` (CLI flags)
|
||||
|
||||
Server type usage:
|
||||
- CLI-only; no server type expected.
|
||||
|
||||
---
|
||||
|
||||
### `packages/cli/src/commands/daemon/status.ts`
|
||||
Inline types:
|
||||
- `DaemonStatus`
|
||||
- `StatusRow`
|
||||
|
||||
Server type usage:
|
||||
- CLI-only; no server type expected.
|
||||
|
||||
---
|
||||
|
||||
### `packages/cli/src/commands/daemon/restart.ts`
|
||||
Inline types:
|
||||
- `RestartResult`
|
||||
|
||||
Server type usage:
|
||||
- CLI-only; no server type expected.
|
||||
|
||||
---
|
||||
|
||||
### `packages/cli/src/commands/daemon/stop.ts`
|
||||
Inline types:
|
||||
- `StopResult`
|
||||
|
||||
Server type usage:
|
||||
- CLI-only; no server type expected.
|
||||
|
||||
## Gaps in `@getpaseo/server` Exports (needed for CLI cleanup)
|
||||
To replace inline types in CLI commands, `@getpaseo/server` would need to export (directly or re-export):
|
||||
- From `packages/server/src/shared/messages.ts`:
|
||||
- `AgentSnapshotPayload`
|
||||
- `AgentStreamEventPayload`
|
||||
- `AgentStreamMessage`
|
||||
- `AgentStreamSnapshotMessage`
|
||||
- (optionally) `AgentStateMessage`, `SessionStateMessage`, `SessionOutboundMessage` if CLI starts typing daemon event queues more strictly
|
||||
- From `packages/server/src/server/agent/agent-sdk-types.ts`:
|
||||
- `AgentMode`
|
||||
- `AgentUsage`
|
||||
- `AgentCapabilityFlags`
|
||||
- `AgentPermissionRequest`
|
||||
- `AgentTimelineItem`
|
||||
|
||||
## Summary
|
||||
Primary inline types that should become server imports are the agent snapshot/timeline/message/permission/mode shapes in `agent/*` commands. All are defined in server shared or agent SDK types today but are not exported through `@getpaseo/server`.
|
||||
Reference in New Issue
Block a user