@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.
Files changed (200) hide show
  1. package/bin/otto +3 -0
  2. package/dist/classify.d.ts +19 -0
  3. package/dist/classify.js +49 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.js +113 -0
  6. package/dist/commands/agent/archive.d.ts +18 -0
  7. package/dist/commands/agent/archive.js +102 -0
  8. package/dist/commands/agent/attach.d.ts +11 -0
  9. package/dist/commands/agent/attach.js +159 -0
  10. package/dist/commands/agent/delete.d.ts +15 -0
  11. package/dist/commands/agent/delete.js +107 -0
  12. package/dist/commands/agent/import.d.ts +14 -0
  13. package/dist/commands/agent/import.js +122 -0
  14. package/dist/commands/agent/index.d.ts +3 -0
  15. package/dist/commands/agent/index.js +48 -0
  16. package/dist/commands/agent/inspect.d.ts +15 -0
  17. package/dist/commands/agent/inspect.js +209 -0
  18. package/dist/commands/agent/logs.d.ts +19 -0
  19. package/dist/commands/agent/logs.js +180 -0
  20. package/dist/commands/agent/ls.d.ts +44 -0
  21. package/dist/commands/agent/ls.js +204 -0
  22. package/dist/commands/agent/mode.d.ts +18 -0
  23. package/dist/commands/agent/mode.js +100 -0
  24. package/dist/commands/agent/reload.d.ts +15 -0
  25. package/dist/commands/agent/reload.js +75 -0
  26. package/dist/commands/agent/run.d.ts +44 -0
  27. package/dist/commands/agent/run.js +464 -0
  28. package/dist/commands/agent/send.d.ts +19 -0
  29. package/dist/commands/agent/send.js +187 -0
  30. package/dist/commands/agent/stop.d.ts +17 -0
  31. package/dist/commands/agent/stop.js +115 -0
  32. package/dist/commands/agent/update.d.ts +18 -0
  33. package/dist/commands/agent/update.js +139 -0
  34. package/dist/commands/agent/wait.d.ts +17 -0
  35. package/dist/commands/agent/wait.js +158 -0
  36. package/dist/commands/chat/create.d.ts +9 -0
  37. package/dist/commands/chat/create.js +23 -0
  38. package/dist/commands/chat/delete.d.ts +6 -0
  39. package/dist/commands/chat/delete.js +20 -0
  40. package/dist/commands/chat/index.d.ts +3 -0
  41. package/dist/commands/chat/index.js +47 -0
  42. package/dist/commands/chat/inspect.d.ts +6 -0
  43. package/dist/commands/chat/inspect.js +20 -0
  44. package/dist/commands/chat/ls.d.ts +6 -0
  45. package/dist/commands/chat/ls.js +20 -0
  46. package/dist/commands/chat/post.d.ts +9 -0
  47. package/dist/commands/chat/post.js +28 -0
  48. package/dist/commands/chat/read.d.ts +11 -0
  49. package/dist/commands/chat/read.js +40 -0
  50. package/dist/commands/chat/schema.d.ts +36 -0
  51. package/dist/commands/chat/schema.js +81 -0
  52. package/dist/commands/chat/shared.d.ts +19 -0
  53. package/dist/commands/chat/shared.js +118 -0
  54. package/dist/commands/chat/wait.d.ts +9 -0
  55. package/dist/commands/chat/wait.js +45 -0
  56. package/dist/commands/daemon/index.d.ts +3 -0
  57. package/dist/commands/daemon/index.js +57 -0
  58. package/dist/commands/daemon/local-daemon.d.ts +78 -0
  59. package/dist/commands/daemon/local-daemon.js +544 -0
  60. package/dist/commands/daemon/pair.d.ts +9 -0
  61. package/dist/commands/daemon/pair.js +76 -0
  62. package/dist/commands/daemon/restart.d.ts +12 -0
  63. package/dist/commands/daemon/restart.js +99 -0
  64. package/dist/commands/daemon/runtime-toolchain.d.ts +6 -0
  65. package/dist/commands/daemon/runtime-toolchain.js +87 -0
  66. package/dist/commands/daemon/set-password.d.ts +17 -0
  67. package/dist/commands/daemon/set-password.js +82 -0
  68. package/dist/commands/daemon/start.d.ts +6 -0
  69. package/dist/commands/daemon/start.js +56 -0
  70. package/dist/commands/daemon/status.d.ts +10 -0
  71. package/dist/commands/daemon/status.js +338 -0
  72. package/dist/commands/daemon/stop.d.ts +15 -0
  73. package/dist/commands/daemon/stop.js +60 -0
  74. package/dist/commands/hooks.d.ts +19 -0
  75. package/dist/commands/hooks.js +89 -0
  76. package/dist/commands/loop/index.d.ts +3 -0
  77. package/dist/commands/loop/index.js +18 -0
  78. package/dist/commands/loop/inspect.d.ts +13 -0
  79. package/dist/commands/loop/inspect.js +100 -0
  80. package/dist/commands/loop/logs.d.ts +8 -0
  81. package/dist/commands/loop/logs.js +69 -0
  82. package/dist/commands/loop/ls.d.ts +18 -0
  83. package/dist/commands/loop/ls.js +62 -0
  84. package/dist/commands/loop/run.d.ts +30 -0
  85. package/dist/commands/loop/run.js +162 -0
  86. package/dist/commands/loop/stop.d.ts +15 -0
  87. package/dist/commands/loop/stop.js +56 -0
  88. package/dist/commands/loop/types.d.ts +138 -0
  89. package/dist/commands/loop/types.js +2 -0
  90. package/dist/commands/onboard.d.ts +10 -0
  91. package/dist/commands/onboard.js +416 -0
  92. package/dist/commands/open.d.ts +2 -0
  93. package/dist/commands/open.js +81 -0
  94. package/dist/commands/permit/allow.d.ts +20 -0
  95. package/dist/commands/permit/allow.js +133 -0
  96. package/dist/commands/permit/deny.d.ts +12 -0
  97. package/dist/commands/permit/deny.js +105 -0
  98. package/dist/commands/permit/index.d.ts +3 -0
  99. package/dist/commands/permit/index.js +27 -0
  100. package/dist/commands/permit/ls.d.ts +18 -0
  101. package/dist/commands/permit/ls.js +66 -0
  102. package/dist/commands/provider/index.d.ts +3 -0
  103. package/dist/commands/provider/index.js +16 -0
  104. package/dist/commands/provider/ls.d.ts +19 -0
  105. package/dist/commands/provider/ls.js +73 -0
  106. package/dist/commands/provider/models.d.ts +20 -0
  107. package/dist/commands/provider/models.js +53 -0
  108. package/dist/commands/schedule/create.d.ts +18 -0
  109. package/dist/commands/schedule/create.js +40 -0
  110. package/dist/commands/schedule/delete.d.ts +10 -0
  111. package/dist/commands/schedule/delete.js +32 -0
  112. package/dist/commands/schedule/index.d.ts +3 -0
  113. package/dist/commands/schedule/index.js +66 -0
  114. package/dist/commands/schedule/inspect.d.ts +6 -0
  115. package/dist/commands/schedule/inspect.js +24 -0
  116. package/dist/commands/schedule/logs.d.ts +6 -0
  117. package/dist/commands/schedule/logs.js +23 -0
  118. package/dist/commands/schedule/ls.d.ts +5 -0
  119. package/dist/commands/schedule/ls.js +23 -0
  120. package/dist/commands/schedule/pause.d.ts +5 -0
  121. package/dist/commands/schedule/pause.js +23 -0
  122. package/dist/commands/schedule/resume.d.ts +5 -0
  123. package/dist/commands/schedule/resume.js +23 -0
  124. package/dist/commands/schedule/run-once.d.ts +5 -0
  125. package/dist/commands/schedule/run-once.js +23 -0
  126. package/dist/commands/schedule/schema.d.ts +21 -0
  127. package/dist/commands/schedule/schema.js +67 -0
  128. package/dist/commands/schedule/shared.d.ts +56 -0
  129. package/dist/commands/schedule/shared.js +346 -0
  130. package/dist/commands/schedule/types.d.ts +168 -0
  131. package/dist/commands/schedule/types.js +2 -0
  132. package/dist/commands/schedule/update.d.ts +21 -0
  133. package/dist/commands/schedule/update.js +39 -0
  134. package/dist/commands/speech/index.d.ts +3 -0
  135. package/dist/commands/speech/index.js +5 -0
  136. package/dist/commands/terminal/capture.d.ts +10 -0
  137. package/dist/commands/terminal/capture.js +68 -0
  138. package/dist/commands/terminal/create.d.ts +10 -0
  139. package/dist/commands/terminal/create.js +38 -0
  140. package/dist/commands/terminal/index.d.ts +3 -0
  141. package/dist/commands/terminal/index.js +43 -0
  142. package/dist/commands/terminal/kill.d.ts +6 -0
  143. package/dist/commands/terminal/kill.js +36 -0
  144. package/dist/commands/terminal/ls.d.ts +10 -0
  145. package/dist/commands/terminal/ls.js +21 -0
  146. package/dist/commands/terminal/schema.d.ts +18 -0
  147. package/dist/commands/terminal/schema.js +23 -0
  148. package/dist/commands/terminal/send-keys.d.ts +7 -0
  149. package/dist/commands/terminal/send-keys.js +76 -0
  150. package/dist/commands/terminal/shared.d.ts +12 -0
  151. package/dist/commands/terminal/shared.js +61 -0
  152. package/dist/commands/worktree/archive.d.ts +20 -0
  153. package/dist/commands/worktree/archive.js +104 -0
  154. package/dist/commands/worktree/create-input.d.ts +15 -0
  155. package/dist/commands/worktree/create-input.js +56 -0
  156. package/dist/commands/worktree/create.d.ts +11 -0
  157. package/dist/commands/worktree/create.js +58 -0
  158. package/dist/commands/worktree/index.d.ts +3 -0
  159. package/dist/commands/worktree/index.js +25 -0
  160. package/dist/commands/worktree/ls.d.ts +19 -0
  161. package/dist/commands/worktree/ls.js +97 -0
  162. package/dist/index.d.ts +2 -0
  163. package/dist/index.js +6 -0
  164. package/dist/output/index.d.ts +45 -0
  165. package/dist/output/index.js +47 -0
  166. package/dist/output/json.d.ts +11 -0
  167. package/dist/output/json.js +37 -0
  168. package/dist/output/quiet.d.ts +9 -0
  169. package/dist/output/quiet.js +22 -0
  170. package/dist/output/render.d.ts +15 -0
  171. package/dist/output/render.js +83 -0
  172. package/dist/output/table.d.ts +13 -0
  173. package/dist/output/table.js +135 -0
  174. package/dist/output/types.d.ts +73 -0
  175. package/dist/output/types.js +8 -0
  176. package/dist/output/with-output.d.ts +41 -0
  177. package/dist/output/with-output.js +87 -0
  178. package/dist/output/yaml.d.ts +11 -0
  179. package/dist/output/yaml.js +38 -0
  180. package/dist/run.d.ts +14 -0
  181. package/dist/run.js +33 -0
  182. package/dist/utils/client-id.d.ts +2 -0
  183. package/dist/utils/client-id.js +37 -0
  184. package/dist/utils/client.d.ts +44 -0
  185. package/dist/utils/client.js +330 -0
  186. package/dist/utils/command-options.d.ts +6 -0
  187. package/dist/utils/command-options.js +17 -0
  188. package/dist/utils/duration.d.ts +7 -0
  189. package/dist/utils/duration.js +38 -0
  190. package/dist/utils/errors.d.ts +5 -0
  191. package/dist/utils/errors.js +10 -0
  192. package/dist/utils/paths.d.ts +12 -0
  193. package/dist/utils/paths.js +22 -0
  194. package/dist/utils/provider-model.d.ts +11 -0
  195. package/dist/utils/provider-model.js +49 -0
  196. package/dist/utils/timeline.d.ts +11 -0
  197. package/dist/utils/timeline.js +11 -0
  198. package/dist/version.d.ts +2 -0
  199. package/dist/version.js +10 -0
  200. package/package.json +48 -0
