@w32191/just-loop 0.1.7 → 0.1.9
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.
|
@@ -4,10 +4,10 @@ export function parseRalphLoopCommand(input) {
|
|
|
4
4
|
if (trimmed === "/cancel-ralph") {
|
|
5
5
|
return { kind: "cancel" };
|
|
6
6
|
}
|
|
7
|
-
if (!/^\/
|
|
7
|
+
if (!/^\/just-loop(?:\s|$)/.test(trimmed)) {
|
|
8
8
|
return null;
|
|
9
9
|
}
|
|
10
|
-
let rest = trimmed.slice("/
|
|
10
|
+
let rest = trimmed.slice("/just-loop".length);
|
|
11
11
|
let maxIterations;
|
|
12
12
|
let completionPromise = DEFAULT_COMPLETION_PROMISE;
|
|
13
13
|
while (true) {
|
|
@@ -41,8 +41,8 @@ This will:
|
|
|
41
41
|
Check if a loop is active and cancel it. Inform the user of the result.`;
|
|
42
42
|
export function getBuiltinCommands() {
|
|
43
43
|
return {
|
|
44
|
-
"
|
|
45
|
-
name: "
|
|
44
|
+
"just-loop": {
|
|
45
|
+
name: "just-loop",
|
|
46
46
|
description: "(builtin) Start self-referential development loop until completion",
|
|
47
47
|
template: `<command-instruction>
|
|
48
48
|
${RALPH_LOOP_TEMPLATE}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
function hasInterruptCommand(input) {
|
|
2
2
|
if (!input || typeof input !== "object")
|
|
3
3
|
return false;
|
|
4
|
-
|
|
5
|
-
if (!properties || typeof properties !== "object")
|
|
6
|
-
return false;
|
|
7
|
-
return properties.command === "session.interrupt";
|
|
4
|
+
return input.command === "session.interrupt";
|
|
8
5
|
}
|
|
9
6
|
export async function handleTuiCommandExecute(input, core) {
|
|
10
7
|
if (!hasInterruptCommand(input))
|
|
@@ -257,7 +257,14 @@ export function createLoopCore(deps) {
|
|
|
257
257
|
showToast("Ralph Loop", `Injecting next continuation in ${remaining - 1}s. Use interrupt to cancel once.`, "warning");
|
|
258
258
|
}
|
|
259
259
|
}
|
|
260
|
-
const
|
|
260
|
+
const dispatchToken = randomUUID();
|
|
261
|
+
const continuationPrompt = buildContinuationPrompt({
|
|
262
|
+
iteration: nextIteration,
|
|
263
|
+
prompt: continuationState.prompt,
|
|
264
|
+
completionPromise: continuationState.completion_promise,
|
|
265
|
+
maxIterations: continuationState.max_iterations,
|
|
266
|
+
});
|
|
267
|
+
const dispatchResult = await runStateMutation(async () => {
|
|
261
268
|
const currentState = await readCurrentState(event.sessionID, incarnationToken);
|
|
262
269
|
if (!currentState?.pending_continuation)
|
|
263
270
|
return { kind: "aborted" };
|
|
@@ -270,13 +277,6 @@ export function createLoopCore(deps) {
|
|
|
270
277
|
await writeState(deps.rootDir, nextState);
|
|
271
278
|
return { kind: "cancelled" };
|
|
272
279
|
}
|
|
273
|
-
const dispatchToken = randomUUID();
|
|
274
|
-
const prompt = buildContinuationPrompt({
|
|
275
|
-
iteration: nextIteration,
|
|
276
|
-
prompt: currentState.prompt,
|
|
277
|
-
completionPromise: currentState.completion_promise,
|
|
278
|
-
maxIterations: currentState.max_iterations,
|
|
279
|
-
});
|
|
280
280
|
await writeState(deps.rootDir, {
|
|
281
281
|
...currentState,
|
|
282
282
|
pending_continuation: {
|
|
@@ -285,23 +285,30 @@ export function createLoopCore(deps) {
|
|
|
285
285
|
dispatch_token: dispatchToken,
|
|
286
286
|
},
|
|
287
287
|
});
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
288
|
+
});
|
|
289
|
+
if (dispatchResult?.kind === "aborted" || dispatchResult?.kind === "cancelled") {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
try {
|
|
293
|
+
await deps.adapter.prompt(event.sessionID, continuationPrompt);
|
|
294
|
+
}
|
|
295
|
+
catch (error) {
|
|
296
|
+
await runStateMutation(async () => {
|
|
292
297
|
const latest = await readCurrentState(event.sessionID, incarnationToken);
|
|
293
|
-
if (latest?.pending_continuation?.dispatch_token
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
298
|
+
if (latest?.pending_continuation?.dispatch_token !== dispatchToken)
|
|
299
|
+
return;
|
|
300
|
+
const nextState = { ...latest };
|
|
301
|
+
delete nextState.pending_continuation;
|
|
302
|
+
await writeState(deps.rootDir, nextState);
|
|
303
|
+
});
|
|
304
|
+
throw error;
|
|
305
|
+
}
|
|
306
|
+
await runStateMutation(async () => {
|
|
300
307
|
const latest = await readCurrentState(event.sessionID, incarnationToken);
|
|
301
308
|
if (!latest?.pending_continuation)
|
|
302
|
-
return
|
|
309
|
+
return;
|
|
303
310
|
if (latest.pending_continuation.dispatch_token !== dispatchToken)
|
|
304
|
-
return
|
|
311
|
+
return;
|
|
305
312
|
const nextState = {
|
|
306
313
|
...latest,
|
|
307
314
|
iteration: nextIteration,
|
|
@@ -309,21 +316,31 @@ export function createLoopCore(deps) {
|
|
|
309
316
|
};
|
|
310
317
|
delete nextState.pending_continuation;
|
|
311
318
|
await writeState(deps.rootDir, nextState);
|
|
312
|
-
return { kind: "dispatched" };
|
|
313
319
|
});
|
|
314
|
-
if (promptGate.kind !== "dispatched")
|
|
315
|
-
return;
|
|
316
320
|
}
|
|
317
321
|
if (wait) {
|
|
318
322
|
showToast("Ralph Loop", "Injected Ralph Loop continuation.", "success");
|
|
319
323
|
return;
|
|
320
324
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
325
|
+
try {
|
|
326
|
+
await deps.adapter.prompt(event.sessionID, buildContinuationPrompt({
|
|
327
|
+
iteration: nextIteration,
|
|
328
|
+
prompt: continuationState.prompt,
|
|
329
|
+
completionPromise: continuationState.completion_promise,
|
|
330
|
+
maxIterations: continuationState.max_iterations,
|
|
331
|
+
}));
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
await runStateMutation(async () => {
|
|
335
|
+
const currentState = await readCurrentState(event.sessionID, incarnationToken);
|
|
336
|
+
if (!currentState?.pending_continuation)
|
|
337
|
+
return;
|
|
338
|
+
const nextState = { ...currentState };
|
|
339
|
+
delete nextState.pending_continuation;
|
|
340
|
+
await writeState(deps.rootDir, nextState);
|
|
341
|
+
});
|
|
342
|
+
throw error;
|
|
343
|
+
}
|
|
327
344
|
await runStateMutation(async () => {
|
|
328
345
|
const currentState = await readState(deps.rootDir);
|
|
329
346
|
if (!currentState ||
|