sylas-edge-worker 0.2.21

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.
Files changed (163) hide show
  1. package/README.md +293 -0
  2. package/dist/ActivityPoster.d.ts +15 -0
  3. package/dist/ActivityPoster.d.ts.map +1 -0
  4. package/dist/ActivityPoster.js +194 -0
  5. package/dist/ActivityPoster.js.map +1 -0
  6. package/dist/AgentSessionManager.d.ts +280 -0
  7. package/dist/AgentSessionManager.d.ts.map +1 -0
  8. package/dist/AgentSessionManager.js +1412 -0
  9. package/dist/AgentSessionManager.js.map +1 -0
  10. package/dist/AskUserQuestionHandler.d.ts +97 -0
  11. package/dist/AskUserQuestionHandler.d.ts.map +1 -0
  12. package/dist/AskUserQuestionHandler.js +206 -0
  13. package/dist/AskUserQuestionHandler.js.map +1 -0
  14. package/dist/AttachmentService.d.ts +69 -0
  15. package/dist/AttachmentService.d.ts.map +1 -0
  16. package/dist/AttachmentService.js +369 -0
  17. package/dist/AttachmentService.js.map +1 -0
  18. package/dist/ChatSessionHandler.d.ts +87 -0
  19. package/dist/ChatSessionHandler.d.ts.map +1 -0
  20. package/dist/ChatSessionHandler.js +231 -0
  21. package/dist/ChatSessionHandler.js.map +1 -0
  22. package/dist/ConfigManager.d.ts +91 -0
  23. package/dist/ConfigManager.d.ts.map +1 -0
  24. package/dist/ConfigManager.js +227 -0
  25. package/dist/ConfigManager.js.map +1 -0
  26. package/dist/EdgeWorker.d.ts +670 -0
  27. package/dist/EdgeWorker.d.ts.map +1 -0
  28. package/dist/EdgeWorker.js +3801 -0
  29. package/dist/EdgeWorker.js.map +1 -0
  30. package/dist/GitService.d.ts +39 -0
  31. package/dist/GitService.d.ts.map +1 -0
  32. package/dist/GitService.js +432 -0
  33. package/dist/GitService.js.map +1 -0
  34. package/dist/GlobalSessionRegistry.d.ts +142 -0
  35. package/dist/GlobalSessionRegistry.d.ts.map +1 -0
  36. package/dist/GlobalSessionRegistry.js +254 -0
  37. package/dist/GlobalSessionRegistry.js.map +1 -0
  38. package/dist/PromptBuilder.d.ts +175 -0
  39. package/dist/PromptBuilder.d.ts.map +1 -0
  40. package/dist/PromptBuilder.js +884 -0
  41. package/dist/PromptBuilder.js.map +1 -0
  42. package/dist/RepositoryRouter.d.ts +152 -0
  43. package/dist/RepositoryRouter.d.ts.map +1 -0
  44. package/dist/RepositoryRouter.js +480 -0
  45. package/dist/RepositoryRouter.js.map +1 -0
  46. package/dist/RunnerSelectionService.d.ts +62 -0
  47. package/dist/RunnerSelectionService.d.ts.map +1 -0
  48. package/dist/RunnerSelectionService.js +379 -0
  49. package/dist/RunnerSelectionService.js.map +1 -0
  50. package/dist/SharedApplicationServer.d.ts +107 -0
  51. package/dist/SharedApplicationServer.d.ts.map +1 -0
  52. package/dist/SharedApplicationServer.js +247 -0
  53. package/dist/SharedApplicationServer.js.map +1 -0
  54. package/dist/SharedWebhookServer.d.ts +39 -0
  55. package/dist/SharedWebhookServer.d.ts.map +1 -0
  56. package/dist/SharedWebhookServer.js +150 -0
  57. package/dist/SharedWebhookServer.js.map +1 -0
  58. package/dist/SlackChatAdapter.d.ts +25 -0
  59. package/dist/SlackChatAdapter.d.ts.map +1 -0
  60. package/dist/SlackChatAdapter.js +143 -0
  61. package/dist/SlackChatAdapter.js.map +1 -0
  62. package/dist/UserAccessControl.d.ts +69 -0
  63. package/dist/UserAccessControl.d.ts.map +1 -0
  64. package/dist/UserAccessControl.js +171 -0
  65. package/dist/UserAccessControl.js.map +1 -0
  66. package/dist/WorktreeIncludeService.d.ts +32 -0
  67. package/dist/WorktreeIncludeService.d.ts.map +1 -0
  68. package/dist/WorktreeIncludeService.js +123 -0
  69. package/dist/WorktreeIncludeService.js.map +1 -0
  70. package/dist/index.d.ts +22 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +17 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/label-prompt-template.md +27 -0
  75. package/dist/procedures/ProcedureAnalyzer.d.ts +69 -0
  76. package/dist/procedures/ProcedureAnalyzer.d.ts.map +1 -0
  77. package/dist/procedures/ProcedureAnalyzer.js +271 -0
  78. package/dist/procedures/ProcedureAnalyzer.js.map +1 -0
  79. package/dist/procedures/index.d.ts +7 -0
  80. package/dist/procedures/index.d.ts.map +1 -0
  81. package/dist/procedures/index.js +7 -0
  82. package/dist/procedures/index.js.map +1 -0
  83. package/dist/procedures/registry.d.ts +156 -0
  84. package/dist/procedures/registry.d.ts.map +1 -0
  85. package/dist/procedures/registry.js +240 -0
  86. package/dist/procedures/registry.js.map +1 -0
  87. package/dist/procedures/types.d.ts +103 -0
  88. package/dist/procedures/types.d.ts.map +1 -0
  89. package/dist/procedures/types.js +5 -0
  90. package/dist/procedures/types.js.map +1 -0
  91. package/dist/prompt-assembly/types.d.ts +80 -0
  92. package/dist/prompt-assembly/types.d.ts.map +1 -0
  93. package/dist/prompt-assembly/types.js +8 -0
  94. package/dist/prompt-assembly/types.js.map +1 -0
  95. package/dist/prompts/builder.md +191 -0
  96. package/dist/prompts/debugger.md +128 -0
  97. package/dist/prompts/graphite-orchestrator.md +362 -0
  98. package/dist/prompts/orchestrator.md +290 -0
  99. package/dist/prompts/scoper.md +95 -0
  100. package/dist/prompts/standard-issue-assigned-user-prompt.md +33 -0
  101. package/dist/prompts/subroutines/changelog-update.md +79 -0
  102. package/dist/prompts/subroutines/coding-activity.md +12 -0
  103. package/dist/prompts/subroutines/concise-summary.md +67 -0
  104. package/dist/prompts/subroutines/debugger-fix.md +92 -0
  105. package/dist/prompts/subroutines/debugger-reproduction.md +74 -0
  106. package/dist/prompts/subroutines/full-delegation.md +68 -0
  107. package/dist/prompts/subroutines/get-approval.md +175 -0
  108. package/dist/prompts/subroutines/gh-pr.md +80 -0
  109. package/dist/prompts/subroutines/git-commit.md +37 -0
  110. package/dist/prompts/subroutines/plan-summary.md +21 -0
  111. package/dist/prompts/subroutines/preparation.md +16 -0
  112. package/dist/prompts/subroutines/question-answer.md +8 -0
  113. package/dist/prompts/subroutines/question-investigation.md +8 -0
  114. package/dist/prompts/subroutines/release-execution.md +81 -0
  115. package/dist/prompts/subroutines/release-summary.md +60 -0
  116. package/dist/prompts/subroutines/user-testing-summary.md +87 -0
  117. package/dist/prompts/subroutines/user-testing.md +48 -0
  118. package/dist/prompts/subroutines/validation-fixer.md +56 -0
  119. package/dist/prompts/subroutines/verbose-summary.md +46 -0
  120. package/dist/prompts/subroutines/verifications.md +77 -0
  121. package/dist/prompts/todolist-system-prompt-extension.md +15 -0
  122. package/dist/sinks/IActivitySink.d.ts +60 -0
  123. package/dist/sinks/IActivitySink.d.ts.map +1 -0
  124. package/dist/sinks/IActivitySink.js +2 -0
  125. package/dist/sinks/IActivitySink.js.map +1 -0
  126. package/dist/sinks/LinearActivitySink.d.ts +69 -0
  127. package/dist/sinks/LinearActivitySink.d.ts.map +1 -0
  128. package/dist/sinks/LinearActivitySink.js +111 -0
  129. package/dist/sinks/LinearActivitySink.js.map +1 -0
  130. package/dist/sinks/NoopActivitySink.d.ts +13 -0
  131. package/dist/sinks/NoopActivitySink.d.ts.map +1 -0
  132. package/dist/sinks/NoopActivitySink.js +17 -0
  133. package/dist/sinks/NoopActivitySink.js.map +1 -0
  134. package/dist/sinks/index.d.ts +9 -0
  135. package/dist/sinks/index.d.ts.map +1 -0
  136. package/dist/sinks/index.js +8 -0
  137. package/dist/sinks/index.js.map +1 -0
  138. package/dist/types.d.ts +32 -0
  139. package/dist/types.d.ts.map +1 -0
  140. package/dist/types.js +2 -0
  141. package/dist/types.js.map +1 -0
  142. package/dist/validation/ValidationLoopController.d.ts +54 -0
  143. package/dist/validation/ValidationLoopController.d.ts.map +1 -0
  144. package/dist/validation/ValidationLoopController.js +242 -0
  145. package/dist/validation/ValidationLoopController.js.map +1 -0
  146. package/dist/validation/index.d.ts +7 -0
  147. package/dist/validation/index.d.ts.map +1 -0
  148. package/dist/validation/index.js +7 -0
  149. package/dist/validation/index.js.map +1 -0
  150. package/dist/validation/types.d.ts +82 -0
  151. package/dist/validation/types.d.ts.map +1 -0
  152. package/dist/validation/types.js +29 -0
  153. package/dist/validation/types.js.map +1 -0
  154. package/label-prompt-template.md +27 -0
  155. package/package.json +56 -0
  156. package/prompt-template.md +116 -0
  157. package/prompts/builder.md +191 -0
  158. package/prompts/debugger.md +128 -0
  159. package/prompts/graphite-orchestrator.md +362 -0
  160. package/prompts/orchestrator.md +290 -0
  161. package/prompts/scoper.md +95 -0
  162. package/prompts/standard-issue-assigned-user-prompt.md +33 -0
  163. package/prompts/todolist-system-prompt-extension.md +15 -0
