loop-sdk 0.1.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 (62) hide show
  1. package/README.md +591 -0
  2. package/dist/agent.d.ts +31 -0
  3. package/dist/agent.d.ts.map +1 -0
  4. package/dist/agent.js +48 -0
  5. package/dist/agent.js.map +1 -0
  6. package/dist/checkpoint.d.ts +16 -0
  7. package/dist/checkpoint.d.ts.map +1 -0
  8. package/dist/checkpoint.js +20 -0
  9. package/dist/checkpoint.js.map +1 -0
  10. package/dist/claude-cli.d.ts +35 -0
  11. package/dist/claude-cli.d.ts.map +1 -0
  12. package/dist/claude-cli.js +135 -0
  13. package/dist/claude-cli.js.map +1 -0
  14. package/dist/context.d.ts +53 -0
  15. package/dist/context.d.ts.map +1 -0
  16. package/dist/context.js +95 -0
  17. package/dist/context.js.map +1 -0
  18. package/dist/events.d.ts +111 -0
  19. package/dist/events.d.ts.map +1 -0
  20. package/dist/events.js +53 -0
  21. package/dist/events.js.map +1 -0
  22. package/dist/flow.d.ts +36 -0
  23. package/dist/flow.d.ts.map +1 -0
  24. package/dist/flow.js +62 -0
  25. package/dist/flow.js.map +1 -0
  26. package/dist/index.d.ts +26 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +14 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/logger.d.ts +37 -0
  31. package/dist/logger.d.ts.map +1 -0
  32. package/dist/logger.js +64 -0
  33. package/dist/logger.js.map +1 -0
  34. package/dist/loop.d.ts +199 -0
  35. package/dist/loop.d.ts.map +1 -0
  36. package/dist/loop.js +403 -0
  37. package/dist/loop.js.map +1 -0
  38. package/dist/loopfile.d.ts +82 -0
  39. package/dist/loopfile.d.ts.map +1 -0
  40. package/dist/loopfile.js +235 -0
  41. package/dist/loopfile.js.map +1 -0
  42. package/dist/mcp/server.d.ts +26 -0
  43. package/dist/mcp/server.d.ts.map +1 -0
  44. package/dist/mcp/server.js +160 -0
  45. package/dist/mcp/server.js.map +1 -0
  46. package/dist/notify.d.ts +43 -0
  47. package/dist/notify.d.ts.map +1 -0
  48. package/dist/notify.js +68 -0
  49. package/dist/notify.js.map +1 -0
  50. package/dist/plugins/retry.d.ts +41 -0
  51. package/dist/plugins/retry.d.ts.map +1 -0
  52. package/dist/plugins/retry.js +53 -0
  53. package/dist/plugins/retry.js.map +1 -0
  54. package/dist/providers/playwright.d.ts +38 -0
  55. package/dist/providers/playwright.d.ts.map +1 -0
  56. package/dist/providers/playwright.js +155 -0
  57. package/dist/providers/playwright.js.map +1 -0
  58. package/dist/session.d.ts +43 -0
  59. package/dist/session.d.ts.map +1 -0
  60. package/dist/session.js +26 -0
  61. package/dist/session.js.map +1 -0
  62. package/package.json +78 -0
