wave-agent-sdk 0.19.3 → 0.19.5

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.
@@ -96,6 +96,7 @@ export declare class AIManager {
96
96
  getIsCompacting(): boolean;
97
97
  setIsCompacting(isCompacting: boolean): void;
98
98
  private get subagentManager();
99
+ private get cronManager();
99
100
  private get skillManager();
100
101
  sendAIMessage(options?: {
101
102
  recursionDepth?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"aiManager.d.ts","sourceRoot":"","sources":["../../src/managers/aiManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"aiManager.d.ts","sourceRoot":"","sources":["../../src/managers/aiManager.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,42 @@ import { recoverTruncatedJson } from "../utils/stringUtils.js";
12
12
  import { logger } from "../utils/globalLogger.js";
13
13
  import { startInteractionSpan, endInteractionSpan, startLLMRequestSpan, endLLMRequestSpan, resetTracingState, } from "../telemetry/sessionTracing.js";
14
14
  import { logOTelEvent } from "../telemetry/events.js";
15
+ // Truncate text to `max` chars and append a "… [+N chars]" marker when exceeded.
16
+ // Used for background_tasks description/command fields (≤1000 chars per spec FR-063).
17
+ function truncateWithMarker(text, max) {
18
+ if (text.length <= max)
19
+ return text;
20
+ return text.slice(0, max) + `… [+${text.length - max} chars]`;
21
+ }
22
+ // Map a BackgroundTask (from BackgroundTaskManager) to the Stop hook's
23
+ // background_tasks array element shape (aligned with Claude Code v2.1.145+).
24
+ // Conditional fields are populated based on task type:
25
+ // - shell: `command`
26
+ // - subagent: `agent_type` (looked up via SubagentManager by subagentId)
27
+ // - workflow: `name` (extracted from "Workflow: <name>" description)
28
+ function mapBackgroundTask(task, subagentManager) {
29
+ const base = {
30
+ id: task.id,
31
+ type: task.type,
32
+ status: task.status,
33
+ description: truncateWithMarker(task.description ?? "", 1000),
34
+ };
35
+ if (task.type === "shell") {
36
+ return { ...base, command: truncateWithMarker(task.command ?? "", 1000) };
37
+ }
38
+ if (task.type === "subagent") {
39
+ const instance = subagentManager
40
+ ?.getActiveInstances()
41
+ .find((i) => i.subagentId === task.subagentId);
42
+ return { ...base, agent_type: instance?.subagentType ?? "" };
43
+ }
44
+ // workflow
45
+ const prefix = "Workflow: ";
46
+ const name = task.description?.startsWith(prefix)
47
+ ? task.description.slice(prefix.length)
48
+ : (task.description ?? "");
49
+ return { ...base, name };
50
+ }
15
51
  export class AIManager {
16
52
  // Service overrides
17
53
  constructor(container, options) {
@@ -499,6 +535,9 @@ export class AIManager {
499
535
  get subagentManager() {
500
536
  return this.container.get("SubagentManager");
501
537
  }
538
+ get cronManager() {
539
+ return this.container.get("CronManager");
540
+ }
502
541
  get skillManager() {
503
542
  return this.container.get("SkillManager");
504
543
  }
@@ -1033,6 +1072,22 @@ export class AIManager {
1033
1072
  try {
1034
1073
  // Use "SubagentStop" hook name when triggered by a subagent, otherwise use "Stop"
1035
1074
  const hookName = this.subagentType ? "SubagentStop" : "Stop";
1075
+ // For main-agent Stop events, snapshot running background tasks and
1076
+ // session cron jobs so the hook can decide whether to block stopping.
1077
+ // SubagentStop does not include these fields (per spec FR-065).
1078
+ const backgroundTasks = hookName === "Stop"
1079
+ ? (this.backgroundTaskManager?.getAllTasks() ?? [])
1080
+ .filter((t) => t.status === "running")
1081
+ .map((t) => mapBackgroundTask(t, this.subagentManager))
1082
+ : undefined;
1083
+ const sessionCrons = hookName === "Stop"
1084
+ ? (this.cronManager?.listJobs() ?? []).map((j) => ({
1085
+ id: j.id,
1086
+ schedule: j.cron,
1087
+ recurring: j.recurring,
1088
+ prompt: j.prompt,
1089
+ }))
1090
+ : undefined;
1036
1091
  const context = {
1037
1092
  event: hookName,
1038
1093
  projectDir: this.getWorkdir(),
@@ -1041,6 +1096,8 @@ export class AIManager {
1041
1096
  transcriptPath: this.messageManager.getTranscriptPath(),
1042
1097
  cwd: this.getWorkdir(),
1043
1098
  subagentType: this.subagentType, // Include subagent type in hook context
1099
+ backgroundTasks, // Stop-only: running background tasks snapshot
1100
+ sessionCrons, // Stop-only: session cron jobs snapshot
1044
1101
  // Stop hooks don't need toolName, toolInput, toolResponse, or userPrompt
1045
1102
  env: Object.fromEntries(Object.entries(process.env).filter((e) => e[1] !== undefined)), // Include environment variables
1046
1103
  };
@@ -16,7 +16,12 @@ export declare class BackgroundTaskManager {
16
16
  private workdir;
17
17
  constructor(container: Container, options: BackgroundTaskManagerOptions);
18
18
  private get notificationQueue();
19
- private notifyTasksChange;
19
+ /**
20
+ * Fire the onBackgroundTasksChange callback so UI consumers refresh.
21
+ * Public so other managers (e.g. WorkflowManager) can trigger a refresh
22
+ * when their state changes without mutating a background task.
23
+ */
24
+ notifyTasksChange(): void;
20
25
  generateId(): string;
21
26
  addTask(task: BackgroundTask): void;
22
27
  getTask(id: string): BackgroundTask | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"backgroundTaskManager.d.ts","sourceRoot":"","sources":["../../src/managers/backgroundTaskManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAIzD,OAAO,EAAE,cAAc,EAAmB,MAAM,uBAAuB,CAAC;AAGxE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGlD,MAAM,WAAW,8BAA8B;IAC7C,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;CAC7D;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,CAAC,EAAE,8BAA8B,CAAC;IAC3C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAqB;IAO9B,OAAO,CAAC,SAAS;IANnB,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,OAAO,CAAS;gBAGd,SAAS,EAAE,SAAS,EAC5B,OAAO,EAAE,4BAA4B;IAMvC,OAAO,KAAK,iBAAiB,GAE5B;IAED,OAAO,CAAC,iBAAiB;IAIlB,UAAU,IAAI,MAAM;IAIpB,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAKnC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI/C,WAAW,IAAI,cAAc,EAAE;IAI/B,UAAU,CACf,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,MAAM,IAAI,CAAA;KAAE;IA8KnD,YAAY,CACjB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,MAAM,EACf,aAAa,GAAE,MAAW,EAC1B,aAAa,GAAE,MAAW,GACzB,MAAM;IAqIF,SAAS,CACd,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,MAAM,GACd;QACD,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI;IAoCD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAgC7B,OAAO,IAAI,IAAI;CAUvB"}
1
+ {"version":3,"file":"backgroundTaskManager.d.ts","sourceRoot":"","sources":["../../src/managers/backgroundTaskManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAIzD,OAAO,EAAE,cAAc,EAAmB,MAAM,uBAAuB,CAAC;AAGxE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGlD,MAAM,WAAW,8BAA8B;IAC7C,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;CAC7D;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,CAAC,EAAE,8BAA8B,CAAC;IAC3C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAqB;IAO9B,OAAO,CAAC,SAAS;IANnB,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,OAAO,CAAS;gBAGd,SAAS,EAAE,SAAS,EAC5B,OAAO,EAAE,4BAA4B;IAMvC,OAAO,KAAK,iBAAiB,GAE5B;IAED;;;;OAIG;IACI,iBAAiB,IAAI,IAAI;IAIzB,UAAU,IAAI,MAAM;IAIpB,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAKnC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI/C,WAAW,IAAI,cAAc,EAAE;IAI/B,UAAU,CACf,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,MAAM,IAAI,CAAA;KAAE;IA8KnD,YAAY,CACjB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,MAAM,EACf,aAAa,GAAE,MAAW,EAC1B,aAAa,GAAE,MAAW,GACzB,MAAM;IAqIF,SAAS,CACd,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,MAAM,GACd;QACD,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI;IAoCD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAgC7B,OAAO,IAAI,IAAI;CAUvB"}
@@ -15,6 +15,11 @@ export class BackgroundTaskManager {
15
15
  get notificationQueue() {
16
16
  return this.container.get("NotificationQueue");
17
17
  }
18
+ /**
19
+ * Fire the onBackgroundTasksChange callback so UI consumers refresh.
20
+ * Public so other managers (e.g. WorkflowManager) can trigger a refresh
21
+ * when their state changes without mutating a background task.
22
+ */
18
23
  notifyTasksChange() {
19
24
  this.callbacks.onBackgroundTasksChange?.(Array.from(this.tasks.values()));
20
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"workflowManager.d.ts","sourceRoot":"","sources":["../../src/managers/workflowManager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAelD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAOxD,qBAAa,eAAe;IAC1B,OAAO,CAAC,IAAI,CAAkC;IAC9C,OAAO,CAAC,gBAAgB,CAAsC;IAC9D,OAAO,CAAC,gBAAgB,CAAmD;IAC3E,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,aAAa,CAA8B;gBAEvC,SAAS,EAAE,SAAS;IAKhC,OAAO,KAAK,UAAU,GAOrB;IAED,OAAO,KAAK,qBAAqB,GAEhC;IAED,OAAO,KAAK,iBAAiB,GAE5B;IAED,OAAO,KAAK,eAAe,GAE1B;IAED,OAAO,KAAK,OAAO,GAElB;IAED,OAAO,KAAK,UAAU,GASrB;IAED;;;OAGG;IACG,SAAS,CACb,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,OAAO,EACd,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GAC1D,OAAO,CAAC,WAAW,CAAC;IAoDvB;;;OAGG;IACG,QAAQ,CACZ,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GAClC,OAAO,CAAC,IAAI,CAAC;IA2NhB;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ7C;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAY5B;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAUlD;;OAEG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBlE;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAsB5B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAcxC;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAI9C;;OAEG;IACH,OAAO,IAAI,IAAI;CAkBhB"}
1
+ {"version":3,"file":"workflowManager.d.ts","sourceRoot":"","sources":["../../src/managers/workflowManager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAelD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAOxD,qBAAa,eAAe;IAC1B,OAAO,CAAC,IAAI,CAAkC;IAC9C,OAAO,CAAC,gBAAgB,CAAsC;IAC9D,OAAO,CAAC,gBAAgB,CAAmD;IAC3E,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,aAAa,CAA8B;gBAEvC,SAAS,EAAE,SAAS;IAKhC,OAAO,KAAK,UAAU,GAOrB;IAED,OAAO,KAAK,qBAAqB,GAEhC;IAED,OAAO,KAAK,iBAAiB,GAE5B;IAED,OAAO,KAAK,eAAe,GAE1B;IAED,OAAO,KAAK,OAAO,GAElB;IAED,OAAO,KAAK,UAAU,GASrB;IAED;;;OAGG;IACG,SAAS,CACb,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,OAAO,EACd,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GAC1D,OAAO,CAAC,WAAW,CAAC;IAoDvB;;;OAGG;IACG,QAAQ,CACZ,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GAClC,OAAO,CAAC,IAAI,CAAC;IA6NhB;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ7C;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAY5B;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAUlD;;OAEG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBlE;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAsB5B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAcxC;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAI9C;;OAEG;IACH,OAAO,IAAI,IAAI;CAkBhB"}
@@ -112,9 +112,16 @@ export class WorkflowManager {
112
112
  ? run.args.budget
113
113
  : null);
114
114
  const progressReporter = new ProgressReporter(run.meta, runId);
115
- // Forward progress events via onProgress callback
115
+ // Forward progress events: mirror live counts onto the WorkflowRun and
116
+ // trigger a UI refresh so /workflows updates mid-execution (not just at
117
+ // completion). The UI reads getWorkflowRuns() -> listRuns(), which returns
118
+ // these same in-memory run objects.
116
119
  const onProgress = (event) => {
117
120
  logger.debug(`[Workflow:${runId}] progress: ${event.type} phase=${event.phaseIndex} agent=${event.agentIndex}`);
121
+ run.phases = progressReporter.getPhaseStates();
122
+ run.totalAgents = progressReporter.totalAgents;
123
+ run.totalTokens = progressReporter.totalTokens;
124
+ this.backgroundTaskManager.notifyTasksChange();
118
125
  };
119
126
  progressReporter.onEvent(onProgress);
120
127
  // Journal — load previous journal if resuming
@@ -175,9 +182,6 @@ export class WorkflowManager {
175
182
  sessionDir: this.sessionDir,
176
183
  runDir: path.join(this.sessionDir, "workflows", runId),
177
184
  agentControllers: runAgentControllers,
178
- onProgress: (event) => {
179
- logger.debug(`[Workflow:${runId}] progress: ${event.type} phase=${event.phaseIndex} agent=${event.agentIndex}`);
180
- },
181
185
  onLog: (message) => {
182
186
  logger.info(`[Workflow:${runId}] ${message}`);
183
187
  },
@@ -1 +1 @@
1
- {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/services/hook.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EAElC,MAAM,mBAAmB,CAAC;AAuG3B;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,EAC5D,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CA6I9B;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,EAC5D,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAchC;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAMhC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAsBtD"}
1
+ {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/services/hook.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EAElC,MAAM,mBAAmB,CAAC;AA8G3B;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,EAC5D,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CA6I9B;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,EAC5D,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAchC;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAMhC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAsBtD"}
@@ -83,6 +83,12 @@ async function buildHookJsonInput(context) {
83
83
  jsonInput.end_source = context.endSource;
84
84
  }
85
85
  }
86
+ // Add background_tasks and session_crons for Stop events only (not SubagentStop).
87
+ // Fields are always present for Stop (empty arrays when nothing in flight).
88
+ if (context.event === "Stop") {
89
+ jsonInput.background_tasks = context.backgroundTasks ?? [];
90
+ jsonInput.session_crons = context.sessionCrons ?? [];
91
+ }
86
92
  return jsonInput;
87
93
  }
88
94
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"grepTool.d.ts","sourceRoot":"","sources":["../../src/tools/grepTool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAUtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UA8StB,CAAC"}
1
+ {"version":3,"file":"grepTool.d.ts","sourceRoot":"","sources":["../../src/tools/grepTool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAsBtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UA0TtB,CAAC"}
@@ -2,6 +2,17 @@ import { spawn } from "child_process";
2
2
  import { rgPath } from "../utils/ripgrep.js";
3
3
  import { getDisplayPath } from "../utils/path.js";
4
4
  import { GREP_TOOL_NAME, BASH_TOOL_NAME, AGENT_TOOL_NAME, } from "../constants/tools.js";
5
+ // Version control system directories to exclude from searches.
6
+ // These are excluded automatically because they create noise in search results.
7
+ // Mirrors Claude Code's VCS_DIRECTORIES_TO_EXCLUDE.
8
+ const VCS_DIRECTORIES_TO_EXCLUDE = [
9
+ ".git",
10
+ ".svn",
11
+ ".hg",
12
+ ".bzr",
13
+ ".jj",
14
+ ".sl",
15
+ ];
5
16
  /**
6
17
  * Grep tool plugin - powerful search tool based on ripgrep
7
18
  */
@@ -119,7 +130,18 @@ export const grepTool = {
119
130
  }
120
131
  try {
121
132
  const workdir = context.workdir;
122
- const rgArgs = ["--color=never", "--max-columns=500"];
133
+ const rgArgs = [
134
+ "--color=never",
135
+ "--max-columns=500",
136
+ // Search hidden files/directories by default (aligns with Claude Code).
137
+ // --hidden does NOT disable .gitignore; only --no-ignore would.
138
+ "--hidden",
139
+ ];
140
+ // Exclude VCS directories to avoid noise from version control metadata.
141
+ // --hidden above would otherwise traverse .git/.svn/etc.
142
+ for (const dir of VCS_DIRECTORIES_TO_EXCLUDE) {
143
+ rgArgs.push("--glob", `!${dir}`);
144
+ }
123
145
  // Set output mode
124
146
  if (outputMode === "files_with_matches") {
125
147
  rgArgs.push("-l");
@@ -1,7 +1,7 @@
1
1
  import { relative, join, isAbsolute } from "path";
2
2
  import * as fs from "fs";
3
3
  import { logger } from "../utils/globalLogger.js";
4
- import { getDisplayPath } from "../utils/path.js";
4
+ import { getDisplayPath, toPosixPath } from "../utils/path.js";
5
5
  import { LSP_TOOL_NAME } from "../constants/tools.js";
6
6
  export const MAX_RESULTS = 1000;
7
7
  export const MAX_FILES = 100;
@@ -25,10 +25,10 @@ function formatUri(uri, workdir) {
25
25
  const relativePath = relative(workdir, path);
26
26
  if (relativePath.length < path.length &&
27
27
  !relativePath.startsWith("../../")) {
28
- return relativePath;
28
+ return toPosixPath(relativePath);
29
29
  }
30
30
  }
31
- return path;
31
+ return toPosixPath(path);
32
32
  }
33
33
  /**
34
34
  * Formats an error message when no results are found, including context from the file
@@ -79,6 +79,23 @@ export interface HookJsonInput {
79
79
  end_source?: SessionEndSource;
80
80
  compact_instructions?: string;
81
81
  compact_summary?: string;
82
+ background_tasks?: BackgroundTaskInfo[];
83
+ session_crons?: SessionCronInfo[];
84
+ }
85
+ export interface BackgroundTaskInfo {
86
+ id: string;
87
+ type: "shell" | "subagent" | "workflow";
88
+ status: string;
89
+ description: string;
90
+ command?: string;
91
+ agent_type?: string;
92
+ name?: string;
93
+ }
94
+ export interface SessionCronInfo {
95
+ id: string;
96
+ schedule: string;
97
+ recurring: boolean;
98
+ prompt: string;
82
99
  }
83
100
  export interface ExtendedHookExecutionContext extends HookExecutionContext {
84
101
  sessionId?: string;
@@ -97,6 +114,8 @@ export interface ExtendedHookExecutionContext extends HookExecutionContext {
97
114
  endSource?: SessionEndSource;
98
115
  compactInstructions?: string;
99
116
  compactSummary?: string;
117
+ backgroundTasks?: BackgroundTaskInfo[];
118
+ sessionCrons?: SessionCronInfo[];
100
119
  }
101
120
  export interface HookEnvironment {
102
121
  WAVE_PROJECT_DIR: string;
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/types/hooks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/types/hooks.ts"],"names":[],"mappings":"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"}
@@ -6,10 +6,16 @@
6
6
  */
7
7
  export declare function resolvePath(filePath: string, workdir: string): string;
8
8
  /**
9
- * Get relative path for display, use relative path if shorter and not in parent directory
9
+ * Get relative path for display, use relative path if shorter and not in parent directory.
10
+ *
11
+ * The returned path is always normalized to forward slashes (posix) regardless of
12
+ * platform. This keeps display output consistent across Windows/Unix so that logs,
13
+ * LLM context, and tests don't need platform-specific branches — `path.relative`
14
+ * and `path.join` produce backslashes on Windows, which we collapse here.
15
+ *
10
16
  * @param filePath Absolute path
11
17
  * @param workdir Working directory
12
- * @returns Path for display (relative or absolute)
18
+ * @returns Path for display (relative or absolute), always forward-slash
13
19
  */
14
20
  export declare function getDisplayPath(filePath: string, workdir: string): string;
15
21
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAarE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAwBxE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7C"}
1
+ {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAarE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAwBxE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7C"}
@@ -20,10 +20,16 @@ export function resolvePath(filePath, workdir) {
20
20
  return resolve(workdir, filePath);
21
21
  }
22
22
  /**
23
- * Get relative path for display, use relative path if shorter and not in parent directory
23
+ * Get relative path for display, use relative path if shorter and not in parent directory.
24
+ *
25
+ * The returned path is always normalized to forward slashes (posix) regardless of
26
+ * platform. This keeps display output consistent across Windows/Unix so that logs,
27
+ * LLM context, and tests don't need platform-specific branches — `path.relative`
28
+ * and `path.join` produce backslashes on Windows, which we collapse here.
29
+ *
24
30
  * @param filePath Absolute path
25
31
  * @param workdir Working directory
26
- * @returns Path for display (relative or absolute)
32
+ * @returns Path for display (relative or absolute), always forward-slash
27
33
  */
28
34
  export function getDisplayPath(filePath, workdir) {
29
35
  if (!filePath) {
@@ -38,13 +44,13 @@ export function getDisplayPath(filePath, workdir) {
38
44
  // If the relative path is shorter than the absolute path and does not start with .. (not in parent directory), use the relative path
39
45
  if (relativePath.length < filePath.length &&
40
46
  !relativePath.startsWith("..")) {
41
- return relativePath;
47
+ return toPosixPath(relativePath);
42
48
  }
43
49
  }
44
50
  catch {
45
51
  // If calculating the relative path fails, keep the original path
46
52
  }
47
- return filePath;
53
+ return toPosixPath(filePath);
48
54
  }
49
55
  /**
50
56
  * Convert backslashes to forward slashes for shell compatibility on Windows.
@@ -1 +1 @@
1
- {"version":3,"file":"pathEncoder.d.ts","sourceRoot":"","sources":["../../src/utils/pathEncoder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgC;IACxD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAwB;gBAExC,OAAO,GAAE,mBAAwB;IAW7C;;OAEG;IACG,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMnD;;;OAGG;IACH,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAsCxC;;;OAGG;IACG,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIzD;;;OAGG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAgC9C;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBhD;;OAEG;IACG,mBAAmB,CACvB,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,gBAAgB,CAAC;IAmC5B;;OAEG;IACG,sBAAsB,CAC1B,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,gBAAgB,CAAC;IAgB5B;;OAEG;IACH,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IA+BjD;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM;IAqBtE;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAsDhC;;OAEG;IACH,OAAO,CAAC,YAAY;IAOpB;;OAEG;IACH,OAAO,CAAC,WAAW;CAMpB;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,aAAoB,CAAC"}
1
+ {"version":3,"file":"pathEncoder.d.ts","sourceRoot":"","sources":["../../src/utils/pathEncoder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgC;IACxD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAwB;gBAExC,OAAO,GAAE,mBAAwB;IAW7C;;OAEG;IACG,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMnD;;;OAGG;IACH,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IA4CxC;;;OAGG;IACG,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIzD;;;OAGG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAgC9C;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBhD;;OAEG;IACG,mBAAmB,CACvB,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,gBAAgB,CAAC;IAmC5B;;OAEG;IACG,sBAAsB,CAC1B,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,gBAAgB,CAAC;IAgB5B;;OAEG;IACH,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IA+BjD;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM;IAqBtE;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAsDhC;;OAEG;IACH,OAAO,CAAC,YAAY;IAOpB;;OAEG;IACH,OAAO,CAAC,WAAW;CAMpB;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,aAAoB,CAAC"}
@@ -35,8 +35,13 @@ export class PathEncoder {
35
35
  encodeSync(pathToEncode) {
36
36
  // Convert to safe directory name
37
37
  let encoded = pathToEncode;
38
- // Remove leading slash to avoid empty directory names
39
- if (encoded.startsWith("/")) {
38
+ // Remove Windows drive letter prefix (e.g. "D:") so encoded names are
39
+ // stable across platforms — path.resolve("/home/user/project") yields
40
+ // "D:\home\user\project" on Windows and we want the same encoded name
41
+ // as on Linux ("home-user-project").
42
+ encoded = encoded.replace(/^[a-zA-Z]:/, "");
43
+ // Remove leading slash/backslash to avoid empty directory names
44
+ if (encoded.startsWith("/") || encoded.startsWith("\\")) {
40
45
  encoded = encoded.substring(1);
41
46
  }
42
47
  // Replace path separators with hyphens
@@ -3,7 +3,7 @@ import { ConcurrencyLimiter } from "./concurrencyLimiter.js";
3
3
  import { BudgetTracker } from "./budgetTracker.js";
4
4
  import { ProgressReporter } from "./progressReporter.js";
5
5
  import { Journal } from "./journal.js";
6
- import type { BudgetInfo, WorkflowProgressEvent } from "./types.js";
6
+ import type { BudgetInfo } from "./types.js";
7
7
  interface WorkflowApiContext {
8
8
  subagentManager: SubagentManager;
9
9
  concurrencyLimiter: ConcurrencyLimiter;
@@ -21,8 +21,6 @@ interface WorkflowApiContext {
21
21
  runDir: string;
22
22
  /** Per-agent abort controllers for kill/skip support */
23
23
  agentControllers: Map<number, AbortController>;
24
- /** Optional callback for progress events */
25
- onProgress?: (event: WorkflowProgressEvent) => void;
26
24
  }
27
25
  interface AgentOpts {
28
26
  label?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"workflowApis.d.ts","sourceRoot":"","sources":["../../src/workflow/workflowApis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAa,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAgC/E,UAAU,kBAAkB;IAC1B,eAAe,EAAE,eAAe,CAAC;IACjC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,aAAa,EAAE,aAAa,CAAC;IAC7B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC/C,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;CACrD;AAED,UAAU,SAAS;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,SAAS,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9D,QAAQ,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACxE,QAAQ,EAAE,CACR,KAAK,EAAE,OAAO,EAAE,EAChB,GAAG,MAAM,EAAE,KAAK,CACd,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAClE,KACE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACxB,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,GAAG,YAAY,CAuUxE"}
1
+ {"version":3,"file":"workflowApis.d.ts","sourceRoot":"","sources":["../../src/workflow/workflowApis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;AAgCxD,UAAU,kBAAkB;IAC1B,eAAe,EAAE,eAAe,CAAC;IACjC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,aAAa,EAAE,aAAa,CAAC;IAC7B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAChD;AAED,UAAU,SAAS;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,SAAS,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9D,QAAQ,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACxE,QAAQ,EAAE,CACR,KAAK,EAAE,OAAO,EAAE,EAChB,GAAG,MAAM,EAAE,KAAK,CACd,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAClE,KACE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACxB,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,GAAG,YAAY,CAuUxE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wave-agent-sdk",
3
- "version": "0.19.3",
3
+ "version": "0.19.5",
4
4
  "description": "SDK for building AI-powered development tools and agents",
5
5
  "keywords": [
6
6
  "ai",
@@ -16,7 +16,7 @@ async function main() {
16
16
  }
17
17
 
18
18
  const manifestContent = fs.readFileSync(MANIFEST_PATH, "utf-8");
19
- const jsonContent = manifestContent.replace(/^#!.*\n/, "");
19
+ const jsonContent = manifestContent.replace(/^#!.*\r?\n/, "");
20
20
  const manifest = JSON.parse(jsonContent);
21
21
  const platforms = manifest.platforms;
22
22
 
@@ -26,8 +26,10 @@ import { ChatCompletionMessageFunctionToolCall } from "openai/resources.js";
26
26
 
27
27
  import type { HookManager } from "./hookManager.js";
28
28
  import type { ExtendedHookExecutionContext } from "../types/hooks.js";
29
+ import type { BackgroundTaskInfo, SessionCronInfo } from "../types/hooks.js";
29
30
  import type { PermissionManager } from "./permissionManager.js";
30
31
  import type { SubagentManager } from "./subagentManager.js";
32
+ import type { CronManager } from "./cronManager.js";
31
33
  import type { SkillManager } from "./skillManager.js";
32
34
  import { buildSystemPrompt } from "../prompts/index.js";
33
35
  import {
@@ -49,6 +51,47 @@ import {
49
51
  resetTracingState,
50
52
  } from "../telemetry/sessionTracing.js";
51
53
  import { logOTelEvent } from "../telemetry/events.js";
54
+ import type { BackgroundTask } from "../types/processes.js";
55
+
56
+ // Truncate text to `max` chars and append a "… [+N chars]" marker when exceeded.
57
+ // Used for background_tasks description/command fields (≤1000 chars per spec FR-063).
58
+ function truncateWithMarker(text: string, max: number): string {
59
+ if (text.length <= max) return text;
60
+ return text.slice(0, max) + `… [+${text.length - max} chars]`;
61
+ }
62
+
63
+ // Map a BackgroundTask (from BackgroundTaskManager) to the Stop hook's
64
+ // background_tasks array element shape (aligned with Claude Code v2.1.145+).
65
+ // Conditional fields are populated based on task type:
66
+ // - shell: `command`
67
+ // - subagent: `agent_type` (looked up via SubagentManager by subagentId)
68
+ // - workflow: `name` (extracted from "Workflow: <name>" description)
69
+ function mapBackgroundTask(
70
+ task: BackgroundTask,
71
+ subagentManager: SubagentManager | undefined,
72
+ ): BackgroundTaskInfo {
73
+ const base: BackgroundTaskInfo = {
74
+ id: task.id,
75
+ type: task.type,
76
+ status: task.status,
77
+ description: truncateWithMarker(task.description ?? "", 1000),
78
+ };
79
+ if (task.type === "shell") {
80
+ return { ...base, command: truncateWithMarker(task.command ?? "", 1000) };
81
+ }
82
+ if (task.type === "subagent") {
83
+ const instance = subagentManager
84
+ ?.getActiveInstances()
85
+ .find((i) => i.subagentId === task.subagentId);
86
+ return { ...base, agent_type: instance?.subagentType ?? "" };
87
+ }
88
+ // workflow
89
+ const prefix = "Workflow: ";
90
+ const name = task.description?.startsWith(prefix)
91
+ ? task.description.slice(prefix.length)
92
+ : (task.description ?? "");
93
+ return { ...base, name };
94
+ }
52
95
 
53
96
  export interface AIManagerCallbacks {
54
97
  onCompactionStateChange?: (isCompacting: boolean) => void;
@@ -734,6 +777,10 @@ export class AIManager {
734
777
  return this.container.get<SubagentManager>("SubagentManager");
735
778
  }
736
779
 
780
+ private get cronManager(): CronManager | undefined {
781
+ return this.container.get<CronManager>("CronManager");
782
+ }
783
+
737
784
  private get skillManager(): SkillManager | undefined {
738
785
  return this.container.get<SkillManager>("SkillManager");
739
786
  }
@@ -1435,6 +1482,26 @@ export class AIManager {
1435
1482
  // Use "SubagentStop" hook name when triggered by a subagent, otherwise use "Stop"
1436
1483
  const hookName = this.subagentType ? "SubagentStop" : "Stop";
1437
1484
 
1485
+ // For main-agent Stop events, snapshot running background tasks and
1486
+ // session cron jobs so the hook can decide whether to block stopping.
1487
+ // SubagentStop does not include these fields (per spec FR-065).
1488
+ const backgroundTasks: BackgroundTaskInfo[] | undefined =
1489
+ hookName === "Stop"
1490
+ ? (this.backgroundTaskManager?.getAllTasks() ?? [])
1491
+ .filter((t) => t.status === "running")
1492
+ .map((t) => mapBackgroundTask(t, this.subagentManager))
1493
+ : undefined;
1494
+
1495
+ const sessionCrons: SessionCronInfo[] | undefined =
1496
+ hookName === "Stop"
1497
+ ? (this.cronManager?.listJobs() ?? []).map((j) => ({
1498
+ id: j.id,
1499
+ schedule: j.cron,
1500
+ recurring: j.recurring,
1501
+ prompt: j.prompt,
1502
+ }))
1503
+ : undefined;
1504
+
1438
1505
  const context: ExtendedHookExecutionContext = {
1439
1506
  event: hookName,
1440
1507
  projectDir: this.getWorkdir(),
@@ -1443,6 +1510,8 @@ export class AIManager {
1443
1510
  transcriptPath: this.messageManager.getTranscriptPath(),
1444
1511
  cwd: this.getWorkdir(),
1445
1512
  subagentType: this.subagentType, // Include subagent type in hook context
1513
+ backgroundTasks, // Stop-only: running background tasks snapshot
1514
+ sessionCrons, // Stop-only: session cron jobs snapshot
1446
1515
  // Stop hooks don't need toolName, toolInput, toolResponse, or userPrompt
1447
1516
  env: Object.fromEntries(
1448
1517
  Object.entries(process.env).filter((e) => e[1] !== undefined),
@@ -35,7 +35,12 @@ export class BackgroundTaskManager {
35
35
  return this.container.get<NotificationQueue>("NotificationQueue")!;
36
36
  }
37
37
 
38
- private notifyTasksChange(): void {
38
+ /**
39
+ * Fire the onBackgroundTasksChange callback so UI consumers refresh.
40
+ * Public so other managers (e.g. WorkflowManager) can trigger a refresh
41
+ * when their state changes without mutating a background task.
42
+ */
43
+ public notifyTasksChange(): void {
39
44
  this.callbacks.onBackgroundTasksChange?.(Array.from(this.tasks.values()));
40
45
  }
41
46
 
@@ -164,13 +164,20 @@ export class WorkflowManager {
164
164
  );
165
165
  const progressReporter = new ProgressReporter(run.meta, runId);
166
166
 
167
- // Forward progress events via onProgress callback
167
+ // Forward progress events: mirror live counts onto the WorkflowRun and
168
+ // trigger a UI refresh so /workflows updates mid-execution (not just at
169
+ // completion). The UI reads getWorkflowRuns() -> listRuns(), which returns
170
+ // these same in-memory run objects.
168
171
  const onProgress = (
169
172
  event: import("../workflow/types.js").WorkflowProgressEvent,
170
173
  ) => {
171
174
  logger.debug(
172
175
  `[Workflow:${runId}] progress: ${event.type} phase=${event.phaseIndex} agent=${event.agentIndex}`,
173
176
  );
177
+ run.phases = progressReporter.getPhaseStates();
178
+ run.totalAgents = progressReporter.totalAgents;
179
+ run.totalTokens = progressReporter.totalTokens;
180
+ this.backgroundTaskManager.notifyTasksChange();
174
181
  };
175
182
  progressReporter.onEvent(onProgress);
176
183
 
@@ -251,11 +258,6 @@ export class WorkflowManager {
251
258
  sessionDir: this.sessionDir,
252
259
  runDir: path.join(this.sessionDir, "workflows", runId),
253
260
  agentControllers: runAgentControllers,
254
- onProgress: (event) => {
255
- logger.debug(
256
- `[Workflow:${runId}] progress: ${event.type} phase=${event.phaseIndex} agent=${event.agentIndex}`,
257
- );
258
- },
259
261
  onLog: (message: string) => {
260
262
  logger.info(`[Workflow:${runId}] ${message}`);
261
263
  },
@@ -113,6 +113,13 @@ async function buildHookJsonInput(
113
113
  }
114
114
  }
115
115
 
116
+ // Add background_tasks and session_crons for Stop events only (not SubagentStop).
117
+ // Fields are always present for Stop (empty arrays when nothing in flight).
118
+ if (context.event === "Stop") {
119
+ jsonInput.background_tasks = context.backgroundTasks ?? [];
120
+ jsonInput.session_crons = context.sessionCrons ?? [];
121
+ }
122
+
116
123
  return jsonInput;
117
124
  }
118
125
 
@@ -8,6 +8,18 @@ import {
8
8
  AGENT_TOOL_NAME,
9
9
  } from "../constants/tools.js";
10
10
 
11
+ // Version control system directories to exclude from searches.
12
+ // These are excluded automatically because they create noise in search results.
13
+ // Mirrors Claude Code's VCS_DIRECTORIES_TO_EXCLUDE.
14
+ const VCS_DIRECTORIES_TO_EXCLUDE = [
15
+ ".git",
16
+ ".svn",
17
+ ".hg",
18
+ ".bzr",
19
+ ".jj",
20
+ ".sl",
21
+ ] as const;
22
+
11
23
  /**
12
24
  * Grep tool plugin - powerful search tool based on ripgrep
13
25
  */
@@ -144,7 +156,19 @@ export const grepTool: ToolPlugin = {
144
156
 
145
157
  try {
146
158
  const workdir = context.workdir;
147
- const rgArgs: string[] = ["--color=never", "--max-columns=500"];
159
+ const rgArgs: string[] = [
160
+ "--color=never",
161
+ "--max-columns=500",
162
+ // Search hidden files/directories by default (aligns with Claude Code).
163
+ // --hidden does NOT disable .gitignore; only --no-ignore would.
164
+ "--hidden",
165
+ ];
166
+
167
+ // Exclude VCS directories to avoid noise from version control metadata.
168
+ // --hidden above would otherwise traverse .git/.svn/etc.
169
+ for (const dir of VCS_DIRECTORIES_TO_EXCLUDE) {
170
+ rgArgs.push("--glob", `!${dir}`);
171
+ }
148
172
 
149
173
  // Set output mode
150
174
  if (outputMode === "files_with_matches") {
@@ -2,7 +2,7 @@ import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
2
2
  import { relative, join, isAbsolute } from "path";
3
3
  import * as fs from "fs";
4
4
  import { logger } from "../utils/globalLogger.js";
5
- import { getDisplayPath } from "../utils/path.js";
5
+ import { getDisplayPath, toPosixPath } from "../utils/path.js";
6
6
  import { LSP_TOOL_NAME } from "../constants/tools.js";
7
7
  import type {
8
8
  LspLocation as Location,
@@ -45,10 +45,10 @@ function formatUri(uri: string, workdir?: string): string {
45
45
  relativePath.length < path.length &&
46
46
  !relativePath.startsWith("../../")
47
47
  ) {
48
- return relativePath;
48
+ return toPosixPath(relativePath);
49
49
  }
50
50
  }
51
- return path;
51
+ return toPosixPath(path);
52
52
  }
53
53
 
54
54
  /**
@@ -196,6 +196,33 @@ export interface HookJsonInput {
196
196
  end_source?: SessionEndSource; // Present for SessionEnd events
197
197
  compact_instructions?: string; // Present for PreCompact events
198
198
  compact_summary?: string; // Present for PostCompact events
199
+ background_tasks?: BackgroundTaskInfo[]; // Present for Stop events: running background tasks snapshot
200
+ session_crons?: SessionCronInfo[]; // Present for Stop events: session-scoped cron jobs snapshot
201
+ }
202
+
203
+ // Describes one in-flight background task in the Stop hook input.
204
+ // Aligned with Claude Code (v2.1.145+) background_tasks array element schema.
205
+ // Conditional fields are populated based on `type`:
206
+ // - "shell": `command` is set
207
+ // - "subagent": `agent_type` is set
208
+ // - "workflow": `name` is set
209
+ export interface BackgroundTaskInfo {
210
+ id: string;
211
+ type: "shell" | "subagent" | "workflow";
212
+ status: string;
213
+ description: string; // Capped at 1000 chars with "… [+N chars]" marker
214
+ command?: string; // Present only for shell tasks (≤1000 chars)
215
+ agent_type?: string; // Present only for subagent tasks
216
+ name?: string; // Present only for workflow tasks
217
+ }
218
+
219
+ // Describes one session-scoped cron job in the Stop hook input.
220
+ // Aligned with Claude Code (v2.1.145+) session_crons array element schema.
221
+ export interface SessionCronInfo {
222
+ id: string;
223
+ schedule: string; // Cron expression
224
+ recurring: boolean;
225
+ prompt: string;
199
226
  }
200
227
 
201
228
  // Extended context interface for passing additional data to hook executor
@@ -216,6 +243,8 @@ export interface ExtendedHookExecutionContext extends HookExecutionContext {
216
243
  endSource?: SessionEndSource; // Session end source (SessionEnd only)
217
244
  compactInstructions?: string; // Custom instructions for PreCompact
218
245
  compactSummary?: string; // Summary text for PostCompact
246
+ backgroundTasks?: BackgroundTaskInfo[]; // Running background tasks snapshot (Stop only)
247
+ sessionCrons?: SessionCronInfo[]; // Session-scoped cron jobs snapshot (Stop only)
219
248
  }
220
249
 
221
250
  // Environment variables injected into hook processes
package/src/utils/path.ts CHANGED
@@ -24,10 +24,16 @@ export function resolvePath(filePath: string, workdir: string): string {
24
24
  }
25
25
 
26
26
  /**
27
- * Get relative path for display, use relative path if shorter and not in parent directory
27
+ * Get relative path for display, use relative path if shorter and not in parent directory.
28
+ *
29
+ * The returned path is always normalized to forward slashes (posix) regardless of
30
+ * platform. This keeps display output consistent across Windows/Unix so that logs,
31
+ * LLM context, and tests don't need platform-specific branches — `path.relative`
32
+ * and `path.join` produce backslashes on Windows, which we collapse here.
33
+ *
28
34
  * @param filePath Absolute path
29
35
  * @param workdir Working directory
30
- * @returns Path for display (relative or absolute)
36
+ * @returns Path for display (relative or absolute), always forward-slash
31
37
  */
32
38
  export function getDisplayPath(filePath: string, workdir: string): string {
33
39
  if (!filePath) {
@@ -47,12 +53,12 @@ export function getDisplayPath(filePath: string, workdir: string): string {
47
53
  relativePath.length < filePath.length &&
48
54
  !relativePath.startsWith("..")
49
55
  ) {
50
- return relativePath;
56
+ return toPosixPath(relativePath);
51
57
  }
52
58
  } catch {
53
59
  // If calculating the relative path fails, keep the original path
54
60
  }
55
- return filePath;
61
+ return toPosixPath(filePath);
56
62
  }
57
63
 
58
64
  /**
@@ -86,8 +86,14 @@ export class PathEncoder {
86
86
  // Convert to safe directory name
87
87
  let encoded = pathToEncode;
88
88
 
89
- // Remove leading slash to avoid empty directory names
90
- if (encoded.startsWith("/")) {
89
+ // Remove Windows drive letter prefix (e.g. "D:") so encoded names are
90
+ // stable across platforms — path.resolve("/home/user/project") yields
91
+ // "D:\home\user\project" on Windows and we want the same encoded name
92
+ // as on Linux ("home-user-project").
93
+ encoded = encoded.replace(/^[a-zA-Z]:/, "");
94
+
95
+ // Remove leading slash/backslash to avoid empty directory names
96
+ if (encoded.startsWith("/") || encoded.startsWith("\\")) {
91
97
  encoded = encoded.substring(1);
92
98
  }
93
99
 
@@ -5,7 +5,7 @@ import { ConcurrencyLimiter } from "./concurrencyLimiter.js";
5
5
  import { BudgetTracker } from "./budgetTracker.js";
6
6
  import { ProgressReporter } from "./progressReporter.js";
7
7
  import { Journal } from "./journal.js";
8
- import type { BudgetInfo, AgentMeta, WorkflowProgressEvent } from "./types.js";
8
+ import type { BudgetInfo, AgentMeta } from "./types.js";
9
9
  import {
10
10
  createStructuredOutputPrompt,
11
11
  createStructuredOutputTool,
@@ -54,8 +54,6 @@ interface WorkflowApiContext {
54
54
  runDir: string;
55
55
  /** Per-agent abort controllers for kill/skip support */
56
56
  agentControllers: Map<number, AbortController>;
57
- /** Optional callback for progress events */
58
- onProgress?: (event: WorkflowProgressEvent) => void;
59
57
  }
60
58
 
61
59
  interface AgentOpts {