wave-agent-sdk 0.9.1 → 0.9.2

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.
@@ -31,6 +31,7 @@ export declare class PermissionManager {
31
31
  private deniedRules;
32
32
  private temporaryRules;
33
33
  private additionalDirectories;
34
+ private systemAdditionalDirectories;
34
35
  private workdir?;
35
36
  private planFilePath?;
36
37
  private onConfiguredDefaultModeChange?;
@@ -84,6 +85,10 @@ export declare class PermissionManager {
84
85
  * Update the additional directories (e.g., when configuration reloads)
85
86
  */
86
87
  updateAdditionalDirectories(directories: string[]): void;
88
+ /**
89
+ * Add a system-level additional directory that is persistent across configuration reloads
90
+ */
91
+ addSystemAdditionalDirectory(directory: string): void;
87
92
  /**
88
93
  * Update the working directory
89
94
  */
@@ -1 +1 @@
1
- {"version":3,"file":"permissionManager.d.ts","sourceRoot":"","sources":["../../src/managers/permissionManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"permissionManager.d.ts","sourceRoot":"","sources":["../../src/managers/permissionManager.ts"],"names":[],"mappings":"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"}
@@ -42,6 +42,7 @@ export class PermissionManager {
42
42
  this.deniedRules = [];
43
43
  this.temporaryRules = [];
44
44
  this.additionalDirectories = [];
45
+ this.systemAdditionalDirectories = [];
45
46
  this.configuredDefaultMode = options.configuredDefaultMode;
46
47
  this.allowedRules = options.allowedRules || [];
47
48
  this.deniedRules = options.deniedRules || [];
@@ -133,6 +134,17 @@ export class PermissionManager {
133
134
  return path.resolve(dir);
134
135
  });
135
136
  }
137
+ /**
138
+ * Add a system-level additional directory that is persistent across configuration reloads
139
+ */
140
+ addSystemAdditionalDirectory(directory) {
141
+ const resolvedPath = this.workdir && !path.isAbsolute(directory)
142
+ ? path.resolve(this.workdir, directory)
143
+ : path.resolve(directory);
144
+ if (!this.systemAdditionalDirectories.includes(resolvedPath)) {
145
+ this.systemAdditionalDirectories.push(resolvedPath);
146
+ }
147
+ }
136
148
  /**
137
149
  * Update the working directory
138
150
  */
@@ -170,6 +182,12 @@ export class PermissionManager {
170
182
  return { isInside: true, resolvedPath: absolutePath };
171
183
  }
172
184
  }
185
+ // Check system additional directories
186
+ for (const dir of this.systemAdditionalDirectories) {
187
+ if (isPathInside(absolutePath, dir)) {
188
+ return { isInside: true, resolvedPath: absolutePath };
189
+ }
190
+ }
173
191
  return { isInside: false, resolvedPath: absolutePath };
174
192
  }
175
193
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"initializationService.d.ts","sourceRoot":"","sources":["../../src/services/initializationService.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,OAAO,EACP,MAAM,EACN,YAAY,EACZ,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAIpD,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,eAAe,CAAC;IACjC,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,WAAW,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,WAAW,CAAC;IACxB,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,WAAW,EAAE,WAAW,CAAC;IACzB,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,WAAW,EAAE,WAAW,CAAC;IACzB,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,wBAAwB,EAAE,MAAM,IAAI,CAAC;CACtC;AAED,qBAAa,qBAAqB;WACZ,UAAU,CAC5B,OAAO,EAAE,qBAAqB,EAC9B,OAAO,CAAC,EAAE;QACR,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;KACtB,GACA,OAAO,CAAC,IAAI,CAAC;CAqOjB"}
1
+ {"version":3,"file":"initializationService.d.ts","sourceRoot":"","sources":["../../src/services/initializationService.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,OAAO,EACP,MAAM,EACN,YAAY,EACZ,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAIpD,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,eAAe,CAAC;IACjC,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,WAAW,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,WAAW,CAAC;IACxB,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,WAAW,EAAE,WAAW,CAAC;IACzB,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,WAAW,EAAE,WAAW,CAAC;IACzB,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,wBAAwB,EAAE,MAAM,IAAI,CAAC;CACtC;AAED,qBAAa,qBAAqB;WACZ,UAAU,CAC5B,OAAO,EAAE,qBAAqB,EAC9B,OAAO,CAAC,EAAE;QACR,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;KACtB,GACA,OAAO,CAAC,IAAI,CAAC;CAgPjB"}
@@ -57,6 +57,9 @@ export class InitializationService {
57
57
  if (configResult.configuration.permissions.defaultMode) {
58
58
  permissionManager.updateConfiguredDefaultMode(configResult.configuration.permissions.defaultMode);
59
59
  }
60
+ if (configResult.configuration.permissions.additionalDirectories) {
61
+ permissionManager.updateAdditionalDirectories(configResult.configuration.permissions.additionalDirectories);
62
+ }
60
63
  }
61
64
  }
62
65
  }
