agent-worker 0.5.0 → 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.
@@ -1,3 +1,3 @@
1
- import { C as getModelForBackend, S as SDK_MODEL_ALIASES, _ as execWithIdleTimeout, a as createMockBackend, b as CODEX_MODEL_MAP, c as CodexBackend, d as codexAdapter, f as createStreamParser, g as IdleTimeoutError, h as formatEvent, i as MockAIBackend, l as ClaudeCodeBackend, m as extractCodexResult, n as createBackend, o as SdkBackend, p as extractClaudeResult, r as listBackends, s as CursorBackend, t as checkBackends, u as claudeAdapter, v as BACKEND_DEFAULT_MODELS, x as CURSOR_MODEL_MAP, y as CLAUDE_MODEL_MAP } from "./backends-CEYiMUgC.mjs";
1
+ import { C as getModelForBackend, S as SDK_MODEL_ALIASES, _ as execWithIdleTimeout, a as createMockBackend, b as CODEX_MODEL_MAP, c as CodexBackend, d as codexAdapter, f as createStreamParser, g as IdleTimeoutError, h as formatEvent, i as MockAIBackend, l as ClaudeCodeBackend, m as extractCodexResult, n as createBackend, o as SdkBackend, p as extractClaudeResult, r as listBackends, s as CursorBackend, t as checkBackends, u as claudeAdapter, v as BACKEND_DEFAULT_MODELS, x as CURSOR_MODEL_MAP, y as CLAUDE_MODEL_MAP } from "./backends-Hclwb_Zp.mjs";
2
2
 
3
3
  export { listBackends };
@@ -359,6 +359,70 @@ async function execWithIdleTimeout(options) {
359
359
  }
360
360
  }
361
361
  /**
362
+ * Execute a command with idle timeout and return abort controller
363
+ * This version returns both the promise and an abort function for external control
364
+ */
365
+ function execWithIdleTimeoutAbortable(options) {
366
+ const { command, args, cwd, onStdout } = options;
367
+ const timeout = Math.max(options.timeout, MIN_TIMEOUT_MS);
368
+ let idleTimedOut = false;
369
+ let timer;
370
+ let stdout = "";
371
+ let stderr = "";
372
+ let isAborted = false;
373
+ const subprocess = execa(command, args, {
374
+ cwd,
375
+ stdin: "ignore",
376
+ buffer: false
377
+ });
378
+ const resetTimer = () => {
379
+ clearTimeout(timer);
380
+ timer = setTimeout(() => {
381
+ idleTimedOut = true;
382
+ subprocess.kill();
383
+ }, timeout);
384
+ };
385
+ subprocess.stdout?.on("data", (chunk) => {
386
+ const text = chunk.toString();
387
+ stdout += text;
388
+ if (onStdout) onStdout(text);
389
+ resetTimer();
390
+ });
391
+ subprocess.stderr?.on("data", (chunk) => {
392
+ stderr += chunk.toString();
393
+ resetTimer();
394
+ });
395
+ resetTimer();
396
+ const abort = () => {
397
+ if (!isAborted) {
398
+ isAborted = true;
399
+ clearTimeout(timer);
400
+ subprocess.kill("SIGTERM");
401
+ setTimeout(() => {
402
+ if (!subprocess.killed) subprocess.kill("SIGKILL");
403
+ }, 1e3);
404
+ }
405
+ };
406
+ return {
407
+ promise: (async () => {
408
+ try {
409
+ await subprocess;
410
+ clearTimeout(timer);
411
+ return {
412
+ stdout: stdout.trimEnd(),
413
+ stderr: stderr.trimEnd()
414
+ };
415
+ } catch (error) {
416
+ clearTimeout(timer);
417
+ if (isAborted) throw new Error("Process aborted by user");
418
+ if (idleTimedOut) throw new IdleTimeoutError(timeout, stdout, stderr);
419
+ throw error;
420
+ }
421
+ })(),
422
+ abort
423
+ };
424
+ }
425
+ /**
362
426
  * Error thrown when a process is killed due to idle timeout
363
427
  */
