@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
- - Mark "completed" when agent returns results
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 (_input, _output) => {}
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;
@@ -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";
@@ -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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencode_weave/weave",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "Weave — lean OpenCode plugin with multi-agent orchestration",
5
5
  "author": "Weave",
6
6
  "license": "MIT",