@tiny-fish/cli 0.1.3-next.31 → 0.1.3-next.32
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/dist/commands/run.js +43 -31
- package/dist/commands/runs.js +1 -1
- package/dist/lib/client.d.ts +7 -6
- package/dist/lib/client.js +129 -108
- package/dist/lib/types.d.ts +2 -97
- package/dist/lib/types.js +1 -18
- package/package.json +4 -2
package/dist/commands/run.js
CHANGED
|
@@ -1,15 +1,30 @@
|
|
|
1
|
+
import { EventType, RunStatus } from "@tiny-fish/sdk";
|
|
1
2
|
import { getApiKey } from "../lib/auth.js";
|
|
2
3
|
import { cancelRun, runAsync, runStream, runSync } from "../lib/client.js";
|
|
3
4
|
import { err, errLine, handleApiError, out, outLine } from "../lib/output.js";
|
|
4
|
-
import { RunStatus, StreamEventType } from "../lib/types.js";
|
|
5
5
|
import { BASE_URL } from "../lib/constants.js";
|
|
6
|
-
|
|
6
|
+
function extractErrorMessage(error) {
|
|
7
|
+
if (typeof error === "string")
|
|
8
|
+
return error;
|
|
9
|
+
if (typeof error === "object" && error !== null) {
|
|
10
|
+
const maybeError = error;
|
|
11
|
+
if (typeof maybeError.message === "string") {
|
|
12
|
+
return maybeError.message;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
7
17
|
function checkRunResult(result, expectComplete = true) {
|
|
8
|
-
|
|
9
|
-
|
|
18
|
+
const errorMessage = extractErrorMessage(result.error);
|
|
19
|
+
if (errorMessage) {
|
|
20
|
+
err({
|
|
21
|
+
error: errorMessage,
|
|
22
|
+
run_id: result.run_id,
|
|
23
|
+
status: "status" in result ? result.status : undefined,
|
|
24
|
+
});
|
|
10
25
|
process.exit(1);
|
|
11
26
|
}
|
|
12
|
-
if (expectComplete && result.status && result.status !== RunStatus.COMPLETED) {
|
|
27
|
+
if (expectComplete && "status" in result && result.status && result.status !== RunStatus.COMPLETED) {
|
|
13
28
|
err({ error: `Run ${result.status}`, run_id: result.run_id, status: result.status });
|
|
14
29
|
process.exit(1);
|
|
15
30
|
}
|
|
@@ -68,8 +83,11 @@ export function registerRun(agentCmd) {
|
|
|
68
83
|
handleApiError(e);
|
|
69
84
|
}
|
|
70
85
|
checkRunResult(result, false); // async = PENDING is expected
|
|
71
|
-
const
|
|
72
|
-
|
|
86
|
+
const asyncResultWithUrl = {
|
|
87
|
+
...result,
|
|
88
|
+
status: RunStatus.PENDING,
|
|
89
|
+
run_url: `${BASE_URL}/runs/${result.run_id}`,
|
|
90
|
+
};
|
|
73
91
|
if (opts.pretty) {
|
|
74
92
|
outLine(`Run submitted\nID: ${asyncResultWithUrl.run_id}\nURL: ${asyncResultWithUrl.run_url}`);
|
|
75
93
|
}
|
|
@@ -82,14 +100,16 @@ export function registerRun(agentCmd) {
|
|
|
82
100
|
errLine("Waiting for result...");
|
|
83
101
|
let result;
|
|
84
102
|
try {
|
|
85
|
-
result = await runSync(req, apiKey
|
|
103
|
+
result = await runSync(req, apiKey);
|
|
86
104
|
}
|
|
87
105
|
catch (e) {
|
|
88
106
|
handleApiError(e);
|
|
89
107
|
}
|
|
90
108
|
checkRunResult(result);
|
|
91
|
-
const
|
|
92
|
-
|
|
109
|
+
const syncResultWithUrl = {
|
|
110
|
+
...result,
|
|
111
|
+
run_url: `${BASE_URL}/runs/${result.run_id}`,
|
|
112
|
+
};
|
|
93
113
|
if (opts.pretty) {
|
|
94
114
|
outLine(`Status: ${syncResultWithUrl.status}\n\n${JSON.stringify(syncResultWithUrl.result ?? {}, null, 2)}`);
|
|
95
115
|
}
|
|
@@ -98,11 +118,10 @@ export function registerRun(agentCmd) {
|
|
|
98
118
|
}
|
|
99
119
|
return;
|
|
100
120
|
}
|
|
101
|
-
// Default: SSE stream —
|
|
121
|
+
// Default: SSE stream — Ctrl+C cancels the active run.
|
|
102
122
|
const controller = new AbortController();
|
|
103
123
|
let siginted = false;
|
|
104
124
|
let capturedRunId = null;
|
|
105
|
-
const timeout = setTimeout(() => controller.abort(), RUN_TIMEOUT_MS);
|
|
106
125
|
const onSigint = () => {
|
|
107
126
|
siginted = true;
|
|
108
127
|
controller.abort();
|
|
@@ -115,6 +134,9 @@ export function registerRun(agentCmd) {
|
|
|
115
134
|
streamFailed = true;
|
|
116
135
|
break;
|
|
117
136
|
}
|
|
137
|
+
if (event.type === EventType.COMPLETE) {
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
118
140
|
}
|
|
119
141
|
}
|
|
120
142
|
catch (e) {
|
|
@@ -130,14 +152,9 @@ export function registerRun(agentCmd) {
|
|
|
130
152
|
process.stderr.write(cancelled ? "\nRun cancelled.\n" : "\n");
|
|
131
153
|
process.exit(130);
|
|
132
154
|
}
|
|
133
|
-
if (controller.signal.aborted) {
|
|
134
|
-
err({ error: "Run timed out after 20 minutes" });
|
|
135
|
-
process.exit(1);
|
|
136
|
-
}
|
|
137
155
|
handleApiError(e);
|
|
138
156
|
}
|
|
139
157
|
finally {
|
|
140
|
-
clearTimeout(timeout);
|
|
141
158
|
process.removeListener("SIGINT", onSigint);
|
|
142
159
|
}
|
|
143
160
|
if (streamFailed)
|
|
@@ -150,42 +167,37 @@ export function registerRun(agentCmd) {
|
|
|
150
167
|
* Returns false on terminal error (caller should exit 1); true otherwise.
|
|
151
168
|
*/
|
|
152
169
|
function handleStreamEvent(event, pretty, onRunId) {
|
|
153
|
-
if (event.type ===
|
|
154
|
-
err({ error: event.error
|
|
155
|
-
return false;
|
|
156
|
-
}
|
|
157
|
-
if (event.type === StreamEventType.COMPLETE && event.status !== RunStatus.COMPLETED) {
|
|
158
|
-
err({ error: event.error ?? `Run ${event.status}`, run_id: event.run_id, status: event.status });
|
|
170
|
+
if (event.type === EventType.COMPLETE && event.status !== RunStatus.COMPLETED) {
|
|
171
|
+
err({ error: event.error?.message ?? `Run ${event.status}`, run_id: event.run_id, status: event.status });
|
|
159
172
|
return false;
|
|
160
173
|
}
|
|
161
174
|
if (pretty) {
|
|
162
175
|
switch (event.type) {
|
|
163
|
-
case
|
|
176
|
+
case EventType.STARTED:
|
|
164
177
|
if (onRunId && event.run_id)
|
|
165
178
|
onRunId(event.run_id);
|
|
166
179
|
outLine(`▶ Run started`);
|
|
167
180
|
break;
|
|
168
|
-
case
|
|
181
|
+
case EventType.STREAMING_URL:
|
|
169
182
|
outLine(`🔗 Live view: ${event.streaming_url}`);
|
|
170
183
|
break;
|
|
171
|
-
case
|
|
184
|
+
case EventType.PROGRESS:
|
|
172
185
|
outLine(`• ${event.purpose}`);
|
|
173
186
|
break;
|
|
174
|
-
case
|
|
187
|
+
case EventType.COMPLETE: {
|
|
175
188
|
const runUrl = `${BASE_URL}/runs/${event.run_id}`;
|
|
176
189
|
outLine(`✓ Completed\n\n${JSON.stringify(event.result ?? {}, null, 2)}\n\nView run: ${runUrl}`);
|
|
177
190
|
break;
|
|
178
191
|
}
|
|
179
|
-
case
|
|
192
|
+
case EventType.HEARTBEAT:
|
|
180
193
|
// silently skip — keep-alive noise
|
|
181
194
|
break;
|
|
182
195
|
}
|
|
183
196
|
}
|
|
184
197
|
else {
|
|
185
198
|
// Raw JSON: emit all events (STREAMING_URL and HEARTBEAT are useful for agents)
|
|
186
|
-
if (event.type ===
|
|
187
|
-
|
|
188
|
-
out({ run_id: event.run_id, run_url: `${BASE_URL}/runs/${event.run_id}`, ...eventRest });
|
|
199
|
+
if (event.type === EventType.COMPLETE) {
|
|
200
|
+
out({ ...event, run_url: `${BASE_URL}/runs/${event.run_id}` });
|
|
189
201
|
}
|
|
190
202
|
else {
|
|
191
203
|
out(event);
|
package/dist/commands/runs.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { RunStatus } from "@tiny-fish/sdk";
|
|
1
2
|
import { getApiKey } from "../lib/auth.js";
|
|
2
3
|
import { cancelRun, getRun, listRuns } from "../lib/client.js";
|
|
3
4
|
import { err, handleApiError, out, outLine } from "../lib/output.js";
|
|
4
|
-
import { RunStatus } from "../lib/types.js";
|
|
5
5
|
const VALID_STATUSES = Object.values(RunStatus);
|
|
6
6
|
export function registerRuns(runCmd) {
|
|
7
7
|
// ── run list ───────────────────────────────────────────────────────────────
|
package/dist/lib/client.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
export declare function
|
|
4
|
-
export declare function
|
|
5
|
-
export declare function
|
|
6
|
-
export declare function
|
|
1
|
+
import { type AgentRunAsyncResponse, type AgentRunParams, type AgentRunResponse, type AgentRunWithStreamingResponse, type Run, type RunListParams, type RunListResponse } from "@tiny-fish/sdk";
|
|
2
|
+
import type { BatchCancelResponse, BatchGetResponse, BatchRunRequest, BatchRunResponse, CancelRunResponse } from "./types.js";
|
|
3
|
+
export declare function runSync(req: AgentRunParams, apiKey: string): Promise<AgentRunResponse>;
|
|
4
|
+
export declare function runAsync(req: AgentRunParams, apiKey: string): Promise<AgentRunAsyncResponse>;
|
|
5
|
+
export declare function runStream(req: AgentRunParams, apiKey: string, signal?: AbortSignal): AsyncGenerator<AgentRunWithStreamingResponse>;
|
|
6
|
+
export declare function listRuns(opts: RunListParams, apiKey: string): Promise<RunListResponse>;
|
|
7
|
+
export declare function getRun(runId: string, apiKey: string): Promise<Run>;
|
|
7
8
|
export declare function cancelRun(runId: string, apiKey: string): Promise<CancelRunResponse>;
|
|
8
9
|
export declare function submitBatch(req: BatchRunRequest, apiKey: string): Promise<BatchRunResponse>;
|
|
9
10
|
export declare function getBatchRuns(runIds: string[], apiKey: string): Promise<BatchGetResponse>;
|
package/dist/lib/client.js
CHANGED
|
@@ -1,138 +1,159 @@
|
|
|
1
|
+
import { APIStatusError, TinyFish, runSchema, } from "@tiny-fish/sdk";
|
|
1
2
|
import { BASE_URL } from "./constants.js";
|
|
2
3
|
import { ApiError } from "./output.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
process.stderr.write(`[debug] ${msg}\n`);
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
class TinyFishCliClient extends TinyFish {
|
|
6
|
+
_buildHeaders() {
|
|
7
|
+
return {
|
|
8
|
+
...super._buildHeaders(),
|
|
9
|
+
"X-TF-Request-Origin": "tinyfish-cli",
|
|
10
|
+
};
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
async function throwIfError(res) {
|
|
22
|
-
if (!res.ok) {
|
|
23
|
-
const json = await res.json().catch(() => ({}));
|
|
24
|
-
const message = json.error?.message ??
|
|
25
|
-
json.detail ??
|
|
26
|
-
`HTTP ${res.status}`;
|
|
27
|
-
throw new ApiError(res.status, message);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
/** POST JSON to a path and return the raw Response, throwing ApiError on non-2xx. */
|
|
31
|
-
async function postJson(path, body, apiKey, signal) {
|
|
32
|
-
const start = Date.now();
|
|
33
|
-
debugLog(`--> POST ${path}`);
|
|
34
|
-
const res = await fetch(`${BASE_URL}${path}`, {
|
|
35
|
-
method: "POST",
|
|
36
|
-
headers: headers(apiKey),
|
|
37
|
-
body: JSON.stringify(body),
|
|
38
|
-
signal,
|
|
13
|
+
function createSdkClient(apiKey, timeout) {
|
|
14
|
+
return new TinyFishCliClient({
|
|
15
|
+
apiKey,
|
|
16
|
+
baseURL: BASE_URL,
|
|
17
|
+
maxRetries: 0,
|
|
18
|
+
...(timeout !== undefined ? { timeout } : {}),
|
|
39
19
|
});
|
|
40
|
-
debugLog(`<-- ${res.status} (${Date.now() - start}ms)`);
|
|
41
|
-
await throwIfError(res);
|
|
42
|
-
return res;
|
|
43
20
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
21
|
+
function rethrowSdkError(error) {
|
|
22
|
+
if (error instanceof APIStatusError) {
|
|
23
|
+
throw new ApiError(error.statusCode, error.message);
|
|
24
|
+
}
|
|
25
|
+
if (error instanceof Error) {
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
throw new Error(String(error));
|
|
29
|
+
}
|
|
30
|
+
const cancelRunResponseSchema = z.object({
|
|
31
|
+
run_id: z.string(),
|
|
32
|
+
status: z.string(),
|
|
33
|
+
cancelled_at: z.string(),
|
|
34
|
+
message: z.string().nullable(),
|
|
35
|
+
});
|
|
36
|
+
const batchRunResponseSchema = z.object({
|
|
37
|
+
run_ids: z.array(z.string()).nullable(),
|
|
38
|
+
error: z.object({
|
|
39
|
+
code: z.string(),
|
|
40
|
+
message: z.string(),
|
|
41
|
+
}).nullable(),
|
|
42
|
+
});
|
|
43
|
+
const batchGetResponseSchema = z.object({
|
|
44
|
+
data: z.array(runSchema),
|
|
45
|
+
not_found: z.array(z.string()).nullable(),
|
|
46
|
+
});
|
|
47
|
+
const batchCancelResultSchema = z.object({
|
|
48
|
+
run_id: z.string(),
|
|
49
|
+
status: z.string(),
|
|
50
|
+
cancelled_at: z.string().nullable(),
|
|
51
|
+
message: z.string().nullable(),
|
|
52
|
+
});
|
|
53
|
+
const batchCancelResponseSchema = z.object({
|
|
54
|
+
results: z.array(batchCancelResultSchema),
|
|
55
|
+
not_found: z.array(z.string()).nullable(),
|
|
56
|
+
});
|
|
57
|
+
function parseWithSchema(schema, value, message) {
|
|
58
|
+
const result = schema.safeParse(value);
|
|
59
|
+
if (!result.success) {
|
|
60
|
+
throw new Error(message);
|
|
61
|
+
}
|
|
62
|
+
return result.data;
|
|
56
63
|
}
|
|
57
|
-
|
|
58
|
-
function* parseSseLine(line) {
|
|
59
|
-
const trimmed = line.trim();
|
|
60
|
-
if (!trimmed.startsWith("data:"))
|
|
61
|
-
return;
|
|
62
|
-
const data = trimmed.slice(5).trim();
|
|
63
|
-
if (!data || data === "[DONE]")
|
|
64
|
-
return;
|
|
64
|
+
export async function runSync(req, apiKey) {
|
|
65
65
|
try {
|
|
66
|
-
|
|
66
|
+
return await createSdkClient(apiKey).agent.run(req);
|
|
67
67
|
}
|
|
68
|
-
catch {
|
|
69
|
-
|
|
68
|
+
catch (error) {
|
|
69
|
+
rethrowSdkError(error);
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
-
// ── Automation run ────────────────────────────────────────────────────────────
|
|
73
|
-
export async function runSync(req, apiKey, signal) {
|
|
74
|
-
const res = await postJson("/v1/automation/run", req, apiKey, signal);
|
|
75
|
-
return res.json();
|
|
76
|
-
}
|
|
77
72
|
export async function runAsync(req, apiKey) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
73
|
+
try {
|
|
74
|
+
return await createSdkClient(apiKey).agent.queue(req);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
rethrowSdkError(error);
|
|
78
|
+
}
|
|
81
79
|
}
|
|
82
80
|
export async function* runStream(req, apiKey, signal) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const decoder = new TextDecoder();
|
|
89
|
-
let buffer = "";
|
|
90
|
-
while (true) {
|
|
91
|
-
const { done, value } = await reader.read();
|
|
92
|
-
if (done) {
|
|
93
|
-
// Flush remaining buffer — handles final event without trailing newline
|
|
94
|
-
for (const line of buffer.split("\n")) {
|
|
95
|
-
yield* parseSseLine(line);
|
|
96
|
-
}
|
|
97
|
-
break;
|
|
81
|
+
let stream = null;
|
|
82
|
+
try {
|
|
83
|
+
stream = await createSdkClient(apiKey).agent.stream(req, { signal });
|
|
84
|
+
for await (const event of stream) {
|
|
85
|
+
yield event;
|
|
98
86
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
rethrowSdkError(error);
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
if (stream) {
|
|
93
|
+
try {
|
|
94
|
+
await stream.close();
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// Ignore close errors — the original stream result/error already decided control flow.
|
|
98
|
+
}
|
|
104
99
|
}
|
|
105
100
|
}
|
|
106
101
|
}
|
|
107
|
-
// ── Run history ───────────────────────────────────────────────────────────────
|
|
108
102
|
export async function listRuns(opts, apiKey) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
params.set("cursor", opts.cursor);
|
|
116
|
-
const qs = params.size ? `?${params}` : "";
|
|
117
|
-
return getJson(`/v1/runs${qs}`, apiKey, AbortSignal.timeout(API_TIMEOUT_MS));
|
|
103
|
+
try {
|
|
104
|
+
return await createSdkClient(apiKey).runs.list(opts);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
rethrowSdkError(error);
|
|
108
|
+
}
|
|
118
109
|
}
|
|
119
110
|
export async function getRun(runId, apiKey) {
|
|
120
|
-
|
|
111
|
+
try {
|
|
112
|
+
return await createSdkClient(apiKey).runs.get(runId);
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
rethrowSdkError(error);
|
|
116
|
+
}
|
|
121
117
|
}
|
|
122
118
|
export async function cancelRun(runId, apiKey) {
|
|
123
|
-
|
|
124
|
-
|
|
119
|
+
try {
|
|
120
|
+
const response = await createSdkClient(apiKey).post(`/v1/runs/${encodeURIComponent(runId)}/cancel`, { json: {} });
|
|
121
|
+
return parseWithSchema(cancelRunResponseSchema, response, "Invalid cancel run response");
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
rethrowSdkError(error);
|
|
125
|
+
}
|
|
125
126
|
}
|
|
126
|
-
// ── Batch operations ──────────────────────────────────────────────────────────
|
|
127
127
|
export async function submitBatch(req, apiKey) {
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
try {
|
|
129
|
+
const response = await createSdkClient(apiKey).post("/v1/automation/run-batch", {
|
|
130
|
+
json: req,
|
|
131
|
+
});
|
|
132
|
+
return parseWithSchema(batchRunResponseSchema, response, "Invalid batch run response");
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
rethrowSdkError(error);
|
|
136
|
+
}
|
|
130
137
|
}
|
|
131
138
|
export async function getBatchRuns(runIds, apiKey) {
|
|
132
|
-
|
|
133
|
-
|
|
139
|
+
try {
|
|
140
|
+
const response = await createSdkClient(apiKey).post("/v1/runs/batch", {
|
|
141
|
+
json: { run_ids: runIds },
|
|
142
|
+
});
|
|
143
|
+
return parseWithSchema(batchGetResponseSchema, response, "Invalid batch get response");
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
rethrowSdkError(error);
|
|
147
|
+
}
|
|
134
148
|
}
|
|
135
149
|
export async function cancelBatchRuns(runIds, apiKey) {
|
|
136
|
-
|
|
137
|
-
|
|
150
|
+
try {
|
|
151
|
+
const response = await createSdkClient(apiKey).post("/v1/runs/batch/cancel", {
|
|
152
|
+
json: { run_ids: runIds },
|
|
153
|
+
});
|
|
154
|
+
return parseWithSchema(batchCancelResponseSchema, response, "Invalid batch cancel response");
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
rethrowSdkError(error);
|
|
158
|
+
}
|
|
138
159
|
}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -1,99 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
goal: string;
|
|
3
|
-
url: string;
|
|
4
|
-
}
|
|
5
|
-
export declare const RunStatus: {
|
|
6
|
-
readonly PENDING: "PENDING";
|
|
7
|
-
readonly RUNNING: "RUNNING";
|
|
8
|
-
readonly COMPLETED: "COMPLETED";
|
|
9
|
-
readonly FAILED: "FAILED";
|
|
10
|
-
readonly CANCELLED: "CANCELLED";
|
|
11
|
-
};
|
|
12
|
-
export type RunStatus = (typeof RunStatus)[keyof typeof RunStatus];
|
|
13
|
-
export declare const StreamEventType: {
|
|
14
|
-
readonly STARTED: "STARTED";
|
|
15
|
-
readonly STREAMING_URL: "STREAMING_URL";
|
|
16
|
-
readonly HEARTBEAT: "HEARTBEAT";
|
|
17
|
-
readonly PROGRESS: "PROGRESS";
|
|
18
|
-
readonly COMPLETE: "COMPLETE";
|
|
19
|
-
readonly ERROR: "ERROR";
|
|
20
|
-
};
|
|
21
|
-
export type StreamEventType = (typeof StreamEventType)[keyof typeof StreamEventType];
|
|
22
|
-
export interface RunResult {
|
|
23
|
-
run_id: string;
|
|
24
|
-
status: RunStatus;
|
|
25
|
-
result?: unknown;
|
|
26
|
-
error?: string;
|
|
27
|
-
}
|
|
28
|
-
/** Discriminated union of all real SSE event shapes from the API */
|
|
29
|
-
export type StreamEvent = {
|
|
30
|
-
type: typeof StreamEventType.STARTED;
|
|
31
|
-
run_id: string;
|
|
32
|
-
timestamp: string;
|
|
33
|
-
} | {
|
|
34
|
-
type: typeof StreamEventType.STREAMING_URL;
|
|
35
|
-
run_id: string;
|
|
36
|
-
streaming_url: string;
|
|
37
|
-
timestamp: string;
|
|
38
|
-
} | {
|
|
39
|
-
type: typeof StreamEventType.HEARTBEAT;
|
|
40
|
-
timestamp: string;
|
|
41
|
-
} | {
|
|
42
|
-
type: typeof StreamEventType.PROGRESS;
|
|
43
|
-
run_id: string;
|
|
44
|
-
purpose: string;
|
|
45
|
-
timestamp: string;
|
|
46
|
-
} | {
|
|
47
|
-
type: typeof StreamEventType.COMPLETE;
|
|
48
|
-
run_id: string;
|
|
49
|
-
status: RunStatus;
|
|
50
|
-
timestamp: string;
|
|
51
|
-
result?: unknown;
|
|
52
|
-
error?: string;
|
|
53
|
-
help_url?: string;
|
|
54
|
-
help_message?: string;
|
|
55
|
-
} | {
|
|
56
|
-
type: typeof StreamEventType.ERROR;
|
|
57
|
-
run_id?: string;
|
|
58
|
-
error: string;
|
|
59
|
-
timestamp: string;
|
|
60
|
-
};
|
|
61
|
-
export interface RunError {
|
|
62
|
-
message: string;
|
|
63
|
-
category: string;
|
|
64
|
-
retry_after: string | null;
|
|
65
|
-
help_url: string | null;
|
|
66
|
-
help_message: string | null;
|
|
67
|
-
}
|
|
68
|
-
export interface RunApiResponse {
|
|
69
|
-
run_id: string;
|
|
70
|
-
status: RunStatus;
|
|
71
|
-
goal: string;
|
|
72
|
-
created_at: string;
|
|
73
|
-
started_at: string | null;
|
|
74
|
-
finished_at: string | null;
|
|
75
|
-
num_of_steps: number;
|
|
76
|
-
result: unknown;
|
|
77
|
-
error: RunError | null;
|
|
78
|
-
streaming_url: string | null;
|
|
79
|
-
browser_config: {
|
|
80
|
-
proxy_enabled: boolean | null;
|
|
81
|
-
proxy_country_code: string | null;
|
|
82
|
-
} | null;
|
|
83
|
-
}
|
|
84
|
-
export interface ListRunsResponse {
|
|
85
|
-
data: RunApiResponse[];
|
|
86
|
-
pagination: {
|
|
87
|
-
total: number;
|
|
88
|
-
next_cursor: string | null;
|
|
89
|
-
has_more: boolean;
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
export interface ListRunsOptions {
|
|
93
|
-
status?: RunStatus;
|
|
94
|
-
limit?: number;
|
|
95
|
-
cursor?: string;
|
|
96
|
-
}
|
|
1
|
+
import type { Run, RunStatus } from "@tiny-fish/sdk";
|
|
97
2
|
export interface CancelRunResponse {
|
|
98
3
|
run_id: string;
|
|
99
4
|
status: RunStatus | string;
|
|
@@ -115,7 +20,7 @@ export interface BatchRunResponse {
|
|
|
115
20
|
} | null;
|
|
116
21
|
}
|
|
117
22
|
export interface BatchGetResponse {
|
|
118
|
-
data:
|
|
23
|
+
data: Run[];
|
|
119
24
|
not_found: string[] | null;
|
|
120
25
|
}
|
|
121
26
|
export interface BatchCancelResult {
|
package/dist/lib/types.js
CHANGED
|
@@ -1,18 +1 @@
|
|
|
1
|
-
|
|
2
|
-
// ── Run status enum ───────────────────────────────────────────────────────────
|
|
3
|
-
export const RunStatus = {
|
|
4
|
-
PENDING: "PENDING",
|
|
5
|
-
RUNNING: "RUNNING",
|
|
6
|
-
COMPLETED: "COMPLETED",
|
|
7
|
-
FAILED: "FAILED",
|
|
8
|
-
CANCELLED: "CANCELLED",
|
|
9
|
-
};
|
|
10
|
-
// ── SSE event types ───────────────────────────────────────────────────────────
|
|
11
|
-
export const StreamEventType = {
|
|
12
|
-
STARTED: "STARTED",
|
|
13
|
-
STREAMING_URL: "STREAMING_URL",
|
|
14
|
-
HEARTBEAT: "HEARTBEAT",
|
|
15
|
-
PROGRESS: "PROGRESS",
|
|
16
|
-
COMPLETE: "COMPLETE",
|
|
17
|
-
ERROR: "ERROR",
|
|
18
|
-
};
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiny-fish/cli",
|
|
3
|
-
"version": "0.1.3-next.
|
|
3
|
+
"version": "0.1.3-next.32",
|
|
4
4
|
"description": "TinyFish CLI — run web automations from your terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -23,8 +23,10 @@
|
|
|
23
23
|
"prepublishOnly": "npm run build"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
+
"@tiny-fish/sdk": "^0.0.7",
|
|
26
27
|
"commander": "^12.0.0",
|
|
27
|
-
"globals": "^17.4.0"
|
|
28
|
+
"globals": "^17.4.0",
|
|
29
|
+
"zod": "^4.3.6"
|
|
28
30
|
},
|
|
29
31
|
"devDependencies": {
|
|
30
32
|
"@eslint/js": "^10.0.1",
|