opencodekit 0.14.2 → 0.14.4

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.
@@ -1,203 +0,0 @@
1
- /**
2
- * Ralph Wiggum Tools
3
- *
4
- * Standalone tools for the Ralph Wiggum autonomous loop pattern.
5
- * The plugin (ralph-wiggum.ts) handles event listening, these handle user interaction.
6
- */
7
-
8
- import fs from "node:fs/promises";
9
- import path from "node:path";
10
- import { tool } from "@opencode-ai/plugin";
11
-
12
- const STATE_FILE = ".opencode/.ralph-state.json";
13
-
14
- interface RalphState {
15
- active: boolean;
16
- sessionID: string | null;
17
- iteration: number;
18
- maxIterations: number;
19
- completionPromise: string;
20
- task: string;
21
- prdFile: string | null;
22
- progressFile: string;
23
- startedAt: number | null;
24
- mode: "hitl" | "afk";
25
- }
26
-
27
- const DEFAULT_STATE: RalphState = {
28
- active: false,
29
- sessionID: null,
30
- iteration: 0,
31
- maxIterations: 50,
32
- completionPromise: "<promise>COMPLETE</promise>",
33
- task: "",
34
- prdFile: null,
35
- progressFile: "progress.txt",
36
- startedAt: null,
37
- mode: "hitl",
38
- };
39
-
40
- async function loadState(): Promise<RalphState> {
41
- try {
42
- const content = await fs.readFile(STATE_FILE, "utf-8");
43
- return JSON.parse(content);
44
- } catch {
45
- return { ...DEFAULT_STATE };
46
- }
47
- }
48
-
49
- async function saveState(state: RalphState): Promise<void> {
50
- await fs.mkdir(path.dirname(STATE_FILE), { recursive: true });
51
- await fs.writeFile(STATE_FILE, JSON.stringify(state, null, 2));
52
- }
53
-
54
- /**
55
- * Start Ralph Wiggum autonomous loop
56
- */
57
- export const ralph_start = tool({
58
- description:
59
- "Start Ralph Wiggum autonomous loop. Agent will work on tasks until completion or max iterations.",
60
- args: {
61
- task: tool.schema
62
- .string()
63
- .describe(
64
- "Task description or goal (e.g., 'Migrate all Jest tests to Vitest')",
65
- ),
66
- prdFile: tool.schema
67
- .string()
68
- .optional()
69
- .describe("Path to PRD/task list file (e.g., 'PRD.md')"),
70
- progressFile: tool.schema
71
- .string()
72
- .optional()
73
- .describe("Path to progress tracking file (default: progress.txt)"),
74
- completionPromise: tool.schema
75
- .string()
76
- .optional()
77
- .describe(
78
- "Text to output when done (default: <promise>COMPLETE</promise>)",
79
- ),
80
- maxIterations: tool.schema
81
- .number()
82
- .optional()
83
- .describe("Maximum iterations before stopping (default: 50)"),
84
- mode: tool.schema
85
- .enum(["hitl", "afk"])
86
- .optional()
87
- .describe("Mode: hitl (human-in-the-loop) or afk (away-from-keyboard)"),
88
- },
89
- execute: async (args, context) => {
90
- const state: RalphState = {
91
- active: true,
92
- sessionID: context.sessionID,
93
- iteration: 0,
94
- maxIterations: args.maxIterations || 50,
95
- completionPromise:
96
- args.completionPromise || "<promise>COMPLETE</promise>",
97
- task: args.task,
98
- prdFile: args.prdFile || null,
99
- progressFile: args.progressFile || "progress.txt",
100
- startedAt: Date.now(),
101
- mode: args.mode || "hitl",
102
- };
103
-
104
- await saveState(state);
105
-
106
- const modeDesc =
107
- state.mode === "hitl"
108
- ? "Human-in-the-loop (watch and intervene)"
109
- : "Away-from-keyboard (autonomous)";
110
-
111
- return `
112
- ## Ralph Loop Active
113
-
114
- **Task:** ${state.task}
115
- **Mode:** ${modeDesc}
116
- **Max Iterations:** ${state.maxIterations}
117
- **Completion Signal:** ${state.completionPromise}
118
- **PRD File:** ${state.prdFile || "(none - using task description)"}
119
- **Progress File:** ${state.progressFile}
120
-
121
- ### Next Steps
122
-
123
- 1. Work on the task described above
124
- 2. After each feature, update ${state.progressFile}
125
- 3. Run feedback loops (typecheck, test, lint)
126
- 4. Commit changes
127
- 5. When ALL tasks complete, output: ${state.completionPromise}
128
-
129
- The loop will continue automatically after each completion until:
130
- - You output the completion promise, OR
131
- - Max iterations (${state.maxIterations}) reached
132
-
133
- **Remember:** ONE feature per iteration. Small steps. Quality over speed.
134
- `.trim();
135
- },
136
- });
137
-
138
- /**
139
- * Stop Ralph Wiggum loop
140
- */
141
- export const ralph_stop = tool({
142
- description: "Stop the Ralph Wiggum loop gracefully",
143
- args: {
144
- reason: tool.schema.string().optional().describe("Reason for stopping"),
145
- },
146
- execute: async (args) => {
147
- const state = await loadState();
148
-
149
- if (!state.active) {
150
- return "No Ralph loop is currently running.";
151
- }
152
-
153
- const duration = state.startedAt
154
- ? Math.round((Date.now() - state.startedAt) / 1000 / 60)
155
- : 0;
156
-
157
- const summary = `
158
- ## Ralph Loop Stopped
159
-
160
- **Iterations Completed:** ${state.iteration}
161
- **Duration:** ${duration} minutes
162
- **Reason:** ${args.reason || "Manual stop requested"}
163
- **Task:** ${state.task}
164
-
165
- Progress has been saved to ${state.progressFile}.
166
- `.trim();
167
-
168
- // Reset state
169
- await saveState(DEFAULT_STATE);
170
-
171
- return summary;
172
- },
173
- });
174
-
175
- /**
176
- * Get Ralph Wiggum status
177
- */
178
- export const ralph_status = tool({
179
- description: "Get current Ralph Wiggum loop status",
180
- args: {},
181
- execute: async () => {
182
- const state = await loadState();
183
-
184
- if (!state.active) {
185
- return "No Ralph loop is currently active.";
186
- }
187
-
188
- const duration = state.startedAt
189
- ? Math.round((Date.now() - state.startedAt) / 1000 / 60)
190
- : 0;
191
-
192
- return `
193
- ## Ralph Loop Active
194
-
195
- **Task:** ${state.task}
196
- **Iteration:** ${state.iteration}/${state.maxIterations}
197
- **Duration:** ${duration} minutes
198
- **Mode:** ${state.mode}
199
- **Completion Signal:** ${state.completionPromise}
200
- **Progress File:** ${state.progressFile}
201
- `.trim();
202
- },
203
- });