@opencode_weave/weave 0.3.2 → 0.4.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
CHANGED
|
@@ -118,6 +118,15 @@ function log(message, data) {
|
|
|
118
118
|
fs.appendFileSync(LOG_FILE, entry);
|
|
119
119
|
} catch {}
|
|
120
120
|
}
|
|
121
|
+
function logDelegation(event) {
|
|
122
|
+
const prefix = `[delegation:${event.phase}]`;
|
|
123
|
+
log(`${prefix} agent=${event.agent}`, {
|
|
124
|
+
sessionId: event.sessionId,
|
|
125
|
+
toolCallId: event.toolCallId,
|
|
126
|
+
durationMs: event.durationMs,
|
|
127
|
+
summary: event.summary
|
|
128
|
+
});
|
|
129
|
+
}
|
|
121
130
|
|
|
122
131
|
// src/config/loader.ts
|
|
123
132
|
function readJsoncFile(filePath) {
|
|
@@ -167,7 +176,8 @@ var AGENT_DISPLAY_NAMES = {
|
|
|
167
176
|
pattern: "pattern",
|
|
168
177
|
thread: "thread",
|
|
169
178
|
spindle: "spindle",
|
|
170
|
-
warp: "warp"
|
|
179
|
+
warp: "warp",
|
|
180
|
+
weft: "weft"
|
|
171
181
|
};
|
|
172
182
|
function getAgentDisplayName(configKey) {
|
|
173
183
|
const exactMatch = AGENT_DISPLAY_NAMES[configKey];
|
|
@@ -491,8 +501,9 @@ WHEN PLANNING (multi-step work):
|
|
|
491
501
|
- When plan ready: mark completed, add "Plan ready — /start-work"
|
|
492
502
|
|
|
493
503
|
WHEN DELEGATING TO AGENTS:
|
|
494
|
-
- Create "in_progress": "[agent]: [task]" (e.g. "thread: scan models")
|
|
495
|
-
-
|
|
504
|
+
- FIRST: Create "in_progress": "[agent]: [task]" (e.g. "thread: scan models")
|
|
505
|
+
- The todowrite call MUST come BEFORE the Task/call_weave_agent tool call in your response
|
|
506
|
+
- Mark "completed" AFTER summarizing what the agent returned
|
|
496
507
|
- If multiple delegations: one todo per active agent
|
|
497
508
|
|
|
498
509
|
WHEN DOING QUICK TASKS (no plan needed):
|
|
@@ -518,6 +529,34 @@ FORMAT RULES:
|
|
|
518
529
|
- Delegate aggressively to keep your context lean
|
|
519
530
|
</Delegation>
|
|
520
531
|
|
|
532
|
+
<DelegationNarration>
|
|
533
|
+
EVERY delegation MUST follow this pattern — no exceptions:
|
|
534
|
+
|
|
535
|
+
1. BEFORE delegating: Write a brief message to the user explaining what you're about to do:
|
|
536
|
+
- "Delegating to Thread to explore the authentication module..."
|
|
537
|
+
- "Asking Pattern to create an implementation plan for the new feature..."
|
|
538
|
+
- "Sending to Spindle to research the library's API docs..."
|
|
539
|
+
|
|
540
|
+
2. BEFORE the Task tool call: Create/update a sidebar todo (in_progress) for the delegation.
|
|
541
|
+
The todowrite call MUST appear BEFORE the Task tool call in your response.
|
|
542
|
+
This ensures the sidebar updates immediately, not after the subagent finishes.
|
|
543
|
+
|
|
544
|
+
3. AFTER the agent returns: Write a brief summary of what was found/produced:
|
|
545
|
+
- "Thread found 3 files related to auth: src/auth/login.ts, src/auth/session.ts, src/auth/middleware.ts"
|
|
546
|
+
- "Pattern saved the plan to .weave/plans/feature-x.md with 7 tasks"
|
|
547
|
+
- "Spindle confirmed the library supports streaming — docs at [url]"
|
|
548
|
+
|
|
549
|
+
4. Mark the delegation todo as "completed" after summarizing results.
|
|
550
|
+
|
|
551
|
+
DURATION HINTS — tell the user when something takes time:
|
|
552
|
+
- Pattern (planning): "This may take a moment — Pattern is researching the codebase and writing a detailed plan..."
|
|
553
|
+
- Spindle (web research): "Spindle is fetching external docs — this may take a moment..."
|
|
554
|
+
- Weft/Warp (review): "Running review — this will take a moment..."
|
|
555
|
+
- Thread (exploration): Fast — no duration hint needed.
|
|
556
|
+
|
|
557
|
+
The user should NEVER see a blank pause with no explanation. If you're about to call Task, WRITE SOMETHING FIRST.
|
|
558
|
+
</DelegationNarration>
|
|
559
|
+
|
|
521
560
|
<PlanWorkflow>
|
|
522
561
|
For complex tasks that benefit from structured planning before execution:
|
|
523
562
|
|
|
@@ -563,7 +602,8 @@ For security-relevant changes, also delegate to Warp:
|
|
|
563
602
|
</ReviewWorkflow>
|
|
564
603
|
|
|
565
604
|
<Style>
|
|
566
|
-
- Start immediately. No acknowledgments.
|
|
605
|
+
- Start immediately. No preamble acknowledgments (e.g., "Sure!", "Great question!").
|
|
606
|
+
- Delegation narration is NOT an acknowledgment — always narrate before/after delegating.
|
|
567
607
|
- Dense > verbose.
|
|
568
608
|
- Match user's communication style.
|
|
569
609
|
</Style>`
|
|
@@ -2057,7 +2097,7 @@ function createHooks(args) {
|
|
|
2057
2097
|
|
|
2058
2098
|
// src/plugin/plugin-interface.ts
|
|
2059
2099
|
function createPluginInterface(args) {
|
|
2060
|
-
const { pluginConfig, hooks, tools, configHandler, agents } = args;
|
|
2100
|
+
const { pluginConfig, hooks, tools, configHandler, agents, client } = args;
|
|
2061
2101
|
return {
|
|
2062
2102
|
tool: tools,
|
|
2063
2103
|
config: async (config) => {
|
|
@@ -2138,7 +2178,21 @@ ${result.contextInjection}`;
|
|
|
2138
2178
|
const sessionId = evt.properties?.sessionID ?? "";
|
|
2139
2179
|
if (sessionId) {
|
|
2140
2180
|
const result = hooks.workContinuation(sessionId);
|
|
2141
|
-
if (result.continuationPrompt) {
|
|
2181
|
+
if (result.continuationPrompt && client) {
|
|
2182
|
+
try {
|
|
2183
|
+
await client.session.promptAsync({
|
|
2184
|
+
path: { id: sessionId },
|
|
2185
|
+
body: {
|
|
2186
|
+
parts: [{ type: "text", text: result.continuationPrompt }]
|
|
2187
|
+
}
|
|
2188
|
+
});
|
|
2189
|
+
log("[work-continuation] Injected continuation prompt", { sessionId });
|
|
2190
|
+
} catch (err) {
|
|
2191
|
+
log("[work-continuation] Failed to inject continuation", { sessionId, error: String(err) });
|
|
2192
|
+
}
|
|
2193
|
+
} else if (result.continuationPrompt) {
|
|
2194
|
+
log("[work-continuation] continuationPrompt available but no client", { sessionId });
|
|
2195
|
+
}
|
|
2142
2196
|
}
|
|
2143
2197
|
}
|
|
2144
2198
|
},
|
|
@@ -2164,8 +2218,28 @@ ${result.contextInjection}`;
|
|
|
2164
2218
|
}
|
|
2165
2219
|
}
|
|
2166
2220
|
}
|
|
2221
|
+
if (input.tool === "task" && args2) {
|
|
2222
|
+
const agentArg = args2.agent ?? args2.description ?? "unknown";
|
|
2223
|
+
logDelegation({
|
|
2224
|
+
phase: "start",
|
|
2225
|
+
agent: agentArg,
|
|
2226
|
+
sessionId: input.sessionID,
|
|
2227
|
+
toolCallId: input.callID
|
|
2228
|
+
});
|
|
2229
|
+
}
|
|
2167
2230
|
},
|
|
2168
|
-
"tool.execute.after": async (
|
|
2231
|
+
"tool.execute.after": async (input, _output) => {
|
|
2232
|
+
if (input.tool === "task") {
|
|
2233
|
+
const inputArgs = input.args;
|
|
2234
|
+
const agentArg = inputArgs?.agent ?? "unknown";
|
|
2235
|
+
logDelegation({
|
|
2236
|
+
phase: "complete",
|
|
2237
|
+
agent: agentArg,
|
|
2238
|
+
sessionId: input.sessionID,
|
|
2239
|
+
toolCallId: input.callID
|
|
2240
|
+
});
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2169
2243
|
};
|
|
2170
2244
|
}
|
|
2171
2245
|
|
|
@@ -2182,7 +2256,8 @@ var WeavePlugin = async (ctx) => {
|
|
|
2182
2256
|
hooks,
|
|
2183
2257
|
tools: toolsResult.tools,
|
|
2184
2258
|
configHandler: managers.configHandler,
|
|
2185
|
-
agents: managers.agents
|
|
2259
|
+
agents: managers.agents,
|
|
2260
|
+
client: ctx.client
|
|
2186
2261
|
});
|
|
2187
2262
|
};
|
|
2188
2263
|
var src_default = WeavePlugin;
|
|
@@ -24,6 +24,26 @@ export interface TaskRecord {
|
|
|
24
24
|
* v1 tracks tasks in memory only — no real session spawning, polling, or
|
|
25
25
|
* tmux integration. Real concurrency control and SDK integration are
|
|
26
26
|
* deferred to a future release.
|
|
27
|
+
*
|
|
28
|
+
* ## Planned Delegation Tracking Integration
|
|
29
|
+
*
|
|
30
|
+
* Once a UI consumer exists (e.g. a `/status` slash command), this class
|
|
31
|
+
* should be wired into `plugin-interface.ts` as follows:
|
|
32
|
+
*
|
|
33
|
+
* 1. **`tool.execute.before`** — when `input.tool === "task"`, call
|
|
34
|
+
* `backgroundManager.spawn({ agentName: args.agent, prompt: args.description })`
|
|
35
|
+
* and store the returned task ID keyed by `input.callID`.
|
|
36
|
+
*
|
|
37
|
+
* 2. **`tool.execute.after`** — look up the task ID by `input.callID` and
|
|
38
|
+
* transition its status:
|
|
39
|
+
* - On success: set `status = "completed"` and `completedAt = new Date()`
|
|
40
|
+
* - On error: set `status = "failed"` and `error = err.message`
|
|
41
|
+
*
|
|
42
|
+
* 3. **`/status` command** — call `list({ status: "running" })` to surface
|
|
43
|
+
* all in-flight delegations to the user in real time.
|
|
44
|
+
*
|
|
45
|
+
* This is deferred until there is an OpenCode API to read task status back
|
|
46
|
+
* out of the plugin (e.g. a query hook or TUI panel).
|
|
27
47
|
*/
|
|
28
48
|
export declare class BackgroundManager {
|
|
29
49
|
private readonly tasks;
|
|
@@ -3,10 +3,12 @@ import type { AgentConfig } from "@opencode-ai/sdk";
|
|
|
3
3
|
import type { WeaveConfig } from "../config/schema";
|
|
4
4
|
import type { ConfigHandler } from "../managers/config-handler";
|
|
5
5
|
import type { CreatedHooks } from "../hooks/create-hooks";
|
|
6
|
+
import type { PluginContext } from "./types";
|
|
6
7
|
export declare function createPluginInterface(args: {
|
|
7
8
|
pluginConfig: WeaveConfig;
|
|
8
9
|
hooks: CreatedHooks;
|
|
9
10
|
tools: ToolsRecord;
|
|
10
11
|
configHandler: ConfigHandler;
|
|
11
12
|
agents: Record<string, AgentConfig>;
|
|
13
|
+
client?: PluginContext["client"];
|
|
12
14
|
}): PluginInterface;
|
package/dist/shared/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export type { DeepPartial, Brand } from "./types";
|
|
2
|
-
export { log, getLogFilePath } from "./log";
|
|
2
|
+
export { log, getLogFilePath, logDelegation } from "./log";
|
|
3
|
+
export type { DelegationEvent } from "./log";
|
|
3
4
|
export { AGENT_DISPLAY_NAMES, getAgentDisplayName, getAgentConfigKey, } from "./agent-display-names";
|
package/dist/shared/log.d.ts
CHANGED
|
@@ -1,2 +1,11 @@
|
|
|
1
1
|
export declare function log(message: string, data?: unknown): void;
|
|
2
2
|
export declare function getLogFilePath(): string;
|
|
3
|
+
export interface DelegationEvent {
|
|
4
|
+
phase: "start" | "complete" | "error";
|
|
5
|
+
agent: string;
|
|
6
|
+
sessionId?: string;
|
|
7
|
+
toolCallId?: string;
|
|
8
|
+
durationMs?: number;
|
|
9
|
+
summary?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function logDelegation(event: DelegationEvent): void;
|