wave-agent-sdk 0.18.4 → 0.18.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/builtin/skills/settings/ENV.md +1 -1
- package/builtin/skills/settings/MEMORY.md +76 -0
- package/builtin/skills/settings/SKILL.md +4 -4
- package/dist/managers/aiManager.js +80 -82
- package/dist/managers/mcpManager.d.ts.map +1 -1
- package/dist/managers/mcpManager.js +22 -15
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +17 -10
- package/dist/tools/editTool.d.ts.map +1 -1
- package/dist/tools/editTool.js +5 -4
- package/dist/utils/constants.d.ts +1 -1
- package/dist/utils/constants.js +1 -1
- package/dist/utils/gitUtils.js +6 -6
- package/dist/utils/openaiClient.d.ts.map +1 -1
- package/dist/utils/openaiClient.js +7 -25
- package/dist/utils/path.d.ts +7 -0
- package/dist/utils/path.d.ts.map +1 -1
- package/dist/utils/path.js +9 -0
- package/dist/utils/worktreeUtils.d.ts.map +1 -1
- package/dist/utils/worktreeUtils.js +19 -13
- package/package.json +1 -1
- package/scripts/install_ripgrep.js +1 -21
- package/src/managers/aiManager.ts +97 -97
- package/src/managers/mcpManager.ts +26 -15
- package/src/tools/bashTool.ts +18 -9
- package/src/tools/editTool.ts +5 -7
- package/src/utils/constants.ts +1 -1
- package/src/utils/gitUtils.ts +6 -6
- package/src/utils/openaiClient.ts +7 -24
- package/src/utils/path.ts +10 -0
- package/src/utils/worktreeUtils.ts +46 -28
- package/vendor/ripgrep/linux-aarch64/rg +0 -0
- package/vendor/ripgrep/macos-aarch64/rg +0 -0
- package/vendor/ripgrep/macos-x86_64/rg +0 -0
- package/vendor/ripgrep/windows-aarch64/rg.exe +0 -0
- package/vendor/ripgrep/windows-x86_64/rg.exe +0 -0
- package/builtin/skills/settings/MEMORY_RULES.md +0 -60
|
@@ -28,7 +28,7 @@ Wave uses several environment variables to control its core functionality.
|
|
|
28
28
|
| `WAVE_MODEL` | The primary AI model to use for the agent. | `gemini-3-flash` |
|
|
29
29
|
| `WAVE_FAST_MODEL` | The fast AI model to use for quick tasks. | `gemini-2.5-flash` |
|
|
30
30
|
| `WAVE_MAX_INPUT_TOKENS` | Maximum number of input tokens allowed. | `200000` |
|
|
31
|
-
| `WAVE_MAX_OUTPUT_TOKENS` | Maximum number of output tokens allowed. | `
|
|
31
|
+
| `WAVE_MAX_OUTPUT_TOKENS` | Maximum number of output tokens allowed. | `32000` |
|
|
32
32
|
| `WAVE_DISABLE_AUTO_MEMORY` | Set to `1` or `true` to disable the auto-memory feature. | `false` |
|
|
33
33
|
| `WAVE_AUTO_MEMORY_FREQUENCY` | Auto memory update frequency. `1` = every turn, `2` = every 2 turns, etc. | `1` |
|
|
34
34
|
| `WAVE_TASK_LIST_ID` | Explicitly set the task list ID for the session. | (Session ID) |
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Wave Memory
|
|
2
|
+
|
|
3
|
+
Wave provides multiple memory layers to give the agent context-specific instructions and knowledge. Memory files are standard Markdown files loaded automatically at startup.
|
|
4
|
+
|
|
5
|
+
## Memory Layers
|
|
6
|
+
|
|
7
|
+
Wave looks for memory in the following locations, loaded in order of increasing priority:
|
|
8
|
+
|
|
9
|
+
1. **User Memory**: `~/.wave/AGENTS.md` — Global instructions across all projects
|
|
10
|
+
2. **Project Memory**: `AGENTS.md` in the project root — Project-specific instructions
|
|
11
|
+
3. **Memory Rules**: `.wave/rules/*.md` and `~/.wave/rules/*.md` — Modular, path-scoped rules (see below)
|
|
12
|
+
|
|
13
|
+
> `CLAUDE.md` is also supported as a fallback for both user and project memory, for compatibility with existing repositories.
|
|
14
|
+
|
|
15
|
+
## User Memory
|
|
16
|
+
|
|
17
|
+
Stored at `~/.wave/AGENTS.md`. Use it for cross-project preferences and global instructions, e.g. "always write tests for new features", "prefer functional style".
|
|
18
|
+
|
|
19
|
+
## Project Memory
|
|
20
|
+
|
|
21
|
+
### Project Memory File
|
|
22
|
+
|
|
23
|
+
The `AGENTS.md` file in the project root is the primary project-level memory. It is checked into the repository and shared with all contributors. Use it for:
|
|
24
|
+
|
|
25
|
+
- Build and test commands (e.g. "use pnpm not npm")
|
|
26
|
+
- Project structure and architecture conventions
|
|
27
|
+
- Coding standards and patterns
|
|
28
|
+
|
|
29
|
+
### Memory Rules
|
|
30
|
+
|
|
31
|
+
Memory rules are modular Markdown files that provide path-scoped instructions. They are discovered in:
|
|
32
|
+
|
|
33
|
+
- **Project scope**: `.wave/rules/*.md` (checked into the repo)
|
|
34
|
+
- **User scope**: `~/.wave/rules/*.md` (personal, not shared)
|
|
35
|
+
|
|
36
|
+
Each file can optionally include YAML frontmatter to scope rules to specific file paths:
|
|
37
|
+
|
|
38
|
+
```markdown
|
|
39
|
+
---
|
|
40
|
+
paths:
|
|
41
|
+
- "src/api/**/*.ts"
|
|
42
|
+
- "src/services/**/*.ts"
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
# API and Service Guidelines
|
|
46
|
+
|
|
47
|
+
- Always use `async/await` for asynchronous operations.
|
|
48
|
+
- Use `Zod` for input validation.
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### YAML Frontmatter Fields
|
|
52
|
+
|
|
53
|
+
- `paths`: (Optional) A list of glob patterns. The rules in this file will only be active when the agent is working with files that match these patterns. If omitted, the rules are always active.
|
|
54
|
+
- `priority`: (Optional) A number controlling rule precedence. Higher priority rules override lower ones on conflict.
|
|
55
|
+
|
|
56
|
+
#### How Memory Rules are Loaded
|
|
57
|
+
|
|
58
|
+
- Wave recursively discovers all `.md` files in `.wave/rules/` and `~/.wave/rules/`.
|
|
59
|
+
- **Path-specific activation**: If a rule has a `paths` field, it is only included in the agent's context when a file being read or modified matches the glob patterns.
|
|
60
|
+
- **Unconditional rules**: Rules without a `paths` field are always active.
|
|
61
|
+
- **Priority**: Project-level rules take priority over user-level rules if there is a conflict.
|
|
62
|
+
|
|
63
|
+
#### Best Practices
|
|
64
|
+
|
|
65
|
+
- **Keep rules focused**: Create separate files for different topics (e.g. `testing.md`, `ui-components.md`).
|
|
66
|
+
- **Leverage path scoping**: Use the `paths` field to keep the agent's context window clean and relevant.
|
|
67
|
+
- **Share with your team**: Commit `.wave/rules/` to your git repository.
|
|
68
|
+
|
|
69
|
+
## Auto-Memory
|
|
70
|
+
|
|
71
|
+
In addition to manual memory files, Wave has an **auto-memory** feature that automatically extracts and remembers important information across sessions. This is stored in `~/.wave/projects/<project-id>/memory/MEMORY.md`.
|
|
72
|
+
|
|
73
|
+
You can control auto-memory in `settings.json`:
|
|
74
|
+
|
|
75
|
+
- `autoMemoryEnabled`: Enable or disable auto-memory (default: `true`).
|
|
76
|
+
- `autoMemoryFrequency`: Frequency of auto-memory extraction turns (default: `1`).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: settings
|
|
3
|
-
description: Manage Wave settings and get guidance on settings.json, hooks, environment variables, permissions, MCP servers, memory
|
|
3
|
+
description: Manage Wave settings and get guidance on settings.json, hooks, environment variables, permissions, MCP servers, memory, skills, subagents, plugins, and plugin marketplaces. Use this when the user wants to view, update, or learn how to configure Wave.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Wave Settings Skill
|
|
@@ -79,9 +79,9 @@ For detailed model configuration, see [MODELS.md](${WAVE_SKILL_DIR}/MODELS.md).
|
|
|
79
79
|
Connect to external servers to provide additional tools and context.
|
|
80
80
|
For detailed MCP configuration, see [MCP.md](${WAVE_SKILL_DIR}/MCP.md).
|
|
81
81
|
|
|
82
|
-
### 6. Memory
|
|
83
|
-
Provide context-specific instructions and
|
|
84
|
-
For detailed memory
|
|
82
|
+
### 6. Memory
|
|
83
|
+
Provide context-specific instructions and knowledge to the agent through user memory, project memory, memory rules, and auto-memory.
|
|
84
|
+
For detailed memory configuration, see [MEMORY.md](${WAVE_SKILL_DIR}/MEMORY.md).
|
|
85
85
|
|
|
86
86
|
### 7. Skills
|
|
87
87
|
Extend Wave's functionality by creating custom skills.
|
|
@@ -894,7 +894,86 @@ export class AIManager {
|
|
|
894
894
|
await this.messageManager.saveSession();
|
|
895
895
|
// Set loading to false first
|
|
896
896
|
this.setIsLoading(false);
|
|
897
|
-
//
|
|
897
|
+
// Clear temporary rules
|
|
898
|
+
this.permissionManager?.clearTemporaryRules();
|
|
899
|
+
// Clear abort controllers
|
|
900
|
+
this.abortController = null;
|
|
901
|
+
this.toolAbortController = null;
|
|
902
|
+
// Execute Stop/SubagentStop hooks only if the operation was not aborted
|
|
903
|
+
const isCurrentlyAborted = abortController.signal.aborted || toolAbortController.signal.aborted;
|
|
904
|
+
if (!isCurrentlyAborted) {
|
|
905
|
+
// Record committed snapshots to message history for the final turn
|
|
906
|
+
if (this.reversionManager) {
|
|
907
|
+
const snapshots = this.reversionManager.getAndClearCommittedSnapshots();
|
|
908
|
+
if (snapshots.length > 0) {
|
|
909
|
+
this.messageManager.addFileHistoryBlock(snapshots);
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
// Goal evaluation — supersedes Stop hooks when active
|
|
913
|
+
const goalManager = this.container.has("GoalManager")
|
|
914
|
+
? this.container.get("GoalManager")
|
|
915
|
+
: undefined;
|
|
916
|
+
let goalContinuing = false;
|
|
917
|
+
if (goalManager?.isGoalActive() && !this.subagentType) {
|
|
918
|
+
// 1. Increment turn count and check circuit breakers
|
|
919
|
+
goalManager.incrementTurnCount();
|
|
920
|
+
const circuitBreaker = goalManager.checkCircuitBreakers();
|
|
921
|
+
if (circuitBreaker) {
|
|
922
|
+
goalManager.clearGoal();
|
|
923
|
+
logger?.info(`[Goal] ${circuitBreaker}`);
|
|
924
|
+
this.messageManager.addUserMessage({
|
|
925
|
+
content: `<system-reminder>${circuitBreaker}</system-reminder>`,
|
|
926
|
+
isMeta: true,
|
|
927
|
+
});
|
|
928
|
+
// Fall through to normal Stop hooks on the final turn
|
|
929
|
+
}
|
|
930
|
+
else {
|
|
931
|
+
// 2. Evaluate goal
|
|
932
|
+
const evaluation = await goalManager.evaluateGoal(abortController.signal);
|
|
933
|
+
if (evaluation.isMet) {
|
|
934
|
+
goalManager.clearGoal();
|
|
935
|
+
logger?.info(`[Goal] Goal achieved: ${evaluation.reason}`);
|
|
936
|
+
this.messageManager.addUserMessage({
|
|
937
|
+
content: `<system-reminder>Goal achieved: ${evaluation.reason}</system-reminder>`,
|
|
938
|
+
isMeta: true,
|
|
939
|
+
});
|
|
940
|
+
// Fall through to normal Stop hooks on the final turn
|
|
941
|
+
}
|
|
942
|
+
else {
|
|
943
|
+
const goal = goalManager.getGoal();
|
|
944
|
+
goal.lastReason = evaluation.reason;
|
|
945
|
+
logger?.info(`[Goal] Not yet met: ${evaluation.reason}`);
|
|
946
|
+
this.messageManager.addUserMessage({
|
|
947
|
+
content: `<system-reminder>Goal not yet met: ${evaluation.reason}. Continue working toward: ${goal.condition}</system-reminder>`,
|
|
948
|
+
isMeta: true,
|
|
949
|
+
});
|
|
950
|
+
// Keep loading state active to prevent UI flicker
|
|
951
|
+
this.setIsLoading(true);
|
|
952
|
+
goalContinuing = true;
|
|
953
|
+
// Restart outer loop to continue goal pursuit
|
|
954
|
+
shouldRestart = true;
|
|
955
|
+
turnOffset = 0;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
// Skip Stop hooks when goal evaluator is continuing the conversation
|
|
960
|
+
if (goalContinuing) {
|
|
961
|
+
// Goal evaluator supersedes Stop hooks
|
|
962
|
+
}
|
|
963
|
+
else {
|
|
964
|
+
const shouldContinue = await this.executeStopHooks();
|
|
965
|
+
// If Stop/SubagentStop hooks indicate we should continue (due to blocking errors),
|
|
966
|
+
// restart the AI conversation cycle
|
|
967
|
+
if (shouldContinue) {
|
|
968
|
+
logger?.info(`${this.subagentType ? "SubagentStop" : "Stop"} hooks indicate issues need fixing, continuing conversation...`);
|
|
969
|
+
// Restart the conversation to let AI fix the issues
|
|
970
|
+
shouldRestart = true;
|
|
971
|
+
turnOffset = 0;
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
// Inject pending notifications from background tasks (after Stop hooks,
|
|
976
|
+
// aligned with Claude Code which fires Stop hooks unconditionally)
|
|
898
977
|
const notificationQueue = this.container.has("NotificationQueue")
|
|
899
978
|
? this.container.get("NotificationQueue")
|
|
900
979
|
: undefined;
|
|
@@ -916,87 +995,6 @@ export class AIManager {
|
|
|
916
995
|
shouldRestart = true;
|
|
917
996
|
turnOffset = 0;
|
|
918
997
|
}
|
|
919
|
-
else {
|
|
920
|
-
// Clear temporary rules
|
|
921
|
-
this.permissionManager?.clearTemporaryRules();
|
|
922
|
-
// Clear abort controllers
|
|
923
|
-
this.abortController = null;
|
|
924
|
-
this.toolAbortController = null;
|
|
925
|
-
// Execute Stop/SubagentStop hooks only if the operation was not aborted
|
|
926
|
-
const isCurrentlyAborted = abortController.signal.aborted ||
|
|
927
|
-
toolAbortController.signal.aborted;
|
|
928
|
-
if (!isCurrentlyAborted) {
|
|
929
|
-
// Record committed snapshots to message history for the final turn
|
|
930
|
-
if (this.reversionManager) {
|
|
931
|
-
const snapshots = this.reversionManager.getAndClearCommittedSnapshots();
|
|
932
|
-
if (snapshots.length > 0) {
|
|
933
|
-
this.messageManager.addFileHistoryBlock(snapshots);
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
// Goal evaluation — supersedes Stop hooks when active
|
|
937
|
-
const goalManager = this.container.has("GoalManager")
|
|
938
|
-
? this.container.get("GoalManager")
|
|
939
|
-
: undefined;
|
|
940
|
-
let goalContinuing = false;
|
|
941
|
-
if (goalManager?.isGoalActive() && !this.subagentType) {
|
|
942
|
-
// 1. Increment turn count and check circuit breakers
|
|
943
|
-
goalManager.incrementTurnCount();
|
|
944
|
-
const circuitBreaker = goalManager.checkCircuitBreakers();
|
|
945
|
-
if (circuitBreaker) {
|
|
946
|
-
goalManager.clearGoal();
|
|
947
|
-
logger?.info(`[Goal] ${circuitBreaker}`);
|
|
948
|
-
this.messageManager.addUserMessage({
|
|
949
|
-
content: `<system-reminder>${circuitBreaker}</system-reminder>`,
|
|
950
|
-
isMeta: true,
|
|
951
|
-
});
|
|
952
|
-
// Fall through to normal Stop hooks on the final turn
|
|
953
|
-
}
|
|
954
|
-
else {
|
|
955
|
-
// 2. Evaluate goal
|
|
956
|
-
const evaluation = await goalManager.evaluateGoal(abortController.signal);
|
|
957
|
-
if (evaluation.isMet) {
|
|
958
|
-
goalManager.clearGoal();
|
|
959
|
-
logger?.info(`[Goal] Goal achieved: ${evaluation.reason}`);
|
|
960
|
-
this.messageManager.addUserMessage({
|
|
961
|
-
content: `<system-reminder>Goal achieved: ${evaluation.reason}</system-reminder>`,
|
|
962
|
-
isMeta: true,
|
|
963
|
-
});
|
|
964
|
-
// Fall through to normal Stop hooks on the final turn
|
|
965
|
-
}
|
|
966
|
-
else {
|
|
967
|
-
const goal = goalManager.getGoal();
|
|
968
|
-
goal.lastReason = evaluation.reason;
|
|
969
|
-
logger?.info(`[Goal] Not yet met: ${evaluation.reason}`);
|
|
970
|
-
this.messageManager.addUserMessage({
|
|
971
|
-
content: `<system-reminder>Goal not yet met: ${evaluation.reason}. Continue working toward: ${goal.condition}</system-reminder>`,
|
|
972
|
-
isMeta: true,
|
|
973
|
-
});
|
|
974
|
-
// Keep loading state active to prevent UI flicker
|
|
975
|
-
this.setIsLoading(true);
|
|
976
|
-
goalContinuing = true;
|
|
977
|
-
// Restart outer loop to continue goal pursuit
|
|
978
|
-
shouldRestart = true;
|
|
979
|
-
turnOffset = 0;
|
|
980
|
-
}
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
// Skip Stop hooks when goal evaluator is continuing the conversation
|
|
984
|
-
if (goalContinuing) {
|
|
985
|
-
// Goal evaluator supersedes Stop hooks
|
|
986
|
-
}
|
|
987
|
-
else {
|
|
988
|
-
const shouldContinue = await this.executeStopHooks();
|
|
989
|
-
// If Stop/SubagentStop hooks indicate we should continue (due to blocking errors),
|
|
990
|
-
// restart the AI conversation cycle
|
|
991
|
-
if (shouldContinue) {
|
|
992
|
-
logger?.info(`${this.subagentType ? "SubagentStop" : "Stop"} hooks indicate issues need fixing, continuing conversation...`);
|
|
993
|
-
// Restart the conversation to let AI fix the issues
|
|
994
|
-
shouldRestart = true;
|
|
995
|
-
turnOffset = 0;
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
998
|
}
|
|
1001
999
|
if (!shouldRestart)
|
|
1002
1000
|
break outer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcpManager.d.ts","sourceRoot":"","sources":["../../src/managers/mcpManager.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAEjE,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EACV,MAAM,EACN,eAAe,EACf,SAAS,EACT,OAAO,EACP,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAQ3B,MAAM,WAAW,mBAAmB;IAClC,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;CAC3D;AAID,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC9C;AAQD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUnD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAsC7D;AAED,qBAAa,UAAU;IAanB,OAAO,CAAC,SAAS;IAZnB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,OAAO,CAA2C;IAC1D,OAAO,CAAC,WAAW,CAAyC;IAC5D,OAAO,CAAC,UAAU,CAAc;IAChC,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,UAAU,CAA8C;IAEhE,OAAO,CAAC,eAAe,CAA0C;IACjE,OAAO,CAAC,iBAAiB,CAAkC;gBAGjD,SAAS,EAAE,SAAS,EAC5B,OAAO,GAAE,iBAAsB;IAMjC;;OAEG;IACG,UAAU,CACd,OAAO,EAAE,MAAM,EACf,WAAW,GAAE,OAAe,GAC3B,OAAO,CAAC,IAAI,CAAC;IAgDV,kBAAkB,IAAI,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAO/C,UAAU,IAAI,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAgEvC,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IAWrD,SAAS,IAAI,SAAS,GAAG,IAAI;IAI7B,aAAa,IAAI,eAAe,EAAE;IAIlC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAIpD,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI;IASzE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO;IAuDzD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAgB7B,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"mcpManager.d.ts","sourceRoot":"","sources":["../../src/managers/mcpManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -363,28 +363,35 @@ export class McpManager {
|
|
|
363
363
|
cwd: this.workdir, // Use the agent's workdir as the process working directory
|
|
364
364
|
stderr: "pipe", // Pipe stderr to capture it
|
|
365
365
|
});
|
|
366
|
-
//
|
|
366
|
+
// Buffer stderr silently (MCP servers use stderr for all logging;
|
|
367
|
+
// stdout is reserved for JSON-RPC). Only dump it on connection
|
|
368
|
+
// success (once) or failure — not line-by-line in real time.
|
|
369
|
+
// Aligns with Claude Code's approach to avoid noise from [INFO],
|
|
370
|
+
// [DEBUG], Warning: lines that are not actual errors.
|
|
367
371
|
const stderr = transport.stderr;
|
|
372
|
+
let stderrOutput = "";
|
|
368
373
|
if (stderr) {
|
|
369
|
-
let buffer = "";
|
|
370
374
|
stderr.on("data", (chunk) => {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
buffer = lines.pop() || "";
|
|
374
|
-
for (const line of lines) {
|
|
375
|
-
if (line.trim()) {
|
|
376
|
-
logger?.error(`[MCP Server ${name}] ${line}`);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
});
|
|
380
|
-
stderr.on("end", () => {
|
|
381
|
-
if (buffer.trim()) {
|
|
382
|
-
logger?.error(`[MCP Server ${name}] ${buffer}`);
|
|
375
|
+
if (stderrOutput.length < 64 * 1024 * 1024) {
|
|
376
|
+
stderrOutput += chunk.toString();
|
|
383
377
|
}
|
|
384
378
|
});
|
|
385
379
|
}
|
|
386
380
|
client = createClient();
|
|
387
|
-
|
|
381
|
+
try {
|
|
382
|
+
await client.connect(transport);
|
|
383
|
+
}
|
|
384
|
+
catch (error) {
|
|
385
|
+
if (stderrOutput.trim()) {
|
|
386
|
+
logger?.error(`[MCP Server ${name}] Server stderr: ${stderrOutput.trim()}`);
|
|
387
|
+
}
|
|
388
|
+
throw error;
|
|
389
|
+
}
|
|
390
|
+
// Dump accumulated stderr once after successful connection
|
|
391
|
+
if (stderrOutput.trim()) {
|
|
392
|
+
logger?.debug(`[MCP Server ${name}] Server stderr: ${stderrOutput.trim()}`);
|
|
393
|
+
stderrOutput = "";
|
|
394
|
+
}
|
|
388
395
|
const toolsResponse = await client.listTools();
|
|
389
396
|
tools =
|
|
390
397
|
toolsResponse.tools?.map((tool) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bashTool.d.ts","sourceRoot":"","sources":["../../src/tools/bashTool.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bashTool.d.ts","sourceRoot":"","sources":["../../src/tools/bashTool.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAuBtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UA2iBtB,CAAC"}
|
package/dist/tools/bashTool.js
CHANGED
|
@@ -4,6 +4,7 @@ import * as path from "path";
|
|
|
4
4
|
import * as os from "os";
|
|
5
5
|
import { logger } from "../utils/globalLogger.js";
|
|
6
6
|
import { resolveShellPath } from "../utils/shellResolver.js";
|
|
7
|
+
import { toPosixPath } from "../utils/path.js";
|
|
7
8
|
import { stripAnsiColors } from "../utils/stringUtils.js";
|
|
8
9
|
import { processToolResult } from "../utils/toolResultStorage.js";
|
|
9
10
|
import { BASH_MAX_OUTPUT_CHARS } from "../constants/toolLimits.js";
|
|
@@ -211,7 +212,8 @@ The working directory persists between commands. Try to maintain your current wo
|
|
|
211
212
|
return new Promise((resolve) => {
|
|
212
213
|
// Create a temporary file to store the CWD
|
|
213
214
|
const tempCwdFile = path.join(os.tmpdir(), `wave_cwd_${Date.now()}_${Math.random().toString(36).substring(2, 11)}.tmp`);
|
|
214
|
-
const
|
|
215
|
+
const tempCwdFileForBash = toPosixPath(tempCwdFile);
|
|
216
|
+
const wrappedCommand = `${command} && pwd -P >| ${tempCwdFileForBash}`;
|
|
215
217
|
const child = spawn(wrappedCommand, {
|
|
216
218
|
shell: shellPath || true,
|
|
217
219
|
stdio: "pipe",
|
|
@@ -226,6 +228,17 @@ The working directory persists between commands. Try to maintain your current wo
|
|
|
226
228
|
let isAborted = false;
|
|
227
229
|
let isBackgrounded = false;
|
|
228
230
|
let isFinished = false;
|
|
231
|
+
// Best-effort cleanup of the temp CWD file — used by abort/error/exit paths
|
|
232
|
+
const cleanupTempFile = () => {
|
|
233
|
+
try {
|
|
234
|
+
if (fs.existsSync(tempCwdFile)) {
|
|
235
|
+
fs.unlinkSync(tempCwdFile);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
// ignore — best-effort cleanup
|
|
240
|
+
}
|
|
241
|
+
};
|
|
229
242
|
const updateRealtimeResults = () => {
|
|
230
243
|
if (isAborted || isBackgrounded || isFinished)
|
|
231
244
|
return;
|
|
@@ -352,6 +365,7 @@ The working directory persists between commands. Try to maintain your current wo
|
|
|
352
365
|
}
|
|
353
366
|
}
|
|
354
367
|
}
|
|
368
|
+
cleanupTempFile();
|
|
355
369
|
const processedOutput = processToolResult(outputBuffer + (errorBuffer ? "\n" + errorBuffer : ""), BASH_MAX_OUTPUT_CHARS, "bash");
|
|
356
370
|
resolve({
|
|
357
371
|
success: false,
|
|
@@ -410,15 +424,7 @@ The working directory persists between commands. Try to maintain your current wo
|
|
|
410
424
|
newCwd = undefined;
|
|
411
425
|
}
|
|
412
426
|
finally {
|
|
413
|
-
|
|
414
|
-
try {
|
|
415
|
-
if (fs.existsSync(tempCwdFile)) {
|
|
416
|
-
fs.unlinkSync(tempCwdFile);
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
catch (fileError) {
|
|
420
|
-
logger.error("Failed to clean up temp CWD file:", fileError);
|
|
421
|
-
}
|
|
427
|
+
cleanupTempFile();
|
|
422
428
|
}
|
|
423
429
|
// If CWD changed, call the onCwdChange callback and add notification
|
|
424
430
|
let cwdMessage;
|
|
@@ -462,6 +468,7 @@ The working directory persists between commands. Try to maintain your current wo
|
|
|
462
468
|
if (timeoutHandle) {
|
|
463
469
|
clearTimeout(timeoutHandle);
|
|
464
470
|
}
|
|
471
|
+
cleanupTempFile();
|
|
465
472
|
resolve({
|
|
466
473
|
success: false,
|
|
467
474
|
content: "",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editTool.d.ts","sourceRoot":"","sources":["../../src/tools/editTool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAgBtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"editTool.d.ts","sourceRoot":"","sources":["../../src/tools/editTool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAgBtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UAgRtB,CAAC"}
|
package/dist/tools/editTool.js
CHANGED
|
@@ -95,9 +95,11 @@ Usage:
|
|
|
95
95
|
}
|
|
96
96
|
// Trigger conditional rule loading for this file
|
|
97
97
|
context.messageManager?.triggerFileRead(filePath);
|
|
98
|
-
// Enforce read-before-edit: the file must have been read first
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
// Enforce read-before-edit: the file must have been read or written first.
|
|
99
|
+
// readFileState is populated by Read, Write, and Edit tools — single source
|
|
100
|
+
// of truth, aligned with Claude Code's readFileState approach.
|
|
101
|
+
const resolvedPath = resolvePath(filePath, context.workdir);
|
|
102
|
+
if (!context.readFileState?.has(resolvedPath)) {
|
|
101
103
|
return {
|
|
102
104
|
success: false,
|
|
103
105
|
content: "",
|
|
@@ -105,7 +107,6 @@ Usage:
|
|
|
105
107
|
};
|
|
106
108
|
}
|
|
107
109
|
try {
|
|
108
|
-
const resolvedPath = resolvePath(filePath, context.workdir);
|
|
109
110
|
// Read file content
|
|
110
111
|
let originalContent;
|
|
111
112
|
try {
|
|
@@ -22,5 +22,5 @@ export declare const USER_MEMORY_FILE: string;
|
|
|
22
22
|
* AI related constants
|
|
23
23
|
*/
|
|
24
24
|
export declare const DEFAULT_WAVE_MAX_INPUT_TOKENS = 200000;
|
|
25
|
-
export declare const DEFAULT_WAVE_MAX_OUTPUT_TOKENS =
|
|
25
|
+
export declare const DEFAULT_WAVE_MAX_OUTPUT_TOKENS = 32000;
|
|
26
26
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/utils/constants.js
CHANGED
|
@@ -24,4 +24,4 @@ export const USER_MEMORY_FILE = path.join(DATA_DIRECTORY, "AGENTS.md");
|
|
|
24
24
|
* AI related constants
|
|
25
25
|
*/
|
|
26
26
|
export const DEFAULT_WAVE_MAX_INPUT_TOKENS = 200000; // Default token limit
|
|
27
|
-
export const DEFAULT_WAVE_MAX_OUTPUT_TOKENS =
|
|
27
|
+
export const DEFAULT_WAVE_MAX_OUTPUT_TOKENS = 32000; // Default output token limit (aligned with Claude Code)
|
package/dist/utils/gitUtils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import * as fsSync from "node:fs";
|
|
3
|
-
import {
|
|
3
|
+
import { execFileSync } from "node:child_process";
|
|
4
4
|
/**
|
|
5
5
|
* Check if a directory is a git repository
|
|
6
6
|
* @param dirPath Directory path
|
|
@@ -30,7 +30,7 @@ export function isGitRepository(dirPath) {
|
|
|
30
30
|
*/
|
|
31
31
|
export function getGitRepoRoot(cwd) {
|
|
32
32
|
try {
|
|
33
|
-
return
|
|
33
|
+
return execFileSync("git", ["rev-parse", "--show-toplevel"], {
|
|
34
34
|
cwd,
|
|
35
35
|
encoding: "utf8",
|
|
36
36
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -47,7 +47,7 @@ export function getGitRepoRoot(cwd) {
|
|
|
47
47
|
*/
|
|
48
48
|
export function getGitCommonDir(cwd) {
|
|
49
49
|
try {
|
|
50
|
-
const commonDir =
|
|
50
|
+
const commonDir = execFileSync("git", ["rev-parse", "--git-common-dir"], {
|
|
51
51
|
cwd,
|
|
52
52
|
encoding: "utf8",
|
|
53
53
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -65,7 +65,7 @@ export function getGitCommonDir(cwd) {
|
|
|
65
65
|
*/
|
|
66
66
|
export function getGitMainRepoRoot(cwd) {
|
|
67
67
|
try {
|
|
68
|
-
const output =
|
|
68
|
+
const output = execFileSync("git", ["worktree", "list", "--porcelain"], {
|
|
69
69
|
cwd,
|
|
70
70
|
encoding: "utf8",
|
|
71
71
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -223,7 +223,7 @@ export function getDefaultRemoteBranch(cwd) {
|
|
|
223
223
|
*/
|
|
224
224
|
export function hasUncommittedChanges(cwd) {
|
|
225
225
|
try {
|
|
226
|
-
const status =
|
|
226
|
+
const status = execFileSync("git", ["status", "--porcelain"], {
|
|
227
227
|
cwd,
|
|
228
228
|
encoding: "utf8",
|
|
229
229
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -243,7 +243,7 @@ export function hasUncommittedChanges(cwd) {
|
|
|
243
243
|
export function hasNewCommits(cwd, baseBranch) {
|
|
244
244
|
try {
|
|
245
245
|
const range = baseBranch ? `${baseBranch}..HEAD` : "@{u}..HEAD";
|
|
246
|
-
const log =
|
|
246
|
+
const log = execFileSync("git", ["log", range, "--oneline"], {
|
|
247
247
|
cwd,
|
|
248
248
|
encoding: "utf8",
|
|
249
249
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openaiClient.d.ts","sourceRoot":"","sources":["../../src/utils/openaiClient.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sCAAsC,EACtC,mCAAmC,EACnC,mBAAmB,EACnB,cAAc,EACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAyBnD,KAAK,YAAY,GACb,sCAAsC,GACtC,mCAAmC,CAAC;AAExC,UAAU,WAAW,CAAC,CAAC;IACrB,IAAI,EAAE,CAAC,CAAC;IACR,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,UAAU,UAAU,CAAC,CAAC,CAAE,SAAQ,OAAO,CAAC,CAAC,CAAC;IACxC,YAAY,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;CACzC;AAED,qBAAa,YAAY;IACX,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAEzC,IAAI,IAAI;;qBAGO,CAAC,SAAS,YAAY,UACrB,CAAC,YACC;gBAAE,MAAM,CAAC,EAAE,WAAW,CAAA;aAAE,KACjC,UAAU,CACX,CAAC,SAAS,mCAAmC,GACzC,aAAa,CAAC,mBAAmB,CAAC,GAClC,cAAc,CACnB;;MA2BN;YAEa,OAAO;
|
|
1
|
+
{"version":3,"file":"openaiClient.d.ts","sourceRoot":"","sources":["../../src/utils/openaiClient.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sCAAsC,EACtC,mCAAmC,EACnC,mBAAmB,EACnB,cAAc,EACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAyBnD,KAAK,YAAY,GACb,sCAAsC,GACtC,mCAAmC,CAAC;AAExC,UAAU,WAAW,CAAC,CAAC;IACrB,IAAI,EAAE,CAAC,CAAC;IACR,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,UAAU,UAAU,CAAC,CAAC,CAAE,SAAQ,OAAO,CAAC,CAAC,CAAC;IACxC,YAAY,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;CACzC;AAED,qBAAa,YAAY;IACX,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAEzC,IAAI,IAAI;;qBAGO,CAAC,SAAS,YAAY,UACrB,CAAC,YACC;gBAAE,MAAM,CAAC,EAAE,WAAW,CAAA;aAAE,KACjC,UAAU,CACX,CAAC,SAAS,mCAAmC,GACzC,aAAa,CAAC,mBAAmB,CAAC,GAClC,cAAc,CACnB;;MA2BN;YAEa,OAAO;YAyHN,oBAAoB;CAyCpC"}
|
|
@@ -67,6 +67,7 @@ export class OpenAIClient {
|
|
|
67
67
|
}
|
|
68
68
|
if (attempt < MAX_RETRIES) {
|
|
69
69
|
logger.warn("OpenAI API network error, retrying...", {
|
|
70
|
+
model: params.model,
|
|
70
71
|
attempt: attempt + 1,
|
|
71
72
|
error: e,
|
|
72
73
|
});
|
|
@@ -91,41 +92,22 @@ export class OpenAIClient {
|
|
|
91
92
|
};
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
|
-
let
|
|
95
|
+
let responseText = "";
|
|
95
96
|
try {
|
|
96
|
-
|
|
97
|
-
try {
|
|
98
|
-
errorBody = JSON.parse(text);
|
|
99
|
-
}
|
|
100
|
-
catch (e) {
|
|
101
|
-
logger.error("Failed to parse error response body as JSON", {
|
|
102
|
-
error: e,
|
|
103
|
-
text,
|
|
104
|
-
});
|
|
105
|
-
errorBody = text;
|
|
106
|
-
}
|
|
97
|
+
responseText = await response.text();
|
|
107
98
|
}
|
|
108
99
|
catch (e) {
|
|
109
100
|
logger.error("Failed to read error response text", { error: e });
|
|
110
|
-
errorBody = {};
|
|
111
101
|
}
|
|
112
|
-
const error = new Error(
|
|
113
|
-
errorBody !== null &&
|
|
114
|
-
"error" in errorBody &&
|
|
115
|
-
typeof errorBody.error === "object" &&
|
|
116
|
-
errorBody.error !== null &&
|
|
117
|
-
"message" in errorBody.error
|
|
118
|
-
? String(errorBody.error.message)
|
|
119
|
-
: typeof errorBody === "string"
|
|
120
|
-
? errorBody
|
|
121
|
-
: response.statusText);
|
|
102
|
+
const error = new Error(`HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}: ${responseText}`);
|
|
122
103
|
error.status = response.status;
|
|
123
|
-
error.body =
|
|
104
|
+
error.body = responseText;
|
|
124
105
|
const retryableStatus = response.status === 429 ||
|
|
125
106
|
(response.status >= 500 && response.status !== 501);
|
|
126
107
|
if (retryableStatus && attempt < MAX_RETRIES) {
|
|
127
108
|
lastRetryAfter = response.headers.get("retry-after");
|
|
128
109
|
logger.warn("OpenAI API error, retrying...", {
|
|
110
|
+
model: params.model,
|
|
129
111
|
attempt: attempt + 1,
|
|
130
112
|
status: response.status,
|
|
131
113
|
retryAfter: lastRetryAfter,
|
|
@@ -136,7 +118,7 @@ export class OpenAIClient {
|
|
|
136
118
|
logger.error("OpenAI API Error:", {
|
|
137
119
|
status: response.status,
|
|
138
120
|
statusText: response.statusText,
|
|
139
|
-
|
|
121
|
+
body: responseText,
|
|
140
122
|
});
|
|
141
123
|
throw error;
|
|
142
124
|
}
|
package/dist/utils/path.d.ts
CHANGED
|
@@ -12,4 +12,11 @@ export declare function resolvePath(filePath: string, workdir: string): string;
|
|
|
12
12
|
* @returns Path for display (relative or absolute)
|
|
13
13
|
*/
|
|
14
14
|
export declare function getDisplayPath(filePath: string, workdir: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Convert backslashes to forward slashes for shell compatibility on Windows.
|
|
17
|
+
* On Windows, os.tmpdir() returns paths with backslashes (e.g., C:\Users\foo\Temp),
|
|
18
|
+
* which are treated as escape characters when interpolated into shell command strings.
|
|
19
|
+
* Returns the path as-is on non-Windows platforms.
|
|
20
|
+
*/
|
|
21
|
+
export declare function toPosixPath(p: string): string;
|
|
15
22
|
//# sourceMappingURL=path.d.ts.map
|
package/dist/utils/path.d.ts.map
CHANGED
|
@@ -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"}
|
|
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"}
|
package/dist/utils/path.js
CHANGED
|
@@ -46,3 +46,12 @@ export function getDisplayPath(filePath, workdir) {
|
|
|
46
46
|
}
|
|
47
47
|
return filePath;
|
|
48
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Convert backslashes to forward slashes for shell compatibility on Windows.
|
|
51
|
+
* On Windows, os.tmpdir() returns paths with backslashes (e.g., C:\Users\foo\Temp),
|
|
52
|
+
* which are treated as escape characters when interpolated into shell command strings.
|
|
53
|
+
* Returns the path as-is on non-Windows platforms.
|
|
54
|
+
*/
|
|
55
|
+
export function toPosixPath(p) {
|
|
56
|
+
return process.platform === "win32" ? p.replace(/\\/g, "/") : p;
|
|
57
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktreeUtils.d.ts","sourceRoot":"","sources":["../../src/utils/worktreeUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,mFAAmF;IACnF,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAmBvD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CA6B7C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"worktreeUtils.d.ts","sourceRoot":"","sources":["../../src/utils/worktreeUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,mFAAmF;IACnF,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAmBvD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CA6B7C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,CA6JtE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAmEvD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,kBAAkB,EAAE,MAAM,GAAG,SAAS,GACrC;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAsClD"}
|