opencode-immune 1.0.76 → 1.0.78
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/server.js +34 -75
- package/package.json +2 -2
package/dist/plugin/server.js
CHANGED
|
@@ -3777,7 +3777,7 @@ import { fileURLToPath } from "url";
|
|
|
3777
3777
|
import { createHash } from "crypto";
|
|
3778
3778
|
import { tmpdir } from "os";
|
|
3779
3779
|
import { execFile } from "child_process";
|
|
3780
|
-
var PLUGIN_VERSION = "1.0.
|
|
3780
|
+
var PLUGIN_VERSION = "1.0.78";
|
|
3781
3781
|
var PLUGIN_PACKAGE_NAME = "opencode-immune";
|
|
3782
3782
|
var PLUGIN_DIRNAME = dirname(fileURLToPath(import.meta.url));
|
|
3783
3783
|
function getServerAuthHeaders() {
|
|
@@ -3852,7 +3852,6 @@ function createState(input) {
|
|
|
3852
3852
|
providerRetryWatchdogs: /* @__PURE__ */ new Map(),
|
|
3853
3853
|
childFallbackRequests: /* @__PURE__ */ new Map(),
|
|
3854
3854
|
sessionErrorRetryCount: /* @__PURE__ */ new Map(),
|
|
3855
|
-
ultraworkPermissionSessions: /* @__PURE__ */ new Set(),
|
|
3856
3855
|
fallbackAgentByAgent: /* @__PURE__ */ new Map(),
|
|
3857
3856
|
baseAgentByFallbackAgent: /* @__PURE__ */ new Map(),
|
|
3858
3857
|
fallbackModelCandidates: [],
|
|
@@ -3889,23 +3888,6 @@ function createState(input) {
|
|
|
3889
3888
|
};
|
|
3890
3889
|
}
|
|
3891
3890
|
var ULTRAWORK_AGENT = "0-ultrawork";
|
|
3892
|
-
var ULTRAWORK_SESSION_PERMISSION = [
|
|
3893
|
-
{ permission: "read", pattern: "*", action: "allow" },
|
|
3894
|
-
{ permission: "edit", pattern: "*", action: "allow" },
|
|
3895
|
-
{ permission: "glob", pattern: "*", action: "allow" },
|
|
3896
|
-
{ permission: "grep", pattern: "*", action: "allow" },
|
|
3897
|
-
{ permission: "list", pattern: "*", action: "allow" },
|
|
3898
|
-
{ permission: "bash", pattern: "*", action: "allow" },
|
|
3899
|
-
{ permission: "task", pattern: "*", action: "allow" },
|
|
3900
|
-
{ permission: "external_directory", pattern: "*", action: "allow" },
|
|
3901
|
-
{ permission: "todowrite", pattern: "*", action: "allow" },
|
|
3902
|
-
{ permission: "question", pattern: "*", action: "allow" },
|
|
3903
|
-
{ permission: "webfetch", pattern: "*", action: "allow" },
|
|
3904
|
-
{ permission: "websearch", pattern: "*", action: "allow" },
|
|
3905
|
-
{ permission: "codesearch", pattern: "*", action: "allow" },
|
|
3906
|
-
{ permission: "lsp", pattern: "*", action: "allow" },
|
|
3907
|
-
{ permission: "skill", pattern: "*", action: "allow" }
|
|
3908
|
-
];
|
|
3909
3891
|
var DIAGNOSTIC_LOG_MAX_BYTES = 5 * 1024 * 1024;
|
|
3910
3892
|
var activeLogDirectory = null;
|
|
3911
3893
|
var MANAGED_SESSION_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
@@ -3935,8 +3917,7 @@ function isManagedRootUltraworkSession(state, sessionID) {
|
|
|
3935
3917
|
async function createManagedUltraworkSession(state, title) {
|
|
3936
3918
|
const result = await state.client.session.create({
|
|
3937
3919
|
directory: state.input.directory,
|
|
3938
|
-
title
|
|
3939
|
-
permission: ULTRAWORK_SESSION_PERMISSION
|
|
3920
|
+
title
|
|
3940
3921
|
});
|
|
3941
3922
|
if (result.error || !result.response.ok) {
|
|
3942
3923
|
throw new Error(
|
|
@@ -3984,31 +3965,7 @@ async function startAutoCycleInNewSession(state, options) {
|
|
|
3984
3965
|
state.autoResumeInFlight = false;
|
|
3985
3966
|
}
|
|
3986
3967
|
}
|
|
3987
|
-
async function applyUltraworkSessionPermissions(state, sessionID) {
|
|
3988
|
-
if (state.ultraworkPermissionSessions.has(sessionID)) return;
|
|
3989
|
-
try {
|
|
3990
|
-
const result = await state.client.session.update({
|
|
3991
|
-
directory: state.input.directory,
|
|
3992
|
-
sessionID,
|
|
3993
|
-
permission: ULTRAWORK_SESSION_PERMISSION
|
|
3994
|
-
});
|
|
3995
|
-
if (result.error || !result.response.ok) {
|
|
3996
|
-
pluginLog.warn(
|
|
3997
|
-
`[opencode-immune] Failed to apply ultrawork permissions to session ${sessionID}:`,
|
|
3998
|
-
result.error ?? result.response.status
|
|
3999
|
-
);
|
|
4000
|
-
return;
|
|
4001
|
-
}
|
|
4002
|
-
state.ultraworkPermissionSessions.add(sessionID);
|
|
4003
|
-
} catch (err) {
|
|
4004
|
-
pluginLog.warn(
|
|
4005
|
-
`[opencode-immune] Failed to apply ultrawork permissions to session ${sessionID}:`,
|
|
4006
|
-
err
|
|
4007
|
-
);
|
|
4008
|
-
}
|
|
4009
|
-
}
|
|
4010
3968
|
async function promptManagedSession(state, sessionID, text, options = {}) {
|
|
4011
|
-
await applyUltraworkSessionPermissions(state, sessionID);
|
|
4012
3969
|
const result = await state.client.session.promptAsync({
|
|
4013
3970
|
directory: state.input.directory,
|
|
4014
3971
|
sessionID,
|
|
@@ -4149,7 +4106,6 @@ async function addManagedUltraworkSession(state, sessionID, timestamp = Date.now
|
|
|
4149
4106
|
return;
|
|
4150
4107
|
}
|
|
4151
4108
|
state.managedUltraworkSessions.set(sessionID, nextRecord);
|
|
4152
|
-
await applyUltraworkSessionPermissions(state, sessionID);
|
|
4153
4109
|
}
|
|
4154
4110
|
async function addManagedChildSession(state, sessionID, parentSessionID, timestamp = Date.now()) {
|
|
4155
4111
|
const parent = state.managedUltraworkSessions.get(parentSessionID);
|
|
@@ -4202,7 +4158,6 @@ async function removeManagedUltraworkSession(state, sessionID, reason) {
|
|
|
4202
4158
|
cancelPendingSessionRetry(state, sessionID, reason);
|
|
4203
4159
|
cancelProviderRetryWatchdog(state, sessionID, reason);
|
|
4204
4160
|
state.sessionErrorRetryCount.delete(sessionID);
|
|
4205
|
-
state.ultraworkPermissionSessions.delete(sessionID);
|
|
4206
4161
|
const existed = state.managedUltraworkSessions.delete(sessionID);
|
|
4207
4162
|
if (!existed) return;
|
|
4208
4163
|
writePluginLog(
|
|
@@ -5835,6 +5790,18 @@ var PRE_COMMIT_MARKER = "0-ULTRAWORK: PRE_COMMIT";
|
|
|
5835
5790
|
var CYCLE_COMPLETE_MARKER = "0-ULTRAWORK: CYCLE_COMPLETE";
|
|
5836
5791
|
var NEXT_TASK_PATTERN = /Next task:\s*(.+)/;
|
|
5837
5792
|
var ALL_CYCLES_COMPLETE_MARKER = "0-ULTRAWORK: ALL_CYCLES_COMPLETE";
|
|
5793
|
+
async function commitCycleChanges(state, reason) {
|
|
5794
|
+
if (state.commitPending) return;
|
|
5795
|
+
state.commitPending = true;
|
|
5796
|
+
pluginLog.info(`[opencode-immune] Multi-Cycle: ${reason}, running git commit...`);
|
|
5797
|
+
try {
|
|
5798
|
+
await runGitCommit(state.input.directory);
|
|
5799
|
+
} catch (err) {
|
|
5800
|
+
pluginLog.error(`[opencode-immune] Multi-Cycle: git commit failed (${reason}):`, err);
|
|
5801
|
+
} finally {
|
|
5802
|
+
state.commitPending = false;
|
|
5803
|
+
}
|
|
5804
|
+
}
|
|
5838
5805
|
async function archiveProgress(directory) {
|
|
5839
5806
|
const progressPath = join(directory, "memory-bank", "progress.md");
|
|
5840
5807
|
try {
|
|
@@ -5942,17 +5909,7 @@ function createTextCompleteHandler(state) {
|
|
|
5942
5909
|
return;
|
|
5943
5910
|
}
|
|
5944
5911
|
if (text.includes(PRE_COMMIT_MARKER) && !text.includes(CYCLE_COMPLETE_MARKER)) {
|
|
5945
|
-
|
|
5946
|
-
state.commitPending = true;
|
|
5947
|
-
pluginLog.info("[opencode-immune] Multi-Cycle: PRE_COMMIT detected (standalone), running git commit...");
|
|
5948
|
-
try {
|
|
5949
|
-
await runGitCommit(state.input.directory);
|
|
5950
|
-
} catch (err) {
|
|
5951
|
-
pluginLog.error("[opencode-immune] Multi-Cycle: git commit failed (standalone):", err);
|
|
5952
|
-
} finally {
|
|
5953
|
-
state.commitPending = false;
|
|
5954
|
-
}
|
|
5955
|
-
}
|
|
5912
|
+
await commitCycleChanges(state, "PRE_COMMIT detected (standalone)");
|
|
5956
5913
|
return;
|
|
5957
5914
|
}
|
|
5958
5915
|
if (text.includes(CYCLE_COMPLETE_MARKER)) {
|
|
@@ -5961,18 +5918,7 @@ function createTextCompleteHandler(state) {
|
|
|
5961
5918
|
} catch (err) {
|
|
5962
5919
|
pluginLog.warn("[opencode-immune] Multi-Cycle: archive progress failed:", err);
|
|
5963
5920
|
}
|
|
5964
|
-
|
|
5965
|
-
state.commitPending = true;
|
|
5966
|
-
pluginLog.info("[opencode-immune] Multi-Cycle: CYCLE_COMPLETE detected, running git commit first...");
|
|
5967
|
-
try {
|
|
5968
|
-
await runGitCommit(state.input.directory);
|
|
5969
|
-
pluginLog.info("[opencode-immune] Multi-Cycle: git commit completed before new cycle.");
|
|
5970
|
-
} catch (err) {
|
|
5971
|
-
pluginLog.error("[opencode-immune] Multi-Cycle: git commit failed (continuing anyway):", err);
|
|
5972
|
-
} finally {
|
|
5973
|
-
state.commitPending = false;
|
|
5974
|
-
}
|
|
5975
|
-
}
|
|
5921
|
+
await commitCycleChanges(state, "CYCLE_COMPLETE detected");
|
|
5976
5922
|
state.cycleCount++;
|
|
5977
5923
|
if (state.cycleCount >= MAX_CYCLES) {
|
|
5978
5924
|
pluginLog.info(
|
|
@@ -6019,6 +5965,7 @@ function createTextCompleteHandler(state) {
|
|
|
6019
5965
|
`[opencode-immune] Multi-Cycle fallback: no CYCLE_COMPLETE marker detected for ${sessionID}, but tasks.md has no active task and backlog has pending items. Starting AUTO-CYCLE.`
|
|
6020
5966
|
);
|
|
6021
5967
|
try {
|
|
5968
|
+
await commitCycleChanges(state, "fallback AUTO-CYCLE before new session");
|
|
6022
5969
|
await refreshAutoCycleLock(state, sessionID);
|
|
6023
5970
|
await startAutoCycleInNewSession(
|
|
6024
5971
|
state,
|
|
@@ -6083,17 +6030,29 @@ function createPermissionAskHandler(state) {
|
|
|
6083
6030
|
state.recoveryContext = recovery;
|
|
6084
6031
|
await addManagedUltraworkSession(state, sessionID);
|
|
6085
6032
|
pluginLog.info(
|
|
6086
|
-
`[opencode-immune] Permission request recovered AUTO-RESUME session ${sessionID};
|
|
6033
|
+
`[opencode-immune] Permission request recovered AUTO-RESUME session ${sessionID}; tracking as managed ultrawork session.`
|
|
6087
6034
|
);
|
|
6088
6035
|
}
|
|
6089
|
-
|
|
6090
|
-
await writeDiagnosticLog(state, "permission:auto-allow", {
|
|
6036
|
+
await writeDiagnosticLog(state, "permission:ask", {
|
|
6091
6037
|
sessionID,
|
|
6092
|
-
|
|
6093
|
-
|
|
6038
|
+
status: output.status,
|
|
6039
|
+
permission: getPermissionType(input),
|
|
6040
|
+
patterns: getPermissionPatterns(input)
|
|
6094
6041
|
});
|
|
6095
6042
|
};
|
|
6096
6043
|
}
|
|
6044
|
+
function getPermissionType(input) {
|
|
6045
|
+
if (!input || typeof input !== "object") return void 0;
|
|
6046
|
+
const value = input;
|
|
6047
|
+
return typeof value.type === "string" ? value.type : typeof value.permission === "string" ? value.permission : void 0;
|
|
6048
|
+
}
|
|
6049
|
+
function getPermissionPatterns(input) {
|
|
6050
|
+
if (!input || typeof input !== "object") return [];
|
|
6051
|
+
const value = input;
|
|
6052
|
+
const source = value.pattern ?? value.patterns;
|
|
6053
|
+
if (Array.isArray(source)) return source.filter((item) => typeof item === "string");
|
|
6054
|
+
return typeof source === "string" ? [source] : [];
|
|
6055
|
+
}
|
|
6097
6056
|
async function server(input) {
|
|
6098
6057
|
const state = createState(input);
|
|
6099
6058
|
checkPluginUpdate(state).catch(() => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-immune",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.78",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenCode plugin: session recovery, auto-retry, multi-cycle automation, context monitoring",
|
|
6
6
|
"exports": {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"dist/plugin/server.js"
|
|
13
13
|
],
|
|
14
14
|
"scripts": {
|
|
15
|
-
"build": "esbuild plugin.ts --bundle --platform=node --format=esm --target=node22 --outfile=dist/plugin/server.js",
|
|
15
|
+
"build": "esbuild plugin.ts --bundle --platform=node --format=esm --target=node22 --outfile=dist/plugin/server.js && esbuild plugin.ts --bundle --platform=node --format=esm --target=node22 --outfile=dist/plugin.js",
|
|
16
16
|
"dev": "node ./node_modules/typescript/bin/tsc --project tsconfig.json --watch",
|
|
17
17
|
"prepublishOnly": "npm run build"
|
|
18
18
|
},
|