@opencode_weave/weave 0.7.0-preview.1 → 0.7.0
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/index.js +59 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -688,7 +688,12 @@ FORMAT RULES:
|
|
|
688
688
|
- Max 5 visible todos at any time
|
|
689
689
|
- in_progress = yellow highlight — use for ACTIVE work only
|
|
690
690
|
- Prefix delegations with agent name
|
|
691
|
-
|
|
691
|
+
|
|
692
|
+
BEFORE FINISHING (MANDATORY):
|
|
693
|
+
- ALWAYS issue a final todowrite before your last response
|
|
694
|
+
- Mark ALL in_progress items → "completed" (or "cancelled")
|
|
695
|
+
- Never leave in_progress items when done
|
|
696
|
+
- This is NON-NEGOTIABLE — skipping it breaks the UI
|
|
692
697
|
</SidebarTodos>`;
|
|
693
698
|
}
|
|
694
699
|
function buildDelegationSection(disabled) {
|
|
@@ -979,6 +984,12 @@ FORMAT RULES:
|
|
|
979
984
|
- Summary todo always present during execution
|
|
980
985
|
- Max 5 visible todos (1 summary + 1 in_progress + 2-3 pending)
|
|
981
986
|
- in_progress = yellow highlight — use for CURRENT task only
|
|
987
|
+
|
|
988
|
+
BEFORE FINISHING (MANDATORY):
|
|
989
|
+
- ALWAYS issue a final todowrite before your last response
|
|
990
|
+
- Mark ALL in_progress items → "completed" (or "cancelled")
|
|
991
|
+
- Never leave in_progress items when done
|
|
992
|
+
- This is NON-NEGOTIABLE — skipping it breaks the UI
|
|
982
993
|
</SidebarTodos>`;
|
|
983
994
|
}
|
|
984
995
|
function buildTapestryPlanExecutionSection(disabled = new Set) {
|
|
@@ -4705,10 +4716,12 @@ function generateMetricsReport(directory, state) {
|
|
|
4705
4716
|
}
|
|
4706
4717
|
|
|
4707
4718
|
// src/plugin/plugin-interface.ts
|
|
4719
|
+
var FINALIZE_TODOS_MARKER = "<!-- weave:finalize-todos -->";
|
|
4708
4720
|
function createPluginInterface(args) {
|
|
4709
4721
|
const { pluginConfig, hooks, tools, configHandler, agents, client, directory = "", tracker } = args;
|
|
4710
4722
|
const lastAssistantMessageText = new Map;
|
|
4711
4723
|
const lastUserMessageText = new Map;
|
|
4724
|
+
const todoFinalizedSessions = new Set;
|
|
4712
4725
|
return {
|
|
4713
4726
|
tool: tools,
|
|
4714
4727
|
config: async (config) => {
|
|
@@ -4791,6 +4804,9 @@ ${result.contextInjection}`;
|
|
|
4791
4804
|
`).trim() ?? "";
|
|
4792
4805
|
if (userText && sessionID) {
|
|
4793
4806
|
lastUserMessageText.set(sessionID, userText);
|
|
4807
|
+
if (!userText.includes(FINALIZE_TODOS_MARKER)) {
|
|
4808
|
+
todoFinalizedSessions.delete(sessionID);
|
|
4809
|
+
}
|
|
4794
4810
|
}
|
|
4795
4811
|
}
|
|
4796
4812
|
if (hooks.workflowCommand) {
|
|
@@ -4825,11 +4841,12 @@ ${cmdResult.contextInjection}`;
|
|
|
4825
4841
|
const isStartWork = promptText.includes("<session-context>");
|
|
4826
4842
|
const isContinuation = promptText.includes(CONTINUATION_MARKER);
|
|
4827
4843
|
const isWorkflowContinuation = promptText.includes(WORKFLOW_CONTINUATION_MARKER);
|
|
4844
|
+
const isTodoFinalize = promptText.includes(FINALIZE_TODOS_MARKER);
|
|
4828
4845
|
const isActiveWorkflow = (() => {
|
|
4829
4846
|
const wf = getActiveWorkflowInstance(directory);
|
|
4830
4847
|
return wf != null && wf.status === "running";
|
|
4831
4848
|
})();
|
|
4832
|
-
if (!isStartWork && !isContinuation && !isWorkflowContinuation && !isActiveWorkflow) {
|
|
4849
|
+
if (!isStartWork && !isContinuation && !isWorkflowContinuation && !isTodoFinalize && !isActiveWorkflow) {
|
|
4833
4850
|
const state = readWorkState(directory);
|
|
4834
4851
|
if (state && !state.paused) {
|
|
4835
4852
|
pauseWork(directory);
|
|
@@ -4866,6 +4883,7 @@ ${cmdResult.contextInjection}`;
|
|
|
4866
4883
|
if (event.type === "session.deleted") {
|
|
4867
4884
|
const evt = event;
|
|
4868
4885
|
clearSession2(evt.properties.info.id);
|
|
4886
|
+
todoFinalizedSessions.delete(evt.properties.info.id);
|
|
4869
4887
|
if (tracker && hooks.analyticsEnabled) {
|
|
4870
4888
|
try {
|
|
4871
4889
|
tracker.endSession(evt.properties.info.id);
|
|
@@ -4953,6 +4971,7 @@ ${cmdResult.contextInjection}`;
|
|
|
4953
4971
|
lastAssistantMessageText.set(part.sessionID, part.text);
|
|
4954
4972
|
}
|
|
4955
4973
|
}
|
|
4974
|
+
let continuationFired = false;
|
|
4956
4975
|
if (hooks.workflowContinuation && event.type === "session.idle") {
|
|
4957
4976
|
const evt = event;
|
|
4958
4977
|
const sessionId = evt.properties?.sessionID ?? "";
|
|
@@ -4997,6 +5016,7 @@ ${cmdResult.contextInjection}`;
|
|
|
4997
5016
|
}
|
|
4998
5017
|
});
|
|
4999
5018
|
log("[work-continuation] Injected continuation prompt", { sessionId });
|
|
5019
|
+
continuationFired = true;
|
|
5000
5020
|
} catch (err) {
|
|
5001
5021
|
log("[work-continuation] Failed to inject continuation", { sessionId, error: String(err) });
|
|
5002
5022
|
}
|
|
@@ -5005,6 +5025,43 @@ ${cmdResult.contextInjection}`;
|
|
|
5005
5025
|
}
|
|
5006
5026
|
}
|
|
5007
5027
|
}
|
|
5028
|
+
if (event.type === "session.idle" && client && !continuationFired) {
|
|
5029
|
+
const evt = event;
|
|
5030
|
+
const sessionId = evt.properties?.sessionID ?? "";
|
|
5031
|
+
if (sessionId && !todoFinalizedSessions.has(sessionId)) {
|
|
5032
|
+
try {
|
|
5033
|
+
const todosResponse = await client.session.todo({ path: { id: sessionId } });
|
|
5034
|
+
const todos = todosResponse.data ?? [];
|
|
5035
|
+
const hasInProgress = todos.some((t) => t.status === "in_progress");
|
|
5036
|
+
if (hasInProgress) {
|
|
5037
|
+
todoFinalizedSessions.add(sessionId);
|
|
5038
|
+
const inProgressItems = todos.filter((t) => t.status === "in_progress").map((t) => ` - "${t.content}"`).join(`
|
|
5039
|
+
`);
|
|
5040
|
+
await client.session.promptAsync({
|
|
5041
|
+
path: { id: sessionId },
|
|
5042
|
+
body: {
|
|
5043
|
+
parts: [
|
|
5044
|
+
{
|
|
5045
|
+
type: "text",
|
|
5046
|
+
text: `${FINALIZE_TODOS_MARKER}
|
|
5047
|
+
You have finished your work but left these todos as in_progress:
|
|
5048
|
+
${inProgressItems}
|
|
5049
|
+
|
|
5050
|
+
Use todowrite NOW to mark all of them as "completed" (or "cancelled" if abandoned). Do not do any other work — just update the todos and stop.`
|
|
5051
|
+
}
|
|
5052
|
+
]
|
|
5053
|
+
}
|
|
5054
|
+
});
|
|
5055
|
+
log("[todo-finalize] Injected finalize prompt for in_progress todos", {
|
|
5056
|
+
sessionId,
|
|
5057
|
+
count: todos.filter((t) => t.status === "in_progress").length
|
|
5058
|
+
});
|
|
5059
|
+
}
|
|
5060
|
+
} catch (err) {
|
|
5061
|
+
log("[todo-finalize] Failed to check/finalize todos (non-fatal)", { sessionId, error: String(err) });
|
|
5062
|
+
}
|
|
5063
|
+
}
|
|
5064
|
+
}
|
|
5008
5065
|
},
|
|
5009
5066
|
"tool.execute.before": async (input, _output) => {
|
|
5010
5067
|
const toolArgs = _output.args;
|