🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

opencode-ralph-loop

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

opencode-ralph-loop - npm Package Compare versions

Comparing version
1.0.3
to
1.0.4
+1
-1
package.json
{
"name": "opencode-ralph-loop",
"version": "1.0.3",
"version": "1.0.4",
"description": "Minimal Ralph Loop plugin for opencode - auto-continues until task completion",

@@ -5,0 +5,0 @@ "main": "src/index.ts",

@@ -1,2 +0,2 @@

import { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync, readdirSync, cpSync } from "fs";
import { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync, cpSync } from "fs";
import { dirname, join } from "path";

@@ -16,3 +16,2 @@ import { fileURLToPath } from "url";

const STATE_FILENAME = "ralph-loop.local.md";
const MESSAGE_DIR = join(process.env.HOME || "~", ".local/share/opencode/storage/message");
const OPENCODE_CONFIG_DIR = join(process.env.HOME || "~", ".config/opencode");

@@ -151,24 +150,29 @@ const COMPLETION_TAG = /<promise>\s*DONE\s*<\/promise>/is;

// Check completion by scanning session messages
function isComplete(sessionId?: string): boolean {
if (!sessionId) return false;
// Check completion by fetching session messages via API
async function isComplete(client: any, sessionId: string): Promise<boolean> {
try {
const sessionMsgDir = join(MESSAGE_DIR, sessionId);
if (!existsSync(sessionMsgDir)) return false;
const response = await client.session.messages({
path: { id: sessionId }
});
const files = readdirSync(sessionMsgDir)
.filter(f => f.endsWith(".json"))
.sort()
.reverse();
if (!response?.data) return false;
for (const file of files.slice(0, 10)) {
try {
const content = readFileSync(join(sessionMsgDir, file), "utf-8");
if (COMPLETION_TAG.test(content)) {
return true;
// Check recent assistant messages for completion promise
const messages = response.data;
for (const msg of messages.slice(-10)) {
if (msg.role === "assistant") {
// Check parts for text content
const parts = msg.parts || [];
for (const part of parts) {
if (part.type === "text" && part.text) {
if (COMPLETION_TAG.test(part.text)) {
return true;
}
}
}
} catch {}
}
}
} catch {}
} catch (e) {
console.error("[ralph-loop] Failed to check completion:", e);
}

@@ -279,3 +283,3 @@ return false;

if (isComplete(sessionId)) {
if (await isComplete(client, sessionId)) {
console.log("[ralph-loop] Task complete - DONE promise found");

@@ -282,0 +286,0 @@ clearState(directory);