@@ -0,0 +1,432 @@
1
+ import { execSync } from "node:child_process";
2
+ import { existsSync, mkdirSync, statSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { basename, join, resolve as pathResolve } from "node:path";
5
+ import { createLogger } from "sylas-core";
6
+ import { WorktreeIncludeService } from "./WorktreeIncludeService.js";
7
+ /**
8
+ * Service responsible for Git worktree operations
9
+ */
10
+ export class GitService {
11
+ logger;
12
+ worktreeIncludeService;
13
+ constructor(logger) {
14
+ this.logger = logger ?? createLogger({ component: "GitService" });
15
+ this.worktreeIncludeService = new WorktreeIncludeService(this.logger);
16
+ }
17
+ /**
18
+ * Check if a branch exists locally or remotely
19
+ */
20
+ async branchExists(branchName, repoPath) {
21
+ try {
22
+ // Check if branch exists locally
23
+ execSync(`git rev-parse --verify "${branchName}"`, {
24
+ cwd: repoPath,
25
+ stdio: "pipe",
26
+ });
27
+ return true;
28
+ }
29
+ catch {
30
+ // Branch doesn't exist locally, check remote
31
+ try {
32
+ const remoteOutput = execSync(`git ls-remote --heads origin "${branchName}"`, {
33
+ cwd: repoPath,
34
+ stdio: "pipe",
35
+ });
36
+ // Check if output is non-empty (branch actually exists on remote)
37
+ return remoteOutput && remoteOutput.toString().trim().length > 0;
38
+ }
39
+ catch {
40
+ return false;
41
+ }
42
+ }
43
+ }
44
+ /**
45
+ * Sanitize branch name by removing backticks to prevent command injection
46
+ */
47
+ sanitizeBranchName(name) {
48
+ return name ? name.replace(/`/g, "") : name;
49
+ }
50
+ /**
51
+ * Resolve mutable Git metadata directories for a repository/worktree.
52
+ * This includes linked worktree metadata paths (for example
53
+ * `.git/worktrees/<name>/FETCH_HEAD`) that must be writable by sandboxes.
54
+ */
55
+ getGitMetadataDirectories(workingDirectory) {
56
+ const resolvedDirectories = new Set();
57
+ const revParse = (flag) => {
58
+ try {
59
+ const output = execSync(`git rev-parse ${flag}`, {
60
+ cwd: workingDirectory,
61
+ encoding: "utf8",
62
+ stdio: "pipe",
63
+ }).trim();
64
+ return output ? pathResolve(workingDirectory, output) : null;
65
+ }
66
+ catch {
67
+ return null;
68
+ }
69
+ };
70
+ const gitDir = revParse("--git-dir");
71
+ if (gitDir) {
72
+ resolvedDirectories.add(gitDir);
73
+ }
74
+ const gitCommonDir = revParse("--git-common-dir");
75
+ if (gitCommonDir) {
76
+ resolvedDirectories.add(gitCommonDir);
77
+ }
78
+ return [...resolvedDirectories];
79
+ }
80
+ /**
81
+ * Run a setup script with proper error handling and logging
82
+ */
83
+ async runSetupScript(scriptPath, scriptType, workspacePath, issue) {
84
+ // Expand ~ to home directory
85
+ const expandedPath = scriptPath.replace(/^~/, homedir());
86
+ // Check if script exists
87
+ if (!existsSync(expandedPath)) {
88
+ this.logger.warn(`⚠️ ${scriptType === "global" ? "Global" : "Repository"} setup script not found: ${scriptPath}`);
89
+ return;
90
+ }
91
+ // Check if script is executable (Unix only)
92
+ if (process.platform !== "win32") {
93
+ try {
94
+ const stats = statSync(expandedPath);
95
+ // Check if file has execute permission for the owner
96
+ if (!(stats.mode & 0o100)) {
97
+ this.logger.warn(`⚠️ ${scriptType === "global" ? "Global" : "Repository"} setup script is not executable: ${scriptPath}`);
98
+ this.logger.warn(` Run: chmod +x "${expandedPath}"`);
99
+ return;
100
+ }
101
+ }
102
+ catch (error) {
103
+ this.logger.warn(`⚠️ Cannot check permissions for ${scriptType} setup script: ${error.message}`);
104
+ return;
105
+ }
106
+ }
107
+ const scriptName = basename(expandedPath);
108
+ this.logger.info(`ℹ️ Running ${scriptType} setup script: ${scriptName}`);
109
+ try {
110
+ // Determine the command based on the script extension and platform
111
+ let command;
112
+ const isWindows = process.platform === "win32";
113
+ if (scriptPath.endsWith(".ps1")) {
114
+ command = `powershell -ExecutionPolicy Bypass -File "${expandedPath}"`;
115
+ }
116
+ else if (scriptPath.endsWith(".cmd") || scriptPath.endsWith(".bat")) {
117
+ command = `"${expandedPath}"`;
118
+ }
119
+ else if (isWindows) {
120
+ // On Windows, try to run with bash if available (Git Bash/WSL)
121
+ command = `bash "${expandedPath}"`;
122
+ }
123
+ else {
124
+ // On Unix, run directly with bash
125
+ command = `bash "${expandedPath}"`;
126
+ }
127
+ execSync(command, {
128
+ cwd: workspacePath,
129
+ stdio: "inherit",
130
+ env: {
131
+ ...process.env,
132
+ LINEAR_ISSUE_ID: issue.id,
133
+ LINEAR_ISSUE_IDENTIFIER: issue.identifier,
134
+ LINEAR_ISSUE_TITLE: issue.title || "",
135
+ },
136
+ timeout: 5 * 60 * 1000, // 5 minute timeout
137
+ });
138
+ this.logger.info(`✅ ${scriptType === "global" ? "Global" : "Repository"} setup script completed successfully`);
139
+ }
140
+ catch (error) {
141
+ const errorMessage = error.signal === "SIGTERM"
142
+ ? "Script execution timed out (exceeded 5 minutes)"
143
+ : error.message;
144
+ this.logger.error(`❌ ${scriptType === "global" ? "Global" : "Repository"} setup script failed: ${errorMessage}`);
145
+ // Log stderr if available
146
+ if (error.stderr) {
147
+ this.logger.error(" stderr:", error.stderr.toString());
148
+ }
149
+ // Continue execution despite setup script failure
150
+ this.logger.info(` Continuing with worktree creation...`);
151
+ }
152
+ }
153
+ /**
154
+ * Find an existing worktree by its checked-out branch name.
155
+ * Parses `git worktree list --porcelain` output and returns the worktree path
156
+ * if a worktree is found with the given branch checked out, or null otherwise.
157
+ */
158
+ findWorktreeByBranch(branchName, repoPath) {
159
+ try {
160
+ const output = execSync("git worktree list --porcelain", {
161
+ cwd: repoPath,
162
+ encoding: "utf-8",
163
+ });
164
+ const blocks = output.split("\n\n");
165
+ for (const block of blocks) {
166
+ const lines = block.split("\n");
167
+ let worktreePath = null;
168
+ let branchRef = null;
169
+ for (const line of lines) {
170
+ if (line.startsWith("worktree ")) {
171
+ worktreePath = line.slice("worktree ".length);
172
+ }
173
+ else if (line.startsWith("branch ")) {
174
+ branchRef = line.slice("branch refs/heads/".length);
175
+ }
176
+ }
177
+ if (worktreePath && branchRef === branchName) {
178
+ return worktreePath;
179
+ }
180
+ }
181
+ return null;
182
+ }
183
+ catch {
184
+ return null;
185
+ }
186
+ }
187
+ /**
188
+ * Create a git worktree for an issue
189
+ */
190
+ async createGitWorktree(issue, repository, globalSetupScript) {
191
+ try {
192
+ // Verify this is a git repository
193
+ try {
194
+ execSync("git rev-parse --git-dir", {
195
+ cwd: repository.repositoryPath,
196
+ stdio: "pipe",
197
+ });
198
+ }
199
+ catch (_e) {
200
+ this.logger.error(`${repository.repositoryPath} is not a git repository`);
201
+ throw new Error("Not a git repository");
202
+ }
203
+ // Use Linear's preferred branch name, or generate one if not available
204
+ const rawBranchName = issue.branchName ||
205
+ `${issue.identifier}-${issue.title
206
+ ?.toLowerCase()
207
+ .replace(/\s+/g, "-")
208
+ .substring(0, 30)}`;
209
+ const branchName = this.sanitizeBranchName(rawBranchName);
210
+ const workspacePath = join(repository.workspaceBaseDir, issue.identifier);
211
+ // Ensure workspace directory exists
212
+ mkdirSync(repository.workspaceBaseDir, { recursive: true });
213
+ // Check if worktree already exists
214
+ try {
215
+ const worktrees = execSync("git worktree list --porcelain", {
216
+ cwd: repository.repositoryPath,
217
+ encoding: "utf-8",
218
+ });
219
+ if (worktrees.includes(workspacePath)) {
220
+ this.logger.info(`Worktree already exists at ${workspacePath}, using existing`);
221
+ return {
222
+ path: workspacePath,
223
+ isGitWorktree: true,
224
+ };
225
+ }
226
+ }
227
+ catch (_e) {
228
+ // git worktree command failed, continue with creation
229
+ }
230
+ // Check if branch already exists
231
+ let createBranch = true;
232
+ try {
233
+ execSync(`git rev-parse --verify "${branchName}"`, {
234
+ cwd: repository.repositoryPath,
235
+ stdio: "pipe",
236
+ });
237
+ createBranch = false;
238
+ }
239
+ catch (_e) {
240
+ // Branch doesn't exist, we'll create it
241
+ }
242
+ // If the branch already exists, check if it's already checked out in another worktree
243
+ if (!createBranch) {
244
+ const existingWorktreePath = this.findWorktreeByBranch(branchName, repository.repositoryPath);
245
+ if (existingWorktreePath && existingWorktreePath !== workspacePath) {
246
+ this.logger.info(`Branch "${branchName}" is already checked out in worktree at ${existingWorktreePath}, reusing existing worktree`);
247
+ return {
248
+ path: existingWorktreePath,
249
+ isGitWorktree: true,
250
+ };
251
+ }
252
+ }
253
+ // Determine base branch for this issue
254
+ let baseBranch = repository.baseBranch;
255
+ // Check if issue has a parent
256
+ try {
257
+ const parent = await issue.parent;
258
+ if (parent) {
259
+ this.logger.info(`Issue ${issue.identifier} has parent: ${parent.identifier}`);
260
+ // Get parent's branch name
261
+ const parentRawBranchName = parent.branchName ||
262
+ `${parent.identifier}-${parent.title
263
+ ?.toLowerCase()
264
+ .replace(/\s+/g, "-")
265
+ .substring(0, 30)}`;
266
+ const parentBranchName = this.sanitizeBranchName(parentRawBranchName);
267
+ // Check if parent branch exists
268
+ const parentBranchExists = await this.branchExists(parentBranchName, repository.repositoryPath);
269
+ if (parentBranchExists) {
270
+ baseBranch = parentBranchName;
271
+ this.logger.info(`Using parent issue branch '${parentBranchName}' as base for sub-issue ${issue.identifier}`);
272
+ }
273
+ else {
274
+ this.logger.info(`Parent branch '${parentBranchName}' not found, using default base branch '${repository.baseBranch}'`);
275
+ }
276
+ }
277
+ }
278
+ catch (_error) {
279
+ // Parent field might not exist or couldn't be fetched, use default base branch
280
+ this.logger.info(`No parent issue found for ${issue.identifier}, using default base branch '${repository.baseBranch}'`);
281
+ }
282
+ // Fetch latest changes from remote
283
+ this.logger.debug("Fetching latest changes from remote...");
284
+ let hasRemote = true;
285
+ try {
286
+ execSync("git fetch origin", {
287
+ cwd: repository.repositoryPath,
288
+ stdio: "pipe",
289
+ });
290
+ }
291
+ catch (e) {
292
+ this.logger.warn("Warning: git fetch failed, proceeding with local branch:", e.message);
293
+ hasRemote = false;
294
+ }
295
+ // Create the worktree - use determined base branch
296
+ let worktreeCmd;
297
+ if (createBranch) {
298
+ if (hasRemote) {
299
+ // Check if the base branch exists remotely
300
+ let useRemoteBranch = false;
301
+ try {
302
+ const remoteOutput = execSync(`git ls-remote --heads origin "${baseBranch}"`, {
303
+ cwd: repository.repositoryPath,
304
+ stdio: "pipe",
305
+ });
306
+ // Check if output is non-empty (branch actually exists on remote)
307
+ useRemoteBranch =
308
+ remoteOutput && remoteOutput.toString().trim().length > 0;
309
+ if (!useRemoteBranch) {
310
+ this.logger.info(`Base branch '${baseBranch}' not found on remote, checking locally...`);
311
+ }
312
+ }
313
+ catch {
314
+ // Base branch doesn't exist remotely, use local or fall back to default
315
+ this.logger.info(`Base branch '${baseBranch}' not found on remote, checking locally...`);
316
+ }
317
+ if (useRemoteBranch) {
318
+ // Use remote version of base branch with --track to set upstream
319
+ const remoteBranch = `origin/${baseBranch}`;
320
+ this.logger.info(`Creating git worktree at ${workspacePath} from ${remoteBranch} (tracking ${baseBranch})`);
321
+ worktreeCmd = `git worktree add --track -b "${branchName}" "${workspacePath}" "${remoteBranch}"`;
322
+ }
323
+ else {
324
+ // Check if base branch exists locally
325
+ try {
326
+ execSync(`git rev-parse --verify "${baseBranch}"`, {
327
+ cwd: repository.repositoryPath,
328
+ stdio: "pipe",
329
+ });
330
+ // Use local base branch (can't track since remote doesn't have it)
331
+ this.logger.info(`Creating git worktree at ${workspacePath} from local ${baseBranch}`);
332
+ worktreeCmd = `git worktree add -b "${branchName}" "${workspacePath}" "${baseBranch}"`;
333
+ }
334
+ catch {
335
+ // Base branch doesn't exist locally either, fall back to remote default with --track
336
+ this.logger.info(`Base branch '${baseBranch}' not found locally, falling back to remote ${repository.baseBranch} (tracking ${repository.baseBranch})`);
337
+ const defaultRemoteBranch = `origin/${repository.baseBranch}`;
338
+ worktreeCmd = `git worktree add --track -b "${branchName}" "${workspacePath}" "${defaultRemoteBranch}"`;
339
+ }
340
+ }
341
+ }
342
+ else {
343
+ // No remote, use local branch (no tracking since no remote)
344
+ this.logger.info(`Creating git worktree at ${workspacePath} from local ${baseBranch}`);
345
+ worktreeCmd = `git worktree add -b "${branchName}" "${workspacePath}" "${baseBranch}"`;
346
+ }
347
+ }
348
+ else {
349
+ // Branch already exists, just check it out
350
+ this.logger.info(`Creating git worktree at ${workspacePath} with existing branch ${branchName}`);
351
+ worktreeCmd = `git worktree add "${workspacePath}" "${branchName}"`;
352
+ }
353
+ execSync(worktreeCmd, {
354
+ cwd: repository.repositoryPath,
355
+ stdio: "pipe",
356
+ });
357
+ // Copy files specified in .worktreeinclude that are also in .gitignore
358
+ // This runs before setup scripts so they can access these files
359
+ await this.worktreeIncludeService.copyIgnoredFiles(repository.repositoryPath, workspacePath);
360
+ // First, run the global setup script if configured
361
+ if (globalSetupScript) {
362
+ await this.runSetupScript(globalSetupScript, "global", workspacePath, issue);
363
+ }
364
+ // Then, check for repository setup scripts (cross-platform)
365
+ const isWindows = process.platform === "win32";
366
+ const setupScripts = [
367
+ {
368
+ file: "sylas-setup.sh",
369
+ platform: "unix",
370
+ },
371
+ {
372
+ file: "sylas-setup.ps1",
373
+ platform: "windows",
374
+ },
375
+ {
376
+ file: "sylas-setup.cmd",
377
+ platform: "windows",
378
+ },
379
+ {
380
+ file: "sylas-setup.bat",
381
+ platform: "windows",
382
+ },
383
+ ];
384
+ // Find the first available setup script for the current platform
385
+ const availableScript = setupScripts.find((script) => {
386
+ const scriptPath = join(repository.repositoryPath, script.file);
387
+ const isCompatible = isWindows
388
+ ? script.platform === "windows"
389
+ : script.platform === "unix";
390
+ return existsSync(scriptPath) && isCompatible;
391
+ });
392
+ // Fallback: on Windows, try bash if no Windows scripts found (for Git Bash/WSL users)
393
+ const fallbackScript = !availableScript && isWindows
394
+ ? setupScripts.find((script) => {
395
+ const scriptPath = join(repository.repositoryPath, script.file);
396
+ return script.platform === "unix" && existsSync(scriptPath);
397
+ })
398
+ : null;
399
+ const scriptToRun = availableScript || fallbackScript;
400
+ if (scriptToRun) {
401
+ const scriptPath = join(repository.repositoryPath, scriptToRun.file);
402
+ await this.runSetupScript(scriptPath, "repository", workspacePath, issue);
403
+ }
404
+ return {
405
+ path: workspacePath,
406
+ isGitWorktree: true,
407
+ };
408
+ }
409
+ catch (error) {
410
+ const errorMessage = error.message;
411
+ this.logger.error("Failed to create git worktree:", errorMessage);
412
+ // Check if the error is "branch already checked out in another worktree"
413
+ // Git error format: "fatal: 'branch-name' is already used by worktree at '/path/to/worktree'"
414
+ const worktreeMatch = errorMessage.match(/already used by worktree at '([^']+)'/);
415
+ if (worktreeMatch?.[1] && existsSync(worktreeMatch[1])) {
416
+ this.logger.info(`Reusing existing worktree at ${worktreeMatch[1]} (branch already checked out)`);
417
+ return {
418
+ path: worktreeMatch[1],
419
+ isGitWorktree: true,
420
+ };
421
+ }
422
+ // Fall back to regular directory if git worktree fails
423
+ const fallbackPath = join(repository.workspaceBaseDir, issue.identifier);
424
+ mkdirSync(fallbackPath, { recursive: true });
425
+ return {
426
+ path: fallbackPath,
427
+ isGitWorktree: false,
428
+ };
429
+ }
430
+ }
431
+ }
432
+ //# sourceMappingURL=GitService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitService.js","sourceRoot":"","sources":["../src/GitService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * GlobalSessionRegistry - Centralized session storage across all repositories
3
+ *
4
+ * This is Phase 1 of the CYPACK-724 architectural refactor.
5
+ * Replaces per-repository session storage in AgentSessionManager with a global registry
6
+ * that enables cross-repository session lookups (e.g., parent orchestrator in Repo A
7
+ * creating child issues in Repo B).
8
+ */
9
+ import { EventEmitter } from "node:events";
10
+ import type { SerializedSylasAgentSession, SerializedSylasAgentSessionEntry, SylasAgentSession, SylasAgentSessionEntry } from "sylas-core";
11
+ /**
12
+ * Serialization format for GlobalSessionRegistry state
13
+ * Version 3.0 to distinguish from previous per-repository format (v2.0)
14
+ */
15
+ export interface SerializedGlobalRegistryState {
16
+ version: "3.0";
17
+ sessions: Record<string, SerializedSylasAgentSession>;
18
+ entries: Record<string, SerializedSylasAgentSessionEntry[]>;
19
+ childToParentMap: Record<string, string>;
20
+ }
21
+ /**
22
+ * Events emitted by GlobalSessionRegistry
23
+ */
24
+ export interface GlobalSessionRegistryEvents {
25
+ sessionCreated: (session: SylasAgentSession) => void;
26
+ sessionUpdated: (sessionId: string, session: SylasAgentSession, updates: Partial<SylasAgentSession>) => void;
27
+ sessionCompleted: (sessionId: string, session: SylasAgentSession) => void;
28
+ }
29
+ /**
30
+ * GlobalSessionRegistry centralizes all session storage across repositories.
31
+ *
32
+ * Responsibilities:
33
+ * - Store ALL SylasAgentSession objects (all repos)
34
+ * - Store ALL SylasAgentSessionEntry arrays (all repos)
35
+ * - Maintain parent-child session relationships
36
+ * - Emit lifecycle events for session changes
37
+ * - Support serialization/deserialization for persistence
38
+ * - Provide cleanup for old sessions
39
+ */
40
+ export declare class GlobalSessionRegistry extends EventEmitter {
41
+ /**
42
+ * All sessions keyed by session id
43
+ */
44
+ private sessions;
45
+ /**
46
+ * All entries keyed by session id
47
+ */
48
+ private entries;
49
+ /**
50
+ * Child session ID → parent session ID mapping
51
+ * Enables orchestrator workflows where parent (Repo A) creates child (Repo B)
52
+ */
53
+ private childToParentMap;
54
+ /**
55
+ * Create a new session in the registry
56
+ * @param session The session to create
57
+ * @throws Error if session with same ID already exists
58
+ */
59
+ createSession(session: SylasAgentSession): void;
60
+ /**
61
+ * Get a session by ID
62
+ * @param sessionId The session id
63
+ * @returns The session or undefined if not found
64
+ */
65
+ getSession(sessionId: string): SylasAgentSession | undefined;
66
+ /**
67
+ * Update a session with partial data
68
+ * @param sessionId The session id
69
+ * @param updates Partial session data to merge
70
+ * @throws Error if session doesn't exist
71
+ */
72
+ updateSession(sessionId: string, updates: Partial<SylasAgentSession>): void;
73
+ /**
74
+ * Delete a session and its entries
75
+ * @param sessionId The session id
76
+ */
77
+ deleteSession(sessionId: string): void;
78
+ /**
79
+ * Get all sessions
80
+ * @returns Array of all sessions
81
+ */
82
+ getAllSessions(): SylasAgentSession[];
83
+ /**
84
+ * Add an entry to a session's conversation history
85
+ * @param sessionId The session id
86
+ * @param entry The entry to add
87
+ * @throws Error if session doesn't exist
88
+ */
89
+ addEntry(sessionId: string, entry: SylasAgentSessionEntry): void;
90
+ /**
91
+ * Get all entries for a session
92
+ * @param sessionId The session id
93
+ * @returns Array of entries (empty if session has no entries or doesn't exist)
94
+ */
95
+ getEntries(sessionId: string): SylasAgentSessionEntry[];
96
+ /**
97
+ * Update an entry in a session's conversation history
98
+ * @param sessionId The session id
99
+ * @param entryIndex The index of the entry to update (0-based)
100
+ * @param updates Partial entry data to merge
101
+ * @throws Error if session doesn't exist or index out of bounds
102
+ */
103
+ updateEntry(sessionId: string, entryIndex: number, updates: Partial<SylasAgentSessionEntry>): void;
104
+ /**
105
+ * Set parent session for a child session (orchestrator workflow)
106
+ * @param childSessionId The child's session id
107
+ * @param parentSessionId The parent's session id
108
+ */
109
+ setParentSession(childSessionId: string, parentSessionId: string): void;
110
+ /**
111
+ * Get parent session ID for a child session
112
+ * @param childSessionId The child's session id
113
+ * @returns The parent session ID or undefined if not found
114
+ */
115
+ getParentSessionId(childSessionId: string): string | undefined;
116
+ /**
117
+ * Get all child session IDs for a parent session
118
+ * @param parentSessionId The parent's session id
119
+ * @returns Array of child session IDs
120
+ */
121
+ getChildSessionIds(parentSessionId: string): string[];
122
+ /**
123
+ * Serialize the registry state for persistence
124
+ * Excludes non-serializable data like agentRunner instances
125
+ * @returns Serialized state
126
+ */
127
+ serializeState(): SerializedGlobalRegistryState;
128
+ /**
129
+ * Restore the registry state from serialized data
130
+ * Clears existing state before restoring
131
+ * @param state Serialized state to restore
132
+ */
133
+ restoreState(state: SerializedGlobalRegistryState): void;
134
+ /**
135
+ * Clean up old sessions based on age
136
+ * Removes sessions where updatedAt is older than maxAgeMs
137
+ * @param maxAgeMs Maximum age in milliseconds (sessions older than this are removed)
138
+ * @returns Number of sessions removed
139
+ */
140
+ cleanup(maxAgeMs: number): number;
141
+ }
142
+ //# sourceMappingURL=GlobalSessionRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlobalSessionRegistry.d.ts","sourceRoot":"","sources":["../src/GlobalSessionRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EACX,2BAA2B,EAC3B,gCAAgC,EAChC,iBAAiB,EACjB,sBAAsB,EACtB,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,MAAM,WAAW,6BAA6B;IAC7C,OAAO,EAAE,KAAK,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;IACtD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gCAAgC,EAAE,CAAC,CAAC;IAC5D,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC3C,cAAc,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACrD,cAAc,EAAE,CACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,KAC/B,IAAI,CAAC;IACV,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC1E;AAED;;;;;;;;;;GAUG;AACH,qBAAa,qBAAsB,SAAQ,YAAY;IACtD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAA6C;IAE7D;;OAEG;IACH,OAAO,CAAC,OAAO,CAAoD;IAEnE;;;OAGG;IACH,OAAO,CAAC,gBAAgB,CAAkC;IAE1D;;;;OAIG;IACH,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAW/C;;;;OAIG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAI5D;;;;;OAKG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,IAAI;IAsB3E;;;OAGG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IActC;;;OAGG;IACH,cAAc,IAAI,iBAAiB,EAAE;IAIrC;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB,GAAG,IAAI;IAgBhE;;;;OAIG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,sBAAsB,EAAE;IAIvD;;;;;;OAMG;IACH,WAAW,CACV,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,CAAC,sBAAsB,CAAC,GACtC,IAAI;IA6BP;;;;OAIG;IACH,gBAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI;IAIvE;;;;OAIG;IACH,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI9D;;;;OAIG;IACH,kBAAkB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,EAAE;IAWrD;;;;OAIG;IACH,cAAc,IAAI,6BAA6B;IA0B/C;;;;OAIG;IACH,YAAY,CAAC,KAAK,EAAE,6BAA6B,GAAG,IAAI;IAsBxD;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CAejC"}