364
428
  var IdleTimeoutError = class extends Error {
@@ -540,7 +604,9 @@ function createStreamParser(debugLog, backendName, adapter) {
540
604
  for (const line of lines) {
541
605
  if (!line.trim()) continue;
542
606
  try {
543
- const event = adapter(JSON.parse(line));
607
+ const raw = JSON.parse(line);
608
+ if (raw.type === "assistant" || raw.type === "system") debugLog(`[DEBUG] ${backendName} event: ${JSON.stringify(raw).substring(0, 200)}`);
609
+ const event = adapter(raw);
544
610
  if (event) {
545
611
  const progress = formatEvent(event, backendName);
546
612
  if (progress) debugLog(progress);
@@ -577,6 +643,7 @@ function formatToolInput(input) {
577
643
  var ClaudeCodeBackend = class {
578
644
  type = "claude";
579
645
  options;
646
+ currentAbort;
580
647
  constructor(options = {}) {
581
648
  this.options = {
582
649
  timeout: 3e5,
@@ -601,13 +668,16 @@ var ClaudeCodeBackend = class {
601
668
  const outputFormat = this.options.outputFormat ?? "stream-json";
602
669
  const timeout = this.options.timeout ?? 3e5;
603
670
  try {
604
- const { stdout } = await execWithIdleTimeout({
671
+ const { promise, abort } = execWithIdleTimeoutAbortable({
605
672
  command: "claude",
606
673
  args,
607
674
  cwd,
608
675
  timeout,
609
676
  onStdout: outputFormat === "stream-json" && debugLog ? createStreamParser(debugLog, "Claude", claudeAdapter) : void 0
610
677
  });
678
+ this.currentAbort = abort;
679
+ const { stdout } = await promise;
680
+ this.currentAbort = void 0;
611
681
  if (outputFormat === "stream-json") return extractClaudeResult(stdout);
612
682
  if (outputFormat === "json") try {
613
683
  const parsed = JSON.parse(stdout);
@@ -621,6 +691,7 @@ var ClaudeCodeBackend = class {
621
691
  }
622
692
  return { content: stdout.trim() };
623
693
  } catch (error) {
694
+ this.currentAbort = void 0;
624
695
  if (error instanceof IdleTimeoutError) throw new Error(`claude timed out after ${timeout}ms of inactivity`);
625
696
  if (error && typeof error === "object" && "exitCode" in error) {
626
697
  const execError = error;
@@ -660,6 +731,7 @@ var ClaudeCodeBackend = class {
660
731
  if (this.options.allowedTools?.length) args.push("--allowed-tools", this.options.allowedTools.join(","));
661
732
  const outputFormat = this.options.outputFormat ?? "stream-json";
662
733
  args.push("--output-format", outputFormat);
734
+ if (outputFormat === "stream-json") args.push("--verbose");
663
735
  if (this.options.continue) args.push("--continue");
664
736
  if (this.options.resume) args.push("--resume", this.options.resume);
665
737
  if (this.options.mcpConfigPath) args.push("--mcp-config", this.options.mcpConfigPath);
@@ -671,6 +743,15 @@ var ClaudeCodeBackend = class {
671
743
  setMcpConfigPath(path) {
672
744
  this.options.mcpConfigPath = path;
673
745
  }
746
+ /**
747
+ * Abort any running claude process
748
+ */
749
+ abort() {
750
+ if (this.currentAbort) {
751
+ this.currentAbort();
752
+ this.currentAbort = void 0;
753
+ }
754
+ }
674
755
  };
675
756
 
676
757
  //#endregion
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { T as FRONTIER_MODELS, k as getDefaultModel, n as createBackend } from "../backends-CEYiMUgC.mjs";
3
- import { a as createSkillsTool, c as createFeedbackTool, l as AgentSession, o as SkillsProvider, s as FEEDBACK_PROMPT, t as SkillImporter } from "../skills-iya7NbH7.mjs";
2
+ import { T as FRONTIER_MODELS, k as getDefaultModel, n as createBackend } from "../backends-Hclwb_Zp.mjs";
3
+ import { a as createSkillsTool, c as createFeedbackTool, l as AgentSession, o as SkillsProvider, s as FEEDBACK_PROMPT, t as SkillImporter } from "../skills-CrCMADND.mjs";
4
4
  import { jsonSchema, tool } from "ai";
5
5
  import { existsSync, mkdirSync, readFileSync, readdirSync, unlinkSync, writeFileSync } from "node:fs";
6
6
  import { dirname, isAbsolute, join, relative } from "node:path";
@@ -541,6 +541,8 @@ async function handleRequest(getState, req, resetIdleTimer, gracefulShutdown, re
541
541
  const RESOURCE_PREFIX = "res_";
542
542
  /** Resource URI scheme */
543
543
  const RESOURCE_SCHEME = "resource:";
544
+ /** Message length threshold for channel messages - content longer than this should use resources or documents */
545
+ const MESSAGE_LENGTH_THRESHOLD = 1200;
544
546
  /**
545
547
  * Generate a unique resource ID
546
548
  */
@@ -554,6 +556,12 @@ function generateResourceId() {
554
556
  function createResourceRef(id) {
555
557
  return `${RESOURCE_SCHEME}${id}`;
556
558
  }
559
+ /**
560
+ * Check if content should be stored as a resource instead of inline
561
+ */
562
+ function shouldUseResource(content) {
563
+ return content.length > MESSAGE_LENGTH_THRESHOLD;
564
+ }
557
565
  /** Default context configuration values */
558
566
  const CONTEXT_DEFAULTS = {
559
567
  dir: "~/.agent-worker/workflows/${{ workflow.name }}/${{ workflow.tag }}/",
@@ -654,6 +662,7 @@ var ContextProviderImpl = class {
654
662
  };
655
663
  if (options?.to) msg.to = options.to;
656
664
  if (options?.kind) msg.kind = options.kind;
665
+ if (options?.toolCall) msg.toolCall = options.toolCall;
657
666
  const line = JSON.stringify(msg) + "\n";
658
667
  await this.storage.append(KEYS.channel, line);
659
668
  return msg;
@@ -679,6 +688,23 @@ var ContextProviderImpl = class {
679
688
  cursor: entries.length
680
689
  };
681
690
  }
691
+ /**
692
+ * Smart send: automatically converts long messages to resources
693
+ *
694
+ * If content exceeds MESSAGE_LENGTH_THRESHOLD:
695
+ * 1. Creates a resource with the full content
696
+ * 2. Sends a short message referencing the resource
697
+ * 3. Logs the full content in debug channel for visibility
698
+ */
699
+ async smartSend(from, content, options) {
700
+ if (!shouldUseResource(content)) return this.appendChannel(from, content, options);
701
+ const resourceType = content.startsWith("```") || content.includes("\n```") ? "markdown" : "text";
702
+ const resource = await this.createResource(content, from, resourceType);
703
+ await this.appendChannel("system", `Created resource ${resource.id} (${content.length} chars) for @${from}:\n${content}`, { kind: "debug" });
704
+ const mentions = extractMentions(content, this.validAgents);
705
+ const shortMessage = `${mentions.length > 0 ? mentions.map((m) => `@${m}`).join(" ") + " " : ""}[Long content stored as resource]\n\nRead the full content: resource_read("${resource.id}")\n\nReference: ${resource.ref}`;
706
+ return this.appendChannel(from, shortMessage, options);
707
+ }
682
708
  async getInbox(agent) {
683
709
  const state = await this.loadInboxState();
684
710
  const lastAckId = state.readCursors[agent];
@@ -2094,22 +2120,42 @@ Examples:
2094
2120
 
2095
2121
  Note: Workflow name is inferred from YAML 'name' field or filename
2096
2122
  `).action(async (file, options) => {
2097
- const { parseWorkflowFile, runWorkflowWithControllers } = await import("../workflow-K1Zd655A.mjs");
2123
+ const { parseWorkflowFile, runWorkflowWithControllers } = await import("../workflow-CzVHUE9I.mjs");
2098
2124
  const tag = options.tag || DEFAULT_TAG;
2099
2125
  const parsedWorkflow = await parseWorkflowFile(file, { tag });
2100
2126
  const workflowName = parsedWorkflow.name;
2127
+ let controllers;
2128
+ let isCleaningUp = false;
2129
+ const cleanup = async () => {
2130
+ if (isCleaningUp) return;
2131
+ isCleaningUp = true;
2132
+ console.log("\nInterrupted, cleaning up...");
2133
+ if (controllers) {
2134
+ const { shutdownControllers } = await import("../workflow-CzVHUE9I.mjs");
2135
+ const { createSilentLogger } = await import("../logger-C3ekEOzi.mjs");
2136
+ await shutdownControllers(controllers, createSilentLogger());
2137
+ }
2138
+ process.exit(130);
2139
+ };
2140
+ process.on("SIGINT", cleanup);
2141
+ process.on("SIGTERM", cleanup);
2101
2142
  try {
2102
2143
  const log = options.json ? console.error : console.log;
2103
2144
  const result = await runWorkflowWithControllers({
2104
2145
  workflow: parsedWorkflow,
2105
2146
  workflowName,
2106
2147
  tag,
2148
+ workflowPath: file,
2107
2149
  instance: `${workflowName}:${tag}`,
2108
2150
  debug: options.debug,
2109
2151
  log,
2110
2152
  mode: "run",
2111
- feedback: options.feedback
2153
+ feedback: options.feedback,
2154
+ prettyDisplay: !options.debug && !options.json
2112
2155
  });
2156
+ controllers = result.controllers;
2157
+ process.off("SIGINT", cleanup);
2158
+ process.off("SIGTERM", cleanup);
2113
2159
  if (!result.success) {
2114
2160
  console.error("Workflow failed:", result.error);
2115
2161
  process.exit(1);
@@ -2122,16 +2168,27 @@ Note: Workflow name is inferred from YAML 'name' field or filename
2122
2168
  document: finalDoc,
2123
2169
  feedback: result.feedback
2124
2170
  }, null, 2));
2125
- else if (finalDoc) {
2126
- console.log("\n--- Document ---");
2127
- console.log(finalDoc);
2171
+ else if (!options.debug) {
2172
+ const { showWorkflowSummary } = await import("../display-pretty-BL9H2ocr.mjs");
2173
+ showWorkflowSummary({
2174
+ duration: result.duration,
2175
+ document: finalDoc,
2176
+ feedback: result.feedback
2177
+ });
2178
+ } else {
2179
+ if (finalDoc) {
2180
+ console.log("\n--- Document ---");
2181
+ console.log(finalDoc);
2182
+ }
2183
+ if (result.feedback && result.feedback.length > 0) {
2184
+ console.log(`\n--- Feedback (${result.feedback.length}) ---`);
2185
+ for (const entry of result.feedback) console.log(` [${entry.type}] ${entry.target}: ${entry.description}`);
2186
+ }
2128
2187
  }
2129
2188
  }
2130
- if (result.feedback && result.feedback.length > 0 && !options.json) {
2131
- console.log(`\n--- Feedback (${result.feedback.length}) ---`);
2132
- for (const entry of result.feedback) console.log(` [${entry.type}] ${entry.target}: ${entry.description}`);
2133
- }
2134
2189
  } catch (error) {
2190
+ process.off("SIGINT", cleanup);
2191
+ process.off("SIGTERM", cleanup);
2135
2192
  console.error("Error:", error instanceof Error ? error.message : String(error));
2136
2193
  process.exit(1);
2137
2194
  }
@@ -2144,7 +2201,7 @@ Examples:
2144
2201
 
2145
2202
  Note: Workflow name is inferred from YAML 'name' field or filename
2146
2203
  `).action(async (file, options) => {
2147
- const { parseWorkflowFile, runWorkflowWithControllers } = await import("../workflow-K1Zd655A.mjs");
2204
+ const { parseWorkflowFile, runWorkflowWithControllers } = await import("../workflow-CzVHUE9I.mjs");
2148
2205
  const tag = options.tag || DEFAULT_TAG;
2149
2206
  const parsedWorkflow = await parseWorkflowFile(file, { tag });
2150
2207
  const workflowName = parsedWorkflow.name;
@@ -2339,7 +2396,7 @@ function registerInfoCommands(program) {
2339
2396
  console.log(`\nDefault: ${defaultModel} (when no model specified)`);
2340
2397
  });
2341
2398
  program.command("backends").description("Check available backends (SDK, CLI tools)").action(async () => {
2342
- const { listBackends } = await import("../backends-B8rYTNqn.mjs");
2399
+ const { listBackends } = await import("../backends-BN3LvE37.mjs");
2343
2400
  const backends = await listBackends();
2344
2401
  console.log("Backend Status:\n");
2345
2402
  for (const backend of backends) {
@@ -2369,7 +2426,7 @@ Examples:
2369
2426
  $ agent-worker doc read @review:pr-123 # Read specific workflow:tag document
2370
2427
  `).action(async (targetInput) => {
2371
2428
  const dir = await resolveDir(targetInput);
2372
- const { createFileContextProvider } = await import("../context-C7nBmU5D.mjs");
2429
+ const { createFileContextProvider } = await import("../context-Bq7pSNVM.mjs");
2373
2430
  const content = await createFileContextProvider(dir, []).readDocument();
2374
2431
  console.log(content || "(empty document)");
2375
2432
  });
@@ -2387,7 +2444,7 @@ Examples:
2387
2444
  process.exit(1);
2388
2445
  }
2389
2446
  const dir = await resolveDir(targetInput);
2390
- const { createFileContextProvider } = await import("../context-C7nBmU5D.mjs");
2447
+ const { createFileContextProvider } = await import("../context-Bq7pSNVM.mjs");
2391
2448
  await createFileContextProvider(dir, []).writeDocument(content);
2392
2449
  console.log("Document written");
2393
2450
  });
@@ -2405,7 +2462,7 @@ Examples:
2405
2462
  process.exit(1);
2406
2463
  }
2407
2464
  const dir = await resolveDir(targetInput);
2408
- const { createFileContextProvider } = await import("../context-C7nBmU5D.mjs");
2465
+ const { createFileContextProvider } = await import("../context-Bq7pSNVM.mjs");
2409
2466
  await createFileContextProvider(dir, []).appendDocument(content);
2410
2467
  console.log("Content appended");
2411
2468
  });
@@ -2485,6 +2542,10 @@ Note: Requires agent to be created with --feedback flag
2485
2542
  });
2486
2543
  }
2487
2544
 
2545
+ //#endregion
2546
+ //#region package.json
2547
+ var version = "0.7.0";
2548
+
2488
2549
  //#endregion
2489
2550
  //#region src/cli/index.ts
2490
2551
  globalThis.AI_SDK_LOG_WARNINGS = false;
@@ -2497,7 +2558,7 @@ process.stderr.write = function(chunk, ...rest) {
2497
2558
  return true;
2498
2559
  };
2499
2560
  const program = new Command();
2500
- program.name("agent-worker").description("CLI for creating and managing AI agents").version("0.0.1");
2561
+ program.name("agent-worker").description("CLI for creating and managing AI agents").version(version);
2501
2562
  registerAgentCommands(program);
2502
2563
  registerSendCommands(program);
2503
2564
  registerMockCommands(program);
@@ -2509,4 +2570,4 @@ registerDocCommands(program);
2509
2570
  program.parse();
2510
2571
 
2511
2572
  //#endregion
2512
- export { FileStorage as a, CONTEXT_DEFAULTS as c, RESOURCE_SCHEME as d, calculatePriority as f, generateResourceId as h, resolveContextDir as i, MENTION_PATTERN as l, extractMentions as m, createFileContextProvider as n, MemoryStorage as o, createResourceRef as p, getDefaultContextDir as r, ContextProviderImpl as s, FileContextProvider as t, RESOURCE_PREFIX as u };
2573
+ export { shouldUseResource as _, FileStorage as a, CONTEXT_DEFAULTS as c, RESOURCE_PREFIX as d, RESOURCE_SCHEME as f, generateResourceId as g, extractMentions as h, resolveContextDir as i, MENTION_PATTERN as l, createResourceRef as m, createFileContextProvider as n, MemoryStorage as o, calculatePriority as p, getDefaultContextDir as r, ContextProviderImpl as s, FileContextProvider as t, MESSAGE_LENGTH_THRESHOLD as u };
@@ -0,0 +1,4 @@
1
+ import { _ as shouldUseResource, a as FileStorage, c as CONTEXT_DEFAULTS, d as RESOURCE_PREFIX, f as RESOURCE_SCHEME, g as generateResourceId, h as extractMentions, i as resolveContextDir, l as MENTION_PATTERN, m as createResourceRef, n as createFileContextProvider, o as MemoryStorage, p as calculatePriority, r as getDefaultContextDir, s as ContextProviderImpl, t as FileContextProvider, u as MESSAGE_LENGTH_THRESHOLD } from "./cli/index.mjs";
2
+ import { a as createMemoryContextProvider, i as MemoryContextProvider, n as formatProposal, r as formatProposalList, t as createContextMCPServer } from "./mcp-server-D5Pnt0lB.mjs";
3
+
4
+ export { createFileContextProvider };
@@ -0,0 +1,169 @@
1
+ import * as p from "@clack/prompts";
2
+ import pc from "picocolors";
3
+
4
+ //#region src/workflow/display-pretty.ts
5
+ /**
6
+ * Pretty display mode using @clack/prompts
7
+ *
8
+ * Clean, step-based CLI output:
9
+ * - Each message/event is a step
10
+ * - Uses clack's native symbols
11
+ * - Minimal decoration, maximum clarity
12
+ */
13
+ const BANNER_LINES = [
14
+ " █████╗ ██████╗ ███████╗███╗ ██╗████████╗ ██╗ ██╗ ██████╗ ██████╗ ██╗ ██╗███████╗██████╗",
15
+ "██╔══██╗██╔════╝ ██╔════╝████╗ ██║╚══██╔══╝ ██║ ██║██╔═══██╗██╔══██╗██║ ██╔╝██╔════╝██╔══██╗",
16
+ "███████║██║ ███╗█████╗ ██╔██╗ ██║ ██║ ██║ █╗ ██║██║ ██║██████╔╝█████╔╝ █████╗ ██████╔╝",
17
+ "██╔══██║██║ ██║██╔══╝ ██║╚██╗██║ ██║ ██║███╗██║██║ ██║██╔══██╗██╔═██╗ ██╔══╝ ██╔══██╗",
18
+ "██║ ██║╚██████╔╝███████╗██║ ╚████║ ██║ ╚███╔███╔╝╚██████╔╝██║ ██║██║ ██╗███████╗██║ ██║",
19
+ "╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚══╝╚══╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝"
20
+ ];
21
+ /**
22
+ * Apply gradient colors to banner lines
23
+ * Creates a smooth cyan gradient effect (bright → dark) using ANSI 256 colors
24
+ * Inspired by vercel-labs/skills gradient approach
25
+ */
26
+ function applyBannerGradient(lines) {
27
+ const CYAN_GRADIENT = [
28
+ "\x1B[38;5;51m",
29
+ "\x1B[38;5;45m",
30
+ "\x1B[38;5;39m",
31
+ "\x1B[38;5;33m",
32
+ "\x1B[38;5;27m",
33
+ "\x1B[38;5;21m"
34
+ ];
35
+ const RESET = "\x1B[0m";
36
+ return lines.map((line, i) => `${CYAN_GRADIENT[i]}${line}${RESET}`).join("\n");
37
+ }
38
+ const AGENT_COLORS = [
39
+ pc.cyan,
40
+ pc.yellow,
41
+ pc.magenta,
42
+ pc.green,
43
+ pc.blue
44
+ ];
45
+ function getAgentColor(name, agentNames) {
46
+ if (name === "system" || name === "user") return pc.dim;
47
+ const idx = agentNames.indexOf(name);
48
+ if (idx < 0) return AGENT_COLORS[name.split("").reduce((acc, c) => acc + c.charCodeAt(0), 0) % AGENT_COLORS.length];
49
+ return AGENT_COLORS[idx % AGENT_COLORS.length];
50
+ }
51
+ /**
52
+ * Process a channel entry for pretty display
53
+ */
54
+ function processEntry(entry, state, agentNames) {
55
+ const { kind, from, content, toolCall } = entry;
56
+ if (kind === "debug") return;
57
+ if (kind === "tool_call" && toolCall) {
58
+ const caller = from.includes(":") ? from.split(":").pop() : from;
59
+ if (caller) {
60
+ const color = getAgentColor(caller, agentNames);
61
+ const tool = pc.bold(pc.cyan(toolCall.name));
62
+ const args = toolCall.args ? pc.dim(`(${toolCall.args})`) : pc.dim("()");
63
+ p.log.message(`${color(caller)} called ${tool}${args}`, { symbol: pc.cyan("▶") });
64
+ } else p.log.message(`called ${pc.cyan(pc.bold(toolCall.name))}${pc.dim(`(${toolCall.args || ""})`)}`, { symbol: pc.cyan("▶") });
65
+ return;
66
+ }
67
+ if (kind === "log") {
68
+ if (content.includes("Running workflow:")) {
69
+ state.phase = "running";
70
+ return;
71
+ }
72
+ if (content.includes("Agents:")) return;
73
+ if (content.includes("Starting agents")) {
74
+ if (state.spinner) {
75
+ const agentList = agentNames.join(", ");
76
+ state.spinner.stop(`Initialized: ${pc.dim(agentList)}`);
77
+ }
78
+ state.spinner = p.spinner();
79
+ state.spinner.start("Starting agents");
80
+ } else if (content.includes("Workflow complete")) {
81
+ if (state.spinner) {
82
+ state.spinner.stop();
83
+ state.spinner = null;
84
+ }
85
+ const match = content.match(/\(([0-9.]+)s\)/);
86
+ if (match) p.log.success(`Completed in ${pc.bold(match[1])}s`);
87
+ else p.log.success("Workflow complete");
88
+ state.phase = "complete";
89
+ } else if (content.startsWith("[ERROR]")) {
90
+ if (state.spinner) {
91
+ state.spinner.stop();
92
+ state.spinner = null;
93
+ }
94
+ p.log.error(content.replace("[ERROR] ", ""));
95
+ state.phase = "error";
96
+ } else if (content.startsWith("[WARN]")) p.log.warn(content.replace("[WARN] ", ""));
97
+ else if (content.match(/Inbox: \d+ message/)) p.log.step(pc.dim(content));
98
+ else if (content.match(/Running \(attempt/)) p.log.step(pc.dim(content));
99
+ else if (content.startsWith("DONE")) {
100
+ const details = content.replace("DONE ", "");
101
+ p.log.info(pc.green("✓") + " " + pc.dim(details));
102
+ }
103
+ return;
104
+ }
105
+ const color = getAgentColor(from, agentNames);
106
+ if (state.spinner && state.phase === "running" && !state.hasShownAgentsStarted) {
107
+ state.spinner.stop();
108
+ state.spinner = null;
109
+ p.log.info("Agents ready and processing");
110
+ state.hasShownAgentsStarted = true;
111
+ }
112
+ p.note(content.trim(), color(from));
113
+ }
114
+ /**
115
+ * Start pretty display watcher
116
+ */
117
+ function startPrettyDisplay(config) {
118
+ const { contextProvider, agentNames, workflowName, tag, workflowPath, pollInterval = 500, initialCursor = 0 } = config;
119
+ const state = {
120
+ spinner: null,
121
+ phase: "init",
122
+ hasShownAgentsStarted: false
123
+ };
124
+ console.log("\n" + applyBannerGradient(BANNER_LINES));
125
+ console.log("");
126
+ const introText = ` ${workflowName}${tag === "main" ? "" : `:${tag}`}${workflowPath ? ` ${pc.dim(`(${workflowPath})`)}` : ""} `;
127
+ p.intro(pc.bgCyan(pc.black(introText)));
128
+ state.spinner = p.spinner();
129
+ const agentCount = agentNames.length;
130
+ const agentWord = agentCount === 1 ? "agent" : "agents";
131
+ state.spinner.start(`Initializing ${agentCount} ${agentWord}`);
132
+ let cursor = initialCursor;
133
+ let running = true;
134
+ const poll = async () => {
135
+ while (running) {
136
+ try {
137
+ const tail = await contextProvider.tailChannel(cursor);
138
+ for (const entry of tail.entries) processEntry(entry, state, agentNames);
139
+ cursor = tail.cursor;
140
+ } catch (error) {
141
+ console.error("Display polling error:", error instanceof Error ? error.message : error);
142
+ }
143
+ await sleep(pollInterval);
144
+ }
145
+ };
146
+ poll();
147
+ return { stop: () => {
148
+ running = false;
149
+ if (state.spinner) state.spinner.stop("Stopped");
150
+ } };
151
+ }
152
+ /**
153
+ * Show workflow completion summary
154
+ */
155
+ function showWorkflowSummary(options) {
156
+ const { document, feedback } = options;
157
+ if (document && document.trim()) p.note(document, "Document");
158
+ if (feedback && feedback.length > 0) {
159
+ const feedbackLines = feedback.map((f) => `[${f.type}] ${f.target}: ${f.description}`);
160
+ p.note(feedbackLines.join("\n"), `Feedback (${feedback.length})`);
161
+ }
162
+ p.outro("Done");
163
+ }
164
+ function sleep(ms) {
165
+ return new Promise((resolve) => setTimeout(resolve, ms));
166
+ }
167
+
168
+ //#endregion
169
+ export { showWorkflowSummary, startPrettyDisplay };
package/dist/index.d.mts CHANGED
@@ -175,6 +175,8 @@ interface Backend {
175
175
  setWorkspace?(workspaceDir: string, mcpConfig: {
176
176
  mcpServers: Record<string, unknown>;
177
177
  }): void;
178
+ /** Abort any running operations and cleanup resources */
179
+ abort?(): void;
178
180
  }
179
181
  //#endregion
180
182
  //#region src/agent/session.d.ts
@@ -477,6 +479,7 @@ interface ClaudeCodeOptions {
477
479
  declare class ClaudeCodeBackend implements Backend {
478
480
  readonly type: "claude";
479
481
  private options;
482
+ private currentAbort?;
480
483
  constructor(options?: ClaudeCodeOptions);
481
484
  /**
482
485
  * Set up workspace directory with MCP config
@@ -499,6 +502,10 @@ declare class ClaudeCodeBackend implements Backend {
499
502
  * Set MCP config path (for workflow integration)
500
503
  */
501
504
  setMcpConfigPath(path: string): void;
505
+ /**
506
+ * Abort any running claude process
507
+ */
508
+ abort(): void;
502
509
  }
503
510
  //#endregion
504
511
  //#region src/backends/codex.d.ts
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { D as createModel, E as SUPPORTED_PROVIDERS, O as createModelAsync, T as FRONTIER_MODELS, a as createMockBackend, c as CodexBackend, i as MockAIBackend, l as ClaudeCodeBackend, n as createBackend, o as SdkBackend, r as listBackends, s as CursorBackend, t as checkBackends } from "./backends-CEYiMUgC.mjs";
2
- import { a as createSkillsTool, c as createFeedbackTool, i as parseImportSpec, l as AgentSession, n as buildGitUrl, o as SkillsProvider, r as getSpecDisplayName, s as FEEDBACK_PROMPT, t as SkillImporter } from "./skills-iya7NbH7.mjs";
1
+ import { D as createModel, E as SUPPORTED_PROVIDERS, O as createModelAsync, T as FRONTIER_MODELS, a as createMockBackend, c as CodexBackend, i as MockAIBackend, l as ClaudeCodeBackend, n as createBackend, o as SdkBackend, r as listBackends, s as CursorBackend, t as checkBackends } from "./backends-Hclwb_Zp.mjs";
2
+ import { a as createSkillsTool, c as createFeedbackTool, i as parseImportSpec, l as AgentSession, n as buildGitUrl, o as SkillsProvider, r as getSpecDisplayName, s as FEEDBACK_PROMPT, t as SkillImporter } from "./skills-CrCMADND.mjs";
3
3
  import { jsonSchema, tool } from "ai";
4
4
  import { createBashTool } from "bash-tool";
5
5
 
@@ -0,0 +1,63 @@
1
+ //#region src/workflow/logger.ts
2
+ /**
3
+ * Create a silent logger (no output)
4
+ */
5
+ function createSilentLogger() {
6
+ const noop = () => {};
7
+ return {
8
+ debug: noop,
9
+ info: noop,
10
+ warn: noop,
11
+ error: noop,
12
+ isDebug: () => false,
13
+ child: () => createSilentLogger()
14
+ };
15
+ }
16
+ /**
17
+ * Create a logger that writes to the channel.
18
+ *
19
+ * - info/warn/error → channel entry with kind="log" (always shown to user)
20
+ * - debug → channel entry with kind="debug" (only shown with --debug)
21
+ *
22
+ * The display layer handles formatting and filtering.
23
+ */
24
+ function createChannelLogger(config) {
25
+ const { provider, from = "system" } = config;
26
+ const formatContent = (level, message, args) => {
27
+ const argsStr = args.length > 0 ? " " + args.map(formatArg).join(" ") : "";
28
+ if (level === "warn") return `[WARN] ${message}${argsStr}`;
29
+ if (level === "error") return `[ERROR] ${message}${argsStr}`;
30
+ return `${message}${argsStr}`;
31
+ };
32
+ const write = (level, message, args) => {
33
+ const content = formatContent(level, message, args);
34
+ const kind = level === "debug" ? "debug" : "log";
35
+ provider.appendChannel(from, content, { kind }).catch(() => {});
36
+ };
37
+ return {
38
+ debug: (message, ...args) => write("debug", message, args),
39
+ info: (message, ...args) => write("info", message, args),
40
+ warn: (message, ...args) => write("warn", message, args),
41
+ error: (message, ...args) => write("error", message, args),
42
+ isDebug: () => true,
43
+ child: (childPrefix) => {
44
+ return createChannelLogger({
45
+ provider,
46
+ from: from ? `${from}:${childPrefix}` : childPrefix
47
+ });
48
+ }
49
+ };
50
+ }
51
+ /** Format an argument for logging */
52
+ function formatArg(arg) {
53
+ if (arg === null || arg === void 0) return String(arg);
54
+ if (typeof arg === "object") try {
55
+ return JSON.stringify(arg);
56
+ } catch {
57
+ return String(arg);
58
+ }
59
+ return String(arg);
60
+ }
61
+
62
+ //#endregion
63
+ export { createChannelLogger, createSilentLogger };
@@ -159,19 +159,26 @@ function createContextMCPServer(options) {
159
159
  const { provider, validAgents, name = "workflow-context", version = "1.0.0", onMention, proposalManager, feedback: feedbackEnabled, debugLog } = options;
160
160
  const feedbackEntries = [];
161
161
  const logTool = (tool, agent, params) => {
162
- if (debugLog) debugLog(`[mcp:${agent || "anonymous"}] ${tool}(${Object.entries(params).filter(([_, v]) => v !== void 0).map(([k, v]) => {
162
+ if (!agent) return;
163
+ const paramsStr = Object.entries(params).filter(([_, v]) => v !== void 0).map(([k, v]) => {
163
164
  const val = typeof v === "string" && v.length > 50 ? v.slice(0, 50) + "..." : v;
164
165
  return `${k}=${JSON.stringify(val)}`;
165
- }).join(", ")})`);
166
+ }).join(", ");
167
+ provider.appendChannel(agent, `${tool}(${paramsStr})`, {
168
+ kind: "tool_call",
169
+ toolCall: {
170
+ name: tool,
171
+ args: paramsStr
172
+ }
173
+ }).catch(() => {});
166
174
  };
167
175
  const server = new McpServer({
168
176
  name,
169
177
  version
170
178
  });
171
179
  const agentConnections = /* @__PURE__ */ new Map();
172
- const CHANNEL_MSG_LIMIT = 2e3;
173
- server.tool("channel_send", `Send a message to the shared channel. Use @agent to mention/notify. Use "to" for private DMs. Max ${CHANNEL_MSG_LIMIT} chars — for longer content, use resource_create first then reference the resource ID in your message.`, {
174
- message: z.string().describe("Message content, can include @mentions like @reviewer or @coder"),
180
+ server.tool("channel_send", `Send a message to the shared channel. Use @agent to mention/notify. Use "to" for private DMs. Long messages (> 2000 chars) are automatically converted to resources.`, {
181
+ message: z.string().describe("Message content, can include @mentions like @reviewer or @coder. Long messages are auto-converted to resources."),
175
182
  to: z.string().optional().describe("Send as DM to a specific agent (private, only you and recipient see it)")
176
183
  }, async ({ message, to }, extra) => {
177
184
  const from = getAgentId(extra) || "anonymous";
@@ -179,15 +186,8 @@ function createContextMCPServer(options) {
179
186
  message,
180
187
  to
181
188
  });
182
- if (message.length > CHANNEL_MSG_LIMIT) return {
183
- isError: true,
184
- content: [{
185
- type: "text",
186
- text: `Message too long (${message.length} chars, max ${CHANNEL_MSG_LIMIT}). Use resource_create to store the full content, then send a short message referencing the resource ID.`
187
- }]
188
- };
189
189
  const sendOpts = to ? { to } : void 0;
190
- const msg = await provider.appendChannel(from, message, sendOpts);
190
+ const msg = await provider.smartSend(from, message, sendOpts);
191
191
  for (const target of msg.mentions) if (onMention) onMention(from, target, msg);
192
192
  if (to && !msg.mentions.includes(to) && onMention) onMention(from, to, msg);
193
193
  return { content: [{
@@ -1,4 +1,4 @@
1
- import { O as createModelAsync } from "./backends-CEYiMUgC.mjs";
1
+ import { O as createModelAsync } from "./backends-Hclwb_Zp.mjs";
2
2
  import { ToolLoopAgent, jsonSchema, stepCountIs, tool } from "ai";
3
3
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
4
4
  import { join, normalize } from "node:path";
@@ -1,6 +1,7 @@
1
- import { O as createModelAsync, a as createMockBackend, n as createBackend, w as parseModel } from "./backends-CEYiMUgC.mjs";
1
+ import { O as createModelAsync, a as createMockBackend, n as createBackend, w as parseModel } from "./backends-Hclwb_Zp.mjs";
2
2
  import { c as CONTEXT_DEFAULTS, i as resolveContextDir, n as createFileContextProvider, t as FileContextProvider } from "./cli/index.mjs";
3
- import { a as createMemoryContextProvider, t as createContextMCPServer } from "./mcp-server-DtIApaBD.mjs";
3
+ import { a as createMemoryContextProvider, t as createContextMCPServer } from "./mcp-server-D5Pnt0lB.mjs";
4
+ import { createChannelLogger, createSilentLogger } from "./logger-C3ekEOzi.mjs";
4
5
  import { generateText, jsonSchema, stepCountIs, tool } from "ai";
5
6
  import { existsSync, mkdirSync, readFileSync } from "node:fs";
6
7
  import { basename, dirname, join, resolve } from "node:path";
@@ -14,9 +15,9 @@ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/
14
15
  import { MockLanguageModelV3, mockValues } from "ai/test";
15
16
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
16
17
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
18
+ import stringWidth from "string-width";
17
19
  import chalk from "chalk";
18
20
  import wrapAnsi from "wrap-ansi";
19
- import stringWidth from "string-width";
20
21
 
21
22
  //#region src/workflow/parser.ts
22
23
  /**
@@ -459,16 +460,6 @@ function formatInbox(inbox) {
459
460
  }).join("\n");
460
461
  }
461
462
  /**
462
- * Format channel messages for display
463
- */
464
- function formatChannel(entries) {
465
- if (entries.length === 0) return "(no messages)";
466
- return entries.map((e) => {
467
- const dm = e.to ? ` [DM→@${e.to}]` : "";
468
- return `[${e.timestamp.slice(11, 19)}] @${e.from}${dm}: ${e.content}`;
469
- }).join("\n");
470
- }
471
- /**
472
463
  * Build the complete agent prompt from run context
473
464
  */
474
465
  function buildAgentPrompt(ctx) {
@@ -479,8 +470,8 @@ function buildAgentPrompt(ctx) {
479
470
  sections.push(`## Inbox (${ctx.inbox.length} message${ctx.inbox.length === 1 ? "" : "s"} for you)`);
480
471
  sections.push(formatInbox(ctx.inbox));
481
472
  sections.push("");
482
- sections.push(`## Recent Activity (last ${ctx.recentChannel.length} messages)`);
483
- sections.push(formatChannel(ctx.recentChannel));
473
+ sections.push("## Recent Activity");
474
+ sections.push("Use channel_read tool to view recent channel messages and conversation context if needed.");
484
475
  if (ctx.documentContent) {
485
476
  sections.push("");
486
477
  sections.push("## Shared Document");
@@ -821,7 +812,18 @@ async function runSdkAgent(ctx, debugLog) {
821
812
  stopWhen: stepCountIs(ctx.agent.max_steps ?? 30),
822
813
  onStepFinish: (step) => {
823
814
  _stepNum++;
824
- if (step.toolCalls?.length) for (const tc of step.toolCalls) log(`CALL ${formatToolCall(tc)}`);
815
+ if (step.toolCalls?.length) {
816
+ for (const tc of step.toolCalls) if (tc.toolName === "bash") {
817
+ const args = formatToolCall(tc);
818
+ ctx.provider.appendChannel(ctx.name, args, {
819
+ kind: "tool_call",
820
+ toolCall: {
821
+ name: tc.toolName,
822
+ args
823
+ }
824
+ }).catch(() => {});
825
+ }
826
+ }
825
827
  }
826
828
  });
827
829
  const totalToolCalls = result.steps.reduce((n, s) => n + s.toolCalls.length, 0);
@@ -922,6 +924,7 @@ function createAgentController(config) {
922
924
  workspaceDir,
923
925
  projectDir,
924
926
  retryAttempt: attempt,
927
+ provider: contextProvider,
925
928
  feedback
926
929
  }, log, infoLog);
927
930
  if (lastResult.success) {
@@ -964,6 +967,7 @@ function createAgentController(config) {
964
967
  async stop() {
965
968
  log(`Stopping`);
966
969
  state = "stopped";
970
+ if (backend.abort) backend.abort();
967
971
  if (pollTimeout) {
968
972
  clearTimeout(pollTimeout);
969
973
  pollTimeout = null;
@@ -1270,46 +1274,6 @@ function formatStandardLog(entry, includeMillis = false) {
1270
1274
  //#endregion
1271
1275
  //#region src/workflow/display.ts
1272
1276
  /**
1273
- * Channel display formatting
1274
- *
1275
- * All output flows through the channel. This module formats and filters
1276
- * channel entries for terminal display:
1277
- * - kind=undefined (agent messages): always shown, colored
1278
- * - kind="log" (operational logs): always shown, dimmed
1279
- * - kind="debug" (debug details): only shown with --debug flag
1280
- *
1281
- * Two display modes:
1282
- * - TTY (human): colored, aligned columns, smart wrapping
1283
- * - Non-TTY (agent/pipe): plain text, no colors, simple separators
1284
- *
1285
- * Best practices implemented:
1286
- * - Adaptive layout based on terminal width and agent names
1287
- * - Smart text wrapping preserving ANSI colors
1288
- * - Message grouping to reduce visual noise
1289
- * - Background-agnostic color scheme
1290
- */
1291
- /** Whether to use rich terminal formatting */
1292
- const isTTY = !!process.stdout.isTTY && !process.env.NO_COLOR;
1293
- /**
1294
- * Background-agnostic color scheme
1295
- * Uses only bold and standard colors that work on any theme
1296
- */
1297
- const C = {
1298
- dim: isTTY ? chalk.dim : (s) => s,
1299
- bold: isTTY ? chalk.bold : (s) => s,
1300
- yellow: isTTY ? chalk.yellow : (s) => s,
1301
- red: isTTY ? chalk.red : (s) => s,
1302
- agents: isTTY ? [
1303
- chalk.cyan,
1304
- chalk.yellow,
1305
- chalk.magenta,
1306
- chalk.green,
1307
- chalk.blue,
1308
- chalk.redBright
1309
- ] : Array(6).fill((s) => s),
1310
- system: isTTY ? chalk.gray : (s) => s
1311
- };
1312
- /**
1313
1277
  * Create display context for a workflow
1314
1278
  */
1315
1279
  function createDisplayContext(agentNames, options) {
@@ -1368,68 +1332,6 @@ function startChannelWatcher(config) {
1368
1332
  } };
1369
1333
  }
1370
1334
 
1371
- //#endregion
1372
- //#region src/workflow/logger.ts
1373
- /**
1374
- * Create a silent logger (no output)
1375
- */
1376
- function createSilentLogger() {
1377
- const noop = () => {};
1378
- return {
1379
- debug: noop,
1380
- info: noop,
1381
- warn: noop,
1382
- error: noop,
1383
- isDebug: () => false,
1384
- child: () => createSilentLogger()
1385
- };
1386
- }
1387
- /**
1388
- * Create a logger that writes to the channel.
1389
- *
1390
- * - info/warn/error → channel entry with kind="log" (always shown to user)
1391
- * - debug → channel entry with kind="debug" (only shown with --debug)
1392
- *
1393
- * The display layer handles formatting and filtering.
1394
- */
1395
- function createChannelLogger(config) {
1396
- const { provider, from = "system" } = config;
1397
- const formatContent = (level, message, args) => {
1398
- const argsStr = args.length > 0 ? " " + args.map(formatArg).join(" ") : "";
1399
- if (level === "warn") return `[WARN] ${message}${argsStr}`;
1400
- if (level === "error") return `[ERROR] ${message}${argsStr}`;
1401
- return `${message}${argsStr}`;
1402
- };
1403
- const write = (level, message, args) => {
1404
- const content = formatContent(level, message, args);
1405
- const kind = level === "debug" ? "debug" : "log";
1406
- provider.appendChannel(from, content, { kind }).catch(() => {});
1407
- };
1408
- return {
1409
- debug: (message, ...args) => write("debug", message, args),
1410
- info: (message, ...args) => write("info", message, args),
1411
- warn: (message, ...args) => write("warn", message, args),
1412
- error: (message, ...args) => write("error", message, args),
1413
- isDebug: () => true,
1414
- child: (childPrefix) => {
1415
- return createChannelLogger({
1416
- provider,
1417
- from: from ? `${from}:${childPrefix}` : childPrefix
1418
- });
1419
- }
1420
- };
1421
- }
1422
- /** Format an argument for logging */
1423
- function formatArg(arg) {
1424
- if (arg === null || arg === void 0) return String(arg);
1425
- if (typeof arg === "object") try {
1426
- return JSON.stringify(arg);
1427
- } catch {
1428
- return String(arg);
1429
- }
1430
- return String(arg);
1431
- }
1432
-
1433
1335
  //#endregion
1434
1336
  //#region src/workflow/runner.ts
1435
1337
  /**
@@ -1560,7 +1462,7 @@ async function initWorkflow(config) {
1560
1462
  return;
1561
1463
  }
1562
1464
  logger.debug(`Kickoff: ${interpolatedKickoff.slice(0, 100)}...`);
1563
- await contextProvider.appendChannel("system", interpolatedKickoff);
1465
+ await contextProvider.smartSend("system", interpolatedKickoff);
1564
1466
  },
1565
1467
  async shutdown() {
1566
1468
  logger.debug("Shutting down...");
@@ -1640,8 +1542,7 @@ async function runWorkflowWithControllers(config) {
1640
1542
  } else logger.debug(`@mention: ${from} → @${target} (no controller found!)`);
1641
1543
  },
1642
1544
  debugLog: (msg) => {
1643
- if (msg.startsWith("CALL ")) logger.info(msg);
1644
- else logger.debug(msg);
1545
+ logger.debug(msg);
1645
1546
  },
1646
1547
  feedback: feedbackEnabled
1647
1548
  });
@@ -1656,9 +1557,9 @@ async function runWorkflowWithControllers(config) {
1656
1557
  backend: agentDef.backend,
1657
1558
  model: agentDef.model
1658
1559
  });
1560
+ const agentLogger = logger.child(agentName);
1659
1561
  const backendDebugLog = (msg) => {
1660
- if (msg.startsWith("CALL ")) logger.info(msg);
1661
- else logger.debug(msg);
1562
+ agentLogger.debug(msg);
1662
1563
  };
1663
1564
  let backend;
1664
1565
  if (createBackend) backend = createBackend(agentName, agentDef);
@@ -1694,7 +1595,19 @@ async function runWorkflowWithControllers(config) {
1694
1595
  logger.debug("Sending kickoff message...");
1695
1596
  await runtime.sendKickoff();
1696
1597
  logger.debug("Kickoff sent");
1697
- const channelWatcher = startChannelWatcher({
1598
+ let channelWatcher;
1599
+ if (config.prettyDisplay) {
1600
+ const { startPrettyDisplay } = await import("./display-pretty-BL9H2ocr.mjs");
1601
+ channelWatcher = startPrettyDisplay({
1602
+ contextProvider: runtime.contextProvider,
1603
+ agentNames: runtime.agentNames,
1604
+ workflowName,
1605
+ tag,
1606
+ workflowPath: config.workflowPath,
1607
+ initialCursor: channelStart,
1608
+ pollInterval: 250
1609
+ });
1610
+ } else channelWatcher = startChannelWatcher({
1698
1611
  contextProvider: runtime.contextProvider,
1699
1612
  agentNames: runtime.agentNames,
1700
1613
  log,
@@ -1789,4 +1702,4 @@ function sleep(ms) {
1789
1702
  }
1790
1703
 
1791
1704
  //#endregion
1792
- export { parseWorkflowFile, runWorkflowWithControllers };
1705
+ export { parseWorkflowFile, runWorkflowWithControllers, shutdownControllers };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-worker",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "SDK and CLI for creating and testing agent workers with Vercel AI SDK",
5
5
  "type": "module",
6
6
  "main": "./dist/index.mjs",
@@ -30,6 +30,7 @@
30
30
  "prepublishOnly": "bun run build"
31
31
  },
32
32
  "dependencies": {
33
+ "@clack/prompts": "^1.0.0",
33
34
  "@modelcontextprotocol/sdk": "^1.26.0",
34
35
  "ai": "^6.0.69",
35
36
  "bash-tool": "^1.3.12",
@@ -38,6 +39,7 @@
38
39
  "execa": "^9.6.1",
39
40
  "just-bash": "^2.8.0",
40
41
  "nanoid": "^5.1.6",
42
+ "picocolors": "^1.1.1",
41
43
  "string-width": "^8.1.1",
42
44
  "wrap-ansi": "^9.0.2",
43
45
  "yaml": "^2.7.0",
@@ -1,4 +0,0 @@
1
- import { a as FileStorage, c as CONTEXT_DEFAULTS, d as RESOURCE_SCHEME, f as calculatePriority, h as generateResourceId, i as resolveContextDir, l as MENTION_PATTERN, m as extractMentions, n as createFileContextProvider, o as MemoryStorage, p as createResourceRef, r as getDefaultContextDir, s as ContextProviderImpl, t as FileContextProvider, u as RESOURCE_PREFIX } from "./cli/index.mjs";
2
- import { a as createMemoryContextProvider, i as MemoryContextProvider, n as formatProposal, r as formatProposalList, t as createContextMCPServer } from "./mcp-server-DtIApaBD.mjs";
3
-
4
- export { createFileContextProvider };