@@ -93,6 +96,11 @@ export class InitializationService {
93
96
  const memoryService = container.get("MemoryService");
94
97
  if (memoryService) {
95
98
  await memoryService.ensureAutoMemoryDirectory(workdir);
99
+ const permissionManager = container.get("PermissionManager");
100
+ if (permissionManager) {
101
+ const autoMemoryDir = memoryService.getAutoMemoryDirectory(workdir);
102
+ permissionManager.addSystemAdditionalDirectory(autoMemoryDir);
103
+ }
96
104
  }
97
105
  }
98
106
  }
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/services/memory.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAIlD,qBAAa,aAAa;IACZ,OAAO,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAExC;;;OAGG;IACH,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAM/C;;OAEG;IACG,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B/D;;OAEG;IACG,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBtD,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IA8BrC,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IAevC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBhD,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAqBjE"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/services/memory.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAIlD,qBAAa,aAAa;IACZ,OAAO,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAExC;;;OAGG;IACH,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAU/C;;OAEG;IACG,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B/D;;OAEG;IACG,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBtD,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IA8BrC,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IAevC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBhD,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAqBjE"}
@@ -14,7 +14,10 @@ export class MemoryService {
14
14
  * Uses the git common directory to ensure worktrees share the same memory.
15
15
  */
16
16
  getAutoMemoryDirectory(workdir) {
17
- const projectRoot = getGitCommonDir(workdir);
17
+ const commonDir = getGitCommonDir(workdir);
18
+ // If the common directory is a .git directory, use its parent as the project root
19
+ // for a cleaner encoded name while maintaining stability across worktrees.
20
+ const projectRoot = path.basename(commonDir) === ".git" ? path.dirname(commonDir) : commonDir;
18
21
  const encodedName = pathEncoder.encodeSync(projectRoot);
19
22
  return path.join(homedir(), ".wave", "projects", encodedName, "memory");
20
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"globTool.d.ts","sourceRoot":"","sources":["../../src/tools/globTool.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAUtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UA4ItB,CAAC"}
1
+ {"version":3,"file":"globTool.d.ts","sourceRoot":"","sources":["../../src/tools/globTool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAiEtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UAsItB,CAAC"}
@@ -1,12 +1,55 @@
1
- import { glob } from "glob";
1
+ import { spawn } from "child_process";
2
+ import { rgPath } from "@vscode/ripgrep";
2
3
  import { stat } from "fs/promises";
3
4
  import { resolvePath, getDisplayPath } from "../utils/path.js";
4
- import { getGlobIgnorePatterns } from "../utils/fileFilter.js";
5
+ import { getAllIgnorePatterns } from "../utils/fileFilter.js";
5
6
  import { GLOB_TOOL_NAME } from "../constants/tools.js";
6
7
  /**
7
8
  * Maximum number of files returned by glob tool
8
9
  */
9
10
  const MAX_GLOB_RESULTS = 1000;
11
+ /**
12
+ * Execute ripgrep to find files matching a pattern
13
+ */
14
+ async function runRipgrep(pattern, workdir) {
15
+ if (!rgPath) {
16
+ throw new Error("ripgrep is not available");
17
+ }
18
+ const ignorePatterns = getAllIgnorePatterns();
19
+ const rgArgs = ["--files", "--color=never", "--hidden", "--glob", pattern];
20
+ for (const ignorePattern of ignorePatterns) {
21
+ rgArgs.push("--glob", `!${ignorePattern}`);
22
+ }
23
+ return new Promise((resolve, reject) => {
24
+ const child = spawn(rgPath, rgArgs, {
25
+ cwd: workdir,
26
+ stdio: ["ignore", "pipe", "pipe"],
27
+ });
28
+ let stdout = "";
29
+ let stderr = "";
30
+ child.stdout?.on("data", (data) => {
31
+ stdout += data.toString();
32
+ });
33
+ child.stderr?.on("data", (data) => {
34
+ stderr += data.toString();
35
+ });
36
+ child.on("close", (code) => {
37
+ if (code !== 0 && code !== 1) {
38
+ reject(new Error(`ripgrep failed with code ${code}: ${stderr || "Unknown error"}`));
39
+ return;
40
+ }
41
+ const files = stdout
42
+ .trim()
43
+ .split("\n")
44
+ .filter((f) => f.length > 0)
45
+ .map((f) => f.replace(/\\/g, "/")); // Normalize to forward slashes
46
+ resolve(files);
47
+ });
48
+ child.on("error", (err) => {
49
+ reject(err);
50
+ });
51
+ });
52
+ }
10
53
  /**
11
54
  * Glob Tool Plugin - Fast file pattern matching
12
55
  */
@@ -54,14 +97,8 @@ export const globTool = {
54
97
  const workdir = searchPath
55
98
  ? resolvePath(searchPath, context.workdir)
56
99
  : context.workdir;
57
- // Execute glob search
58
- const matches = await glob(pattern, {
59
- cwd: workdir,
60
- ignore: getGlobIgnorePatterns(workdir),
61
- dot: false,
62
- absolute: false,
63
- nocase: false, // Keep case sensitive
64
- });
100
+ // Execute glob search using ripgrep
101
+ const matches = await runRipgrep(pattern, workdir);
65
102
  if (matches.length === 0) {
66
103
  return {
67
104
  success: true,
@@ -72,7 +109,7 @@ export const globTool = {
72
109
  // Get file modification time and sort
73
110
  const filesWithStats = await Promise.allSettled(matches.map(async (file) => {
74
111
  try {
75
- const fullPath = resolvePath(file, context.workdir);
112
+ const fullPath = resolvePath(file, workdir);
76
113
  const stats = await stat(fullPath);
77
114
  return {
78
115
  path: file,
@@ -1,5 +1,5 @@
1
1
  import { spawn } from "child_process";
2
- import { getGlobIgnorePatterns } from "../utils/fileFilter.js";
2
+ import { getAllIgnorePatterns } from "../utils/fileFilter.js";
3
3
  import { rgPath } from "@vscode/ripgrep";
4
4
  import { getDisplayPath } from "../utils/path.js";
5
5
  import { GREP_TOOL_NAME, BASH_TOOL_NAME, AGENT_TOOL_NAME, } from "../constants/tools.js";
@@ -158,7 +158,7 @@ export const grepTool = {
158
158
  rgArgs.push("--glob", globPattern);
159
159
  }
160
160
  // Get common ignore rules
161
- const ignorePatterns = getGlobIgnorePatterns(workdir);
161
+ const ignorePatterns = getAllIgnorePatterns();
162
162
  for (const exclude of ignorePatterns) {
163
163
  rgArgs.push("--glob", `!${exclude}`);
164
164
  }
@@ -78,7 +78,7 @@ export function setupAgentContainer(setupOptions) {
78
78
  const permissionManager = new PermissionManager(container, { workdir });
79
79
  if (configurationService.resolveAutoMemoryEnabled()) {
80
80
  const autoMemoryDir = memoryService.getAutoMemoryDirectory(workdir);
81
- permissionManager.updateAdditionalDirectories([autoMemoryDir]);
81
+ permissionManager.addSystemAdditionalDirectory(autoMemoryDir);
82
82
  }
83
83
  container.register("PermissionManager", permissionManager);
84
84
  permissionManager.setOnConfiguredDefaultModeChange((mode) => {
@@ -12,15 +12,4 @@ export declare const COMMON_IGNORE_PATTERNS: {
12
12
  * Get flat array of all common ignore patterns
13
13
  */
14
14
  export declare const getAllIgnorePatterns: () => string[];
15
- /**
16
- * Parse all .gitignore files in the working directory and its subdirectories and convert to glob patterns
17
- * @param workdir Working directory
18
- * @returns Array of glob ignore patterns
19
- */
20
- export declare const parseGitignoreToGlob: (workdir: string) => string[];
21
- /**
22
- * Get ignore patterns for glob search
23
- * @param workdir Working directory for resolving .gitignore files
24
- */
25
- export declare const getGlobIgnorePatterns: (workdir?: string) => string[];
26
15
  //# sourceMappingURL=fileFilter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fileFilter.d.ts","sourceRoot":"","sources":["../../src/utils/fileFilter.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;;;CAsBlC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,QAAO,MAAM,EAO7C,CAAC;AA4HF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAS,MAAM,KAAG,MAAM,EAgB5D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAAI,UAAU,MAAM,KAAG,MAAM,EAS9D,CAAC"}
1
+ {"version":3,"file":"fileFilter.d.ts","sourceRoot":"","sources":["../../src/utils/fileFilter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;;;CAsBlC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,QAAO,MAAM,EAO7C,CAAC"}
@@ -1,5 +1,3 @@
1
- import * as fs from "fs";
2
- import * as path from "path";
3
1
  /**
4
2
  * Common ignore directory and file patterns
5
3
  * Can be reused by multiple tools (glob, ripgrep, etc.)
@@ -35,143 +33,3 @@ export const getAllIgnorePatterns = () => {
35
33
  ...COMMON_IGNORE_PATTERNS.os,
36
34
  ];
37
35
  };
38
- /**
39
- * Recursively find all .gitignore files in directory
40
- * @param dir Directory to search
41
- * @param maxDepth Maximum recursion depth to prevent too deep searches
42
- * @returns Array of .gitignore file paths
43
- */
44
- const findAllGitignoreFiles = (dir, maxDepth = 5) => {
45
- const gitignoreFiles = [];
46
- if (maxDepth <= 0)
47
- return gitignoreFiles;
48
- try {
49
- const items = fs.readdirSync(dir, { withFileTypes: true });
50
- for (const item of items) {
51
- const fullPath = path.join(dir, item.name);
52
- if (item.isFile() && item.name === ".gitignore") {
53
- gitignoreFiles.push(fullPath);
54
- }
55
- else if (item.isDirectory() && !shouldSkipDirectory(item.name)) {
56
- // Recursively search subdirectories, but skip some obviously unnecessary directories
57
- gitignoreFiles.push(...findAllGitignoreFiles(fullPath, maxDepth - 1));
58
- }
59
- }
60
- }
61
- catch {
62
- // Ignore permission errors and other issues
63
- }
64
- return gitignoreFiles;
65
- };
66
- /**
67
- * Determine whether to skip searching a directory
68
- */
69
- const shouldSkipDirectory = (dirName) => {
70
- const skipDirs = [
71
- "node_modules",
72
- ".git",
73
- "dist",
74
- "build",
75
- ".next",
76
- "coverage",
77
- ".nyc_output",
78
- "tmp",
79
- "temp",
80
- ".cache",
81
- ];
82
- return skipDirs.includes(dirName);
83
- };
84
- /**
85
- * Parse single .gitignore file content
86
- * @param gitignorePath .gitignore file path
87
- * @param basePath Base path for calculating relative paths
88
- * @returns Array of parsed glob patterns
89
- */
90
- const parseGitignoreFile = (gitignorePath, basePath) => {
91
- const patterns = [];
92
- try {
93
- if (fs.existsSync(gitignorePath)) {
94
- const gitignoreContent = fs.readFileSync(gitignorePath, "utf8");
95
- const gitignoreDir = path.dirname(gitignorePath);
96
- // Calculate relative directory relative to base path
97
- const relativeDirFromBase = path.relative(basePath, gitignoreDir);
98
- const lines = gitignoreContent
99
- .split("\n")
100
- .map((line) => line.trim())
101
- .filter((line) => line && !line.startsWith("#"));
102
- for (const line of lines) {
103
- // Skip negation rules (starting with !)
104
- if (line.startsWith("!")) {
105
- continue;
106
- }
107
- let pattern = line;
108
- // Handle patterns starting with / (relative to current .gitignore file directory)
109
- if (pattern.startsWith("/")) {
110
- pattern = pattern.slice(1); // Remove leading /
111
- }
112
- // If .gitignore is in subdirectory, need to add path prefix
113
- if (relativeDirFromBase && relativeDirFromBase !== ".") {
114
- pattern = path.posix.join(relativeDirFromBase, pattern);
115
- }
116
- // If directory pattern (ending with /)
117
- if (pattern.endsWith("/")) {
118
- const dirName = pattern.slice(0, -1);
119
- // For directory patterns, add both exact match and wildcard match
120
- patterns.push(`${dirName}/**`); // Directory and all its sub-content
121
- // If no path separators, it's a simple directory name, add global match
122
- if (!dirName.includes("/") && !dirName.includes("*")) {
123
- patterns.push(`**/${dirName}/**`); // Match directories of same name at any level
124
- }
125
- }
126
- else {
127
- // File pattern
128
- patterns.push(pattern);
129
- // If no wildcards and no extension, also treat as directory
130
- if (!pattern.includes("*") && !pattern.includes(".")) {
131
- patterns.push(`${pattern}/**`);
132
- // Also add global match for simple directory names
133
- if (!pattern.includes("/")) {
134
- patterns.push(`**/${pattern}/**`);
135
- }
136
- }
137
- }
138
- }
139
- }
140
- }
141
- catch {
142
- // Ignore errors when reading .gitignore files
143
- }
144
- return patterns;
145
- };
146
- /**
147
- * Parse all .gitignore files in the working directory and its subdirectories and convert to glob patterns
148
- * @param workdir Working directory
149
- * @returns Array of glob ignore patterns
150
- */
151
- export const parseGitignoreToGlob = (workdir) => {
152
- const patterns = [];
153
- try {
154
- // Find all .gitignore files
155
- const gitignoreFiles = findAllGitignoreFiles(workdir);
156
- // Parse each .gitignore file
157
- for (const gitignoreFile of gitignoreFiles) {
158
- patterns.push(...parseGitignoreFile(gitignoreFile, workdir));
159
- }
160
- }
161
- catch {
162
- // Ignore errors during search process
163
- }
164
- return patterns;
165
- };
166
- /**
167
- * Get ignore patterns for glob search
168
- * @param workdir Working directory for resolving .gitignore files
169
- */
170
- export const getGlobIgnorePatterns = (workdir) => {
171
- const patterns = getAllIgnorePatterns();
172
- // If working directory is provided, parse .gitignore files
173
- if (workdir) {
174
- patterns.push(...parseGitignoreToGlob(workdir));
175
- }
176
- return patterns;
177
- };
@@ -1,7 +1,7 @@
1
1
  import { spawn } from "child_process";
2
2
  import { rgPath } from "@vscode/ripgrep";
3
3
  import fuzzysort from "fuzzysort";
4
- import { getGlobIgnorePatterns } from "./fileFilter.js";
4
+ import { getAllIgnorePatterns } from "./fileFilter.js";
5
5
  import { logger } from "./globalLogger.js";
6
6
  /**
7
7
  * Execute ripgrep to get all file paths
@@ -10,7 +10,7 @@ async function getAllFiles(workingDirectory) {
10
10
  if (!rgPath) {
11
11
  throw new Error("ripgrep is not available");
12
12
  }
13
- const ignorePatterns = getGlobIgnorePatterns(workingDirectory);
13
+ const ignorePatterns = getAllIgnorePatterns();
14
14
  const rgArgs = ["--files", "--color=never", "--hidden"];
15
15
  for (const pattern of ignorePatterns) {
16
16
  rgArgs.push("--glob", `!${pattern}`);
@@ -108,14 +108,16 @@ export const updateToolBlockInMessage = ({ messages, id, parameters, result, suc
108
108
  if (toolBlockIndex !== -1) {
109
109
  const toolBlock = newMessages[i].blocks[toolBlockIndex];
110
110
  if (toolBlock.type === "tool") {
111
- toolBlock.parameters = parameters;
111
+ if (parameters !== undefined)
112
+ toolBlock.parameters = parameters;
112
113
  if (result !== undefined)
113
114
  toolBlock.result = result;
114
115
  if (shortResult !== undefined)
115
116
  toolBlock.shortResult = shortResult;
116
117
  if (startLineNumber !== undefined)
117
118
  toolBlock.startLineNumber = startLineNumber;
118
- toolBlock.images = images; // Add image data update
119
+ if (images !== undefined)
120
+ toolBlock.images = images; // Add image data update
119
121
  if (success !== undefined)
120
122
  toolBlock.success = success;
121
123
  if (error !== undefined)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wave-agent-sdk",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "description": "SDK for building AI-powered development tools and agents",
5
5
  "keywords": [
6
6
  "ai",
@@ -84,6 +84,7 @@ export class PermissionManager {
84
84
  private deniedRules: string[] = [];
85
85
  private temporaryRules: string[] = [];
86
86
  private additionalDirectories: string[] = [];
87
+ private systemAdditionalDirectories: string[] = [];
87
88
  private workdir?: string;
88
89
  private planFilePath?: string;
89
90
  private onConfiguredDefaultModeChange?: (mode: PermissionMode) => void;
@@ -203,6 +204,20 @@ export class PermissionManager {
203
204
  });
204
205
  }
205
206
 
207
+ /**
208
+ * Add a system-level additional directory that is persistent across configuration reloads
209
+ */
210
+ public addSystemAdditionalDirectory(directory: string): void {
211
+ const resolvedPath =
212
+ this.workdir && !path.isAbsolute(directory)
213
+ ? path.resolve(this.workdir, directory)
214
+ : path.resolve(directory);
215
+
216
+ if (!this.systemAdditionalDirectories.includes(resolvedPath)) {
217
+ this.systemAdditionalDirectories.push(resolvedPath);
218
+ }
219
+ }
220
+
206
221
  /**
207
222
  * Update the working directory
208
223
  */
@@ -251,6 +266,13 @@ export class PermissionManager {
251
266
  }
252
267
  }
253
268
 
269
+ // Check system additional directories
270
+ for (const dir of this.systemAdditionalDirectories) {
271
+ if (isPathInside(absolutePath, dir)) {
272
+ return { isInside: true, resolvedPath: absolutePath };
273
+ }
274
+ }
275
+
254
276
  return { isInside: false, resolvedPath: absolutePath };
255
277
  }
256
278
 
@@ -151,6 +151,11 @@ export class InitializationService {
151
151
  configResult.configuration.permissions.defaultMode,
152
152
  );
153
153
  }
154
+ if (configResult.configuration.permissions.additionalDirectories) {
155
+ permissionManager.updateAdditionalDirectories(
156
+ configResult.configuration.permissions.additionalDirectories,
157
+ );
158
+ }
154
159
  }
155
160
  }
156
161
  } catch (error) {
@@ -196,6 +201,12 @@ export class InitializationService {
196
201
  container.get<import("./memory.js").MemoryService>("MemoryService");
197
202
  if (memoryService) {
198
203
  await memoryService.ensureAutoMemoryDirectory(workdir);
204
+ const permissionManager =
205
+ container.get<PermissionManager>("PermissionManager");
206
+ if (permissionManager) {
207
+ const autoMemoryDir = memoryService.getAutoMemoryDirectory(workdir);
208
+ permissionManager.addSystemAdditionalDirectory(autoMemoryDir);
209
+ }
199
210
  }
200
211
  }
201
212
  } catch (error) {
@@ -15,7 +15,11 @@ export class MemoryService {
15
15
  * Uses the git common directory to ensure worktrees share the same memory.
16
16
  */
17
17
  getAutoMemoryDirectory(workdir: string): string {
18
- const projectRoot = getGitCommonDir(workdir);
18
+ const commonDir = getGitCommonDir(workdir);
19
+ // If the common directory is a .git directory, use its parent as the project root
20
+ // for a cleaner encoded name while maintaining stability across worktrees.
21
+ const projectRoot =
22
+ path.basename(commonDir) === ".git" ? path.dirname(commonDir) : commonDir;
19
23
  const encodedName = pathEncoder.encodeSync(projectRoot);
20
24
  return path.join(homedir(), ".wave", "projects", encodedName, "memory");
21
25
  }
@@ -1,8 +1,9 @@
1
- import { glob } from "glob";
1
+ import { spawn } from "child_process";
2
+ import { rgPath } from "@vscode/ripgrep";
2
3
  import { stat } from "fs/promises";
3
4
  import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
4
5
  import { resolvePath, getDisplayPath } from "../utils/path.js";
5
- import { getGlobIgnorePatterns } from "../utils/fileFilter.js";
6
+ import { getAllIgnorePatterns } from "../utils/fileFilter.js";
6
7
  import { GLOB_TOOL_NAME } from "../constants/tools.js";
7
8
 
8
9
  /**
@@ -10,6 +11,61 @@ import { GLOB_TOOL_NAME } from "../constants/tools.js";
10
11
  */
11
12
  const MAX_GLOB_RESULTS = 1000;
12
13
 
14
+ /**
15
+ * Execute ripgrep to find files matching a pattern
16
+ */
17
+ async function runRipgrep(pattern: string, workdir: string): Promise<string[]> {
18
+ if (!rgPath) {
19
+ throw new Error("ripgrep is not available");
20
+ }
21
+
22
+ const ignorePatterns = getAllIgnorePatterns();
23
+ const rgArgs = ["--files", "--color=never", "--hidden", "--glob", pattern];
24
+
25
+ for (const ignorePattern of ignorePatterns) {
26
+ rgArgs.push("--glob", `!${ignorePattern}`);
27
+ }
28
+
29
+ return new Promise<string[]>((resolve, reject) => {
30
+ const child = spawn(rgPath, rgArgs, {
31
+ cwd: workdir,
32
+ stdio: ["ignore", "pipe", "pipe"],
33
+ });
34
+
35
+ let stdout = "";
36
+ let stderr = "";
37
+
38
+ child.stdout?.on("data", (data) => {
39
+ stdout += data.toString();
40
+ });
41
+
42
+ child.stderr?.on("data", (data) => {
43
+ stderr += data.toString();
44
+ });
45
+
46
+ child.on("close", (code) => {
47
+ if (code !== 0 && code !== 1) {
48
+ reject(
49
+ new Error(
50
+ `ripgrep failed with code ${code}: ${stderr || "Unknown error"}`,
51
+ ),
52
+ );
53
+ return;
54
+ }
55
+ const files = stdout
56
+ .trim()
57
+ .split("\n")
58
+ .filter((f) => f.length > 0)
59
+ .map((f) => f.replace(/\\/g, "/")); // Normalize to forward slashes
60
+ resolve(files);
61
+ });
62
+
63
+ child.on("error", (err) => {
64
+ reject(err);
65
+ });
66
+ });
67
+ }
68
+
13
69
  /**
14
70
  * Glob Tool Plugin - Fast file pattern matching
15
71
  */
@@ -66,14 +122,8 @@ export const globTool: ToolPlugin = {
66
122
  ? resolvePath(searchPath, context.workdir)
67
123
  : context.workdir;
68
124
 
69
- // Execute glob search
70
- const matches = await glob(pattern, {
71
- cwd: workdir,
72
- ignore: getGlobIgnorePatterns(workdir),
73
- dot: false,
74
- absolute: false,
75
- nocase: false, // Keep case sensitive
76
- });
125
+ // Execute glob search using ripgrep
126
+ const matches = await runRipgrep(pattern, workdir);
77
127
 
78
128
  if (matches.length === 0) {
79
129
  return {
@@ -87,7 +137,7 @@ export const globTool: ToolPlugin = {
87
137
  const filesWithStats = await Promise.allSettled(
88
138
  matches.map(async (file) => {
89
139
  try {
90
- const fullPath = resolvePath(file, context.workdir);
140
+ const fullPath = resolvePath(file, workdir);
91
141
  const stats = await stat(fullPath);
92
142
  return {
93
143
  path: file,
@@ -1,6 +1,6 @@
1
1
  import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
2
2
  import { spawn } from "child_process";
3
- import { getGlobIgnorePatterns } from "../utils/fileFilter.js";
3
+ import { getAllIgnorePatterns } from "../utils/fileFilter.js";
4
4
  import { rgPath } from "@vscode/ripgrep";
5
5
  import { getDisplayPath } from "../utils/path.js";
6
6
  import {
@@ -189,7 +189,7 @@ export const grepTool: ToolPlugin = {
189
189
  }
190
190
 
191
191
  // Get common ignore rules
192
- const ignorePatterns = getGlobIgnorePatterns(workdir);
192
+ const ignorePatterns = getAllIgnorePatterns();
193
193
  for (const exclude of ignorePatterns) {
194
194
  rgArgs.push("--glob", `!${exclude}`);
195
195
  }
@@ -133,7 +133,7 @@ export function setupAgentContainer(
133
133
  const permissionManager = new PermissionManager(container, { workdir });
134
134
  if (configurationService.resolveAutoMemoryEnabled()) {
135
135
  const autoMemoryDir = memoryService.getAutoMemoryDirectory(workdir);
136
- permissionManager.updateAdditionalDirectories([autoMemoryDir]);
136
+ permissionManager.addSystemAdditionalDirectory(autoMemoryDir);
137
137
  }
138
138
  container.register("PermissionManager", permissionManager);
139
139
  permissionManager.setOnConfiguredDefaultModeChange((mode) => {
@@ -1,6 +1,3 @@
1
- import * as fs from "fs";
2
- import * as path from "path";
3
-
4
1
  /**
5
2
  * Common ignore directory and file patterns
6
3
  * Can be reused by multiple tools (glob, ripgrep, etc.)
@@ -40,163 +37,3 @@ export const getAllIgnorePatterns = (): string[] => {
40
37
  ...COMMON_IGNORE_PATTERNS.os,
41
38
  ];
42
39
  };
43
-
44
- /**
45
- * Recursively find all .gitignore files in directory
46
- * @param dir Directory to search
47
- * @param maxDepth Maximum recursion depth to prevent too deep searches
48
- * @returns Array of .gitignore file paths
49
- */
50
- const findAllGitignoreFiles = (dir: string, maxDepth: number = 5): string[] => {
51
- const gitignoreFiles: string[] = [];
52
-
53
- if (maxDepth <= 0) return gitignoreFiles;
54
-
55
- try {
56
- const items = fs.readdirSync(dir, { withFileTypes: true });
57
-
58
- for (const item of items) {
59
- const fullPath = path.join(dir, item.name);
60
-
61
- if (item.isFile() && item.name === ".gitignore") {
62
- gitignoreFiles.push(fullPath);
63
- } else if (item.isDirectory() && !shouldSkipDirectory(item.name)) {
64
- // Recursively search subdirectories, but skip some obviously unnecessary directories
65
- gitignoreFiles.push(...findAllGitignoreFiles(fullPath, maxDepth - 1));
66
- }
67
- }
68
- } catch {
69
- // Ignore permission errors and other issues
70
- }
71
-
72
- return gitignoreFiles;
73
- };
74
-
75
- /**
76
- * Determine whether to skip searching a directory
77
- */
78
- const shouldSkipDirectory = (dirName: string): boolean => {
79
- const skipDirs = [
80
- "node_modules",
81
- ".git",
82
- "dist",
83
- "build",
84
- ".next",
85
- "coverage",
86
- ".nyc_output",
87
- "tmp",
88
- "temp",
89
- ".cache",
90
- ];
91
- return skipDirs.includes(dirName);
92
- };
93
-
94
- /**
95
- * Parse single .gitignore file content
96
- * @param gitignorePath .gitignore file path
97
- * @param basePath Base path for calculating relative paths
98
- * @returns Array of parsed glob patterns
99
- */
100
- const parseGitignoreFile = (
101
- gitignorePath: string,
102
- basePath: string,
103
- ): string[] => {
104
- const patterns: string[] = [];
105
-
106
- try {
107
- if (fs.existsSync(gitignorePath)) {
108
- const gitignoreContent = fs.readFileSync(gitignorePath, "utf8");
109
- const gitignoreDir = path.dirname(gitignorePath);
110
- // Calculate relative directory relative to base path
111
- const relativeDirFromBase = path.relative(basePath, gitignoreDir);
112
-
113
- const lines = gitignoreContent
114
- .split("\n")
115
- .map((line) => line.trim())
116
- .filter((line) => line && !line.startsWith("#"));
117
-
118
- for (const line of lines) {
119
- // Skip negation rules (starting with !)
120
- if (line.startsWith("!")) {
121
- continue;
122
- }
123
-
124
- let pattern = line;
125
-
126
- // Handle patterns starting with / (relative to current .gitignore file directory)
127
- if (pattern.startsWith("/")) {
128
- pattern = pattern.slice(1); // Remove leading /
129
- }
130
-
131
- // If .gitignore is in subdirectory, need to add path prefix
132
- if (relativeDirFromBase && relativeDirFromBase !== ".") {
133
- pattern = path.posix.join(relativeDirFromBase, pattern);
134
- }
135
-
136
- // If directory pattern (ending with /)
137
- if (pattern.endsWith("/")) {
138
- const dirName = pattern.slice(0, -1);
139
- // For directory patterns, add both exact match and wildcard match
140
- patterns.push(`${dirName}/**`); // Directory and all its sub-content
141
- // If no path separators, it's a simple directory name, add global match
142
- if (!dirName.includes("/") && !dirName.includes("*")) {
143
- patterns.push(`**/${dirName}/**`); // Match directories of same name at any level
144
- }
145
- } else {
146
- // File pattern
147
- patterns.push(pattern);
148
- // If no wildcards and no extension, also treat as directory
149
- if (!pattern.includes("*") && !pattern.includes(".")) {
150
- patterns.push(`${pattern}/**`);
151
- // Also add global match for simple directory names
152
- if (!pattern.includes("/")) {
153
- patterns.push(`**/${pattern}/**`);
154
- }
155
- }
156
- }
157
- }
158
- }
159
- } catch {
160
- // Ignore errors when reading .gitignore files
161
- }
162
-
163
- return patterns;
164
- };
165
-
166
- /**
167
- * Parse all .gitignore files in the working directory and its subdirectories and convert to glob patterns
168
- * @param workdir Working directory
169
- * @returns Array of glob ignore patterns
170
- */
171
- export const parseGitignoreToGlob = (workdir: string): string[] => {
172
- const patterns: string[] = [];
173
-
174
- try {
175
- // Find all .gitignore files
176
- const gitignoreFiles = findAllGitignoreFiles(workdir);
177
-
178
- // Parse each .gitignore file
179
- for (const gitignoreFile of gitignoreFiles) {
180
- patterns.push(...parseGitignoreFile(gitignoreFile, workdir));
181
- }
182
- } catch {
183
- // Ignore errors during search process
184
- }
185
-
186
- return patterns;
187
- };
188
-
189
- /**
190
- * Get ignore patterns for glob search
191
- * @param workdir Working directory for resolving .gitignore files
192
- */
193
- export const getGlobIgnorePatterns = (workdir?: string): string[] => {
194
- const patterns = getAllIgnorePatterns();
195
-
196
- // If working directory is provided, parse .gitignore files
197
- if (workdir) {
198
- patterns.push(...parseGitignoreToGlob(workdir));
199
- }
200
-
201
- return patterns;
202
- };
@@ -1,7 +1,7 @@
1
1
  import { spawn } from "child_process";
2
2
  import { rgPath } from "@vscode/ripgrep";
3
3
  import fuzzysort from "fuzzysort";
4
- import { getGlobIgnorePatterns } from "./fileFilter.js";
4
+ import { getAllIgnorePatterns } from "./fileFilter.js";
5
5
  import type { FileItem } from "../types/fileSearch.js";
6
6
  import { logger } from "./globalLogger.js";
7
7
 
@@ -13,7 +13,7 @@ async function getAllFiles(workingDirectory: string): Promise<string[]> {
13
13
  throw new Error("ripgrep is not available");
14
14
  }
15
15
 
16
- const ignorePatterns = getGlobIgnorePatterns(workingDirectory);
16
+ const ignorePatterns = getAllIgnorePatterns();
17
17
  const rgArgs = ["--files", "--color=never", "--hidden"];
18
18
  for (const pattern of ignorePatterns) {
19
19
  rgArgs.push("--glob", `!${pattern}`);
@@ -220,12 +220,12 @@ export const updateToolBlockInMessage = ({
220
220
  if (toolBlockIndex !== -1) {
221
221
  const toolBlock = newMessages[i].blocks[toolBlockIndex];
222
222
  if (toolBlock.type === "tool") {
223
- toolBlock.parameters = parameters;
223
+ if (parameters !== undefined) toolBlock.parameters = parameters;
224
224
  if (result !== undefined) toolBlock.result = result;
225
225
  if (shortResult !== undefined) toolBlock.shortResult = shortResult;
226
226
  if (startLineNumber !== undefined)
227
227
  toolBlock.startLineNumber = startLineNumber;
228
- toolBlock.images = images; // Add image data update
228
+ if (images !== undefined) toolBlock.images = images; // Add image data update
229
229
  if (success !== undefined) toolBlock.success = success;
230
230
  if (error !== undefined) toolBlock.error = error;
231
231
  if (stage !== undefined) toolBlock.stage = stage;