@relauts/spotcheck-service 1.0.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 (124) hide show
  1. package/LICENSE +661 -0
  2. package/NOTICE +19 -0
  3. package/README.md +169 -0
  4. package/dist/api/auth.d.ts +11 -0
  5. package/dist/api/auth.js +32 -0
  6. package/dist/api/auth.js.map +1 -0
  7. package/dist/api/history.d.ts +46 -0
  8. package/dist/api/history.js +172 -0
  9. package/dist/api/history.js.map +1 -0
  10. package/dist/api/saved-run.d.ts +35 -0
  11. package/dist/api/saved-run.js +234 -0
  12. package/dist/api/saved-run.js.map +1 -0
  13. package/dist/api/saved.d.ts +33 -0
  14. package/dist/api/saved.js +209 -0
  15. package/dist/api/saved.js.map +1 -0
  16. package/dist/api/server.d.ts +23 -0
  17. package/dist/api/server.js +852 -0
  18. package/dist/api/server.js.map +1 -0
  19. package/dist/computer-use/actions.d.ts +14 -0
  20. package/dist/computer-use/actions.js +212 -0
  21. package/dist/computer-use/actions.js.map +1 -0
  22. package/dist/computer-use/args.d.ts +11 -0
  23. package/dist/computer-use/args.js +74 -0
  24. package/dist/computer-use/args.js.map +1 -0
  25. package/dist/computer-use/cli.d.ts +1 -0
  26. package/dist/computer-use/cli.js +8 -0
  27. package/dist/computer-use/cli.js.map +1 -0
  28. package/dist/computer-use/client.d.ts +3 -0
  29. package/dist/computer-use/client.js +68 -0
  30. package/dist/computer-use/client.js.map +1 -0
  31. package/dist/computer-use/coords.d.ts +5 -0
  32. package/dist/computer-use/coords.js +21 -0
  33. package/dist/computer-use/coords.js.map +1 -0
  34. package/dist/computer-use/history.d.ts +11 -0
  35. package/dist/computer-use/history.js +59 -0
  36. package/dist/computer-use/history.js.map +1 -0
  37. package/dist/computer-use/index.d.ts +17 -0
  38. package/dist/computer-use/index.js +75 -0
  39. package/dist/computer-use/index.js.map +1 -0
  40. package/dist/computer-use/keys.d.ts +3 -0
  41. package/dist/computer-use/keys.js +50 -0
  42. package/dist/computer-use/keys.js.map +1 -0
  43. package/dist/computer-use/loop.d.ts +22 -0
  44. package/dist/computer-use/loop.js +90 -0
  45. package/dist/computer-use/loop.js.map +1 -0
  46. package/dist/computer-use/safety.d.ts +15 -0
  47. package/dist/computer-use/safety.js +45 -0
  48. package/dist/computer-use/safety.js.map +1 -0
  49. package/dist/computer-use/screenshot.d.ts +5 -0
  50. package/dist/computer-use/screenshot.js +16 -0
  51. package/dist/computer-use/screenshot.js.map +1 -0
  52. package/dist/computer-use/system-prompt.d.ts +11 -0
  53. package/dist/computer-use/system-prompt.js +41 -0
  54. package/dist/computer-use/system-prompt.js.map +1 -0
  55. package/dist/computer-use/types.d.ts +83 -0
  56. package/dist/computer-use/types.js +31 -0
  57. package/dist/computer-use/types.js.map +1 -0
  58. package/dist/playwright/actions.d.ts +81 -0
  59. package/dist/playwright/actions.js +170 -0
  60. package/dist/playwright/actions.js.map +1 -0
  61. package/dist/playwright/chromium.d.ts +10 -0
  62. package/dist/playwright/chromium.js +27 -0
  63. package/dist/playwright/chromium.js.map +1 -0
  64. package/dist/playwright/index.d.ts +2 -0
  65. package/dist/playwright/index.js +64 -0
  66. package/dist/playwright/index.js.map +1 -0
  67. package/dist/playwright/processed.d.ts +11 -0
  68. package/dist/playwright/processed.js +183 -0
  69. package/dist/playwright/processed.js.map +1 -0
  70. package/dist/playwright/session.d.ts +28 -0
  71. package/dist/playwright/session.js +165 -0
  72. package/dist/playwright/session.js.map +1 -0
  73. package/dist/shared/config.d.ts +38 -0
  74. package/dist/shared/config.js +227 -0
  75. package/dist/shared/config.js.map +1 -0
  76. package/dist/shared/cost.d.ts +15 -0
  77. package/dist/shared/cost.js +40 -0
  78. package/dist/shared/cost.js.map +1 -0
  79. package/dist/shared/logger.d.ts +4 -0
  80. package/dist/shared/logger.js +10 -0
  81. package/dist/shared/logger.js.map +1 -0
  82. package/dist/shared/main-module.d.ts +1 -0
  83. package/dist/shared/main-module.js +19 -0
  84. package/dist/shared/main-module.js.map +1 -0
  85. package/dist/shared/models.d.ts +12 -0
  86. package/dist/shared/models.js +40 -0
  87. package/dist/shared/models.js.map +1 -0
  88. package/dist/shared/telemetry.d.ts +9 -0
  89. package/dist/shared/telemetry.js +43 -0
  90. package/dist/shared/telemetry.js.map +1 -0
  91. package/files/model.json +26 -0
  92. package/files/system_prompt.txt +15 -0
  93. package/openapi.yaml +901 -0
  94. package/package.json +60 -0
  95. package/relauts-spotcheck-service-config.example.json +19 -0
  96. package/src/api/auth.ts +40 -0
  97. package/src/api/history.ts +251 -0
  98. package/src/api/saved-run.ts +346 -0
  99. package/src/api/saved.ts +275 -0
  100. package/src/api/server.ts +1198 -0
  101. package/src/computer-use/actions.ts +273 -0
  102. package/src/computer-use/args.ts +97 -0
  103. package/src/computer-use/cli.ts +8 -0
  104. package/src/computer-use/client.ts +81 -0
  105. package/src/computer-use/coords.ts +26 -0
  106. package/src/computer-use/history.ts +80 -0
  107. package/src/computer-use/index.ts +121 -0
  108. package/src/computer-use/keys.ts +54 -0
  109. package/src/computer-use/loop.ts +140 -0
  110. package/src/computer-use/safety.ts +59 -0
  111. package/src/computer-use/screenshot.ts +20 -0
  112. package/src/computer-use/system-prompt.ts +65 -0
  113. package/src/computer-use/types.ts +126 -0
  114. package/src/playwright/actions.ts +332 -0
  115. package/src/playwright/chromium.ts +30 -0
  116. package/src/playwright/index.ts +77 -0
  117. package/src/playwright/processed.ts +253 -0
  118. package/src/playwright/session.ts +220 -0
  119. package/src/shared/config.ts +320 -0
  120. package/src/shared/cost.ts +58 -0
  121. package/src/shared/logger.ts +9 -0
  122. package/src/shared/main-module.ts +20 -0
  123. package/src/shared/models.ts +62 -0
  124. package/src/shared/telemetry.ts +63 -0
