opencode-immune 1.0.5 → 1.0.6

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 (2) hide show
  1. package/dist/plugin.js +38 -0
  2. package/package.json +1 -1
package/dist/plugin.js CHANGED
@@ -13,6 +13,7 @@ function createState(input) {
13
13
  retryTimers: new Map(),
14
14
  retryCount: new Map(),
15
15
  managedSessionsCachePath: (0, path_1.join)(input.directory, ".opencode", "state", "opencode-immune-managed-sessions.json"),
16
+ diagnosticsLogPath: (0, path_1.join)(input.directory, ".opencode", "state", "opencode-immune-debug.log"),
16
17
  lastEditAttempt: null,
17
18
  toolCallCount: 0,
18
19
  todoWriteUsed: false,
@@ -66,6 +67,17 @@ async function writeManagedSessionsCache(state) {
66
67
  console.log(`[opencode-immune] Pruned ${removed} expired managed ultrawork session(s) while writing cache.`);
67
68
  }
68
69
  }
70
+ async function writeDiagnosticLog(state, event, data = {}) {
71
+ try {
72
+ const cacheDir = (0, path_1.join)(state.input.directory, ".opencode", "state");
73
+ await (0, promises_1.mkdir)(cacheDir, { recursive: true });
74
+ const line = JSON.stringify({ ts: new Date().toISOString(), event, ...data });
75
+ await (0, promises_1.appendFile)(state.diagnosticsLogPath, `${line}\n`, "utf-8");
76
+ }
77
+ catch {
78
+ // diagnostics must never affect runtime behavior
79
+ }
80
+ }
69
81
  async function loadManagedSessionsCache(state) {
70
82
  try {
71
83
  const raw = await (0, promises_1.readFile)(state.managedSessionsCachePath, "utf-8");
@@ -219,6 +231,26 @@ async function forceRetryManagedSession(state, sessionID, reason) {
219
231
  const retryText = retryAgent === ULTRAWORK_AGENT
220
232
  ? "[SYSTEM: Previous API call failed with a transient error. Re-read memory-bank/tasks.md, check the Phase Status block, and continue the pipeline. Use the exact neutral prompt from your Step 5 table for the next router call. Do NOT analyze or evaluate file contents.]"
221
233
  : `[SYSTEM: Previous API call failed with a transient error. Resume the current task in your current role as ${retryAgent}. Continue from the existing session state. Do not restart from scratch unless the current session state is missing.]`;
234
+ await writeDiagnosticLog(state, "force-retry:start", {
235
+ sessionID,
236
+ reason,
237
+ retryAgent,
238
+ managedKind: managedSession.kind,
239
+ rootSessionID: managedSession.rootSessionID,
240
+ fallbackModel,
241
+ });
242
+ try {
243
+ await state.input.client.session.abort({
244
+ path: { id: sessionID },
245
+ });
246
+ await writeDiagnosticLog(state, "force-retry:abort-success", { sessionID });
247
+ }
248
+ catch (err) {
249
+ await writeDiagnosticLog(state, "force-retry:abort-failed", {
250
+ sessionID,
251
+ error: err instanceof Error ? err.message : String(err),
252
+ });
253
+ }
222
254
  await state.input.client.session.promptAsync({
223
255
  body: {
224
256
  ...(fallbackModel ? { model: fallbackModel } : {}),
@@ -236,6 +268,12 @@ async function forceRetryManagedSession(state, sessionID, reason) {
236
268
  (fallbackModel
237
269
  ? ` using fallback model ${fallbackModel.providerID}/${fallbackModel.modelID}`
238
270
  : ""));
271
+ await writeDiagnosticLog(state, "force-retry:prompt-sent", {
272
+ sessionID,
273
+ reason,
274
+ retryAgent,
275
+ fallbackModel,
276
+ });
239
277
  }
240
278
  // ═══════════════════════════════════════════════════════════════════════════════
241
279
  // UTILITY: ERROR BOUNDARY
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-immune",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "OpenCode plugin: session recovery, auto-retry, multi-cycle automation, context monitoring",
5
5
  "exports": {
6
6
  "./server": "./dist/plugin.js"