package/dist/loop.js ADDED
@@ -0,0 +1,403 @@
1
+ import { Context } from './context.js';
2
+ import { Logger } from './logger.js';
3
+ import { readCheckpoint, writeCheckpoint, deleteCheckpoint, checkpointExists, } from './checkpoint.js';
4
+ import { Emitter } from './events.js';
5
+ export class Loop {
6
+ name;
7
+ _steps;
8
+ _plugins;
9
+ _emitter;
10
+ constructor(name) {
11
+ this.name = name;
12
+ this._steps = [];
13
+ this._plugins = [];
14
+ this._emitter = new Emitter();
15
+ }
16
+ step(name, fn, opts = {}) {
17
+ this._steps.push({ name, fn, opts });
18
+ return this;
19
+ }
20
+ /**
21
+ * Add a parallel step — all named functions run concurrently.
22
+ * The step only completes when every sub-step resolves.
23
+ * Each sub-step's return value is stored in ctx under its name.
24
+ *
25
+ * @example
26
+ * loop.parallel('gather', {
27
+ * 'fetch-prices': async (ctx) => { ctx.set('fetch-prices', await getPrice()) },
28
+ * 'fetch-reviews': async (ctx) => { ctx.set('fetch-reviews', await getReviews()) },
29
+ * })
30
+ *
31
+ * loop.step('summarize', async (ctx) => {
32
+ * const prices = ctx.get('fetch-prices')
33
+ * const reviews = ctx.get('fetch-reviews')
34
+ * })
35
+ */
36
+ parallel(name, fns, opts = {}) {
37
+ const parallelFn = async (ctx) => {
38
+ await Promise.all(Object.entries(fns).map(async ([subName, fn]) => {
39
+ const result = await fn(ctx);
40
+ if (result !== undefined)
41
+ ctx.set(subName, result);
42
+ }));
43
+ };
44
+ this._steps.push({ name, fn: parallelFn, opts });
45
+ return this;
46
+ }
47
+ /**
48
+ * Run multiple loops concurrently and return all results.
49
+ *
50
+ * @example
51
+ * const logs = await Loop.runAll([
52
+ * { loop: researchLoop, session: sessionA },
53
+ * { loop: reportLoop, session: sessionB },
54
+ * ])
55
+ */
56
+ static async runAll(jobs) {
57
+ const handles = jobs.map(({ loop, ...opts }) => loop.runBackground(opts));
58
+ return Promise.all(handles.map(h => h.wait()));
59
+ }
60
+ use(plugin) {
61
+ this._plugins.push(plugin);
62
+ return this;
63
+ }
64
+ on(event, listener) {
65
+ this._emitter.on(event, listener);
66
+ return this;
67
+ }
68
+ off(event, listener) {
69
+ this._emitter.off(event, listener);
70
+ return this;
71
+ }
72
+ /** Run steps against an existing Context — used by sub() and each(). */
73
+ async runWith(ctx) {
74
+ const loopStartMs = Date.now();
75
+ let stepsCompleted = 0;
76
+ let loopStatus = 'completed';
77
+ await this._emitter.emit('loop:start', {
78
+ loop: this.name, session: ctx.session.id, totalSteps: this._steps.length,
79
+ });
80
+ try {
81
+ for (let i = 0; i < this._steps.length; i++) {
82
+ const { name, fn, opts } = this._steps[i];
83
+ const startMs = Date.now();
84
+ process.stdout.write(` [${i + 1}/${this._steps.length}] ${name} ... `);
85
+ await this._emitter.emit('step:start', { loop: this.name, step: name, index: i, total: this._steps.length });
86
+ try {
87
+ await fn(ctx);
88
+ console.log('ok');
89
+ stepsCompleted++;
90
+ await this._emitter.emit('step:complete', { loop: this.name, step: name, index: i, durationMs: Date.now() - startMs });
91
+ }
92
+ catch (err) {
93
+ const error = err instanceof Error ? err : new Error(String(err));
94
+ console.log(`ERROR: ${error.message}`);
95
+ await this._emitter.emit('step:error', { loop: this.name, step: name, index: i, error, durationMs: Date.now() - startMs });
96
+ const recovered = await this._runErrorHooks(error, { name, index: i }, ctx);
97
+ if (recovered) {
98
+ i--;
99
+ continue;
100
+ }
101
+ loopStatus = 'failed';
102
+ throw error;
103
+ }
104
+ }
105
+ }
106
+ finally {
107
+ await this._emitter.emit('loop:complete', {
108
+ loop: this.name, session: ctx.session.id,
109
+ status: loopStatus, durationMs: Date.now() - loopStartMs, stepsCompleted,
110
+ });
111
+ }
112
+ }
113
+ /** Full run: create a fresh Context, execute all steps, return a run log. */
114
+ async run({ session, vars = {}, logDir = null, startAt = null, stopAt = null, checkpointFile = null, resumeFrom = null, keepCheckpointOnSuccess = false, onError, signal = null, }) {
115
+ const logger = new Logger(logDir, this.name, session.id);
116
+ const ctx = new Context({ session, vars, logger, checkpointFile, emitter: this._emitter, signal });
117
+ ctx._loopName = this.name;
118
+ ctx._checkpointFile = checkpointFile;
119
+ // ── resume from checkpoint ───────────────────────────────────────────────
120
+ let resumeIndex = -1;
121
+ let checkpoint = null;
122
+ if (resumeFrom && checkpointExists(resumeFrom)) {
123
+ checkpoint = readCheckpoint(resumeFrom);
124
+ resumeIndex = checkpoint.lastCompletedIndex;
125
+ for (const [k, v] of Object.entries(checkpoint.state))
126
+ ctx.set(k, v);
127
+ ctx._completedSteps = [...checkpoint.completedSteps];
128
+ ctx._lastCompletedIndex = checkpoint.lastCompletedIndex;
129
+ console.log(`\nResuming: ${this.name} (from step ${resumeIndex + 2} of ${this._steps.length})`);
130
+ console.log(`Restored: ${Object.keys(checkpoint.state).length} state keys from ${resumeFrom}`);
131
+ }
132
+ else {
133
+ console.log(`\nLoop: ${this.name}`);
134
+ }
135
+ console.log(`Session: ${session.id}`);
136
+ console.log(`Steps: ${this._steps.length}`);
137
+ console.log('---');
138
+ const loopStartMs = Date.now();
139
+ const runLog = {
140
+ loop: this.name,
141
+ session: session.id,
142
+ startedAt: new Date().toISOString(),
143
+ finishedAt: '',
144
+ status: 'running',
145
+ steps: [],
146
+ ...(resumeFrom ? { resumedFrom: resumeFrom } : {}),
147
+ };
148
+ await this._emitter.emit('loop:start', {
149
+ loop: this.name,
150
+ session: session.id,
151
+ totalSteps: this._steps.length,
152
+ ...(resumeFrom ? { resumedFrom: resumeFrom } : {}),
153
+ });
154
+ for (let i = 0; i < this._steps.length; i++) {
155
+ const { name, fn, opts } = this._steps[i];
156
+ // Skip steps already completed in a prior run
157
+ if (i <= resumeIndex) {
158
+ console.log(`[${i + 1}/${this._steps.length}] ${name} ... skipped (completed in prior run)`);
159
+ await this._emitter.emit('step:skip', { loop: this.name, step: name, index: i, reason: 'checkpoint' });
160
+ runLog.steps.push({ name, status: 'skipped' });
161
+ continue;
162
+ }
163
+ // Check for cancellation before starting each step
164
+ if (signal?.aborted) {
165
+ console.log(`[${i + 1}/${this._steps.length}] ${name} ... cancelled`);
166
+ runLog.status = 'cancelled';
167
+ break;
168
+ }
169
+ if (startAt != null && i + 1 < startAt) {
170
+ console.log(`[${i + 1}/${this._steps.length}] ${name} ... skipped`);
171
+ await this._emitter.emit('step:skip', { loop: this.name, step: name, index: i, reason: 'range' });
172
+ continue;
173
+ }
174
+ if (stopAt != null && i + 1 > stopAt)
175
+ break;
176
+ const stepStartMs = Date.now();
177
+ process.stdout.write(`[${i + 1}/${this._steps.length}] ${name} ... `);
178
+ logger.stepStart(name);
179
+ await this._emitter.emit('step:start', { loop: this.name, step: name, index: i, total: this._steps.length });
180
+ // ── attempt the step ─────────────────────────────────────────────────
181
+ let stepSucceeded = false;
182
+ let lastErr = null;
183
+ try {
184
+ await fn(ctx);
185
+ stepSucceeded = true;
186
+ }
187
+ catch (err) {
188
+ lastErr = err instanceof Error ? err : new Error(String(err));
189
+ }
190
+ // ── step-level retries ───────────────────────────────────────────────
191
+ if (!stepSucceeded && (opts.retries ?? 0) > 0) {
192
+ for (let attempt = 0; attempt < (opts.retries ?? 0); attempt++) {
193
+ const wait = computeDelay(attempt, opts.retryDelay ?? 0, opts.retryBackoff ?? 'flat');
194
+ const label = `attempt ${attempt + 2}/${(opts.retries ?? 0) + 1}`;
195
+ process.stdout.write(wait > 0 ? `\n retrying in ${wait}ms (${label}) ... ` : `\n retrying (${label}) ... `);
196
+ if (wait > 0)
197
+ await sleep(wait);
198
+ await this._emitter.emit('step:retry', { loop: this.name, step: name, index: i, plugin: 'step.retries' });
199
+ try {
200
+ await fn(ctx);
201
+ stepSucceeded = true;
202
+ break;
203
+ }
204
+ catch (retryErr) {
205
+ lastErr = retryErr instanceof Error ? retryErr : new Error(String(retryErr));
206
+ }
207
+ }
208
+ }
209
+ // ── plugin onStepError hooks ─────────────────────────────────────────
210
+ if (!stepSucceeded) {
211
+ const pluginRetry = await this._runErrorHooks(lastErr, { name, index: i }, ctx);
212
+ if (pluginRetry) {
213
+ i--;
214
+ continue;
215
+ }
216
+ }
217
+ // ── step-level onError fallback ──────────────────────────────────────
218
+ if (!stepSucceeded && opts.onError) {
219
+ try {
220
+ process.stdout.write(`\n running fallback for "${name}" ... `);
221
+ await opts.onError(lastErr, ctx);
222
+ stepSucceeded = true;
223
+ console.log('ok (fallback)');
224
+ const durationMs = Date.now() - stepStartMs;
225
+ logger.stepDone('fallback');
226
+ runLog.steps.push({ name, status: 'recovered', error: lastErr.message });
227
+ await this._emitter.emit('step:complete', { loop: this.name, step: name, index: i, durationMs });
228
+ }
229
+ catch (fallbackErr) {
230
+ lastErr = fallbackErr instanceof Error ? fallbackErr : new Error(String(fallbackErr));
231
+ console.log(`ERROR in fallback: ${lastErr.message}`);
232
+ }
233
+ }
234
+ // ── skipOnError ──────────────────────────────────────────────────────
235
+ if (!stepSucceeded && opts.skipOnError) {
236
+ console.log(`skipped (${lastErr.message})`);
237
+ await this._emitter.emit('step:skip', { loop: this.name, step: name, index: i, reason: 'error' });
238
+ runLog.steps.push({ name, status: 'skipped', error: lastErr.message });
239
+ continue;
240
+ }
241
+ // ── success path ─────────────────────────────────────────────────────
242
+ if (stepSucceeded && !runLog.steps.find(s => s.name === name)) {
243
+ const durationMs = Date.now() - stepStartMs;
244
+ console.log('ok');
245
+ logger.stepDone();
246
+ runLog.steps.push({ name, status: 'ok' });
247
+ await this._emitter.emit('step:complete', { loop: this.name, step: name, index: i, durationMs });
248
+ if (checkpointFile) {
249
+ ctx._completedSteps.push(name);
250
+ ctx._lastCompletedIndex = i;
251
+ writeCheckpoint(checkpointFile, {
252
+ loop: this.name,
253
+ session: session.id,
254
+ savedAt: new Date().toISOString(),
255
+ completedSteps: [...ctx._completedSteps],
256
+ lastCompletedIndex: i,
257
+ state: ctx.snapshot(),
258
+ });
259
+ const count = ctx._completedSteps.length;
260
+ console.log(` ✓ checkpoint saved (${count}/${this._steps.length} steps) → ${checkpointFile}`);
261
+ await this._emitter.emit('checkpoint:saved', {
262
+ loop: this.name,
263
+ file: checkpointFile,
264
+ step: name,
265
+ completedCount: count,
266
+ totalSteps: this._steps.length,
267
+ });
268
+ }
269
+ }
270
+ // ── unrecoverable failure ────────────────────────────────────────────
271
+ if (!stepSucceeded) {
272
+ const durationMs = Date.now() - stepStartMs;
273
+ console.log(`ERROR: ${lastErr.message}`);
274
+ await this._emitter.emit('step:error', { loop: this.name, step: name, index: i, error: lastErr, durationMs });
275
+ logger.stepError(lastErr);
276
+ runLog.steps.push({ name, status: 'error', error: lastErr.message });
277
+ runLog.status = 'failed';
278
+ // Loop-level onError handler
279
+ if (onError) {
280
+ try {
281
+ await onError(lastErr, ctx, name);
282
+ }
283
+ catch { }
284
+ }
285
+ break;
286
+ }
287
+ }
288
+ if (runLog.status === 'running') {
289
+ runLog.status = signal?.aborted ? 'cancelled' : 'completed';
290
+ }
291
+ runLog.finishedAt = new Date().toISOString();
292
+ logger.finish(runLog.status);
293
+ if (checkpointFile && runLog.status === 'completed' && !keepCheckpointOnSuccess) {
294
+ deleteCheckpoint(checkpointFile);
295
+ }
296
+ await this._emitter.emit('loop:complete', {
297
+ loop: this.name,
298
+ session: session.id,
299
+ status: runLog.status,
300
+ durationMs: Date.now() - loopStartMs,
301
+ stepsCompleted: runLog.steps.filter(s => s.status === 'ok' || s.status === 'recovered').length,
302
+ });
303
+ console.log('---');
304
+ console.log(`Loop ${runLog.status}.`);
305
+ if (logger.logFile)
306
+ console.log(`Log: ${logger.logFile}`);
307
+ return runLog;
308
+ }
309
+ /**
310
+ * Start the loop in the background and return a RunHandle immediately.
311
+ * Auto-generates a checkpoint file so pause/resume works without any configuration.
312
+ *
313
+ * @example
314
+ * const handle = loop.runBackground({ session })
315
+ *
316
+ * // Pause after the current step, resume later
317
+ * handle.pause()
318
+ * const handle2 = handle.resume()
319
+ * await handle2.wait()
320
+ *
321
+ * // Parallel loops
322
+ * const [log1, log2] = await Promise.all([h1.wait(), h2.wait()])
323
+ */
324
+ runBackground(opts) {
325
+ const id = `${this.name}-${Date.now()}`;
326
+ // Auto-generate a checkpoint path so pause/resume works out of the box.
327
+ // Respects a user-provided checkpointFile if one was passed.
328
+ const checkpointFile = opts.checkpointFile ?? `.loop/${id}.checkpoint.json`;
329
+ const controller = new AbortController();
330
+ let currentStatus = 'running';
331
+ const promise = this.run({ ...opts, checkpointFile, signal: controller.signal })
332
+ .then(log => {
333
+ // Don't overwrite 'paused' — the loop reports 'cancelled' internally when aborted,
334
+ // but we distinguish pause vs cancel at the handle level.
335
+ if (currentStatus !== 'paused')
336
+ currentStatus = log.status;
337
+ return log;
338
+ })
339
+ .catch(err => {
340
+ if (currentStatus !== 'paused') {
341
+ currentStatus = controller.signal.aborted ? 'cancelled' : 'failed';
342
+ }
343
+ throw err;
344
+ });
345
+ const loop = this;
346
+ const resumeOpts = { ...opts, checkpointFile };
347
+ return {
348
+ id,
349
+ get status() { return currentStatus; },
350
+ wait: () => promise,
351
+ cancel: () => {
352
+ if (currentStatus !== 'running')
353
+ return;
354
+ currentStatus = 'cancelled';
355
+ controller.abort();
356
+ },
357
+ pause: () => {
358
+ if (currentStatus !== 'running')
359
+ return;
360
+ currentStatus = 'paused';
361
+ controller.abort();
362
+ // The checkpoint was written after the last completed step automatically —
363
+ // nothing extra to do here. It will exist at checkpointFile when resume() is called.
364
+ },
365
+ resume: () => {
366
+ if (currentStatus !== 'paused') {
367
+ throw new Error(`Cannot resume: loop is "${currentStatus}" (must be "paused")`);
368
+ }
369
+ return loop.runBackground({ ...resumeOpts, resumeFrom: checkpointFile });
370
+ },
371
+ };
372
+ }
373
+ async _runErrorHooks(err, step, ctx) {
374
+ for (const plugin of this._plugins) {
375
+ if (!plugin.hooks?.onStepError)
376
+ continue;
377
+ const recovered = await plugin.hooks.onStepError(err, step, ctx).catch(() => false);
378
+ if (recovered)
379
+ return true;
380
+ }
381
+ return false;
382
+ }
383
+ }
384
+ /** Functional API — define and run a loop in one call. */
385
+ export async function run(name, session, fn, opts = {}) {
386
+ const loop = new Loop(name);
387
+ loop.step(name, fn);
388
+ return loop.run({ session, ...opts });
389
+ }
390
+ // ── helpers ──────────────────────────────────────────────────────────────────
391
+ function computeDelay(attempt, base, backoff) {
392
+ if (base === 0)
393
+ return 0;
394
+ if (backoff === 'linear')
395
+ return base * (attempt + 1);
396
+ if (backoff === 'exponential')
397
+ return base * Math.pow(2, attempt);
398
+ return base;
399
+ }
400
+ function sleep(ms) {
401
+ return new Promise(resolve => setTimeout(resolve, ms));
402
+ }
403
+ //# sourceMappingURL=loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loop.js","sourceRoot":"","sources":["../src/loop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ import { Loop } from './loop.js';
2
+ import type { Context } from './context.js';
3
+ import type { Session } from './session.js';
4
+ import type { RunOptions, RunLog, RunHandle } from './loop.js';
5
+ export interface LoopFileMeta {
6
+ name: string;
7
+ /** Informational — tells the runner what session type to expect. */
8
+ session?: string;
9
+ /** Default model for claudeCli/agent steps. */
10
+ model?: string;
11
+ }
12
+ export interface LoopFileStep {
13
+ name: string;
14
+ /**
15
+ * Built-in actions: claudeCli | navigate | screenshot | log | sub | each
16
+ * Custom: any string key registered in the actions map passed to loadLoop()
17
+ */
18
+ action: string;
19
+ /** Prompt text. Supports {{step-name}} interpolation. */
20
+ prompt?: string;
21
+ /** Model override for this step. */
22
+ model?: string;
23
+ /** URL for navigate steps. Supports {{step-name}} interpolation. */
24
+ url?: string;
25
+ /** Message for log steps. Supports {{step-name}} interpolation. */
26
+ message?: string;
27
+ /** Path to another .loop file to run as a nested sub-loop. */
28
+ loop?: string;
29
+ /** Extra vars to pass into the sub-loop context. */
30
+ vars?: Record<string, unknown>;
31
+ /**
32
+ * Items to iterate over. Either a {{step-name}} reference (resolves from ctx)
33
+ * or a literal YAML array.
34
+ */
35
+ items?: string | unknown[];
36
+ /** Variable name for the current item inside each iteration. Default: 'item'. */
37
+ as?: string;
38
+ /** Inline step definitions for each iteration (alternative to referencing a loop file). */
39
+ steps?: LoopFileStep[];
40
+ /** Which step's output to collect per iteration. Defaults to the last step. */
41
+ output?: string;
42
+ /** If true, each continues past failed items instead of aborting. */
43
+ continueOnError?: boolean;
44
+ retries?: number;
45
+ retryDelay?: number;
46
+ retryBackoff?: 'flat' | 'linear' | 'exponential';
47
+ skipOnError?: boolean;
48
+ /** 'skip' is shorthand for skipOnError: true */
49
+ onError?: 'skip' | string;
50
+ }
51
+ export interface LoopFileSchema {
52
+ meta: LoopFileMeta;
53
+ steps: LoopFileStep[];
54
+ }
55
+ export declare function parseLoopFile(content: string): LoopFileSchema;
56
+ export declare function loadLoopFile(filePath: string): LoopFileSchema;
57
+ export type ActionRegistry = Record<string, (ctx: Context, step: LoopFileStep) => Promise<unknown>>;
58
+ /**
59
+ * Load a .loop file and return a configured Loop instance ready to run.
60
+ *
61
+ * Built-in actions: claudeCli, navigate, screenshot, log, sub, each
62
+ * Pass `actions` to register custom action handlers.
63
+ */
64
+ export declare function loadLoop(filePath: string, actions?: ActionRegistry): Loop;
65
+ /**
66
+ * Load and run a .loop file in one call.
67
+ *
68
+ * @example
69
+ * await runFile('./research.loop', new PlaywrightSession('run-1'))
70
+ */
71
+ export declare function runFile(filePath: string, session: Session, opts?: Omit<RunOptions, 'session'>, actions?: ActionRegistry): Promise<RunLog>;
72
+ /**
73
+ * Load and run a .loop file in the background, returning a RunHandle immediately.
74
+ *
75
+ * @example
76
+ * const handle = runFileBackground('./research.loop', session)
77
+ * const handle2 = runFileBackground('./report.loop', session2)
78
+ *
79
+ * const [log1, log2] = await Promise.all([handle.wait(), handle2.wait()])
80
+ */
81
+ export declare function runFileBackground(filePath: string, session: Session, opts?: Omit<RunOptions, 'session'>, actions?: ActionRegistry): RunHandle;
82
+ //# sourceMappingURL=loopfile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loopfile.d.ts","sourceRoot":"","sources":["../src/loopfile.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAGhC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAI9D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAA;IAGd,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAA;IAGd,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAA;IAGZ,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAA;IAGhB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAG9B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,EAAE,CAAA;IAC1B,iFAAiF;IACjF,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,2FAA2F;IAC3F,KAAK,CAAC,EAAE,YAAY,EAAE,CAAA;IACtB,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,eAAe,CAAC,EAAE,OAAO,CAAA;IAGzB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,aAAa,CAAA;IAChD,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,EAAE,YAAY,EAAE,CAAA;CACtB;AAID,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAyB7D;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAG7D;AAID,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;AAEnG;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,IAAI,CAmB7E;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,IAAI,GAAE,IAAI,CAAC,UAAU,EAAE,SAAS,CAAM,EACtC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,IAAI,GAAE,IAAI,CAAC,UAAU,EAAE,SAAS,CAAM,EACtC,OAAO,GAAE,cAAmB,GAC3B,SAAS,CAGX"}