wave-agent-sdk 0.17.4 → 0.17.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/managers/MemoryRuleManager.d.ts.map +1 -1
- package/dist/managers/MemoryRuleManager.js +30 -13
- package/dist/managers/hookManager.d.ts.map +1 -1
- package/dist/managers/hookManager.js +3 -1
- package/dist/managers/lspManager.d.ts.map +1 -1
- package/dist/managers/lspManager.js +12 -4
- package/dist/managers/mcpManager.d.ts.map +1 -1
- package/dist/managers/mcpManager.js +13 -6
- package/dist/managers/skillManager.d.ts +3 -0
- package/dist/managers/skillManager.d.ts.map +1 -1
- package/dist/managers/skillManager.js +69 -54
- package/dist/services/MarketplaceService.d.ts +15 -0
- package/dist/services/MarketplaceService.d.ts.map +1 -1
- package/dist/services/MarketplaceService.js +95 -6
- package/dist/services/memory.d.ts.map +1 -1
- package/dist/services/memory.js +39 -5
- package/dist/services/pluginLoader.d.ts.map +1 -1
- package/dist/services/pluginLoader.js +30 -7
- package/dist/types/marketplace.d.ts +1 -0
- package/dist/types/marketplace.d.ts.map +1 -1
- package/dist/types/skills.d.ts +1 -0
- package/dist/types/skills.d.ts.map +1 -1
- package/dist/utils/customCommands.d.ts.map +1 -1
- package/dist/utils/customCommands.js +11 -9
- package/dist/utils/skillParser.d.ts.map +1 -1
- package/dist/utils/skillParser.js +3 -1
- package/dist/utils/subagentParser.d.ts.map +1 -1
- package/dist/utils/subagentParser.js +18 -7
- package/package.json +1 -1
- package/src/managers/MemoryRuleManager.ts +29 -14
- package/src/managers/hookManager.ts +6 -1
- package/src/managers/lspManager.ts +23 -5
- package/src/managers/mcpManager.ts +24 -7
- package/src/managers/skillManager.ts +90 -57
- package/src/services/MarketplaceService.ts +152 -6
- package/src/services/memory.ts +43 -6
- package/src/services/pluginLoader.ts +35 -7
- package/src/types/marketplace.ts +1 -0
- package/src/types/skills.ts +1 -0
- package/src/utils/customCommands.ts +17 -12
- package/src/utils/skillParser.ts +3 -1
- package/src/utils/subagentParser.ts +22 -8
package/dist/services/memory.js
CHANGED
|
@@ -117,6 +117,22 @@ export class MemoryService {
|
|
|
117
117
|
userMemoryFile: USER_MEMORY_FILE,
|
|
118
118
|
contentLength: content.length,
|
|
119
119
|
});
|
|
120
|
+
// If the file is still the default empty template, fallback to ~/.claude/AGENTS.md
|
|
121
|
+
const defaultTemplate = "# User Memory\n\nThis is the user-level memory file, recording important information and context across projects.\n\n";
|
|
122
|
+
if (content === defaultTemplate) {
|
|
123
|
+
const claudeMemoryPath = path.join(homedir(), ".claude", "AGENTS.md");
|
|
124
|
+
try {
|
|
125
|
+
const claudeContent = await fs.readFile(claudeMemoryPath, "utf-8");
|
|
126
|
+
logger.debug("User memory content read from ~/.claude/AGENTS.md fallback", {
|
|
127
|
+
claudeMemoryPath,
|
|
128
|
+
contentLength: claudeContent.length,
|
|
129
|
+
});
|
|
130
|
+
return claudeContent;
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
// CLAUDE.md doesn't exist or can't be read, return the default template
|
|
134
|
+
}
|
|
135
|
+
}
|
|
120
136
|
return content;
|
|
121
137
|
}
|
|
122
138
|
catch (error) {
|
|
@@ -126,7 +142,6 @@ export class MemoryService {
|
|
|
126
142
|
}
|
|
127
143
|
async readMemoryFile(workdir) {
|
|
128
144
|
const memoryFilePath = path.join(workdir, "AGENTS.md");
|
|
129
|
-
// Direct file access
|
|
130
145
|
try {
|
|
131
146
|
const content = await fs.readFile(memoryFilePath, "utf-8");
|
|
132
147
|
logger.debug("Memory file read successfully via direct file access", {
|
|
@@ -137,10 +152,29 @@ export class MemoryService {
|
|
|
137
152
|
}
|
|
138
153
|
catch (error) {
|
|
139
154
|
if (error.code === "ENOENT") {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
155
|
+
// Fallback to CLAUDE.md
|
|
156
|
+
const claudeMemoryPath = path.join(workdir, "CLAUDE.md");
|
|
157
|
+
try {
|
|
158
|
+
const content = await fs.readFile(claudeMemoryPath, "utf-8");
|
|
159
|
+
logger.debug("Memory file read from CLAUDE.md fallback", {
|
|
160
|
+
memoryFilePath: claudeMemoryPath,
|
|
161
|
+
contentLength: content.length,
|
|
162
|
+
});
|
|
163
|
+
return content;
|
|
164
|
+
}
|
|
165
|
+
catch (claudeError) {
|
|
166
|
+
if (claudeError.code === "ENOENT") {
|
|
167
|
+
logger.debug("Neither AGENTS.md nor CLAUDE.md found", {
|
|
168
|
+
memoryFilePath,
|
|
169
|
+
});
|
|
170
|
+
return "";
|
|
171
|
+
}
|
|
172
|
+
logger.error("Failed to read CLAUDE.md fallback", {
|
|
173
|
+
memoryFilePath: claudeMemoryPath,
|
|
174
|
+
error: claudeError,
|
|
175
|
+
});
|
|
176
|
+
return "";
|
|
177
|
+
}
|
|
144
178
|
}
|
|
145
179
|
logger.error("Failed to read memory file", { memoryFilePath, error });
|
|
146
180
|
return "";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pluginLoader.d.ts","sourceRoot":"","sources":["../../src/services/pluginLoader.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,KAAK,EACL,SAAS,EACT,SAAS,EACT,wBAAwB,EACzB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,4BAA4B,CAAC;AAGpC,qBAAa,YAAY;IACvB;;;OAGG;WACU,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"pluginLoader.d.ts","sourceRoot":"","sources":["../../src/services/pluginLoader.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,KAAK,EACL,SAAS,EACT,SAAS,EACT,wBAAwB,EACzB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,4BAA4B,CAAC;AAGpC,qBAAa,YAAY;IACvB;;;OAGG;WACU,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAyEtE;;;OAGG;IACH,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAK7D;;;OAGG;WACU,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAuC7D;;OAEG;WACU,aAAa,CACxB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAUjC;;OAEG;WACU,aAAa,CACxB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAWjC;;OAEG;WACU,eAAe,CAC1B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC;IAgBhD;;OAEG;WACU,UAAU,CACrB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,qBAAqB,EAAE,CAAC;IA2BnC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;CAgBhC"}
|
|
@@ -11,10 +11,12 @@ export class PluginLoader {
|
|
|
11
11
|
*/
|
|
12
12
|
static async loadManifest(pluginPath) {
|
|
13
13
|
const dotWavePluginPath = path.join(pluginPath, ".wave-plugin");
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
// Check if .wave-plugin/ directory exists
|
|
15
|
+
let wavePluginDirExists = false;
|
|
16
16
|
try {
|
|
17
17
|
const entries = await fs.readdir(dotWavePluginPath);
|
|
18
|
+
wavePluginDirExists = true;
|
|
19
|
+
// T018: Ensure plugin.json is the only file in .wave-plugin/
|
|
18
20
|
const misplaced = entries.filter((e) => e !== "plugin.json");
|
|
19
21
|
if (misplaced.length > 0) {
|
|
20
22
|
throw new Error(`Misplaced files/directories in .wave-plugin/: ${misplaced.join(", ")}. Only plugin.json should be in this directory.`);
|
|
@@ -23,12 +25,33 @@ export class PluginLoader {
|
|
|
23
25
|
catch (error) {
|
|
24
26
|
if (error instanceof Error &&
|
|
25
27
|
error.code === "ENOENT") {
|
|
26
|
-
|
|
28
|
+
// .wave-plugin/ doesn't exist, will try .claude-plugin/ fallback below
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (wavePluginDirExists) {
|
|
35
|
+
const manifestPath = path.join(dotWavePluginPath, "plugin.json");
|
|
36
|
+
try {
|
|
37
|
+
const content = await fs.readFile(manifestPath, "utf-8");
|
|
38
|
+
const manifest = JSON.parse(content);
|
|
39
|
+
this.validateManifest(manifest);
|
|
40
|
+
return manifest;
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error instanceof Error &&
|
|
44
|
+
error.code === "ENOENT") {
|
|
45
|
+
throw new Error(`Plugin manifest not found at ${manifestPath}`);
|
|
46
|
+
}
|
|
47
|
+
throw new Error(`Failed to load plugin manifest at ${manifestPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
27
48
|
}
|
|
28
|
-
throw error;
|
|
29
49
|
}
|
|
50
|
+
// Fallback to .claude-plugin/
|
|
51
|
+
const dotClaudePluginPath = path.join(pluginPath, ".claude-plugin");
|
|
52
|
+
const claudeManifestPath = path.join(dotClaudePluginPath, "plugin.json");
|
|
30
53
|
try {
|
|
31
|
-
const content = await fs.readFile(
|
|
54
|
+
const content = await fs.readFile(claudeManifestPath, "utf-8");
|
|
32
55
|
const manifest = JSON.parse(content);
|
|
33
56
|
this.validateManifest(manifest);
|
|
34
57
|
return manifest;
|
|
@@ -36,9 +59,9 @@ export class PluginLoader {
|
|
|
36
59
|
catch (error) {
|
|
37
60
|
if (error instanceof Error &&
|
|
38
61
|
error.code === "ENOENT") {
|
|
39
|
-
throw new Error(`Plugin manifest not found at ${
|
|
62
|
+
throw new Error(`Plugin manifest not found at ${dotWavePluginPath} or ${dotClaudePluginPath}`);
|
|
40
63
|
}
|
|
41
|
-
throw new Error(`Failed to load plugin manifest at ${
|
|
64
|
+
throw new Error(`Failed to load plugin manifest at ${claudeManifestPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
42
65
|
}
|
|
43
66
|
}
|
|
44
67
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"marketplace.d.ts","sourceRoot":"","sources":["../../src/types/marketplace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,uBAAwB,SAAQ,sBAAsB;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,sBAAsB,EAAE,CAAC;CACnC;AAED,MAAM,MAAM,iBAAiB,GACzB;IACE,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,MAAM,EAAE,QAAQ,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GACD;IACE,MAAM,EAAE,KAAK,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEN,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;CAC1D;AAED,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,gBAAgB,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B"}
|
|
1
|
+
{"version":3,"file":"marketplace.d.ts","sourceRoot":"","sources":["../../src/types/marketplace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,uBAAwB,SAAQ,sBAAsB;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,sBAAsB,EAAE,CAAC;CACnC;AAED,MAAM,MAAM,iBAAiB,GACzB;IACE,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,MAAM,EAAE,QAAQ,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GACD;IACE,MAAM,EAAE,KAAK,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEN,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;CAC1D;AAED,MAAM,WAAW,yBAAyB;IACxC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,gBAAgB,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B"}
|
package/dist/types/skills.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/types/skills.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/types/skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"customCommands.d.ts","sourceRoot":"","sources":["../../src/utils/customCommands.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAK5D;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAwC3E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"customCommands.d.ts","sourceRoot":"","sources":["../../src/utils/customCommands.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAK5D;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAwC3E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAuB7E"}
|
|
@@ -60,16 +60,18 @@ export function scanCommandsDirectory(dirPath) {
|
|
|
60
60
|
* Load all custom slash commands from both project and user directories
|
|
61
61
|
*/
|
|
62
62
|
export function loadCustomSlashCommands(workdir) {
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
|
|
63
|
+
const userClaudeCommands = scanCommandsDirectory(join(homedir(), ".claude", "commands"));
|
|
64
|
+
const userWaveCommands = scanCommandsDirectory(getUserCommandsDir());
|
|
65
|
+
const projectClaudeCommands = scanCommandsDirectory(join(workdir, ".claude", "commands"));
|
|
66
|
+
const projectWaveCommands = scanCommandsDirectory(getProjectCommandsDir(workdir));
|
|
66
67
|
const commandMap = new Map();
|
|
67
|
-
//
|
|
68
|
-
for (const command of
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
// Write in priority order: lowest first, highest last (overwrites)
|
|
69
|
+
for (const command of [
|
|
70
|
+
...userClaudeCommands,
|
|
71
|
+
...userWaveCommands,
|
|
72
|
+
...projectClaudeCommands,
|
|
73
|
+
...projectWaveCommands,
|
|
74
|
+
]) {
|
|
73
75
|
commandMap.set(command.id, command);
|
|
74
76
|
}
|
|
75
77
|
return Array.from(commandMap.values());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skillParser.d.ts","sourceRoot":"","sources":["../../src/utils/skillParser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EAEjB,aAAa,EACd,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,iBAAsB,GAC9B,eAAe,
|
|
1
|
+
{"version":3,"file":"skillParser.d.ts","sourceRoot":"","sources":["../../src/utils/skillParser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EAEjB,aAAa,EACd,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,iBAAsB,GAC9B,eAAe,CAkGjB;AAyDD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,EAAE,CAwCvE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOtD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAa5E"}
|
|
@@ -36,7 +36,9 @@ export function parseSkillFile(filePath, options = {}) {
|
|
|
36
36
|
// Determine skill type and path
|
|
37
37
|
const skillPath = basePath || dirname(filePath);
|
|
38
38
|
const skillType = skillPath.includes("/.wave/skills") ||
|
|
39
|
-
skillPath.includes("\\.wave\\skills")
|
|
39
|
+
skillPath.includes("\\.wave\\skills") ||
|
|
40
|
+
skillPath.includes("/.claude/skills") ||
|
|
41
|
+
skillPath.includes("\\.claude\\skills")
|
|
40
42
|
? "project"
|
|
41
43
|
: "personal";
|
|
42
44
|
// Extract allowed tools
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagentParser.d.ts","sourceRoot":"","sources":["../../src/utils/subagentParser.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAmKD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,QAAQ,EACf,UAAU,EAAE,MAAM,GACjB,qBAAqB,CAEvB;AAqCD;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,qBAAqB,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"subagentParser.d.ts","sourceRoot":"","sources":["../../src/utils/subagentParser.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAmKD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,QAAQ,EACf,UAAU,EAAE,MAAM,GACjB,qBAAqB,CAEvB;AAqCD;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAoClC;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAGvC"}
|
|
@@ -160,17 +160,28 @@ function scanSubagentDirectory(dirPath, scope) {
|
|
|
160
160
|
* Load all subagent configurations from project and user directories, plus built-in subagents
|
|
161
161
|
*/
|
|
162
162
|
export async function loadSubagentConfigurations(workdir) {
|
|
163
|
-
const
|
|
164
|
-
const
|
|
163
|
+
const projectWaveDir = join(workdir, ".wave", "agents");
|
|
164
|
+
const projectClaudeDir = join(workdir, ".claude", "agents");
|
|
165
|
+
const userWaveDir = join(process.env.HOME || "~", ".wave", "agents");
|
|
166
|
+
const userClaudeDir = join(process.env.HOME || "~", ".claude", "agents");
|
|
165
167
|
const builtinDir = getBuiltinSubagentsDir();
|
|
166
168
|
// Load configurations from all sources
|
|
167
169
|
const builtinConfigs = scanSubagentDirectory(builtinDir, "builtin");
|
|
168
|
-
const
|
|
169
|
-
const
|
|
170
|
-
|
|
170
|
+
const userClaudeConfigs = scanSubagentDirectory(userClaudeDir, "user");
|
|
171
|
+
const userWaveConfigs = scanSubagentDirectory(userWaveDir, "user");
|
|
172
|
+
const projectClaudeConfigs = scanSubagentDirectory(projectClaudeDir, "project");
|
|
173
|
+
const projectWaveConfigs = scanSubagentDirectory(projectWaveDir, "project");
|
|
174
|
+
// Merge configurations, with .wave taking priority over .claude
|
|
171
175
|
const configMap = new Map();
|
|
172
|
-
//
|
|
173
|
-
|
|
176
|
+
// Merge order: builtin → userClaude → userWave → projectClaude → projectWave
|
|
177
|
+
// Later writes override earlier ones, so .wave takes priority over .claude
|
|
178
|
+
for (const config of [
|
|
179
|
+
...builtinConfigs,
|
|
180
|
+
...userClaudeConfigs,
|
|
181
|
+
...userWaveConfigs,
|
|
182
|
+
...projectClaudeConfigs,
|
|
183
|
+
...projectWaveConfigs,
|
|
184
|
+
]) {
|
|
174
185
|
configMap.set(config.name, config);
|
|
175
186
|
}
|
|
176
187
|
return Array.from(configMap.values()).sort((a, b) => {
|
package/package.json
CHANGED
|
@@ -39,23 +39,26 @@ export class MemoryRuleManager {
|
|
|
39
39
|
* Scans .wave/rules and ~/.wave/rules for memory rule files.
|
|
40
40
|
*/
|
|
41
41
|
async discoverRules(): Promise<void> {
|
|
42
|
-
const
|
|
43
|
-
const
|
|
42
|
+
const projectWaveRulesDir = path.join(this.workdir, ".wave", "rules");
|
|
43
|
+
const projectClaudeRulesDir = path.join(this.workdir, ".claude", "rules");
|
|
44
|
+
const userWaveRulesDir = path.join(os.homedir(), ".wave", "rules");
|
|
45
|
+
const userClaudeRulesDir = path.join(os.homedir(), ".claude", "rules");
|
|
44
46
|
|
|
45
47
|
logger.debug(`Scanning for modular memory rules...`);
|
|
46
|
-
logger.debug(` User rules directory: ${
|
|
47
|
-
logger.debug(` Project rules directory: ${
|
|
48
|
+
logger.debug(` User rules directory: ${userWaveRulesDir}`);
|
|
49
|
+
logger.debug(` Project rules directory: ${projectWaveRulesDir}`);
|
|
48
50
|
|
|
49
51
|
const newRules: Record<string, MemoryRule> = {};
|
|
50
52
|
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
await this.scanDirectory(
|
|
54
|
-
await this.scanDirectory(
|
|
53
|
+
// Scan order: userClaude → userWave → projectClaude → projectWave
|
|
54
|
+
// Later writes override, so .wave takes priority over .claude
|
|
55
|
+
await this.scanDirectory(userClaudeRulesDir, "user", newRules);
|
|
56
|
+
await this.scanDirectory(userWaveRulesDir, "user", newRules);
|
|
57
|
+
await this.scanDirectory(projectClaudeRulesDir, "project", newRules);
|
|
58
|
+
await this.scanDirectory(projectWaveRulesDir, "project", newRules);
|
|
55
59
|
|
|
56
60
|
this.state.rules = newRules;
|
|
57
61
|
const ruleCount = Object.keys(newRules).length;
|
|
58
|
-
// Removed verbose logging of all discovered rules
|
|
59
62
|
logger.debug(`Discovered ${ruleCount} modular memory rules`);
|
|
60
63
|
}
|
|
61
64
|
|
|
@@ -124,11 +127,23 @@ export class MemoryRuleManager {
|
|
|
124
127
|
try {
|
|
125
128
|
const content = await fs.readFile(filePath, "utf-8");
|
|
126
129
|
const rule = this.service.parseRule(content, filePath, source);
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
|
|
131
|
+
// Determine rulesRoot dynamically based on actual file path
|
|
132
|
+
let rulesRoot: string;
|
|
133
|
+
if (source === "project") {
|
|
134
|
+
if (filePath.includes(path.join(".claude", "rules"))) {
|
|
135
|
+
rulesRoot = path.join(this.workdir, ".claude", "rules");
|
|
136
|
+
} else {
|
|
137
|
+
rulesRoot = path.join(this.workdir, ".wave", "rules");
|
|
138
|
+
}
|
|
139
|
+
} else {
|
|
140
|
+
if (filePath.includes(path.join(".claude", "rules"))) {
|
|
141
|
+
rulesRoot = path.join(os.homedir(), ".claude", "rules");
|
|
142
|
+
} else {
|
|
143
|
+
rulesRoot = path.join(os.homedir(), ".wave", "rules");
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
132
147
|
const relativeId = path.relative(rulesRoot, filePath);
|
|
133
148
|
rule.id = relativeId;
|
|
134
149
|
registry[rule.id] = rule;
|
|
@@ -183,16 +183,21 @@ export class HookManager {
|
|
|
183
183
|
env: {
|
|
184
184
|
...("env" in context ? (context.env ?? {}) : {}),
|
|
185
185
|
WAVE_PLUGIN_ROOT: hookCommand.pluginRoot,
|
|
186
|
+
CLAUDE_PLUGIN_ROOT: hookCommand.pluginRoot,
|
|
186
187
|
},
|
|
187
188
|
}
|
|
188
189
|
: context;
|
|
189
190
|
|
|
190
|
-
// Substitute ${WAVE_PLUGIN_ROOT} in the command string
|
|
191
|
+
// Substitute ${WAVE_PLUGIN_ROOT} and ${CLAUDE_PLUGIN_ROOT} in the command string
|
|
191
192
|
if (hookCommand.pluginRoot) {
|
|
192
193
|
command = command.replace(
|
|
193
194
|
/\$\{WAVE_PLUGIN_ROOT\}/g,
|
|
194
195
|
hookCommand.pluginRoot,
|
|
195
196
|
);
|
|
197
|
+
command = command.replace(
|
|
198
|
+
/\$\{CLAUDE_PLUGIN_ROOT\}/g,
|
|
199
|
+
hookCommand.pluginRoot,
|
|
200
|
+
);
|
|
196
201
|
}
|
|
197
202
|
|
|
198
203
|
if (hookCommand.async) {
|
|
@@ -92,22 +92,40 @@ export class LspManager implements ILspManager {
|
|
|
92
92
|
try {
|
|
93
93
|
const env = { ...process.env, ...config.env };
|
|
94
94
|
|
|
95
|
-
// For plugin servers, substitute ${WAVE_PLUGIN_ROOT}
|
|
95
|
+
// For plugin servers, substitute ${WAVE_PLUGIN_ROOT} and ${CLAUDE_PLUGIN_ROOT}
|
|
96
96
|
let command = config.command;
|
|
97
97
|
let args = config.args || [];
|
|
98
98
|
if (config.pluginRoot) {
|
|
99
99
|
env.WAVE_PLUGIN_ROOT = config.pluginRoot;
|
|
100
|
+
env.CLAUDE_PLUGIN_ROOT = config.pluginRoot;
|
|
100
101
|
command = command.replace(/\$\{WAVE_PLUGIN_ROOT\}/g, config.pluginRoot);
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
command = command.replace(
|
|
103
|
+
/\$\{CLAUDE_PLUGIN_ROOT\}/g,
|
|
104
|
+
config.pluginRoot,
|
|
103
105
|
);
|
|
104
|
-
|
|
106
|
+
args = args.map((arg) => {
|
|
107
|
+
let result = arg.replace(
|
|
108
|
+
/\$\{WAVE_PLUGIN_ROOT\}/g,
|
|
109
|
+
config.pluginRoot!,
|
|
110
|
+
);
|
|
111
|
+
result = result.replace(
|
|
112
|
+
/\$\{CLAUDE_PLUGIN_ROOT\}/g,
|
|
113
|
+
config.pluginRoot!,
|
|
114
|
+
);
|
|
115
|
+
return result;
|
|
116
|
+
});
|
|
117
|
+
// Also expand plugin root in user-provided env values
|
|
105
118
|
if (config.env) {
|
|
106
119
|
for (const [key, value] of Object.entries(config.env)) {
|
|
107
|
-
|
|
120
|
+
let expanded = value.replace(
|
|
108
121
|
/\$\{WAVE_PLUGIN_ROOT\}/g,
|
|
109
122
|
config.pluginRoot!,
|
|
110
123
|
);
|
|
124
|
+
expanded = expanded.replace(
|
|
125
|
+
/\$\{CLAUDE_PLUGIN_ROOT\}/g,
|
|
126
|
+
config.pluginRoot!,
|
|
127
|
+
);
|
|
128
|
+
env[key] = expanded;
|
|
111
129
|
}
|
|
112
130
|
}
|
|
113
131
|
}
|
|
@@ -40,7 +40,7 @@ export interface McpManagerOptions {
|
|
|
40
40
|
* Expand environment variables in a string value.
|
|
41
41
|
* Supports ${VAR} and ${VAR:-default} patterns.
|
|
42
42
|
*/
|
|
43
|
-
const WAVE_TEMPLATE_VARS = ["WAVE_PLUGIN_ROOT"];
|
|
43
|
+
const WAVE_TEMPLATE_VARS = ["WAVE_PLUGIN_ROOT", "CLAUDE_PLUGIN_ROOT"];
|
|
44
44
|
|
|
45
45
|
export function expandEnvVars(value: string): string {
|
|
46
46
|
return value.replace(/\$\{([^}]+)\}/g, (_match, expr: string) => {
|
|
@@ -440,25 +440,42 @@ export class McpManager {
|
|
|
440
440
|
...(server.config.env || {}),
|
|
441
441
|
};
|
|
442
442
|
|
|
443
|
-
// For plugin servers, substitute ${WAVE_PLUGIN_ROOT}
|
|
444
|
-
// (same pattern as Claude Code's substitutePluginVariables)
|
|
443
|
+
// For plugin servers, substitute ${WAVE_PLUGIN_ROOT} and ${CLAUDE_PLUGIN_ROOT}
|
|
445
444
|
let command = server.config.command;
|
|
446
445
|
let args = server.config.args || [];
|
|
447
446
|
if (server.config.pluginRoot) {
|
|
448
447
|
env.WAVE_PLUGIN_ROOT = server.config.pluginRoot;
|
|
448
|
+
env.CLAUDE_PLUGIN_ROOT = server.config.pluginRoot;
|
|
449
449
|
command = command.replace(
|
|
450
450
|
/\$\{WAVE_PLUGIN_ROOT\}/g,
|
|
451
451
|
server.config.pluginRoot,
|
|
452
452
|
);
|
|
453
|
-
|
|
454
|
-
|
|
453
|
+
command = command.replace(
|
|
454
|
+
/\$\{CLAUDE_PLUGIN_ROOT\}/g,
|
|
455
|
+
server.config.pluginRoot,
|
|
455
456
|
);
|
|
456
|
-
|
|
457
|
+
args = args.map((arg) => {
|
|
458
|
+
let result = arg.replace(
|
|
459
|
+
/\$\{WAVE_PLUGIN_ROOT\}/g,
|
|
460
|
+
server.config.pluginRoot!,
|
|
461
|
+
);
|
|
462
|
+
result = result.replace(
|
|
463
|
+
/\$\{CLAUDE_PLUGIN_ROOT\}/g,
|
|
464
|
+
server.config.pluginRoot!,
|
|
465
|
+
);
|
|
466
|
+
return result;
|
|
467
|
+
});
|
|
468
|
+
// Also expand plugin root in user-provided env values
|
|
457
469
|
for (const [key, value] of Object.entries(server.config.env || {})) {
|
|
458
|
-
|
|
470
|
+
let expanded = value.replace(
|
|
459
471
|
/\$\{WAVE_PLUGIN_ROOT\}/g,
|
|
460
472
|
server.config.pluginRoot!,
|
|
461
473
|
);
|
|
474
|
+
expanded = expanded.replace(
|
|
475
|
+
/\$\{CLAUDE_PLUGIN_ROOT\}/g,
|
|
476
|
+
server.config.pluginRoot!,
|
|
477
|
+
);
|
|
478
|
+
env[key] = expanded;
|
|
462
479
|
}
|
|
463
480
|
}
|
|
464
481
|
transport = new StdioClientTransport({
|