@@ -0,0 +1,69 @@
1
+ import { connectToDaemon, getDaemonHost } from "../../utils/client.js";
2
+ export function addLoopLogsOptions(command) {
3
+ return command
4
+ .description("Stream loop logs")
5
+ .argument("<id>", "Loop ID")
6
+ .option("--poll-interval <ms>", "Polling interval in milliseconds", "1000");
7
+ }
8
+ function parsePollInterval(value) {
9
+ const parsed = Number.parseInt(value, 10);
10
+ if (!Number.isInteger(parsed) || parsed <= 0) {
11
+ throw {
12
+ code: "INVALID_POLL_INTERVAL",
13
+ message: "--poll-interval must be a positive integer",
14
+ };
15
+ }
16
+ return parsed;
17
+ }
18
+ function renderLogEntry(entry) {
19
+ const prefix = [
20
+ entry.timestamp,
21
+ entry.source,
22
+ entry.iteration === null ? null : `iteration=${entry.iteration}`,
23
+ entry.level === "error" ? "ERROR" : null,
24
+ ]
25
+ .filter(Boolean)
26
+ .join(" ");
27
+ return `${prefix}\n${entry.text}`;
28
+ }
29
+ export async function runLoopLogsCommand(id, options, _command) {
30
+ const host = getDaemonHost({ host: options.host });
31
+ const pollInterval = parsePollInterval(options.pollInterval ?? "1000");
32
+ let client;
33
+ try {
34
+ client = (await connectToDaemon({
35
+ host: options.host,
36
+ }));
37
+ }
38
+ catch (error) {
39
+ const message = error instanceof Error ? error.message : String(error);
40
+ console.error(`Error: Cannot connect to daemon at ${host}: ${message}`);
41
+ console.error("Start the daemon with: otto daemon start");
42
+ process.exit(1);
43
+ }
44
+ async function streamLogs(cursor) {
45
+ const payload = await client.loopLogs(id, cursor);
46
+ if (payload.error || !payload.loop) {
47
+ throw new Error(payload.error ?? `Loop not found: ${id}`);
48
+ }
49
+ for (const entry of payload.entries) {
50
+ console.log(renderLogEntry(entry));
51
+ }
52
+ if (payload.loop.status !== "running") {
53
+ await client.close();
54
+ return;
55
+ }
56
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
57
+ return streamLogs(payload.nextCursor);
58
+ }
59
+ try {
60
+ await streamLogs(0);
61
+ }
62
+ catch (error) {
63
+ await client.close().catch(() => { });
64
+ const message = error instanceof Error ? error.message : String(error);
65
+ console.error(`Error: Failed to stream loop logs: ${message}`);
66
+ process.exit(1);
67
+ }
68
+ }
69
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1,18 @@
1
+ import { Command } from "commander";
2
+ import type { CommandOptions, OutputSchema, ListResult } from "../../output/index.js";
3
+ interface LoopListRow {
4
+ id: string;
5
+ name: string | null;
6
+ status: string;
7
+ cwd: string;
8
+ updated: string;
9
+ activeIteration: string;
10
+ }
11
+ export interface LoopLsOptions extends CommandOptions {
12
+ }
13
+ export declare const loopLsSchema: OutputSchema<LoopListRow>;
14
+ export declare function addLoopLsOptions(command: Command): Command;
15
+ export type LoopLsResult = ListResult<LoopListRow>;
16
+ export declare function runLoopLsCommand(options: LoopLsOptions, _command: Command): Promise<LoopLsResult>;
17
+ export {};
18
+ //# sourceMappingURL=ls.d.ts.map
@@ -0,0 +1,62 @@
1
+ import { connectToDaemon, getDaemonHost } from "../../utils/client.js";
2
+ export const loopLsSchema = {
3
+ idField: "id",
4
+ columns: [
5
+ { header: "LOOP ID", field: "id", width: 10 },
6
+ { header: "NAME", field: "name", width: 20 },
7
+ { header: "STATUS", field: "status", width: 10 },
8
+ { header: "ITER", field: "activeIteration", width: 8 },
9
+ { header: "CWD", field: "cwd", width: 40 },
10
+ { header: "UPDATED", field: "updated", width: 24 },
11
+ ],
12
+ };
13
+ export function addLoopLsOptions(command) {
14
+ return command.description("List loops");
15
+ }
16
+ function toRow(loop) {
17
+ return {
18
+ id: loop.id,
19
+ name: loop.name,
20
+ status: loop.status,
21
+ cwd: loop.cwd,
22
+ updated: loop.updatedAt,
23
+ activeIteration: loop.activeIteration === null ? "-" : String(loop.activeIteration),
24
+ };
25
+ }
26
+ export async function runLoopLsCommand(options, _command) {
27
+ const host = getDaemonHost({ host: options.host });
28
+ let client;
29
+ try {
30
+ client = (await connectToDaemon({
31
+ host: options.host,
32
+ }));
33
+ }
34
+ catch (error) {
35
+ const message = error instanceof Error ? error.message : String(error);
36
+ throw {
37
+ code: "DAEMON_NOT_RUNNING",
38
+ message: `Cannot connect to daemon at ${host}: ${message}`,
39
+ details: "Start the daemon with: otto daemon start",
40
+ };
41
+ }
42
+ try {
43
+ const payload = await client.loopList();
44
+ await client.close();
45
+ if (payload.error) {
46
+ throw new Error(payload.error);
47
+ }
48
+ return {
49
+ type: "list",
50
+ data: payload.loops.map(toRow),
51
+ schema: loopLsSchema,
52
+ };
53
+ }
54
+ catch (error) {
55
+ await client.close().catch(() => { });
56
+ throw {
57
+ code: "LOOP_LIST_FAILED",
58
+ message: error instanceof Error ? error.message : String(error),
59
+ };
60
+ }
61
+ }
62
+ //# sourceMappingURL=ls.js.map
@@ -0,0 +1,30 @@
1
+ import { Command } from "commander";
2
+ import type { CommandOptions, OutputSchema, SingleResult } from "../../output/index.js";
3
+ import type { LoopRunInput } from "./types.js";
4
+ export interface LoopRunRow {
5
+ id: string;
6
+ status: string;
7
+ name: string | null;
8
+ cwd: string;
9
+ }
10
+ export interface LoopRunOptions extends CommandOptions {
11
+ provider?: string;
12
+ model?: string;
13
+ mode?: string;
14
+ verifyProvider?: string;
15
+ verifyModel?: string;
16
+ verifyMode?: string;
17
+ verify?: string;
18
+ verifyCheck?: string[];
19
+ archive?: boolean;
20
+ name?: string;
21
+ sleep?: string;
22
+ maxIterations?: string;
23
+ maxTime?: string;
24
+ }
25
+ export declare const loopRunSchema: OutputSchema<LoopRunRow>;
26
+ export declare function addLoopRunOptions(command: Command): Command;
27
+ export declare function buildLoopRunInput(prompt: string, options: LoopRunOptions): LoopRunInput;
28
+ export type LoopRunResult = SingleResult<LoopRunRow>;
29
+ export declare function runLoopRunCommand(prompt: string, options: LoopRunOptions, _command: Command): Promise<LoopRunResult>;
30
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1,162 @@
1
+ import { connectToDaemon, getDaemonHost } from "../../utils/client.js";
2
+ import { collectMultiple } from "../../utils/command-options.js";
3
+ import { parseDuration } from "../../utils/duration.js";
4
+ import { resolveProviderAndModel } from "../../utils/provider-model.js";
5
+ export const loopRunSchema = {
6
+ idField: "id",
7
+ columns: [
8
+ { header: "LOOP ID", field: "id", width: 10 },
9
+ { header: "STATUS", field: "status", width: 10 },
10
+ { header: "NAME", field: "name", width: 20 },
11
+ { header: "CWD", field: "cwd", width: 40 },
12
+ ],
13
+ };
14
+ export function addLoopRunOptions(command) {
15
+ return command
16
+ .description("Start a loop")
17
+ .argument("<prompt>", "Prompt for each fresh worker iteration")
18
+ .option("--provider <provider>", "Default provider for worker and verifier agents")
19
+ .option("--model <model>", "Default model for worker and verifier agents")
20
+ .option("--mode <mode>", "Provider-specific mode for the worker agent (e.g. claude bypassPermissions, opencode build)")
21
+ .option("--verify-provider <provider>", "Provider for the verifier agent")
22
+ .option("--verify-model <model>", "Model for the verifier agent")
23
+ .option("--verify-mode <mode>", "Provider-specific mode for the verifier agent")
24
+ .option("--verify <prompt>", "Verifier agent prompt")
25
+ .option("--verify-check <command>", "Shell command that must exit 0 (repeatable)", collectMultiple, [])
26
+ .option("--archive", "Archive worker and verifier agents after each iteration")
27
+ .option("--name <name>", "Optional loop name")
28
+ .option("--sleep <duration>", "Delay between iterations (for example: 30s, 5m)")
29
+ .option("--max-iterations <n>", "Maximum number of iterations")
30
+ .option("--max-time <duration>", "Maximum total runtime (for example: 1h, 30m)");
31
+ }
32
+ function toRow(loop) {
33
+ return {
34
+ id: loop.id,
35
+ status: loop.status,
36
+ name: loop.name,
37
+ cwd: loop.cwd,
38
+ };
39
+ }
40
+ function parseMaxIterations(value) {
41
+ if (value === undefined) {
42
+ return undefined;
43
+ }
44
+ const parsed = Number.parseInt(value, 10);
45
+ if (!Number.isInteger(parsed) || parsed <= 0) {
46
+ throw {
47
+ code: "INVALID_MAX_ITERATIONS",
48
+ message: "--max-iterations must be a positive integer",
49
+ };
50
+ }
51
+ return parsed;
52
+ }
53
+ // oxlint-disable complexity
54
+ export function buildLoopRunInput(prompt, options) {
55
+ const verifyPrompt = options.verify?.trim();
56
+ if (options.verify !== undefined && !verifyPrompt) {
57
+ throw {
58
+ code: "INVALID_VERIFY_PROMPT",
59
+ message: "--verify cannot be empty",
60
+ };
61
+ }
62
+ const result = {
63
+ prompt,
64
+ cwd: process.cwd(),
65
+ };
66
+ // Resolve provider/model
67
+ if (options.provider) {
68
+ const { provider, model } = resolveProviderAndModel({ provider: options.provider });
69
+ if (provider)
70
+ result.provider = provider;
71
+ // Explicit --model takes precedence over parsed model
72
+ if (options.model?.trim()) {
73
+ result.model = options.model.trim();
74
+ }
75
+ else if (model) {
76
+ result.model = model;
77
+ }
78
+ }
79
+ else if (options.model?.trim()) {
80
+ result.model = options.model.trim();
81
+ }
82
+ if (options.mode?.trim()) {
83
+ result.modeId = options.mode.trim();
84
+ }
85
+ // Resolve verifier provider/model
86
+ if (options.verifyProvider) {
87
+ const { provider, model } = resolveProviderAndModel({ provider: options.verifyProvider });
88
+ if (provider)
89
+ result.verifierProvider = provider;
90
+ // Explicit --verify-model takes precedence over parsed model
91
+ if (options.verifyModel?.trim()) {
92
+ result.verifierModel = options.verifyModel.trim();
93
+ }
94
+ else if (model) {
95
+ result.verifierModel = model;
96
+ }
97
+ }
98
+ else if (options.verifyModel?.trim()) {
99
+ result.verifierModel = options.verifyModel.trim();
100
+ }
101
+ if (options.verifyMode?.trim()) {
102
+ result.verifierModeId = options.verifyMode.trim();
103
+ }
104
+ if (verifyPrompt)
105
+ result.verifyPrompt = verifyPrompt;
106
+ if (options.verifyCheck && options.verifyCheck.length > 0) {
107
+ result.verifyChecks = options.verifyCheck;
108
+ }
109
+ if (options.archive)
110
+ result.archive = true;
111
+ if (options.name?.trim())
112
+ result.name = options.name.trim();
113
+ if (options.sleep)
114
+ result.sleepMs = parseDuration(options.sleep);
115
+ if (options.maxIterations) {
116
+ result.maxIterations = parseMaxIterations(options.maxIterations);
117
+ }
118
+ if (options.maxTime)
119
+ result.maxTimeMs = parseDuration(options.maxTime);
120
+ return result;
121
+ }
122
+ export async function runLoopRunCommand(prompt, options, _command) {
123
+ const host = getDaemonHost({ host: options.host });
124
+ const input = buildLoopRunInput(prompt, options);
125
+ let client;
126
+ try {
127
+ client = (await connectToDaemon({
128
+ host: options.host,
129
+ }));
130
+ }
131
+ catch (error) {
132
+ const message = error instanceof Error ? error.message : String(error);
133
+ throw {
134
+ code: "DAEMON_NOT_RUNNING",
135
+ message: `Cannot connect to daemon at ${host}: ${message}`,
136
+ details: "Start the daemon with: otto daemon start",
137
+ };
138
+ }
139
+ try {
140
+ const payload = await client.loopRun(input);
141
+ await client.close();
142
+ if (payload.error || !payload.loop) {
143
+ throw new Error(payload.error ?? "Loop creation failed");
144
+ }
145
+ return {
146
+ type: "single",
147
+ data: toRow(payload.loop),
148
+ schema: loopRunSchema,
149
+ };
150
+ }
151
+ catch (error) {
152
+ await client.close().catch(() => { });
153
+ if (error && typeof error === "object" && "code" in error) {
154
+ throw error;
155
+ }
156
+ throw {
157
+ code: "LOOP_RUN_FAILED",
158
+ message: error instanceof Error ? error.message : String(error),
159
+ };
160
+ }
161
+ }
162
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1,15 @@
1
+ import { Command } from "commander";
2
+ import type { CommandOptions, OutputSchema, SingleResult } from "../../output/index.js";
3
+ interface LoopStopRow {
4
+ id: string;
5
+ status: string;
6
+ activeIteration: string;
7
+ }
8
+ export interface LoopStopOptions extends CommandOptions {
9
+ }
10
+ export declare const loopStopSchema: OutputSchema<LoopStopRow>;
11
+ export declare function addLoopStopOptions(command: Command): Command;
12
+ export type LoopStopResult = SingleResult<LoopStopRow>;
13
+ export declare function runLoopStopCommand(id: string, options: LoopStopOptions, _command: Command): Promise<LoopStopResult>;
14
+ export {};
15
+ //# sourceMappingURL=stop.d.ts.map
@@ -0,0 +1,56 @@
1
+ import { connectToDaemon, getDaemonHost } from "../../utils/client.js";
2
+ export const loopStopSchema = {
3
+ idField: "id",
4
+ columns: [
5
+ { header: "LOOP ID", field: "id", width: 10 },
6
+ { header: "STATUS", field: "status", width: 10 },
7
+ { header: "ITER", field: "activeIteration", width: 8 },
8
+ ],
9
+ };
10
+ export function addLoopStopOptions(command) {
11
+ return command.description("Stop a running loop").argument("<id>", "Loop ID");
12
+ }
13
+ function toRow(loop) {
14
+ return {
15
+ id: loop.id,
16
+ status: loop.status,
17
+ activeIteration: loop.activeIteration === null ? "-" : String(loop.activeIteration),
18
+ };
19
+ }
20
+ export async function runLoopStopCommand(id, options, _command) {
21
+ const host = getDaemonHost({ host: options.host });
22
+ let client;
23
+ try {
24
+ client = (await connectToDaemon({
25
+ host: options.host,
26
+ }));
27
+ }
28
+ catch (error) {
29
+ const message = error instanceof Error ? error.message : String(error);
30
+ throw {
31
+ code: "DAEMON_NOT_RUNNING",
32
+ message: `Cannot connect to daemon at ${host}: ${message}`,
33
+ details: "Start the daemon with: otto daemon start",
34
+ };
35
+ }
36
+ try {
37
+ const payload = await client.loopStop(id);
38
+ await client.close();
39
+ if (payload.error || !payload.loop) {
40
+ throw new Error(payload.error ?? `Loop not found: ${id}`);
41
+ }
42
+ return {
43
+ type: "single",
44
+ data: toRow(payload.loop),
45
+ schema: loopStopSchema,
46
+ };
47
+ }
48
+ catch (error) {
49
+ await client.close().catch(() => { });
50
+ throw {
51
+ code: "LOOP_STOP_FAILED",
52
+ message: error instanceof Error ? error.message : String(error),
53
+ };
54
+ }
55
+ }
56
+ //# sourceMappingURL=stop.js.map
@@ -0,0 +1,138 @@
1
+ export type LoopStatus = "running" | "succeeded" | "failed" | "stopped";
2
+ export interface LoopLogEntry {
3
+ seq: number;
4
+ timestamp: string;
5
+ iteration: number | null;
6
+ source: "loop" | "worker" | "verifier" | "verify-check";
7
+ level: "info" | "error";
8
+ text: string;
9
+ }
10
+ export interface LoopVerifyCheckResult {
11
+ command: string;
12
+ exitCode: number;
13
+ passed: boolean;
14
+ stdout: string;
15
+ stderr: string;
16
+ startedAt: string;
17
+ completedAt: string;
18
+ }
19
+ export interface LoopVerifyPromptResult {
20
+ passed: boolean;
21
+ reason: string;
22
+ verifierAgentId: string | null;
23
+ startedAt: string;
24
+ completedAt: string;
25
+ }
26
+ export interface LoopIterationRecord {
27
+ index: number;
28
+ workerAgentId: string | null;
29
+ workerStartedAt: string;
30
+ workerCompletedAt: string | null;
31
+ verifierAgentId: string | null;
32
+ status: "running" | "succeeded" | "failed" | "stopped";
33
+ workerOutcome: "completed" | "failed" | "canceled" | null;
34
+ failureReason: string | null;
35
+ verifyChecks: LoopVerifyCheckResult[];
36
+ verifyPrompt: LoopVerifyPromptResult | null;
37
+ }
38
+ export interface LoopRecord {
39
+ id: string;
40
+ name: string | null;
41
+ prompt: string;
42
+ cwd: string;
43
+ provider: string;
44
+ model: string | null;
45
+ modeId: string | null;
46
+ workerProvider: string | null;
47
+ workerModel: string | null;
48
+ verifierProvider: string | null;
49
+ verifierModel: string | null;
50
+ verifierModeId: string | null;
51
+ verifyPrompt: string | null;
52
+ verifyChecks: string[];
53
+ archive: boolean;
54
+ sleepMs: number;
55
+ maxIterations: number | null;
56
+ maxTimeMs: number | null;
57
+ status: LoopStatus;
58
+ createdAt: string;
59
+ updatedAt: string;
60
+ startedAt: string;
61
+ completedAt: string | null;
62
+ stopRequestedAt: string | null;
63
+ iterations: LoopIterationRecord[];
64
+ logs: LoopLogEntry[];
65
+ nextLogSeq: number;
66
+ activeIteration: number | null;
67
+ activeWorkerAgentId: string | null;
68
+ activeVerifierAgentId: string | null;
69
+ }
70
+ export interface LoopListItem {
71
+ id: string;
72
+ name: string | null;
73
+ status: LoopStatus;
74
+ cwd: string;
75
+ createdAt: string;
76
+ updatedAt: string;
77
+ activeIteration: number | null;
78
+ }
79
+ export interface LoopLogsResult {
80
+ loop: LoopRecord;
81
+ entries: LoopLogEntry[];
82
+ nextCursor: number;
83
+ }
84
+ export interface LoopRunPayload {
85
+ requestId: string;
86
+ loop: LoopRecord | null;
87
+ error: string | null;
88
+ }
89
+ export interface LoopListPayload {
90
+ requestId: string;
91
+ loops: LoopListItem[];
92
+ error: string | null;
93
+ }
94
+ export interface LoopInspectPayload {
95
+ requestId: string;
96
+ loop: LoopRecord | null;
97
+ error: string | null;
98
+ }
99
+ export interface LoopLogsPayload {
100
+ requestId: string;
101
+ loop: LoopRecord | null;
102
+ entries: LoopLogEntry[];
103
+ nextCursor: number;
104
+ error: string | null;
105
+ }
106
+ export interface LoopStopPayload {
107
+ requestId: string;
108
+ loop: LoopRecord | null;
109
+ error: string | null;
110
+ }
111
+ export interface LoopRunInput {
112
+ prompt: string;
113
+ cwd: string;
114
+ provider?: string;
115
+ model?: string;
116
+ modeId?: string;
117
+ workerProvider?: string;
118
+ workerModel?: string;
119
+ verifierProvider?: string;
120
+ verifierModel?: string;
121
+ verifierModeId?: string;
122
+ verifyPrompt?: string;
123
+ verifyChecks?: string[];
124
+ archive?: boolean;
125
+ name?: string;
126
+ sleepMs?: number;
127
+ maxIterations?: number;
128
+ maxTimeMs?: number;
129
+ }
130
+ export interface LoopDaemonClient {
131
+ loopRun(input: LoopRunInput): Promise<LoopRunPayload>;
132
+ loopList(): Promise<LoopListPayload>;
133
+ loopInspect(id: string): Promise<LoopInspectPayload>;
134
+ loopLogs(id: string, afterSeq?: number): Promise<LoopLogsPayload>;
135
+ loopStop(id: string): Promise<LoopStopPayload>;
136
+ close(): Promise<void>;
137
+ }
138
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,10 @@
1
+ import { Command } from "commander";
2
+ import { type DaemonStartOptions } from "./daemon/local-daemon.js";
3
+ interface OnboardOptions extends DaemonStartOptions {
4
+ timeout?: string;
5
+ voice?: "ask" | "enable" | "disable";
6
+ }
7
+ export declare function onboardCommand(): Command;
8
+ export declare function runOnboard(options: OnboardOptions): Promise<void>;
9
+ export {};
10
+ //# sourceMappingURL=onboard.d.ts.map