@otto-code/cli 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/otto +3 -0
- package/dist/classify.d.ts +19 -0
- package/dist/classify.js +49 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +113 -0
- package/dist/commands/agent/archive.d.ts +18 -0
- package/dist/commands/agent/archive.js +102 -0
- package/dist/commands/agent/attach.d.ts +11 -0
- package/dist/commands/agent/attach.js +159 -0
- package/dist/commands/agent/delete.d.ts +15 -0
- package/dist/commands/agent/delete.js +107 -0
- package/dist/commands/agent/import.d.ts +14 -0
- package/dist/commands/agent/import.js +122 -0
- package/dist/commands/agent/index.d.ts +3 -0
- package/dist/commands/agent/index.js +48 -0
- package/dist/commands/agent/inspect.d.ts +15 -0
- package/dist/commands/agent/inspect.js +209 -0
- package/dist/commands/agent/logs.d.ts +19 -0
- package/dist/commands/agent/logs.js +180 -0
- package/dist/commands/agent/ls.d.ts +44 -0
- package/dist/commands/agent/ls.js +204 -0
- package/dist/commands/agent/mode.d.ts +18 -0
- package/dist/commands/agent/mode.js +100 -0
- package/dist/commands/agent/reload.d.ts +15 -0
- package/dist/commands/agent/reload.js +75 -0
- package/dist/commands/agent/run.d.ts +44 -0
- package/dist/commands/agent/run.js +464 -0
- package/dist/commands/agent/send.d.ts +19 -0
- package/dist/commands/agent/send.js +187 -0
- package/dist/commands/agent/stop.d.ts +17 -0
- package/dist/commands/agent/stop.js +115 -0
- package/dist/commands/agent/update.d.ts +18 -0
- package/dist/commands/agent/update.js +139 -0
- package/dist/commands/agent/wait.d.ts +17 -0
- package/dist/commands/agent/wait.js +158 -0
- package/dist/commands/chat/create.d.ts +9 -0
- package/dist/commands/chat/create.js +23 -0
- package/dist/commands/chat/delete.d.ts +6 -0
- package/dist/commands/chat/delete.js +20 -0
- package/dist/commands/chat/index.d.ts +3 -0
- package/dist/commands/chat/index.js +47 -0
- package/dist/commands/chat/inspect.d.ts +6 -0
- package/dist/commands/chat/inspect.js +20 -0
- package/dist/commands/chat/ls.d.ts +6 -0
- package/dist/commands/chat/ls.js +20 -0
- package/dist/commands/chat/post.d.ts +9 -0
- package/dist/commands/chat/post.js +28 -0
- package/dist/commands/chat/read.d.ts +11 -0
- package/dist/commands/chat/read.js +40 -0
- package/dist/commands/chat/schema.d.ts +36 -0
- package/dist/commands/chat/schema.js +81 -0
- package/dist/commands/chat/shared.d.ts +19 -0
- package/dist/commands/chat/shared.js +118 -0
- package/dist/commands/chat/wait.d.ts +9 -0
- package/dist/commands/chat/wait.js +45 -0
- package/dist/commands/daemon/index.d.ts +3 -0
- package/dist/commands/daemon/index.js +57 -0
- package/dist/commands/daemon/local-daemon.d.ts +78 -0
- package/dist/commands/daemon/local-daemon.js +544 -0
- package/dist/commands/daemon/pair.d.ts +9 -0
- package/dist/commands/daemon/pair.js +76 -0
- package/dist/commands/daemon/restart.d.ts +12 -0
- package/dist/commands/daemon/restart.js +99 -0
- package/dist/commands/daemon/runtime-toolchain.d.ts +6 -0
- package/dist/commands/daemon/runtime-toolchain.js +87 -0
- package/dist/commands/daemon/set-password.d.ts +17 -0
- package/dist/commands/daemon/set-password.js +82 -0
- package/dist/commands/daemon/start.d.ts +6 -0
- package/dist/commands/daemon/start.js +56 -0
- package/dist/commands/daemon/status.d.ts +10 -0
- package/dist/commands/daemon/status.js +338 -0
- package/dist/commands/daemon/stop.d.ts +15 -0
- package/dist/commands/daemon/stop.js +60 -0
- package/dist/commands/hooks.d.ts +19 -0
- package/dist/commands/hooks.js +89 -0
- package/dist/commands/loop/index.d.ts +3 -0
- package/dist/commands/loop/index.js +18 -0
- package/dist/commands/loop/inspect.d.ts +13 -0
- package/dist/commands/loop/inspect.js +100 -0
- package/dist/commands/loop/logs.d.ts +8 -0
- package/dist/commands/loop/logs.js +69 -0
- package/dist/commands/loop/ls.d.ts +18 -0
- package/dist/commands/loop/ls.js +62 -0
- package/dist/commands/loop/run.d.ts +30 -0
- package/dist/commands/loop/run.js +162 -0
- package/dist/commands/loop/stop.d.ts +15 -0
- package/dist/commands/loop/stop.js +56 -0
- package/dist/commands/loop/types.d.ts +138 -0
- package/dist/commands/loop/types.js +2 -0
- package/dist/commands/onboard.d.ts +10 -0
- package/dist/commands/onboard.js +416 -0
- package/dist/commands/open.d.ts +2 -0
- package/dist/commands/open.js +81 -0
- package/dist/commands/permit/allow.d.ts +20 -0
- package/dist/commands/permit/allow.js +133 -0
- package/dist/commands/permit/deny.d.ts +12 -0
- package/dist/commands/permit/deny.js +105 -0
- package/dist/commands/permit/index.d.ts +3 -0
- package/dist/commands/permit/index.js +27 -0
- package/dist/commands/permit/ls.d.ts +18 -0
- package/dist/commands/permit/ls.js +66 -0
- package/dist/commands/provider/index.d.ts +3 -0
- package/dist/commands/provider/index.js +16 -0
- package/dist/commands/provider/ls.d.ts +19 -0
- package/dist/commands/provider/ls.js +73 -0
- package/dist/commands/provider/models.d.ts +20 -0
- package/dist/commands/provider/models.js +53 -0
- package/dist/commands/schedule/create.d.ts +18 -0
- package/dist/commands/schedule/create.js +40 -0
- package/dist/commands/schedule/delete.d.ts +10 -0
- package/dist/commands/schedule/delete.js +32 -0
- package/dist/commands/schedule/index.d.ts +3 -0
- package/dist/commands/schedule/index.js +66 -0
- package/dist/commands/schedule/inspect.d.ts +6 -0
- package/dist/commands/schedule/inspect.js +24 -0
- package/dist/commands/schedule/logs.d.ts +6 -0
- package/dist/commands/schedule/logs.js +23 -0
- package/dist/commands/schedule/ls.d.ts +5 -0
- package/dist/commands/schedule/ls.js +23 -0
- package/dist/commands/schedule/pause.d.ts +5 -0
- package/dist/commands/schedule/pause.js +23 -0
- package/dist/commands/schedule/resume.d.ts +5 -0
- package/dist/commands/schedule/resume.js +23 -0
- package/dist/commands/schedule/run-once.d.ts +5 -0
- package/dist/commands/schedule/run-once.js +23 -0
- package/dist/commands/schedule/schema.d.ts +21 -0
- package/dist/commands/schedule/schema.js +67 -0
- package/dist/commands/schedule/shared.d.ts +56 -0
- package/dist/commands/schedule/shared.js +346 -0
- package/dist/commands/schedule/types.d.ts +168 -0
- package/dist/commands/schedule/types.js +2 -0
- package/dist/commands/schedule/update.d.ts +21 -0
- package/dist/commands/schedule/update.js +39 -0
- package/dist/commands/speech/index.d.ts +3 -0
- package/dist/commands/speech/index.js +5 -0
- package/dist/commands/terminal/capture.d.ts +10 -0
- package/dist/commands/terminal/capture.js +68 -0
- package/dist/commands/terminal/create.d.ts +10 -0
- package/dist/commands/terminal/create.js +38 -0
- package/dist/commands/terminal/index.d.ts +3 -0
- package/dist/commands/terminal/index.js +43 -0
- package/dist/commands/terminal/kill.d.ts +6 -0
- package/dist/commands/terminal/kill.js +36 -0
- package/dist/commands/terminal/ls.d.ts +10 -0
- package/dist/commands/terminal/ls.js +21 -0
- package/dist/commands/terminal/schema.d.ts +18 -0
- package/dist/commands/terminal/schema.js +23 -0
- package/dist/commands/terminal/send-keys.d.ts +7 -0
- package/dist/commands/terminal/send-keys.js +76 -0
- package/dist/commands/terminal/shared.d.ts +12 -0
- package/dist/commands/terminal/shared.js +61 -0
- package/dist/commands/worktree/archive.d.ts +20 -0
- package/dist/commands/worktree/archive.js +104 -0
- package/dist/commands/worktree/create-input.d.ts +15 -0
- package/dist/commands/worktree/create-input.js +56 -0
- package/dist/commands/worktree/create.d.ts +11 -0
- package/dist/commands/worktree/create.js +58 -0
- package/dist/commands/worktree/index.d.ts +3 -0
- package/dist/commands/worktree/index.js +25 -0
- package/dist/commands/worktree/ls.d.ts +19 -0
- package/dist/commands/worktree/ls.js +97 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +6 -0
- package/dist/output/index.d.ts +45 -0
- package/dist/output/index.js +47 -0
- package/dist/output/json.d.ts +11 -0
- package/dist/output/json.js +37 -0
- package/dist/output/quiet.d.ts +9 -0
- package/dist/output/quiet.js +22 -0
- package/dist/output/render.d.ts +15 -0
- package/dist/output/render.js +83 -0
- package/dist/output/table.d.ts +13 -0
- package/dist/output/table.js +135 -0
- package/dist/output/types.d.ts +73 -0
- package/dist/output/types.js +8 -0
- package/dist/output/with-output.d.ts +41 -0
- package/dist/output/with-output.js +87 -0
- package/dist/output/yaml.d.ts +11 -0
- package/dist/output/yaml.js +38 -0
- package/dist/run.d.ts +14 -0
- package/dist/run.js +33 -0
- package/dist/utils/client-id.d.ts +2 -0
- package/dist/utils/client-id.js +37 -0
- package/dist/utils/client.d.ts +44 -0
- package/dist/utils/client.js +330 -0
- package/dist/utils/command-options.d.ts +6 -0
- package/dist/utils/command-options.js +17 -0
- package/dist/utils/duration.d.ts +7 -0
- package/dist/utils/duration.js +38 -0
- package/dist/utils/errors.d.ts +5 -0
- package/dist/utils/errors.js +10 -0
- package/dist/utils/paths.d.ts +12 -0
- package/dist/utils/paths.js +22 -0
- package/dist/utils/provider-model.d.ts +11 -0
- package/dist/utils/provider-model.js +49 -0
- package/dist/utils/timeline.d.ts +11 -0
- package/dist/utils/timeline.js +11 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +10 -0
- package/package.json +48 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
export type ScheduleStatus = "active" | "paused" | "completed";
|
|
2
|
+
export type ScheduleCadence = {
|
|
3
|
+
type: "every";
|
|
4
|
+
everyMs: number;
|
|
5
|
+
} | {
|
|
6
|
+
type: "cron";
|
|
7
|
+
expression: string;
|
|
8
|
+
timezone?: string;
|
|
9
|
+
};
|
|
10
|
+
export type ScheduleTarget = {
|
|
11
|
+
type: "self";
|
|
12
|
+
agentId: string;
|
|
13
|
+
} | {
|
|
14
|
+
type: "agent";
|
|
15
|
+
agentId: string;
|
|
16
|
+
} | {
|
|
17
|
+
type: "new-agent";
|
|
18
|
+
config: {
|
|
19
|
+
provider: string;
|
|
20
|
+
cwd: string;
|
|
21
|
+
modeId?: string;
|
|
22
|
+
model?: string;
|
|
23
|
+
thinkingOptionId?: string;
|
|
24
|
+
title?: string | null;
|
|
25
|
+
approvalPolicy?: string;
|
|
26
|
+
sandboxMode?: string;
|
|
27
|
+
networkAccess?: boolean;
|
|
28
|
+
webSearch?: boolean;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export interface ScheduleRunRecord {
|
|
32
|
+
id: string;
|
|
33
|
+
scheduledFor: string;
|
|
34
|
+
startedAt: string;
|
|
35
|
+
endedAt: string | null;
|
|
36
|
+
status: "running" | "succeeded" | "failed";
|
|
37
|
+
agentId: string | null;
|
|
38
|
+
output: string | null;
|
|
39
|
+
error: string | null;
|
|
40
|
+
}
|
|
41
|
+
export interface ScheduleRecord {
|
|
42
|
+
id: string;
|
|
43
|
+
name: string | null;
|
|
44
|
+
prompt: string;
|
|
45
|
+
cadence: ScheduleCadence;
|
|
46
|
+
target: Exclude<ScheduleTarget, {
|
|
47
|
+
type: "self";
|
|
48
|
+
}>;
|
|
49
|
+
status: ScheduleStatus;
|
|
50
|
+
createdAt: string;
|
|
51
|
+
updatedAt: string;
|
|
52
|
+
nextRunAt: string | null;
|
|
53
|
+
lastRunAt: string | null;
|
|
54
|
+
pausedAt: string | null;
|
|
55
|
+
expiresAt: string | null;
|
|
56
|
+
maxRuns: number | null;
|
|
57
|
+
runs: ScheduleRunRecord[];
|
|
58
|
+
}
|
|
59
|
+
export interface ScheduleListItem {
|
|
60
|
+
id: string;
|
|
61
|
+
name: string | null;
|
|
62
|
+
cadence: ScheduleCadence;
|
|
63
|
+
target: Exclude<ScheduleTarget, {
|
|
64
|
+
type: "self";
|
|
65
|
+
}>;
|
|
66
|
+
status: ScheduleStatus;
|
|
67
|
+
nextRunAt: string | null;
|
|
68
|
+
lastRunAt: string | null;
|
|
69
|
+
createdAt: string;
|
|
70
|
+
updatedAt: string;
|
|
71
|
+
pausedAt: string | null;
|
|
72
|
+
expiresAt: string | null;
|
|
73
|
+
maxRuns: number | null;
|
|
74
|
+
}
|
|
75
|
+
export interface CreateScheduleInput {
|
|
76
|
+
prompt: string;
|
|
77
|
+
name?: string;
|
|
78
|
+
cadence: ScheduleCadence;
|
|
79
|
+
target: ScheduleTarget;
|
|
80
|
+
maxRuns?: number;
|
|
81
|
+
expiresAt?: string;
|
|
82
|
+
runOnCreate?: boolean;
|
|
83
|
+
}
|
|
84
|
+
export interface ScheduleCreatePayload {
|
|
85
|
+
requestId: string;
|
|
86
|
+
schedule: ScheduleListItem | null;
|
|
87
|
+
error: string | null;
|
|
88
|
+
}
|
|
89
|
+
export interface ScheduleListPayload {
|
|
90
|
+
requestId: string;
|
|
91
|
+
schedules: ScheduleListItem[];
|
|
92
|
+
error: string | null;
|
|
93
|
+
}
|
|
94
|
+
export interface ScheduleInspectPayload {
|
|
95
|
+
requestId: string;
|
|
96
|
+
schedule: ScheduleRecord | null;
|
|
97
|
+
error: string | null;
|
|
98
|
+
}
|
|
99
|
+
export interface ScheduleLogsPayload {
|
|
100
|
+
requestId: string;
|
|
101
|
+
runs: ScheduleRunRecord[];
|
|
102
|
+
error: string | null;
|
|
103
|
+
}
|
|
104
|
+
export interface SchedulePausePayload {
|
|
105
|
+
requestId: string;
|
|
106
|
+
schedule: ScheduleListItem | null;
|
|
107
|
+
error: string | null;
|
|
108
|
+
}
|
|
109
|
+
export interface ScheduleResumePayload {
|
|
110
|
+
requestId: string;
|
|
111
|
+
schedule: ScheduleListItem | null;
|
|
112
|
+
error: string | null;
|
|
113
|
+
}
|
|
114
|
+
export interface ScheduleDeletePayload {
|
|
115
|
+
requestId: string;
|
|
116
|
+
scheduleId: string;
|
|
117
|
+
error: string | null;
|
|
118
|
+
}
|
|
119
|
+
export interface ScheduleRunOncePayload {
|
|
120
|
+
requestId: string;
|
|
121
|
+
schedule: ScheduleRecord | null;
|
|
122
|
+
error: string | null;
|
|
123
|
+
}
|
|
124
|
+
export interface UpdateScheduleNewAgentConfig {
|
|
125
|
+
provider?: string;
|
|
126
|
+
model?: string | null;
|
|
127
|
+
modeId?: string | null;
|
|
128
|
+
cwd?: string;
|
|
129
|
+
}
|
|
130
|
+
export interface UpdateScheduleInput {
|
|
131
|
+
id: string;
|
|
132
|
+
name?: string | null;
|
|
133
|
+
prompt?: string;
|
|
134
|
+
cadence?: ScheduleCadence;
|
|
135
|
+
newAgentConfig?: UpdateScheduleNewAgentConfig;
|
|
136
|
+
maxRuns?: number | null;
|
|
137
|
+
expiresAt?: string | null;
|
|
138
|
+
}
|
|
139
|
+
export interface ScheduleUpdatePayload {
|
|
140
|
+
requestId: string;
|
|
141
|
+
schedule: ScheduleRecord | null;
|
|
142
|
+
error: string | null;
|
|
143
|
+
}
|
|
144
|
+
export interface ScheduleDaemonClient {
|
|
145
|
+
scheduleCreate(input: CreateScheduleInput): Promise<ScheduleCreatePayload>;
|
|
146
|
+
scheduleList(): Promise<ScheduleListPayload>;
|
|
147
|
+
scheduleInspect(input: {
|
|
148
|
+
id: string;
|
|
149
|
+
}): Promise<ScheduleInspectPayload>;
|
|
150
|
+
scheduleLogs(input: {
|
|
151
|
+
id: string;
|
|
152
|
+
}): Promise<ScheduleLogsPayload>;
|
|
153
|
+
schedulePause(input: {
|
|
154
|
+
id: string;
|
|
155
|
+
}): Promise<SchedulePausePayload>;
|
|
156
|
+
scheduleResume(input: {
|
|
157
|
+
id: string;
|
|
158
|
+
}): Promise<ScheduleResumePayload>;
|
|
159
|
+
scheduleDelete(input: {
|
|
160
|
+
id: string;
|
|
161
|
+
}): Promise<ScheduleDeletePayload>;
|
|
162
|
+
scheduleRunOnce(input: {
|
|
163
|
+
id: string;
|
|
164
|
+
}): Promise<ScheduleRunOncePayload>;
|
|
165
|
+
scheduleUpdate(input: UpdateScheduleInput): Promise<ScheduleUpdatePayload>;
|
|
166
|
+
close(): Promise<void>;
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { ListResult } from "../../output/index.js";
|
|
3
|
+
import { type ScheduleInspectRow } from "./schema.js";
|
|
4
|
+
import { type ScheduleCommandOptions } from "./shared.js";
|
|
5
|
+
export interface ScheduleUpdateOptions extends ScheduleCommandOptions {
|
|
6
|
+
every?: string;
|
|
7
|
+
cron?: string;
|
|
8
|
+
timezone?: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
prompt?: string;
|
|
11
|
+
provider?: string;
|
|
12
|
+
model?: string;
|
|
13
|
+
mode?: string;
|
|
14
|
+
cwd?: string;
|
|
15
|
+
maxRuns?: string;
|
|
16
|
+
noMaxRuns?: boolean;
|
|
17
|
+
expiresIn?: string;
|
|
18
|
+
noExpiresIn?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare function runUpdateCommand(id: string, options: ScheduleUpdateOptions, _command: Command): Promise<ListResult<ScheduleInspectRow>>;
|
|
21
|
+
//# sourceMappingURL=update.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createScheduleInspectRows, createScheduleInspectSchema, } from "./schema.js";
|
|
2
|
+
import { connectScheduleClient, parseScheduleUpdateInput, toScheduleCommandError, } from "./shared.js";
|
|
3
|
+
export async function runUpdateCommand(id, options, _command) {
|
|
4
|
+
const input = parseScheduleUpdateInput({
|
|
5
|
+
id,
|
|
6
|
+
every: options.every,
|
|
7
|
+
cron: options.cron,
|
|
8
|
+
timezone: options.timezone,
|
|
9
|
+
name: options.name,
|
|
10
|
+
prompt: options.prompt,
|
|
11
|
+
provider: options.provider,
|
|
12
|
+
model: options.model,
|
|
13
|
+
mode: options.mode,
|
|
14
|
+
cwd: options.cwd,
|
|
15
|
+
maxRuns: options.maxRuns,
|
|
16
|
+
expiresIn: options.expiresIn,
|
|
17
|
+
clearMaxRuns: options.noMaxRuns,
|
|
18
|
+
clearExpires: options.noExpiresIn,
|
|
19
|
+
});
|
|
20
|
+
const { client } = await connectScheduleClient(options.host);
|
|
21
|
+
try {
|
|
22
|
+
const payload = await client.scheduleUpdate(input);
|
|
23
|
+
if (payload.error || !payload.schedule) {
|
|
24
|
+
throw new Error(payload.error ?? `Failed to update schedule: ${id}`);
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
type: "list",
|
|
28
|
+
data: createScheduleInspectRows(payload.schedule),
|
|
29
|
+
schema: createScheduleInspectSchema(payload.schedule),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
throw toScheduleCommandError("SCHEDULE_UPDATE_FAILED", "update schedule", error);
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
await client.close().catch(() => { });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import { type TerminalCommandOptions } from "./shared.js";
|
|
3
|
+
export interface TerminalCaptureOptions extends TerminalCommandOptions {
|
|
4
|
+
start?: string;
|
|
5
|
+
end?: string;
|
|
6
|
+
scrollback?: boolean;
|
|
7
|
+
ansi?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function runCaptureCommand(terminalId: string, _options: TerminalCaptureOptions, command: Command): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=capture.d.ts.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { renderError, toCommandError } from "../../output/render.js";
|
|
2
|
+
import { connectTerminalClient, resolveTerminalId, toTerminalCommandError, } from "./shared.js";
|
|
3
|
+
export async function runCaptureCommand(terminalId, _options, command) {
|
|
4
|
+
const options = command.optsWithGlobals();
|
|
5
|
+
try {
|
|
6
|
+
const payload = await executeCaptureCommand(terminalId, options);
|
|
7
|
+
if (options.json) {
|
|
8
|
+
process.stdout.write(JSON.stringify({
|
|
9
|
+
terminalId: payload.terminalId,
|
|
10
|
+
lines: payload.lines,
|
|
11
|
+
totalLines: payload.totalLines,
|
|
12
|
+
}, null, 2) + "\n");
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (payload.lines.length > 0) {
|
|
16
|
+
process.stdout.write(payload.lines.join("\n") + "\n");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
const output = renderError(toCommandError(err), {
|
|
21
|
+
format: options.json ? "json" : "table",
|
|
22
|
+
noColor: options.color === false,
|
|
23
|
+
});
|
|
24
|
+
process.stderr.write(output + "\n");
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async function executeCaptureCommand(terminalId, options) {
|
|
29
|
+
const { client } = await connectTerminalClient(options.host);
|
|
30
|
+
try {
|
|
31
|
+
const resolvedId = await resolveTerminalId(client, terminalId);
|
|
32
|
+
if (!resolvedId) {
|
|
33
|
+
throw {
|
|
34
|
+
code: "TERMINAL_NOT_FOUND",
|
|
35
|
+
message: `No terminal found matching: ${terminalId}`,
|
|
36
|
+
details: "Use `otto terminal ls --all` to list available terminals.",
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const start = options.scrollback ? 0 : parseLineNumber("--start", options.start);
|
|
40
|
+
const end = parseLineNumber("--end", options.end);
|
|
41
|
+
return await client.captureTerminal(resolvedId, {
|
|
42
|
+
...(start === undefined ? {} : { start }),
|
|
43
|
+
...(end === undefined ? {} : { end }),
|
|
44
|
+
stripAnsi: !options.ansi,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
throw toTerminalCommandError("TERMINAL_CAPTURE_FAILED", "capture terminal output", err);
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
await client.close().catch(() => { });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function parseLineNumber(flag, value) {
|
|
55
|
+
if (value === undefined) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
const parsed = Number.parseInt(value, 10);
|
|
59
|
+
if (!Number.isInteger(parsed)) {
|
|
60
|
+
throw {
|
|
61
|
+
code: "INVALID_LINE_NUMBER",
|
|
62
|
+
message: `Invalid ${flag} value: ${value}`,
|
|
63
|
+
details: "Use an integer line number.",
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
return parsed;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=capture.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { SingleResult } from "../../output/index.js";
|
|
3
|
+
import { type TerminalCommandOptions } from "./shared.js";
|
|
4
|
+
import { type TerminalRow } from "./schema.js";
|
|
5
|
+
export interface TerminalCreateOptions extends TerminalCommandOptions {
|
|
6
|
+
cwd?: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function runCreateCommand(options: TerminalCreateOptions, _command: Command): Promise<SingleResult<TerminalRow>>;
|
|
10
|
+
//# sourceMappingURL=create.d.ts.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { connectTerminalClient, toTerminalCommandError, } from "./shared.js";
|
|
2
|
+
import { terminalSchema, toTerminalRow } from "./schema.js";
|
|
3
|
+
export async function runCreateCommand(options, _command) {
|
|
4
|
+
const { client } = await connectTerminalClient(options.host);
|
|
5
|
+
const cwd = options.cwd ?? process.cwd();
|
|
6
|
+
try {
|
|
7
|
+
const opened = await client.openProject(cwd);
|
|
8
|
+
if (!opened.workspace) {
|
|
9
|
+
const error = {
|
|
10
|
+
code: "WORKSPACE_OPEN_FAILED",
|
|
11
|
+
message: opened.error ?? "Failed to open workspace",
|
|
12
|
+
};
|
|
13
|
+
throw error;
|
|
14
|
+
}
|
|
15
|
+
const payload = await client.createTerminal(cwd, options.name, undefined, {
|
|
16
|
+
workspaceId: opened.workspace.id,
|
|
17
|
+
});
|
|
18
|
+
if (!payload.terminal) {
|
|
19
|
+
const error = {
|
|
20
|
+
code: "TERMINAL_CREATE_FAILED",
|
|
21
|
+
message: payload.error ?? "Failed to create terminal",
|
|
22
|
+
};
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
type: "single",
|
|
27
|
+
data: toTerminalRow(payload.terminal),
|
|
28
|
+
schema: terminalSchema,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
throw toTerminalCommandError("TERMINAL_CREATE_FAILED", "create terminal", err);
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
await client.close().catch(() => { });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { withOutput } from "../../output/index.js";
|
|
3
|
+
import { addDaemonHostOption, addJsonAndDaemonHostOptions } from "../../utils/command-options.js";
|
|
4
|
+
import { runCaptureCommand } from "./capture.js";
|
|
5
|
+
import { runCreateCommand } from "./create.js";
|
|
6
|
+
import { runKillCommand } from "./kill.js";
|
|
7
|
+
import { runLsCommand } from "./ls.js";
|
|
8
|
+
import { runSendKeysCommand } from "./send-keys.js";
|
|
9
|
+
export function createTerminalCommand() {
|
|
10
|
+
const terminal = new Command("terminal").description("Manage workspace terminals");
|
|
11
|
+
addJsonAndDaemonHostOptions(terminal
|
|
12
|
+
.command("ls")
|
|
13
|
+
.description("List terminals")
|
|
14
|
+
.option("--all", "List terminals across all workspaces")
|
|
15
|
+
.option("--cwd <path>", "Workspace directory")).action(withOutput(runLsCommand));
|
|
16
|
+
addJsonAndDaemonHostOptions(terminal
|
|
17
|
+
.command("create")
|
|
18
|
+
.description("Create a terminal")
|
|
19
|
+
.option("--cwd <path>", "Workspace directory")
|
|
20
|
+
.option("--name <name>", "Terminal name")).action(withOutput(runCreateCommand));
|
|
21
|
+
addJsonAndDaemonHostOptions(terminal
|
|
22
|
+
.command("kill")
|
|
23
|
+
.description("Kill a terminal")
|
|
24
|
+
.argument("<terminal-id>", "Terminal ID, ID prefix, or name")).action(withOutput(runKillCommand));
|
|
25
|
+
addDaemonHostOption(terminal
|
|
26
|
+
.command("capture")
|
|
27
|
+
.description("Capture terminal output")
|
|
28
|
+
.argument("<terminal-id>", "Terminal ID, ID prefix, or name")
|
|
29
|
+
.option("--start <n>", "Capture start line")
|
|
30
|
+
.option("--end <n>", "Capture end line")
|
|
31
|
+
.option("-S, --scrollback", "Capture from the beginning of scrollback")
|
|
32
|
+
.option("--ansi", "Preserve ANSI escape codes")
|
|
33
|
+
.option("--json", "Output in JSON format")).action(runCaptureCommand);
|
|
34
|
+
addDaemonHostOption(terminal
|
|
35
|
+
.command("send-keys")
|
|
36
|
+
.description("Send keys to a terminal")
|
|
37
|
+
.argument("<terminal-id>", "Terminal ID, ID prefix, or name")
|
|
38
|
+
.argument("<keys...>", "Keys to send")
|
|
39
|
+
.option("-l, --literal", "Send raw keys without interpreting special tokens")
|
|
40
|
+
.option("--json", "Output in JSON format")).action(runSendKeysCommand);
|
|
41
|
+
return terminal;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { SingleResult } from "../../output/index.js";
|
|
3
|
+
import { type TerminalCommandOptions } from "./shared.js";
|
|
4
|
+
import { type TerminalKillRow } from "./schema.js";
|
|
5
|
+
export declare function runKillCommand(terminalId: string, options: TerminalCommandOptions, _command: Command): Promise<SingleResult<TerminalKillRow>>;
|
|
6
|
+
//# sourceMappingURL=kill.d.ts.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { connectTerminalClient, resolveTerminalId, toTerminalCommandError, } from "./shared.js";
|
|
2
|
+
import { terminalKillSchema } from "./schema.js";
|
|
3
|
+
export async function runKillCommand(terminalId, options, _command) {
|
|
4
|
+
const { client } = await connectTerminalClient(options.host);
|
|
5
|
+
try {
|
|
6
|
+
const resolvedId = await requireTerminalId(client, terminalId);
|
|
7
|
+
const payload = await client.killTerminal(resolvedId);
|
|
8
|
+
return {
|
|
9
|
+
type: "single",
|
|
10
|
+
data: {
|
|
11
|
+
terminalId: payload.terminalId,
|
|
12
|
+
success: payload.success,
|
|
13
|
+
},
|
|
14
|
+
schema: terminalKillSchema,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
throw toTerminalCommandError("TERMINAL_KILL_FAILED", "kill terminal", err);
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
await client.close().catch(() => { });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async function requireTerminalId(client, terminalId) {
|
|
25
|
+
const resolvedId = await resolveTerminalId(client, terminalId);
|
|
26
|
+
if (resolvedId) {
|
|
27
|
+
return resolvedId;
|
|
28
|
+
}
|
|
29
|
+
const error = {
|
|
30
|
+
code: "TERMINAL_NOT_FOUND",
|
|
31
|
+
message: `No terminal found matching: ${terminalId}`,
|
|
32
|
+
details: "Use `otto terminal ls --all` to list available terminals.",
|
|
33
|
+
};
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=kill.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { ListResult } from "../../output/index.js";
|
|
3
|
+
import { type TerminalCommandOptions } from "./shared.js";
|
|
4
|
+
import { type TerminalRow } from "./schema.js";
|
|
5
|
+
export interface TerminalLsOptions extends TerminalCommandOptions {
|
|
6
|
+
all?: boolean;
|
|
7
|
+
cwd?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function runLsCommand(options: TerminalLsOptions, _command: Command): Promise<ListResult<TerminalRow>>;
|
|
10
|
+
//# sourceMappingURL=ls.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { connectTerminalClient, toTerminalCommandError, } from "./shared.js";
|
|
2
|
+
import { terminalSchema, toTerminalRow } from "./schema.js";
|
|
3
|
+
export async function runLsCommand(options, _command) {
|
|
4
|
+
const { client } = await connectTerminalClient(options.host);
|
|
5
|
+
const cwd = options.all ? undefined : (options.cwd ?? process.cwd());
|
|
6
|
+
try {
|
|
7
|
+
const payload = cwd === undefined ? await client.listTerminals() : await client.listTerminals(cwd);
|
|
8
|
+
return {
|
|
9
|
+
type: "list",
|
|
10
|
+
data: payload.terminals.map((terminal) => toTerminalRow(terminal, payload.cwd ?? cwd)),
|
|
11
|
+
schema: terminalSchema,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
throw toTerminalCommandError("TERMINAL_LIST_FAILED", "list terminals", err);
|
|
16
|
+
}
|
|
17
|
+
finally {
|
|
18
|
+
await client.close().catch(() => { });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=ls.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { OutputSchema } from "../../output/index.js";
|
|
2
|
+
export interface TerminalRow {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
cwd: string;
|
|
6
|
+
}
|
|
7
|
+
export interface TerminalKillRow {
|
|
8
|
+
terminalId: string;
|
|
9
|
+
success: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const terminalSchema: OutputSchema<TerminalRow>;
|
|
12
|
+
export declare const terminalKillSchema: OutputSchema<TerminalKillRow>;
|
|
13
|
+
export declare function toTerminalRow(terminal: {
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
cwd?: string;
|
|
17
|
+
}, cwd?: string): TerminalRow;
|
|
18
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const terminalSchema = {
|
|
2
|
+
idField: "id",
|
|
3
|
+
columns: [
|
|
4
|
+
{ header: "ID", field: (row) => row.id.slice(0, 8), width: 8 },
|
|
5
|
+
{ header: "NAME", field: "name", width: 24 },
|
|
6
|
+
{ header: "CWD", field: "cwd", width: 48 },
|
|
7
|
+
],
|
|
8
|
+
};
|
|
9
|
+
export const terminalKillSchema = {
|
|
10
|
+
idField: "terminalId",
|
|
11
|
+
columns: [
|
|
12
|
+
{ header: "ID", field: (row) => row.terminalId.slice(0, 8), width: 8 },
|
|
13
|
+
{ header: "SUCCESS", field: "success", width: 8 },
|
|
14
|
+
],
|
|
15
|
+
};
|
|
16
|
+
export function toTerminalRow(terminal, cwd) {
|
|
17
|
+
return {
|
|
18
|
+
id: terminal.id,
|
|
19
|
+
name: terminal.name,
|
|
20
|
+
cwd: terminal.cwd ?? cwd ?? "-",
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import { type TerminalCommandOptions } from "./shared.js";
|
|
3
|
+
export interface TerminalSendKeysOptions extends TerminalCommandOptions {
|
|
4
|
+
literal?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function runSendKeysCommand(terminalId: string, keys: string[], _options: TerminalSendKeysOptions, command: Command): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=send-keys.d.ts.map
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { renderError, toCommandError } from "../../output/render.js";
|
|
2
|
+
import { connectTerminalClient, resolveTerminalId, toTerminalCommandError, } from "./shared.js";
|
|
3
|
+
export async function runSendKeysCommand(terminalId, keys, _options, command) {
|
|
4
|
+
const options = command.optsWithGlobals();
|
|
5
|
+
try {
|
|
6
|
+
const payload = await executeSendKeysCommand(terminalId, keys, options);
|
|
7
|
+
if (options.json) {
|
|
8
|
+
process.stdout.write(JSON.stringify(payload, null, 2) + "\n");
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
catch (err) {
|
|
12
|
+
const output = renderError(toCommandError(err), {
|
|
13
|
+
format: options.json ? "json" : "table",
|
|
14
|
+
noColor: options.color === false,
|
|
15
|
+
});
|
|
16
|
+
process.stderr.write(output + "\n");
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async function executeSendKeysCommand(terminalId, keys, options) {
|
|
21
|
+
const { client } = await connectTerminalClient(options.host);
|
|
22
|
+
try {
|
|
23
|
+
const resolvedId = await resolveTerminalId(client, terminalId);
|
|
24
|
+
if (!resolvedId) {
|
|
25
|
+
throw {
|
|
26
|
+
code: "TERMINAL_NOT_FOUND",
|
|
27
|
+
message: `No terminal found matching: ${terminalId}`,
|
|
28
|
+
details: "Use `otto terminal ls --all` to list available terminals.",
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const data = keys.map((key) => resolveKeyToken(key, options.literal === true)).join("");
|
|
32
|
+
client.sendTerminalInput(resolvedId, { type: "input", data });
|
|
33
|
+
return {
|
|
34
|
+
terminalId: resolvedId,
|
|
35
|
+
keysSent: data.length,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
throw toTerminalCommandError("TERMINAL_SEND_KEYS_FAILED", "send terminal keys", err);
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
await client.close().catch(() => { });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function resolveKeyToken(key, literal) {
|
|
46
|
+
if (literal) {
|
|
47
|
+
return key;
|
|
48
|
+
}
|
|
49
|
+
switch (key) {
|
|
50
|
+
case "Enter":
|
|
51
|
+
return "\r";
|
|
52
|
+
case "Tab":
|
|
53
|
+
return "\t";
|
|
54
|
+
case "Escape":
|
|
55
|
+
return "\u001b";
|
|
56
|
+
case "Space":
|
|
57
|
+
return " ";
|
|
58
|
+
case "BSpace":
|
|
59
|
+
return "\u007f";
|
|
60
|
+
case "C-c":
|
|
61
|
+
return "\u0003";
|
|
62
|
+
case "C-d":
|
|
63
|
+
return "\u0004";
|
|
64
|
+
case "C-z":
|
|
65
|
+
return "\u001a";
|
|
66
|
+
case "C-l":
|
|
67
|
+
return "\u000c";
|
|
68
|
+
case "C-a":
|
|
69
|
+
return "\u0001";
|
|
70
|
+
case "C-e":
|
|
71
|
+
return "\u0005";
|
|
72
|
+
default:
|
|
73
|
+
return key;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=send-keys.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { connectToDaemon } from "../../utils/client.js";
|
|
2
|
+
import type { CommandError, CommandOptions } from "../../output/index.js";
|
|
3
|
+
export interface TerminalCommandOptions extends CommandOptions {
|
|
4
|
+
host?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function connectTerminalClient(host?: string): Promise<{
|
|
7
|
+
client: import("@otto-code/client/internal/daemon-client").DaemonClient;
|
|
8
|
+
daemonHost: string;
|
|
9
|
+
}>;
|
|
10
|
+
export declare function toTerminalCommandError(code: string, action: string, err: unknown): CommandError;
|
|
11
|
+
export declare function resolveTerminalId(client: Awaited<ReturnType<typeof connectToDaemon>>, idOrName: string): Promise<string | null>;
|
|
12
|
+
//# sourceMappingURL=shared.d.ts.map
|