@@ -0,0 +1,234 @@
1
+ import path from "node:path";
2
+ import { AgentRunError, runAgent } from "../computer-use/index.js";
3
+ import { launchLightChromium } from "../playwright/chromium.js";
4
+ import { SAVED_RUNS_SUBDIR, savedRunItemScreenshotDir, savedRunScreenshotStem } from "../playwright/processed.js";
5
+ import { createBrowserSession } from "../playwright/session.js";
6
+ import { createAutomationReporter } from "../shared/telemetry.js";
7
+ import { computeCostUsd, EMPTY_USAGE } from "../shared/cost.js";
8
+ import { logger } from "../shared/logger.js";
9
+ import { getModelEntry, loadModels } from "../shared/models.js";
10
+ import { createHistoryDocument, makeHistoryFileName, readHistoryFile, writeHistoryFile, } from "./history.js";
11
+ import { CREATE_DEFAULT_FILE, isCreateDefaultFileName, normalizeSavedFileName, readSavedFile, SavedNameError, } from "./saved.js";
12
+ export class SavedRunBusyError extends Error {
13
+ constructor(message = "Saved run already running for this file") {
14
+ super(message);
15
+ this.name = "SavedRunBusyError";
16
+ }
17
+ }
18
+ export class SavedRunLimitError extends Error {
19
+ constructor(message = "Saved run limit reached") {
20
+ super(message);
21
+ this.name = "SavedRunLimitError";
22
+ }
23
+ }
24
+ export class SavedRunNotRunningError extends Error {
25
+ constructor(message = "No running saved execution") {
26
+ super(message);
27
+ this.name = "SavedRunNotRunningError";
28
+ }
29
+ }
30
+ export class SavedRunFinishedError extends Error {
31
+ constructor(message = "Saved run already finished") {
32
+ super(message);
33
+ this.name = "SavedRunFinishedError";
34
+ }
35
+ }
36
+ function errorMessage(error) {
37
+ return error instanceof Error ? error.message : String(error);
38
+ }
39
+ export async function denySavedRunSafety() {
40
+ throw new AgentRunError("Safety confirmation denied", EMPTY_USAGE);
41
+ }
42
+ function patchItem(document, sequence, patch) {
43
+ return {
44
+ ...document,
45
+ current: sequence,
46
+ items: document.items.map((item) => item.sequence === sequence
47
+ ? {
48
+ sequence: item.sequence,
49
+ id: item.id,
50
+ prompt: item.prompt,
51
+ model: item.model,
52
+ status: patch.status,
53
+ ...(patch.resultText !== undefined ? { resultText: patch.resultText } : {}),
54
+ ...(patch.costUsd !== undefined ? { costUsd: patch.costUsd } : {}),
55
+ ...(patch.error !== undefined ? { error: patch.error } : {}),
56
+ }
57
+ : item),
58
+ };
59
+ }
60
+ export function createSavedRunManager(deps) {
61
+ const createSession = deps.createSession ??
62
+ ((screenshotDir) => createBrowserSession({
63
+ launch: launchLightChromium,
64
+ screenshotDir,
65
+ }));
66
+ const reportAutomation = deps.reportAutomation ?? createAutomationReporter(deps.config);
67
+ const active = new Map();
68
+ async function persist(historyFile, document) {
69
+ await writeHistoryFile(historyFile, document, deps.historyDir);
70
+ return document;
71
+ }
72
+ async function costFor(model, usage) {
73
+ try {
74
+ const models = await loadModels();
75
+ return computeCostUsd(usage ?? EMPTY_USAGE, getModelEntry(model, models));
76
+ }
77
+ catch {
78
+ return 0;
79
+ }
80
+ }
81
+ function callTask(task, model, session, screenshotDir, extras) {
82
+ if (deps.runTask) {
83
+ return deps.runTask(task, model, session, extras, screenshotDir);
84
+ }
85
+ return runAgent(task, { ...deps.config, processedDir: screenshotDir }, denySavedRunSafety, session, model, { ...extras, confirmSafety: extras.confirmSafety ?? denySavedRunSafety });
86
+ }
87
+ function findActiveByHistoryFile(historyFile) {
88
+ for (const run of active.values()) {
89
+ if (run.historyFile === historyFile) {
90
+ return run;
91
+ }
92
+ }
93
+ return undefined;
94
+ }
95
+ async function execute(savedFileName, historyFile, items, session, abort) {
96
+ let document = await readHistoryFile(historyFile, deps.historyDir);
97
+ try {
98
+ await session.ensurePage(deps.config);
99
+ for (const item of items) {
100
+ if (abort.signal.aborted) {
101
+ document = await persist(historyFile, { ...document, status: "stopped" });
102
+ return;
103
+ }
104
+ if (!item.prompt.trim()) {
105
+ document = await persist(historyFile, patchItem(document, item.sequence, { status: "skipped" }));
106
+ continue;
107
+ }
108
+ document = await persist(historyFile, patchItem(document, item.sequence, { status: "running" }));
109
+ try {
110
+ const startedAt = new Date();
111
+ const result = await callTask(item.prompt, item.model, session, savedRunItemScreenshotDir(deps.processedDir, historyFile, item.sequence, item.id), {
112
+ signal: abort.signal,
113
+ confirmSafety: denySavedRunSafety,
114
+ });
115
+ if (abort.signal.aborted) {
116
+ document = await persist(historyFile, { ...document, status: "stopped" });
117
+ return;
118
+ }
119
+ reportAutomation(startedAt, new Date());
120
+ const costUsd = await costFor(item.model, result.usage);
121
+ document = await persist(historyFile, patchItem(document, item.sequence, {
122
+ status: "done",
123
+ resultText: result.text,
124
+ costUsd,
125
+ }));
126
+ }
127
+ catch (error) {
128
+ if (abort.signal.aborted || (error instanceof AgentRunError && error.message === "Agent stopped")) {
129
+ document = await persist(historyFile, { ...document, status: "stopped" });
130
+ return;
131
+ }
132
+ const usage = error instanceof AgentRunError ? error.usage : EMPTY_USAGE;
133
+ const costUsd = await costFor(item.model, usage);
134
+ document = await persist(historyFile, {
135
+ ...patchItem(document, item.sequence, {
136
+ status: "error",
137
+ error: errorMessage(error),
138
+ costUsd,
139
+ }),
140
+ status: "error",
141
+ });
142
+ return;
143
+ }
144
+ }
145
+ if (document.status === "running" && !abort.signal.aborted) {
146
+ await persist(historyFile, { ...document, status: "done", current: document.total });
147
+ }
148
+ else if (abort.signal.aborted && document.status === "running") {
149
+ await persist(historyFile, { ...document, status: "stopped" });
150
+ }
151
+ }
152
+ catch (error) {
153
+ logger.error("Saved run failed", error);
154
+ if (document.status === "running") {
155
+ await persist(historyFile, {
156
+ ...document,
157
+ status: abort.signal.aborted ? "stopped" : "error",
158
+ });
159
+ }
160
+ }
161
+ finally {
162
+ try {
163
+ await session.close();
164
+ }
165
+ catch (error) {
166
+ logger.error("Failed to close saved-run browser", error);
167
+ }
168
+ const current = active.get(savedFileName);
169
+ if (current?.historyFile === historyFile) {
170
+ active.delete(savedFileName);
171
+ }
172
+ }
173
+ }
174
+ return {
175
+ async start(savedFileName) {
176
+ if (isCreateDefaultFileName(savedFileName)) {
177
+ throw new SavedNameError(`${CREATE_DEFAULT_FILE} is reserved`);
178
+ }
179
+ const saved = await readSavedFile(savedFileName, deps.savedDir);
180
+ if (active.has(saved.fileName)) {
181
+ throw new SavedRunBusyError();
182
+ }
183
+ if (active.size >= deps.config.maxSavedRuns) {
184
+ throw new SavedRunLimitError();
185
+ }
186
+ const historyFile = makeHistoryFileName(saved.fileName, deps.now?.() ?? new Date());
187
+ const screenshotDir = path.join(deps.processedDir, SAVED_RUNS_SUBDIR, savedRunScreenshotStem(historyFile));
188
+ const session = createSession(screenshotDir);
189
+ const abort = new AbortController();
190
+ const run = {
191
+ savedFileName: saved.fileName,
192
+ historyFile,
193
+ abort,
194
+ session,
195
+ done: Promise.resolve(),
196
+ };
197
+ active.set(saved.fileName, run);
198
+ try {
199
+ await persist(historyFile, createHistoryDocument(saved.fileName, saved.items));
200
+ }
201
+ catch (error) {
202
+ active.delete(saved.fileName);
203
+ await session.close();
204
+ throw error;
205
+ }
206
+ run.done = execute(saved.fileName, historyFile, saved.items, session, abort);
207
+ return historyFile;
208
+ },
209
+ async stop(historyFileName) {
210
+ const name = normalizeSavedFileName(historyFileName);
211
+ const current = findActiveByHistoryFile(name);
212
+ if (!current) {
213
+ const document = await readHistoryFile(name, deps.historyDir);
214
+ if (document.status !== "running") {
215
+ throw new SavedRunFinishedError();
216
+ }
217
+ throw new SavedRunNotRunningError();
218
+ }
219
+ current.abort.abort();
220
+ await current.done;
221
+ },
222
+ async close() {
223
+ const runs = [...active.values()];
224
+ for (const run of runs) {
225
+ run.abort.abort();
226
+ }
227
+ await Promise.all(runs.map((run) => run.done));
228
+ },
229
+ listRunning() {
230
+ return [...active.keys()].sort((left, right) => left.localeCompare(right));
231
+ },
232
+ };
233
+ }
234
+ //# sourceMappingURL=saved-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saved-run.js","sourceRoot":"","sources":["../../src/api/saved-run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ export declare const SAVED_DIR: string;
2
+ export declare const CREATE_DEFAULT_FILE = "create-default.json";
3
+ export interface SavedPromptItem {
4
+ readonly sequence: number;
5
+ readonly id: string;
6
+ readonly prompt: string;
7
+ readonly model: string;
8
+ readonly costUsd?: number;
9
+ readonly resultText?: string;
10
+ readonly sessionReset?: boolean;
11
+ readonly error?: string;
12
+ }
13
+ export declare class SavedNameError extends Error {
14
+ }
15
+ export declare class SavedExistsError extends Error {
16
+ }
17
+ export declare class SavedNotFoundError extends Error {
18
+ }
19
+ export declare function normalizeSavedFileName(raw: string): string;
20
+ export declare function isCreateDefaultFileName(fileName: string): boolean;
21
+ export declare function uniqueSavedItems(items: readonly SavedPromptItem[]): SavedPromptItem[];
22
+ export declare function parseSavedItems(value: unknown): SavedPromptItem[];
23
+ export declare function parseCreateItems(value: unknown): SavedPromptItem[];
24
+ export declare function listSavedFiles(directory?: string): Promise<string[]>;
25
+ export declare function writeSavedFile(fileName: string, items: readonly SavedPromptItem[], directory?: string): Promise<string>;
26
+ export declare function upsertSavedFile(fileName: string, items: readonly SavedPromptItem[], directory?: string): Promise<string>;
27
+ export declare function overwriteSavedFile(fileName: string, items: readonly SavedPromptItem[], directory?: string): Promise<string>;
28
+ export declare function deleteSavedFile(fileName: string, directory?: string): Promise<string>;
29
+ export declare function ensureCreateDefaultFile(directory?: string): Promise<void>;
30
+ export declare function readSavedFile(fileName: string, directory?: string): Promise<{
31
+ fileName: string;
32
+ items: SavedPromptItem[];
33
+ }>;
@@ -0,0 +1,209 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ export const SAVED_DIR = path.resolve(process.cwd(), "saved");
4
+ export const CREATE_DEFAULT_FILE = "create-default.json";
5
+ export class SavedNameError extends Error {
6
+ }
7
+ export class SavedExistsError extends Error {
8
+ }
9
+ export class SavedNotFoundError extends Error {
10
+ }
11
+ function isSavedPromptItem(value, requirePrompt) {
12
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
13
+ return false;
14
+ }
15
+ const item = value;
16
+ if (typeof item.sequence !== "number" ||
17
+ !Number.isInteger(item.sequence) ||
18
+ item.sequence <= 0 ||
19
+ typeof item.id !== "string" ||
20
+ item.id.trim().length === 0 ||
21
+ typeof item.prompt !== "string" ||
22
+ (requirePrompt && item.prompt.trim().length === 0) ||
23
+ typeof item.model !== "string" ||
24
+ item.model.trim().length === 0) {
25
+ return false;
26
+ }
27
+ if (item.costUsd !== undefined && (typeof item.costUsd !== "number" || !Number.isFinite(item.costUsd))) {
28
+ return false;
29
+ }
30
+ if (item.resultText !== undefined && typeof item.resultText !== "string") {
31
+ return false;
32
+ }
33
+ if (item.sessionReset !== undefined && typeof item.sessionReset !== "boolean") {
34
+ return false;
35
+ }
36
+ if (item.error !== undefined && typeof item.error !== "string") {
37
+ return false;
38
+ }
39
+ return true;
40
+ }
41
+ export function normalizeSavedFileName(raw) {
42
+ const trimmed = raw.trim();
43
+ if (!trimmed) {
44
+ throw new SavedNameError("File name is required");
45
+ }
46
+ const withExt = trimmed.toLowerCase().endsWith(".json") ? `${trimmed.slice(0, -5)}.json` : `${trimmed}.json`;
47
+ if (withExt !== path.basename(withExt) || withExt.includes("..") || withExt === ".json") {
48
+ throw new SavedNameError("File name must not contain a path");
49
+ }
50
+ const stem = withExt.slice(0, -5);
51
+ if (!/^[a-zA-Z0-9._ -]+$/.test(stem) || stem.trim().length === 0) {
52
+ throw new SavedNameError("File name can only use letters, numbers, space, dot, dash, and underscore");
53
+ }
54
+ return withExt;
55
+ }
56
+ export function isCreateDefaultFileName(fileName) {
57
+ return normalizeSavedFileName(fileName).toLowerCase() === CREATE_DEFAULT_FILE;
58
+ }
59
+ export function uniqueSavedItems(items) {
60
+ const byId = new Map();
61
+ for (const item of items) {
62
+ byId.set(item.id, item);
63
+ }
64
+ return [...byId.values()]
65
+ .sort((left, right) => left.sequence - right.sequence)
66
+ .map((item, index) => ({
67
+ sequence: index + 1,
68
+ id: item.id,
69
+ prompt: item.prompt.trim(),
70
+ model: item.model.trim(),
71
+ ...(typeof item.costUsd === "number" ? { costUsd: item.costUsd } : {}),
72
+ ...(item.resultText ? { resultText: item.resultText } : {}),
73
+ ...(item.sessionReset ? { sessionReset: true } : {}),
74
+ ...(item.error ? { error: item.error } : {}),
75
+ }));
76
+ }
77
+ export function parseSavedItems(value) {
78
+ if (!Array.isArray(value) || value.length === 0) {
79
+ throw new SavedNameError("items must be a non-empty array");
80
+ }
81
+ if (!value.every((item) => isSavedPromptItem(item, true))) {
82
+ throw new SavedNameError("items has invalid saved prompt entries");
83
+ }
84
+ return uniqueSavedItems(value);
85
+ }
86
+ export function parseCreateItems(value) {
87
+ if (!Array.isArray(value)) {
88
+ throw new SavedNameError("items must be an array");
89
+ }
90
+ if (value.length === 0) {
91
+ return [];
92
+ }
93
+ if (!value.every((item) => isSavedPromptItem(item, false))) {
94
+ throw new SavedNameError("items has invalid saved prompt entries");
95
+ }
96
+ return uniqueSavedItems(value);
97
+ }
98
+ export async function listSavedFiles(directory = SAVED_DIR) {
99
+ let names;
100
+ try {
101
+ names = await fs.readdir(directory);
102
+ }
103
+ catch (error) {
104
+ if (error.code === "ENOENT") {
105
+ return [];
106
+ }
107
+ throw error;
108
+ }
109
+ const jsonNames = names.filter((name) => name.toLowerCase().endsWith(".json"));
110
+ jsonNames.sort((left, right) => left.localeCompare(right));
111
+ return jsonNames;
112
+ }
113
+ async function writeJsonFile(directory, name, items, flag) {
114
+ await fs.mkdir(directory, { recursive: true });
115
+ await fs.writeFile(path.join(directory, name), `${JSON.stringify(items, null, 2)}\n`, { flag });
116
+ }
117
+ export async function writeSavedFile(fileName, items, directory = SAVED_DIR) {
118
+ const name = normalizeSavedFileName(fileName);
119
+ if (name.toLowerCase() === CREATE_DEFAULT_FILE) {
120
+ throw new SavedNameError(`${CREATE_DEFAULT_FILE} is reserved`);
121
+ }
122
+ const uniqueItems = uniqueSavedItems(items);
123
+ if (uniqueItems.length === 0) {
124
+ throw new SavedNameError("items must be a non-empty array");
125
+ }
126
+ const existing = await listSavedFiles(directory);
127
+ if (existing.some((entry) => entry.toLowerCase() === name.toLowerCase())) {
128
+ throw new SavedExistsError(`File already exists: ${name}`);
129
+ }
130
+ await writeJsonFile(directory, name, uniqueItems, "wx");
131
+ return name;
132
+ }
133
+ export async function upsertSavedFile(fileName, items, directory = SAVED_DIR) {
134
+ const name = normalizeSavedFileName(fileName);
135
+ await writeJsonFile(directory, name, uniqueSavedItems(items), "w");
136
+ return name;
137
+ }
138
+ export async function overwriteSavedFile(fileName, items, directory = SAVED_DIR) {
139
+ const name = normalizeSavedFileName(fileName);
140
+ if (name.toLowerCase() === CREATE_DEFAULT_FILE) {
141
+ throw new SavedNameError(`${CREATE_DEFAULT_FILE} is reserved`);
142
+ }
143
+ const filePath = path.join(directory, name);
144
+ try {
145
+ await fs.access(filePath);
146
+ }
147
+ catch (error) {
148
+ if (error.code === "ENOENT") {
149
+ throw new SavedNotFoundError(`Saved file not found: ${name}`);
150
+ }
151
+ throw error;
152
+ }
153
+ const uniqueItems = uniqueSavedItems(items);
154
+ if (uniqueItems.length === 0) {
155
+ throw new SavedNameError("items must be a non-empty array");
156
+ }
157
+ await writeJsonFile(directory, name, uniqueItems, "w");
158
+ return name;
159
+ }
160
+ export async function deleteSavedFile(fileName, directory = SAVED_DIR) {
161
+ const name = normalizeSavedFileName(fileName);
162
+ if (name.toLowerCase() === CREATE_DEFAULT_FILE) {
163
+ throw new SavedNameError(`${CREATE_DEFAULT_FILE} is reserved`);
164
+ }
165
+ try {
166
+ await fs.unlink(path.join(directory, name));
167
+ }
168
+ catch (error) {
169
+ if (error.code === "ENOENT") {
170
+ throw new SavedNotFoundError(`Saved file not found: ${name}`);
171
+ }
172
+ throw error;
173
+ }
174
+ return name;
175
+ }
176
+ export async function ensureCreateDefaultFile(directory = SAVED_DIR) {
177
+ await fs.mkdir(directory, { recursive: true });
178
+ const filePath = path.join(directory, CREATE_DEFAULT_FILE);
179
+ try {
180
+ await fs.access(filePath);
181
+ }
182
+ catch {
183
+ await writeJsonFile(directory, CREATE_DEFAULT_FILE, [], "wx");
184
+ }
185
+ }
186
+ export async function readSavedFile(fileName, directory = SAVED_DIR) {
187
+ const name = normalizeSavedFileName(fileName);
188
+ const filePath = path.join(directory, name);
189
+ let raw;
190
+ try {
191
+ raw = await fs.readFile(filePath, "utf8");
192
+ }
193
+ catch (error) {
194
+ if (error.code === "ENOENT") {
195
+ throw new SavedNotFoundError(`Saved file not found: ${name}`);
196
+ }
197
+ throw error;
198
+ }
199
+ let parsed;
200
+ try {
201
+ parsed = JSON.parse(raw);
202
+ }
203
+ catch {
204
+ throw new SavedNameError("Saved file is not valid JSON");
205
+ }
206
+ const items = name.toLowerCase() === CREATE_DEFAULT_FILE ? parseCreateItems(parsed) : parseSavedItems(parsed);
207
+ return { fileName: name, items };
208
+ }
209
+ //# sourceMappingURL=saved.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saved.js","sourceRoot":"","sources":["../../src/api/saved.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ import http from "node:http";
3
+ import { type AgentRunExtras, type AgentRunResult } from "../computer-use/index.js";
4
+ import { type BrowserSession } from "../playwright/session.js";
5
+ import { type AppConfig } from "../shared/config.js";
6
+ import { type AutomationReporter } from "../shared/telemetry.js";
7
+ import { type SavedRunTask } from "./saved-run.js";
8
+ export type AgentRunner = (task: string, model: string, extras?: AgentRunExtras) => Promise<AgentRunResult>;
9
+ export interface ServiceServerDeps {
10
+ readonly runTask?: AgentRunner;
11
+ readonly session?: BrowserSession;
12
+ readonly savedDir?: string;
13
+ readonly processedDir?: string;
14
+ readonly historyDir?: string;
15
+ readonly savedRunTask?: SavedRunTask;
16
+ readonly createSavedRunSession?: (screenshotDir: string) => BrowserSession;
17
+ readonly apiToken?: string;
18
+ readonly corsOrigins?: readonly string[];
19
+ readonly config?: AppConfig;
20
+ readonly reportAutomation?: AutomationReporter;
21
+ }
22
+ export declare function startServiceServer(port?: number, deps?: ServiceServerDeps): Promise<http.Server>;
23
+ export declare function closeServiceServer(server: http.Server | undefined): Promise<void>;