opencode-immune 1.0.60 → 1.0.61
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.
- package/dist/plugin.js +38 -15
- package/package.json +1 -1
package/dist/plugin.js
CHANGED
|
@@ -107,6 +107,7 @@ function createState(input) {
|
|
|
107
107
|
approximateTokens: 0,
|
|
108
108
|
sessionActive: false,
|
|
109
109
|
autoResumeAttempted: false,
|
|
110
|
+
autoResumeInFlight: false,
|
|
110
111
|
cycleCount: 0,
|
|
111
112
|
commitPending: false,
|
|
112
113
|
pluginUpdateMessage: null,
|
|
@@ -178,16 +179,21 @@ async function createManagedUltraworkSession(state, title) {
|
|
|
178
179
|
async function applyUltraworkSessionPermissions(state, sessionID) {
|
|
179
180
|
if (state.ultraworkPermissionSessions.has(sessionID))
|
|
180
181
|
return;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
182
|
+
try {
|
|
183
|
+
const result = await state.client.session.update({
|
|
184
|
+
directory: state.input.directory,
|
|
185
|
+
sessionID,
|
|
186
|
+
permission: ULTRAWORK_SESSION_PERMISSION,
|
|
187
|
+
});
|
|
188
|
+
if (result.error || !result.response.ok) {
|
|
189
|
+
pluginLog.warn(`[opencode-immune] Failed to apply ultrawork permissions to session ${sessionID}:`, result.error ?? result.response.status);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
state.ultraworkPermissionSessions.add(sessionID);
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
pluginLog.warn(`[opencode-immune] Failed to apply ultrawork permissions to session ${sessionID}:`, err);
|
|
189
196
|
}
|
|
190
|
-
state.ultraworkPermissionSessions.add(sessionID);
|
|
191
197
|
}
|
|
192
198
|
async function promptManagedSession(state, sessionID, text, options = {}) {
|
|
193
199
|
const result = await state.client.session.promptAsync({
|
|
@@ -1394,18 +1400,23 @@ function createSessionRecoveryEvent(state) {
|
|
|
1394
1400
|
// Register this root session as managed so retry/recovery works
|
|
1395
1401
|
await addManagedUltraworkSession(state, sessionID);
|
|
1396
1402
|
// Skip sending AUTO-RESUME if already sent from plugin init
|
|
1397
|
-
if (state.autoResumeAttempted) {
|
|
1398
|
-
pluginLog.info(`[opencode-immune] Auto-resume already sent
|
|
1403
|
+
if (state.autoResumeAttempted || state.autoResumeInFlight) {
|
|
1404
|
+
pluginLog.info(`[opencode-immune] Auto-resume already sent or in flight, skipping duplicate for session ${sessionID}.`);
|
|
1399
1405
|
return;
|
|
1400
1406
|
}
|
|
1407
|
+
state.autoResumeInFlight = true;
|
|
1401
1408
|
setTimeout(async () => {
|
|
1402
1409
|
try {
|
|
1403
1410
|
await promptManagedSession(state, sessionID, `[AUTO-RESUME] Previous session was interrupted. Read memory-bank/tasks.md, check the Phase Status block, and continue the pipeline. Use ONLY the Phase Status block to determine the next phase. Do NOT analyze or evaluate the content of tasks.md. Call the appropriate router with the exact neutral prompt from your Step 5 table.`);
|
|
1411
|
+
state.autoResumeAttempted = true;
|
|
1404
1412
|
pluginLog.info(`[opencode-immune] Auto-resume prompt sent to managed ultrawork session ${sessionID}`);
|
|
1405
1413
|
}
|
|
1406
1414
|
catch (err) {
|
|
1407
1415
|
pluginLog.info(`[opencode-immune] Auto-resume failed (session may have been taken over):`, err);
|
|
1408
1416
|
}
|
|
1417
|
+
finally {
|
|
1418
|
+
state.autoResumeInFlight = false;
|
|
1419
|
+
}
|
|
1409
1420
|
}, 3_000);
|
|
1410
1421
|
}
|
|
1411
1422
|
}
|
|
@@ -1631,8 +1642,7 @@ function createFallbackModels(state) {
|
|
|
1631
1642
|
scheduleProviderRetryWatchdog(state, input.sessionID);
|
|
1632
1643
|
// First contact with 0-ultrawork after plugin restart:
|
|
1633
1644
|
// if marker is active and tasks.md has incomplete work, send AUTO-RESUME prompt.
|
|
1634
|
-
if (!wasAlreadyManaged && !state.autoResumeAttempted) {
|
|
1635
|
-
state.autoResumeAttempted = true;
|
|
1645
|
+
if (!wasAlreadyManaged && !state.autoResumeAttempted && !state.autoResumeInFlight) {
|
|
1636
1646
|
const markerActive = await isUltraworkMarkerActive(state);
|
|
1637
1647
|
if (markerActive) {
|
|
1638
1648
|
const recovery = await parseTasksFile(state.input.directory);
|
|
@@ -1642,14 +1652,19 @@ function createFallbackModels(state) {
|
|
|
1642
1652
|
`task="${recovery.task}", level=${recovery.level}, phase=${recovery.phase}. ` +
|
|
1643
1653
|
`Sending AUTO-RESUME prompt in 3s...`);
|
|
1644
1654
|
const sid = input.sessionID;
|
|
1655
|
+
state.autoResumeInFlight = true;
|
|
1645
1656
|
setTimeout(async () => {
|
|
1646
1657
|
try {
|
|
1647
1658
|
await promptManagedSession(state, sid, `[AUTO-RESUME] Previous session was interrupted. Read memory-bank/tasks.md, check the Phase Status block, and continue the pipeline. Use ONLY the Phase Status block to determine the next phase. Do NOT analyze or evaluate the content of tasks.md. Call the appropriate router with the exact neutral prompt from your Step 5 table.`);
|
|
1659
|
+
state.autoResumeAttempted = true;
|
|
1648
1660
|
pluginLog.info(`[opencode-immune] Auto-resume prompt sent to session ${sid}`);
|
|
1649
1661
|
}
|
|
1650
1662
|
catch (err) {
|
|
1651
1663
|
pluginLog.info(`[opencode-immune] Auto-resume prompt failed:`, err);
|
|
1652
1664
|
}
|
|
1665
|
+
finally {
|
|
1666
|
+
state.autoResumeInFlight = false;
|
|
1667
|
+
}
|
|
1653
1668
|
}, 3_000);
|
|
1654
1669
|
}
|
|
1655
1670
|
}
|
|
@@ -2123,12 +2138,12 @@ async function server(input) {
|
|
|
2123
2138
|
if (recovery && recovery.phase !== "ARCHIVE: DONE") {
|
|
2124
2139
|
// Active task exists with incomplete phases — resume it
|
|
2125
2140
|
state.recoveryContext = recovery;
|
|
2126
|
-
state.autoResumeAttempted = true;
|
|
2127
2141
|
pluginLog.info(`[opencode-immune] Plugin init: ultrawork marker active, recovery context loaded: ` +
|
|
2128
2142
|
`task="${recovery.task}", level=${recovery.level}, phase=${recovery.phase}. ` +
|
|
2129
2143
|
`Will create new session and send AUTO-RESUME.`);
|
|
2130
2144
|
// Create a new session and send AUTO-RESUME prompt (same pattern as CYCLE_COMPLETE).
|
|
2131
2145
|
// Delay to let opencode fully initialize.
|
|
2146
|
+
state.autoResumeInFlight = true;
|
|
2132
2147
|
setTimeout(async () => {
|
|
2133
2148
|
try {
|
|
2134
2149
|
const newSessionID = await createManagedUltraworkSession(state, `AUTO-RESUME: ${recovery.task}`);
|
|
@@ -2138,11 +2153,15 @@ async function server(input) {
|
|
|
2138
2153
|
}
|
|
2139
2154
|
pluginLog.info(`[opencode-immune] Auto-resume: New session created: ${newSessionID}`);
|
|
2140
2155
|
await promptManagedSession(state, newSessionID, `[AUTO-RESUME] Previous session was interrupted. Read memory-bank/tasks.md, check the Phase Status block, and continue the pipeline. Use ONLY the Phase Status block to determine the next phase. Do NOT analyze or evaluate the content of tasks.md. Call the appropriate router with the exact neutral prompt from your Step 5 table.`);
|
|
2156
|
+
state.autoResumeAttempted = true;
|
|
2141
2157
|
pluginLog.info(`[opencode-immune] Auto-resume prompt sent to new session ${newSessionID}`);
|
|
2142
2158
|
}
|
|
2143
2159
|
catch (err) {
|
|
2144
2160
|
pluginLog.error("[opencode-immune] Auto-resume: Failed to create session or send prompt:", err);
|
|
2145
2161
|
}
|
|
2162
|
+
finally {
|
|
2163
|
+
state.autoResumeInFlight = false;
|
|
2164
|
+
}
|
|
2146
2165
|
}, 5_000);
|
|
2147
2166
|
}
|
|
2148
2167
|
else {
|
|
@@ -2152,9 +2171,9 @@ async function server(input) {
|
|
|
2152
2171
|
const backlogContent = await readFile(backlogPath, "utf-8");
|
|
2153
2172
|
const hasPendingTasks = /- \[ \]/.test(backlogContent);
|
|
2154
2173
|
if (hasPendingTasks) {
|
|
2155
|
-
state.autoResumeAttempted = true;
|
|
2156
2174
|
pluginLog.info(`[opencode-immune] Plugin init: no active task but backlog has pending items. ` +
|
|
2157
2175
|
`Will create new session to start next cycle.`);
|
|
2176
|
+
state.autoResumeInFlight = true;
|
|
2158
2177
|
setTimeout(async () => {
|
|
2159
2178
|
try {
|
|
2160
2179
|
const newSessionID = await createManagedUltraworkSession(state, `AUTO-CYCLE: next backlog task`);
|
|
@@ -2164,11 +2183,15 @@ async function server(input) {
|
|
|
2164
2183
|
}
|
|
2165
2184
|
pluginLog.info(`[opencode-immune] Auto-cycle: New session created: ${newSessionID}`);
|
|
2166
2185
|
await promptManagedSession(state, newSessionID, `[AUTO-CYCLE] Continue processing task backlog. Read memory-bank/tasks.md and memory-bank/backlog.md, pick the next pending task, and run the full pipeline.`);
|
|
2186
|
+
state.autoResumeAttempted = true;
|
|
2167
2187
|
pluginLog.info(`[opencode-immune] Auto-cycle prompt sent to new session ${newSessionID}`);
|
|
2168
2188
|
}
|
|
2169
2189
|
catch (err) {
|
|
2170
2190
|
pluginLog.error("[opencode-immune] Auto-cycle: Failed to create session or send prompt:", err);
|
|
2171
2191
|
}
|
|
2192
|
+
finally {
|
|
2193
|
+
state.autoResumeInFlight = false;
|
|
2194
|
+
}
|
|
2172
2195
|
}, 5_000);
|
|
2173
2196
|
}
|
|
2174
2197
|
else {
|