wave-agent-sdk 0.19.4 → 0.19.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/agent.d.ts +21 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +21 -0
- package/dist/managers/aiManager.d.ts +15 -1
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +96 -2
- package/dist/managers/backgroundTaskManager.d.ts +1 -1
- package/dist/managers/backgroundTaskManager.d.ts.map +1 -1
- package/dist/managers/backgroundTaskManager.js +4 -3
- package/dist/managers/bangManager.d.ts.map +1 -1
- package/dist/managers/bangManager.js +2 -1
- package/dist/managers/messageManager.d.ts +7 -0
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +64 -5
- package/dist/managers/messageQueue.d.ts +8 -0
- package/dist/managers/messageQueue.d.ts.map +1 -1
- package/dist/managers/messageQueue.js +13 -0
- package/dist/managers/permissionManager.d.ts.map +1 -1
- package/dist/managers/permissionManager.js +3 -3
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +7 -1
- package/dist/prompts/index.d.ts +3 -1
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +2 -4
- package/dist/services/hook.d.ts.map +1 -1
- package/dist/services/hook.js +12 -0
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +7 -5
- package/dist/tools/enterWorktreeTool.d.ts.map +1 -1
- package/dist/tools/enterWorktreeTool.js +3 -8
- package/dist/tools/exitWorktreeTool.d.ts.map +1 -1
- package/dist/tools/exitWorktreeTool.js +5 -8
- package/dist/tools/grepTool.d.ts.map +1 -1
- package/dist/tools/grepTool.js +23 -1
- package/dist/types/hooks.d.ts +21 -0
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/messaging.d.ts +2 -0
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/utils/containerSetup.d.ts.map +1 -1
- package/dist/utils/containerSetup.js +3 -0
- package/dist/utils/shellResolver.d.ts.map +1 -1
- package/dist/utils/shellResolver.js +156 -7
- package/dist/utils/worktreeSession.d.ts +6 -6
- package/dist/utils/worktreeSession.d.ts.map +1 -1
- package/dist/utils/worktreeSession.js +7 -11
- package/package.json +1 -1
- package/src/agent.ts +31 -0
- package/src/managers/aiManager.ts +118 -2
- package/src/managers/backgroundTaskManager.ts +4 -2
- package/src/managers/bangManager.ts +2 -1
- package/src/managers/messageManager.ts +72 -6
- package/src/managers/messageQueue.ts +17 -0
- package/src/managers/permissionManager.ts +6 -3
- package/src/managers/subagentManager.ts +13 -1
- package/src/prompts/index.ts +4 -4
- package/src/services/hook.ts +16 -0
- package/src/tools/bashTool.ts +11 -5
- package/src/tools/enterWorktreeTool.ts +4 -14
- package/src/tools/exitWorktreeTool.ts +5 -13
- package/src/tools/grepTool.ts +25 -1
- package/src/types/hooks.ts +31 -0
- package/src/types/messaging.ts +2 -0
- package/src/utils/containerSetup.ts +4 -0
- package/src/utils/shellResolver.ts +167 -8
- package/src/utils/worktreeSession.ts +6 -16
|
@@ -4,10 +4,6 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
|
|
7
|
-
import {
|
|
8
|
-
getCurrentWorktreeSession,
|
|
9
|
-
setCurrentWorktreeSession,
|
|
10
|
-
} from "../utils/worktreeSession.js";
|
|
11
7
|
import {
|
|
12
8
|
removeWorktree,
|
|
13
9
|
countWorktreeChanges,
|
|
@@ -89,8 +85,8 @@ export const exitWorktreeTool: ToolPlugin = {
|
|
|
89
85
|
};
|
|
90
86
|
}
|
|
91
87
|
|
|
92
|
-
// Validate: must be in an active worktree session
|
|
93
|
-
const session =
|
|
88
|
+
// Validate: must be in an active worktree session (for this session)
|
|
89
|
+
const session = context.aiManager?.getWorktreeSession();
|
|
94
90
|
if (!session) {
|
|
95
91
|
return {
|
|
96
92
|
success: false,
|
|
@@ -139,11 +135,9 @@ export const exitWorktreeTool: ToolPlugin = {
|
|
|
139
135
|
|
|
140
136
|
if (action === "keep") {
|
|
141
137
|
// Clear session state
|
|
142
|
-
setCurrentWorktreeSession(null);
|
|
143
|
-
|
|
144
|
-
// Restore CWD
|
|
145
138
|
const aiManager = context.aiManager;
|
|
146
139
|
if (aiManager) {
|
|
140
|
+
aiManager.setWorktreeSession(null);
|
|
147
141
|
aiManager.setWorkdir(originalCwd);
|
|
148
142
|
}
|
|
149
143
|
|
|
@@ -170,12 +164,10 @@ export const exitWorktreeTool: ToolPlugin = {
|
|
|
170
164
|
|
|
171
165
|
removeWorktree(worktreeInfo);
|
|
172
166
|
|
|
173
|
-
// Clear session state
|
|
174
|
-
setCurrentWorktreeSession(null);
|
|
175
|
-
|
|
176
|
-
// Restore CWD
|
|
167
|
+
// Clear session state and restore CWD
|
|
177
168
|
const aiManager = context.aiManager;
|
|
178
169
|
if (aiManager) {
|
|
170
|
+
aiManager.setWorktreeSession(null);
|
|
179
171
|
aiManager.setWorkdir(originalCwd);
|
|
180
172
|
}
|
|
181
173
|
|
package/src/tools/grepTool.ts
CHANGED
|
@@ -8,6 +8,18 @@ import {
|
|
|
8
8
|
AGENT_TOOL_NAME,
|
|
9
9
|
} from "../constants/tools.js";
|
|
10
10
|
|
|
11
|
+
// Version control system directories to exclude from searches.
|
|
12
|
+
// These are excluded automatically because they create noise in search results.
|
|
13
|
+
// Mirrors Claude Code's VCS_DIRECTORIES_TO_EXCLUDE.
|
|
14
|
+
const VCS_DIRECTORIES_TO_EXCLUDE = [
|
|
15
|
+
".git",
|
|
16
|
+
".svn",
|
|
17
|
+
".hg",
|
|
18
|
+
".bzr",
|
|
19
|
+
".jj",
|
|
20
|
+
".sl",
|
|
21
|
+
] as const;
|
|
22
|
+
|
|
11
23
|
/**
|
|
12
24
|
* Grep tool plugin - powerful search tool based on ripgrep
|
|
13
25
|
*/
|
|
@@ -144,7 +156,19 @@ export const grepTool: ToolPlugin = {
|
|
|
144
156
|
|
|
145
157
|
try {
|
|
146
158
|
const workdir = context.workdir;
|
|
147
|
-
const rgArgs: string[] = [
|
|
159
|
+
const rgArgs: string[] = [
|
|
160
|
+
"--color=never",
|
|
161
|
+
"--max-columns=500",
|
|
162
|
+
// Search hidden files/directories by default (aligns with Claude Code).
|
|
163
|
+
// --hidden does NOT disable .gitignore; only --no-ignore would.
|
|
164
|
+
"--hidden",
|
|
165
|
+
];
|
|
166
|
+
|
|
167
|
+
// Exclude VCS directories to avoid noise from version control metadata.
|
|
168
|
+
// --hidden above would otherwise traverse .git/.svn/etc.
|
|
169
|
+
for (const dir of VCS_DIRECTORIES_TO_EXCLUDE) {
|
|
170
|
+
rgArgs.push("--glob", `!${dir}`);
|
|
171
|
+
}
|
|
148
172
|
|
|
149
173
|
// Set output mode
|
|
150
174
|
if (outputMode === "files_with_matches") {
|
package/src/types/hooks.ts
CHANGED
|
@@ -196,6 +196,34 @@ export interface HookJsonInput {
|
|
|
196
196
|
end_source?: SessionEndSource; // Present for SessionEnd events
|
|
197
197
|
compact_instructions?: string; // Present for PreCompact events
|
|
198
198
|
compact_summary?: string; // Present for PostCompact events
|
|
199
|
+
background_tasks?: BackgroundTaskInfo[]; // Present for Stop events: running background tasks snapshot
|
|
200
|
+
session_crons?: SessionCronInfo[]; // Present for Stop events: session-scoped cron jobs snapshot
|
|
201
|
+
last_assistant_message?: string; // Present for Stop and SubagentStop events: text content of the last assistant message
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Describes one in-flight background task in the Stop hook input.
|
|
205
|
+
// Aligned with Claude Code (v2.1.145+) background_tasks array element schema.
|
|
206
|
+
// Conditional fields are populated based on `type`:
|
|
207
|
+
// - "shell": `command` is set
|
|
208
|
+
// - "subagent": `agent_type` is set
|
|
209
|
+
// - "workflow": `name` is set
|
|
210
|
+
export interface BackgroundTaskInfo {
|
|
211
|
+
id: string;
|
|
212
|
+
type: "shell" | "subagent" | "workflow";
|
|
213
|
+
status: string;
|
|
214
|
+
description: string; // Capped at 1000 chars with "… [+N chars]" marker
|
|
215
|
+
command?: string; // Present only for shell tasks (≤1000 chars)
|
|
216
|
+
agent_type?: string; // Present only for subagent tasks
|
|
217
|
+
name?: string; // Present only for workflow tasks
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Describes one session-scoped cron job in the Stop hook input.
|
|
221
|
+
// Aligned with Claude Code (v2.1.145+) session_crons array element schema.
|
|
222
|
+
export interface SessionCronInfo {
|
|
223
|
+
id: string;
|
|
224
|
+
schedule: string; // Cron expression
|
|
225
|
+
recurring: boolean;
|
|
226
|
+
prompt: string;
|
|
199
227
|
}
|
|
200
228
|
|
|
201
229
|
// Extended context interface for passing additional data to hook executor
|
|
@@ -216,6 +244,9 @@ export interface ExtendedHookExecutionContext extends HookExecutionContext {
|
|
|
216
244
|
endSource?: SessionEndSource; // Session end source (SessionEnd only)
|
|
217
245
|
compactInstructions?: string; // Custom instructions for PreCompact
|
|
218
246
|
compactSummary?: string; // Summary text for PostCompact
|
|
247
|
+
backgroundTasks?: BackgroundTaskInfo[]; // Running background tasks snapshot (Stop only)
|
|
248
|
+
sessionCrons?: SessionCronInfo[]; // Session-scoped cron jobs snapshot (Stop only)
|
|
249
|
+
lastAssistantMessage?: string; // Text content of last assistant message (Stop and SubagentStop only)
|
|
219
250
|
}
|
|
220
251
|
|
|
221
252
|
// Environment variables injected into hook processes
|
package/src/types/messaging.ts
CHANGED
|
@@ -95,6 +95,8 @@ export interface ReasoningBlock {
|
|
|
95
95
|
type: "reasoning";
|
|
96
96
|
content: string;
|
|
97
97
|
stage?: "streaming" | "end";
|
|
98
|
+
startTime?: number; // Unix ms, set when the first reasoning content arrives
|
|
99
|
+
endTime?: number; // Unix ms, set when stage transitions to "end"
|
|
98
100
|
}
|
|
99
101
|
|
|
100
102
|
export interface FileHistoryBlock {
|
|
@@ -88,6 +88,10 @@ export function setupAgentContainer(
|
|
|
88
88
|
container.register("MainRepoRoot", getGitMainRepoRoot(workdir));
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
// Per-agent worktree session state (EnterWorktree/ExitWorktree). Stored in the
|
|
92
|
+
// container so it is isolated per session, not shared process-wide.
|
|
93
|
+
container.register("WorktreeSession", null);
|
|
94
|
+
|
|
91
95
|
const notificationQueue = new NotificationQueue();
|
|
92
96
|
container.register("NotificationQueue", notificationQueue);
|
|
93
97
|
|
|
@@ -1,19 +1,170 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { execFileSync } from "child_process";
|
|
2
4
|
|
|
3
5
|
export const WINDOWS_GIT_BASH_PATHS = [
|
|
4
6
|
"C:\\Program Files\\Git\\bin\\bash.exe",
|
|
5
7
|
"C:\\Program Files (x86)\\Git\\bin\\bash.exe",
|
|
6
8
|
];
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
// Common git.exe locations (checked before falling back to `where.exe`).
|
|
11
|
+
const WINDOWS_GIT_EXE_PATHS = [
|
|
12
|
+
"C:\\Program Files\\Git\\cmd\\git.exe",
|
|
13
|
+
"C:\\Program Files (x86)\\Git\\cmd\\git.exe",
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
// Common directories where bash/zsh may live, used as fallback after PATH lookup.
|
|
17
|
+
const FIXED_SHELL_DIRS = [
|
|
18
|
+
"/bin",
|
|
19
|
+
"/usr/bin",
|
|
20
|
+
"/usr/local/bin",
|
|
21
|
+
"/opt/homebrew/bin",
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
function isExecutable(shellPath: string): boolean {
|
|
25
|
+
try {
|
|
26
|
+
fs.accessSync(shellPath, fs.constants.X_OK);
|
|
27
|
+
return true;
|
|
28
|
+
} catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Resolve a command name (e.g. "bash") to an absolute path by searching $PATH. */
|
|
34
|
+
function which(command: string): string | undefined {
|
|
35
|
+
const pathEnv = process.env.PATH;
|
|
36
|
+
if (!pathEnv) return undefined;
|
|
37
|
+
for (const dir of pathEnv.split(":")) {
|
|
38
|
+
if (!dir) continue;
|
|
39
|
+
const candidate = path.join(dir, command);
|
|
40
|
+
if (isExecutable(candidate)) {
|
|
41
|
+
return candidate;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function isSupportedShell(shellPath: string): boolean {
|
|
48
|
+
return shellPath.includes("bash") || shellPath.includes("zsh");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Locate the `git` executable on Windows, then infer bash.exe from it.
|
|
53
|
+
* Checks common Git for Windows install locations first, then falls back
|
|
54
|
+
* to `where.exe git` (aligned with Claude Code's findExecutable('git')).
|
|
55
|
+
* Returns the inferred bash.exe path, or undefined if not found.
|
|
56
|
+
*/
|
|
57
|
+
function inferGitBashFromGit(): string | undefined {
|
|
58
|
+
// 1. Common git.exe locations
|
|
59
|
+
let gitExe: string | undefined;
|
|
60
|
+
for (const candidate of WINDOWS_GIT_EXE_PATHS) {
|
|
61
|
+
if (fs.existsSync(candidate)) {
|
|
62
|
+
gitExe = candidate;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 2. Fallback: where.exe git
|
|
68
|
+
if (!gitExe) {
|
|
69
|
+
try {
|
|
70
|
+
const result = execFileSync("where", ["git"], {
|
|
71
|
+
stdio: "pipe",
|
|
72
|
+
encoding: "utf8",
|
|
73
|
+
timeout: 3000,
|
|
74
|
+
}).trim();
|
|
75
|
+
// where.exe may return multiple lines; take the first non-empty one.
|
|
76
|
+
gitExe = result.split(/\r?\n/).find((line) => line.trim()) || undefined;
|
|
77
|
+
} catch {
|
|
78
|
+
gitExe = undefined;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!gitExe) return undefined;
|
|
83
|
+
|
|
84
|
+
// git.exe is at <install>/cmd/git.exe → bash.exe is at <install>/bin/bash.exe
|
|
85
|
+
// join treats git.exe as a segment, so ".." cancels it (→ cmd dir),
|
|
86
|
+
// the second ".." cancels cmd (→ <install>), then bin/bash.exe.
|
|
87
|
+
const bashPath = path.win32.join(gitExe, "..", "..", "bin", "bash.exe");
|
|
88
|
+
if (fs.existsSync(bashPath)) {
|
|
89
|
+
return bashPath;
|
|
11
90
|
}
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
12
93
|
|
|
13
|
-
|
|
14
|
-
|
|
94
|
+
/**
|
|
95
|
+
* Resolve a bash or zsh binary on macOS/Linux.
|
|
96
|
+
*
|
|
97
|
+
* Priority (aligned with Claude Code's findSuitableShell):
|
|
98
|
+
* 1. WAVE_SHELL env var (only if it points to an executable bash/zsh)
|
|
99
|
+
* 2. $SHELL (only if it is bash/zsh)
|
|
100
|
+
* 3. `which bash` / `which zsh` discovered on $PATH
|
|
101
|
+
* 4. Common fixed locations (/bin, /usr/bin, /usr/local/bin, /opt/homebrew/bin)
|
|
102
|
+
*
|
|
103
|
+
* When $SHELL is bash, bash is preferred; otherwise zsh is preferred. This
|
|
104
|
+
* matters because /bin/sh may be dash (Debian/Ubuntu) or POSIX-mode bash
|
|
105
|
+
* (macOS), neither of which supports bashisms like process substitution
|
|
106
|
+
* `<()`, causing `eval '<()...'` to fail at parse time.
|
|
107
|
+
*/
|
|
108
|
+
function resolveUnixShell(): string | undefined {
|
|
109
|
+
// 1. WAVE_SHELL env override
|
|
110
|
+
const waveShell = process.env.WAVE_SHELL;
|
|
111
|
+
if (waveShell && isSupportedShell(waveShell) && isExecutable(waveShell)) {
|
|
112
|
+
return waveShell;
|
|
15
113
|
}
|
|
16
114
|
|
|
115
|
+
// 2. $SHELL (only bash/zsh)
|
|
116
|
+
const envShell = process.env.SHELL;
|
|
117
|
+
const isEnvShellSupported = !!envShell && isSupportedShell(envShell);
|
|
118
|
+
const preferBash = envShell?.includes("bash") ?? false;
|
|
119
|
+
|
|
120
|
+
// 3. Locate via PATH
|
|
121
|
+
const bashPath = which("bash");
|
|
122
|
+
const zshPath = which("zsh");
|
|
123
|
+
|
|
124
|
+
// 4. Fixed common locations, ordered by user preference
|
|
125
|
+
const shellOrder = preferBash ? ["bash", "zsh"] : ["zsh", "bash"];
|
|
126
|
+
const candidates = shellOrder.flatMap((shell) =>
|
|
127
|
+
FIXED_SHELL_DIRS.map((dir) => `${dir}/${shell}`),
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
// Discovered PATH paths: preferred type first, the other as fallback
|
|
131
|
+
if (preferBash) {
|
|
132
|
+
if (bashPath) candidates.unshift(bashPath);
|
|
133
|
+
if (zshPath) candidates.push(zshPath);
|
|
134
|
+
} else {
|
|
135
|
+
if (zshPath) candidates.unshift(zshPath);
|
|
136
|
+
if (bashPath) candidates.push(bashPath);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Always prioritize $SHELL if it is a supported, executable shell
|
|
140
|
+
if (isEnvShellSupported && envShell && isExecutable(envShell)) {
|
|
141
|
+
candidates.unshift(envShell);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return candidates.find((candidate) => isExecutable(candidate));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Resolve the Git Bash path on Windows.
|
|
149
|
+
*
|
|
150
|
+
* Priority (aligned with Claude Code's findGitBashPath):
|
|
151
|
+
* 1. WAVE_GIT_BASH_PATH env var
|
|
152
|
+
* 2. Infer from `git` executable location (<git dir>/../../bin/bash.exe)
|
|
153
|
+
* 3. Common install paths (C:\Program Files\Git\bin\bash.exe, etc.)
|
|
154
|
+
*/
|
|
155
|
+
function resolveWindowsShell(): string | undefined {
|
|
156
|
+
// 1. Env var override
|
|
157
|
+
if (process.env.WAVE_GIT_BASH_PATH) {
|
|
158
|
+
return process.env.WAVE_GIT_BASH_PATH;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// 2. Infer from git executable location
|
|
162
|
+
const inferred = inferGitBashFromGit();
|
|
163
|
+
if (inferred) {
|
|
164
|
+
return inferred;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// 4. Common install paths
|
|
17
168
|
const paths = [
|
|
18
169
|
...WINDOWS_GIT_BASH_PATHS,
|
|
19
170
|
process.env.LOCALAPPDATA
|
|
@@ -21,11 +172,19 @@ export function resolveShellPath(): string | undefined {
|
|
|
21
172
|
: null,
|
|
22
173
|
].filter(Boolean) as string[];
|
|
23
174
|
|
|
24
|
-
for (const
|
|
25
|
-
if (fs.existsSync(
|
|
26
|
-
return
|
|
175
|
+
for (const p of paths) {
|
|
176
|
+
if (fs.existsSync(p)) {
|
|
177
|
+
return p;
|
|
27
178
|
}
|
|
28
179
|
}
|
|
29
180
|
|
|
30
181
|
return undefined;
|
|
31
182
|
}
|
|
183
|
+
|
|
184
|
+
export function resolveShellPath(): string | undefined {
|
|
185
|
+
if (process.platform === "win32") {
|
|
186
|
+
return resolveWindowsShell();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return resolveUnixShell();
|
|
190
|
+
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Analogous to Claude Code's currentWorktreeSession in worktree.ts.
|
|
2
|
+
* Worktree session state tracking.
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* The session state is stored per-agent in each session's DI container (see the
|
|
5
|
+
* "WorktreeSession" container slot registered in containerSetup.ts and accessed via
|
|
6
|
+
* AIManager.getWorktreeSession()/setWorktreeSession()). This keeps worktree state
|
|
7
|
+
* isolated per session in stdio multi-agent mode — a process-level singleton would
|
|
8
|
+
* leak state across concurrent sessions (see specs/047-worktree.md FR-042).
|
|
7
9
|
*/
|
|
8
10
|
|
|
9
11
|
export interface WorktreeSession {
|
|
@@ -22,15 +24,3 @@ export interface WorktreeSession {
|
|
|
22
24
|
/** The HEAD commit of the original branch at worktree creation time */
|
|
23
25
|
originalHeadCommit?: string;
|
|
24
26
|
}
|
|
25
|
-
|
|
26
|
-
let currentWorktreeSession: WorktreeSession | null = null;
|
|
27
|
-
|
|
28
|
-
export function getCurrentWorktreeSession(): WorktreeSession | null {
|
|
29
|
-
return currentWorktreeSession;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function setCurrentWorktreeSession(
|
|
33
|
-
session: WorktreeSession | null,
|
|
34
|
-
): void {
|
|
35
|
-
currentWorktreeSession = session;
|
|
36
|
-
}
|