@prevalentware/opencode-goal-plugin 0.1.50 → 0.1.51
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/README.md +1 -1
- package/dist/server.js +70 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -178,7 +178,7 @@ Defaults:
|
|
|
178
178
|
- `auto_continue`: `true`
|
|
179
179
|
- `defer_while_tasks_active`: `true`; when enabled, goal auto-continuation waits for active OpenCode Task child sessions and their orchestrator reconciliation before sending the next goal prompt. A deferral re-checks child sessions on a short timer, so a goal deferred by a task never depends on a further idle event to resume.
|
|
180
180
|
- `max_task_block_seconds`: `900`; wall-clock ceiling on how long a single Task child session may defer goal continuation. A child that stays listed but never reports a terminal state, or a terminal child whose result is never reconciled, stops blocking once the ceiling passes. Set a smaller value for shorter subagents, `0` to remove the ceiling, or disable deferral entirely with `defer_while_tasks_active: false`.
|
|
181
|
-
- `max_auto_turns`: `25`
|
|
181
|
+
- `max_auto_turns`: `25`; explicitly resuming a goal with `/goal resume` or `/resume_goal` after it reaches this limit starts a fresh auto-turn window. Token usage and elapsed-time usage are preserved.
|
|
182
182
|
- `min_continue_interval_seconds`: `3`
|
|
183
183
|
- Fast V2 executions that finish inside this interval schedule a delayed continuation; they do not require another user message to wake up.
|
|
184
184
|
- `max_turn_time`: unset by default; set a positive number of seconds to retry one active-goal continuation prompt when a model turn remains busy for that long. Each new busy event resets the watchdog. Idle, built-in retry, session deletion, active Task children, and restricted agents suppress the retry. Watchdog retries are independent of `min_continue_interval_seconds` and never consume auto-turn or no-progress budgets, but recognized transport failures still count toward the `max_prompt_failures` ceiling.
|
package/dist/server.js
CHANGED
|
@@ -132,6 +132,7 @@ var MAX_LISTED_GOALS = 50;
|
|
|
132
132
|
var CHECKPOINT_CHAR_LIMIT = 280;
|
|
133
133
|
var DEFAULT_NO_PROGRESS_TOKEN_THRESHOLD = 50;
|
|
134
134
|
var DEFAULT_MAX_NO_PROGRESS_TURNS = 2;
|
|
135
|
+
var MAX_AUTO_CONTINUES_STOP_REASON_PREFIX = "max auto-continues reached (";
|
|
135
136
|
var PLAN_MODE_STOP_REASON = "plan mode";
|
|
136
137
|
var PLAN_MODE_BLOCKER = "Goal execution is paused while the session is in Plan mode. Switch to Build mode and resume the goal to continue.";
|
|
137
138
|
var NullableString = Schema.NullOr(Schema.String);
|
|
@@ -689,7 +690,7 @@ async function pauseGoalForPlanMode(sessionID) {
|
|
|
689
690
|
return snapshot(goal);
|
|
690
691
|
});
|
|
691
692
|
}
|
|
692
|
-
async function setGoalStatus(sessionID, status, agent) {
|
|
693
|
+
async function setGoalStatus(sessionID, status, agent, options) {
|
|
693
694
|
const agentValue = typeof agent === "string" && agent.trim() ? agent.trim() : null;
|
|
694
695
|
return mutate((state) => {
|
|
695
696
|
const goal = state.goals[sessionID];
|
|
@@ -701,10 +702,12 @@ async function setGoalStatus(sessionID, status, agent) {
|
|
|
701
702
|
return snapshot(goal);
|
|
702
703
|
if (status === "paused" && goal.status !== "active")
|
|
703
704
|
return snapshot(goal);
|
|
705
|
+
const resumesAutoTurnLimit = options?.resetAutoTurnLimit === true && status === "active" && goal.status === "usageLimited" && goal.stopReason?.startsWith(MAX_AUTO_CONTINUES_STOP_REASON_PREFIX) === true;
|
|
704
706
|
accountWallClock(goal);
|
|
705
707
|
goal.status = status;
|
|
706
708
|
goal.updatedAt = nowSeconds();
|
|
707
709
|
goal.lastAccountedAt = status === "active" ? goal.updatedAt : null;
|
|
710
|
+
goal.autoTurns = resumesAutoTurnLimit ? 0 : goal.autoTurns;
|
|
708
711
|
goal.continuationFailures = status === "active" ? 0 : goal.continuationFailures;
|
|
709
712
|
goal.pendingAttempt = status === "active" ? null : goal.pendingAttempt;
|
|
710
713
|
goal.noProgressTurns = status === "active" ? 0 : goal.noProgressTurns;
|
|
@@ -1053,7 +1056,7 @@ function maybeStopForUsageLimit(goal, defaultMaxAutoTurns, now = nowSeconds()) {
|
|
|
1053
1056
|
if (effectiveMaxAutoTurns > 0 && goal.autoTurns >= effectiveMaxAutoTurns) {
|
|
1054
1057
|
goal.status = "usageLimited";
|
|
1055
1058
|
goal.lastAccountedAt = null;
|
|
1056
|
-
goal.stopReason =
|
|
1059
|
+
goal.stopReason = `${MAX_AUTO_CONTINUES_STOP_REASON_PREFIX}${effectiveMaxAutoTurns})`;
|
|
1057
1060
|
goal.lastStatus = `${goal.stopReason}; wrap-up required.`;
|
|
1058
1061
|
pushHistory(goal, "limited", goal.lastStatus);
|
|
1059
1062
|
return true;
|
|
@@ -1617,7 +1620,7 @@ ${budgetLines(goal, locale)}
|
|
|
1617
1620
|
\u72B6\u6001\uFF1A${presentGoalStatus(goal.status, locale)}
|
|
1618
1621
|
\u505C\u6B62\u539F\u56E0\uFF1A${presentGoalStopReason(goal.stopReason ?? "goal limit reached", locale)}
|
|
1619
1622
|
|
|
1620
|
-
\u4E0D\u8981\u4E3A\u6B64\u76EE\u6807\u5F00\u59CB\u65B0\u7684\u5B9E\u8D28\u6027\u5DE5\u4F5C\u3002\u5C3D\u5FEB\u7ED3\u675F\u672C\u8F6E\uFF1A\u4F7F\u7528\u7B80\u4F53\u4E2D\u6587\u603B\u7ED3\u6709\u6548\u8FDB\u5C55\uFF0C\u6307\u51FA\u5269\u4F59\u5DE5\u4F5C\u6216\u963B\u585E\u9879\uFF0C\u5E76\u7ED9\u7528\u6237\u4E00\u4E2A\u6E05\u6670\u7684\u4E0B\u4E00\u6B65\u3002\u9664\u975E\u76EE\u6807\u786E\u5B9E\u5DF2\u7ECF\u5B8C\u6210\uFF0C\u5426\u5219\u4E0D\u8981\u8C03\u7528 update_goal\u3002`;
|
|
1623
|
+
\u4E0D\u8981\u4E3A\u6B64\u76EE\u6807\u5F00\u59CB\u65B0\u7684\u5B9E\u8D28\u6027\u5DE5\u4F5C\u3002\u4E0D\u8981\u8C03\u7528 update_goal_status \u6765\u7EE7\u7EED\u76EE\u6807\uFF1B\u53EA\u6709\u7528\u6237\u660E\u786E\u53D1\u51FA\u7EE7\u7EED\u547D\u4EE4\u540E\u624D\u80FD\u7EE7\u7EED\u3002\u5C3D\u5FEB\u7ED3\u675F\u672C\u8F6E\uFF1A\u4F7F\u7528\u7B80\u4F53\u4E2D\u6587\u603B\u7ED3\u6709\u6548\u8FDB\u5C55\uFF0C\u6307\u51FA\u5269\u4F59\u5DE5\u4F5C\u6216\u963B\u585E\u9879\uFF0C\u5E76\u7ED9\u7528\u6237\u4E00\u4E2A\u6E05\u6670\u7684\u4E0B\u4E00\u6B65\u3002\u9664\u975E\u76EE\u6807\u786E\u5B9E\u5DF2\u7ECF\u5B8C\u6210\uFF0C\u5426\u5219\u4E0D\u8981\u8C03\u7528 update_goal\u3002`;
|
|
1621
1624
|
}
|
|
1622
1625
|
return `The active session goal has reached a safety limit.
|
|
1623
1626
|
|
|
@@ -1633,7 +1636,7 @@ ${budgetLines(goal, locale)}
|
|
|
1633
1636
|
Status: ${goal.status}
|
|
1634
1637
|
Stop reason: ${goal.stopReason ?? "goal limit reached"}
|
|
1635
1638
|
|
|
1636
|
-
Do not start new substantive work for this goal. Wrap up this turn soon: summarize useful progress, identify remaining work or blockers, and leave the user with a clear next step. Do not call update_goal unless the goal is actually complete.`;
|
|
1639
|
+
Do not start new substantive work for this goal. Do not call update_goal_status to resume it; only an explicit user resume command may continue the goal. Wrap up this turn soon: summarize useful progress, identify remaining work or blockers, and leave the user with a clear next step. Do not call update_goal unless the goal is actually complete.`;
|
|
1637
1640
|
}
|
|
1638
1641
|
function systemReminder(locale = "en") {
|
|
1639
1642
|
if (locale === "zh-CN") {
|
|
@@ -1890,6 +1893,10 @@ Ignore any command arguments. Call get_goal first, then handle only this resume
|
|
|
1890
1893
|
|
|
1891
1894
|
Do not create, edit, clear, complete, or mark a goal unmet.`;
|
|
1892
1895
|
}
|
|
1896
|
+
function isExplicitResumePrompt(text, commandName, locale, messages) {
|
|
1897
|
+
const value = text.trim();
|
|
1898
|
+
return value === goalStatusCommandTemplate("resume_goal", locale) || value === goalCommandTemplate(commandName, locale).replace("$ARGUMENTS", "resume") || value === messages.tui.resumePrompt;
|
|
1899
|
+
}
|
|
1893
1900
|
function goalCommandDefinitions(commandName, locale = "en") {
|
|
1894
1901
|
const messages = messagesFor(locale);
|
|
1895
1902
|
return [
|
|
@@ -2662,10 +2669,11 @@ async function closeGoalFromTool(input, context, services) {
|
|
|
2662
2669
|
return JSON.stringify({ goal, unmet_report: report }, null, 2);
|
|
2663
2670
|
}
|
|
2664
2671
|
async function updateGoalStatusFromTool(input, context, services) {
|
|
2672
|
+
const resetAutoTurnLimit = input.status === "active" && services.consumeAutoTurnReset(context.sessionID);
|
|
2665
2673
|
if (input.status === "active" && services.isPlanAgent(context.agent)) {
|
|
2666
2674
|
throw new Error(services.messages.notices.cannotResumeInPlan);
|
|
2667
2675
|
}
|
|
2668
|
-
const goal = await setGoalStatus(context.sessionID, input.status, typeof context.agent === "string" ? context.agent : null);
|
|
2676
|
+
const goal = await setGoalStatus(context.sessionID, input.status, typeof context.agent === "string" ? context.agent : null, { resetAutoTurnLimit });
|
|
2669
2677
|
return JSON.stringify({ goal }, null, 2);
|
|
2670
2678
|
}
|
|
2671
2679
|
function v2ObjectSchema(properties, required = []) {
|
|
@@ -2737,10 +2745,18 @@ var server = async ({ client }, options) => {
|
|
|
2737
2745
|
const nativeRetrySessions = new Set;
|
|
2738
2746
|
const locallyDeliveredPendingSessions = new Set;
|
|
2739
2747
|
const toolAttempts = new Map;
|
|
2748
|
+
const explicitResumeRequests = new Set;
|
|
2740
2749
|
const watchdogRescuedSessions = new Set;
|
|
2741
2750
|
const planAgents = restrictedAgentSet(options);
|
|
2742
2751
|
const isPlanAgent = (agent) => typeof agent === "string" && planAgents.has(agent.trim().toLowerCase());
|
|
2743
|
-
const goalServices = {
|
|
2752
|
+
const goalServices = {
|
|
2753
|
+
options: options ?? {},
|
|
2754
|
+
locale,
|
|
2755
|
+
messages,
|
|
2756
|
+
isPlanAgent,
|
|
2757
|
+
maxObjectiveChars: objectiveChars,
|
|
2758
|
+
consumeAutoTurnReset: (sessionID) => explicitResumeRequests.delete(sessionID)
|
|
2759
|
+
};
|
|
2744
2760
|
const stopStateRecoveryReporting = onStateRecovery(statePath(), async ({ stateFile, quarantineFile, outcome, error }) => {
|
|
2745
2761
|
await client.app?.log?.({
|
|
2746
2762
|
body: {
|
|
@@ -3014,6 +3030,7 @@ var server = async ({ client }, options) => {
|
|
|
3014
3030
|
locallyDeliveredPendingSessions.clear();
|
|
3015
3031
|
nativeRetrySessions.clear();
|
|
3016
3032
|
toolAttempts.clear();
|
|
3033
|
+
explicitResumeRequests.clear();
|
|
3017
3034
|
},
|
|
3018
3035
|
async config(config) {
|
|
3019
3036
|
if (!registerCommand)
|
|
@@ -3116,7 +3133,10 @@ var server = async ({ client }, options) => {
|
|
|
3116
3133
|
},
|
|
3117
3134
|
async "command.execute.before"(input, output) {
|
|
3118
3135
|
if (input.command === commandName) {
|
|
3119
|
-
escapeGoalCommandArguments(output, goalCommandTemplate(commandName, locale), input.arguments);
|
|
3136
|
+
const sanitized = escapeGoalCommandArguments(output, goalCommandTemplate(commandName, locale), input.arguments);
|
|
3137
|
+
if (sanitized && input.arguments.trim().toLowerCase() === "resume") {
|
|
3138
|
+
explicitResumeRequests.add(input.sessionID);
|
|
3139
|
+
}
|
|
3120
3140
|
return;
|
|
3121
3141
|
}
|
|
3122
3142
|
if (input.command !== "pause_goal" && input.command !== "resume_goal")
|
|
@@ -3124,6 +3144,8 @@ var server = async ({ client }, options) => {
|
|
|
3124
3144
|
const template = goalStatusCommandTemplate(input.command, locale);
|
|
3125
3145
|
if (!sanitizeGoalStatusCommandParts(output, template))
|
|
3126
3146
|
return;
|
|
3147
|
+
if (input.command === "resume_goal")
|
|
3148
|
+
explicitResumeRequests.add(input.sessionID);
|
|
3127
3149
|
if (input.command !== "pause_goal")
|
|
3128
3150
|
return;
|
|
3129
3151
|
const goal = await getGoal(input.sessionID);
|
|
@@ -3164,7 +3186,13 @@ var server = async ({ client }, options) => {
|
|
|
3164
3186
|
async "chat.message"(input, output) {
|
|
3165
3187
|
const sessionID = typeof input?.sessionID === "string" ? input.sessionID : output.message?.sessionID;
|
|
3166
3188
|
const agent = typeof input?.agent === "string" && input.agent.trim() ? input.agent : output.message?.agent;
|
|
3167
|
-
if (typeof sessionID !== "string"
|
|
3189
|
+
if (typeof sessionID !== "string")
|
|
3190
|
+
return;
|
|
3191
|
+
explicitResumeRequests.delete(sessionID);
|
|
3192
|
+
if (output.parts?.some((part) => isExplicitResumePrompt(textFromPart(part), commandName, locale, messages))) {
|
|
3193
|
+
explicitResumeRequests.add(sessionID);
|
|
3194
|
+
}
|
|
3195
|
+
if (typeof agent !== "string" || !agent.trim())
|
|
3168
3196
|
return;
|
|
3169
3197
|
await recordPromptAgent(sessionID, agent);
|
|
3170
3198
|
},
|
|
@@ -3215,6 +3243,7 @@ var server = async ({ client }, options) => {
|
|
|
3215
3243
|
if (status.type === "busy")
|
|
3216
3244
|
await markPendingContinuationStarted(sessionID);
|
|
3217
3245
|
if (status.type === "idle") {
|
|
3246
|
+
explicitResumeRequests.delete(sessionID);
|
|
3218
3247
|
busySessions.delete(sessionID);
|
|
3219
3248
|
nativeRetrySessions.delete(sessionID);
|
|
3220
3249
|
clearTurnWatchdog(sessionID);
|
|
@@ -3229,6 +3258,7 @@ var server = async ({ client }, options) => {
|
|
|
3229
3258
|
}
|
|
3230
3259
|
}
|
|
3231
3260
|
if (sessionID && eventType === "session.idle") {
|
|
3261
|
+
explicitResumeRequests.delete(sessionID);
|
|
3232
3262
|
busySessions.delete(sessionID);
|
|
3233
3263
|
nativeRetrySessions.delete(sessionID);
|
|
3234
3264
|
clearTurnWatchdog(sessionID);
|
|
@@ -3236,6 +3266,7 @@ var server = async ({ client }, options) => {
|
|
|
3236
3266
|
taskTracker.observeSessionStatus(sessionID, "idle");
|
|
3237
3267
|
}
|
|
3238
3268
|
if (sessionID && eventType === "session.error") {
|
|
3269
|
+
explicitResumeRequests.delete(sessionID);
|
|
3239
3270
|
const inNativeRetry = nativeRetrySessions.has(sessionID);
|
|
3240
3271
|
busySessions.delete(sessionID);
|
|
3241
3272
|
clearTurnWatchdog(sessionID);
|
|
@@ -3265,6 +3296,7 @@ var server = async ({ client }, options) => {
|
|
|
3265
3296
|
}
|
|
3266
3297
|
}
|
|
3267
3298
|
if (sessionID && eventType === "session.deleted") {
|
|
3299
|
+
explicitResumeRequests.delete(sessionID);
|
|
3268
3300
|
busySessions.delete(sessionID);
|
|
3269
3301
|
clearTurnWatchdog(sessionID);
|
|
3270
3302
|
watchdogRescuedSessions.delete(sessionID);
|
|
@@ -3323,6 +3355,7 @@ async function setupV2(context) {
|
|
|
3323
3355
|
const locallyDeliveredPendingSessions = new Set;
|
|
3324
3356
|
const watchdogRescuedSessions = new Set;
|
|
3325
3357
|
const toolAttempts = new Map;
|
|
3358
|
+
const explicitResumeRequests = new Set;
|
|
3326
3359
|
const planAgents = restrictedAgentSet(options);
|
|
3327
3360
|
const isPlanAgent = (agent) => typeof agent === "string" && planAgents.has(agent.trim().toLowerCase());
|
|
3328
3361
|
const activeContinuationsV2 = new Set;
|
|
@@ -3336,6 +3369,7 @@ async function setupV2(context) {
|
|
|
3336
3369
|
messages,
|
|
3337
3370
|
maxObjectiveChars: objectiveChars,
|
|
3338
3371
|
isPlanAgent,
|
|
3372
|
+
consumeAutoTurnReset: (sessionID) => explicitResumeRequests.delete(sessionID),
|
|
3339
3373
|
initializeUsage: async (sessionID) => {
|
|
3340
3374
|
try {
|
|
3341
3375
|
await accountUsage(sessionID, stepTokenSums.get(sessionID) ?? 0, { cumulative: true, source: "v2.steps" });
|
|
@@ -3706,6 +3740,7 @@ async function setupV2(context) {
|
|
|
3706
3740
|
await markPendingContinuationStarted(sessionID);
|
|
3707
3741
|
}
|
|
3708
3742
|
if (status.type === "idle") {
|
|
3743
|
+
explicitResumeRequests.delete(sessionID);
|
|
3709
3744
|
busySessions.delete(sessionID);
|
|
3710
3745
|
nativeRetrySessions.delete(sessionID);
|
|
3711
3746
|
clearTurnWatchdog(sessionID);
|
|
@@ -3728,6 +3763,7 @@ async function setupV2(context) {
|
|
|
3728
3763
|
case "session.execution.succeeded":
|
|
3729
3764
|
case "session.idle": {
|
|
3730
3765
|
if (sessionID) {
|
|
3766
|
+
explicitResumeRequests.delete(sessionID);
|
|
3731
3767
|
busySessions.delete(sessionID);
|
|
3732
3768
|
nativeRetrySessions.delete(sessionID);
|
|
3733
3769
|
clearTurnWatchdog(sessionID);
|
|
@@ -3744,6 +3780,7 @@ async function setupV2(context) {
|
|
|
3744
3780
|
case "session.execution.interrupted": {
|
|
3745
3781
|
if (!sessionID)
|
|
3746
3782
|
return;
|
|
3783
|
+
explicitResumeRequests.delete(sessionID);
|
|
3747
3784
|
stoppedExecutions.add(sessionID);
|
|
3748
3785
|
busySessions.delete(sessionID);
|
|
3749
3786
|
nativeRetrySessions.delete(sessionID);
|
|
@@ -3757,6 +3794,7 @@ async function setupV2(context) {
|
|
|
3757
3794
|
case "session.execution.failed": {
|
|
3758
3795
|
if (!sessionID)
|
|
3759
3796
|
return;
|
|
3797
|
+
explicitResumeRequests.delete(sessionID);
|
|
3760
3798
|
nativeRetrySessions.delete(sessionID);
|
|
3761
3799
|
busySessions.delete(sessionID);
|
|
3762
3800
|
clearTurnWatchdog(sessionID);
|
|
@@ -3791,6 +3829,7 @@ async function setupV2(context) {
|
|
|
3791
3829
|
case "session.deleted": {
|
|
3792
3830
|
if (!sessionID)
|
|
3793
3831
|
return;
|
|
3832
|
+
explicitResumeRequests.delete(sessionID);
|
|
3794
3833
|
stoppedExecutions.delete(sessionID);
|
|
3795
3834
|
sessionOwnership.delete(sessionID);
|
|
3796
3835
|
busySessions.delete(sessionID);
|
|
@@ -3956,6 +3995,9 @@ async function setupV2(context) {
|
|
|
3956
3995
|
cancelScheduledContinuation(input.sessionID);
|
|
3957
3996
|
clearTurnWatchdog(input.sessionID);
|
|
3958
3997
|
}
|
|
3998
|
+
if (command.action === "resume" || command.action === "goal" && input.prompt.text.trim().toLowerCase() === "resume") {
|
|
3999
|
+
explicitResumeRequests.add(input.sessionID);
|
|
4000
|
+
}
|
|
3959
4001
|
let forwardedPrompt = {};
|
|
3960
4002
|
if (command.action === "goal") {
|
|
3961
4003
|
const stripMention = ({ mention: _mention, ...attachment }) => attachment;
|
|
@@ -3977,25 +4019,31 @@ async function setupV2(context) {
|
|
|
3977
4019
|
});
|
|
3978
4020
|
}
|
|
3979
4021
|
}));
|
|
4022
|
+
}
|
|
4023
|
+
if (registerCommand) {
|
|
3980
4024
|
registrations.push(await context.session.hook("prompt", async (input) => {
|
|
3981
4025
|
if (typeof input.sessionID === "string")
|
|
3982
4026
|
markSessionOwnership(input.sessionID, true);
|
|
4027
|
+
explicitResumeRequests.delete(input.sessionID);
|
|
3983
4028
|
const pauseTemplate = goalStatusCommandTemplate("pause_goal", locale);
|
|
3984
4029
|
const resumeTemplate = goalStatusCommandTemplate("resume_goal", locale);
|
|
3985
4030
|
const template = input.prompt.text.startsWith(pauseTemplate) ? pauseTemplate : input.prompt.text.startsWith(resumeTemplate) ? resumeTemplate : null;
|
|
3986
|
-
if (
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
4031
|
+
if (template) {
|
|
4032
|
+
input.prompt.text = template;
|
|
4033
|
+
delete input.prompt.files;
|
|
4034
|
+
delete input.prompt.agents;
|
|
4035
|
+
delete input.prompt.skills;
|
|
4036
|
+
if (template === pauseTemplate) {
|
|
4037
|
+
const goal = await getGoal(input.sessionID);
|
|
4038
|
+
if (goal?.status === "active")
|
|
4039
|
+
await setGoalStatus(input.sessionID, "paused");
|
|
4040
|
+
cancelScheduledContinuation(input.sessionID);
|
|
4041
|
+
clearTurnWatchdog(input.sessionID);
|
|
4042
|
+
}
|
|
4043
|
+
}
|
|
4044
|
+
if (isExplicitResumePrompt(input.prompt.text, commandName, locale, messages)) {
|
|
4045
|
+
explicitResumeRequests.add(input.sessionID);
|
|
4046
|
+
}
|
|
3999
4047
|
}));
|
|
4000
4048
|
}
|
|
4001
4049
|
registrations.push(await context.tool.transform((draft) => {
|
|
@@ -4114,6 +4162,7 @@ async function setupV2(context) {
|
|
|
4114
4162
|
locallyDeliveredPendingSessions.clear();
|
|
4115
4163
|
watchdogRescuedSessions.clear();
|
|
4116
4164
|
toolAttempts.clear();
|
|
4165
|
+
explicitResumeRequests.clear();
|
|
4117
4166
|
for (const registration of registrations)
|
|
4118
4167
|
await registration.dispose();
|
|
4119
4168
|
const termination = Promise.allSettled([consumer, eventIterator?.return?.()]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prevalentware/opencode-goal-plugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.51",
|
|
4
4
|
"description": "OpenCode goal plugin that adds Codex-style long-running goal mode, /goal commands, persistence, and TUI status for AI coding agents.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"opencode",
|