opencode-immune 1.0.20 → 1.0.21

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 +36 -28
  2. package/package.json +1 -1
package/dist/plugin.js CHANGED
@@ -914,9 +914,12 @@ const ALL_CYCLES_COMPLETE_MARKER = "0-ULTRAWORK: ALL_CYCLES_COMPLETE";
914
914
  /**
915
915
  * experimental.text.complete: scans completed assistant text for signal markers.
916
916
  *
917
- * PRE_COMMIT executes /commit via client.session.command()
918
- * CYCLE_COMPLETE creates a new session and sends bootstrap prompt
919
- * ALL_CYCLES_COMPLETEclears ultrawork marker
917
+ * Handles the full cycle-end sequence:
918
+ * 1. PRE_COMMIT detected execute /commit await result
919
+ * 2. CYCLE_COMPLETE detected create new session → send AUTO-CYCLE prompt
920
+ * Steps are sequential: new session only starts AFTER commit completes (or fails).
921
+ *
922
+ * ALL_CYCLES_COMPLETE → clears ultrawork marker, no new session.
920
923
  */
921
924
  function createTextCompleteHandler(state) {
922
925
  return async (input, output) => {
@@ -928,44 +931,49 @@ function createTextCompleteHandler(state) {
928
931
  if (text.includes(ALL_CYCLES_COMPLETE_MARKER)) {
929
932
  await clearUltraworkMarker(state);
930
933
  console.log("[opencode-immune] Multi-Cycle: ALL_CYCLES_COMPLETE detected in text.complete, ultrawork marker cleared.");
934
+ return;
931
935
  }
932
- // ── PRE_COMMIT: execute /commit ──
933
- if (text.includes(PRE_COMMIT_MARKER) && !state.commitPending && sessionID) {
934
- state.commitPending = true;
935
- console.log("[opencode-immune] Multi-Cycle: PRE_COMMIT detected in text.complete, executing /commit...");
936
- setTimeout(async () => {
936
+ const hasPRECOMMIT = text.includes(PRE_COMMIT_MARKER);
937
+ const hasCYCLECOMPLETE = text.includes(CYCLE_COMPLETE_MARKER);
938
+ if (!hasPRECOMMIT && !hasCYCLECOMPLETE)
939
+ return;
940
+ // Run the full sequence in one async flow (no timers):
941
+ // commit → wait → new session
942
+ // Use setTimeout(0) only to not block the hook return.
943
+ setTimeout(async () => {
944
+ // ── Step 1: PRE_COMMIT → execute /commit and await result ──
945
+ if (hasPRECOMMIT && !state.commitPending && sessionID) {
946
+ state.commitPending = true;
947
+ console.log("[opencode-immune] Multi-Cycle: PRE_COMMIT detected, executing /commit...");
937
948
  try {
938
- await state.input.client.session.command({
949
+ const commitResult = await state.input.client.session.command({
939
950
  body: {
940
951
  command: "/commit",
941
952
  arguments: "",
942
953
  },
943
954
  path: { id: sessionID },
944
955
  });
945
- console.log("[opencode-immune] Multi-Cycle: /commit executed successfully.");
956
+ console.log("[opencode-immune] Multi-Cycle: /commit completed.", commitResult?.response?.status ?? "");
946
957
  }
947
958
  catch (err) {
948
- console.error("[opencode-immune] Multi-Cycle: /commit failed:", err);
959
+ console.error("[opencode-immune] Multi-Cycle: /commit failed (continuing to next cycle anyway):", err);
949
960
  }
950
961
  finally {
951
962
  state.commitPending = false;
952
963
  }
953
- }, 2_000);
954
- }
955
- // ── CYCLE_COMPLETE: create new session ──
956
- if (text.includes(CYCLE_COMPLETE_MARKER)) {
957
- state.cycleCount++;
958
- if (state.cycleCount >= MAX_CYCLES) {
959
- console.log(`[opencode-immune] Multi-Cycle: MAX_CYCLES (${MAX_CYCLES}) reached. Not creating new session.`);
960
- await clearUltraworkMarker(state);
961
- return;
962
964
  }
963
- const taskMatch = text.match(NEXT_TASK_PATTERN);
964
- const nextTask = taskMatch?.[1]?.trim() ?? "Continue processing task backlog";
965
- console.log(`[opencode-immune] Multi-Cycle: CYCLE_COMPLETE detected in text.complete (cycle ${state.cycleCount}/${MAX_CYCLES}). ` +
966
- `Creating new session for: "${nextTask}"`);
967
- // Delay to let commit finish
968
- setTimeout(async () => {
965
+ // ── Step 2: CYCLE_COMPLETE → create new session ──
966
+ if (hasCYCLECOMPLETE) {
967
+ state.cycleCount++;
968
+ if (state.cycleCount >= MAX_CYCLES) {
969
+ console.log(`[opencode-immune] Multi-Cycle: MAX_CYCLES (${MAX_CYCLES}) reached. Not creating new session.`);
970
+ await clearUltraworkMarker(state);
971
+ return;
972
+ }
973
+ const taskMatch = text.match(NEXT_TASK_PATTERN);
974
+ const nextTask = taskMatch?.[1]?.trim() ?? "Continue processing task backlog";
975
+ console.log(`[opencode-immune] Multi-Cycle: CYCLE_COMPLETE detected (cycle ${state.cycleCount}/${MAX_CYCLES}). ` +
976
+ `Creating new session for: "${nextTask}"`);
969
977
  try {
970
978
  const createResult = await state.input.client.session.create({
971
979
  body: {
@@ -997,8 +1005,8 @@ function createTextCompleteHandler(state) {
997
1005
  catch (err) {
998
1006
  console.error("[opencode-immune] Multi-Cycle: Failed to create new session or send prompt:", err);
999
1007
  }
1000
- }, 8_000);
1001
- }
1008
+ }
1009
+ }, 0);
1002
1010
  };
1003
1011
  }
1004
1012
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-immune",
3
- "version": "1.0.20",
3
+ "version": "1.0.21",
4
4
  "description": "OpenCode plugin: session recovery, auto-retry, multi-cycle automation, context monitoring",
5
5
  "exports": {
6
6
  "./server": "./dist/plugin.js"